Generate same instructions for global and local variable assignment
This commit is contained in:
@@ -964,7 +964,8 @@ var
|
|||||||
rtl_operand: ElnaRtlOperand;
|
rtl_operand: ElnaRtlOperand;
|
||||||
begin
|
begin
|
||||||
result := elna_rtl_instruction_create(operation);
|
result := elna_rtl_instruction_create(operation);
|
||||||
elna_rtl_copy_operand(instructions, @tac_instruction^.operands[1], 1, result, variable_map);
|
elna_rtl_instruction_set_operand(result, 1, ElnaRtlKind.pseudo,
|
||||||
|
tac_instruction^.operands[1].value, tac_instruction^.operands[1].length);
|
||||||
|
|
||||||
elna_rtl_operand_value(instructions, @tac_instruction^.operands[2], variable_map, @rtl_operand);
|
elna_rtl_operand_value(instructions, @tac_instruction^.operands[2], variable_map, @rtl_operand);
|
||||||
elna_rtl_instruction_set_operand(result, 2, rtl_operand.kind, rtl_operand.value, rtl_operand.length);
|
elna_rtl_instruction_set_operand(result, 2, rtl_operand.kind, rtl_operand.value, rtl_operand.length);
|
||||||
@@ -998,7 +999,8 @@ var
|
|||||||
rtl_operand: ElnaRtlOperand;
|
rtl_operand: ElnaRtlOperand;
|
||||||
begin
|
begin
|
||||||
slt_instruction := elna_rtl_instruction_create(ElnaRtlOperator.slt);
|
slt_instruction := elna_rtl_instruction_create(ElnaRtlOperator.slt);
|
||||||
elna_rtl_copy_operand(instructions, @tac_instruction^.operands[1], 1, slt_instruction, variable_map);
|
elna_rtl_instruction_set_operand(slt_instruction, 1, ElnaRtlKind.pseudo,
|
||||||
|
tac_instruction^.operands[1].value, tac_instruction^.operands[1].length);
|
||||||
|
|
||||||
elna_rtl_operand_value(instructions, @tac_instruction^.operands[2], variable_map, @rtl_operand);
|
elna_rtl_operand_value(instructions, @tac_instruction^.operands[2], variable_map, @rtl_operand);
|
||||||
elna_rtl_instruction_set_operand(slt_instruction, lhs, rtl_operand.kind, rtl_operand.value, rtl_operand.length);
|
elna_rtl_instruction_set_operand(slt_instruction, lhs, rtl_operand.kind, rtl_operand.value, rtl_operand.length);
|
||||||
@@ -1029,30 +1031,26 @@ begin
|
|||||||
elna_list_append(instructions, xor_instruction)
|
elna_list_append(instructions, xor_instruction)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_rtl_copy_operand(instructions: ^ElnaList, tac_operand: ^ElnaTacOperand, number: Word,
|
proc elna_rtl_get_address(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable);
|
||||||
rtl_instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable);
|
|
||||||
var
|
var
|
||||||
operand_length: Word;
|
|
||||||
operand_value: Word;
|
|
||||||
pseudo_symbol: ^ElnaRtlInfo;
|
pseudo_symbol: ^ElnaRtlInfo;
|
||||||
instruction: ^ElnaRtlInstruction;
|
instruction: ^ElnaRtlInstruction;
|
||||||
begin
|
begin
|
||||||
operand_value := tac_operand^.value;
|
pseudo_symbol := elna_symbol_table_lookup(variable_map,
|
||||||
operand_length := tac_operand^.length;
|
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length);
|
||||||
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.la);
|
||||||
|
|
||||||
if tac_operand^.kind = ElnaTacKind.constant then
|
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo,
|
||||||
elna_rtl_instruction_set_operand(rtl_instruction, number, ElnaRtlKind.immediate, operand_value, operand_length)
|
tac_instruction^.operands[1].value, tac_instruction^.operands[1].length);
|
||||||
elsif tac_operand^.kind = ElnaTacKind.variable then
|
|
||||||
pseudo_symbol := elna_symbol_table_lookup(variable_map, operand_value, operand_length);
|
if pseudo_symbol = nil then
|
||||||
if pseudo_symbol = nil then
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.symbol,
|
||||||
pseudo_symbol := elna_rtl_generate_pseudo(@operand_value, @operand_length, variable_map);
|
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length)
|
||||||
instruction := elna_rtl_instruction_create(ElnaRtlOperator.la);
|
else
|
||||||
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo, operand_value, operand_length);
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo,
|
||||||
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.symbol, tac_operand^.value, tac_operand^.length);
|
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length)
|
||||||
elna_list_append(instructions, instruction)
|
end;
|
||||||
end;
|
elna_list_append(instructions, instruction)
|
||||||
elna_rtl_instruction_set_operand(rtl_instruction, number, ElnaRtlKind.pseudo, operand_value, operand_length)
|
|
||||||
end
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_rtl_conditional_jump(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction,
|
proc elna_rtl_conditional_jump(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction,
|
||||||
@@ -1078,7 +1076,9 @@ begin
|
|||||||
elna_rtl_operand_value(instructions, @tac_instruction^.operands[2], variable_map, @rtl_operand);
|
elna_rtl_operand_value(instructions, @tac_instruction^.operands[2], variable_map, @rtl_operand);
|
||||||
|
|
||||||
instruction := elna_rtl_instruction_create(rtl_operator);
|
instruction := elna_rtl_instruction_create(rtl_operator);
|
||||||
elna_rtl_copy_operand(instructions, @tac_instruction^.operands[1], 1, instruction, variable_map);
|
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo,
|
||||||
|
tac_instruction^.operands[1].value, tac_instruction^.operands[1].length);
|
||||||
|
|
||||||
elna_rtl_instruction_set_operand(instruction, 2, rtl_operand.kind, rtl_operand.value, rtl_operand.length);
|
elna_rtl_instruction_set_operand(instruction, 2, rtl_operand.kind, rtl_operand.value, rtl_operand.length);
|
||||||
elna_list_append(instructions, instruction)
|
elna_list_append(instructions, instruction)
|
||||||
end;
|
end;
|
||||||
@@ -1149,16 +1149,36 @@ end;
|
|||||||
proc elna_rtl_copy(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable);
|
proc elna_rtl_copy(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable);
|
||||||
var
|
var
|
||||||
instruction: ^ElnaRtlInstruction;
|
instruction: ^ElnaRtlInstruction;
|
||||||
rtl_operand: ElnaRtlOperand;
|
source_operand: ElnaRtlOperand;
|
||||||
|
target_operand: ElnaRtlOperand;
|
||||||
|
pseudo_symbol: ^ElnaRtlInfo;
|
||||||
begin
|
begin
|
||||||
if tac_instruction^.operands[1].kind = ElnaTacKind.variable then
|
if tac_instruction^.operands[1].kind = ElnaTacKind.variable then
|
||||||
elna_rtl_operand_value(instructions, @tac_instruction^.operands[2], variable_map, @rtl_operand);
|
elna_rtl_operand_value(instructions, @tac_instruction^.operands[2], variable_map, @source_operand);
|
||||||
|
pseudo_symbol := elna_symbol_table_lookup(variable_map,
|
||||||
|
tac_instruction^.operands[1].value, tac_instruction^.operands[1].length);
|
||||||
|
|
||||||
instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv);
|
if pseudo_symbol = nil then
|
||||||
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo,
|
target_operand.kind := ElnaRtlKind.pseudo;
|
||||||
|
elna_rtl_generate_pseudo(@target_operand.value, @target_operand.length, 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);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.symbol,
|
||||||
tac_instruction^.operands[1].value, tac_instruction^.operands[1].length);
|
tac_instruction^.operands[1].value, tac_instruction^.operands[1].length);
|
||||||
elna_rtl_instruction_set_operand(instruction, 2, rtl_operand.kind, rtl_operand.value, rtl_operand.length);
|
elna_list_append(instructions, instruction);
|
||||||
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);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 2, target_operand.kind, target_operand.value, target_operand.length);
|
||||||
|
elna_list_append(instructions, instruction)
|
||||||
|
else
|
||||||
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo,
|
||||||
|
tac_instruction^.operands[1].value, tac_instruction^.operands[1].length);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 2, source_operand.kind, source_operand.value, source_operand.length);
|
||||||
|
elna_list_append(instructions, instruction);
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@@ -1168,19 +1188,7 @@ var
|
|||||||
pseudo_symbol: ^ElnaRtlInfo;
|
pseudo_symbol: ^ElnaRtlInfo;
|
||||||
begin
|
begin
|
||||||
if tac_instruction^.operator = ElnaTacOperator.get_address then
|
if tac_instruction^.operator = ElnaTacOperator.get_address then
|
||||||
pseudo_symbol := elna_symbol_table_lookup(variable_map,
|
elna_rtl_get_address(instructions, tac_instruction, variable_map)
|
||||||
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length);
|
|
||||||
instruction := elna_rtl_instruction_create(ElnaRtlOperator.la);
|
|
||||||
|
|
||||||
elna_rtl_copy_operand(instructions, @tac_instruction^.operands[1], 1, instruction, variable_map);
|
|
||||||
if pseudo_symbol = nil then
|
|
||||||
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.symbol,
|
|
||||||
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length)
|
|
||||||
else
|
|
||||||
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo,
|
|
||||||
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length)
|
|
||||||
end;
|
|
||||||
elna_list_append(instructions, instruction)
|
|
||||||
elsif tac_instruction^.operator = ElnaTacOperator.add then
|
elsif tac_instruction^.operator = ElnaTacOperator.add then
|
||||||
elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator.add, variable_map)
|
elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator.add, variable_map)
|
||||||
elsif tac_instruction^.operator = ElnaTacOperator.load then
|
elsif tac_instruction^.operator = ElnaTacOperator.load then
|
||||||
@@ -1249,7 +1257,7 @@ end;
|
|||||||
|
|
||||||
proc elna_tac_label(instructions: ^ElnaList, counter: Word, length: Word);
|
proc elna_tac_label(instructions: ^ElnaList, counter: Word, length: Word);
|
||||||
var
|
var
|
||||||
result: Word;
|
result: ^ElnaTacInstruction;
|
||||||
begin
|
begin
|
||||||
result := elna_tac_instruction_create(ElnaTacOperator.label);
|
result := elna_tac_instruction_create(ElnaTacOperator.label);
|
||||||
elna_tac_instruction_set_operand(result, 1, ElnaTacKind.label, counter, length);
|
elna_tac_instruction_set_operand(result, 1, ElnaTacKind.label, counter, length);
|
||||||
@@ -2352,8 +2360,7 @@ begin
|
|||||||
elna_tac_instruction_set_operand(instruction, 3, rhs.kind, rhs.value, rhs.length);
|
elna_tac_instruction_set_operand(instruction, 3, rhs.kind, rhs.value, rhs.length);
|
||||||
|
|
||||||
elna_list_append(instructions, instruction)
|
elna_list_append(instructions, instruction)
|
||||||
end;
|
end
|
||||||
return instructions^.first
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_parser_call(cursor: ^ElnaLexerCursor, callee: Word);
|
proc elna_parser_call(cursor: ^ElnaLexerCursor, callee: Word);
|
||||||
@@ -2724,9 +2731,6 @@ proc elna_tac_assign_statement(instructions: ^ElnaList, parser_tree: ^ElnaTreeAs
|
|||||||
var
|
var
|
||||||
is_address: Word;
|
is_address: Word;
|
||||||
instruction: Word;
|
instruction: Word;
|
||||||
operand_type: Word;
|
|
||||||
operand_value: Word;
|
|
||||||
operand_length: Word;
|
|
||||||
assignment_operand: ElnaTacOperand;
|
assignment_operand: ElnaTacOperand;
|
||||||
assignee: ElnaTacOperand;
|
assignee: ElnaTacOperand;
|
||||||
symbol_info: ^ElnaSymbolInfo;
|
symbol_info: ^ElnaSymbolInfo;
|
||||||
@@ -2734,39 +2738,20 @@ begin
|
|||||||
elna_tac_designator(instructions, parser_tree^.assignee, symbol_table, @is_address, @assignee);
|
elna_tac_designator(instructions, parser_tree^.assignee, symbol_table, @is_address, @assignee);
|
||||||
|
|
||||||
(* Compile the assignment. *)
|
(* Compile the assignment. *)
|
||||||
instruction := elna_tac_binary_expression(instructions, parser_tree^.assignment, symbol_table, @assignment_operand);
|
elna_tac_binary_expression(instructions, parser_tree^.assignment, symbol_table, @assignment_operand);
|
||||||
symbol_info := elna_symbol_table_lookup(symbol_table, assignee.value, assignee.length);
|
|
||||||
|
|
||||||
(* Fix me: if local variable generate different instructions. TAC instructions should not be probably different. *)
|
|
||||||
if symbol_info <> nil then
|
|
||||||
if is_address then
|
|
||||||
instruction := elna_tac_instruction_create(ElnaTacOperator.store);
|
|
||||||
|
|
||||||
elna_tac_instruction_set_operand(instruction, 1, assignment_operand.kind, assignment_operand.value, assignment_operand.length);
|
|
||||||
elna_tac_instruction_set_operand(instruction, 2, assignee.kind, assignee.value, assignee.length)
|
|
||||||
else
|
|
||||||
instruction := elna_tac_instruction_create(ElnaTacOperator.copy);
|
|
||||||
|
|
||||||
elna_tac_instruction_set_operand(instruction, 1, assignee.kind, assignee.value, assignee.length);
|
|
||||||
elna_tac_instruction_set_operand(instruction, 2, assignment_operand.kind, assignment_operand.value, assignment_operand.length)
|
|
||||||
end;
|
|
||||||
elna_list_append(instructions, instruction)
|
|
||||||
else
|
|
||||||
elna_tac_generate_pseudo(@operand_type, @operand_value, @operand_length, symbol_table);
|
|
||||||
|
|
||||||
(* Save the assignee address on the stack. *)
|
|
||||||
instruction := elna_tac_instruction_create(ElnaTacOperator.get_address);
|
|
||||||
elna_tac_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length);
|
|
||||||
elna_tac_instruction_set_operand(instruction, 2, assignee.kind, assignee.value, assignee.length);
|
|
||||||
|
|
||||||
elna_list_append(instructions, instruction);
|
|
||||||
|
|
||||||
|
if is_address then
|
||||||
instruction := elna_tac_instruction_create(ElnaTacOperator.store);
|
instruction := elna_tac_instruction_create(ElnaTacOperator.store);
|
||||||
elna_tac_instruction_set_operand(instruction, 1, assignment_operand.kind, assignment_operand.value, assignment_operand.length);
|
|
||||||
elna_tac_instruction_set_operand(instruction, 2, operand_type, operand_value, operand_length);
|
|
||||||
|
|
||||||
elna_list_append(instructions, instruction)
|
elna_tac_instruction_set_operand(instruction, 1, assignment_operand.kind, assignment_operand.value, assignment_operand.length);
|
||||||
end
|
elna_tac_instruction_set_operand(instruction, 2, assignee.kind, assignee.value, assignee.length)
|
||||||
|
else
|
||||||
|
instruction := elna_tac_instruction_create(ElnaTacOperator.copy);
|
||||||
|
|
||||||
|
elna_tac_instruction_set_operand(instruction, 1, assignee.kind, assignee.value, assignee.length);
|
||||||
|
elna_tac_instruction_set_operand(instruction, 2, assignment_operand.kind, assignment_operand.value, assignment_operand.length)
|
||||||
|
end;
|
||||||
|
elna_list_append(instructions, instruction)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_parser_return_statement(cursor: ^ElnaLexerCursor);
|
proc elna_parser_return_statement(cursor: ^ElnaLexerCursor);
|
||||||
@@ -2793,7 +2778,7 @@ var
|
|||||||
instruction: Word;
|
instruction: Word;
|
||||||
operand: ElnaTacOperand;
|
operand: ElnaTacOperand;
|
||||||
begin
|
begin
|
||||||
instruction := elna_tac_binary_expression(instructions, parser_node^.returned, symbol_table, @operand);
|
elna_tac_binary_expression(instructions, parser_node^.returned, symbol_table, @operand);
|
||||||
|
|
||||||
instruction := elna_tac_instruction_create(ElnaTacOperator._return);
|
instruction := elna_tac_instruction_create(ElnaTacOperator._return);
|
||||||
elna_tac_instruction_set_operand(instruction, 1, operand.kind, operand.value, operand.length);
|
elna_tac_instruction_set_operand(instruction, 1, operand.kind, operand.value, operand.length);
|
||||||
@@ -2845,7 +2830,7 @@ var
|
|||||||
operand: ElnaTacOperand;
|
operand: ElnaTacOperand;
|
||||||
begin
|
begin
|
||||||
(* Compile condition. *)
|
(* Compile condition. *)
|
||||||
instruction := elna_tac_binary_expression(instructions, parser_node^.condition, symbol_table, @operand);
|
elna_tac_binary_expression(instructions, parser_node^.condition, symbol_table, @operand);
|
||||||
|
|
||||||
(* condition_label is the label in front of the next elsif condition or end. *)
|
(* condition_label is the label in front of the next elsif condition or end. *)
|
||||||
condition_label := label_counter;
|
condition_label := label_counter;
|
||||||
@@ -5359,3 +5344,11 @@ begin
|
|||||||
exit(4)
|
exit(4)
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
proc f();
|
||||||
|
var
|
||||||
|
x: Word;
|
||||||
|
y: Word;
|
||||||
|
begin
|
||||||
|
x := y
|
||||||
|
end;
|
||||||
|
|||||||
Reference in New Issue
Block a user