Make designator independent of hardware registers
This commit is contained in:
@@ -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,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);
|
||||
|
||||
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);
|
||||
(* 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);
|
||||
|
||||
first_instruction := elna_instruction_list_concatenate(instruction, current_instruction)
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user