From aab7e42260c19f9901ab684c2d1f7c7d26d44064 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sat, 7 Mar 2026 22:50:13 +0100 Subject: [PATCH] Move register allocation into the allocation pass --- boot/stage20/cl.elna | 602 +++++++++++++++++++++++++------------------ 1 file changed, 355 insertions(+), 247 deletions(-) diff --git a/boot/stage20/cl.elna b/boot/stage20/cl.elna index 99a8ab1..5da101e 100644 --- a/boot/stage20/cl.elna +++ b/boot/stage20/cl.elna @@ -477,7 +477,7 @@ type jump_if_not_zero, label, _return, - noop + nop ); ElnaTacKind = (list, immediate, symbol, pseudo); ElnaTacOperand = record @@ -534,7 +534,7 @@ type label, allocate_stack, ret, - noop + nop ); ElnaRtlKind = (register, immediate, symbol, pseudo, offset, pseudo_mem); ElnaRtlOperand = record @@ -816,9 +816,9 @@ var temporary_info: ^ElnaSymbolTemporaryInfo; begin pseudo_counter := pseudo_counter + 1; - buffer := malloc(6); + buffer := malloc(7); - sprintf(buffer, "$%i\0", pseudo_counter); + sprintf(buffer, "$a%i\0", pseudo_counter); operand_type^ := ElnaTacKind.pseudo; operand_value^ := buffer; @@ -866,168 +866,221 @@ begin this^.operands[n].length := operand_length end; -proc elna_rtl_load_operand_value(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, operand_number: Word, into: Word); +(** + * Loads or moves the value from a TAC operand into the given register. + *) +proc elna_rtl_load_operand_value(instructions: ^ElnaList, operand: ^ElnaTacOperand, + into: ElnaRtlRegister, variable_map: ^ElnaSymbolTable); var instruction: ^ElnaRtlInstruction; - operand_value: Word; - operand_length: Word; - operand_type: Word; + pseudo_symbol: ^ElnaRtlInfo; begin - operand_type := tac_instruction^.operands[operand_number].kind; - operand_value := tac_instruction^.operands[operand_number].value; - operand_length := tac_instruction^.operands[operand_number].length; - - if operand_type = ElnaTacKind.immediate then + if operand^.kind = ElnaTacKind.immediate then instruction := elna_rtl_instruction_create(ElnaRtlOperator.li); elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0); - elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.immediate, operand_value, operand_length); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.immediate, operand^.value, operand^.length); elna_list_append(instructions, instruction) - elsif operand_type = ElnaTacKind.symbol then + elsif operand^.kind = ElnaTacKind.symbol then instruction := elna_rtl_instruction_create(ElnaRtlOperator.la); elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0); - elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.symbol, operand_value, operand_length); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.symbol, operand^.value, operand^.length); elna_list_append(instructions, instruction); instruction := elna_rtl_instruction_create(ElnaRtlOperator.lw); elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0); elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, into, 0); elna_list_append(instructions, instruction) - elsif operand_type = ElnaTacKind.pseudo then - instruction := elna_rtl_instruction_create(ElnaRtlOperator.move); - elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0); - elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo, operand_value, operand_length); + elsif operand^.kind = ElnaTacKind.pseudo then + pseudo_symbol := elna_symbol_table_lookup(variable_map, operand^.value, operand^.length); + if pseudo_symbol = nil then + instruction := elna_rtl_instruction_create(ElnaRtlOperator.la); + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.symbol, operand^.value, operand^.length); + elna_list_append(instructions, instruction); + instruction := elna_rtl_instruction_create(ElnaRtlOperator.lw); + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, into, 0) + else + instruction := elna_rtl_instruction_create(ElnaRtlOperator.move); + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo, operand^.value, operand^.length) + end; elna_list_append(instructions, instruction) end end; -proc elna_rtl_binary_operands(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction); -begin - elna_rtl_load_operand_value(instructions, tac_instruction, 2, ElnaRtlRegister.t2); - elna_rtl_load_operand_value(instructions, tac_instruction, 3, ElnaRtlRegister.t3) -end; - -proc elna_rtl_binary_arithmetic(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, operation: Word); +proc elna_rtl_operand_value(instructions: ^ElnaList, tac_operand: ^ElnaTacOperand, variable_map: ^ElnaSymbolTable, rtl_operand: ^ElnaRtlOperand); var instruction: ^ElnaRtlInstruction; + pseudo_symbol: ^ElnaRtlInfo; begin - elna_rtl_binary_operands(instructions, tac_instruction); - instruction := elna_rtl_instruction_create(operation); + rtl_operand^.kind := ElnaRtlKind.pseudo; + if tac_operand^.kind = ElnaTacKind.immediate then + elna_rtl_generate_pseudo(@rtl_operand^.value, @rtl_operand^.length, variable_map); - elna_rtl_copy_operand(tac_instruction, 1, instruction); - elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.t2, 0); - elna_rtl_instruction_set_operand(instruction, 3, ElnaRtlKind.register, ElnaRtlRegister.t3, 0); - elna_list_append(instructions, instruction) + instruction := elna_rtl_instruction_create(ElnaRtlOperator.li); + elna_rtl_instruction_set_operand(instruction, 1, rtl_operand^.kind, rtl_operand^.value, rtl_operand^.length); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.immediate, tac_operand^.value, tac_operand^.length); + elna_list_append(instructions, instruction) + elsif tac_operand^.kind = ElnaTacKind.symbol then + elna_rtl_generate_pseudo(@rtl_operand^.value, @rtl_operand^.length, variable_map); + + instruction := elna_rtl_instruction_create(ElnaRtlOperator.la); + elna_rtl_instruction_set_operand(instruction, 1, rtl_operand^.kind, rtl_operand^.value, rtl_operand^.length); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.symbol, tac_operand^.value, tac_operand^.length); + elna_list_append(instructions, instruction); + + instruction := elna_rtl_instruction_create(ElnaRtlOperator.lw); + elna_rtl_instruction_set_operand(instruction, 1, rtl_operand^.kind, rtl_operand^.value, rtl_operand^.length); + elna_rtl_instruction_set_operand(instruction, 2, rtl_operand^.kind, rtl_operand^.value, rtl_operand^.length); + elna_list_append(instructions, instruction) + elsif tac_operand^.kind = ElnaTacKind.pseudo then + pseudo_symbol := elna_symbol_table_lookup(variable_map, tac_operand^.value, tac_operand^.length); + if pseudo_symbol = nil then + elna_rtl_generate_pseudo(@rtl_operand^.value, @rtl_operand^.length, variable_map); + + instruction := elna_rtl_instruction_create(ElnaRtlOperator.la); + elna_rtl_instruction_set_operand(instruction, 1, rtl_operand^.kind, rtl_operand^.value, rtl_operand^.length); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.symbol, tac_operand^.value, tac_operand^.length); + elna_list_append(instructions, instruction); + + instruction := elna_rtl_instruction_create(ElnaRtlOperator.lw); + elna_rtl_instruction_set_operand(instruction, 1, rtl_operand^.kind, rtl_operand^.value, rtl_operand^.length); + elna_rtl_instruction_set_operand(instruction, 2, rtl_operand^.kind, rtl_operand^.value, rtl_operand^.length); + elna_list_append(instructions, instruction) + else + rtl_operand^.value := tac_operand^.value; + rtl_operand^.length := tac_operand^.length + end + end end; -proc elna_rtl_binary_equality(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, instruction_kind: Word); +proc elna_rtl_binary_arithmetic(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, + operation: ElnaRtlOperator, variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; +var + result: ^ElnaRtlInstruction; + rtl_operand: ElnaRtlOperand; +begin + result := elna_rtl_instruction_create(operation); + elna_rtl_copy_operand(instructions, @tac_instruction^.operands[1], 1, result, variable_map); + + elna_rtl_operand_value(instructions, @tac_instruction^.operands[2], variable_map, @rtl_operand); + elna_rtl_instruction_set_operand(result, 2, rtl_operand.kind, rtl_operand.value, rtl_operand.length); + + elna_rtl_operand_value(instructions, @tac_instruction^.operands[3], variable_map, @rtl_operand); + elna_rtl_instruction_set_operand(result, 3, rtl_operand.kind, rtl_operand.value, rtl_operand.length); + + elna_list_append(instructions, result); + return result +end; + +proc elna_rtl_binary_equality(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, + instruction_kind: ElnaRtlOperator, variable_map: ^ElnaSymbolTable); var instruction: ^ElnaRtlInstruction; + target_operand: ^ElnaRtlOperand; begin - elna_rtl_binary_operands(instructions, tac_instruction); - instruction := elna_rtl_instruction_create(ElnaRtlOperator._xor); - - elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t2, 0); - elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.t2, 0); - elna_rtl_instruction_set_operand(instruction, 3, ElnaRtlKind.register, ElnaRtlRegister.t3, 0); - elna_list_append(instructions, instruction); + instruction := elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator._xor, variable_map); + target_operand := @instruction^.operands[1]; instruction := elna_rtl_instruction_create(instruction_kind); - elna_rtl_copy_operand(tac_instruction, 1, instruction); - elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.t2, 0); + elna_rtl_instruction_set_operand(instruction, 1, target_operand^.kind, target_operand^.value, target_operand^.length); + elna_rtl_instruction_set_operand(instruction, 2, target_operand^.kind, target_operand^.value, target_operand^.length); elna_list_append(instructions, instruction) end; +proc elna_rtl_set_less_than(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, + lhs: Word, rhs: Word, variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; +var + slt_instruction: ^ElnaRtlInstruction; + rtl_operand: ElnaRtlOperand; +begin + slt_instruction := elna_rtl_instruction_create(ElnaRtlOperator.slt); + elna_rtl_copy_operand(instructions, @tac_instruction^.operands[1], 1, slt_instruction, variable_map); + + elna_rtl_operand_value(instructions, @tac_instruction^.operands[2], variable_map, @rtl_operand); + elna_rtl_instruction_set_operand(slt_instruction, lhs, rtl_operand.kind, rtl_operand.value, rtl_operand.length); + + elna_rtl_operand_value(instructions, @tac_instruction^.operands[3], variable_map, @rtl_operand); + elna_rtl_instruction_set_operand(slt_instruction, rhs, rtl_operand.kind, rtl_operand.value, rtl_operand.length); + + elna_list_append(instructions, slt_instruction); + return slt_instruction +end; + proc elna_rtl_binary_comparison(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, - lhs: ElnaRtlRegister, rhs: ElnaRtlRegister); + lhs: Word, rhs: Word, variable_map: ^ElnaSymbolTable); var - instruction: ^ElnaRtlInstruction; + slt_instruction: ^ElnaRtlInstruction; + xor_instruction: ^ElnaRtlInstruction; + rtl_operand: ElnaRtlOperand; begin - elna_rtl_binary_operands(instructions, tac_instruction); + slt_instruction := elna_rtl_set_less_than(instructions, tac_instruction, lhs, rhs, variable_map); - instruction := elna_rtl_instruction_create(ElnaRtlOperator.slt); - elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t2, 0); - elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, lhs, 0); - elna_rtl_instruction_set_operand(instruction, 3, ElnaRtlKind.register, rhs, 0); + xor_instruction := elna_rtl_instruction_create(ElnaRtlOperator.xori); + elna_rtl_instruction_set_operand(xor_instruction, 1, slt_instruction^.operands[1].kind, + slt_instruction^.operands[1].value, slt_instruction^.operands[1].length); + elna_rtl_instruction_set_operand(xor_instruction, 2, slt_instruction^.operands[1].kind, + slt_instruction^.operands[1].value, slt_instruction^.operands[1].length); + elna_rtl_instruction_set_operand(xor_instruction, 3, ElnaRtlKind.immediate, 1, 0); - elna_list_append(instructions, instruction); - - instruction := elna_rtl_instruction_create(ElnaRtlOperator.xori); - elna_rtl_copy_operand(tac_instruction, 1, instruction); - elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.t2, 0); - elna_rtl_instruction_set_operand(instruction, 3, ElnaRtlKind.immediate, 1, 0); - - elna_list_append(instructions, instruction) + elna_list_append(instructions, xor_instruction) end; -proc elna_rtl_copy_operand(tac_instruction: ^ElnaTacInstruction, number: Word, rtl_instruction: Word); +proc elna_rtl_copy_operand(instructions: ^ElnaList, tac_operand: ^ElnaTacOperand, number: Word, + rtl_instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable); var operand_length: Word; - operand_type: Word; operand_value: Word; + pseudo_symbol: ^ElnaRtlInfo; + instruction: ^ElnaRtlInstruction; begin - operand_type := tac_instruction^.operands[number].kind; - operand_value := tac_instruction^.operands[number].value; - operand_length := tac_instruction^.operands[number].length; + operand_value := tac_operand^.value; + operand_length := tac_operand^.length; - if operand_type = ElnaTacKind.immediate then + if tac_operand^.kind = ElnaTacKind.immediate then elna_rtl_instruction_set_operand(rtl_instruction, number, ElnaRtlKind.immediate, operand_value, operand_length) - elsif operand_type = ElnaTacKind.symbol then + elsif tac_operand^.kind = ElnaTacKind.symbol then elna_rtl_instruction_set_operand(rtl_instruction, number, ElnaRtlKind.symbol, operand_value, operand_length) - elsif operand_type = ElnaTacKind.pseudo then + elsif tac_operand^.kind = ElnaTacKind.pseudo then + pseudo_symbol := elna_symbol_table_lookup(variable_map, operand_value, operand_length); + if pseudo_symbol = nil then + pseudo_symbol := elna_rtl_generate_pseudo(@operand_value, @operand_length, variable_map); + instruction := elna_rtl_instruction_create(ElnaRtlOperator.la); + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo, operand_value, operand_length); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.symbol, tac_operand^.value, tac_operand^.length); + elna_list_append(instructions, instruction) + end; elna_rtl_instruction_set_operand(rtl_instruction, number, ElnaRtlKind.pseudo, operand_value, operand_length) end end; -proc elna_rtl_conditional_jump(instructions: ^ElnaList, tac_instruction: Word, condition: Word); +proc elna_rtl_conditional_jump(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, + condition: ElnaRtlOperator, variable_map: ^ElnaSymbolTable); var - instruction: Word; + instruction: ^ElnaRtlInstruction; + rtl_operand: ElnaRtlOperand; begin instruction := elna_rtl_instruction_create(condition); - elna_rtl_copy_operand(tac_instruction, 1, instruction); - elna_rtl_copy_operand(tac_instruction, 2, instruction); + elna_rtl_operand_value(instructions, @tac_instruction^.operands[1], variable_map, @rtl_operand); + elna_rtl_instruction_set_operand(instruction, 1, rtl_operand.kind, rtl_operand.value, rtl_operand.length); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.symbol, + tac_instruction^.operands[2].value, tac_instruction^.operands[2].length); elna_list_append(instructions, instruction) end; -proc elna_rtl_unary(instructions: ^ElnaList, tac_instruction: Word, rtl_operator: Word); +proc elna_rtl_unary(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, rtl_operator: ElnaRtlOperator, variable_map: ^ElnaSymbolTable); var instruction: ^ElnaRtlInstruction; + rtl_operand: ElnaRtlOperand; begin - elna_rtl_load_operand_value(instructions, tac_instruction, 2, ElnaRtlRegister.t0); + elna_rtl_operand_value(instructions, @tac_instruction^.operands[2], variable_map, @rtl_operand); instruction := elna_rtl_instruction_create(rtl_operator); - elna_rtl_copy_operand(tac_instruction, 1, instructions^.first); - elna_rtl_instruction_set_operand(instructions^.first, 2, ElnaRtlKind.register, ElnaRtlRegister.t0); - elna_list_append(instructions, instruction) -end; - -proc elna_rtl_call_parameter(instructions: ^ElnaList, current_argument: ^ElnaTacOperand, into: ElnaRtlRegister); -var - instruction: ^ElnaRtlInstruction; -begin - if current_argument^.kind = ElnaTacKind.pseudo then - instruction := elna_rtl_instruction_create(ElnaRtlOperator.move); - elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0); - elna_rtl_instruction_set_operand(instruction, 2, ElnaTacKind.pseudo, - current_argument^.value, current_argument^.length) - elsif current_argument^.kind = ElnaTacKind.immediate then - instruction := elna_rtl_instruction_create(ElnaRtlOperator.li); - elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0); - elna_rtl_instruction_set_operand(instruction, 2, ElnaTacKind.immediate, - current_argument^.value, current_argument^.length) - elsif current_argument^.kind = ElnaTacKind.symbol then - instruction := elna_rtl_instruction_create(ElnaRtlOperator.la); - elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0); - elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.symbol, - current_argument^.value, current_argument^.length); - elna_list_append(instructions, instruction); - - instruction := elna_rtl_instruction_create(ElnaRtlOperator.lw); - elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0); - elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, into, 0); - elna_list_append(instructions, instruction) - end; + elna_rtl_copy_operand(instructions, @tac_instruction^.operands[1], 1, instruction, variable_map); + elna_rtl_instruction_set_operand(instruction, 2, rtl_operand.kind, rtl_operand.value, rtl_operand.length); elna_list_append(instructions, instruction) end; @@ -1048,14 +1101,15 @@ begin if argument_count > 0 then argument_count := argument_count - 1; - elna_rtl_call_parameter(instructions, current_argument, ElnaRtlRegister.a0 + current_register); + elna_rtl_load_operand_value(instructions, current_argument, ElnaRtlRegister.a0 + current_register, variable_map); current_argument := current_argument + #size(ElnaTacOperand); current_register := current_register + 1; goto elna_rtl_call_loop end; instruction := elna_rtl_instruction_create(ElnaRtlOperator.jal); - elna_rtl_copy_operand(tac_instruction, 1, instruction); + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.symbol, + tac_instruction^.operands[1].value, tac_instruction^.operands[1].length); elna_list_append(instructions, instruction); instruction := elna_rtl_instruction_create(ElnaRtlOperator.move); @@ -1065,31 +1119,30 @@ begin elna_list_append(instructions, instruction) end; -proc elna_rtl_store(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction); +proc elna_rtl_store(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable); var instruction: ^ElnaRtlInstruction; + rtl_operand: ElnaRtlOperand; begin - elna_rtl_load_operand_value(instructions, tac_instruction, 1, ElnaRtlRegister.t0); + 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, ElnaRtlKind.register, ElnaRtlRegister.t0, 0); - - if tac_instruction^.operands[2].kind = ElnaTacKind.pseudo then - elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo, - tac_instruction^.operands[2].value, tac_instruction^.operands[2].length) - end; + elna_rtl_instruction_set_operand(instruction, 1, rtl_operand.kind, rtl_operand.value, rtl_operand.length); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo, + tac_instruction^.operands[2].value, tac_instruction^.operands[2].length); elna_list_append(instructions, instruction) end; -proc elna_rtl_load(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction); +proc elna_rtl_load(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable); var instruction: ^ElnaRtlInstruction; + rtl_operand: ElnaRtlOperand; begin - elna_rtl_load_operand_value(instructions, tac_instruction, 1, ElnaRtlRegister.t0); - + elna_rtl_operand_value(instructions, @tac_instruction^.operands[1], variable_map, @rtl_operand); instruction := elna_rtl_instruction_create(ElnaRtlOperator.lw); - elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.t0, 0); - elna_rtl_instruction_set_operand(instruction, 1, tac_instruction^.operands[2].kind, + + elna_rtl_instruction_set_operand(instruction, 2, rtl_operand.kind, rtl_operand.value, rtl_operand.length); + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo, tac_instruction^.operands[2].value, tac_instruction^.operands[2].length); elna_list_append(instructions, instruction) end; @@ -1097,74 +1150,80 @@ end; proc elna_rtl_instruction(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable); var instruction: ^ElnaRtlInstruction; + pseudo_symbol: ^ElnaRtlInfo; + rtl_operand: ElnaRtlOperand; begin if tac_instruction^.operator = ElnaTacOperator.get_address then + pseudo_symbol := elna_symbol_table_lookup(variable_map, + tac_instruction^.operands[2].value, tac_instruction^.operands[2].length); instruction := elna_rtl_instruction_create(ElnaRtlOperator.la); - elna_rtl_copy_operand(tac_instruction, 1, instruction); - elna_rtl_copy_operand(tac_instruction, 2, instruction); + elna_rtl_copy_operand(instructions, @tac_instruction^.operands[1], 1, instruction, variable_map); + if pseudo_symbol = nil then + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.symbol, + tac_instruction^.operands[2].value, tac_instruction^.operands[2].length) + else + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo, + tac_instruction^.operands[2].value, tac_instruction^.operands[2].length) + end; elna_list_append(instructions, instruction) elsif tac_instruction^.operator = ElnaTacOperator.add then - elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator.add) + elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator.add, variable_map) elsif tac_instruction^.operator = ElnaTacOperator.load then - elna_rtl_load(instructions, tac_instruction) + elna_rtl_load(instructions, tac_instruction, variable_map) elsif tac_instruction^.operator = ElnaTacOperator.store then - elna_rtl_store(instructions, tac_instruction) + elna_rtl_store(instructions, tac_instruction, variable_map) elsif tac_instruction^.operator = ElnaTacOperator.proc_call then elna_rtl_call(instructions, tac_instruction, variable_map) elsif tac_instruction^.operator = ElnaTacOperator.subtract then - elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator.sub) + elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator.sub, variable_map) elsif tac_instruction^.operator = ElnaTacOperator.multiply then - elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator.mul) + elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator.mul, variable_map) elsif tac_instruction^.operator = ElnaTacOperator.divide then - elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator.div) + elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator.div, variable_map) elsif tac_instruction^.operator = ElnaTacOperator.remainder then - elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator.rem) + elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator.rem, variable_map) elsif tac_instruction^.operator = ElnaTacOperator._xor then - elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator._xor) + elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator._xor, variable_map) elsif tac_instruction^.operator = ElnaTacOperator._or then - elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator._or) + elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator._or, variable_map) elsif tac_instruction^.operator = ElnaTacOperator.and then - elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator.and) + elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator.and, variable_map) elsif tac_instruction^.operator = ElnaTacOperator.less_than then - elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator.slt) + elna_rtl_set_less_than(instructions, tac_instruction, 2, 3, variable_map) elsif tac_instruction^.operator = ElnaTacOperator.greater_than then - elna_rtl_binary_operands(instructions, tac_instruction); - - instruction := elna_rtl_instruction_create(ElnaRtlOperator.slt); - elna_rtl_copy_operand(tac_instruction, 1, instruction); - elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.t3, 0); - elna_rtl_instruction_set_operand(instruction, 3, ElnaRtlKind.register, ElnaRtlRegister.t2, 0); - elna_list_append(instructions, instruction) + elna_rtl_set_less_than(instructions, tac_instruction, 3, 2, variable_map) elsif tac_instruction^.operator = ElnaTacOperator.less_or_equal then - elna_rtl_binary_comparison(instructions, tac_instruction, ElnaRtlRegister.t3, ElnaRtlRegister.t2) + elna_rtl_binary_comparison(instructions, tac_instruction, 3, 2, variable_map) elsif tac_instruction^.operator = ElnaTacOperator.greater_or_equal then - elna_rtl_binary_comparison(instructions, tac_instruction, ElnaRtlRegister.t2, ElnaRtlRegister.t3) + elna_rtl_binary_comparison(instructions, tac_instruction, 2, 3, variable_map) elsif tac_instruction^.operator = ElnaTacOperator.equal then - elna_rtl_binary_equality(instructions, tac_instruction, ElnaRtlOperator.seqz) + elna_rtl_binary_equality(instructions, tac_instruction, ElnaRtlOperator.seqz, variable_map) elsif tac_instruction^.operator = ElnaTacOperator.not_equal then - elna_rtl_binary_equality(instructions, tac_instruction, ElnaRtlOperator.snez) + elna_rtl_binary_equality(instructions, tac_instruction, ElnaRtlOperator.snez, variable_map) elsif tac_instruction^.operator = ElnaTacOperator.negate then - elna_rtl_unary(instructions, tac_instruction, ElnaRtlOperator.neg) + elna_rtl_unary(instructions, tac_instruction, ElnaRtlOperator.neg, variable_map) elsif tac_instruction^.operator = ElnaTacOperator.complement then - elna_rtl_unary(instructions, tac_instruction, ElnaRtlOperator.not) + elna_rtl_unary(instructions, tac_instruction, ElnaRtlOperator.not, variable_map) elsif tac_instruction^.operator = ElnaTacOperator.jump then instruction := elna_rtl_instruction_create(ElnaRtlOperator.j); - elna_rtl_copy_operand(tac_instruction, 1, instruction); + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.symbol, + tac_instruction^.operands[1].value, tac_instruction^.operands[1].length); elna_list_append(instructions, instruction) elsif tac_instruction^.operator = ElnaTacOperator.jump_if_zero then - elna_rtl_conditional_jump(instructions, tac_instruction, ElnaRtlOperator.beqz) + elna_rtl_conditional_jump(instructions, tac_instruction, ElnaRtlOperator.beqz, variable_map) elsif tac_instruction^.operator = ElnaTacOperator.jump_if_not_zero then - elna_rtl_conditional_jump(instructions, tac_instruction, ElnaRtlOperator.bnez) + 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, 1, ElnaRtlRegister.a0) + elna_rtl_load_operand_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_copy_operand(tac_instruction, 1, instruction); + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.symbol, + tac_instruction^.operands[1].value, tac_instruction^.operands[1].length); elna_list_append(instructions, instruction) elsif tac_instruction^.operator = ElnaTacOperator.copy then if tac_instruction^.operands[1].kind = ElnaTacKind.pseudo then - elna_rtl_load_operand_value(instructions, tac_instruction, 2, ElnaRtlRegister.t4); + elna_rtl_load_operand_value(instructions, @tac_instruction^.operands[2], ElnaRtlRegister.t4, variable_map); instruction := elna_rtl_instruction_create(ElnaRtlOperator.move); elna_tac_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo, @@ -1172,10 +1231,8 @@ begin elna_tac_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.t4, 0); elna_list_append(instructions, instruction) end - elsif tac_instruction^.operator = ElnaTacOperator.noop then - instruction := elna_rtl_instruction_create(ElnaRtlOperator.noop); - elna_rtl_copy_operand(tac_instruction, 1, instruction); - elna_rtl_copy_operand(tac_instruction, 2, instruction); + elsif tac_instruction^.operator = ElnaTacOperator.nop then + instruction := elna_rtl_instruction_create(ElnaRtlOperator.nop); elna_list_append(instructions, instruction) end end; @@ -1321,7 +1378,8 @@ end; * to be a register, but is not a register, then this procedure rewrites it * to a temporary register and preserves its value in the following instruction. *) -proc elna_alloc_operation_target(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable); +proc elna_alloc_operation_target(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, + variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; var pseudo_symbol: ^ElnaRtlInfo; store_instruction: ^ElnaRtlInstruction; @@ -1335,8 +1393,10 @@ begin elna_rtl_instruction_set_operand(store_instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol^.counter); elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t0, 0); - elna_list_insert(instructions, instruction, store_instruction) - end + elna_list_insert(instructions, instruction, store_instruction); + instruction := store_instruction + end; + return instruction end; proc elna_alloc_load_address(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable); @@ -1358,15 +1418,17 @@ end; proc elna_alloc_store(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable); var - old_instruction: ^ElnaRtlInstruction; + store_instruction: ^ElnaRtlInstruction; pseudo_symbol: ^ElnaRtlInfo; begin - if instruction^.operands[2].kind = ElnaRtlKind.pseudo then - old_instruction := elna_rtl_instruction_create(ElnaRtlOperator.sw); + instruction := elna_alloc_operand(instructions, instruction, 1, ElnaRtlRegister.t0, variable_map); - elna_rtl_instruction_set_operand(old_instruction, 1, instruction^.operands[1].kind, + if instruction^.operands[2].kind = ElnaRtlKind.pseudo then + store_instruction := elna_rtl_instruction_create(ElnaRtlOperator.sw); + + elna_rtl_instruction_set_operand(store_instruction, 1, instruction^.operands[1].kind, instruction^.operands[1].value, instruction^.operands[1].length); - elna_rtl_instruction_set_operand(old_instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.t1, 0); + elna_rtl_instruction_set_operand(store_instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.t1, 0); pseudo_symbol := elna_alloc_variable(instruction^.operands[2].value, instruction^.operands[2].length, variable_map); @@ -1374,8 +1436,10 @@ begin elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t1, 0); elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol^.counter); - elna_list_insert(instructions, instruction, old_instruction) - end + elna_list_insert(instructions, instruction, store_instruction); + instruction := store_instruction + end; + return instruction end; proc elna_alloc_load(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable); @@ -1383,17 +1447,23 @@ var new_instruction: ^ElnaRtlInstruction; pseudo_symbol: ^ElnaRtlInfo; begin - if instruction^.operands[1].kind = ElnaRtlKind.pseudo then - pseudo_symbol := elna_alloc_variable(instruction^.operands[1].value, instruction^.operands[1].length, - variable_map); - new_instruction := elna_rtl_instruction_create(ElnaRtlOperator.sw); + if instruction^.operands[2].kind = ElnaRtlKind.pseudo then + pseudo_symbol := elna_alloc_variable(instruction^.operands[2].value, + instruction^.operands[2].length, variable_map); + new_instruction := malloc(#size(ElnaRtlInstruction)); + memcpy(new_instruction, instruction, #size(ElnaRtlInstruction)); + new_instruction^.next := nil; - elna_rtl_instruction_set_operand(new_instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t1, 0); - elna_rtl_instruction_set_operand(new_instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol^.counter); + elna_rtl_instruction_set_operand(new_instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.t1, 0); + + instruction^.operator := ElnaRtlOperator.lw; elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t1, 0); - elna_list_insert(instructions, instruction, new_instruction) - end + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol^.counter); + elna_list_insert(instructions, instruction, new_instruction); + instruction := new_instruction + end; + return elna_alloc_operation_target(instructions, instruction, variable_map) end; proc elna_alloc_move(instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable); @@ -1416,7 +1486,51 @@ begin end end; -proc elna_alloc_instruction(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable); +proc elna_alloc_operand(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, + number: Word, target: ElnaRtlRegister, variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; +var + main_instruction: ^ElnaRtlInstruction; + pseudo_symbol: ^ElnaRtlInfo; +begin + if instruction^.operands[number].kind = ElnaRtlKind.pseudo then + pseudo_symbol := elna_alloc_variable(instruction^.operands[number].value, + instruction^.operands[number].length, variable_map); + main_instruction := malloc(#size(ElnaRtlInstruction)); + memcpy(main_instruction, instruction, #size(ElnaRtlInstruction)); + main_instruction^.next := nil; + + elna_rtl_instruction_set_operand(main_instruction, number, ElnaRtlKind.register, target, 0); + + instruction^.operator := ElnaRtlOperator.lw; + + elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, target, 0); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol^.counter); + elna_list_insert(instructions, instruction, main_instruction); + instruction := main_instruction + end; + return instruction +end; + +proc elna_alloc_binary(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; +var + new_instruction: ^ElnaRtlInstruction; + pseudo_symbol: ^ElnaRtlInfo; +begin + instruction := elna_alloc_operand(instructions, instruction, 2, ElnaRtlRegister.t2, variable_map); + instruction := elna_alloc_operand(instructions, instruction, 3, ElnaRtlRegister.t3, variable_map); + return elna_alloc_operation_target(instructions, instruction, variable_map) +end; + +proc elna_alloc_unary(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; +var + new_instruction: ^ElnaRtlInstruction; + pseudo_symbol: ^ElnaRtlInfo; +begin + instruction := elna_alloc_operand(instructions, instruction, 2, ElnaRtlRegister.t2, variable_map); + return elna_alloc_operation_target(instructions, instruction, variable_map) +end; + +proc elna_alloc_instruction(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; var pseudo_symbol: ^ElnaRtlInfo; new_instruction: ^ElnaRtlInstruction; @@ -1426,25 +1540,25 @@ begin elsif instruction^.operator = ElnaRtlOperator.la then elna_alloc_load_address(instructions, instruction, variable_map) elsif instruction^.operator = ElnaRtlOperator.lw then - elna_alloc_load(instructions, instruction, variable_map) + instruction := elna_alloc_load(instructions, instruction, variable_map) elsif instruction^.operator = ElnaRtlOperator.sw then - elna_alloc_store(instructions, instruction, variable_map) + instruction := elna_alloc_store(instructions, instruction, variable_map) elsif instruction^.operator = ElnaRtlOperator._or then - elna_alloc_operation_target(instructions, instruction, variable_map) + instruction := elna_alloc_binary(instructions, instruction, variable_map) elsif instruction^.operator = ElnaRtlOperator.and then - elna_alloc_operation_target(instructions, instruction, variable_map) + instruction := elna_alloc_binary(instructions, instruction, variable_map) elsif instruction^.operator = ElnaRtlOperator.mul then - elna_alloc_operation_target(instructions, instruction, variable_map) + instruction := elna_alloc_binary(instructions, instruction, variable_map) elsif instruction^.operator = ElnaRtlOperator.sub then - elna_alloc_operation_target(instructions, instruction, variable_map) + instruction := elna_alloc_binary(instructions, instruction, variable_map) elsif instruction^.operator = ElnaRtlOperator.add then - elna_alloc_operation_target(instructions, instruction, variable_map) + instruction := elna_alloc_binary(instructions, instruction, variable_map) elsif instruction^.operator = ElnaRtlOperator._xor then - elna_alloc_operation_target(instructions, instruction, variable_map) + instruction := elna_alloc_binary(instructions, instruction, variable_map) elsif instruction^.operator = ElnaRtlOperator.rem then - elna_alloc_operation_target(instructions, instruction, variable_map) + instruction := elna_alloc_binary(instructions, instruction, variable_map) elsif instruction^.operator = ElnaRtlOperator.slt then - elna_alloc_operation_target(instructions, instruction, variable_map) + instruction := elna_alloc_binary(instructions, instruction, variable_map) elsif instruction^.operator = ElnaRtlOperator.beqz then if instruction^.operands[1].kind = ElnaRtlKind.pseudo then new_instruction := elna_rtl_instruction_create(ElnaRtlOperator.beqz); @@ -1462,12 +1576,17 @@ begin elna_list_insert(instructions, instruction, new_instruction) end elsif instruction^.operator = ElnaRtlOperator.seqz then - elna_alloc_operation_target(instructions, instruction, variable_map) + instruction := elna_alloc_unary(instructions, instruction, variable_map) elsif instruction^.operator = ElnaRtlOperator.snez then - elna_alloc_operation_target(instructions, instruction, variable_map) + instruction := elna_alloc_unary(instructions, instruction, variable_map) elsif instruction^.operator = ElnaRtlOperator.xori then + instruction := elna_alloc_binary(instructions, instruction, variable_map) + elsif instruction^.operator = ElnaRtlOperator.addi then + instruction := elna_alloc_binary(instructions, instruction, variable_map) + elsif instruction^.operator = ElnaRtlOperator.li then elna_alloc_operation_target(instructions, instruction, variable_map) - end + end; + return instruction^.next end; proc elna_riscv_instruction(instruction: ^ElnaRtlInstruction); @@ -1494,15 +1613,7 @@ begin (* Write the epilogue. *) printf("\tlw ra, %i(sp)\n\tlw s0, %i(sp)\n\taddi sp, sp, %i\n\0", operand_value + 4, operand_value, operand_value + 8); fflush(nil) - elsif instruction^.operator = ElnaRtlOperator.noop then - operand_value := instruction^.operands[2].value; - - if operand_value = 0 then - printf("# Debug start\n\0"); - else - printf("# Debug end\n\0"); - end; - fflush(nil) + elsif instruction^.operator = ElnaRtlOperator.nop then else argument_count := elna_riscv_instruction_name(instruction^.operator) end; @@ -1541,8 +1652,8 @@ begin .elna_alloc_instructions_start; if instruction <> nil then - elna_alloc_instruction(instructions, instruction, variable_map); - instruction := instruction^.next; + instruction := elna_alloc_instruction(instructions, instruction, variable_map); + goto elna_alloc_instructions_start end end; @@ -2551,28 +2662,18 @@ begin instruction := elna_tac_binary_expression(instructions, parser_tree^.assignment, symbol_table, @assignment_operand); if assignee.kind = ElnaTacKind.pseudo then - instruction := elna_tac_instruction_create(ElnaTacOperator.copy); - if is_address then - elna_tac_generate_pseudo(@operand_type, @operand_value, @operand_length, symbol_table); - - (* Save the assignee address on the stack. *) - elna_tac_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length); - elna_tac_instruction_set_operand(instruction, 2, assignee.kind, assignee.value, assignee.length); - - elna_list_append(instructions, instruction); - instruction := elna_tac_instruction_create(ElnaTacOperator.store); + elna_tac_instruction_set_operand(instruction, 1, assignment_operand.kind, assignment_operand.value, assignment_operand.length); - elna_tac_instruction_set_operand(instruction, 2, operand_type, operand_value, operand_length); - - elna_list_append(instructions, instruction) + elna_tac_instruction_set_operand(instruction, 2, assignee.kind, assignee.value, assignee.length) else - elna_tac_instruction_set_operand(instruction, 1, assignee.kind, assignee.value, assignee.length); - elna_tac_instruction_set_operand(instruction, 2, assignment_operand.kind, assignment_operand.value, assignment_operand.length); + instruction := elna_tac_instruction_create(ElnaTacOperator.copy); - elna_list_append(instructions, instruction) - end + elna_tac_instruction_set_operand(instruction, 1, assignee.kind, assignee.value, assignee.length); + elna_tac_instruction_set_operand(instruction, 2, assignment_operand.kind, assignment_operand.value, assignment_operand.length) + end; + elna_list_append(instructions, instruction) else elna_tac_generate_pseudo(@operand_type, @operand_value, @operand_length, symbol_table); @@ -3429,6 +3530,32 @@ begin return lhs or rhs end; +proc elna_rtl_generate_pseudo(operand_value: Word, operand_length: Word, variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInfo; +var + pseudo_symbol: ^ElnaRtlInfo; + pseudo_type: ^ElnaRtlTypeWord; + buffer: Word; +begin + pseudo_counter := pseudo_counter + 1; + pseudo_symbol := malloc(#size(ElnaRtlInfo)); + buffer := malloc(7); + + sprintf(buffer, "$b%i\0", pseudo_counter); + pseudo_symbol^.allocated := false; + + pseudo_type := malloc(#size(ElnaRtlTypeWord)); + pseudo_type^.kind := ElnaRtlTypeKind.long_word; + pseudo_type^.size := 4; + + operand_value^ := buffer; + operand_length^ := strlen(buffer); + + pseudo_symbol^.rtl_type := pseudo_type; + elna_symbol_table_enter(variable_map, buffer, operand_length^, pseudo_symbol); + + return pseudo_symbol +end; + proc elna_rtl_symbol_table(symbol_table: ^ElnaSymbolTable); var variable_map: ^ElnaSymbolTable; @@ -3487,6 +3614,7 @@ begin result^.name := tac_declaration^.name; result^.length := tac_declaration^.length; + pseudo_counter := 0; elna_rtl_parameters(@result^.body, tac_declaration^.parameters, tac_declaration^.count); result^.variable_map := elna_rtl_symbol_table(tac_declaration^.symbol_table); @@ -4383,38 +4511,21 @@ proc elna_lexer_classifications(); var code: Word; begin + code := 1; + + (* Set everything by default to invalid. *) + .elna_lexer_classifications_invalid; + classification[code] := ElnaLexerClass.invalid; + code := code + 1; + + if code < 129 then + goto elna_lexer_classifications_invalid + end; + classification[1] := ElnaLexerClass.eof; - classification[2] := ElnaLexerClass.invalid; - classification[3] := ElnaLexerClass.invalid; - classification[4] := ElnaLexerClass.invalid; - classification[5] := ElnaLexerClass.invalid; - classification[6] := ElnaLexerClass.invalid; - classification[7] := ElnaLexerClass.invalid; - classification[8] := ElnaLexerClass.invalid; - classification[9] := ElnaLexerClass.invalid; classification[10] := ElnaLexerClass.space; classification[11] := ElnaLexerClass.space; - classification[12] := ElnaLexerClass.invalid; - classification[13] := ElnaLexerClass.invalid; classification[14] := ElnaLexerClass.space; - classification[15] := ElnaLexerClass.invalid; - classification[16] := ElnaLexerClass.invalid; - classification[17] := ElnaLexerClass.invalid; - classification[18] := ElnaLexerClass.invalid; - classification[19] := ElnaLexerClass.invalid; - classification[20] := ElnaLexerClass.invalid; - classification[21] := ElnaLexerClass.invalid; - classification[22] := ElnaLexerClass.invalid; - classification[23] := ElnaLexerClass.invalid; - classification[24] := ElnaLexerClass.invalid; - classification[25] := ElnaLexerClass.invalid; - classification[26] := ElnaLexerClass.invalid; - classification[27] := ElnaLexerClass.invalid; - classification[28] := ElnaLexerClass.invalid; - classification[29] := ElnaLexerClass.invalid; - classification[30] := ElnaLexerClass.invalid; - classification[31] := ElnaLexerClass.invalid; - classification[32] := ElnaLexerClass.invalid; classification[33] := ElnaLexerClass.space; classification[34] := ElnaLexerClass.single; classification[35] := ElnaLexerClass.double_quote; @@ -4510,17 +4621,14 @@ begin classification[125] := ElnaLexerClass.single; classification[126] := ElnaLexerClass.other; classification[127] := ElnaLexerClass.single; - classification[128] := ElnaLexerClass.invalid; - - code := 129; (* Set the remaining 129 - 256 bytes to transitionClassOther. *) - .create_classification_loop; + .elna_lexer_classifications_other; classification[code] := ElnaLexerClass.other; code := code + 1; if code < 257 then - goto create_classification_loop + goto elna_lexer_classifications_other end end;