Rewrite RTL with the new singly linked list
This commit is contained in:
@@ -544,7 +544,7 @@ type
|
|||||||
next: Word;
|
next: Word;
|
||||||
name: Word;
|
name: Word;
|
||||||
length: Word;
|
length: Word;
|
||||||
body: Word;
|
body: ElnaList;
|
||||||
variable_map: ^ElnaSymbolTable
|
variable_map: ^ElnaSymbolTable
|
||||||
end;
|
end;
|
||||||
ElnaRtlInstruction = record
|
ElnaRtlInstruction = record
|
||||||
@@ -771,14 +771,7 @@ begin
|
|||||||
else
|
else
|
||||||
list^.last^.next := element
|
list^.last^.next := element
|
||||||
end;
|
end;
|
||||||
(* TODO: This is a temporary solution for the migration from the old lists. *)
|
list^.last := element
|
||||||
.elna_list_append_loop;
|
|
||||||
if element^.next = nil then
|
|
||||||
list^.last := element
|
|
||||||
else
|
|
||||||
element := element^.next;
|
|
||||||
goto elna_list_append_loop
|
|
||||||
end
|
|
||||||
end;
|
end;
|
||||||
return element
|
return element
|
||||||
end;
|
end;
|
||||||
@@ -861,134 +854,98 @@ begin
|
|||||||
this^.operands[n].length := operand_length
|
this^.operands[n].length := operand_length
|
||||||
end;
|
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
|
var
|
||||||
result: ^ElnaRtlInstruction;
|
instruction: ^ElnaRtlInstruction;
|
||||||
operand_value: Word;
|
operand_value: Word;
|
||||||
operand_length: Word;
|
operand_length: Word;
|
||||||
operand_type: Word;
|
operand_type: Word;
|
||||||
next_instruction: Word;
|
|
||||||
begin
|
begin
|
||||||
operand_type := tac_instruction^.operands[operand_number].kind;
|
operand_type := tac_instruction^.operands[operand_number].kind;
|
||||||
operand_value := tac_instruction^.operands[operand_number].value;
|
operand_value := tac_instruction^.operands[operand_number].value;
|
||||||
operand_length := tac_instruction^.operands[operand_number].length;
|
operand_length := tac_instruction^.operands[operand_number].length;
|
||||||
|
|
||||||
if operand_type = ElnaTacKind.immediate then
|
if operand_type = ElnaTacKind.immediate then
|
||||||
result := elna_rtl_instruction_create(ElnaRtlOperator.li);
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.li);
|
||||||
elna_rtl_instruction_set_operand(result, 1, ElnaRtlKind.register, into, 0);
|
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0);
|
||||||
elna_rtl_instruction_set_operand(result, 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_type = ElnaTacKind.symbol then
|
||||||
result := elna_rtl_instruction_create(ElnaRtlOperator.la);
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.la);
|
||||||
elna_rtl_instruction_set_operand(result, 1, ElnaRtlKind.register, into, 0);
|
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0);
|
||||||
elna_rtl_instruction_set_operand(result, 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);
|
||||||
|
|
||||||
next_instruction := elna_rtl_instruction_create(ElnaRtlOperator.lw);
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.lw);
|
||||||
elna_rtl_instruction_set_operand(next_instruction, 1, ElnaRtlKind.register, into, 0);
|
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0);
|
||||||
elna_rtl_instruction_set_operand(next_instruction, 2, ElnaRtlKind.offset, into, 0);
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, into, 0);
|
||||||
|
elna_list_append(instructions, instruction)
|
||||||
result^.next := next_instruction
|
|
||||||
elsif operand_type = ElnaTacKind.pseudo then
|
elsif operand_type = ElnaTacKind.pseudo then
|
||||||
result := elna_rtl_instruction_create(ElnaRtlOperator.move);
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.move);
|
||||||
elna_rtl_instruction_set_operand(result, 1, ElnaRtlKind.register, into, 0);
|
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0);
|
||||||
elna_rtl_instruction_set_operand(result, 2, ElnaRtlKind.pseudo, operand_value, operand_length)
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo, operand_value, operand_length);
|
||||||
end;
|
|
||||||
|
|
||||||
return result
|
elna_list_append(instructions, instruction)
|
||||||
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_rtl_load_operand_address(tac_instruction: ^ElnaTacInstruction, operand_number: Word, into: Word);
|
proc elna_rtl_binary_operands(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction);
|
||||||
var
|
|
||||||
result: Word;
|
|
||||||
operand_value: Word;
|
|
||||||
operand_length: Word;
|
|
||||||
operand_type: Word;
|
|
||||||
begin
|
begin
|
||||||
operand_type := tac_instruction^.operands[operand_number].kind;
|
elna_rtl_load_operand_value(instructions, tac_instruction, 2, ElnaRtlRegister.t2);
|
||||||
operand_value := tac_instruction^.operands[operand_number].value;
|
elna_rtl_load_operand_value(instructions, tac_instruction, 3, ElnaRtlRegister.t3)
|
||||||
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
|
|
||||||
end;
|
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
|
var
|
||||||
lhs: ^ElnaRtlInstruction;
|
instruction: ^ElnaRtlInstruction;
|
||||||
rhs: ^ElnaRtlInstruction;
|
|
||||||
begin
|
begin
|
||||||
lhs := elna_rtl_load_operand_value(tac_instruction, 2, ElnaRtlRegister.t2);
|
elna_rtl_binary_operands(instructions, tac_instruction);
|
||||||
rhs := elna_rtl_load_operand_value(tac_instruction, 3, ElnaRtlRegister.t3);
|
instruction := elna_rtl_instruction_create(operation);
|
||||||
|
|
||||||
next_instruction^ := lhs^.next;
|
elna_rtl_copy_operand(tac_instruction, 1, instruction);
|
||||||
if next_instruction^ = 0 then
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.t2, 0);
|
||||||
lhs^.next := rhs
|
elna_rtl_instruction_set_operand(instruction, 3, ElnaRtlKind.register, ElnaRtlRegister.t3, 0);
|
||||||
else
|
elna_list_append(instructions, instruction)
|
||||||
next_instruction^^ := rhs
|
|
||||||
end;
|
|
||||||
next_instruction^ := rhs^.next;
|
|
||||||
if next_instruction^ = 0 then
|
|
||||||
next_instruction^ := rhs
|
|
||||||
end;
|
|
||||||
|
|
||||||
return lhs
|
|
||||||
end;
|
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
|
var
|
||||||
lhs: Word;
|
instruction: ^ElnaRtlInstruction;
|
||||||
binary_result: ^ElnaRtlInstruction;
|
|
||||||
intermediate_instruction: ^ElnaRtlInstruction;
|
|
||||||
begin
|
begin
|
||||||
lhs := elna_rtl_binary_operands(tac_instruction, next_instruction);
|
elna_rtl_binary_operands(instructions, tac_instruction);
|
||||||
binary_result := elna_rtl_instruction_create(operation);
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator._xor);
|
||||||
|
|
||||||
elna_rtl_copy_operand(tac_instruction, 1, binary_result);
|
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t2, 0);
|
||||||
elna_rtl_instruction_set_operand(binary_result, 2, ElnaRtlKind.register, ElnaRtlRegister.t2, 0);
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.t2, 0);
|
||||||
elna_rtl_instruction_set_operand(binary_result, 3, ElnaRtlKind.register, ElnaRtlRegister.t3, 0);
|
elna_rtl_instruction_set_operand(instruction, 3, ElnaRtlKind.register, ElnaRtlRegister.t3, 0);
|
||||||
binary_result^.operator := operation;
|
elna_list_append(instructions, instruction);
|
||||||
|
|
||||||
intermediate_instruction := next_instruction^;
|
instruction := elna_rtl_instruction_create(instruction_kind);
|
||||||
intermediate_instruction^.next := binary_result;
|
elna_rtl_copy_operand(tac_instruction, 1, instruction);
|
||||||
next_instruction^ := binary_result;
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.t2, 0);
|
||||||
|
elna_list_append(instructions, instruction)
|
||||||
return lhs
|
|
||||||
end;
|
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
|
var
|
||||||
operands: ^ElnaRtlInstruction;
|
instruction: ^ElnaRtlInstruction;
|
||||||
intermediate_instruction: ^ElnaRtlInstruction;
|
|
||||||
operating_instruction: ^ElnaRtlInstruction;
|
|
||||||
binary_result: ^ElnaRtlInstruction;
|
|
||||||
begin
|
begin
|
||||||
operands := elna_rtl_binary_operands(tac_instruction, next_instruction);
|
elna_rtl_binary_operands(instructions, tac_instruction);
|
||||||
operating_instruction := elna_rtl_instruction_create(ElnaRtlOperator._xor);
|
|
||||||
|
|
||||||
elna_rtl_instruction_set_operand(operating_instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t2, 0);
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.slt);
|
||||||
elna_rtl_instruction_set_operand(operating_instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.t2, 0);
|
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t2, 0);
|
||||||
elna_rtl_instruction_set_operand(operating_instruction, 3, ElnaRtlKind.register, ElnaRtlRegister.t3, 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^;
|
elna_list_append(instructions, instruction);
|
||||||
intermediate_instruction^.next := operating_instruction;
|
|
||||||
|
|
||||||
binary_result := elna_rtl_instruction_create(instruction_kind);
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.xori);
|
||||||
elna_rtl_copy_operand(tac_instruction, 1, binary_result);
|
elna_rtl_copy_operand(tac_instruction, 1, instruction);
|
||||||
elna_rtl_instruction_set_operand(binary_result, 2, 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.immediate, 1, 0);
|
||||||
|
|
||||||
intermediate_instruction := next_instruction^;
|
elna_list_append(instructions, instruction)
|
||||||
operating_instruction^.next := binary_result;
|
|
||||||
next_instruction^ := binary_result;
|
|
||||||
|
|
||||||
return operands
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_rtl_copy_operand(tac_instruction: ^ElnaTacInstruction, number: Word, rtl_instruction: Word);
|
proc elna_rtl_copy_operand(tac_instruction: ^ElnaTacInstruction, number: Word, rtl_instruction: Word);
|
||||||
@@ -1010,43 +967,38 @@ begin
|
|||||||
end
|
end
|
||||||
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
|
var
|
||||||
result: Word;
|
instruction: Word;
|
||||||
begin
|
begin
|
||||||
result := elna_rtl_instruction_create(condition);
|
instruction := elna_rtl_instruction_create(condition);
|
||||||
elna_rtl_copy_operand(tac_instruction, 1, result);
|
elna_rtl_copy_operand(tac_instruction, 1, instruction);
|
||||||
elna_rtl_copy_operand(tac_instruction, 2, result);
|
elna_rtl_copy_operand(tac_instruction, 2, instruction);
|
||||||
|
|
||||||
return result
|
elna_list_append(instructions, instruction)
|
||||||
end;
|
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
|
var
|
||||||
result: ^ElnaRtlInstruction;
|
instruction: ^ElnaRtlInstruction;
|
||||||
begin
|
begin
|
||||||
result := elna_rtl_load_operand_value(tac_instruction, 2, ElnaRtlRegister.t0);
|
elna_rtl_load_operand_value(instructions, 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^;
|
|
||||||
|
|
||||||
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;
|
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
|
var
|
||||||
argument_count: Word;
|
argument_count: Word;
|
||||||
current_argument: ^ElnaTacOperand;
|
current_argument: ^ElnaTacOperand;
|
||||||
argument_move: ^ElnaRtlInstruction;
|
instruction: ^ElnaRtlInstruction;
|
||||||
current_register: Word;
|
current_register: Word;
|
||||||
first_instruction: Word;
|
|
||||||
current_instruction: Word;
|
|
||||||
variable_info: ^ElnaRtlInfo;
|
variable_info: ^ElnaRtlInfo;
|
||||||
begin
|
begin
|
||||||
current_register := 0;
|
current_register := 0;
|
||||||
first_instruction := nil;
|
|
||||||
|
|
||||||
current_argument := tac_instruction^.operands[2].value;
|
current_argument := tac_instruction^.operands[2].value;
|
||||||
argument_count := tac_instruction^.operands[2].length;
|
argument_count := tac_instruction^.operands[2].length;
|
||||||
|
|
||||||
@@ -1057,233 +1009,146 @@ begin
|
|||||||
|
|
||||||
if current_argument^.kind = ElnaTacKind.pseudo then
|
if current_argument^.kind = ElnaTacKind.pseudo then
|
||||||
variable_info := elna_symbol_table_lookup(variable_map, current_argument^.value, current_argument^.length);
|
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
|
if variable_info^.rtl_type^.size <= 4 then
|
||||||
argument_move := elna_rtl_instruction_create(ElnaRtlOperator.move);
|
instruction := 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(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a0 + current_register, 0);
|
||||||
elna_rtl_instruction_set_operand(argument_move, 2, ElnaRtlKind.pseudo,
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo,
|
||||||
current_argument^.value, current_argument^.length)
|
current_argument^.value, current_argument^.length)
|
||||||
elsif variable_info^.rtl_type^.size <= 8 then
|
elsif variable_info^.rtl_type^.size <= 8 then
|
||||||
|
|
||||||
argument_move := elna_rtl_instruction_create(ElnaRtlOperator.move);
|
instruction := 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(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a0 + current_register, 0);
|
||||||
elna_rtl_instruction_set_operand(argument_move, 2, ElnaRtlKind.pseudo,
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo,
|
||||||
current_argument^.value, current_argument^.length)
|
current_argument^.value, current_argument^.length)
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
if first_instruction = nil then
|
elna_list_append(instructions, instruction);
|
||||||
first_instruction := argument_move
|
|
||||||
else
|
|
||||||
elna_instruction_list_concatenate(current_instruction, argument_move)
|
|
||||||
end;
|
|
||||||
current_instruction := argument_move;
|
|
||||||
|
|
||||||
current_argument := current_argument + #size(ElnaTacOperand);
|
current_argument := current_argument + #size(ElnaTacOperand);
|
||||||
current_register := current_register + 1;
|
current_register := current_register + 1;
|
||||||
|
|
||||||
goto elna_rtl_call_loop
|
goto elna_rtl_call_loop
|
||||||
end;
|
end;
|
||||||
argument_move := elna_rtl_instruction_create(ElnaRtlOperator.jal);
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.jal);
|
||||||
elna_rtl_copy_operand(tac_instruction, 1, argument_move);
|
elna_rtl_copy_operand(tac_instruction, 1, instruction);
|
||||||
|
elna_list_append(instructions, instruction);
|
||||||
|
|
||||||
if first_instruction = nil then
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.move);
|
||||||
first_instruction := argument_move
|
elna_rtl_instruction_set_operand(instruction, 1, tac_instruction^.operands[3].kind,
|
||||||
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,
|
|
||||||
tac_instruction^.operands[3].value, tac_instruction^.operands[3].length);
|
tac_instruction^.operands[3].value, tac_instruction^.operands[3].length);
|
||||||
elna_rtl_instruction_set_operand(argument_move, 2, ElnaRtlKind.register, ElnaRtlRegister.a0, 0);
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.a0, 0);
|
||||||
elna_instruction_list_concatenate(current_instruction, argument_move);
|
elna_list_append(instructions, instruction)
|
||||||
|
|
||||||
next_instruction^ := argument_move;
|
|
||||||
|
|
||||||
return first_instruction
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_rtl_store(tac_instruction: ^ElnaTacInstruction, next_instruction: ^^ElnaRtlInstruction);
|
proc elna_rtl_store(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction);
|
||||||
var
|
var
|
||||||
result: ^ElnaRtlInstruction;
|
instruction: ^ElnaRtlInstruction;
|
||||||
operands: ^ElnaRtlInstruction;
|
|
||||||
begin
|
begin
|
||||||
operands := elna_rtl_load_operand_value(tac_instruction, 1, ElnaRtlRegister.t0);
|
elna_rtl_load_operand_value(instructions, tac_instruction, 1, ElnaRtlRegister.t0);
|
||||||
next_instruction^ := elna_rtl_instruction_create(ElnaRtlOperator.sw);
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.sw);
|
||||||
result := operands;
|
|
||||||
operands := result^.next;
|
|
||||||
|
|
||||||
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
|
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)
|
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length)
|
||||||
end;
|
end;
|
||||||
if operands = nil then
|
elna_list_append(instructions, instruction)
|
||||||
result^.next := next_instruction^
|
|
||||||
else
|
|
||||||
operands^.next := next_instruction^
|
|
||||||
end;
|
|
||||||
return result
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_rtl_load(tac_instruction: ^ElnaTacInstruction, next_instruction: ^^ElnaRtlInstruction);
|
proc elna_rtl_load(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction);
|
||||||
var
|
var
|
||||||
result: ^ElnaRtlInstruction;
|
instruction: ^ElnaRtlInstruction;
|
||||||
operands: ^ElnaRtlInstruction;
|
|
||||||
begin
|
begin
|
||||||
operands := elna_rtl_load_operand_value(tac_instruction, 1, ElnaRtlRegister.t0);
|
elna_rtl_load_operand_value(instructions, tac_instruction, 1, ElnaRtlRegister.t0);
|
||||||
next_instruction^ := elna_rtl_instruction_create(ElnaRtlOperator.lw);
|
|
||||||
result := operands;
|
|
||||||
operands := result^.next;
|
|
||||||
|
|
||||||
elna_rtl_instruction_set_operand(next_instruction^, 2, ElnaRtlKind.offset, ElnaRtlRegister.t0, 0);
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.lw);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.t0, 0);
|
||||||
elna_rtl_instruction_set_operand(next_instruction^, 1, tac_instruction^.operands[2].kind,
|
elna_rtl_instruction_set_operand(instruction, 1, tac_instruction^.operands[2].kind,
|
||||||
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length);
|
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length);
|
||||||
|
elna_list_append(instructions, instruction)
|
||||||
if operands = 0 then
|
|
||||||
result^.next := next_instruction^
|
|
||||||
else
|
|
||||||
operands^.next := next_instruction^
|
|
||||||
end;
|
|
||||||
return result
|
|
||||||
end;
|
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
|
var
|
||||||
result: ^ElnaRtlInstruction;
|
instruction: ^ElnaRtlInstruction;
|
||||||
operands: ^ElnaRtlInstruction;
|
|
||||||
intermediate_instruction: ^ElnaRtlInstruction;
|
|
||||||
begin
|
begin
|
||||||
result := malloc(#size(ElnaRtlInstruction));
|
|
||||||
next_instruction^ := nil;
|
|
||||||
|
|
||||||
if tac_instruction^.operator = ElnaTacOperator.get_address then
|
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, 1, instruction);
|
||||||
elna_rtl_copy_operand(tac_instruction, 2, result)
|
elna_rtl_copy_operand(tac_instruction, 2, instruction);
|
||||||
|
elna_list_append(instructions, instruction)
|
||||||
elsif tac_instruction^.operator = ElnaTacOperator.add then
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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);
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.slt);
|
||||||
elna_rtl_copy_operand(tac_instruction, 1, result);
|
elna_rtl_copy_operand(tac_instruction, 1, instruction);
|
||||||
elna_rtl_instruction_set_operand(result, 2, ElnaRtlKind.register, ElnaRtlRegister.t3, 0);
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.t3, 0);
|
||||||
elna_rtl_instruction_set_operand(result, 3, ElnaRtlKind.register, ElnaRtlRegister.t2, 0);
|
elna_rtl_instruction_set_operand(instruction, 3, ElnaRtlKind.register, ElnaRtlRegister.t2, 0);
|
||||||
|
elna_list_append(instructions, instruction)
|
||||||
intermediate_instruction := next_instruction^;
|
|
||||||
intermediate_instruction^.next := result;
|
|
||||||
next_instruction^ := result;
|
|
||||||
|
|
||||||
result := operands;
|
|
||||||
next_instruction^^.operator := ElnaRtlOperator.slt
|
|
||||||
elsif tac_instruction^.operator = ElnaTacOperator.less_or_equal then
|
elsif tac_instruction^.operator = ElnaTacOperator.less_or_equal then
|
||||||
operands := elna_rtl_binary_operands(tac_instruction, next_instruction);
|
elna_rtl_binary_comparison(instructions, tac_instruction, ElnaRtlRegister.t3, ElnaRtlRegister.t2)
|
||||||
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
|
|
||||||
elsif tac_instruction^.operator = ElnaTacOperator.greater_or_equal then
|
elsif tac_instruction^.operator = ElnaTacOperator.greater_or_equal then
|
||||||
operands := elna_rtl_binary_operands(tac_instruction, next_instruction);
|
elna_rtl_binary_comparison(instructions, tac_instruction, ElnaRtlRegister.t2, ElnaRtlRegister.t3)
|
||||||
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
|
|
||||||
elsif tac_instruction^.operator = ElnaTacOperator.equal then
|
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
|
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
|
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
|
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
|
elsif tac_instruction^.operator = ElnaTacOperator.jump then
|
||||||
result := elna_rtl_instruction_create(ElnaRtlOperator.j);
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.j);
|
||||||
elna_rtl_copy_operand(tac_instruction, 1, result)
|
elna_rtl_copy_operand(tac_instruction, 1, instruction);
|
||||||
|
elna_list_append(instructions, instruction)
|
||||||
elsif tac_instruction^.operator = ElnaTacOperator.jump_if_zero then
|
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
|
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
|
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
|
elsif tac_instruction^.operator = ElnaTacOperator.label then
|
||||||
result := elna_rtl_instruction_create(ElnaRtlOperator.label);
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.label);
|
||||||
elna_rtl_copy_operand(tac_instruction, 1, result)
|
elna_rtl_copy_operand(tac_instruction, 1, instruction);
|
||||||
|
elna_list_append(instructions, instruction)
|
||||||
elsif tac_instruction^.operator = ElnaTacOperator.copy then
|
elsif tac_instruction^.operator = ElnaTacOperator.copy then
|
||||||
if tac_instruction^.operands[1].kind = ElnaTacKind.pseudo then
|
if tac_instruction^.operands[1].kind = ElnaTacKind.pseudo then
|
||||||
operands := elna_rtl_load_operand_value(tac_instruction, 2, ElnaRtlRegister.t4);
|
elna_rtl_load_operand_value(instructions, tac_instruction, 2, ElnaRtlRegister.t4);
|
||||||
result := operands;
|
|
||||||
operands := result^.next;
|
|
||||||
|
|
||||||
next_instruction^ := elna_rtl_instruction_create(ElnaRtlOperator.move);
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.move);
|
||||||
elna_tac_instruction_set_operand(next_instruction^, 1, ElnaRtlKind.pseudo,
|
elna_tac_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo,
|
||||||
tac_instruction^.operands[1].value, tac_instruction^.operands[1].length);
|
tac_instruction^.operands[1].value, tac_instruction^.operands[1].length);
|
||||||
elna_tac_instruction_set_operand(next_instruction^, 2, ElnaRtlKind.register, ElnaRtlRegister.t4, 0);
|
elna_tac_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.t4, 0);
|
||||||
|
elna_list_append(instructions, instruction)
|
||||||
if operands = nil then
|
|
||||||
result^.next := next_instruction^
|
|
||||||
else
|
|
||||||
operands^.next := next_instruction^
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
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);
|
proc elna_tac_label(instructions: ^ElnaList, counter: Word, length: Word);
|
||||||
@@ -1622,32 +1487,15 @@ begin
|
|||||||
_write_c('\n')
|
_write_c('\n')
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_rtl_instructions(instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable);
|
proc elna_rtl_instructions(instructions: ^ElnaList, instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable);
|
||||||
var
|
|
||||||
last_copy: ^ElnaRtlInstruction;
|
|
||||||
current_copy: ^ElnaRtlInstruction;
|
|
||||||
next_copy: ^ElnaRtlInstruction;
|
|
||||||
first_copy: ^ElnaRtlInstruction;
|
|
||||||
begin
|
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;
|
.elna_rtl_instructions_start;
|
||||||
|
|
||||||
if instruction <> nil then
|
if instruction <> nil then
|
||||||
next_copy := elna_rtl_instruction(instruction, @last_copy, variable_map);
|
elna_rtl_instruction(instructions, instruction, variable_map);
|
||||||
|
|
||||||
instruction := instruction^.next;
|
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;
|
end;
|
||||||
|
|
||||||
proc elna_alloc_instructions(instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable);
|
proc elna_alloc_instructions(instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable);
|
||||||
@@ -1678,10 +1526,10 @@ begin
|
|||||||
.elna_alloc_procedure_loop;
|
.elna_alloc_procedure_loop;
|
||||||
temporary_variable_counter := 0;
|
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 := 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);
|
elna_rtl_instruction_set_operand(stack_instruction, 1, ElnaRtlKind.immediate, temporary_variable_counter, 0);
|
||||||
|
|
||||||
rtl_declaration^.body := stack_instruction;
|
rtl_declaration^.body := stack_instruction;
|
||||||
@@ -2137,26 +1985,37 @@ begin
|
|||||||
end;
|
end;
|
||||||
elna_tac_designator(instructions, unary_operand, symbol_table, @is_address, @base);
|
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
|
if operator = '@' then
|
||||||
|
elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table);
|
||||||
elna_tac_copy_address(instructions, is_address, @base, operand)
|
elna_tac_copy_address(instructions, is_address, @base, operand)
|
||||||
elsif operator = '-' then
|
elsif operator = '-' then
|
||||||
|
elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table);
|
||||||
|
|
||||||
instruction := elna_tac_instruction_create(ElnaTacOperator.negate);
|
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, 1, operand^.kind, operand^.value, operand^.length);
|
||||||
elna_tac_instruction_set_operand(instruction, 2, base.kind, base.value, base.length);
|
elna_tac_instruction_set_operand(instruction, 2, base.kind, base.value, base.length);
|
||||||
elna_list_append(instructions, instruction)
|
elna_list_append(instructions, instruction)
|
||||||
elsif operator = '~' then
|
elsif operator = '~' then
|
||||||
|
elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table);
|
||||||
|
|
||||||
instruction := elna_tac_instruction_create(ElnaTacOperator.complement);
|
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, 1, operand^.kind, operand^.value, operand^.length);
|
||||||
elna_tac_instruction_set_operand(instruction, 2, base.kind, base.value, base.length);
|
elna_tac_instruction_set_operand(instruction, 2, base.kind, base.value, base.length);
|
||||||
elna_list_append(instructions, instruction)
|
elna_list_append(instructions, instruction)
|
||||||
elsif is_address then
|
elsif is_address then
|
||||||
|
elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table);
|
||||||
|
|
||||||
instruction := elna_tac_instruction_create(ElnaTacOperator.load);
|
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, 1, base.kind, base.value, base.length);
|
||||||
elna_tac_instruction_set_operand(instruction, 2, operand^.kind, operand^.value, operand^.length);
|
elna_tac_instruction_set_operand(instruction, 2, operand^.kind, operand^.value, operand^.length);
|
||||||
elna_list_append(instructions, instruction)
|
elna_list_append(instructions, instruction)
|
||||||
|
elsif base.kind = ElnaTacKind.pseudo then
|
||||||
|
operand^.kind := base.kind;
|
||||||
|
operand^.value := base.value;
|
||||||
|
operand^.length := base.length
|
||||||
else
|
else
|
||||||
|
elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table);
|
||||||
|
|
||||||
instruction := elna_tac_instruction_create(ElnaTacOperator.copy);
|
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, 1, operand^.kind, operand^.value, operand^.length);
|
||||||
elna_tac_instruction_set_operand(instruction, 2, base.kind, base.value, base.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);
|
proc elna_tac_binary_expression(instructions: ^ElnaList, parser_node: ^ElnaTreeBinaryExpression, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand);
|
||||||
var
|
var
|
||||||
first_instruction: Word;
|
|
||||||
instruction: Word;
|
instruction: Word;
|
||||||
lhs: ElnaTacOperand;
|
lhs: ElnaTacOperand;
|
||||||
rhs: ElnaTacOperand;
|
rhs: ElnaTacOperand;
|
||||||
@@ -3541,11 +3399,10 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_rtl_parameters(parameters: Word, count: Word);
|
proc elna_rtl_parameters(instructions: ^ElnaList, parameters: Word, count: Word);
|
||||||
var
|
var
|
||||||
result: ^ElnaRtlInstruction;
|
result: ^ElnaRtlInstruction;
|
||||||
current_instruction: ^ElnaRtlInstruction;
|
instruction: ^ElnaRtlInstruction;
|
||||||
last_instruction: Word;
|
|
||||||
parameter_index: Word;
|
parameter_index: Word;
|
||||||
parameter_name: Word;
|
parameter_name: Word;
|
||||||
name_length: Word;
|
name_length: Word;
|
||||||
@@ -3560,16 +3417,10 @@ begin
|
|||||||
name_length := parameters^;
|
name_length := parameters^;
|
||||||
parameters := parameters + 4;
|
parameters := parameters + 4;
|
||||||
|
|
||||||
current_instruction := elna_rtl_instruction_create(ElnaRtlOperator.move);
|
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(instruction, 1, ElnaRtlKind.pseudo, parameter_name, name_length);
|
||||||
elna_rtl_instruction_set_operand(current_instruction, 2, ElnaRtlKind.register, 11 + parameter_index, 0);
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, 11 + parameter_index, 0);
|
||||||
|
elna_list_append(instructions, instruction);
|
||||||
if result = nil then
|
|
||||||
result := current_instruction
|
|
||||||
else
|
|
||||||
elna_instruction_list_concatenate(last_instruction, current_instruction)
|
|
||||||
end;
|
|
||||||
last_instruction := current_instruction;
|
|
||||||
|
|
||||||
parameter_index := parameter_index + 1;
|
parameter_index := parameter_index + 1;
|
||||||
goto elna_rtl_parameters_loop
|
goto elna_rtl_parameters_loop
|
||||||
@@ -3640,19 +3491,18 @@ end;
|
|||||||
proc elna_rtl_procedure_declaration(tac_declaration: ^ElnaTacProcedure);
|
proc elna_rtl_procedure_declaration(tac_declaration: ^ElnaTacProcedure);
|
||||||
var
|
var
|
||||||
result: ^ElnaRtlProcedure;
|
result: ^ElnaRtlProcedure;
|
||||||
body: ^ElnaRtlInstruction;
|
|
||||||
parameters: ^ElnaRtlInstruction;
|
|
||||||
begin
|
begin
|
||||||
result := malloc(#size(ElnaRtlProcedure));
|
result := malloc(#size(ElnaRtlProcedure));
|
||||||
|
elna_list_initialize(@result^.body);
|
||||||
|
|
||||||
result^.next := nil;
|
result^.next := nil;
|
||||||
result^.name := tac_declaration^.name;
|
result^.name := tac_declaration^.name;
|
||||||
result^.length := tac_declaration^.length;
|
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);
|
result^.variable_map := elna_rtl_symbol_table(tac_declaration^.symbol_table);
|
||||||
body := elna_rtl_instructions(tac_declaration^.body, result^.variable_map);
|
elna_rtl_instructions(@result^.body, tac_declaration^.body.first, result^.variable_map);
|
||||||
result^.body := elna_instruction_list_concatenate(parameters, body);
|
|
||||||
|
|
||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|||||||
Reference in New Issue
Block a user