Do not generate pseudo variables for literals and local variables

This commit is contained in:
2026-02-26 21:24:19 +01:00
parent 68a305b00b
commit 63ecc4e71b

View File

@@ -470,7 +470,8 @@ type
jump_if_zero, jump_if_zero,
jump_if_not_zero, jump_if_not_zero,
label, label,
_return _return,
noop
); );
ElnaTacKind = (list, immediate, symbol, pseudo); ElnaTacKind = (list, immediate, symbol, pseudo);
ElnaTacOperand = record ElnaTacOperand = record
@@ -526,7 +527,8 @@ type
bnez, bnez,
label, label,
allocate_stack, allocate_stack,
ret ret,
noop
); );
ElnaRtlKind = (register, immediate, symbol, pseudo, offset, pseudo_mem); ElnaRtlKind = (register, immediate, symbol, pseudo, offset, pseudo_mem);
ElnaRtlOperand = record ElnaRtlOperand = record
@@ -990,6 +992,35 @@ begin
elna_list_append(instructions, instruction) elna_list_append(instructions, instruction)
end; end;
proc elna_rtl_call_parameter(instructions: ^ElnaList, current_argument: ^ElnaTacOperand, into: ElnaRtlRegister);
var
instruction: ^ElnaRtlInstruction;
begin
if current_argument^.kind = ElnaTacKind.pseudo then
instruction := elna_rtl_instruction_create(ElnaRtlOperator.move);
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0);
elna_rtl_instruction_set_operand(instruction, 2, ElnaTacKind.pseudo,
current_argument^.value, current_argument^.length)
elsif current_argument^.kind = ElnaTacKind.immediate then
instruction := elna_rtl_instruction_create(ElnaRtlOperator.li);
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0);
elna_rtl_instruction_set_operand(instruction, 2, ElnaTacKind.immediate,
current_argument^.value, current_argument^.length)
elsif current_argument^.kind = ElnaTacKind.symbol then
instruction := elna_rtl_instruction_create(ElnaRtlOperator.la);
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0);
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.symbol,
current_argument^.value, current_argument^.length);
elna_list_append(instructions, instruction);
instruction := elna_rtl_instruction_create(ElnaRtlOperator.lw);
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0);
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, into, 0);
elna_list_append(instructions, instruction)
end;
elna_list_append(instructions, instruction)
end;
proc elna_rtl_call(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable); proc elna_rtl_call(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable);
var var
argument_count: Word; argument_count: Word;
@@ -1007,24 +1038,7 @@ begin
if argument_count > 0 then if argument_count > 0 then
argument_count := argument_count - 1; argument_count := argument_count - 1;
if current_argument^.kind = ElnaTacKind.pseudo then elna_rtl_call_parameter(instructions, current_argument, ElnaRtlRegister.a0 + current_register);
variable_info := elna_symbol_table_lookup(variable_map, current_argument^.value, current_argument^.length);
if variable_info^.rtl_type^.size <= 4 then
instruction := elna_rtl_instruction_create(ElnaRtlOperator.move);
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a0 + current_register, 0);
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo,
current_argument^.value, current_argument^.length)
elsif variable_info^.rtl_type^.size <= 8 then
instruction := elna_rtl_instruction_create(ElnaRtlOperator.move);
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a0 + current_register, 0);
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo,
current_argument^.value, current_argument^.length)
end
end;
elna_list_append(instructions, instruction);
current_argument := current_argument + #size(ElnaTacOperand); current_argument := current_argument + #size(ElnaTacOperand);
current_register := current_register + 1; current_register := current_register + 1;
@@ -1148,6 +1162,11 @@ begin
elna_tac_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.t4, 0); elna_tac_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.t4, 0);
elna_list_append(instructions, instruction) elna_list_append(instructions, instruction)
end end
elsif tac_instruction^.operator = ElnaTacOperator.noop then
instruction := elna_rtl_instruction_create(ElnaRtlOperator.noop);
elna_rtl_copy_operand(tac_instruction, 1, instruction);
elna_rtl_copy_operand(tac_instruction, 2, instruction);
elna_list_append(instructions, instruction)
end end
end; end;
@@ -1469,6 +1488,15 @@ begin
(* Write the epilogue. *) (* Write the epilogue. *)
printf("\tlw ra, %i(sp)\n\tlw s0, %i(sp)\n\taddi sp, sp, %i\n\0", operand_value + 4, operand_value, operand_value + 8); printf("\tlw ra, %i(sp)\n\tlw s0, %i(sp)\n\taddi sp, sp, %i\n\0", operand_value + 4, operand_value, operand_value + 8);
fflush(nil) fflush(nil)
elsif instruction^.operator = ElnaRtlOperator.noop then
operand_value := instruction^.operands[2].value;
if operand_value = 0 then
printf("# Debug start\n\0");
else
printf("# Debug end\n\0");
end;
fflush(nil)
else else
argument_count := elna_riscv_instruction_name(instruction^.operator) argument_count := elna_riscv_instruction_name(instruction^.operator)
end; end;
@@ -2009,17 +2037,14 @@ begin
elna_tac_instruction_set_operand(instruction, 1, base.kind, base.value, base.length); elna_tac_instruction_set_operand(instruction, 1, base.kind, base.value, base.length);
elna_tac_instruction_set_operand(instruction, 2, operand^.kind, operand^.value, operand^.length); elna_tac_instruction_set_operand(instruction, 2, operand^.kind, operand^.value, operand^.length);
elna_list_append(instructions, instruction) elna_list_append(instructions, instruction)
elsif base.kind = ElnaTacKind.pseudo then else
(* Debug
printf("# Here %i %.*s\n\0", base.value, base.length, base.value);
fflush(nil); *)
operand^.kind := base.kind; operand^.kind := base.kind;
operand^.value := base.value; operand^.value := base.value;
operand^.length := base.length operand^.length := base.length
else
elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table);
instruction := elna_tac_instruction_create(ElnaTacOperator.copy);
elna_tac_instruction_set_operand(instruction, 1, operand^.kind, operand^.value, operand^.length);
elna_tac_instruction_set_operand(instruction, 2, base.kind, base.value, base.length);
elna_list_append(instructions, instruction)
end end
end; end;