Make designator independent of hardware registers

This commit is contained in:
2025-12-29 00:33:32 +01:00
parent b4eabfae4e
commit 3db3a0f20e

View File

@@ -1070,11 +1070,6 @@ begin
if operand_type = ElnaTacOperand.symbol then
result := elna_rtl_instruction_create(ElnaRtlOperator.la);
elna_rtl_copy_operand(tac_instruction, 1, result);
elna_rtl_copy_operand(tac_instruction, 2, result)
elsif operand_type = ElnaTacOperand.temporary then
result := elna_rtl_instruction_create(ElnaRtlOperator.move);
elna_rtl_copy_operand(tac_instruction, 1, result);
elna_rtl_copy_operand(tac_instruction, 2, result)
elsif operand_type = ElnaTacOperand.pseudo then
@@ -1088,13 +1083,7 @@ begin
elsif instruction_kind = ElnaTacOperator.load then
operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, 2);
if operand_type = ElnaTacOperand.temporary then
result := elna_rtl_instruction_create(ElnaRtlOperator.lw);
elna_rtl_copy_operand(tac_instruction, 1, result);
operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2);
elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.offset, operand_value, 0)
elsif operand_type = ElnaTacOperand.pseudo then
if operand_type = ElnaTacOperand.pseudo then
operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2);
operand_length := _elna_tac_instruction_get_operand_length(tac_instruction, 2);
@@ -1424,6 +1413,81 @@ begin
end
end;
proc elna_alloc_load_address(instruction: ^ElnaInstructionList);
var
operand_type: Word;
operand_value: Word;
operand_length: Word;
pseudo_symbol: Word;
begin
operand_type := elna_rtl_instruction_get_operand_type(instruction, 2);
operand_value := elna_rtl_instruction_get_operand_value(instruction, 2);
operand_length := elna_rtl_instruction_get_operand_length(instruction, 2);
if operand_type = ElnaRtlOperand.pseudo then
pseudo_symbol := elna_alloc_variable(operand_value, operand_length);
elna_rtl_instruction_set_kind(instruction, ElnaRtlOperator.addi);
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlOperand.register, ElnaRtlRegister.sp, 0);
elna_rtl_instruction_set_operand(instruction, 3, ElnaRtlOperand.immediate, pseudo_symbol, 0)
end;
operand_type := elna_rtl_instruction_get_operand_type(instruction, 1);
if operand_type = ElnaRtlOperand.pseudo then
elna_alloc_operation_target(instruction)
end
end;
proc elna_alloc_load_store(instruction: ^ElnaInstructionList);
var
old_instruction: ^ElnaInstructionList;
operand_type: Word;
operand_value: Word;
operand_length: Word;
pseudo_symbol: Word;
begin
operand_type := elna_rtl_instruction_get_operand_type(instruction, 1);
operand_value := elna_rtl_instruction_get_operand_value(instruction, 1);
operand_length := elna_rtl_instruction_get_operand_length(instruction, 1);
if operand_type = ElnaRtlOperand.pseudo then
old_instruction := malloc(elna_rtl_instruction_size());
memcpy(old_instruction, instruction, elna_rtl_instruction_size());
pseudo_symbol := elna_alloc_variable(operand_value, operand_length);
elna_rtl_instruction_set_kind(instruction, ElnaRtlOperator.lw);
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlOperand.register, ElnaRtlRegister.t1, 0);
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, pseudo_symbol);
instruction^.next := old_instruction;
elna_rtl_instruction_set_operand(old_instruction, 1, ElnaRtlOperand.register, ElnaRtlRegister.t1, 0);
goto elna_alloc_load_store_end
end;
operand_type := elna_rtl_instruction_get_operand_type(instruction, 2);
operand_value := elna_rtl_instruction_get_operand_value(instruction, 2);
operand_length := elna_rtl_instruction_get_operand_length(instruction, 2);
if operand_type = ElnaRtlOperand.pseudo then
old_instruction := malloc(elna_rtl_instruction_size());
memcpy(old_instruction, instruction, elna_rtl_instruction_size());
pseudo_symbol := elna_alloc_variable(operand_value, operand_length);
elna_rtl_instruction_set_kind(instruction, ElnaRtlOperator.lw);
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlOperand.register, ElnaRtlRegister.t1, 0);
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, pseudo_symbol);
instruction^.next := old_instruction;
elna_rtl_instruction_set_operand(old_instruction, 2, ElnaRtlOperand.offset, ElnaRtlRegister.t1, 0);
goto elna_alloc_load_store_end
end;
.elna_alloc_load_store_end
end;
proc elna_alloc_instruction(instruction: ^ElnaInstructionList);
var
instruction_kind: Word;
@@ -1466,41 +1530,11 @@ begin
goto elna_alloc_instruction_end
end
elsif instruction_kind = ElnaRtlOperator.la then
operand_type := elna_rtl_instruction_get_operand_type(instruction, 2);
operand_value := elna_rtl_instruction_get_operand_value(instruction, 2);
operand_length := elna_rtl_instruction_get_operand_length(instruction, 2);
if operand_type = ElnaRtlOperand.pseudo then
pseudo_symbol := elna_alloc_variable(operand_value, operand_length);
elna_rtl_instruction_set_kind(instruction, ElnaRtlOperator.addi);
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlOperand.register, ElnaRtlRegister.sp, 0);
elna_rtl_instruction_set_operand(instruction, 3, ElnaRtlOperand.immediate, pseudo_symbol, 0);
goto elna_alloc_instruction_end
end;
elna_alloc_operation_target(instruction)
elna_alloc_load_address(instruction)
elsif instruction_kind = ElnaRtlOperator.lw then
elna_alloc_load_store(instruction)
elsif instruction_kind = ElnaRtlOperator.sw then
operand_type := elna_rtl_instruction_get_operand_type(instruction, 2);
operand_value := elna_rtl_instruction_get_operand_value(instruction, 2);
operand_length := elna_rtl_instruction_get_operand_length(instruction, 2);
if operand_type = ElnaRtlOperand.pseudo then
old_instruction := malloc(elna_rtl_instruction_size());
memcpy(old_instruction, instruction, elna_rtl_instruction_size());
pseudo_symbol := elna_alloc_variable(operand_value, operand_length);
elna_rtl_instruction_set_kind(instruction, ElnaRtlOperator.lw);
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0);
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, pseudo_symbol);
instruction^.next := old_instruction;
elna_rtl_instruction_set_operand(old_instruction, 2, ElnaRtlOperand.offset, ElnaRtlRegister.t2, 0);
goto elna_alloc_instruction_end
end
elna_alloc_load_store(instruction)
elsif instruction_kind = ElnaRtlOperator._or then
elna_alloc_operation_target(instruction)
elsif instruction_kind = ElnaRtlOperator.and then
@@ -1941,18 +1975,18 @@ begin
offset := _add_string(string_literal_node^.value);
first_instruction := _elna_tac_instruction_create(ElnaTacOperator.get_address);
_elna_tac_instruction_set_operand(first_instruction, 1, ElnaTacOperand.temporary, 6, 0);
_elna_tac_instruction_set_operand(first_instruction, 1, ElnaTacOperand.pseudo, "$unary", 6);
_elna_tac_instruction_set_operand(first_instruction, 2, ElnaTacOperand.symbol, "strings", 7);
(* Add offset to the string block pointer. *)
next_instruction := _elna_tac_instruction_create(ElnaTacOperator.add);
_elna_tac_instruction_set_operand(next_instruction, 1, ElnaTacOperand.temporary, 6, 0);
_elna_tac_instruction_set_operand(next_instruction, 2, ElnaTacOperand.temporary, 6, 0);
_elna_tac_instruction_set_operand(next_instruction, 1, ElnaTacOperand.pseudo, "$unary", 6);
_elna_tac_instruction_set_operand(next_instruction, 2, ElnaTacOperand.pseudo, "$unary", 6);
_elna_tac_instruction_set_operand(next_instruction, 3, ElnaTacOperand.immediate, offset, 0);
operand_type^ := ElnaTacOperand.temporary;
operand_value^ := 6;
operand_length^ := 0;
operand_type^ := ElnaTacOperand.pseudo;
operand_value^ := "$unary";
operand_length^ := 6;
return elna_instruction_list_concatenate(first_instruction, next_instruction)
end;
@@ -2076,76 +2110,75 @@ end;
proc elna_tac_unary_expression(parser_node: ^ElnaTreeUnaryExpression, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word);
var
current_character: Word;
token_kind: Word;
operator: Word;
operand: Word;
is_address: Word;
first_instruction: Word;
instruction: Word;
temp: Word;
begin
operator := 0;
operand := 0;
instruction := nil;
if parser_node^.kind = ElnaTreeKind.unary_expression then
operator := parser_node^.operator;
operand := parser_node^.operand
else
operator := 0;
operand := parser_node
end;
first_instruction := elna_tac_designator(operand, symbol_table, @is_address, operand_type, operand_value, operand_length);
if operator = '@' then
first_instruction := elna_tac_designator(operand, symbol_table, @is_address, operand_type, operand_value, operand_length);
instruction := _elna_tac_instruction_create(ElnaTacOperator.get_address);
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 6, 0);
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.pseudo, "$unary", 6);
_elna_tac_instruction_set_operand(instruction, 2, operand_type^, operand_value^, operand_length^);
operand_type^ := ElnaTacOperand.temporary;
operand_value^ := 6;
operand_length^ := 0;
operand_type^ := ElnaTacOperand.pseudo;
operand_value^ := "$unary";
operand_length^ := 6
elsif operator = '-' then
instruction := _elna_tac_instruction_create(ElnaTacOperator.negate);
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.pseudo, "$unary", 6);
_elna_tac_instruction_set_operand(instruction, 2, operand_type^, operand_value^, operand_length^);
first_instruction := elna_instruction_list_concatenate(first_instruction, instruction)
else
current_character := operand_type^;
first_instruction := elna_tac_designator(operand, symbol_table, @is_address, operand_type, operand_value, operand_length);
operand := operand_type^;
operand_type^ := ElnaTacOperand.pseudo;
operand_value^ := "$unary";
operand_length^ := 6
elsif operator = '~' then
instruction := _elna_tac_instruction_create(ElnaTacOperator.complement);
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.pseudo, "$unary", 6);
_elna_tac_instruction_set_operand(instruction, 2, operand_type^, operand_value^, operand_length^);
if is_address then
operand_type^ := ElnaTacOperand.pseudo;
operand_value^ := "$unary";
operand_length^ := 6
elsif is_address then
if operand_type^ = ElnaTacOperand.pseudo then
instruction := _elna_tac_instruction_create(ElnaTacOperator.load);
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 6, 0);
_elna_tac_instruction_set_operand(instruction, 2, operand_type^, operand_value^, operand_length^);
operand_type^ := ElnaTacOperand.temporary;
operand_value^ := 6;
operand_length^ := 0;
elna_instruction_list_concatenate(first_instruction, instruction)
elsif operator = 0 then
instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 6, 0);
operand_length^ := 0
else
instruction := _elna_tac_instruction_create(ElnaTacOperator.load);
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.pseudo, "$unary", 6);
_elna_tac_instruction_set_operand(instruction, 2, operand_type^, operand_value^, operand_length^);
operand_type^ := ElnaTacOperand.temporary;
operand_value^ := 6;
operand_length^ := 0;
first_instruction := elna_instruction_list_concatenate(first_instruction, instruction)
operand_type^ := ElnaTacOperand.pseudo;
operand_value^ := "$unary";
operand_length^ := 6
end
end;
if operator = '-' then
instruction := _elna_tac_instruction_create(ElnaTacOperator.negate);
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 6, 0);
else
instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.pseudo, "$unary", 6);
_elna_tac_instruction_set_operand(instruction, 2, operand_type^, operand_value^, operand_length^);
elna_instruction_list_concatenate(first_instruction, instruction)
elsif operator = '~' then
instruction := _elna_tac_instruction_create(ElnaTacOperator.complement);
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 6, 0);
_elna_tac_instruction_set_operand(instruction, 2, operand_type^, operand_value^, operand_length^);
elna_instruction_list_concatenate(first_instruction, instruction)
operand_type^ := ElnaTacOperand.pseudo;
operand_value^ := "$unary";
operand_length^ := 6
end;
return first_instruction
return elna_instruction_list_concatenate(first_instruction, instruction)
end;
proc elna_parser_binary_expression();
@@ -2601,15 +2634,15 @@ begin
first_instruction := elna_tac_designator(dereference_expression^.pointer, symbol_table, is_address, operand_type, operand_value, operand_length);
last_instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
_elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.temporary, 6, 0);
_elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.pseudo, "$unary", 6);
_elna_tac_instruction_set_operand(last_instruction, 2, operand_type^, operand_value^, operand_length^);
operand_type^ := ElnaTacOperand.temporary;
operand_value^ := 6;
operand_length^ := 0;
operand_type^ := ElnaTacOperand.pseudo;
operand_value^ := "$unary";
operand_length^ := 6;
is_address^ := 1;
first_instruction := elna_instruction_list_concatenate(first_instruction, last_instruction)
first_instruction := elna_instruction_list_concatenate(first_instruction, last_instruction);
elsif parser_node^.kind = ElnaTreeKind.field_access_expression then
field_access_expression := parser_node;
expression_type := field_access_expression^.type_decoration;
@@ -2635,13 +2668,13 @@ begin
goto elna_tac_designator_field
end;
last_instruction := _elna_tac_instruction_create(ElnaTacOperator.add);
_elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.temporary, 6, 0);
_elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.pseudo, "$unary", 6);
_elna_tac_instruction_set_operand(last_instruction, 2, ElnaTacOperand.immediate, field_offset, 0);
_elna_tac_instruction_set_operand(last_instruction, 3, operand_type^, operand_value^, operand_length^);
operand_type^ := ElnaTacOperand.temporary;
operand_value^ := 6;
operand_length^ := 0;
operand_type^ := ElnaTacOperand.pseudo;
operand_value^ := "$unary";
operand_length^ := 6;
is_address^ := 1;
first_instruction := elna_instruction_list_concatenate(first_instruction, last_instruction)
@@ -2696,6 +2729,30 @@ begin
first_instruction := elna_tac_designator(parser_tree^.assignee, symbol_table, @is_address, @operand_type, @operand_value, @operand_length);
if operand_type = ElnaTacOperand.pseudo then
if is_address then
(* Save the assignee address on the stack. *)
current_instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
_elna_tac_instruction_set_operand(current_instruction, 1, ElnaTacOperand.pseudo, "$assign", 7);
_elna_tac_instruction_set_operand(current_instruction, 2, operand_type, operand_value, operand_length);
first_instruction := elna_instruction_list_concatenate(first_instruction, current_instruction);
(* Compile the assignment. *)
operand_type := 0;
operand_value := 0;
operand_length := 0;
instruction := elna_tac_binary_expression(parser_tree^.assignment, symbol_table, @operand_type, @operand_value, @operand_length);
if instruction <> 0 then
elna_instruction_list_concatenate(current_instruction, instruction);
current_instruction := instruction
end;
instruction := _elna_tac_instruction_create(ElnaTacOperator.store);
_elna_tac_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length);
_elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.pseudo, "$assign", 7);
elna_instruction_list_concatenate(current_instruction, instruction)
else
current_instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
_elna_tac_instruction_set_operand(current_instruction, 1, operand_type, operand_value, operand_length);
@@ -2706,6 +2763,7 @@ begin
_elna_tac_instruction_set_operand(current_instruction, 2, operand_type, operand_value, operand_length);
first_instruction := elna_instruction_list_concatenate(instruction, current_instruction)
end
else
(* Save the assignee address on the stack. *)
current_instruction := _elna_tac_instruction_create(ElnaTacOperator.get_address);
@@ -2728,7 +2786,7 @@ begin
_elna_tac_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length);
_elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.pseudo, "$assign", 7);
elna_instruction_list_concatenate(current_instruction, instruction);
elna_instruction_list_concatenate(current_instruction, instruction)
end;
return first_instruction
end;