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