diff --git a/Rakefile b/Rakefile index 39aa6c6..c48a248 100644 --- a/Rakefile +++ b/Rakefile @@ -44,17 +44,15 @@ task :convert do seen_proc = false if line.start_with? 'end' if line.start_with?('begin') && !seen_proc current_stage << <<~FUN - proc f(); var - x: ^ElnaLocation; - y: ElnaLocation; + x: ElnaType; + y: ElnaTypeField; begin - x := malloc(#size(ElnaLocation)); - y.line := 1; - y.column := 3; - x^ := y; - printf("# %i %i %i %i\\n\\0", x^.line, x^.column, y.line, y.column) + x.size := 3; + y.field_type := malloc(#size(ElnaType)); + y.field_type^ := x; + printf("# %i\\n\\0", y.field_type^.size) end; begin diff --git a/boot/stage21/cl.elna b/boot/stage21/cl.elna index 16de300..b8672f9 100644 --- a/boot/stage21/cl.elna +++ b/boot/stage21/cl.elna @@ -1181,14 +1181,37 @@ proc elna_rtl_store(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstructio var instruction: ^ElnaRtlInstruction; rtl_operand: ElnaRtlOperand; + pseudo_symbol: ^ElnaRtlObjectInfo; begin elna_rtl_operand_value(instructions, @tac_instruction^.operands[1], variable_map, @rtl_operand); - instruction := elna_rtl_instruction_create(ElnaRtlOperator.sw); - elna_rtl_instruction_set_operand(instruction, 1, rtl_operand.kind, rtl_operand.value, rtl_operand.length, 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) + pseudo_symbol := elna_symbol_table_lookup(variable_map, + tac_instruction^.operands[1].value, tac_instruction^.operands[1].length); + if pseudo_symbol <> nil then + if pseudo_symbol^.rtl_type^.kind = ElnaRtlTypeKind.byte_array then + instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv); + 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, rtl_operand.kind, rtl_operand.value, rtl_operand.length, 0); + elna_list_append(instructions, instruction); + + elna_rtl_memcpy(instructions, pseudo_symbol^.rtl_type) + else + pseudo_symbol = nil + end + end; + if pseudo_symbol = nil then + instruction := elna_rtl_instruction_create(ElnaRtlOperator.sw); + elna_rtl_instruction_set_operand(instruction, 1, rtl_operand.kind, rtl_operand.value, rtl_operand.length, 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) + end; end; proc elna_rtl_copy_to_offset(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable); @@ -1196,18 +1219,48 @@ var instruction: ^ElnaRtlInstruction; target_operand: ElnaRtlOperand; source_operand: ElnaRtlOperand; + pseudo_symbol: ^ElnaRtlObjectInfo; begin - elna_rtl_generate_pseudo(@target_operand, variable_map); - instruction := elna_rtl_operand_address(variable_map, @tac_instruction^.operands[2], @target_operand); - elna_list_append(instructions, instruction); - elna_rtl_operand_value(instructions, @tac_instruction^.operands[1], variable_map, @source_operand); - 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, tac_instruction^.operands[3].value); - elna_list_append(instructions, instruction) + pseudo_symbol := elna_symbol_table_lookup(variable_map, + tac_instruction^.operands[1].value, tac_instruction^.operands[1].length); + if pseudo_symbol <> nil then + if pseudo_symbol^.rtl_type^.kind = ElnaRtlTypeKind.byte_array then + 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.addi); + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a0, 0, 0); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.a0, 0, 0); + elna_rtl_instruction_set_operand(instruction, 3, ElnaRtlKind.immediate, tac_instruction^.operands[3].value, 0, 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); + + elna_rtl_memcpy(instructions, pseudo_symbol^.rtl_type) + + else + pseudo_symbol := nil + end + end; + if pseudo_symbol = nil then + elna_rtl_generate_pseudo(@target_operand, variable_map); + instruction := elna_rtl_operand_address(variable_map, @tac_instruction^.operands[2], @target_operand); + 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, tac_instruction^.operands[3].value); + elna_list_append(instructions, instruction) + end end; proc elna_rtl_load(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable); @@ -1221,8 +1274,18 @@ begin tac_instruction^.operands[2].value, tac_instruction^.operands[2].length); if pseudo_symbol^.rtl_type^.kind = ElnaRtlTypeKind.byte_array then - elna_rtl_memcpy(instructions, @rtl_operand, pseudo_symbol^.rtl_type, rtl_operand.kind, - tac_instruction^.operands[2].value, tac_instruction^.operands[2].length) + 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.mv); + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a1, 0, 0); + elna_rtl_instruction_set_operand(instruction, 2, rtl_operand.kind, rtl_operand.value, rtl_operand.length, 0); + elna_list_append(instructions, instruction); + + elna_rtl_memcpy(instructions, pseudo_symbol^.rtl_type) else instruction := elna_rtl_instruction_create(ElnaRtlOperator.lw); elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo, @@ -1251,25 +1314,10 @@ 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); +proc elna_rtl_memcpy(instructions: ^ElnaList, byte_array: ^ElnaRtlTypeByteArray); 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); - - if source_operand^.kind = ElnaRtlKind.pseudo then - instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv) - else - instruction := elna_rtl_instruction_create(ElnaRtlOperator.la) - end; - 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); @@ -1297,8 +1345,18 @@ begin elna_rtl_instruction_set_operand(instruction, 2, source_operand.kind, source_operand.value, source_operand.length, 0); elna_list_append(instructions, instruction); else - elna_rtl_memcpy(instructions, @source_operand, pseudo_symbol^.rtl_type, source_operand.kind, - tac_instruction^.operands[2].value, tac_instruction^.operands[2].length) + 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_mem, + 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); + + elna_rtl_memcpy(instructions, pseudo_symbol^.rtl_type) end end; @@ -2909,18 +2967,24 @@ proc elna_tac_dereference_expression(instructions: ^ElnaList, dereference_expres var load_instruction: ^ElnaTacInstruction; operand_result: ElnaTacOperandResult; + intermediate: ElnaTacOperand; begin elna_tac_designator(instructions, dereference_expression^.pointer, symbol_table, @operand_result, operand); if operand_result.kind = ElnaTacOperandType.dereferenced_pointer then - load_instruction := elna_tac_instruction_create(ElnaTacOperator.load); - elna_tac_instruction_set_operand(load_instruction, 1, operand^.kind, operand^.value, operand^.length); - elna_tac_instruction_set_operand(load_instruction, 2, operand^.kind, operand^.value, operand^.length); + memcpy(@intermediate, operand, #size(ElnaTacOperand)); + elna_tac_make_variable(operand, symbol_table, word_type); + load_instruction := elna_tac_instruction_create(ElnaTacOperator.load); + elna_tac_instruction_set_operand(load_instruction, 1, intermediate.kind, intermediate.value, intermediate.length); + elna_tac_instruction_set_operand(load_instruction, 2, operand^.kind, operand^.value, operand^.length); elna_list_append(instructions, load_instruction) elsif operand_result.kind = ElnaTacOperandType.sub_object then + memcpy(@intermediate, operand, #size(ElnaTacOperand)); + elna_tac_make_variable(operand, symbol_table, word_type); + load_instruction := elna_tac_instruction_create(ElnaTacOperator.copy_from_offset); - elna_tac_instruction_set_operand(load_instruction, 1, operand^.kind, operand^.value, operand^.length); + elna_tac_instruction_set_operand(load_instruction, 1, intermediate.kind, intermediate.value, intermediate.length); elna_tac_instruction_set_operand(load_instruction, 2, ElnaTacKind.constant, operand_result.offset, 0); elna_tac_instruction_set_operand(load_instruction, 3, operand^.kind, operand^.value, operand^.length); elna_list_append(instructions, load_instruction)