Implement copy_to_offset for aggregate sources
This commit is contained in:
@@ -44,17 +44,15 @@ task :convert do
|
|||||||
seen_proc = false if line.start_with? 'end'
|
seen_proc = false if line.start_with? 'end'
|
||||||
if line.start_with?('begin') && !seen_proc
|
if line.start_with?('begin') && !seen_proc
|
||||||
current_stage << <<~FUN
|
current_stage << <<~FUN
|
||||||
|
|
||||||
proc f();
|
proc f();
|
||||||
var
|
var
|
||||||
x: ^ElnaLocation;
|
x: ElnaType;
|
||||||
y: ElnaLocation;
|
y: ElnaTypeField;
|
||||||
begin
|
begin
|
||||||
x := malloc(#size(ElnaLocation));
|
x.size := 3;
|
||||||
y.line := 1;
|
y.field_type := malloc(#size(ElnaType));
|
||||||
y.column := 3;
|
y.field_type^ := x;
|
||||||
x^ := y;
|
printf("# %i\\n\\0", y.field_type^.size)
|
||||||
printf("# %i %i %i %i\\n\\0", x^.line, x^.column, y.line, y.column)
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|||||||
+102
-38
@@ -1181,14 +1181,37 @@ proc elna_rtl_store(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstructio
|
|||||||
var
|
var
|
||||||
instruction: ^ElnaRtlInstruction;
|
instruction: ^ElnaRtlInstruction;
|
||||||
rtl_operand: ElnaRtlOperand;
|
rtl_operand: ElnaRtlOperand;
|
||||||
|
pseudo_symbol: ^ElnaRtlObjectInfo;
|
||||||
begin
|
begin
|
||||||
elna_rtl_operand_value(instructions, @tac_instruction^.operands[1], variable_map, @rtl_operand);
|
elna_rtl_operand_value(instructions, @tac_instruction^.operands[1], variable_map, @rtl_operand);
|
||||||
|
|
||||||
instruction := elna_rtl_instruction_create(ElnaRtlOperator.sw);
|
pseudo_symbol := elna_symbol_table_lookup(variable_map,
|
||||||
elna_rtl_instruction_set_operand(instruction, 1, rtl_operand.kind, rtl_operand.value, rtl_operand.length, 0);
|
tac_instruction^.operands[1].value, tac_instruction^.operands[1].length);
|
||||||
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo,
|
if pseudo_symbol <> nil then
|
||||||
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0);
|
if pseudo_symbol^.rtl_type^.kind = ElnaRtlTypeKind.byte_array then
|
||||||
elna_list_append(instructions, instruction)
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a0, 0, 0);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo,
|
||||||
|
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0);
|
||||||
|
elna_list_append(instructions, instruction);
|
||||||
|
|
||||||
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.la);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a1, 0, 0);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 2, rtl_operand.kind, rtl_operand.value, rtl_operand.length, 0);
|
||||||
|
elna_list_append(instructions, instruction);
|
||||||
|
|
||||||
|
elna_rtl_memcpy(instructions, pseudo_symbol^.rtl_type)
|
||||||
|
else
|
||||||
|
pseudo_symbol = nil
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
if pseudo_symbol = nil then
|
||||||
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.sw);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 1, rtl_operand.kind, rtl_operand.value, rtl_operand.length, 0);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo,
|
||||||
|
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0);
|
||||||
|
elna_list_append(instructions, instruction)
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_rtl_copy_to_offset(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable);
|
proc elna_rtl_copy_to_offset(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable);
|
||||||
@@ -1196,18 +1219,48 @@ var
|
|||||||
instruction: ^ElnaRtlInstruction;
|
instruction: ^ElnaRtlInstruction;
|
||||||
target_operand: ElnaRtlOperand;
|
target_operand: ElnaRtlOperand;
|
||||||
source_operand: ElnaRtlOperand;
|
source_operand: ElnaRtlOperand;
|
||||||
|
pseudo_symbol: ^ElnaRtlObjectInfo;
|
||||||
begin
|
begin
|
||||||
elna_rtl_generate_pseudo(@target_operand, variable_map);
|
|
||||||
instruction := elna_rtl_operand_address(variable_map, @tac_instruction^.operands[2], @target_operand);
|
|
||||||
elna_list_append(instructions, instruction);
|
|
||||||
|
|
||||||
elna_rtl_operand_value(instructions, @tac_instruction^.operands[1], variable_map, @source_operand);
|
elna_rtl_operand_value(instructions, @tac_instruction^.operands[1], variable_map, @source_operand);
|
||||||
instruction := elna_rtl_instruction_create(ElnaRtlOperator.sw);
|
|
||||||
|
|
||||||
elna_rtl_instruction_set_operand(instruction, 1, source_operand.kind, source_operand.value, source_operand.length, 0);
|
pseudo_symbol := elna_symbol_table_lookup(variable_map,
|
||||||
elna_rtl_instruction_set_operand(instruction, 2, target_operand.kind, target_operand.value,
|
tac_instruction^.operands[1].value, tac_instruction^.operands[1].length);
|
||||||
target_operand.length, tac_instruction^.operands[3].value);
|
if pseudo_symbol <> nil then
|
||||||
elna_list_append(instructions, instruction)
|
if pseudo_symbol^.rtl_type^.kind = ElnaRtlTypeKind.byte_array then
|
||||||
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.la);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a0, 0, 0);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo,
|
||||||
|
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0);
|
||||||
|
elna_list_append(instructions, instruction);
|
||||||
|
|
||||||
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.addi);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a0, 0, 0);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.a0, 0, 0);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 3, ElnaRtlKind.immediate, tac_instruction^.operands[3].value, 0, 0);
|
||||||
|
elna_list_append(instructions, instruction);
|
||||||
|
|
||||||
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.la);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a1, 0, 0);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 2, source_operand.kind, source_operand.value, source_operand.length, 0);
|
||||||
|
elna_list_append(instructions, instruction);
|
||||||
|
|
||||||
|
elna_rtl_memcpy(instructions, pseudo_symbol^.rtl_type)
|
||||||
|
|
||||||
|
else
|
||||||
|
pseudo_symbol := nil
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
if pseudo_symbol = nil then
|
||||||
|
elna_rtl_generate_pseudo(@target_operand, variable_map);
|
||||||
|
instruction := elna_rtl_operand_address(variable_map, @tac_instruction^.operands[2], @target_operand);
|
||||||
|
elna_list_append(instructions, instruction);
|
||||||
|
|
||||||
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.sw);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 1, source_operand.kind, source_operand.value, source_operand.length, 0);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 2, target_operand.kind, target_operand.value,
|
||||||
|
target_operand.length, tac_instruction^.operands[3].value);
|
||||||
|
elna_list_append(instructions, instruction)
|
||||||
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_rtl_load(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable);
|
proc elna_rtl_load(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable);
|
||||||
@@ -1221,8 +1274,18 @@ begin
|
|||||||
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length);
|
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length);
|
||||||
|
|
||||||
if pseudo_symbol^.rtl_type^.kind = ElnaRtlTypeKind.byte_array then
|
if pseudo_symbol^.rtl_type^.kind = ElnaRtlTypeKind.byte_array then
|
||||||
elna_rtl_memcpy(instructions, @rtl_operand, pseudo_symbol^.rtl_type, rtl_operand.kind,
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.la);
|
||||||
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length)
|
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a0, 0, 0);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo,
|
||||||
|
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0);
|
||||||
|
elna_list_append(instructions, instruction);
|
||||||
|
|
||||||
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a1, 0, 0);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 2, rtl_operand.kind, rtl_operand.value, rtl_operand.length, 0);
|
||||||
|
elna_list_append(instructions, instruction);
|
||||||
|
|
||||||
|
elna_rtl_memcpy(instructions, pseudo_symbol^.rtl_type)
|
||||||
else
|
else
|
||||||
instruction := elna_rtl_instruction_create(ElnaRtlOperator.lw);
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.lw);
|
||||||
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo,
|
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo,
|
||||||
@@ -1251,25 +1314,10 @@ begin
|
|||||||
elna_list_append(instructions, instruction)
|
elna_list_append(instructions, instruction)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_rtl_memcpy(instructions: ^ElnaList, source_operand: ^ElnaRtlOperand, byte_array: ^ElnaRtlTypeByteArray,
|
proc elna_rtl_memcpy(instructions: ^ElnaList, byte_array: ^ElnaRtlTypeByteArray);
|
||||||
target_type: Word, target_value: Word, target_length: Word);
|
|
||||||
var
|
var
|
||||||
instruction: ElnaRtlInstruction;
|
instruction: ElnaRtlInstruction;
|
||||||
begin
|
begin
|
||||||
instruction := elna_rtl_instruction_create(ElnaRtlOperator.la);
|
|
||||||
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a0, 0, 0);
|
|
||||||
elna_rtl_instruction_set_operand(instruction, 2, target_type, target_value, target_length, 0);
|
|
||||||
elna_list_append(instructions, instruction);
|
|
||||||
|
|
||||||
if source_operand^.kind = ElnaRtlKind.pseudo then
|
|
||||||
instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv)
|
|
||||||
else
|
|
||||||
instruction := elna_rtl_instruction_create(ElnaRtlOperator.la)
|
|
||||||
end;
|
|
||||||
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a1, 0, 0);
|
|
||||||
elna_rtl_instruction_set_operand(instruction, 2, source_operand^.kind, source_operand^.value, source_operand^.length, 0);
|
|
||||||
elna_list_append(instructions, instruction);
|
|
||||||
|
|
||||||
instruction := elna_rtl_instruction_create(ElnaRtlOperator.li);
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.li);
|
||||||
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a2, 0, 0);
|
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a2, 0, 0);
|
||||||
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.immediate, byte_array^.size, 0, 0);
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.immediate, byte_array^.size, 0, 0);
|
||||||
@@ -1297,8 +1345,18 @@ begin
|
|||||||
elna_rtl_instruction_set_operand(instruction, 2, source_operand.kind, source_operand.value, source_operand.length, 0);
|
elna_rtl_instruction_set_operand(instruction, 2, source_operand.kind, source_operand.value, source_operand.length, 0);
|
||||||
elna_list_append(instructions, instruction);
|
elna_list_append(instructions, instruction);
|
||||||
else
|
else
|
||||||
elna_rtl_memcpy(instructions, @source_operand, pseudo_symbol^.rtl_type, source_operand.kind,
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.la);
|
||||||
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length)
|
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a0, 0, 0);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo_mem,
|
||||||
|
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0);
|
||||||
|
elna_list_append(instructions, instruction);
|
||||||
|
|
||||||
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.la);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a1, 0, 0);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 2, source_operand.kind, source_operand.value, source_operand.length, 0);
|
||||||
|
elna_list_append(instructions, instruction);
|
||||||
|
|
||||||
|
elna_rtl_memcpy(instructions, pseudo_symbol^.rtl_type)
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@@ -2909,18 +2967,24 @@ proc elna_tac_dereference_expression(instructions: ^ElnaList, dereference_expres
|
|||||||
var
|
var
|
||||||
load_instruction: ^ElnaTacInstruction;
|
load_instruction: ^ElnaTacInstruction;
|
||||||
operand_result: ElnaTacOperandResult;
|
operand_result: ElnaTacOperandResult;
|
||||||
|
intermediate: ElnaTacOperand;
|
||||||
begin
|
begin
|
||||||
elna_tac_designator(instructions, dereference_expression^.pointer, symbol_table, @operand_result, operand);
|
elna_tac_designator(instructions, dereference_expression^.pointer, symbol_table, @operand_result, operand);
|
||||||
|
|
||||||
if operand_result.kind = ElnaTacOperandType.dereferenced_pointer then
|
if operand_result.kind = ElnaTacOperandType.dereferenced_pointer then
|
||||||
load_instruction := elna_tac_instruction_create(ElnaTacOperator.load);
|
memcpy(@intermediate, operand, #size(ElnaTacOperand));
|
||||||
elna_tac_instruction_set_operand(load_instruction, 1, operand^.kind, operand^.value, operand^.length);
|
elna_tac_make_variable(operand, symbol_table, word_type);
|
||||||
elna_tac_instruction_set_operand(load_instruction, 2, operand^.kind, operand^.value, operand^.length);
|
|
||||||
|
|
||||||
|
load_instruction := elna_tac_instruction_create(ElnaTacOperator.load);
|
||||||
|
elna_tac_instruction_set_operand(load_instruction, 1, intermediate.kind, intermediate.value, intermediate.length);
|
||||||
|
elna_tac_instruction_set_operand(load_instruction, 2, operand^.kind, operand^.value, operand^.length);
|
||||||
elna_list_append(instructions, load_instruction)
|
elna_list_append(instructions, load_instruction)
|
||||||
elsif operand_result.kind = ElnaTacOperandType.sub_object then
|
elsif operand_result.kind = ElnaTacOperandType.sub_object then
|
||||||
|
memcpy(@intermediate, operand, #size(ElnaTacOperand));
|
||||||
|
elna_tac_make_variable(operand, symbol_table, word_type);
|
||||||
|
|
||||||
load_instruction := elna_tac_instruction_create(ElnaTacOperator.copy_from_offset);
|
load_instruction := elna_tac_instruction_create(ElnaTacOperator.copy_from_offset);
|
||||||
elna_tac_instruction_set_operand(load_instruction, 1, operand^.kind, operand^.value, operand^.length);
|
elna_tac_instruction_set_operand(load_instruction, 1, intermediate.kind, intermediate.value, intermediate.length);
|
||||||
elna_tac_instruction_set_operand(load_instruction, 2, ElnaTacKind.constant, operand_result.offset, 0);
|
elna_tac_instruction_set_operand(load_instruction, 2, ElnaTacKind.constant, operand_result.offset, 0);
|
||||||
elna_tac_instruction_set_operand(load_instruction, 3, operand^.kind, operand^.value, operand^.length);
|
elna_tac_instruction_set_operand(load_instruction, 3, operand^.kind, operand^.value, operand^.length);
|
||||||
elna_list_append(instructions, load_instruction)
|
elna_list_append(instructions, load_instruction)
|
||||||
|
|||||||
Reference in New Issue
Block a user