Accept pseudo registers in the move instruction

This commit is contained in:
2026-03-17 17:24:27 +01:00
parent 953447dc23
commit 5fb3c910a6

View File

@@ -535,7 +535,7 @@ type
lw, lw,
sw, sw,
jal, jal,
move, mv,
sub, sub,
div, div,
rem, rem,
@@ -912,7 +912,7 @@ begin
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0); elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0);
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, into, 0) elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, into, 0)
else else
instruction := elna_rtl_instruction_create(ElnaRtlOperator.move); instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv);
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0); elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0);
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo, operand^.value, operand^.length) elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo, operand^.value, operand^.length)
end; end;
@@ -1108,7 +1108,7 @@ begin
tac_instruction^.operands[1].value, tac_instruction^.operands[1].length); tac_instruction^.operands[1].value, tac_instruction^.operands[1].length);
elna_list_append(instructions, instruction); elna_list_append(instructions, instruction);
instruction := elna_rtl_instruction_create(ElnaRtlOperator.move); instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv);
elna_rtl_instruction_set_operand(instruction, 1, tac_instruction^.operands[3].kind, elna_rtl_instruction_set_operand(instruction, 1, tac_instruction^.operands[3].kind,
tac_instruction^.operands[3].value, tac_instruction^.operands[3].length); tac_instruction^.operands[3].value, tac_instruction^.operands[3].length);
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.a0, 0); elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.a0, 0);
@@ -1143,11 +1143,26 @@ begin
elna_list_append(instructions, instruction) elna_list_append(instructions, instruction)
end; end;
proc elna_rtl_copy(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable);
var
instruction: ^ElnaRtlInstruction;
rtl_operand: ElnaRtlOperand;
begin
if tac_instruction^.operands[1].kind = ElnaTacKind.variable then
elna_rtl_operand_value(instructions, @tac_instruction^.operands[2], variable_map, @rtl_operand);
instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv);
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo,
tac_instruction^.operands[1].value, tac_instruction^.operands[1].length);
elna_rtl_instruction_set_operand(instruction, 2, rtl_operand.kind, rtl_operand.value, rtl_operand.length);
elna_list_append(instructions, instruction);
end
end;
proc elna_rtl_instruction(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable); proc elna_rtl_instruction(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable);
var var
instruction: ^ElnaRtlInstruction; instruction: ^ElnaRtlInstruction;
pseudo_symbol: ^ElnaRtlInfo; pseudo_symbol: ^ElnaRtlInfo;
rtl_operand: ElnaRtlOperand;
begin begin
if tac_instruction^.operator = ElnaTacOperator.get_address then if tac_instruction^.operator = ElnaTacOperator.get_address then
pseudo_symbol := elna_symbol_table_lookup(variable_map, pseudo_symbol := elna_symbol_table_lookup(variable_map,
@@ -1218,15 +1233,7 @@ begin
tac_instruction^.operands[1].value, tac_instruction^.operands[1].length); tac_instruction^.operands[1].value, tac_instruction^.operands[1].length);
elna_list_append(instructions, instruction) elna_list_append(instructions, instruction)
elsif tac_instruction^.operator = ElnaTacOperator.copy then elsif tac_instruction^.operator = ElnaTacOperator.copy then
if tac_instruction^.operands[1].kind = ElnaTacKind.variable then elna_rtl_copy(instructions, tac_instruction, variable_map)
elna_rtl_load_operand_value(instructions, @tac_instruction^.operands[2], ElnaRtlRegister.t4, variable_map);
instruction := elna_rtl_instruction_create(ElnaRtlOperator.move);
elna_tac_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo,
tac_instruction^.operands[1].value, tac_instruction^.operands[1].length);
elna_tac_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.t4, 0);
elna_list_append(instructions, instruction)
end
elsif tac_instruction^.operator = ElnaTacOperator.nop then elsif tac_instruction^.operator = ElnaTacOperator.nop then
instruction := elna_rtl_instruction_create(ElnaRtlOperator.nop); instruction := elna_rtl_instruction_create(ElnaRtlOperator.nop);
elna_tac_instruction_set_operand(instruction, 1, tac_instruction^.operands[1].kind, elna_tac_instruction_set_operand(instruction, 1, tac_instruction^.operands[1].kind,
@@ -1271,7 +1278,7 @@ begin
elsif instruction_kind = ElnaRtlOperator.jal then elsif instruction_kind = ElnaRtlOperator.jal then
argument_count := 1; argument_count := 1;
_write_s("\tcall", 5) _write_s("\tcall", 5)
elsif instruction_kind = ElnaRtlOperator.move then elsif instruction_kind = ElnaRtlOperator.mv then
argument_count := 2; argument_count := 2;
_write_s("\tmv", 3) _write_s("\tmv", 3)
elsif instruction_kind = ElnaRtlOperator.sub then elsif instruction_kind = ElnaRtlOperator.sub then
@@ -1477,33 +1484,45 @@ begin
return elna_alloc_operation_target(instructions, instruction, variable_map) return elna_alloc_operation_target(instructions, instruction, variable_map)
end; end;
proc elna_alloc_move(instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable); proc elna_alloc_move(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable);
var var
pseudo_symbol: ^ElnaRtlInfo; pseudo_symbol: ^ElnaRtlInfo;
destination_pseudo: Word;
source_pseudo: Word;
begin begin
if instruction^.operands[1].kind = ElnaRtlKind.pseudo then destination_pseudo := instruction^.operands[1].kind = ElnaRtlKind.pseudo;
source_pseudo := instruction^.operands[2].kind = ElnaRtlKind.pseudo;
if destination_pseudo & source_pseudo then
instruction := elna_alloc_operand(instructions, instruction, 2, ElnaRtlRegister.t4, variable_map);
pseudo_symbol := elna_alloc_variable(instruction^.operands[1].value, instruction^.operands[1].length,
variable_map);
instruction^.operator = ElnaRtlOperator.sw;
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t4, 0);
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol^.counter)
elsif destination_pseudo then
pseudo_symbol := elna_alloc_variable(instruction^.operands[1].value, instruction^.operands[1].length, pseudo_symbol := elna_alloc_variable(instruction^.operands[1].value, instruction^.operands[1].length,
variable_map); variable_map);
instruction^.operator = ElnaRtlOperator.sw; instruction^.operator = ElnaRtlOperator.sw;
if pseudo_symbol = nil then elna_rtl_instruction_set_operand(instruction, 1, instruction^.operands[2].kind,
elna_rtl_instruction_set_operand(instruction, 1, instruction^.operands[2].kind, instruction^.operands[2].value, instruction^.operands[2].length);
instruction^.operands[2].value, instruction^.operands[2].length); elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol^.counter)
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.symbol, elsif source_pseudo then
instruction^.operands[1].value, instruction^.operands[1].length)
else
elna_rtl_instruction_set_operand(instruction, 1, instruction^.operands[2].kind,
instruction^.operands[2].value, instruction^.operands[2].length);
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol^.counter)
end;
elsif instruction^.operands[2].kind = ElnaRtlKind.pseudo then
pseudo_symbol := elna_alloc_variable(instruction^.operands[2].value, instruction^.operands[2].length, pseudo_symbol := elna_alloc_variable(instruction^.operands[2].value, instruction^.operands[2].length,
variable_map); variable_map);
instruction^.operator = ElnaRtlOperator.lw; instruction^.operator = ElnaRtlOperator.lw;
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol^.counter) elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol^.counter)
end end;
return instruction
end; end;
(**
* Move the operand value from the pseudo register into a hardware register if needed.
* If copying requires an additional instruction inserts the instruction before the
* current instruction and returns the new current instruction.
*)
proc elna_alloc_operand(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, proc elna_alloc_operand(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction,
number: Word, target: ElnaRtlRegister, variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; number: Word, target: ElnaRtlRegister, variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction;
var var
@@ -1553,8 +1572,8 @@ var
pseudo_symbol: ^ElnaRtlInfo; pseudo_symbol: ^ElnaRtlInfo;
new_instruction: ^ElnaRtlInstruction; new_instruction: ^ElnaRtlInstruction;
begin begin
if instruction^.operator = ElnaRtlOperator.move then if instruction^.operator = ElnaRtlOperator.mv then
elna_alloc_move(instruction, variable_map) instruction := elna_alloc_move(instructions, instruction, variable_map)
elsif instruction^.operator = ElnaRtlOperator.la then elsif instruction^.operator = ElnaRtlOperator.la then
elna_alloc_load_address(instructions, instruction, variable_map) elna_alloc_load_address(instructions, instruction, variable_map)
elsif instruction^.operator = ElnaRtlOperator.lw then elsif instruction^.operator = ElnaRtlOperator.lw then
@@ -3558,7 +3577,7 @@ begin
name_length := parameters^; name_length := parameters^;
parameters := parameters + 4; parameters := parameters + 4;
instruction := elna_rtl_instruction_create(ElnaRtlOperator.move); instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv);
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo, parameter_name, name_length); elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo, parameter_name, name_length);
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, 11 + parameter_index, 0); elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, 11 + parameter_index, 0);
elna_list_append(instructions, instruction); elna_list_append(instructions, instruction);