Process global variables as pseudo in the move instruction

This commit is contained in:
2026-04-22 22:01:16 +02:00
parent f3ddf0d671
commit 89672f6d74

View File

@@ -917,11 +917,10 @@ end;
(** (**
* Loads or moves the value from a TAC operand into the given register. * Loads or moves the value from a TAC operand into the given register.
*) *)
proc elna_rtl_load_operand_value(instructions: ^ElnaList, operand: ^ElnaTacOperand, proc elna_rtl_hardware_value(instructions: ^ElnaList, operand: ^ElnaTacOperand,
into: ElnaRtlRegister, variable_map: ^ElnaSymbolTable); into: ElnaRtlRegister, variable_map: ^ElnaSymbolTable);
var var
instruction: ^ElnaRtlInstruction; instruction: ^ElnaRtlInstruction;
pseudo_symbol: ^ElnaRtlInfo;
begin begin
if operand^.kind = ElnaTacKind.constant then if operand^.kind = ElnaTacKind.constant then
instruction := elna_rtl_instruction_create(ElnaRtlOperator.li); instruction := elna_rtl_instruction_create(ElnaRtlOperator.li);
@@ -929,25 +928,14 @@ begin
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.immediate, operand^.value, operand^.length, 0); elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.immediate, operand^.value, operand^.length, 0);
elna_list_append(instructions, instruction) elna_list_append(instructions, instruction)
elsif operand^.kind = ElnaTacKind.variable then elsif operand^.kind = ElnaTacKind.variable then
pseudo_symbol := elna_symbol_table_lookup(variable_map, operand^.value, operand^.length);
if pseudo_symbol^.kind = ElnaRtlInfoKind.static_info then
instruction := elna_rtl_instruction_create(ElnaRtlOperator.la);
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0, 0);
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.data, operand^.value, operand^.length, 0);
elna_list_append(instructions, instruction);
instruction := elna_rtl_instruction_create(ElnaRtlOperator.lw);
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0, 0);
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.memory, into, 0, 0)
else
instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv); instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv);
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0, 0); elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0, 0);
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo, operand^.value, operand^.length, 0) elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo, operand^.value, operand^.length, 0);
end;
elna_list_append(instructions, instruction) elna_list_append(instructions, instruction)
end end
end; end;
proc elna_rtl_operand_value(instructions: ^ElnaList, tac_operand: ^ElnaTacOperand, variable_map: ^ElnaSymbolTable, proc elna_rtl_operand_value(instructions: ^ElnaList, tac_operand: ^ElnaTacOperand, variable_map: ^ElnaSymbolTable,
rtl_operand: ^ElnaRtlOperand) -> ^ElnaRtlInfo; rtl_operand: ^ElnaRtlOperand) -> ^ElnaRtlInfo;
var var
@@ -1183,7 +1171,7 @@ begin
if argument_count > 0 then if argument_count > 0 then
argument_count := argument_count - 1; argument_count := argument_count - 1;
elna_rtl_load_operand_value(instructions, current_argument, ElnaRtlRegister.a0 + current_register, variable_map); elna_rtl_hardware_value(instructions, current_argument, ElnaRtlRegister.a0 + current_register, variable_map);
current_argument := current_argument + 1; current_argument := current_argument + 1;
current_register := current_register + 1; current_register := current_register + 1;
@@ -1267,49 +1255,19 @@ 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); proc elna_rtl_memcpy(instructions: ^ElnaList, source_operand: ^ElnaRtlOperand, byte_array: ^ElnaRtlTypeByteArray,
target_type: Word, target_value: Word, target_length: Word);
var var
instruction: ^ElnaRtlInstruction; instruction: ElnaRtlInstruction;
source_operand: ElnaRtlOperand;
target_operand: ElnaRtlOperand;
pseudo_symbol: ^ElnaRtlObjectInfo;
byte_array: ^ElnaRtlTypeByteArray;
begin begin
elna_rtl_operand_value(instructions, @tac_instruction^.operands[1], variable_map, @source_operand);
pseudo_symbol := elna_symbol_table_lookup(variable_map,
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length);
if pseudo_symbol^.kind = ElnaRtlInfoKind.static_info then
elna_rtl_generate_pseudo(@target_operand, variable_map);
instruction := elna_rtl_instruction_create(ElnaRtlOperator.la);
elna_rtl_instruction_set_operand(instruction, 1, target_operand.kind, target_operand.value, target_operand.length, 0);
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.data,
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0);
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, 0);
elna_list_append(instructions, instruction)
elsif source_operand.kind = ElnaRtlKind.pseudo then
instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv);
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo,
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0);
elna_rtl_instruction_set_operand(instruction, 2, source_operand.kind, source_operand.value, source_operand.length, 0);
elna_list_append(instructions, instruction);
else
byte_array := pseudo_symbol^.rtl_type;
instruction := elna_rtl_instruction_create(ElnaRtlOperator.la); 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, 1, ElnaRtlKind.register, ElnaRtlRegister.a0, 0, 0);
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo, elna_rtl_instruction_set_operand(instruction, 2, target_type, target_value, target_length, 0);
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0);
elna_list_append(instructions, instruction); elna_list_append(instructions, instruction);
instruction := elna_rtl_instruction_create(ElnaRtlOperator.la); 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, 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_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);
instruction := elna_rtl_instruction_create(ElnaRtlOperator.li); instruction := elna_rtl_instruction_create(ElnaRtlOperator.li);
@@ -1320,6 +1278,27 @@ begin
instruction := elna_rtl_instruction_create(ElnaRtlOperator.jal); instruction := elna_rtl_instruction_create(ElnaRtlOperator.jal);
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.data, "memcpy", 6, 0); elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.data, "memcpy", 6, 0);
elna_list_append(instructions, instruction) elna_list_append(instructions, instruction)
end;
proc elna_rtl_copy(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable);
var
instruction: ^ElnaRtlInstruction;
source_operand: ElnaRtlOperand;
pseudo_symbol: ^ElnaRtlObjectInfo;
begin
elna_rtl_operand_value(instructions, @tac_instruction^.operands[1], variable_map, @source_operand);
pseudo_symbol := elna_symbol_table_lookup(variable_map,
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length);
if source_operand.kind = ElnaRtlKind.pseudo then
instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv);
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo,
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0);
elna_rtl_instruction_set_operand(instruction, 2, source_operand.kind, source_operand.value, source_operand.length, 0);
elna_list_append(instructions, instruction);
else
elna_rtl_memcpy(instructions, @source_operand, pseudo_symbol^.rtl_type, ElnaRtlKind.pseudo,
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length)
end end
end; end;
@@ -1383,7 +1362,7 @@ begin
elsif tac_instruction^.operator = ElnaTacOperator.jump_if_not_zero then elsif tac_instruction^.operator = ElnaTacOperator.jump_if_not_zero then
elna_rtl_conditional_jump(instructions, tac_instruction, ElnaRtlOperator.bnez, variable_map) elna_rtl_conditional_jump(instructions, tac_instruction, ElnaRtlOperator.bnez, variable_map)
elsif tac_instruction^.operator = ElnaTacOperator._return then elsif tac_instruction^.operator = ElnaTacOperator._return then
elna_rtl_load_operand_value(instructions, @tac_instruction^.operands[1], ElnaRtlRegister.a0, variable_map) elna_rtl_hardware_value(instructions, @tac_instruction^.operands[1], ElnaRtlRegister.a0, variable_map)
elsif tac_instruction^.operator = ElnaTacOperator.label then elsif tac_instruction^.operator = ElnaTacOperator.label then
instruction := elna_rtl_instruction_create(ElnaRtlOperator.label); instruction := elna_rtl_instruction_create(ElnaRtlOperator.label);
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.data, elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.data,
@@ -1652,37 +1631,87 @@ end;
proc elna_alloc_move(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, proc elna_alloc_move(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction,
variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction;
var var
load_instruction: ^ElnaRtlInstruction;
target_operand: ElnaRtlOperand;
pseudo_symbol: ^ElnaRtlObjectInfo; pseudo_symbol: ^ElnaRtlObjectInfo;
destination_pseudo: Word; destination_pseudo: Word;
source_pseudo: Word; source_pseudo: Word;
begin begin
memcpy(@target_operand, @instruction^.operands[1], #size(ElnaRtlOperand));
destination_pseudo := instruction^.operands[1].kind = ElnaRtlKind.pseudo; destination_pseudo := instruction^.operands[1].kind = ElnaRtlKind.pseudo;
source_pseudo := instruction^.operands[2].kind = ElnaRtlKind.pseudo; source_pseudo := instruction^.operands[2].kind = ElnaRtlKind.pseudo;
if destination_pseudo & source_pseudo then if destination_pseudo & source_pseudo then
pseudo_symbol := elna_symbol_table_lookup(variable_map, target_operand.value, target_operand.length);
instruction := elna_alloc_operand(instructions, instruction, 2, ElnaRtlRegister.t0, variable_map); instruction := elna_alloc_operand(instructions, instruction, 2, ElnaRtlRegister.t0, variable_map);
if pseudo_symbol^.kind = ElnaRtlInfoKind.static_info then
load_instruction := malloc(#size(ElnaRtlInstruction));
memcpy(load_instruction, instruction, #size(ElnaRtlInstruction));
load_instruction^.next := nil;
instruction^.operator = ElnaRtlOperator.la;
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t1, 0, 0);
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.data, target_operand.value, target_operand.length, 0);
elna_list_insert(instructions, instruction, load_instruction);
load_instruction^.operator = ElnaRtlOperator.sw;
elna_rtl_instruction_set_operand(load_instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t0, 0, 0);
elna_rtl_instruction_set_operand(load_instruction, 2, ElnaRtlKind.memory, ElnaRtlRegister.t1, 0, 0)
else
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;
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t0, 0, 0); elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t0, 0, 0);
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.memory, elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.memory,
ElnaRtlRegister.sp, 0, pseudo_symbol^.counter) ElnaRtlRegister.sp, 0, pseudo_symbol^.counter)
end
elsif destination_pseudo then elsif destination_pseudo then
pseudo_symbol := elna_alloc_variable(instruction^.operands[1].value, instruction^.operands[1].length, pseudo_symbol := elna_symbol_table_lookup(variable_map,
variable_map); instruction^.operands[1].value, instruction^.operands[1].length);
if pseudo_symbol^.kind = ElnaRtlInfoKind.static_info then
load_instruction := malloc(#size(ElnaRtlInstruction));
memcpy(load_instruction, instruction, #size(ElnaRtlInstruction));
load_instruction^.next := nil;
instruction^.operator = ElnaRtlOperator.la;
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t1, 0, 0);
elna_list_insert(instructions, instruction, load_instruction);
load_instruction^.operator = ElnaRtlOperator.sw;
elna_rtl_instruction_set_operand(load_instruction, 2, ElnaRtlKind.memory, ElnaRtlRegister.t1, 0, 0)
else
pseudo_symbol := elna_alloc_variable(target_operand.value, target_operand.length, variable_map);
instruction^.operator = ElnaRtlOperator.sw; instruction^.operator = ElnaRtlOperator.sw;
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, 0); instruction^.operands[2].value, instruction^.operands[2].length, 0);
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.memory, elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.memory,
ElnaRtlRegister.sp, 0, pseudo_symbol^.counter) ElnaRtlRegister.sp, 0, pseudo_symbol^.counter)
end
elsif source_pseudo then elsif source_pseudo then
pseudo_symbol := elna_symbol_table_lookup(variable_map,
instruction^.operands[2].value, instruction^.operands[2].length);
if pseudo_symbol^.kind = ElnaRtlInfoKind.static_info then
load_instruction := malloc(#size(ElnaRtlInstruction));
memcpy(load_instruction, instruction, #size(ElnaRtlInstruction));
load_instruction^.next := nil;
instruction^.operator := ElnaRtlOperator.la;
elna_list_insert(instructions, instruction, load_instruction);
load_instruction^.operator = ElnaRtlOperator.lw;
elna_rtl_instruction_set_operand(load_instruction, 2, ElnaRtlKind.memory,
instruction^.operands[1].value, instruction^.operands[1].length, 0)
else
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.memory, elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.memory,
ElnaRtlRegister.sp, 0, pseudo_symbol^.counter) ElnaRtlRegister.sp, 0, pseudo_symbol^.counter)
end
end; end;
return instruction return instruction
end; end;