summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2025-12-29 00:33:32 +0100
committerEugen Wissner <belka@caraus.de>2025-12-29 00:33:32 +0100
commit3db3a0f20e37ba4a9973f9fe9fb9a61df25391f8 (patch)
tree169655632fcc8ab42bb37764bf32464ccfeaf264
parentb4eabfae4ea668596c098a5b8859f3de0fe0762f (diff)
downloadelna-3db3a0f20e37ba4a9973f9fe9fb9a61df25391f8.tar.gz
Make designator independent of hardware registers
-rw-r--r--boot/stage17/cl.elna276
1 files changed, 167 insertions, 109 deletions
diff --git a/boot/stage17/cl.elna b/boot/stage17/cl.elna
index c2205a1..ac4ceaa 100644
--- a/boot/stage17/cl.elna
+++ b/boot/stage17/cl.elna
@@ -1072,11 +1072,6 @@ begin
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
result := elna_rtl_instruction_create(ElnaRtlOperator.la);
@@ -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);
- _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);
+ 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)
+
+ 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,16 +2729,41 @@ 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
- current_instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
- _elna_tac_instruction_set_operand(current_instruction, 1, operand_type, operand_value, operand_length);
+ 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;
- 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);
- _elna_tac_instruction_set_operand(current_instruction, 2, operand_type, operand_value, operand_length);
+ 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);
- first_instruction := elna_instruction_list_concatenate(instruction, current_instruction)
+ 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);
+ _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;