Accept pseudo registers in the move instruction
This commit is contained in:
@@ -535,7 +535,7 @@ type
|
|||||||
lw,
|
lw,
|
||||||
sw,
|
sw,
|
||||||
jal,
|
jal,
|
||||||
move,
|
mv,
|
||||||
sub,
|
sub,
|
||||||
div,
|
div,
|
||||||
rem,
|
rem,
|
||||||
@@ -912,7 +912,7 @@ begin
|
|||||||
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0);
|
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0);
|
||||||
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, into, 0)
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, into, 0)
|
||||||
else
|
else
|
||||||
instruction := elna_rtl_instruction_create(ElnaRtlOperator.move);
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv);
|
||||||
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0);
|
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;
|
end;
|
||||||
@@ -1108,7 +1108,7 @@ begin
|
|||||||
tac_instruction^.operands[1].value, tac_instruction^.operands[1].length);
|
tac_instruction^.operands[1].value, tac_instruction^.operands[1].length);
|
||||||
elna_list_append(instructions, instruction);
|
elna_list_append(instructions, instruction);
|
||||||
|
|
||||||
instruction := elna_rtl_instruction_create(ElnaRtlOperator.move);
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv);
|
||||||
elna_rtl_instruction_set_operand(instruction, 1, tac_instruction^.operands[3].kind,
|
elna_rtl_instruction_set_operand(instruction, 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(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.a0, 0);
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.a0, 0);
|
||||||
@@ -1143,11 +1143,26 @@ begin
|
|||||||
elna_list_append(instructions, instruction)
|
elna_list_append(instructions, instruction)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
proc elna_rtl_copy(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable);
|
||||||
|
var
|
||||||
|
instruction: ^ElnaRtlInstruction;
|
||||||
|
rtl_operand: ElnaRtlOperand;
|
||||||
|
begin
|
||||||
|
if tac_instruction^.operands[1].kind = ElnaTacKind.variable then
|
||||||
|
elna_rtl_operand_value(instructions, @tac_instruction^.operands[2], variable_map, @rtl_operand);
|
||||||
|
|
||||||
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo,
|
||||||
|
tac_instruction^.operands[1].value, tac_instruction^.operands[1].length);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 2, rtl_operand.kind, rtl_operand.value, rtl_operand.length);
|
||||||
|
elna_list_append(instructions, instruction);
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
proc elna_rtl_instruction(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable);
|
proc elna_rtl_instruction(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable);
|
||||||
var
|
var
|
||||||
instruction: ^ElnaRtlInstruction;
|
instruction: ^ElnaRtlInstruction;
|
||||||
pseudo_symbol: ^ElnaRtlInfo;
|
pseudo_symbol: ^ElnaRtlInfo;
|
||||||
rtl_operand: ElnaRtlOperand;
|
|
||||||
begin
|
begin
|
||||||
if tac_instruction^.operator = ElnaTacOperator.get_address then
|
if tac_instruction^.operator = ElnaTacOperator.get_address then
|
||||||
pseudo_symbol := elna_symbol_table_lookup(variable_map,
|
pseudo_symbol := elna_symbol_table_lookup(variable_map,
|
||||||
@@ -1218,15 +1233,7 @@ begin
|
|||||||
tac_instruction^.operands[1].value, tac_instruction^.operands[1].length);
|
tac_instruction^.operands[1].value, tac_instruction^.operands[1].length);
|
||||||
elna_list_append(instructions, 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.variable then
|
elna_rtl_copy(instructions, tac_instruction, variable_map)
|
||||||
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,
|
|
||||||
tac_instruction^.operands[1].value, tac_instruction^.operands[1].length);
|
|
||||||
elna_tac_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.t4, 0);
|
|
||||||
elna_list_append(instructions, instruction)
|
|
||||||
end
|
|
||||||
elsif tac_instruction^.operator = ElnaTacOperator.nop then
|
elsif tac_instruction^.operator = ElnaTacOperator.nop then
|
||||||
instruction := elna_rtl_instruction_create(ElnaRtlOperator.nop);
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.nop);
|
||||||
elna_tac_instruction_set_operand(instruction, 1, tac_instruction^.operands[1].kind,
|
elna_tac_instruction_set_operand(instruction, 1, tac_instruction^.operands[1].kind,
|
||||||
@@ -1271,7 +1278,7 @@ begin
|
|||||||
elsif instruction_kind = ElnaRtlOperator.jal then
|
elsif instruction_kind = ElnaRtlOperator.jal then
|
||||||
argument_count := 1;
|
argument_count := 1;
|
||||||
_write_s("\tcall", 5)
|
_write_s("\tcall", 5)
|
||||||
elsif instruction_kind = ElnaRtlOperator.move then
|
elsif instruction_kind = ElnaRtlOperator.mv then
|
||||||
argument_count := 2;
|
argument_count := 2;
|
||||||
_write_s("\tmv", 3)
|
_write_s("\tmv", 3)
|
||||||
elsif instruction_kind = ElnaRtlOperator.sub then
|
elsif instruction_kind = ElnaRtlOperator.sub then
|
||||||
@@ -1477,33 +1484,45 @@ begin
|
|||||||
return elna_alloc_operation_target(instructions, instruction, variable_map)
|
return elna_alloc_operation_target(instructions, instruction, variable_map)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_alloc_move(instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable);
|
proc elna_alloc_move(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable);
|
||||||
var
|
var
|
||||||
pseudo_symbol: ^ElnaRtlInfo;
|
pseudo_symbol: ^ElnaRtlInfo;
|
||||||
|
destination_pseudo: Word;
|
||||||
|
source_pseudo: Word;
|
||||||
begin
|
begin
|
||||||
if instruction^.operands[1].kind = ElnaRtlKind.pseudo then
|
destination_pseudo := instruction^.operands[1].kind = ElnaRtlKind.pseudo;
|
||||||
|
source_pseudo := instruction^.operands[2].kind = ElnaRtlKind.pseudo;
|
||||||
|
|
||||||
|
if destination_pseudo & source_pseudo then
|
||||||
|
instruction := elna_alloc_operand(instructions, instruction, 2, ElnaRtlRegister.t4, variable_map);
|
||||||
|
|
||||||
|
pseudo_symbol := elna_alloc_variable(instruction^.operands[1].value, instruction^.operands[1].length,
|
||||||
|
variable_map);
|
||||||
|
instruction^.operator = ElnaRtlOperator.sw;
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t4, 0);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol^.counter)
|
||||||
|
elsif destination_pseudo then
|
||||||
pseudo_symbol := elna_alloc_variable(instruction^.operands[1].value, instruction^.operands[1].length,
|
pseudo_symbol := elna_alloc_variable(instruction^.operands[1].value, instruction^.operands[1].length,
|
||||||
variable_map);
|
variable_map);
|
||||||
instruction^.operator = ElnaRtlOperator.sw;
|
instruction^.operator = ElnaRtlOperator.sw;
|
||||||
|
|
||||||
if pseudo_symbol = nil then
|
elna_rtl_instruction_set_operand(instruction, 1, instruction^.operands[2].kind,
|
||||||
elna_rtl_instruction_set_operand(instruction, 1, instruction^.operands[2].kind,
|
instruction^.operands[2].value, instruction^.operands[2].length);
|
||||||
instruction^.operands[2].value, instruction^.operands[2].length);
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol^.counter)
|
||||||
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.symbol,
|
elsif source_pseudo then
|
||||||
instruction^.operands[1].value, instruction^.operands[1].length)
|
|
||||||
else
|
|
||||||
elna_rtl_instruction_set_operand(instruction, 1, instruction^.operands[2].kind,
|
|
||||||
instruction^.operands[2].value, instruction^.operands[2].length);
|
|
||||||
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol^.counter)
|
|
||||||
end;
|
|
||||||
elsif instruction^.operands[2].kind = ElnaRtlKind.pseudo then
|
|
||||||
pseudo_symbol := elna_alloc_variable(instruction^.operands[2].value, instruction^.operands[2].length,
|
pseudo_symbol := elna_alloc_variable(instruction^.operands[2].value, instruction^.operands[2].length,
|
||||||
variable_map);
|
variable_map);
|
||||||
instruction^.operator = ElnaRtlOperator.lw;
|
instruction^.operator = ElnaRtlOperator.lw;
|
||||||
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol^.counter)
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol^.counter)
|
||||||
end
|
end;
|
||||||
|
return instruction
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
(**
|
||||||
|
* Move the operand value from the pseudo register into a hardware register if needed.
|
||||||
|
* If copying requires an additional instruction inserts the instruction before the
|
||||||
|
* current instruction and returns the new current instruction.
|
||||||
|
*)
|
||||||
proc elna_alloc_operand(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction,
|
proc elna_alloc_operand(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction,
|
||||||
number: Word, target: ElnaRtlRegister, variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction;
|
number: Word, target: ElnaRtlRegister, variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction;
|
||||||
var
|
var
|
||||||
@@ -1553,8 +1572,8 @@ var
|
|||||||
pseudo_symbol: ^ElnaRtlInfo;
|
pseudo_symbol: ^ElnaRtlInfo;
|
||||||
new_instruction: ^ElnaRtlInstruction;
|
new_instruction: ^ElnaRtlInstruction;
|
||||||
begin
|
begin
|
||||||
if instruction^.operator = ElnaRtlOperator.move then
|
if instruction^.operator = ElnaRtlOperator.mv then
|
||||||
elna_alloc_move(instruction, variable_map)
|
instruction := elna_alloc_move(instructions, instruction, variable_map)
|
||||||
elsif instruction^.operator = ElnaRtlOperator.la then
|
elsif instruction^.operator = ElnaRtlOperator.la then
|
||||||
elna_alloc_load_address(instructions, instruction, variable_map)
|
elna_alloc_load_address(instructions, instruction, variable_map)
|
||||||
elsif instruction^.operator = ElnaRtlOperator.lw then
|
elsif instruction^.operator = ElnaRtlOperator.lw then
|
||||||
@@ -3558,7 +3577,7 @@ begin
|
|||||||
name_length := parameters^;
|
name_length := parameters^;
|
||||||
parameters := parameters + 4;
|
parameters := parameters + 4;
|
||||||
|
|
||||||
instruction := elna_rtl_instruction_create(ElnaRtlOperator.move);
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv);
|
||||||
elna_rtl_instruction_set_operand(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(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);
|
elna_list_append(instructions, instruction);
|
||||||
|
|||||||
Reference in New Issue
Block a user