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