diff --git a/boot/stage21/cl.elna b/boot/stage21/cl.elna index 8c613e1..c6d7837 100644 --- a/boot/stage21/cl.elna +++ b/boot/stage21/cl.elna @@ -917,11 +917,10 @@ end; (** * Loads or moves the value from a TAC operand into the given register. *) -proc elna_rtl_load_operand_value(instructions: ^ElnaList, operand: ^ElnaTacOperand, +proc elna_rtl_hardware_value(instructions: ^ElnaList, operand: ^ElnaTacOperand, into: ElnaRtlRegister, variable_map: ^ElnaSymbolTable); var instruction: ^ElnaRtlInstruction; - pseudo_symbol: ^ElnaRtlInfo; begin if operand^.kind = ElnaTacKind.constant then instruction := elna_rtl_instruction_create(ElnaRtlOperator.li); @@ -929,25 +928,14 @@ begin elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.immediate, operand^.value, operand^.length, 0); elna_list_append(instructions, instruction) elsif operand^.kind = ElnaTacKind.variable then - pseudo_symbol := elna_symbol_table_lookup(variable_map, operand^.value, operand^.length); - if pseudo_symbol^.kind = ElnaRtlInfoKind.static_info then - instruction := elna_rtl_instruction_create(ElnaRtlOperator.la); - elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0, 0); - elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.data, operand^.value, operand^.length, 0); - elna_list_append(instructions, instruction); - - instruction := elna_rtl_instruction_create(ElnaRtlOperator.lw); - elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0, 0); - elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.memory, into, 0, 0) - else - instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv); - elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0, 0); - elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo, operand^.value, operand^.length, 0) - end; + instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv); + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0, 0); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo, operand^.value, operand^.length, 0); elna_list_append(instructions, instruction) end end; + proc elna_rtl_operand_value(instructions: ^ElnaList, tac_operand: ^ElnaTacOperand, variable_map: ^ElnaSymbolTable, rtl_operand: ^ElnaRtlOperand) -> ^ElnaRtlInfo; var @@ -1183,7 +1171,7 @@ begin if argument_count > 0 then argument_count := argument_count - 1; - elna_rtl_load_operand_value(instructions, current_argument, ElnaRtlRegister.a0 + current_register, variable_map); + elna_rtl_hardware_value(instructions, current_argument, ElnaRtlRegister.a0 + current_register, variable_map); current_argument := current_argument + 1; current_register := current_register + 1; @@ -1267,59 +1255,50 @@ begin elna_list_append(instructions, instruction) end; +proc elna_rtl_memcpy(instructions: ^ElnaList, source_operand: ^ElnaRtlOperand, byte_array: ^ElnaRtlTypeByteArray, + target_type: Word, target_value: Word, target_length: Word); +var + instruction: ElnaRtlInstruction; +begin + instruction := elna_rtl_instruction_create(ElnaRtlOperator.la); + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a0, 0, 0); + elna_rtl_instruction_set_operand(instruction, 2, target_type, target_value, target_length, 0); + elna_list_append(instructions, instruction); + + instruction := elna_rtl_instruction_create(ElnaRtlOperator.la); + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a1, 0, 0); + elna_rtl_instruction_set_operand(instruction, 2, source_operand^.kind, source_operand^.value, source_operand^.length, 0); + elna_list_append(instructions, instruction); + + instruction := elna_rtl_instruction_create(ElnaRtlOperator.li); + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a2, 0, 0); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.immediate, byte_array^.size, 0, 0); + elna_list_append(instructions, instruction); + + instruction := elna_rtl_instruction_create(ElnaRtlOperator.jal); + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.data, "memcpy", 6, 0); + elna_list_append(instructions, instruction) +end; + proc elna_rtl_copy(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable); var instruction: ^ElnaRtlInstruction; source_operand: ElnaRtlOperand; - target_operand: ElnaRtlOperand; pseudo_symbol: ^ElnaRtlObjectInfo; - byte_array: ^ElnaRtlTypeByteArray; begin elna_rtl_operand_value(instructions, @tac_instruction^.operands[1], variable_map, @source_operand); pseudo_symbol := elna_symbol_table_lookup(variable_map, tac_instruction^.operands[2].value, tac_instruction^.operands[2].length); - if pseudo_symbol^.kind = ElnaRtlInfoKind.static_info then - elna_rtl_generate_pseudo(@target_operand, 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, 0); - elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.data, - tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0); - 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, 0); - elna_rtl_instruction_set_operand(instruction, 2, target_operand.kind, target_operand.value, target_operand.length, 0); - elna_list_append(instructions, instruction) - elsif source_operand.kind = ElnaRtlKind.pseudo then + if source_operand.kind = ElnaRtlKind.pseudo then instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv); elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo, tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0); elna_rtl_instruction_set_operand(instruction, 2, source_operand.kind, source_operand.value, source_operand.length, 0); elna_list_append(instructions, instruction); else - byte_array := pseudo_symbol^.rtl_type; - - instruction := elna_rtl_instruction_create(ElnaRtlOperator.la); - elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a0, 0, 0); - elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo, - tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0); - elna_list_append(instructions, instruction); - - instruction := elna_rtl_instruction_create(ElnaRtlOperator.la); - elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a1, 0, 0); - elna_rtl_instruction_set_operand(instruction, 2, source_operand.kind, source_operand.value, source_operand.length, 0); - elna_list_append(instructions, instruction); - - instruction := elna_rtl_instruction_create(ElnaRtlOperator.li); - elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a2, 0, 0); - elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.immediate, byte_array^.size, 0, 0); - elna_list_append(instructions, instruction); - - instruction := elna_rtl_instruction_create(ElnaRtlOperator.jal); - elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.data, "memcpy", 6, 0); - elna_list_append(instructions, instruction) + elna_rtl_memcpy(instructions, @source_operand, pseudo_symbol^.rtl_type, ElnaRtlKind.pseudo, + tac_instruction^.operands[2].value, tac_instruction^.operands[2].length) end end; @@ -1383,7 +1362,7 @@ begin elsif tac_instruction^.operator = ElnaTacOperator.jump_if_not_zero then elna_rtl_conditional_jump(instructions, tac_instruction, ElnaRtlOperator.bnez, variable_map) elsif tac_instruction^.operator = ElnaTacOperator._return then - elna_rtl_load_operand_value(instructions, @tac_instruction^.operands[1], ElnaRtlRegister.a0, variable_map) + elna_rtl_hardware_value(instructions, @tac_instruction^.operands[1], ElnaRtlRegister.a0, variable_map) elsif tac_instruction^.operator = ElnaTacOperator.label then instruction := elna_rtl_instruction_create(ElnaRtlOperator.label); elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.data, @@ -1652,37 +1631,87 @@ end; proc elna_alloc_move(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; var + load_instruction: ^ElnaRtlInstruction; + target_operand: ElnaRtlOperand; pseudo_symbol: ^ElnaRtlObjectInfo; destination_pseudo: Word; source_pseudo: Word; begin + memcpy(@target_operand, @instruction^.operands[1], #size(ElnaRtlOperand)); destination_pseudo := instruction^.operands[1].kind = ElnaRtlKind.pseudo; source_pseudo := instruction^.operands[2].kind = ElnaRtlKind.pseudo; if destination_pseudo & source_pseudo then + pseudo_symbol := elna_symbol_table_lookup(variable_map, target_operand.value, target_operand.length); instruction := elna_alloc_operand(instructions, instruction, 2, ElnaRtlRegister.t0, variable_map); - pseudo_symbol := elna_alloc_variable(instruction^.operands[1].value, instruction^.operands[1].length, - variable_map); - instruction^.operator = ElnaRtlOperator.sw; - elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t0, 0, 0); - elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.memory, - ElnaRtlRegister.sp, 0, pseudo_symbol^.counter) - elsif destination_pseudo then - pseudo_symbol := elna_alloc_variable(instruction^.operands[1].value, instruction^.operands[1].length, - variable_map); - instruction^.operator = ElnaRtlOperator.sw; + if pseudo_symbol^.kind = ElnaRtlInfoKind.static_info then + load_instruction := malloc(#size(ElnaRtlInstruction)); + memcpy(load_instruction, instruction, #size(ElnaRtlInstruction)); + load_instruction^.next := nil; - elna_rtl_instruction_set_operand(instruction, 1, instruction^.operands[2].kind, - instruction^.operands[2].value, instruction^.operands[2].length, 0); - elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.memory, - ElnaRtlRegister.sp, 0, pseudo_symbol^.counter) + instruction^.operator = ElnaRtlOperator.la; + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t1, 0, 0); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.data, target_operand.value, target_operand.length, 0); + elna_list_insert(instructions, instruction, load_instruction); + + load_instruction^.operator = ElnaRtlOperator.sw; + elna_rtl_instruction_set_operand(load_instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t0, 0, 0); + elna_rtl_instruction_set_operand(load_instruction, 2, ElnaRtlKind.memory, ElnaRtlRegister.t1, 0, 0) + else + pseudo_symbol := elna_alloc_variable(instruction^.operands[1].value, instruction^.operands[1].length, + variable_map); + instruction^.operator = ElnaRtlOperator.sw; + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t0, 0, 0); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.memory, + ElnaRtlRegister.sp, 0, pseudo_symbol^.counter) + end + elsif destination_pseudo then + pseudo_symbol := elna_symbol_table_lookup(variable_map, + instruction^.operands[1].value, instruction^.operands[1].length); + + if pseudo_symbol^.kind = ElnaRtlInfoKind.static_info then + load_instruction := malloc(#size(ElnaRtlInstruction)); + memcpy(load_instruction, instruction, #size(ElnaRtlInstruction)); + load_instruction^.next := nil; + + instruction^.operator = ElnaRtlOperator.la; + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t1, 0, 0); + elna_list_insert(instructions, instruction, load_instruction); + + load_instruction^.operator = ElnaRtlOperator.sw; + elna_rtl_instruction_set_operand(load_instruction, 2, ElnaRtlKind.memory, ElnaRtlRegister.t1, 0, 0) + else + pseudo_symbol := elna_alloc_variable(target_operand.value, target_operand.length, variable_map); + instruction^.operator = ElnaRtlOperator.sw; + + elna_rtl_instruction_set_operand(instruction, 1, instruction^.operands[2].kind, + instruction^.operands[2].value, instruction^.operands[2].length, 0); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.memory, + ElnaRtlRegister.sp, 0, pseudo_symbol^.counter) + end elsif source_pseudo then - pseudo_symbol := elna_alloc_variable(instruction^.operands[2].value, instruction^.operands[2].length, - variable_map); - instruction^.operator = ElnaRtlOperator.lw; - elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.memory, - ElnaRtlRegister.sp, 0, pseudo_symbol^.counter) + pseudo_symbol := elna_symbol_table_lookup(variable_map, + instruction^.operands[2].value, instruction^.operands[2].length); + + if pseudo_symbol^.kind = ElnaRtlInfoKind.static_info then + load_instruction := malloc(#size(ElnaRtlInstruction)); + memcpy(load_instruction, instruction, #size(ElnaRtlInstruction)); + load_instruction^.next := nil; + + instruction^.operator := ElnaRtlOperator.la; + elna_list_insert(instructions, instruction, load_instruction); + + load_instruction^.operator = ElnaRtlOperator.lw; + elna_rtl_instruction_set_operand(load_instruction, 2, ElnaRtlKind.memory, + instruction^.operands[1].value, instruction^.operands[1].length, 0) + else + pseudo_symbol := elna_alloc_variable(instruction^.operands[2].value, instruction^.operands[2].length, + variable_map); + instruction^.operator = ElnaRtlOperator.lw; + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.memory, + ElnaRtlRegister.sp, 0, pseudo_symbol^.counter) + end end; return instruction end;