diff --git a/boot/stage20/cl.elna b/boot/stage20/cl.elna index 7312a03..bf8a1f5 100644 --- a/boot/stage20/cl.elna +++ b/boot/stage20/cl.elna @@ -964,7 +964,8 @@ var rtl_operand: ElnaRtlOperand; begin 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_instruction_set_operand(result, 2, rtl_operand.kind, rtl_operand.value, rtl_operand.length); @@ -998,7 +999,8 @@ var rtl_operand: ElnaRtlOperand; begin 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_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) end; -proc elna_rtl_copy_operand(instructions: ^ElnaList, tac_operand: ^ElnaTacOperand, number: Word, - rtl_instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable); +proc elna_rtl_get_address(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable); var - operand_length: Word; - operand_value: Word; pseudo_symbol: ^ElnaRtlInfo; instruction: ^ElnaRtlInstruction; begin - operand_value := tac_operand^.value; - operand_length := tac_operand^.length; + pseudo_symbol := elna_symbol_table_lookup(variable_map, + 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(rtl_instruction, number, ElnaRtlKind.immediate, operand_value, operand_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 - pseudo_symbol := elna_rtl_generate_pseudo(@operand_value, @operand_length, variable_map); - instruction := elna_rtl_instruction_create(ElnaRtlOperator.la); - elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo, operand_value, operand_length); - elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.symbol, tac_operand^.value, tac_operand^.length); - elna_list_append(instructions, instruction) - end; - elna_rtl_instruction_set_operand(rtl_instruction, number, ElnaRtlKind.pseudo, operand_value, operand_length) - end + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo, + tac_instruction^.operands[1].value, tac_instruction^.operands[1].length); + + 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) end; 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); 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_list_append(instructions, instruction) end; @@ -1149,16 +1149,36 @@ end; proc elna_rtl_copy(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable); var instruction: ^ElnaRtlInstruction; - rtl_operand: ElnaRtlOperand; + source_operand: ElnaRtlOperand; + target_operand: ElnaRtlOperand; + pseudo_symbol: ^ElnaRtlInfo; begin 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); - elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo, + if pseudo_symbol = nil then + 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); - 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; @@ -1168,19 +1188,7 @@ var pseudo_symbol: ^ElnaRtlInfo; begin if tac_instruction^.operator = ElnaTacOperator.get_address then - pseudo_symbol := elna_symbol_table_lookup(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) + elna_rtl_get_address(instructions, tac_instruction, variable_map) elsif tac_instruction^.operator = ElnaTacOperator.add then elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator.add, variable_map) elsif tac_instruction^.operator = ElnaTacOperator.load then @@ -1249,7 +1257,7 @@ end; proc elna_tac_label(instructions: ^ElnaList, counter: Word, length: Word); var - result: Word; + result: ^ElnaTacInstruction; begin result := elna_tac_instruction_create(ElnaTacOperator.label); 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_list_append(instructions, instruction) - end; - return instructions^.first + end end; proc elna_parser_call(cursor: ^ElnaLexerCursor, callee: Word); @@ -2724,9 +2731,6 @@ proc elna_tac_assign_statement(instructions: ^ElnaList, parser_tree: ^ElnaTreeAs var is_address: Word; instruction: Word; - operand_type: Word; - operand_value: Word; - operand_length: Word; assignment_operand: ElnaTacOperand; assignee: ElnaTacOperand; symbol_info: ^ElnaSymbolInfo; @@ -2734,39 +2738,20 @@ begin elna_tac_designator(instructions, parser_tree^.assignee, symbol_table, @is_address, @assignee); (* Compile the assignment. *) - instruction := 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); + elna_tac_binary_expression(instructions, parser_tree^.assignment, symbol_table, @assignment_operand); + 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, operand_type, operand_value, operand_length); - elna_list_append(instructions, instruction) - end + 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) end; proc elna_parser_return_statement(cursor: ^ElnaLexerCursor); @@ -2793,7 +2778,7 @@ var instruction: Word; operand: ElnaTacOperand; 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); elna_tac_instruction_set_operand(instruction, 1, operand.kind, operand.value, operand.length); @@ -2845,7 +2830,7 @@ var operand: ElnaTacOperand; begin (* 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 := label_counter; @@ -5359,3 +5344,11 @@ begin exit(4) end end; + +proc f(); +var + x: Word; + y: Word; +begin + x := y +end;