summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--boot/stage20/cl.elna81
1 files 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);