diff --git a/boot/stage20/cl.elna b/boot/stage20/cl.elna index 74dee3c..a0bdfaf 100644 --- a/boot/stage20/cl.elna +++ b/boot/stage20/cl.elna @@ -544,7 +544,7 @@ type next: Word; name: Word; length: Word; - body: Word; + body: ElnaList; variable_map: ^ElnaSymbolTable end; ElnaRtlInstruction = record @@ -771,14 +771,7 @@ begin else list^.last^.next := element end; - (* TODO: This is a temporary solution for the migration from the old lists. *) - .elna_list_append_loop; - if element^.next = nil then - list^.last := element - else - element := element^.next; - goto elna_list_append_loop - end + list^.last := element end; return element end; @@ -861,134 +854,98 @@ begin this^.operands[n].length := operand_length end; -proc elna_rtl_load_operand_value(tac_instruction: ^ElnaTacInstruction, operand_number: Word, into: Word); +proc elna_rtl_load_operand_value(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, operand_number: Word, into: Word); var - result: ^ElnaRtlInstruction; + instruction: ^ElnaRtlInstruction; operand_value: Word; operand_length: Word; operand_type: Word; - next_instruction: Word; begin operand_type := tac_instruction^.operands[operand_number].kind; operand_value := tac_instruction^.operands[operand_number].value; operand_length := tac_instruction^.operands[operand_number].length; if operand_type = ElnaTacKind.immediate then - result := elna_rtl_instruction_create(ElnaRtlOperator.li); - elna_rtl_instruction_set_operand(result, 1, ElnaRtlKind.register, into, 0); - elna_rtl_instruction_set_operand(result, 2, ElnaRtlKind.immediate, operand_value, operand_length) + instruction := elna_rtl_instruction_create(ElnaRtlOperator.li); + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.immediate, operand_value, operand_length); + elna_list_append(instructions, instruction) elsif operand_type = ElnaTacKind.symbol then - result := elna_rtl_instruction_create(ElnaRtlOperator.la); - elna_rtl_instruction_set_operand(result, 1, ElnaRtlKind.register, into, 0); - elna_rtl_instruction_set_operand(result, 2, ElnaRtlKind.symbol, operand_value, operand_length); + instruction := elna_rtl_instruction_create(ElnaRtlOperator.la); + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.symbol, operand_value, operand_length); + elna_list_append(instructions, instruction); - next_instruction := elna_rtl_instruction_create(ElnaRtlOperator.lw); - elna_rtl_instruction_set_operand(next_instruction, 1, ElnaRtlKind.register, into, 0); - elna_rtl_instruction_set_operand(next_instruction, 2, ElnaRtlKind.offset, into, 0); - - result^.next := next_instruction + instruction := elna_rtl_instruction_create(ElnaRtlOperator.lw); + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, into, 0); + elna_list_append(instructions, instruction) elsif operand_type = ElnaTacKind.pseudo then - result := elna_rtl_instruction_create(ElnaRtlOperator.move); - elna_rtl_instruction_set_operand(result, 1, ElnaRtlKind.register, into, 0); - elna_rtl_instruction_set_operand(result, 2, ElnaRtlKind.pseudo, operand_value, operand_length) - end; + instruction := elna_rtl_instruction_create(ElnaRtlOperator.move); + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo, operand_value, operand_length); - return result + elna_list_append(instructions, instruction) + end end; -proc elna_rtl_load_operand_address(tac_instruction: ^ElnaTacInstruction, operand_number: Word, into: Word); -var - result: Word; - operand_value: Word; - operand_length: Word; - operand_type: Word; +proc elna_rtl_binary_operands(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction); begin - operand_type := tac_instruction^.operands[operand_number].kind; - operand_value := tac_instruction^.operands[operand_number].value; - operand_length := tac_instruction^.operands[operand_number].length; - - if operand_type = ElnaTacKind.symbol then - result := elna_rtl_instruction_create(ElnaRtlOperator.la); - elna_rtl_instruction_set_operand(result, 1, ElnaRtlKind.register, into, 0); - elna_rtl_instruction_set_operand(result, 2, ElnaRtlKind.symbol, operand_value, operand_length) - elsif operand_type = ElnaTacKind.pseudo then - result := elna_rtl_instruction_create(ElnaRtlOperator.la); - elna_rtl_instruction_set_operand(result, 1, ElnaRtlKind.register, into, 0); - elna_rtl_instruction_set_operand(result, 2, ElnaRtlKind.pseudo, operand_value, operand_length) - end; - - return result + elna_rtl_load_operand_value(instructions, tac_instruction, 2, ElnaRtlRegister.t2); + elna_rtl_load_operand_value(instructions, tac_instruction, 3, ElnaRtlRegister.t3) end; -proc elna_rtl_binary_operands(tac_instruction: ^ElnaTacInstruction, next_instruction: ^^ElnaRtlInstruction); +proc elna_rtl_binary_arithmetic(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, operation: Word); var - lhs: ^ElnaRtlInstruction; - rhs: ^ElnaRtlInstruction; + instruction: ^ElnaRtlInstruction; begin - lhs := elna_rtl_load_operand_value(tac_instruction, 2, ElnaRtlRegister.t2); - rhs := elna_rtl_load_operand_value(tac_instruction, 3, ElnaRtlRegister.t3); + elna_rtl_binary_operands(instructions, tac_instruction); + instruction := elna_rtl_instruction_create(operation); - next_instruction^ := lhs^.next; - if next_instruction^ = 0 then - lhs^.next := rhs - else - next_instruction^^ := rhs - end; - next_instruction^ := rhs^.next; - if next_instruction^ = 0 then - next_instruction^ := rhs - end; - - return lhs + elna_rtl_copy_operand(tac_instruction, 1, instruction); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.t2, 0); + elna_rtl_instruction_set_operand(instruction, 3, ElnaRtlKind.register, ElnaRtlRegister.t3, 0); + elna_list_append(instructions, instruction) end; -proc elna_rtl_binary_arithmetic(tac_instruction: ^ElnaTacInstruction, next_instruction: ^^ElnaRtlInstruction, operation: Word); +proc elna_rtl_binary_equality(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, instruction_kind: Word); var - lhs: Word; - binary_result: ^ElnaRtlInstruction; - intermediate_instruction: ^ElnaRtlInstruction; + instruction: ^ElnaRtlInstruction; begin - lhs := elna_rtl_binary_operands(tac_instruction, next_instruction); - binary_result := elna_rtl_instruction_create(operation); + elna_rtl_binary_operands(instructions, tac_instruction); + instruction := elna_rtl_instruction_create(ElnaRtlOperator._xor); - elna_rtl_copy_operand(tac_instruction, 1, binary_result); - elna_rtl_instruction_set_operand(binary_result, 2, ElnaRtlKind.register, ElnaRtlRegister.t2, 0); - elna_rtl_instruction_set_operand(binary_result, 3, ElnaRtlKind.register, ElnaRtlRegister.t3, 0); - binary_result^.operator := operation; + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t2, 0); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.t2, 0); + elna_rtl_instruction_set_operand(instruction, 3, ElnaRtlKind.register, ElnaRtlRegister.t3, 0); + elna_list_append(instructions, instruction); - intermediate_instruction := next_instruction^; - intermediate_instruction^.next := binary_result; - next_instruction^ := binary_result; - - return lhs + instruction := elna_rtl_instruction_create(instruction_kind); + elna_rtl_copy_operand(tac_instruction, 1, instruction); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.t2, 0); + elna_list_append(instructions, instruction) end; -proc elna_rtl_binary_equality(tac_instruction: ^ElnaTacInstruction, instruction_kind: Word, next_instruction: ^^ElnaRtlInstruction); +proc elna_rtl_binary_comparison(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, + lhs: ElnaRtlRegister, rhs: ElnaRtlRegister); var - operands: ^ElnaRtlInstruction; - intermediate_instruction: ^ElnaRtlInstruction; - operating_instruction: ^ElnaRtlInstruction; - binary_result: ^ElnaRtlInstruction; + instruction: ^ElnaRtlInstruction; begin - operands := elna_rtl_binary_operands(tac_instruction, next_instruction); - operating_instruction := elna_rtl_instruction_create(ElnaRtlOperator._xor); + elna_rtl_binary_operands(instructions, tac_instruction); - elna_rtl_instruction_set_operand(operating_instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t2, 0); - elna_rtl_instruction_set_operand(operating_instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.t2, 0); - elna_rtl_instruction_set_operand(operating_instruction, 3, ElnaRtlKind.register, ElnaRtlRegister.t3, 0); + instruction := elna_rtl_instruction_create(ElnaRtlOperator.slt); + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t2, 0); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, lhs, 0); + elna_rtl_instruction_set_operand(instruction, 3, ElnaRtlKind.register, rhs, 0); - intermediate_instruction := next_instruction^; - intermediate_instruction^.next := operating_instruction; + elna_list_append(instructions, instruction); - binary_result := elna_rtl_instruction_create(instruction_kind); - elna_rtl_copy_operand(tac_instruction, 1, binary_result); - elna_rtl_instruction_set_operand(binary_result, 2, ElnaRtlKind.register, ElnaRtlRegister.t2, 0); + instruction := elna_rtl_instruction_create(ElnaRtlOperator.xori); + elna_rtl_copy_operand(tac_instruction, 1, instruction); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.t2, 0); + elna_rtl_instruction_set_operand(instruction, 3, ElnaRtlKind.immediate, 1, 0); - intermediate_instruction := next_instruction^; - operating_instruction^.next := binary_result; - next_instruction^ := binary_result; - - return operands + elna_list_append(instructions, instruction) end; proc elna_rtl_copy_operand(tac_instruction: ^ElnaTacInstruction, number: Word, rtl_instruction: Word); @@ -1010,43 +967,38 @@ begin end end; -proc elna_rtl_conditional_jump(tac_instruction: Word, condition: Word); +proc elna_rtl_conditional_jump(instructions: ^ElnaList, tac_instruction: Word, condition: Word); var - result: Word; + instruction: Word; begin - result := elna_rtl_instruction_create(condition); - elna_rtl_copy_operand(tac_instruction, 1, result); - elna_rtl_copy_operand(tac_instruction, 2, result); + instruction := elna_rtl_instruction_create(condition); + elna_rtl_copy_operand(tac_instruction, 1, instruction); + elna_rtl_copy_operand(tac_instruction, 2, instruction); - return result + elna_list_append(instructions, instruction) end; -proc elna_rtl_unary(tac_instruction: Word, rtl_operator: Word, next_instruction: Word); +proc elna_rtl_unary(instructions: ^ElnaList, tac_instruction: Word, rtl_operator: Word); var - result: ^ElnaRtlInstruction; + instruction: ^ElnaRtlInstruction; begin - result := elna_rtl_load_operand_value(tac_instruction, 2, ElnaRtlRegister.t0); - next_instruction^ := elna_rtl_instruction_create(rtl_operator); - elna_rtl_copy_operand(tac_instruction, 1, result); - elna_rtl_instruction_set_operand(result, 2, ElnaRtlKind.register, ElnaRtlRegister.t0); - result^.next := next_instruction^; + elna_rtl_load_operand_value(instructions, tac_instruction, 2, ElnaRtlRegister.t0); - return result + instruction := elna_rtl_instruction_create(rtl_operator); + elna_rtl_copy_operand(tac_instruction, 1, instructions^.first); + elna_rtl_instruction_set_operand(instructions^.first, 2, ElnaRtlKind.register, ElnaRtlRegister.t0); + elna_list_append(instructions, instruction) end; -proc elna_rtl_call(tac_instruction: ^ElnaTacInstruction, next_instruction: ^^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable); +proc elna_rtl_call(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable); var argument_count: Word; current_argument: ^ElnaTacOperand; - argument_move: ^ElnaRtlInstruction; + instruction: ^ElnaRtlInstruction; current_register: Word; - first_instruction: Word; - current_instruction: Word; variable_info: ^ElnaRtlInfo; begin current_register := 0; - first_instruction := nil; - current_argument := tac_instruction^.operands[2].value; argument_count := tac_instruction^.operands[2].length; @@ -1057,233 +1009,146 @@ begin if current_argument^.kind = ElnaTacKind.pseudo then variable_info := elna_symbol_table_lookup(variable_map, current_argument^.value, current_argument^.length); - (* DEBUG printf("# Sample %i %.*s\n\0", variable_info^.rtl_type^.size, current_argument^.length, current_argument^.value); *) if variable_info^.rtl_type^.size <= 4 then - argument_move := elna_rtl_instruction_create(ElnaRtlOperator.move); - elna_rtl_instruction_set_operand(argument_move, 1, ElnaRtlKind.register, ElnaRtlRegister.a0 + current_register, 0); - elna_rtl_instruction_set_operand(argument_move, 2, ElnaRtlKind.pseudo, + instruction := elna_rtl_instruction_create(ElnaRtlOperator.move); + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a0 + current_register, 0); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo, current_argument^.value, current_argument^.length) elsif variable_info^.rtl_type^.size <= 8 then - argument_move := elna_rtl_instruction_create(ElnaRtlOperator.move); - elna_rtl_instruction_set_operand(argument_move, 1, ElnaRtlKind.register, ElnaRtlRegister.a0 + current_register, 0); - elna_rtl_instruction_set_operand(argument_move, 2, ElnaRtlKind.pseudo, + instruction := elna_rtl_instruction_create(ElnaRtlOperator.move); + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a0 + current_register, 0); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo, current_argument^.value, current_argument^.length) end end; - if first_instruction = nil then - first_instruction := argument_move - else - elna_instruction_list_concatenate(current_instruction, argument_move) - end; - current_instruction := argument_move; + elna_list_append(instructions, instruction); current_argument := current_argument + #size(ElnaTacOperand); current_register := current_register + 1; goto elna_rtl_call_loop end; - argument_move := elna_rtl_instruction_create(ElnaRtlOperator.jal); - elna_rtl_copy_operand(tac_instruction, 1, argument_move); + instruction := elna_rtl_instruction_create(ElnaRtlOperator.jal); + elna_rtl_copy_operand(tac_instruction, 1, instruction); + elna_list_append(instructions, instruction); - if first_instruction = nil then - first_instruction := argument_move - else - elna_instruction_list_concatenate(current_instruction, argument_move) - end; - current_instruction := argument_move; - - argument_move := elna_rtl_instruction_create(ElnaRtlOperator.move); - elna_rtl_instruction_set_operand(argument_move, 1, tac_instruction^.operands[3].kind, + instruction := elna_rtl_instruction_create(ElnaRtlOperator.move); + elna_rtl_instruction_set_operand(instruction, 1, tac_instruction^.operands[3].kind, tac_instruction^.operands[3].value, tac_instruction^.operands[3].length); - elna_rtl_instruction_set_operand(argument_move, 2, ElnaRtlKind.register, ElnaRtlRegister.a0, 0); - elna_instruction_list_concatenate(current_instruction, argument_move); - - next_instruction^ := argument_move; - - return first_instruction + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.a0, 0); + elna_list_append(instructions, instruction) end; -proc elna_rtl_store(tac_instruction: ^ElnaTacInstruction, next_instruction: ^^ElnaRtlInstruction); +proc elna_rtl_store(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction); var - result: ^ElnaRtlInstruction; - operands: ^ElnaRtlInstruction; + instruction: ^ElnaRtlInstruction; begin - operands := elna_rtl_load_operand_value(tac_instruction, 1, ElnaRtlRegister.t0); - next_instruction^ := elna_rtl_instruction_create(ElnaRtlOperator.sw); - result := operands; - operands := result^.next; + elna_rtl_load_operand_value(instructions, tac_instruction, 1, ElnaRtlRegister.t0); + instruction := elna_rtl_instruction_create(ElnaRtlOperator.sw); - elna_rtl_instruction_set_operand(next_instruction^, 1, ElnaRtlKind.register, ElnaRtlRegister.t0, 0); + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t0, 0); if tac_instruction^.operands[2].kind = ElnaTacKind.pseudo then - elna_rtl_instruction_set_operand(next_instruction^, 2, ElnaRtlKind.pseudo, + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo, tac_instruction^.operands[2].value, tac_instruction^.operands[2].length) end; - if operands = nil then - result^.next := next_instruction^ - else - operands^.next := next_instruction^ - end; - return result + elna_list_append(instructions, instruction) end; -proc elna_rtl_load(tac_instruction: ^ElnaTacInstruction, next_instruction: ^^ElnaRtlInstruction); +proc elna_rtl_load(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction); var - result: ^ElnaRtlInstruction; - operands: ^ElnaRtlInstruction; + instruction: ^ElnaRtlInstruction; begin - operands := elna_rtl_load_operand_value(tac_instruction, 1, ElnaRtlRegister.t0); - next_instruction^ := elna_rtl_instruction_create(ElnaRtlOperator.lw); - result := operands; - operands := result^.next; + elna_rtl_load_operand_value(instructions, tac_instruction, 1, ElnaRtlRegister.t0); - elna_rtl_instruction_set_operand(next_instruction^, 2, ElnaRtlKind.offset, ElnaRtlRegister.t0, 0); - - elna_rtl_instruction_set_operand(next_instruction^, 1, tac_instruction^.operands[2].kind, + instruction := elna_rtl_instruction_create(ElnaRtlOperator.lw); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.t0, 0); + elna_rtl_instruction_set_operand(instruction, 1, tac_instruction^.operands[2].kind, tac_instruction^.operands[2].value, tac_instruction^.operands[2].length); - - if operands = 0 then - result^.next := next_instruction^ - else - operands^.next := next_instruction^ - end; - return result + elna_list_append(instructions, instruction) end; -proc elna_rtl_instruction(tac_instruction: ^ElnaTacInstruction, next_instruction: ^^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable); +proc elna_rtl_instruction(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable); var - result: ^ElnaRtlInstruction; - operands: ^ElnaRtlInstruction; - intermediate_instruction: ^ElnaRtlInstruction; + instruction: ^ElnaRtlInstruction; begin - result := malloc(#size(ElnaRtlInstruction)); - next_instruction^ := nil; - if tac_instruction^.operator = ElnaTacOperator.get_address then - result := elna_rtl_instruction_create(ElnaRtlOperator.la); + instruction := elna_rtl_instruction_create(ElnaRtlOperator.la); - elna_rtl_copy_operand(tac_instruction, 1, result); - elna_rtl_copy_operand(tac_instruction, 2, result) + elna_rtl_copy_operand(tac_instruction, 1, instruction); + elna_rtl_copy_operand(tac_instruction, 2, instruction); + elna_list_append(instructions, instruction) elsif tac_instruction^.operator = ElnaTacOperator.add then - result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.add) + elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator.add) elsif tac_instruction^.operator = ElnaTacOperator.load then - result := elna_rtl_load(tac_instruction, next_instruction) + elna_rtl_load(instructions, tac_instruction) elsif tac_instruction^.operator = ElnaTacOperator.store then - result := elna_rtl_store(tac_instruction, next_instruction) + elna_rtl_store(instructions, tac_instruction) elsif tac_instruction^.operator = ElnaTacOperator.proc_call then - result := elna_rtl_call(tac_instruction, next_instruction, variable_map) + elna_rtl_call(instructions, tac_instruction, variable_map) elsif tac_instruction^.operator = ElnaTacOperator.subtract then - result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.sub) + elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator.sub) elsif tac_instruction^.operator = ElnaTacOperator.multiply then - result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.mul) + elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator.mul) elsif tac_instruction^.operator = ElnaTacOperator.divide then - result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.div) + elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator.div) elsif tac_instruction^.operator = ElnaTacOperator.remainder then - result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.rem) + elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator.rem) elsif tac_instruction^.operator = ElnaTacOperator._xor then - result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator._xor) + elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator._xor) elsif tac_instruction^.operator = ElnaTacOperator._or then - result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator._or) + elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator._or) elsif tac_instruction^.operator = ElnaTacOperator.and then - result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.and) + elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator.and) elsif tac_instruction^.operator = ElnaTacOperator.less_than then - result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.slt) + elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator.slt) elsif tac_instruction^.operator = ElnaTacOperator.greater_than then - operands := elna_rtl_binary_operands(tac_instruction, next_instruction); + elna_rtl_binary_operands(instructions, tac_instruction); - result := elna_rtl_instruction_create(ElnaRtlOperator.slt); - elna_rtl_copy_operand(tac_instruction, 1, result); - elna_rtl_instruction_set_operand(result, 2, ElnaRtlKind.register, ElnaRtlRegister.t3, 0); - elna_rtl_instruction_set_operand(result, 3, ElnaRtlKind.register, ElnaRtlRegister.t2, 0); - - intermediate_instruction := next_instruction^; - intermediate_instruction^.next := result; - next_instruction^ := result; - - result := operands; - next_instruction^^.operator := ElnaRtlOperator.slt + instruction := elna_rtl_instruction_create(ElnaRtlOperator.slt); + elna_rtl_copy_operand(tac_instruction, 1, instruction); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.t3, 0); + elna_rtl_instruction_set_operand(instruction, 3, ElnaRtlKind.register, ElnaRtlRegister.t2, 0); + elna_list_append(instructions, instruction) elsif tac_instruction^.operator = ElnaTacOperator.less_or_equal then - operands := elna_rtl_binary_operands(tac_instruction, next_instruction); - intermediate_instruction := elna_rtl_instruction_create(ElnaRtlOperator.slt); - - elna_rtl_instruction_set_operand(intermediate_instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t2, 0); - elna_rtl_instruction_set_operand(intermediate_instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.t3, 0); - elna_rtl_instruction_set_operand(intermediate_instruction, 3, ElnaRtlKind.register, ElnaRtlRegister.t2, 0); - result := next_instruction^; - result^.next := intermediate_instruction; - next_instruction^ := intermediate_instruction; - - result := elna_rtl_instruction_create(ElnaRtlOperator.xori); - elna_rtl_copy_operand(tac_instruction, 1, result); - elna_rtl_instruction_set_operand(result, 2, ElnaRtlKind.register, ElnaRtlRegister.t2, 0); - elna_rtl_instruction_set_operand(result, 3, ElnaRtlKind.immediate, 1, 0); - intermediate_instruction := next_instruction^; - intermediate_instruction^.next := result; - next_instruction^ := result; - result := operands + elna_rtl_binary_comparison(instructions, tac_instruction, ElnaRtlRegister.t3, ElnaRtlRegister.t2) elsif tac_instruction^.operator = ElnaTacOperator.greater_or_equal then - operands := elna_rtl_binary_operands(tac_instruction, next_instruction); - intermediate_instruction := elna_rtl_instruction_create(ElnaRtlOperator.slt); - - elna_rtl_instruction_set_operand(intermediate_instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t2, 0); - elna_rtl_instruction_set_operand(intermediate_instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.t2, 0); - elna_rtl_instruction_set_operand(intermediate_instruction, 3, ElnaRtlKind.register, ElnaRtlRegister.t3, 0); - result := next_instruction^; - result^.next := intermediate_instruction; - next_instruction^ := intermediate_instruction; - - result := elna_rtl_instruction_create(ElnaRtlOperator.xori); - elna_rtl_copy_operand(tac_instruction, 1, result); - elna_rtl_instruction_set_operand(result, 2, ElnaRtlKind.register, ElnaRtlRegister.t2, 0); - elna_rtl_instruction_set_operand(result, 3, ElnaRtlKind.immediate, 1, 0); - intermediate_instruction := next_instruction^; - intermediate_instruction^.next := result; - next_instruction^ := result; - result := operands + elna_rtl_binary_comparison(instructions, tac_instruction, ElnaRtlRegister.t2, ElnaRtlRegister.t3) elsif tac_instruction^.operator = ElnaTacOperator.equal then - result := elna_rtl_binary_equality(tac_instruction, ElnaRtlOperator.seqz, next_instruction) + elna_rtl_binary_equality(instructions, tac_instruction, ElnaRtlOperator.seqz) elsif tac_instruction^.operator = ElnaTacOperator.not_equal then - result := elna_rtl_binary_equality(tac_instruction, ElnaRtlOperator.snez, next_instruction) + elna_rtl_binary_equality(instructions, tac_instruction, ElnaRtlOperator.snez) elsif tac_instruction^.operator = ElnaTacOperator.negate then - result := elna_rtl_unary(tac_instruction, ElnaRtlOperator.neg, next_instruction) + elna_rtl_unary(instructions, tac_instruction, ElnaRtlOperator.neg) elsif tac_instruction^.operator = ElnaTacOperator.complement then - result := elna_rtl_unary(tac_instruction, ElnaRtlOperator.not, next_instruction) + elna_rtl_unary(instructions, tac_instruction, ElnaRtlOperator.not) elsif tac_instruction^.operator = ElnaTacOperator.jump then - result := elna_rtl_instruction_create(ElnaRtlOperator.j); - elna_rtl_copy_operand(tac_instruction, 1, result) + instruction := elna_rtl_instruction_create(ElnaRtlOperator.j); + elna_rtl_copy_operand(tac_instruction, 1, instruction); + elna_list_append(instructions, instruction) elsif tac_instruction^.operator = ElnaTacOperator.jump_if_zero then - result := elna_rtl_conditional_jump(tac_instruction, ElnaRtlOperator.beqz) + elna_rtl_conditional_jump(instructions, tac_instruction, ElnaRtlOperator.beqz) elsif tac_instruction^.operator = ElnaTacOperator.jump_if_not_zero then - result := elna_rtl_conditional_jump(tac_instruction, ElnaRtlOperator.bnez) + elna_rtl_conditional_jump(instructions, tac_instruction, ElnaRtlOperator.bnez) elsif tac_instruction^.operator = ElnaTacOperator._return then - result := elna_rtl_load_operand_value(tac_instruction, 1, ElnaRtlRegister.a0) + elna_rtl_load_operand_value(instructions, tac_instruction, 1, ElnaRtlRegister.a0) elsif tac_instruction^.operator = ElnaTacOperator.label then - result := elna_rtl_instruction_create(ElnaRtlOperator.label); - elna_rtl_copy_operand(tac_instruction, 1, result) + instruction := elna_rtl_instruction_create(ElnaRtlOperator.label); + elna_rtl_copy_operand(tac_instruction, 1, instruction); + elna_list_append(instructions, instruction) elsif tac_instruction^.operator = ElnaTacOperator.copy then if tac_instruction^.operands[1].kind = ElnaTacKind.pseudo then - operands := elna_rtl_load_operand_value(tac_instruction, 2, ElnaRtlRegister.t4); - result := operands; - operands := result^.next; + elna_rtl_load_operand_value(instructions, tac_instruction, 2, ElnaRtlRegister.t4); - next_instruction^ := elna_rtl_instruction_create(ElnaRtlOperator.move); - elna_tac_instruction_set_operand(next_instruction^, 1, ElnaRtlKind.pseudo, + instruction := elna_rtl_instruction_create(ElnaRtlOperator.move); + elna_tac_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo, tac_instruction^.operands[1].value, tac_instruction^.operands[1].length); - elna_tac_instruction_set_operand(next_instruction^, 2, ElnaRtlKind.register, ElnaRtlRegister.t4, 0); - - if operands = nil then - result^.next := next_instruction^ - else - operands^.next := next_instruction^ - end + elna_tac_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.t4, 0); + elna_list_append(instructions, instruction) end - end; - if next_instruction^ = nil then - next_instruction^ := result; - end; - return result + end end; proc elna_tac_label(instructions: ^ElnaList, counter: Word, length: Word); @@ -1622,32 +1487,15 @@ begin _write_c('\n') end; -proc elna_rtl_instructions(instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable); -var - last_copy: ^ElnaRtlInstruction; - current_copy: ^ElnaRtlInstruction; - next_copy: ^ElnaRtlInstruction; - first_copy: ^ElnaRtlInstruction; +proc elna_rtl_instructions(instructions: ^ElnaList, instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable); begin - if instruction <> nil then - first_copy := elna_rtl_instruction(instruction, @current_copy, variable_map); - instruction := instruction^.next - else - first_copy := nil; - current_copy := nil - end; .elna_rtl_instructions_start; - if instruction <> nil then - next_copy := elna_rtl_instruction(instruction, @last_copy, variable_map); - + elna_rtl_instruction(instructions, instruction, variable_map); instruction := instruction^.next; - current_copy^.next := next_copy; - current_copy := last_copy; - goto elna_rtl_instructions_start - end; - return first_copy + goto elna_rtl_instructions_start + end end; proc elna_alloc_instructions(instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable); @@ -1678,10 +1526,10 @@ begin .elna_alloc_procedure_loop; temporary_variable_counter := 0; - elna_alloc_instructions(rtl_declaration^.body, rtl_declaration^.variable_map); + elna_alloc_instructions(rtl_declaration^.body.first, rtl_declaration^.variable_map); stack_instruction := elna_rtl_instruction_create(ElnaRtlOperator.allocate_stack); - stack_instruction^.next := rtl_declaration^.body; + stack_instruction^.next := rtl_declaration^.body.first; elna_rtl_instruction_set_operand(stack_instruction, 1, ElnaRtlKind.immediate, temporary_variable_counter, 0); rtl_declaration^.body := stack_instruction; @@ -2137,26 +1985,37 @@ begin end; elna_tac_designator(instructions, unary_operand, symbol_table, @is_address, @base); - elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table); - if operator = '@' then + elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table); elna_tac_copy_address(instructions, is_address, @base, operand) elsif operator = '-' then + elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table); + instruction := elna_tac_instruction_create(ElnaTacOperator.negate); elna_tac_instruction_set_operand(instruction, 1, operand^.kind, operand^.value, operand^.length); elna_tac_instruction_set_operand(instruction, 2, base.kind, base.value, base.length); elna_list_append(instructions, instruction) elsif operator = '~' then + elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table); + instruction := elna_tac_instruction_create(ElnaTacOperator.complement); elna_tac_instruction_set_operand(instruction, 1, operand^.kind, operand^.value, operand^.length); elna_tac_instruction_set_operand(instruction, 2, base.kind, base.value, base.length); elna_list_append(instructions, instruction) elsif is_address then + elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table); + instruction := elna_tac_instruction_create(ElnaTacOperator.load); elna_tac_instruction_set_operand(instruction, 1, base.kind, base.value, base.length); elna_tac_instruction_set_operand(instruction, 2, operand^.kind, operand^.value, operand^.length); elna_list_append(instructions, instruction) + elsif base.kind = ElnaTacKind.pseudo then + operand^.kind := base.kind; + operand^.value := base.value; + operand^.length := base.length else + elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table); + instruction := elna_tac_instruction_create(ElnaTacOperator.copy); elna_tac_instruction_set_operand(instruction, 1, operand^.kind, operand^.value, operand^.length); elna_tac_instruction_set_operand(instruction, 2, base.kind, base.value, base.length); @@ -2234,7 +2093,6 @@ end; proc elna_tac_binary_expression(instructions: ^ElnaList, parser_node: ^ElnaTreeBinaryExpression, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand); var - first_instruction: Word; instruction: Word; lhs: ElnaTacOperand; rhs: ElnaTacOperand; @@ -3541,11 +3399,10 @@ begin return result end; -proc elna_rtl_parameters(parameters: Word, count: Word); +proc elna_rtl_parameters(instructions: ^ElnaList, parameters: Word, count: Word); var result: ^ElnaRtlInstruction; - current_instruction: ^ElnaRtlInstruction; - last_instruction: Word; + instruction: ^ElnaRtlInstruction; parameter_index: Word; parameter_name: Word; name_length: Word; @@ -3560,16 +3417,10 @@ begin name_length := parameters^; parameters := parameters + 4; - current_instruction := elna_rtl_instruction_create(ElnaRtlOperator.move); - elna_rtl_instruction_set_operand(current_instruction, 1, ElnaRtlKind.pseudo, parameter_name, name_length); - elna_rtl_instruction_set_operand(current_instruction, 2, ElnaRtlKind.register, 11 + parameter_index, 0); - - if result = nil then - result := current_instruction - else - elna_instruction_list_concatenate(last_instruction, current_instruction) - end; - last_instruction := current_instruction; + instruction := elna_rtl_instruction_create(ElnaRtlOperator.move); + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo, parameter_name, name_length); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, 11 + parameter_index, 0); + elna_list_append(instructions, instruction); parameter_index := parameter_index + 1; goto elna_rtl_parameters_loop @@ -3640,19 +3491,18 @@ end; proc elna_rtl_procedure_declaration(tac_declaration: ^ElnaTacProcedure); var result: ^ElnaRtlProcedure; - body: ^ElnaRtlInstruction; - parameters: ^ElnaRtlInstruction; begin result := malloc(#size(ElnaRtlProcedure)); + elna_list_initialize(@result^.body); result^.next := nil; result^.name := tac_declaration^.name; result^.length := tac_declaration^.length; - parameters = elna_rtl_parameters(tac_declaration^.parameters, tac_declaration^.count); + elna_rtl_parameters(@result^.body, tac_declaration^.parameters, tac_declaration^.count); + result^.variable_map := elna_rtl_symbol_table(tac_declaration^.symbol_table); - body := elna_rtl_instructions(tac_declaration^.body, result^.variable_map); - result^.body := elna_instruction_list_concatenate(parameters, body); + elna_rtl_instructions(@result^.body, tac_declaration^.body.first, result^.variable_map); return result end;