Rewrite RTL with the new singly linked list
This commit is contained in:
@@ -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
|
||||
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);
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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)
|
||||
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);
|
||||
|
||||
elna_list_append(instructions, instruction)
|
||||
end
|
||||
end;
|
||||
|
||||
return result
|
||||
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)
|
||||
elna_rtl_load_operand_value(instructions, tac_instruction, 2, ElnaRtlRegister.t2);
|
||||
elna_rtl_load_operand_value(instructions, tac_instruction, 3, ElnaRtlRegister.t3)
|
||||
end;
|
||||
|
||||
return result
|
||||
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);
|
||||
elna_rtl_binary_operands(instructions, tac_instruction);
|
||||
instruction := elna_rtl_instruction_create(operation);
|
||||
|
||||
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
|
||||
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;
|
||||
|
||||
return lhs
|
||||
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_binary_operands(instructions, tac_instruction);
|
||||
instruction := elna_rtl_instruction_create(ElnaRtlOperator._xor);
|
||||
|
||||
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_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);
|
||||
|
||||
intermediate_instruction := next_instruction^;
|
||||
intermediate_instruction^.next := binary_result;
|
||||
next_instruction^ := binary_result;
|
||||
|
||||
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;
|
||||
elna_list_append(instructions, 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);
|
||||
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);
|
||||
|
||||
intermediate_instruction := next_instruction^;
|
||||
operating_instruction^.next := binary_result;
|
||||
next_instruction^ := binary_result;
|
||||
|
||||
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,234 +1009,147 @@ 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);
|
||||
instruction := elna_rtl_instruction_create(ElnaRtlOperator.jal);
|
||||
elna_rtl_copy_operand(tac_instruction, 1, instruction);
|
||||
elna_list_append(instructions, instruction);
|
||||
|
||||
if first_instruction = nil then
|
||||
first_instruction := argument_move
|
||||
else
|
||||
elna_instruction_list_concatenate(current_instruction, argument_move)
|
||||
end;
|
||||
current_instruction := argument_move;
|
||||
|
||||
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);
|
||||
elna_rtl_binary_operands(instructions, tac_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);
|
||||
|
||||
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^
|
||||
elna_tac_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.t4, 0);
|
||||
elna_list_append(instructions, instruction)
|
||||
end
|
||||
end
|
||||
end;
|
||||
if next_instruction^ = nil then
|
||||
next_instruction^ := result;
|
||||
end;
|
||||
return result
|
||||
end;
|
||||
|
||||
proc elna_tac_label(instructions: ^ElnaList, counter: Word, length: Word);
|
||||
var
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user