From 5fb3c910a6a05e1d85f837193a9221bc5ac5f4a6 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Tue, 17 Mar 2026 17:24:27 +0100 Subject: [PATCH] Accept pseudo registers in the move instruction --- boot/stage20/cl.elna | 81 +++++++++++++++++++++++++++----------------- 1 file changed, 50 insertions(+), 31 deletions(-) diff --git a/boot/stage20/cl.elna b/boot/stage20/cl.elna index 64e1fb9..d0d3adc 100644 --- a/boot/stage20/cl.elna +++ b/boot/stage20/cl.elna @@ -535,7 +535,7 @@ type lw, sw, jal, - move, + mv, sub, div, rem, @@ -912,7 +912,7 @@ begin elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0); elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, into, 0) 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, 2, ElnaRtlKind.pseudo, operand^.value, operand^.length) end; @@ -1108,7 +1108,7 @@ begin tac_instruction^.operands[1].value, tac_instruction^.operands[1].length); 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, tac_instruction^.operands[3].value, tac_instruction^.operands[3].length); elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.a0, 0); @@ -1143,11 +1143,26 @@ begin elna_list_append(instructions, instruction) 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); var instruction: ^ElnaRtlInstruction; pseudo_symbol: ^ElnaRtlInfo; - rtl_operand: ElnaRtlOperand; begin if tac_instruction^.operator = ElnaTacOperator.get_address then pseudo_symbol := elna_symbol_table_lookup(variable_map, @@ -1218,15 +1233,7 @@ begin tac_instruction^.operands[1].value, tac_instruction^.operands[1].length); elna_list_append(instructions, instruction) elsif tac_instruction^.operator = ElnaTacOperator.copy then - if tac_instruction^.operands[1].kind = ElnaTacKind.variable then - 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 + elna_rtl_copy(instructions, tac_instruction, variable_map) elsif tac_instruction^.operator = ElnaTacOperator.nop then instruction := elna_rtl_instruction_create(ElnaRtlOperator.nop); elna_tac_instruction_set_operand(instruction, 1, tac_instruction^.operands[1].kind, @@ -1271,7 +1278,7 @@ begin elsif instruction_kind = ElnaRtlOperator.jal then argument_count := 1; _write_s("\tcall", 5) - elsif instruction_kind = ElnaRtlOperator.move then + elsif instruction_kind = ElnaRtlOperator.mv then argument_count := 2; _write_s("\tmv", 3) elsif instruction_kind = ElnaRtlOperator.sub then @@ -1477,33 +1484,45 @@ begin return elna_alloc_operation_target(instructions, instruction, variable_map) end; -proc elna_alloc_move(instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable); +proc elna_alloc_move(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable); var pseudo_symbol: ^ElnaRtlInfo; + destination_pseudo: Word; + source_pseudo: Word; 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, variable_map); instruction^.operator = ElnaRtlOperator.sw; - if pseudo_symbol = nil then - 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.symbol, - 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 + 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) + elsif source_pseudo then pseudo_symbol := elna_alloc_variable(instruction^.operands[2].value, instruction^.operands[2].length, variable_map); instruction^.operator = ElnaRtlOperator.lw; elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol^.counter) - end + end; + return instruction 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, number: Word, target: ElnaRtlRegister, variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; var @@ -1553,8 +1572,8 @@ var pseudo_symbol: ^ElnaRtlInfo; new_instruction: ^ElnaRtlInstruction; begin - if instruction^.operator = ElnaRtlOperator.move then - elna_alloc_move(instruction, variable_map) + if instruction^.operator = ElnaRtlOperator.mv then + instruction := elna_alloc_move(instructions, instruction, variable_map) elsif instruction^.operator = ElnaRtlOperator.la then elna_alloc_load_address(instructions, instruction, variable_map) elsif instruction^.operator = ElnaRtlOperator.lw then @@ -3558,7 +3577,7 @@ begin name_length := parameters^; 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, 2, ElnaRtlKind.register, 11 + parameter_index, 0); elna_list_append(instructions, instruction);