diff --git a/boot/stage15/cl.elna b/boot/stage15/cl.elna index 3f2dde2..031cec2 100644 --- a/boot/stage15/cl.elna +++ b/boot/stage15/cl.elna @@ -1109,10 +1109,10 @@ begin _write_s("\tbeqz", 5) elsif instruction_kind = ElnaTacOperator.start then argument_count := 0; - _write_z("\taddi sp, sp, -128\n\tsw ra, 124(sp)\n\tsw s0, 120(sp)\n\taddi s0, sp, 128\0") + _write_z("\taddi sp, sp, -144\n\tsw ra, 140(sp)\n\tsw s0, 136(sp)\n\taddi s0, sp, 144\0") elsif instruction_kind = ElnaTacOperator.ret then argument_count := 0; - _write_z("\tlw ra, 124(sp)\n\tlw s0, 120(sp)\n\taddi sp, sp, 128\0") + _write_z("\tlw ra, 140(sp)\n\tlw s0, 136(sp)\n\taddi sp, sp, 144\0") end; return argument_count end; @@ -1900,7 +1900,7 @@ begin first_instruction := _elna_tac_unary_expression(operand_node, symbol_table); (* Save the value of the left expression on the stack. *) - instruction := _elna_tac_store_word(ElnaTacRegister.t0, ElnaTacRegister.sp, 64); + instruction := _elna_tac_store_word(ElnaTacRegister.t0, ElnaTacRegister.sp, 72); _elna_tac_instruction_set_next(first_instruction, instruction); current_instruction := instruction; @@ -1910,7 +1910,7 @@ begin current_instruction := instruction; (* Load the left expression from the stack; *) - instruction := _elna_tac_load_word(ElnaTacRegister.t1, ElnaTacRegister.sp, 64); + instruction := _elna_tac_load_word(ElnaTacRegister.t1, ElnaTacRegister.sp, 72); _elna_tac_instruction_set_next(current_instruction, instruction); current_instruction := instruction; @@ -2088,7 +2088,7 @@ begin stack_offset := argument_count * 4; instruction := _elna_tac_store_word(ElnaTacRegister.t0, - ElnaTacRegister.sp, 116 - stack_offset); + ElnaTacRegister.sp, 132 - stack_offset); _elna_tac_instruction_set_next(current_instruction, instruction); current_instruction := instruction; @@ -2103,9 +2103,9 @@ begin argument_count := argument_count - 1; stack_offset := argument_count * 4; - (* Calculate the stack offset: 116 - (4 * argument_counter) *) + (* Calculate the stack offset: 132 - (4 * argument_counter) *) instruction := _elna_tac_load_word(ElnaTacRegister.a0 + argument_count, - ElnaTacRegister.sp, 116 - stack_offset); + ElnaTacRegister.sp, 132 - stack_offset); _elna_tac_instruction_set_next(current_instruction, instruction); current_instruction := instruction; @@ -2502,7 +2502,7 @@ begin first_instruction := _elna_tac_designator(current_expression, symbol_table, @is_address); (* Save the assignee address on the stack. *) - current_instruction := _elna_tac_store_word(ElnaTacRegister.t0, ElnaTacRegister.sp, 60); + current_instruction := _elna_tac_store_word(ElnaTacRegister.t0, ElnaTacRegister.sp, 76); _elna_tac_instruction_set_next(first_instruction, current_instruction); (* Compile the assignment. *) @@ -2510,7 +2510,7 @@ begin instruction := _elna_tac_binary_expression(current_expression, symbol_table); _elna_tac_instruction_set_next(current_instruction, instruction); - current_instruction := _elna_tac_load_word(ElnaTacRegister.t1, ElnaTacRegister.sp, 60); + current_instruction := _elna_tac_load_word(ElnaTacRegister.t1, ElnaTacRegister.sp, 76); _elna_tac_instruction_set_next(instruction, current_instruction); instruction := _elna_tac_store_word(ElnaTacRegister.t0, ElnaTacRegister.t1, 0); @@ -3415,9 +3415,9 @@ begin current_word := current_word + 4; - (* Calculate the stack offset: 88 - (4 * parameter_counter) *) + (* Calculate the stack offset: 104 - (4 * parameter_counter) *) offset := parameter_index * 4; - current_word^ := 88 - offset; + current_word^ := 104 - offset; return result end; diff --git a/boot/stage16/cl.elna b/boot/stage16/cl.elna index f76edae..e7eb475 100644 --- a/boot/stage16/cl.elna +++ b/boot/stage16/cl.elna @@ -7,13 +7,13 @@ (* Stage 16 compiler. *) type - _elna_tac_declaration = record - next: Word; - name: Word; - length: Word; - body: Word + (** + * List of intermediate representation items. + *) + ElnaInstructionList = record + next: Word end; - elna_rtl_declaration = record + ElnaInstructionDeclaration = record next: Word; name: Word; length: Word; @@ -90,11 +90,7 @@ type field: Word; length: Word end; - _elna_tac_module = record - data: Word; - code: Word - end; - elna_rtl_module = record + ElnaInstructionModule = record data: Word; code: Word end; @@ -352,14 +348,12 @@ type InfoKind = (type_info, parameter_info, temporary_info, procedure_info); TypeKind = (primitive, enumeration, _record); ElnaTacOperator = ( - load_immediate, - load_address, + get_address, add, - add_immediate, load_word, store_word, jal, - move, + assign, sub, div, rem, @@ -367,10 +361,12 @@ type _xor, _or, and, - seqz, - snez, slt, - xor_immediate, + sgt, + sle, + sge, + seq, + sne, neg, not, jump, @@ -407,7 +403,7 @@ type start, ret ); - ElnaTacOperand = (register, immediate, symbol, offset); + ElnaTacOperand = (register, immediate, symbol, offset, stack); ElnaRtlOperand = (register, immediate, symbol, offset); ElnaRtlRegister = ( zero, @@ -454,6 +450,7 @@ var compiler_strings_length: Word; label_counter: Word; symbol_table_store: Word; + temporary_variable_counter: Word; (** * Calculates and returns the string token length between quotes, including the @@ -662,31 +659,37 @@ proc _elna_tac_instruction_size(); end; proc _elna_tac_instruction_get_kind(this: Word); +begin + this := this + 4; return this^ end; proc _elna_tac_instruction_set_kind(this: Word, value: Word); begin + this := this + 4; this^ := value end; -proc _elna_tac_instruction_get_next(this: Word); +proc elna_instruction_list_concatenate(this: Word, value: Word); +var + start: Word; begin - this := this + 4; - return this^ -end; - -proc _elna_tac_instruction_set_next(this: Word, value: Word); -begin - .elna_tac_instruction_set_next_loop; - this := this + 4; + if this = 0 then + start := value; + goto elna_instruction_list_concatenate_end + else + start := this + end; + .elna_instruction_list_concatenate_loop; if value <> 0 then if this^ <> 0 then this := this^; - goto elna_tac_instruction_set_next_loop + goto elna_instruction_list_concatenate_loop end end; - this^ := value + this^ := value; + .elna_instruction_list_concatenate_end; + return start end; proc _elna_tac_instruction_get_operand_type(this: Word, n: Word); @@ -742,7 +745,19 @@ begin result := malloc(_elna_tac_instruction_size()); _elna_tac_instruction_set_kind(result, kind); - _elna_tac_instruction_set_next(result, 0); + elna_instruction_list_concatenate(result, 0); + + return result +end; + +proc elna_rtl_instruction_create(kind: Word); +var + result: Word; +begin + result := malloc(elna_rtl_instruction_size()); + + elna_rtl_instruction_set_kind(result, kind); + ElnaInstructionList_set_next(result, 0); return result end; @@ -752,23 +767,14 @@ proc elna_rtl_instruction_size(); end; proc elna_rtl_instruction_get_kind(this: Word); - return this^ -end; - -proc elna_rtl_instruction_get_next(this: Word); begin this := this + 4; return this^ end; -proc elna_rtl_instruction_set_next(this: Word, value: Word); -begin - this := this + 4; - this^ := value -end; - proc elna_rtl_instruction_set_kind(this: Word, value: Word); begin + this := this + 4; this^ := value end; @@ -818,39 +824,300 @@ begin this^ := operand_length end; -proc elna_rtl_instruction(tac_instruction: Word); +proc elna_rtl_load_operand_value(tac_instruction: Word, operand_number: Word, into: Word); var result: Word; + operand_value: Word; + operand_length: Word; + operand_type: Word; + next_instruction: Word; instruction_size: Word; begin instruction_size := elna_rtl_instruction_size(); + operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, operand_number); + operand_length := _elna_tac_instruction_get_operand_length(tac_instruction, operand_number); + operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, operand_number); result := malloc(instruction_size); - memcpy(result, tac_instruction, instruction_size); + if operand_type = ElnaTacOperand.immediate then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.load_immediate); + elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0); + elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.immediate, operand_value, operand_length); + ElnaInstructionList_set_next(result, 0) + elsif operand_type = ElnaTacOperand.stack then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.load_word); + elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0); + elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, operand_value); + ElnaInstructionList_set_next(result, 0) + elsif operand_type = ElnaTacOperand.symbol then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.load_address); + elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0); + elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.symbol, operand_value, operand_length); + + next_instruction := malloc(instruction_size); + elna_rtl_instruction_set_kind(next_instruction, ElnaRtlOperator.load_word); + elna_rtl_instruction_set_operand(next_instruction, 1, ElnaRtlOperand.register, into, 0); + elna_rtl_instruction_set_operand(next_instruction, 2, ElnaRtlOperand.offset, into, 0); + ElnaInstructionList_set_next(next_instruction, 0); + + ElnaInstructionList_set_next(result, next_instruction) + elsif operand_type = ElnaTacOperand.register then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.move); + elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0); + elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.register, operand_value, 0); + ElnaInstructionList_set_next(result, 0) + end; return result end; -proc _elna_tac_module_create(data: Word, code: Word); +proc elna_rtl_load_operand_address(tac_instruction: Word, operand_number: Word, into: Word); var result: Word; + operand_value: Word; + operand_length: Word; + operand_type: Word; begin - result := malloc(_elna_tac_module_size()); + operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, operand_number); + operand_length := _elna_tac_instruction_get_operand_length(tac_instruction, operand_number); + operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, operand_number); - _elna_tac_module_set_data(result, data); - _elna_tac_module_set_code(result, code); + result := malloc(elna_rtl_instruction_size()); + ElnaInstructionList_set_next(result, 0); + + if operand_type = ElnaTacOperand.stack then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.add_immediate); + elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0); + elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, operand_value); + elsif operand_type = ElnaTacOperand.symbol then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.load_address); + elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0); + elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.symbol, operand_value, operand_length) + end; return result end; -proc _elna_tac_load_immediate(target_register: Word, source_immediate: Word, immediate_length: Word); +proc elna_rtl_binary_operands(tac_instruction: Word, next_instruction: Word); +var + lhs: Word; + rhs: Word; +begin + lhs := elna_rtl_load_operand_value(tac_instruction, 2, ElnaRtlRegister.t2); + rhs := elna_rtl_load_operand_value(tac_instruction, 3, ElnaRtlRegister.t3); + + next_instruction^ := ElnaInstructionList_get_next(lhs); + if next_instruction^ = 0 then + ElnaInstructionList_set_next(lhs, rhs) + else + ElnaInstructionList_set_next(next_instruction^, rhs) + end; + next_instruction^ := ElnaInstructionList_get_next(rhs); + if next_instruction^ = 0 then + next_instruction^ := rhs + end; + + return lhs +end; + +proc elna_rtl_binary_arithmetic(tac_instruction: Word, binary_result: Word, next_instruction: Word); +var + lhs: Word; +begin + lhs := elna_rtl_binary_operands(tac_instruction, next_instruction); + elna_rtl_instruction_set_operand(binary_result, 2, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); + elna_rtl_instruction_set_operand(binary_result, 3, ElnaRtlOperand.register, ElnaRtlRegister.t3, 0); + + ElnaInstructionList_set_next(next_instruction^, binary_result); + next_instruction^ := binary_result; + + return lhs +end; + +proc elna_rtl_binary_equality(tac_instruction: Word, binary_result: Word, next_instruction: Word); +var + operands: Word; + intermediate_instruction: Word; +begin + operands := elna_rtl_binary_operands(tac_instruction, next_instruction); + intermediate_instruction := elna_rtl_instruction_create(ElnaRtlOperator._xor); + + elna_rtl_instruction_set_operand(intermediate_instruction, 1, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); + elna_rtl_instruction_set_operand(intermediate_instruction, 2, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); + elna_rtl_instruction_set_operand(intermediate_instruction, 3, ElnaRtlOperand.register, ElnaRtlRegister.t3, 0); + ElnaInstructionList_set_next(next_instruction^, intermediate_instruction); + next_instruction^ := intermediate_instruction; + + elna_rtl_instruction_set_operand(binary_result, 2, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); + ElnaInstructionList_set_next(next_instruction^, binary_result); + next_instruction^ := binary_result; + + return operands +end; + +proc elna_rtl_instruction(tac_instruction: Word, next_instruction: Word); +var + result: Word; + instruction_size: Word; + instruction_kind: Word; + operand_type: Word; + operand_value: Word; + operands: Word; + intermediate_instruction: Word; +begin + instruction_size := elna_rtl_instruction_size(); + result := malloc(instruction_size); + instruction_kind := _elna_tac_instruction_get_kind(tac_instruction); + memcpy(result + 4, tac_instruction + 4, instruction_size - 4); + next_instruction^ := 0; + + if instruction_kind = ElnaTacOperator.get_address then + operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, 2); + + if operand_type = ElnaTacOperand.stack then + operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2); + elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.register, ElnaRtlRegister.sp, 0); + elna_rtl_instruction_set_operand(result, 3, ElnaRtlOperand.immediate, operand_value, 0); + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.add) + elsif operand_type = ElnaTacOperand.symbol then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.load_address) + elsif operand_type = ElnaTacOperand.register then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.move); + else + (* Debug. Error stream output. + _syscall(2, name_pointer, name_length, 0, 0, 0, 64); *) + printf("# here %i\n\0", operand_type); + fflush(0); + end; + elsif instruction_kind = ElnaTacOperator.add then + result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction); + elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.add) + elsif instruction_kind = ElnaTacOperator.load_word then + operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, 2); + + if operand_type = ElnaTacOperand.stack then + operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 1); + next_instruction^ := elna_rtl_instruction_create(ElnaRtlOperator.load_word); + elna_rtl_instruction_set_operand(next_instruction^, 1, ElnaRtlOperand.register, operand_value, 0); + elna_rtl_instruction_set_operand(next_instruction^, 2, ElnaRtlOperand.offset, operand_value, 0); + + operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2); + elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, operand_value); + ElnaInstructionList_set_next(result, next_instruction^) + end; + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.load_word) + elsif instruction_kind = ElnaTacOperator.store_word then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.store_word) + elsif instruction_kind = ElnaTacOperator.jal then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.jal) + elsif instruction_kind = ElnaTacOperator.sub then + result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction); + elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.sub) + elsif instruction_kind = ElnaTacOperator.mul then + result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction); + elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.mul) + elsif instruction_kind = ElnaTacOperator.div then + result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction); + elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.div) + elsif instruction_kind = ElnaTacOperator.rem then + result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction); + elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.rem) + elsif instruction_kind = ElnaTacOperator._xor then + result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction); + elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator._xor) + elsif instruction_kind = ElnaTacOperator._or then + result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction); + elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator._or) + elsif instruction_kind = ElnaTacOperator.and then + result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction); + elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.and) + elsif instruction_kind = ElnaTacOperator.slt then + result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction); + elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.slt) + elsif instruction_kind = ElnaTacOperator.sgt then + operands := elna_rtl_binary_operands(tac_instruction, next_instruction); + elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.register, ElnaRtlRegister.t3, 0); + elna_rtl_instruction_set_operand(result, 3, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); + + ElnaInstructionList_set_next(next_instruction^, result); + next_instruction^ := result; + + result := operands; + elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.slt) + elsif instruction_kind = ElnaTacOperator.sle 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, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); + elna_rtl_instruction_set_operand(intermediate_instruction, 2, ElnaRtlOperand.register, ElnaRtlRegister.t3, 0); + elna_rtl_instruction_set_operand(intermediate_instruction, 3, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); + ElnaInstructionList_set_next(next_instruction^, intermediate_instruction); + next_instruction^ := intermediate_instruction; + + elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); + elna_rtl_instruction_set_operand(result, 3, ElnaRtlOperand.immediate, 1, 0); + ElnaInstructionList_set_next(next_instruction^, result); + next_instruction^ := result; + + result := operands; + elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.xor_immediate) + elsif instruction_kind = ElnaTacOperator.sge 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, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); + elna_rtl_instruction_set_operand(intermediate_instruction, 2, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); + elna_rtl_instruction_set_operand(intermediate_instruction, 3, ElnaRtlOperand.register, ElnaRtlRegister.t3, 0); + ElnaInstructionList_set_next(next_instruction^, intermediate_instruction); + next_instruction^ := intermediate_instruction; + + elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); + elna_rtl_instruction_set_operand(result, 3, ElnaRtlOperand.immediate, 1, 0); + ElnaInstructionList_set_next(next_instruction^, result); + next_instruction^ := result; + + result := operands; + elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.xor_immediate) + elsif instruction_kind = ElnaTacOperator.seq then + result := elna_rtl_binary_equality(tac_instruction, result, next_instruction); + elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.seqz) + elsif instruction_kind = ElnaTacOperator.sne then + result := elna_rtl_binary_equality(tac_instruction, result, next_instruction); + elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.snez) + elsif instruction_kind = ElnaTacOperator.neg then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.neg) + elsif instruction_kind = ElnaTacOperator.not then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.not) + elsif instruction_kind = ElnaTacOperator.jump then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.jump) + elsif instruction_kind = ElnaTacOperator.beqz then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.beqz) + elsif instruction_kind = ElnaTacOperator.start then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.start) + elsif instruction_kind = ElnaTacOperator.ret then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.ret) + elsif instruction_kind = ElnaTacOperator.label then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.label) + elsif instruction_kind = ElnaTacOperator.assign then + free(result); + operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 1); + result := elna_rtl_load_operand_value(tac_instruction, 2, operand_value); + next_instruction^ := ElnaInstructionList_get_next(result) + end; + if next_instruction^ = 0 then + next_instruction^ := result; + end; + return result +end; + +proc elna_instruction_module_create(data: Word, code: Word); var result: Word; begin - result := _elna_tac_instruction_create(ElnaTacOperator.load_immediate); + result := malloc(ElnaInstructionModule_size()); - _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, target_register, 0); - _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.immediate, source_immediate, immediate_length); + ElnaInstructionModule_set_data(result, data); + ElnaInstructionModule_set_code(result, code); return result end; @@ -859,19 +1126,7 @@ proc _elna_tac_load_address(target_register: Word, source_symbol: Word, symbol_l var result: Word; begin - result := _elna_tac_instruction_create(ElnaTacOperator.load_address); - - _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, target_register, 0); - _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.symbol, source_symbol, symbol_length); - - return result -end; - -proc _elna_tac_beqz(target_register: Word, source_symbol: Word, symbol_length: Word); -var - result: Word; -begin - result := _elna_tac_instruction_create(ElnaTacOperator.beqz); + result := _elna_tac_instruction_create(ElnaTacOperator.get_address); _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, target_register, 0); _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.symbol, source_symbol, symbol_length); @@ -890,7 +1145,7 @@ begin return result end; -proc _elna_tac_add(destination: Word, lhs: Word, rhs: Word); +proc _elna_tac_add(destination: Word, lhs: Word, rhs_type: Word, rhs: Word); var result: Word; begin @@ -898,20 +1153,7 @@ begin _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0); _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0); - _elna_tac_instruction_set_operand(result, 3, ElnaTacOperand.register, rhs, 0); - - return result -end; - -proc _elna_tac_mul(destination: Word, lhs: Word, rhs: Word); -var - result: Word; -begin - result := _elna_tac_instruction_create(ElnaTacOperator.mul); - - _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0); - _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0); - _elna_tac_instruction_set_operand(result, 3, ElnaTacOperand.register, rhs, 0); + _elna_tac_instruction_set_operand(result, 3, rhs_type, rhs, 0); return result end; @@ -929,110 +1171,6 @@ begin return result end; -proc _elna_tac_div(destination: Word, lhs: Word, rhs: Word); -var - result: Word; -begin - result := _elna_tac_instruction_create(ElnaTacOperator.div); - - _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0); - _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0); - _elna_tac_instruction_set_operand(result, 3, ElnaTacOperand.register, rhs, 0); - - return result -end; - -proc _elna_tac_rem(destination: Word, lhs: Word, rhs: Word); -var - result: Word; -begin - result := _elna_tac_instruction_create(ElnaTacOperator.rem); - - _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0); - _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0); - _elna_tac_instruction_set_operand(result, 3, ElnaTacOperand.register, rhs, 0); - - return result -end; - -proc _elna_tac_xor(destination: Word, lhs: Word, rhs: Word); -var - result: Word; -begin - result := _elna_tac_instruction_create(ElnaTacOperator._xor); - - _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0); - _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0); - _elna_tac_instruction_set_operand(result, 3, ElnaTacOperand.register, rhs, 0); - - return result -end; - -proc _elna_tac_xor_immediate(destination: Word, lhs: Word, rhs: Word); -var - result: Word; -begin - result := _elna_tac_instruction_create(ElnaTacOperator._xor); - - _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0); - _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0); - _elna_tac_instruction_set_operand(result, 3, ElnaTacOperand.immediate, rhs, 0); - - return result -end; - -proc _elna_tac_or(destination: Word, lhs: Word, rhs: Word); -var - result: Word; -begin - result := _elna_tac_instruction_create(ElnaTacOperator._or); - - _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0); - _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0); - _elna_tac_instruction_set_operand(result, 3, ElnaTacOperand.register, rhs, 0); - - return result -end; - -proc _elna_tac_and(destination: Word, lhs: Word, rhs: Word); -var - result: Word; -begin - result := _elna_tac_instruction_create(ElnaTacOperator.and); - - _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0); - _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0); - _elna_tac_instruction_set_operand(result, 3, ElnaTacOperand.register, rhs, 0); - - return result -end; - -proc _elna_tac_add_immediate(destination: Word, lhs: Word, rhs: Word); -var - result: Word; -begin - result := _elna_tac_instruction_create(ElnaTacOperator.add_immediate); - - _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0); - _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0); - _elna_tac_instruction_set_operand(result, 3, ElnaTacOperand.immediate, rhs, 0); - - return result -end; - -proc _elna_tac_slt(destination: Word, lhs: Word, rhs: Word); -var - result: Word; -begin - result := _elna_tac_instruction_create(ElnaTacOperator.slt); - - _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0); - _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0); - _elna_tac_instruction_set_operand(result, 3, ElnaTacOperand.register, rhs, 0); - - return result -end; - proc _elna_tac_jal(symbol: Word, length: Word); var result: Word; @@ -1068,42 +1206,6 @@ begin return result end; -proc _elna_tac_move(destination: Word, source: Word); -var - result: Word; -begin - result := _elna_tac_instruction_create(ElnaTacOperator.move); - - _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0); - _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, source, 0); - - return result -end; - -proc _elna_tac_seqz(destination: Word, source: Word); -var - result: Word; -begin - result := _elna_tac_instruction_create(ElnaTacOperator.seqz); - - _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0); - _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, source, 0); - - return result -end; - -proc _elna_tac_snez(destination: Word, source: Word); -var - result: Word; -begin - result := _elna_tac_instruction_create(ElnaTacOperator.snez); - - _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0); - _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, source, 0); - - return result -end; - proc _elna_tac_neg(destination: Word, source: Word); var result: Word; @@ -1214,10 +1316,10 @@ begin _write_s("\tbeqz", 5) elsif instruction_kind = ElnaRtlOperator.start then argument_count := 0; - _write_z("\taddi sp, sp, -128\n\tsw ra, 124(sp)\n\tsw s0, 120(sp)\n\taddi s0, sp, 128\0") + _write_z("\taddi sp, sp, -144\n\tsw ra, 140(sp)\n\tsw s0, 136(sp)\n\taddi s0, sp, 144\0") elsif instruction_kind = ElnaRtlOperator.ret then argument_count := 0; - _write_z("\tlw ra, 124(sp)\n\tlw s0, 120(sp)\n\taddi sp, sp, 128\0") + _write_z("\tlw ra, 140(sp)\n\tlw s0, 136(sp)\n\taddi sp, sp, 144\0") end; return argument_count end; @@ -1298,23 +1400,23 @@ var current_copy: Word; next_copy: Word; first_copy: Word; + last_copy: Word; begin if instruction <> 0 then - first_copy := elna_rtl_instruction(instruction); - instruction := _elna_tac_instruction_get_next(instruction) + first_copy := elna_rtl_instruction(instruction, @current_copy); + instruction := ElnaInstructionList_get_next(instruction) else first_copy := 0; + current_copy := 0 end; - current_copy := first_copy; - .elna_rtl_instructions_start; if instruction <> 0 then - next_copy := elna_rtl_instruction(instruction); + next_copy := elna_rtl_instruction(instruction, @last_copy); - instruction := _elna_tac_instruction_get_next(instruction); - elna_rtl_instruction_set_next(current_copy, next_copy); - current_copy := next_copy; + instruction := ElnaInstructionList_get_next(instruction); + ElnaInstructionList_set_next(current_copy, next_copy); + current_copy := last_copy; goto elna_rtl_instructions_start end; @@ -1326,7 +1428,7 @@ begin .elna_writer_instructions_start; if instruction <> 0 then _elna_writer_instruction(instruction); - instruction := elna_rtl_instruction_get_next(instruction); + instruction := ElnaInstructionList_get_next(instruction); goto elna_writer_instructions_start end end; @@ -1338,9 +1440,9 @@ var body_statements: Word; begin .elna_writer_procedure_loop; - name_pointer := elna_rtl_declaration_get_name(procedure); - name_length := elna_rtl_declaration_get_length(procedure); - body_statements := elna_rtl_declaration_get_body(procedure); + name_pointer := ElnaInstructionDeclaration_get_name(procedure); + name_length := ElnaInstructionDeclaration_get_length(procedure); + body_statements := ElnaInstructionDeclaration_get_body(procedure); (* Write .type _procedure_name, @function. *) _write_z(".type \0"); @@ -1355,7 +1457,7 @@ begin _elna_writer_instructions(body_statements); _write_z("\tret\n\0"); - procedure := elna_rtl_declaration_get_next(procedure); + procedure := ElnaInstructionList_get_next(procedure); if procedure <> 0 then goto elna_writer_procedure_loop end @@ -1369,9 +1471,9 @@ var begin .elna_writer_variable_loop; if variable <> 0 then - name := elna_rtl_declaration_get_name(variable); - name_length := elna_rtl_declaration_get_length(variable); - size := elna_rtl_declaration_get_body(variable); + name := ElnaInstructionDeclaration_get_name(variable); + name_length := ElnaInstructionDeclaration_get_length(variable); + size := ElnaInstructionDeclaration_get_body(variable); _write_z(".type \0"); _write_s(name, name_length); @@ -1384,7 +1486,7 @@ begin _write_i(size); _write_c('\n'); - variable := elna_rtl_declaration_get_next(variable); + variable := ElnaInstructionList_get_next(variable); goto elna_writer_variable_loop end @@ -1392,20 +1494,17 @@ end; proc elna_rtl_module_declaration(tac_module: Word); var - result: Word; + code_part: Word; + data_part: Word; current_part: Word; begin - result := malloc(elna_rtl_module_size()); + current_part := ElnaInstructionModule_get_data(tac_module); + data_part := elna_rtl_globals(current_part); - current_part := _elna_tac_module_get_data(tac_module); - current_part := elna_rtl_globals(current_part); - elna_rtl_module_set_data(result, current_part); + current_part := ElnaInstructionModule_get_code(tac_module); + code_part := elna_rtl_procedures(current_part); - current_part := _elna_tac_module_get_code(tac_module); - current_part := elna_rtl_procedures(current_part); - elna_rtl_module_set_code(result, current_part); - - return result + return elna_instruction_module_create(data_part, code_part) end; proc _elna_writer_module(pair: Word); @@ -1418,7 +1517,7 @@ begin _write_z(".globl main\n\n\0"); _write_z(".section .data\n\0"); - current_part := elna_rtl_module_get_data(pair); + current_part := ElnaInstructionModule_get_data(pair); _elna_writer_variable(current_part); _write_z(".section .text\n\n\0"); @@ -1426,7 +1525,7 @@ begin _write_z(".type _load_byte, @function\n_load_byte:\n\tlb a0, (a0)\nret\n\n\0"); _write_z(".type _store_byte, @function\n_store_byte:\n\tsb a0, (a1)\nret\n\n\0"); - current_part := elna_rtl_module_get_code(pair); + current_part := ElnaInstructionModule_get_code(pair); _elna_writer_procedure(current_part); _write_z(".section .rodata\n.type strings, @object\nstrings: .ascii \0"); @@ -1467,16 +1566,13 @@ begin return result end; -proc _elna_tac_integer_literal(integer_literal_node: Word); -var - integer_token: Word; - integer_length: Word; - token_kind: Word; +proc _elna_tac_integer_literal(integer_literal_node: Word, operand_type: Word, operand_value: Word, operand_length: Word); begin - integer_token := _integer_literal_node_get_value(integer_literal_node); - integer_length := _integer_literal_node_get_length(integer_literal_node); + operand_type^ := ElnaTacOperand.immediate; + operand_value^ := _integer_literal_node_get_value(integer_literal_node); + operand_length^ := _integer_literal_node_get_length(integer_literal_node); - return _elna_tac_load_immediate(ElnaRtlRegister.t0, integer_token, integer_length) + return 0 end; proc _elna_parser_character_literal(); @@ -1499,15 +1595,13 @@ begin return result end; -proc _elna_tac_character_literal(character_literal_node: Word); -var - character: Word; - character_length: Word; +proc _elna_tac_character_literal(character_literal_node: Word, operand_type: Word, operand_value: Word, operand_length: Word); begin - character := _character_literal_node_get_value(character_literal_node); - character_length := _character_literal_node_get_length(character_literal_node); + operand_type^ := ElnaTacOperand.immediate; + operand_value^ :=_character_literal_node_get_value(character_literal_node); + operand_length^ := _character_literal_node_get_length(character_literal_node); - return _elna_tac_load_immediate(ElnaRtlRegister.t0, character, character_length) + return 0 end; proc _elna_parser_variable_expression(); @@ -1530,23 +1624,26 @@ begin return result end; -proc _elna_tac_variable_expression(variable_expression: Word, symbol_table: Word); +proc _elna_tac_variable_expression(variable_expression: Word, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word); var - name: Word; - name_token: Word; + name_pointer: Word; + name_length: Word; lookup_result: Word; - instruction: Word; begin - name := _variable_expression_get_name(variable_expression); - name_token := _variable_expression_get_length(variable_expression); + name_pointer := _variable_expression_get_name(variable_expression); + name_length := _variable_expression_get_length(variable_expression); - lookup_result := _symbol_table_lookup(symbol_table, name, name_token); + lookup_result := _symbol_table_lookup(symbol_table, name_pointer, name_length); if lookup_result <> 0 then - instruction := _elna_tac_local_designator(lookup_result) + operand_type^ := ElnaTacOperand.stack; + operand_value^ := _parameter_info_get_offset(lookup_result); + operand_length^ := 0 else - instruction := _elna_tac_global_designator(variable_expression) + operand_type^ := ElnaTacOperand.symbol; + operand_value^ := name_pointer; + operand_length^ := name_length end; - return instruction + return 0 end; proc _elna_parser_string_literal(); @@ -1568,26 +1665,31 @@ begin return result end; -proc _elna_tac_string_literal(string_literal_node: Word); +proc _elna_tac_string_literal(string_literal_node: Word, operand_type: Word, operand_value: Word, operand_length: Word); var token_start: Word; - length: Word; offset: Word; - instruction: Word; first_instruction: Word; next_instruction: Word; begin token_start := _string_literal_node_get_value(string_literal_node); - length := _string_literal_node_get_length(string_literal_node); offset := _add_string(token_start); - first_instruction := _elna_tac_load_address(ElnaRtlRegister.t0, "strings", 7); - instruction := _elna_tac_load_immediate(ElnaRtlRegister.t1, offset, 0); - _elna_tac_instruction_set_next(first_instruction, instruction); - next_instruction := _elna_tac_add(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1); - _elna_tac_instruction_set_next(instruction, next_instruction); + first_instruction := _elna_tac_instruction_create(ElnaTacOperator.get_address); + _elna_tac_instruction_set_operand(first_instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0); + _elna_tac_instruction_set_operand(first_instruction, 2, ElnaTacOperand.symbol, "strings", 7); - return first_instruction + (* Add offset to the string block pointer. *) + next_instruction := _elna_tac_instruction_create(ElnaTacOperator.add); + _elna_tac_instruction_set_operand(next_instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0); + _elna_tac_instruction_set_operand(next_instruction, 2, ElnaTacOperand.register, ElnaRtlRegister.t0, 0); + _elna_tac_instruction_set_operand(next_instruction, 3, ElnaTacOperand.immediate, offset, 0); + + operand_type^ := ElnaTacOperand.register; + operand_value^ := ElnaRtlRegister.t0; + operand_length^ := 0; + + return elna_instruction_list_concatenate(first_instruction, next_instruction) end; proc _elna_parser_simple_expression(); @@ -1643,9 +1745,8 @@ begin return simple_expression end; -proc _elna_tac_simple_expression(parser_node: Word, symbol_table: Word, is_address: Word); +proc _elna_tac_simple_expression(parser_node: Word, symbol_table: Word, is_address: Word, operand_type: Word, operand_value: Word, operand_length: Word); var - is_address: Word; node_kind: Word; instruction: Word; begin @@ -1653,13 +1754,13 @@ begin node_kind := _node_get_kind(parser_node); if node_kind = NodeKind.character_literal then - instruction := _elna_tac_character_literal(parser_node) + instruction := _elna_tac_character_literal(parser_node, operand_type, operand_value, operand_length) elsif node_kind = NodeKind.string_literal then - instruction := _elna_tac_string_literal(parser_node) + instruction := _elna_tac_string_literal(parser_node, operand_type, operand_value, operand_length) elsif node_kind = NodeKind.integer_literal then - instruction := _elna_tac_integer_literal(parser_node) + instruction := _elna_tac_integer_literal(parser_node, operand_type, operand_value, operand_length) else - instruction := _elna_tac_variable_expression(parser_node, symbol_table); + instruction := _elna_tac_variable_expression(parser_node, symbol_table, operand_type, operand_value, operand_length); is_address^ := 1 end; return instruction @@ -1699,7 +1800,7 @@ begin return result end; -proc _elna_tac_unary_expression(parser_node: Word, symbol_table: Word); +proc _elna_tac_unary_expression(parser_node: Word, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word); var current_character: Word; token_kind: Word; @@ -1723,20 +1824,56 @@ begin end; if operator = '@' then - first_instruction := _elna_tac_designator(operand, symbol_table, @is_address) + first_instruction := _elna_tac_designator(operand, symbol_table, @is_address, operand_type, operand_value, operand_length); + + instruction := _elna_tac_instruction_create(ElnaTacOperator.get_address); + _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0); + _elna_tac_instruction_set_operand(instruction, 2, operand_type^, operand_value^, operand_length^); + + operand_type^ := ElnaTacOperand.register; + operand_value^ := ElnaRtlRegister.t0; + operand_length^ := 0; + + first_instruction := elna_instruction_list_concatenate(first_instruction, instruction) else - first_instruction := _elna_tac_designator(operand, symbol_table, @is_address); + first_instruction := _elna_tac_designator(operand, symbol_table, @is_address, operand_type, operand_value, operand_length); + + if operand_type^ = ElnaTacOperand.immediate then + first_instruction := _elna_tac_instruction_create(ElnaTacOperator.assign); + _elna_tac_instruction_set_operand(first_instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0); + _elna_tac_instruction_set_operand(first_instruction, 2, operand_type^, operand_value^, operand_length^); + + operand_type^ := ElnaTacOperand.register; + operand_value^ := ElnaRtlRegister.t0; + operand_length^ := 0 + elsif first_instruction = 0 then + first_instruction := _elna_tac_instruction_create(ElnaTacOperator.get_address); + _elna_tac_instruction_set_operand(first_instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0); + _elna_tac_instruction_set_operand(first_instruction, 2, operand_type^, operand_value^, operand_length^); + + operand_type^ := ElnaTacOperand.register; + operand_value^ := ElnaRtlRegister.t0; + operand_length^ := 0 + end; + if is_address then - instruction := _elna_tac_load_word(ElnaRtlRegister.t0, ElnaRtlRegister.t0, 0); - _elna_tac_instruction_set_next(first_instruction, instruction) + instruction := _elna_tac_instruction_create(ElnaTacOperator.load_word); + _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0); + _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.offset, ElnaRtlRegister.t0, 0); + + operand_type^ := ElnaTacOperand.register; + operand_value^ := ElnaRtlRegister.t0; + operand_length^ := 0; + + elna_instruction_list_concatenate(first_instruction, instruction) end end; if operator = '-' then instruction := _elna_tac_neg(ElnaRtlRegister.t0, ElnaRtlRegister.t0); - _elna_tac_instruction_set_next(first_instruction, instruction) + elna_instruction_list_concatenate(first_instruction, instruction) elsif operator = '~' then instruction := _elna_tac_not(ElnaRtlRegister.t0, ElnaRtlRegister.t0); - _elna_tac_instruction_set_next(first_instruction, instruction) + elna_instruction_list_concatenate(first_instruction, instruction) end; return first_instruction end; @@ -1808,7 +1945,7 @@ begin return result end; -proc _elna_tac_binary_expression(parser_node: Word, symbol_table: Word); +proc _elna_tac_binary_expression(parser_node: Word, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word); var token_kind: Word; expression_kind: Word; @@ -1816,91 +1953,85 @@ var first_instruction: Word; instruction: Word; current_instruction: Word; + lhs_type: Word; + lhs_value: Word; + lhs_length: Word; begin expression_kind := _node_get_kind(parser_node); if expression_kind <> NodeKind.binary_expression then - first_instruction := _elna_tac_unary_expression(parser_node, symbol_table) + first_instruction := _elna_tac_unary_expression(parser_node, symbol_table, operand_type, operand_value, operand_length) else token_kind := _binary_expression_get_operator(parser_node); operand_node := _binary_expression_get_lhs(parser_node); - first_instruction := _elna_tac_unary_expression(operand_node, symbol_table); + lhs_type := 0; + lhs_value := 0; + lhs_length := 0; + first_instruction := _elna_tac_unary_expression(operand_node, symbol_table, @lhs_type, @lhs_value, @lhs_length); (* Save the value of the left expression on the stack. *) - instruction := _elna_tac_store_word(ElnaRtlRegister.t0, ElnaRtlRegister.sp, 64); - _elna_tac_instruction_set_next(first_instruction, instruction); + instruction := _elna_tac_instruction_create(ElnaTacOperator.store_word); + _elna_tac_instruction_set_operand(instruction, 1, lhs_type, lhs_value, lhs_length); + _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.offset, ElnaRtlRegister.sp, 72); + + elna_instruction_list_concatenate(first_instruction, instruction); current_instruction := instruction; operand_node := _binary_expression_get_rhs(parser_node); - instruction := _elna_tac_unary_expression(operand_node, symbol_table); - _elna_tac_instruction_set_next(current_instruction, instruction); + lhs_type := 0; + lhs_value := 0; + lhs_length := 0; + instruction := _elna_tac_unary_expression(operand_node, symbol_table, @lhs_type, @lhs_value, @lhs_length); + elna_instruction_list_concatenate(current_instruction, instruction); current_instruction := instruction; (* Load the left expression from the stack; *) - instruction := _elna_tac_load_word(ElnaRtlRegister.t1, ElnaRtlRegister.sp, 64); - _elna_tac_instruction_set_next(current_instruction, instruction); + instruction := _elna_tac_instruction_create(ElnaTacOperator.load_word); + _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t1, 0); + _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.offset, ElnaRtlRegister.sp, 72); + + elna_instruction_list_concatenate(current_instruction, instruction); current_instruction := instruction; if token_kind = ElnaLexerKind.plus then - instruction := _elna_tac_add(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1); - _elna_tac_instruction_set_next(current_instruction, instruction) + instruction := _elna_tac_instruction_create(ElnaTacOperator.add) elsif token_kind = ElnaLexerKind.minus then - instruction := _elna_tac_sub(ElnaRtlRegister.t0, ElnaRtlRegister.t1, ElnaRtlRegister.t0); - _elna_tac_instruction_set_next(current_instruction, instruction) + instruction := _elna_tac_instruction_create(ElnaTacOperator.sub) elsif token_kind = ElnaLexerKind.multiplication then - instruction := _elna_tac_mul(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1); - _elna_tac_instruction_set_next(current_instruction, instruction) + instruction := _elna_tac_instruction_create(ElnaTacOperator.mul) elsif token_kind = ElnaLexerKind.and then - instruction := _elna_tac_and(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1); - _elna_tac_instruction_set_next(current_instruction, instruction) + instruction := _elna_tac_instruction_create(ElnaTacOperator.and) elsif token_kind = ElnaLexerKind._or then - instruction := _elna_tac_or(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1); - _elna_tac_instruction_set_next(current_instruction, instruction) + instruction := _elna_tac_instruction_create(ElnaTacOperator._or) elsif token_kind = ElnaLexerKind._xor then - instruction := _elna_tac_xor(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1); - _elna_tac_instruction_set_next(current_instruction, instruction) + instruction := _elna_tac_instruction_create(ElnaTacOperator._xor) elsif token_kind = ElnaLexerKind.equals then - instruction := _elna_tac_xor(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1); - _elna_tac_instruction_set_next(current_instruction, instruction); - current_instruction := instruction; - - instruction := _elna_tac_seqz(ElnaRtlRegister.t0, ElnaRtlRegister.t0); - _elna_tac_instruction_set_next(current_instruction, instruction) + instruction := _elna_tac_instruction_create(ElnaTacOperator.seq) elsif token_kind = ElnaLexerKind.remainder then - instruction := _elna_tac_rem(ElnaRtlRegister.t0, ElnaRtlRegister.t1, ElnaRtlRegister.t0); - _elna_tac_instruction_set_next(current_instruction, instruction) + instruction := _elna_tac_instruction_create(ElnaTacOperator.rem) elsif token_kind = ElnaLexerKind.division then - instruction := _elna_tac_div(ElnaRtlRegister.t0, ElnaRtlRegister.t1, ElnaRtlRegister.t0); - _elna_tac_instruction_set_next(current_instruction, instruction) + instruction := _elna_tac_instruction_create(ElnaTacOperator.div) elsif token_kind = ElnaLexerKind.less_than then - instruction := _elna_tac_slt(ElnaRtlRegister.t0, ElnaRtlRegister.t1, ElnaRtlRegister.t0); - _elna_tac_instruction_set_next(current_instruction, instruction) + instruction := _elna_tac_instruction_create(ElnaTacOperator.slt) elsif token_kind = ElnaLexerKind.greater_than then - instruction := _elna_tac_slt(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1); - _elna_tac_instruction_set_next(current_instruction, instruction) + instruction := _elna_tac_instruction_create(ElnaTacOperator.sgt) elsif token_kind = ElnaLexerKind.less_equal then - instruction := _elna_tac_slt(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1); - _elna_tac_instruction_set_next(current_instruction, instruction); - current_instruction := instruction; - - instruction := _elna_tac_xor_immediate(ElnaRtlRegister.t0, ElnaRtlRegister.t0, 1); - _elna_tac_instruction_set_next(current_instruction, instruction) - elsif token_kind = ElnaLexerKind.not_equal then - instruction := _elna_tac_xor(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1); - _elna_tac_instruction_set_next(current_instruction, instruction); - current_instruction := instruction; - - instruction := _elna_tac_snez(ElnaRtlRegister.t0, ElnaRtlRegister.t0); - _elna_tac_instruction_set_next(current_instruction, instruction) + instruction := _elna_tac_instruction_create(ElnaTacOperator.sle) elsif token_kind = ElnaLexerKind.greater_equal then - instruction := _elna_tac_slt(ElnaRtlRegister.t0, ElnaRtlRegister.t1, ElnaRtlRegister.t0); - _elna_tac_instruction_set_next(current_instruction, instruction); - current_instruction := instruction; + instruction := _elna_tac_instruction_create(ElnaTacOperator.sge) + elsif token_kind = ElnaLexerKind.not_equal then + instruction := _elna_tac_instruction_create(ElnaTacOperator.sne) + end; + _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0); + _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 72, 0); + _elna_tac_instruction_set_operand(instruction, 3, lhs_type, lhs_value, lhs_length); - instruction := _elna_tac_xor_immediate(ElnaRtlRegister.t0, ElnaRtlRegister.t0, 1); - _elna_tac_instruction_set_next(current_instruction, instruction) - end + elna_instruction_list_concatenate(current_instruction, instruction); + + operand_type^ := ElnaTacOperand.register; + operand_value^ := ElnaRtlRegister.t0; + operand_length^ := 0 end; return first_instruction end; @@ -1989,6 +2120,9 @@ var instruction: Word; first_instruction: Word; current_instruction: Word; + operand_type: Word; + operand_value: Word; + operand_length: Word; begin parsed_expression := _call_get_name(parsed_call); name := _variable_expression_get_name(parsed_expression); @@ -2002,20 +2136,25 @@ begin if parsed_expression = 0 then goto elna_tac_call_finalize else - instruction := _elna_tac_binary_expression(parsed_expression, symbol_table); + operand_type := 0; + operand_value := 0; + operand_length := 0; + instruction := _elna_tac_binary_expression(parsed_expression, symbol_table, @operand_type, @operand_value, @operand_length); if first_instruction = 0 then first_instruction := instruction else - _elna_tac_instruction_set_next(current_instruction, instruction) + elna_instruction_list_concatenate(current_instruction, instruction) end; current_instruction := instruction; (* Save the argument on the stack. *) stack_offset := argument_count * 4; - instruction := _elna_tac_store_word(ElnaRtlRegister.t0, - ElnaRtlRegister.sp, 116 - stack_offset); - _elna_tac_instruction_set_next(current_instruction, instruction); + instruction := _elna_tac_instruction_create(ElnaTacOperator.store_word); + _elna_tac_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length); + _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.offset, ElnaRtlRegister.sp, 132 - stack_offset); + + elna_instruction_list_concatenate(current_instruction, instruction); current_instruction := instruction; argument_count := argument_count + 1; @@ -2029,10 +2168,10 @@ begin argument_count := argument_count - 1; stack_offset := argument_count * 4; - (* Calculate the stack offset: 116 - (4 * argument_counter) *) + (* Calculate the stack offset: 132 - (4 * argument_counter) *) instruction := _elna_tac_load_word(ElnaRtlRegister.a0 + argument_count, - ElnaRtlRegister.sp, 116 - stack_offset); - _elna_tac_instruction_set_next(current_instruction, instruction); + ElnaRtlRegister.sp, 132 - stack_offset); + elna_instruction_list_concatenate(current_instruction, instruction); current_instruction := instruction; goto elna_tac_call_finalize @@ -2041,7 +2180,7 @@ begin if first_instruction = 0 then first_instruction := instruction else - _elna_tac_instruction_set_next(current_instruction, instruction) + elna_instruction_list_concatenate(current_instruction, instruction) end; return first_instruction end; @@ -2122,27 +2261,7 @@ begin return _elna_tac_label(label_name, label_length) end; -proc _elna_tac_local_designator(symbol: Word); -var - variable_offset: Word; -begin - variable_offset := _parameter_info_get_offset(symbol); - - return _elna_tac_add_immediate(ElnaRtlRegister.t0, ElnaRtlRegister.sp, variable_offset) -end; - -proc _elna_tac_global_designator(variable_expression: Word); -var - name: Word; - token_length: Word; -begin - name := _variable_expression_get_name(variable_expression); - token_length := _variable_expression_get_length(variable_expression); - - return _elna_tac_load_address(ElnaRtlRegister.t0, name, token_length) -end; - -proc _elna_tac_enumeration_value(field_access_expression: Word); +proc _elna_tac_enumeration_value(field_access_expression: Word, operand_type: Word, operand_value: Word, operand_length: Word); var enumeration_type: Word; members: Word; @@ -2154,7 +2273,6 @@ var member_length: Word; counter: Word; symbol: Word; - instruction: Word; begin symbol := _field_access_expression_get_aggregate(field_access_expression); value_name := _variable_expression_get_name(symbol); @@ -2172,7 +2290,6 @@ begin name_length := _field_access_expression_get_length(field_access_expression); counter := 1; - instruction := 0; .elna_tac_enumeration_value_members; if members_length > 0 then member_name := members^; @@ -2185,9 +2302,12 @@ begin counter := counter + 1; goto elna_tac_enumeration_value_members end; - instruction := _elna_tac_load_immediate(ElnaRtlRegister.t0, counter, 0) + (* Found. *) + operand_type^ := ElnaTacOperand.immediate; + operand_value^ := counter; + operand_length^ := 0 end; - return instruction + return 0 end; proc _elna_parser_field_access_expression(aggregate: Word); @@ -2216,33 +2336,46 @@ begin return result end; -proc _elna_tac_designator(parser_node: Word, symbol_table: Word, is_address: Word); +proc _elna_tac_designator(parser_node: Word, symbol_table: Word, is_address: Word, operand_type: Word, operand_value: Word, operand_length: Word); var - name_token: Word; - lookup_result: Word; - token_kind: Word; parser_node: Word; node_kind: Word; first_instruction: Word; - instruction: Word; + last_instruction: Word; begin node_kind := _node_get_kind(parser_node); if node_kind = NodeKind.dereference_expression then parser_node := _dereference_expression_get_pointer(parser_node); - first_instruction := _elna_tac_simple_expression(parser_node, symbol_table, is_address); - instruction := _elna_tac_load_word(ElnaRtlRegister.t0, ElnaRtlRegister.t0, 0); - _elna_tac_instruction_set_next(first_instruction, instruction) + first_instruction := _elna_tac_simple_expression(parser_node, symbol_table, is_address, operand_type, operand_value, operand_length); + + last_instruction := _elna_tac_instruction_create(ElnaTacOperator.assign); + _elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0); + _elna_tac_instruction_set_operand(last_instruction, 2, operand_type^, operand_value^, operand_length^); + + operand_type^ := ElnaTacOperand.register; + operand_value^ := ElnaRtlRegister.t0; + operand_length^ := 0; + + first_instruction := elna_instruction_list_concatenate(first_instruction, last_instruction) elsif node_kind = NodeKind.field_access_expression then - first_instruction := _elna_tac_enumeration_value(parser_node); + _elna_tac_enumeration_value(parser_node, operand_type, operand_value, operand_length); is_address^ := 0 elsif node_kind = NodeKind.call then first_instruction := _elna_tac_call(parser_node, symbol_table); - instruction := _elna_tac_move(ElnaRtlRegister.t0, ElnaRtlRegister.a0); - _elna_tac_instruction_set_next(first_instruction, instruction); + + last_instruction := _elna_tac_instruction_create(ElnaTacOperator.assign); + _elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0); + _elna_tac_instruction_set_operand(last_instruction, 2, ElnaTacOperand.register, ElnaRtlRegister.a0, 0); + + operand_type^ := ElnaTacOperand.register; + operand_value^ := ElnaRtlRegister.t0; + operand_length^ := 0; + + elna_instruction_list_concatenate(first_instruction, last_instruction); is_address^ := 0 else - first_instruction := _elna_tac_simple_expression(parser_node, symbol_table, is_address) + first_instruction := _elna_tac_simple_expression(parser_node, symbol_table, is_address, operand_type, operand_value, operand_length) end; return first_instruction end; @@ -2276,24 +2409,42 @@ var first_instruction: Word; instruction: Word; current_instruction: Word; + operand_type: Word; + operand_value: Word; + operand_length: Word; begin current_expression := _assign_statement_get_assignee(parser_tree); - first_instruction := _elna_tac_designator(current_expression, symbol_table, @is_address); + operand_type := 0; + operand_value := 0; + operand_length := 0; + first_instruction := _elna_tac_designator(current_expression, symbol_table, @is_address, @operand_type, @operand_value, @operand_length); + + current_instruction := _elna_tac_instruction_create(ElnaTacOperator.get_address); + _elna_tac_instruction_set_operand(current_instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0); + _elna_tac_instruction_set_operand(current_instruction, 2, operand_type, operand_value, operand_length); + first_instruction := elna_instruction_list_concatenate(first_instruction, current_instruction); (* Save the assignee address on the stack. *) - current_instruction := _elna_tac_store_word(ElnaRtlRegister.t0, ElnaRtlRegister.sp, 60); - _elna_tac_instruction_set_next(first_instruction, current_instruction); + current_instruction := _elna_tac_store_word(ElnaRtlRegister.t0, ElnaRtlRegister.sp, 76); + elna_instruction_list_concatenate(first_instruction, current_instruction); (* Compile the assignment. *) current_expression := _assign_statement_get_assignment(parser_tree); - instruction := _elna_tac_binary_expression(current_expression, symbol_table); - _elna_tac_instruction_set_next(current_instruction, instruction); + operand_type := 0; + operand_value := 0; + operand_length := 0; + instruction := _elna_tac_binary_expression(current_expression, symbol_table, @operand_type, @operand_value, @operand_length); - current_instruction := _elna_tac_load_word(ElnaRtlRegister.t1, ElnaRtlRegister.sp, 60); - _elna_tac_instruction_set_next(instruction, current_instruction); + elna_instruction_list_concatenate(current_instruction, instruction); - instruction := _elna_tac_store_word(ElnaRtlRegister.t0, ElnaRtlRegister.t1, 0); - _elna_tac_instruction_set_next(current_instruction, instruction); + current_instruction := _elna_tac_load_word(ElnaRtlRegister.t1, ElnaRtlRegister.sp, 76); + elna_instruction_list_concatenate(instruction, current_instruction); + + instruction := _elna_tac_instruction_create(ElnaTacOperator.store_word); + _elna_tac_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length); + _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.offset, ElnaRtlRegister.t1, 0); + + elna_instruction_list_concatenate(current_instruction, instruction); return first_instruction end; @@ -2324,11 +2475,21 @@ var return_expression: Word; first_instruction: Word; instruction: Word; + operand_type: Word; + operand_value: Word; + operand_length: Word; begin + operand_type := 0; + operand_value := 0; + operand_length := 0; return_expression := _return_statement_get_returned(parser_node); - first_instruction := _elna_tac_binary_expression(return_expression, symbol_table); - instruction := _elna_tac_move(ElnaRtlRegister.a0, ElnaRtlRegister.t0); - _elna_tac_instruction_set_next(first_instruction, instruction); + first_instruction := _elna_tac_binary_expression(return_expression, symbol_table, @operand_type, @operand_value, @operand_length); + + instruction := _elna_tac_instruction_create(ElnaTacOperator.assign); + _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.a0, 0); + _elna_tac_instruction_set_operand(instruction, 2, operand_type, operand_value, operand_length); + + elna_instruction_list_concatenate(first_instruction, instruction); return first_instruction end; @@ -2386,30 +2547,39 @@ var instruction: Word; current_instruction: Word; first_instruction: Word; + operand_type: Word; + operand_value: Word; + operand_length: Word; begin (* Compile condition. *) + operand_type := 0; + operand_value := 0; + operand_length := 0; current_node := _conditional_statements_get_condition(parser_node); - first_instruction := _elna_tac_binary_expression(current_node, symbol_table); + first_instruction := _elna_tac_binary_expression(current_node, symbol_table, @operand_type, @operand_value, @operand_length); (* condition_label is the label in front of the next elsif condition or end. *) condition_label := label_counter; label_counter := label_counter + 1; - current_instruction := _elna_tac_beqz(ElnaRtlRegister.t0, condition_label, 0); - _elna_tac_instruction_set_next(first_instruction, current_instruction); + current_instruction := _elna_tac_instruction_create(ElnaTacOperator.beqz); + _elna_tac_instruction_set_operand(current_instruction, 1, operand_type, operand_value, operand_length); + _elna_tac_instruction_set_operand(current_instruction, 2, ElnaTacOperand.symbol, condition_label, 0); + + elna_instruction_list_concatenate(first_instruction, current_instruction); current_node := _conditional_statements_get_statements(parser_node); instruction := _elna_tac_statements(current_node, symbol_table); if instruction <> 0 then - _elna_tac_instruction_set_next(current_instruction, instruction); + elna_instruction_list_concatenate(current_instruction, instruction); current_instruction := instruction end; instruction := _elna_tac_jump(after_end_label, 0); - _elna_tac_instruction_set_next(current_instruction, instruction); + elna_instruction_list_concatenate(current_instruction, instruction); current_instruction := _elna_tac_label(condition_label, 0); - _elna_tac_instruction_set_next(instruction, current_instruction); + elna_instruction_list_concatenate(instruction, current_instruction); return first_instruction end; @@ -2533,7 +2703,7 @@ begin if first_instruction = 0 then first_instruction := instruction else - _elna_tac_instruction_set_next(current_instruction, instruction) + elna_instruction_list_concatenate(current_instruction, instruction) end; current_instruction := instruction; goto elna_tac_statements_loop @@ -2561,7 +2731,7 @@ begin current_node := _conditional_statements_get_next(current_node); if current_node <> 0 then instruction := _elna_tac_conditional_statements(current_node, after_end_label, symbol_table); - _elna_tac_instruction_set_next(current_instruction, instruction); + elna_instruction_list_concatenate(current_instruction, instruction); current_instruction := instruction; goto elna_tac_if_statement_loop end; @@ -2570,12 +2740,12 @@ begin if current_node <> 0 then instruction := _elna_tac_statements(current_node, symbol_table); if instruction <> 0 then - _elna_tac_instruction_set_next(current_instruction, instruction); + elna_instruction_list_concatenate(current_instruction, instruction); current_instruction := instruction end end; instruction := _elna_tac_label(after_end_label, 0); - _elna_tac_instruction_set_next(current_instruction, instruction); + elna_instruction_list_concatenate(current_instruction, instruction); return first_instruction end; @@ -2919,9 +3089,9 @@ begin result := malloc(_parameter_info_size()); _info_set_kind(result, InfoKind.parameter_info); - (* Calculate the stack offset: 88 - (4 * parameter_counter) *) + (* Calculate the stack offset: 104 - (4 * parameter_counter) *) offset := parameter_index * 4; - _parameter_info_set_offset(result, 88 - offset); + _parameter_info_set_offset(result, 104 - offset); return result end; @@ -3117,12 +3287,11 @@ begin symbol_info := _parameter_info_get_offset(symbol_info); - instruction := _elna_tac_store_word(ElnaRtlRegister.a0 + parameter_counter, - ElnaRtlRegister.sp, symbol_info); + instruction := _elna_tac_store_word(ElnaRtlRegister.a0 + parameter_counter, ElnaRtlRegister.sp, symbol_info); if first_instruction = 0 then first_instruction := instruction else - _elna_tac_instruction_set_next(current_instruction, instruction) + elna_instruction_list_concatenate(current_instruction, instruction) end; current_instruction := instruction; @@ -3141,15 +3310,15 @@ var body: Word; result: Word; begin - result := malloc(elna_rtl_declaration_size()); - name := _elna_tac_declaration_get_name(tac_declaration); - length := _elna_tac_declaration_get_length(tac_declaration); - body := _elna_tac_declaration_get_body(tac_declaration); + result := malloc(ElnaInstructionDeclaration_size()); + name := ElnaInstructionDeclaration_get_name(tac_declaration); + length := ElnaInstructionDeclaration_get_length(tac_declaration); + body := ElnaInstructionDeclaration_get_body(tac_declaration); - elna_rtl_declaration_set_next(result, 0); - elna_rtl_declaration_set_name(result, name); - elna_rtl_declaration_set_length(result, length); - elna_rtl_declaration_set_body(result, body); + ElnaInstructionList_set_next(result, 0); + ElnaInstructionDeclaration_set_name(result, name); + ElnaInstructionDeclaration_set_length(result, length); + ElnaInstructionDeclaration_set_body(result, body); return result end; @@ -3161,16 +3330,16 @@ var body: Word; result: Word; begin - result := malloc(elna_rtl_declaration_size()); - name := _elna_tac_declaration_get_name(tac_declaration); - length := _elna_tac_declaration_get_length(tac_declaration); - body := _elna_tac_declaration_get_body(tac_declaration); + result := malloc(ElnaInstructionDeclaration_size()); + name := ElnaInstructionDeclaration_get_name(tac_declaration); + length := ElnaInstructionDeclaration_get_length(tac_declaration); + body := ElnaInstructionDeclaration_get_body(tac_declaration); body := elna_rtl_instructions(body); - elna_rtl_declaration_set_next(result, 0); - elna_rtl_declaration_set_name(result, name); - elna_rtl_declaration_set_length(result, length); - elna_rtl_declaration_set_body(result, body); + ElnaInstructionList_set_next(result, 0); + ElnaInstructionDeclaration_set_name(result, name); + ElnaInstructionDeclaration_set_length(result, length); + ElnaInstructionDeclaration_set_body(result, body); return result end; @@ -3188,15 +3357,15 @@ var result: Word; result_size: Word; begin - result := malloc(_elna_tac_declaration_size()); + result := malloc(ElnaInstructionDeclaration_size()); - _elna_tac_declaration_set_next(result, 0); + ElnaInstructionList_set_next(result, 0); name_pointer := _declaration_get_name(parser_node); name_length := _declaration_get_length(parser_node); - _elna_tac_declaration_set_name(result, name_pointer); - _elna_tac_declaration_set_length(result, name_length); + ElnaInstructionDeclaration_set_name(result, name_pointer); + ElnaInstructionDeclaration_set_length(result, name_length); symbol_info := _symbol_table_lookup(@symbol_table_global, name_pointer, name_length); new_symbol_table := _procedure_info_get_symbol_table(symbol_info); @@ -3206,17 +3375,17 @@ begin current_parameter := _procedure_declaration_get_parameters(parser_node); current_parameter := _elna_tac_parameters(current_parameter, new_symbol_table); - _elna_tac_instruction_set_next(first_instruction, current_parameter); + elna_instruction_list_concatenate(first_instruction, current_parameter); body := _procedure_declaration_get_body(parser_node); instruction := _elna_tac_statements(body, new_symbol_table); - _elna_tac_instruction_set_next(first_instruction, instruction); + elna_instruction_list_concatenate(first_instruction, instruction); (* Write the epilogue. *) instruction := _elna_tac_instruction_create(ElnaTacOperator.ret); - _elna_tac_instruction_set_next(first_instruction, instruction); + elna_instruction_list_concatenate(first_instruction, instruction); - _elna_tac_declaration_set_body(result, first_instruction); + ElnaInstructionDeclaration_set_body(result, first_instruction); return result end; @@ -3260,7 +3429,7 @@ var begin if tac_procedure <> 0 then first_copy := elna_rtl_global_declaration(tac_procedure); - tac_procedure := _elna_tac_declaration_get_next(tac_procedure) + tac_procedure := ElnaInstructionList_get_next(tac_procedure) else first_copy := 0; end; @@ -3271,8 +3440,8 @@ begin if tac_procedure <> 0 then next_copy := elna_rtl_global_declaration(tac_procedure); - tac_procedure := _elna_tac_declaration_get_next(tac_procedure); - elna_rtl_declaration_set_next(current_copy, next_copy); + tac_procedure := ElnaInstructionList_get_next(tac_procedure); + ElnaInstructionList_set_next(current_copy, next_copy); current_copy := next_copy; goto elna_rtl_globals_start end; @@ -3288,7 +3457,7 @@ var begin if tac_procedure <> 0 then first_copy := elna_rtl_procedure_declaration(tac_procedure); - tac_procedure := _elna_tac_declaration_get_next(tac_procedure) + tac_procedure := ElnaInstructionList_get_next(tac_procedure) else first_copy := 0; end; @@ -3299,8 +3468,8 @@ begin if tac_procedure <> 0 then next_copy := elna_rtl_procedure_declaration(tac_procedure); - tac_procedure := _elna_tac_declaration_get_next(tac_procedure); - elna_rtl_declaration_set_next(current_copy, next_copy); + tac_procedure := ElnaInstructionList_get_next(tac_procedure); + ElnaInstructionList_set_next(current_copy, next_copy); current_copy := next_copy; goto elna_rtl_procedures_start end; @@ -3324,7 +3493,7 @@ begin if first_procedure = 0 then first_procedure := result else - _elna_tac_declaration_set_next(current_procedure, result) + ElnaInstructionList_set_next(current_procedure, result) end; current_procedure := result; @@ -3475,25 +3644,25 @@ var variable_type: Word; result: Word; begin - result := malloc(_elna_tac_declaration_size()); + result := malloc(ElnaInstructionDeclaration_size()); - _elna_tac_declaration_set_next(result, 0); + ElnaInstructionList_set_next(result, 0); name := _declaration_get_name(parser_tree); name_length := _declaration_get_length(parser_tree); variable_type := _variable_declaration_get__type(parser_tree); - _elna_tac_declaration_set_name(result, name); - _elna_tac_declaration_set_length(result, name_length); + ElnaInstructionDeclaration_set_name(result, name); + ElnaInstructionDeclaration_set_length(result, name_length); name := _named_type_expression_get_name(variable_type); name_length := _named_type_expression_get_length(variable_type); if string_compare("Array", 5, name, name_length) then (* Else we assume this is a zeroed 4096 bytes big array. *) - _elna_tac_declaration_set_body(result, 4096) + ElnaInstructionDeclaration_set_body(result, 4096) else - _elna_tac_declaration_set_body(result, 4) + ElnaInstructionDeclaration_set_body(result, 4) end; return result end; @@ -3514,8 +3683,8 @@ begin new_length := field_length + name_length; new_length := new_length + 5; - first_result := malloc(_elna_tac_declaration_size()); - _elna_tac_declaration_set_next(first_result, 0); + first_result := malloc(ElnaInstructionDeclaration_size()); + ElnaInstructionList_set_next(first_result, 0); new_name := malloc(new_length); @@ -3526,16 +3695,16 @@ begin name_target := name_target + 5; memcpy(name_target, field_pointer^, field_length); - _elna_tac_declaration_set_name(first_result, new_name); - _elna_tac_declaration_set_length(first_result, new_length); + ElnaInstructionDeclaration_set_name(first_result, new_name); + ElnaInstructionDeclaration_set_length(first_result, new_length); - instruction := _elna_tac_add_immediate(ElnaRtlRegister.a0, ElnaRtlRegister.a0, field_offset, 0); + instruction := _elna_tac_add(ElnaRtlRegister.a0, ElnaRtlRegister.a0, ElnaTacOperand.immediate, field_offset); next_instruction := _elna_tac_load_word(ElnaRtlRegister.a0, ElnaRtlRegister.a0, 0); - _elna_tac_instruction_set_next(instruction, next_instruction); - _elna_tac_declaration_set_body(first_result, instruction); + elna_instruction_list_concatenate(instruction, next_instruction); + ElnaInstructionDeclaration_set_body(first_result, instruction); - second_result := malloc(_elna_tac_declaration_size()); - _elna_tac_declaration_set_next(second_result, 0); + second_result := malloc(ElnaInstructionDeclaration_size()); + ElnaInstructionList_set_next(second_result, 0); new_name := malloc(new_length); @@ -3546,15 +3715,15 @@ begin name_target := name_target + 5; memcpy(name_target, field_pointer^, field_length); - _elna_tac_declaration_set_name(second_result, new_name); - _elna_tac_declaration_set_length(second_result, new_length); + ElnaInstructionDeclaration_set_name(second_result, new_name); + ElnaInstructionDeclaration_set_length(second_result, new_length); - instruction := _elna_tac_add_immediate(ElnaRtlRegister.a0, ElnaRtlRegister.a0, field_offset, 0); + instruction := _elna_tac_add(ElnaRtlRegister.a0, ElnaRtlRegister.a0, ElnaTacOperand.immediate, field_offset); next_instruction := _elna_tac_store_word(ElnaRtlRegister.a1, ElnaRtlRegister.a0, 0); - _elna_tac_instruction_set_next(instruction, next_instruction); - _elna_tac_declaration_set_body(second_result, instruction); + elna_instruction_list_concatenate(instruction, next_instruction); + ElnaInstructionDeclaration_set_body(second_result, instruction); - _elna_tac_declaration_set_next(first_result, second_result); + ElnaInstructionList_set_next(first_result, second_result); return first_result end; @@ -3571,12 +3740,9 @@ var field_offset: Word; field_pointer: Word; begin - first_result := malloc(_elna_tac_declaration_size()); + first_result := malloc(ElnaInstructionDeclaration_size()); result := 0; - (* Debug. Error stream output. - _syscall(2, name_pointer, name_length, 0, 0, 0, 64); *) - type_size := _type_get_size(type_representation); new_length := name_length + 5; new_name := malloc(new_length); @@ -3584,11 +3750,14 @@ begin memcpy(new_name, name_pointer, name_length); memcpy(new_name + name_length, "_size", 5); - _elna_tac_declaration_set_name(first_result, new_name); - _elna_tac_declaration_set_length(first_result, new_length); + ElnaInstructionDeclaration_set_name(first_result, new_name); + ElnaInstructionDeclaration_set_length(first_result, new_length); - instruction := _elna_tac_load_immediate(ElnaRtlRegister.a0, type_size, 0); - _elna_tac_declaration_set_body(first_result, instruction); + instruction := _elna_tac_instruction_create(ElnaTacOperator.assign); + _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.a0, 0); + _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.immediate, type_size, 0); + + ElnaInstructionDeclaration_set_body(first_result, instruction); field_count := _record_type_get_length(type_representation); field_pointer := _record_type_get_members(type_representation); @@ -3599,8 +3768,8 @@ begin if field_count > 0 then result := _elna_tac_type_field(name_pointer, name_length, field_pointer, field_offset); - _elna_tac_declaration_set_next(current_result^, result); - current_result^ := _elna_tac_declaration_get_next(result); + ElnaInstructionList_set_next(current_result^, result); + current_result^ := ElnaInstructionList_get_next(result); field_offset := field_offset + 4; field_count := field_count - 1; @@ -3647,7 +3816,7 @@ begin first_result := result; current_result := out_result elsif result <> 0 then - _elna_tac_declaration_set_next(current_result, result); + ElnaInstructionList_set_next(current_result, result); current_result := out_result end; parser_node := _declaration_get_next(parser_node); @@ -3713,7 +3882,7 @@ begin if first_variable = 0 then first_variable := node else - _elna_tac_declaration_set_next(current_variable, node) + ElnaInstructionList_set_next(current_variable, node) end; current_variable := node; @@ -3770,15 +3939,15 @@ begin current_declaration := code_part; .elna_tac_module_declaration_types; - next_declaration := _elna_tac_declaration_get_next(current_declaration); + next_declaration := ElnaInstructionList_get_next(current_declaration); if next_declaration <> 0 then current_declaration := next_declaration; goto elna_tac_module_declaration_types end; - _elna_tac_declaration_set_next(current_declaration, type_part); + ElnaInstructionList_set_next(current_declaration, type_part); - return _elna_tac_module_create(data_part, code_part) + return elna_instruction_module_create(data_part, code_part) end; proc _elna_name_procedure_declaration(parser_node: Word); @@ -4790,7 +4959,8 @@ proc _initialize_global_state(); begin compiler_strings_position := @compiler_strings; source_code := malloc(495616); - symbol_table_store := malloc(4194304) + symbol_table_store := malloc(4194304); + temporary_variable_counter := 0 end; (*