Move procedure call register allocation to RTL
This commit is contained in:
@@ -467,7 +467,7 @@ type
|
||||
allocate_stack,
|
||||
ret
|
||||
);
|
||||
ElnaTacOperand = (temporary, immediate, symbol, stack, pseudo);
|
||||
ElnaTacOperand = (temporary, immediate, symbol, stack, pseudo, list);
|
||||
ElnaRtlOperand = (register, immediate, symbol, offset, pseudo);
|
||||
ElnaRtlRegister = (
|
||||
zero,
|
||||
@@ -819,45 +819,45 @@ end;
|
||||
|
||||
proc elna_rtl_load_operand_value(tac_instruction: Word, operand_number: Word, into: Word);
|
||||
var
|
||||
result1: ^ElnaInstructionList;
|
||||
operand_value1: Word;
|
||||
operand_length1: Word;
|
||||
operand_type1: Word;
|
||||
result: ^ElnaInstructionList;
|
||||
operand_value: Word;
|
||||
operand_length: Word;
|
||||
operand_type: Word;
|
||||
next_instruction: Word;
|
||||
begin
|
||||
operand_value1 := _elna_tac_instruction_get_operand_value(tac_instruction, operand_number);
|
||||
operand_length1 := _elna_tac_instruction_get_operand_length(tac_instruction, operand_number);
|
||||
operand_type1 := _elna_tac_instruction_get_operand_type(tac_instruction, operand_number);
|
||||
operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, operand_number);
|
||||
operand_length := _elna_tac_instruction_get_operand_length(tac_instruction, operand_number);
|
||||
operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, operand_number);
|
||||
|
||||
if operand_type1 = ElnaTacOperand.immediate then
|
||||
result1 := elna_rtl_instruction_create(ElnaRtlOperator.li);
|
||||
elna_rtl_instruction_set_operand(result1, 1, ElnaRtlOperand.register, into, 0);
|
||||
elna_rtl_instruction_set_operand(result1, 2, ElnaRtlOperand.immediate, operand_value1, operand_length1)
|
||||
elsif operand_type1 = ElnaTacOperand.stack then
|
||||
result1 := elna_rtl_instruction_create(ElnaRtlOperator.lw);
|
||||
elna_rtl_instruction_set_operand(result1, 1, ElnaRtlOperand.register, into, 0);
|
||||
elna_rtl_instruction_set_operand(result1, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, operand_value1)
|
||||
elsif operand_type1 = ElnaTacOperand.symbol then
|
||||
result1 := elna_rtl_instruction_create(ElnaRtlOperator.la);
|
||||
elna_rtl_instruction_set_operand(result1, 1, ElnaRtlOperand.register, into, 0);
|
||||
elna_rtl_instruction_set_operand(result1, 2, ElnaRtlOperand.symbol, operand_value1, operand_length1);
|
||||
if operand_type = ElnaTacOperand.immediate then
|
||||
result := elna_rtl_instruction_create(ElnaRtlOperator.li);
|
||||
elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0);
|
||||
elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.immediate, operand_value, operand_length)
|
||||
elsif operand_type = ElnaTacOperand.stack then
|
||||
result := elna_rtl_instruction_create(ElnaRtlOperator.lw);
|
||||
elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0);
|
||||
elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, operand_value)
|
||||
elsif operand_type = ElnaTacOperand.symbol then
|
||||
result := elna_rtl_instruction_create(ElnaRtlOperator.la);
|
||||
elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0);
|
||||
elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.symbol, operand_value, operand_length);
|
||||
|
||||
next_instruction := elna_rtl_instruction_create(ElnaRtlOperator.lw);
|
||||
elna_rtl_instruction_set_operand(next_instruction, 1, ElnaRtlOperand.register, into, 0);
|
||||
elna_rtl_instruction_set_operand(next_instruction, 2, ElnaRtlOperand.offset, into, 0);
|
||||
|
||||
result1^.next := next_instruction
|
||||
elsif operand_type1 = ElnaTacOperand.temporary then
|
||||
result1 := elna_rtl_instruction_create(ElnaRtlOperator.move);
|
||||
elna_rtl_instruction_set_operand(result1, 1, ElnaRtlOperand.register, into, 0);
|
||||
elna_rtl_instruction_set_operand(result1, 2, ElnaRtlOperand.register, operand_value1, 0)
|
||||
elsif operand_type1 = ElnaTacOperand.pseudo then
|
||||
result1 := elna_rtl_instruction_create(ElnaRtlOperator.move);
|
||||
elna_rtl_instruction_set_operand(result1, 1, ElnaRtlOperand.register, into, 0);
|
||||
elna_rtl_instruction_set_operand(result1, 2, ElnaRtlOperand.pseudo, operand_value1, operand_length1)
|
||||
result^.next := next_instruction
|
||||
elsif operand_type = ElnaTacOperand.temporary then
|
||||
result := elna_rtl_instruction_create(ElnaRtlOperator.move);
|
||||
elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0);
|
||||
elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.register, operand_value, 0)
|
||||
elsif operand_type = ElnaTacOperand.pseudo then
|
||||
result := elna_rtl_instruction_create(ElnaRtlOperator.move);
|
||||
elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0);
|
||||
elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.pseudo, operand_value, operand_length)
|
||||
end;
|
||||
|
||||
return result1
|
||||
return result
|
||||
end;
|
||||
|
||||
proc elna_rtl_load_operand_address(tac_instruction: Word, operand_number: Word, into: Word);
|
||||
@@ -871,11 +871,7 @@ begin
|
||||
operand_length := _elna_tac_instruction_get_operand_length(tac_instruction, operand_number);
|
||||
operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, operand_number);
|
||||
|
||||
if operand_type = ElnaTacOperand.stack then
|
||||
result := elna_rtl_instruction_create(ElnaRtlOperator.addi);
|
||||
elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0);
|
||||
elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, operand_value)
|
||||
elsif operand_type = ElnaTacOperand.symbol then
|
||||
if operand_type = ElnaTacOperand.symbol then
|
||||
result := elna_rtl_instruction_create(ElnaRtlOperator.la);
|
||||
elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0);
|
||||
elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.symbol, operand_value, operand_length)
|
||||
@@ -996,6 +992,69 @@ begin
|
||||
return result
|
||||
end;
|
||||
|
||||
proc elna_rtl_call(tac_instruction: Word, next_instruction: ^^ElnaInstructionList);
|
||||
var
|
||||
argument_count: Word;
|
||||
current_argument: Word;
|
||||
argument_type: Word;
|
||||
argument_value: Word;
|
||||
argument_length: Word;
|
||||
argument_move: Word;
|
||||
current_register: Word;
|
||||
first_instruction: Word;
|
||||
current_instruction: Word;
|
||||
name: Word;
|
||||
name_length: Word;
|
||||
begin
|
||||
current_register := 0;
|
||||
first_instruction := nil;
|
||||
|
||||
current_argument := _elna_tac_instruction_get_operand_value(tac_instruction, 2);
|
||||
argument_count := _elna_tac_instruction_get_operand_length(tac_instruction, 2);
|
||||
|
||||
name := _elna_tac_instruction_get_operand_value(tac_instruction, 1);
|
||||
name_length := _elna_tac_instruction_get_operand_length(tac_instruction, 1);
|
||||
|
||||
.elna_rtl_call_loop;
|
||||
|
||||
if argument_count > 0 then
|
||||
argument_count := argument_count - 1;
|
||||
|
||||
argument_type := current_argument^;
|
||||
current_argument := current_argument + 4;
|
||||
argument_value := current_argument^;
|
||||
current_argument := current_argument + 4;
|
||||
argument_length := current_argument^;
|
||||
current_argument := current_argument + 4;
|
||||
|
||||
argument_move := elna_rtl_instruction_create(ElnaRtlOperator.move);
|
||||
elna_rtl_instruction_set_operand(argument_move, 1, ElnaRtlOperand.register, ElnaRtlRegister.a0 + current_register, 0);
|
||||
elna_rtl_instruction_set_operand(argument_move, 2, argument_type, argument_value, argument_length);
|
||||
|
||||
if first_instruction = nil then
|
||||
first_instruction := argument_move
|
||||
else
|
||||
elna_instruction_list_concatenate(current_instruction, argument_move)
|
||||
end;
|
||||
current_instruction := argument_move;
|
||||
|
||||
current_register := current_register + 1;
|
||||
|
||||
goto elna_rtl_call_loop
|
||||
end;
|
||||
argument_move := elna_rtl_instruction_create(ElnaRtlOperator.jal);
|
||||
elna_rtl_copy_operand(tac_instruction, 1, argument_move);
|
||||
|
||||
if first_instruction = nil then
|
||||
first_instruction := argument_move
|
||||
else
|
||||
elna_instruction_list_concatenate(current_instruction, argument_move)
|
||||
end;
|
||||
next_instruction^ := argument_move;
|
||||
|
||||
return first_instruction
|
||||
end;
|
||||
|
||||
proc elna_rtl_instruction(tac_instruction: Word, next_instruction: ^^ElnaInstructionList);
|
||||
var
|
||||
result: ^ElnaInstructionList;
|
||||
@@ -1042,18 +1101,7 @@ begin
|
||||
elsif instruction_kind = ElnaTacOperator.load then
|
||||
operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, 2);
|
||||
|
||||
if operand_type = ElnaTacOperand.stack then
|
||||
result := elna_rtl_instruction_create(ElnaRtlOperator.lw);
|
||||
|
||||
operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 1);
|
||||
next_instruction^ := elna_rtl_instruction_create(ElnaRtlOperator.lw);
|
||||
elna_rtl_instruction_set_operand(next_instruction^, 1, ElnaRtlOperand.register, operand_value, 0);
|
||||
elna_rtl_instruction_set_operand(next_instruction^, 2, ElnaRtlOperand.offset, operand_value, 0);
|
||||
|
||||
operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2);
|
||||
elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, operand_value);
|
||||
result^.next := next_instruction^
|
||||
elsif operand_type = ElnaTacOperand.temporary then
|
||||
if operand_type = ElnaTacOperand.temporary then
|
||||
result := elna_rtl_instruction_create(ElnaRtlOperator.lw);
|
||||
|
||||
elna_rtl_copy_operand(tac_instruction, 1, result);
|
||||
@@ -1080,8 +1128,6 @@ begin
|
||||
operand_length := _elna_tac_instruction_get_operand_length(tac_instruction, 2);
|
||||
if operand_type = ElnaTacOperand.stack then
|
||||
elna_rtl_instruction_set_operand(next_instruction^, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, operand_value)
|
||||
elsif operand_type = ElnaTacOperand.temporary then
|
||||
elna_rtl_instruction_set_operand(next_instruction^, 2, ElnaRtlOperand.offset, operand_value, 0)
|
||||
elsif operand_type = ElnaTacOperand.pseudo then
|
||||
elna_rtl_instruction_set_operand(next_instruction^, 2, ElnaRtlOperand.pseudo, operand_value, operand_length)
|
||||
end;
|
||||
@@ -1091,8 +1137,7 @@ begin
|
||||
operands^.next := next_instruction^
|
||||
end
|
||||
elsif instruction_kind = ElnaTacOperator.proc_call then
|
||||
result := elna_rtl_instruction_create(ElnaRtlOperator.jal);
|
||||
elna_rtl_copy_operand(tac_instruction, 1, result)
|
||||
result := elna_rtl_call(tac_instruction, next_instruction)
|
||||
elsif instruction_kind = ElnaTacOperator.subtract then
|
||||
result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.sub)
|
||||
elsif instruction_kind = ElnaTacOperator.multiply then
|
||||
@@ -1189,20 +1234,6 @@ begin
|
||||
if operand_type = ElnaTacOperand.temporary then
|
||||
result := elna_rtl_load_operand_value(tac_instruction, 2, operand_value);
|
||||
next_instruction^ := result^.next
|
||||
elsif operand_type = ElnaTacOperand.stack then
|
||||
operands := elna_rtl_load_operand_value(tac_instruction, 2, ElnaRtlRegister.t4);
|
||||
result := operands;
|
||||
operands := result^.next;
|
||||
|
||||
next_instruction^ := elna_rtl_instruction_create(ElnaRtlOperator.sw);
|
||||
_elna_tac_instruction_set_operand(next_instruction^, 1, ElnaRtlOperand.register, ElnaRtlRegister.t4, 0);
|
||||
_elna_tac_instruction_set_operand(next_instruction^, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, operand_value);
|
||||
|
||||
if operands = nil then
|
||||
result^.next := next_instruction^
|
||||
else
|
||||
operands^.next := next_instruction^
|
||||
end
|
||||
elsif operand_type = ElnaTacOperand.pseudo then
|
||||
operands := elna_rtl_load_operand_value(tac_instruction, 2, ElnaRtlRegister.t4);
|
||||
result := operands;
|
||||
@@ -1378,13 +1409,14 @@ begin
|
||||
return pseudo_symbol1
|
||||
end;
|
||||
|
||||
proc elna_alloc_instruction(instruction: Word);
|
||||
proc elna_alloc_instruction(instruction: ^ElnaInstructionList);
|
||||
var
|
||||
instruction_kind: Word;
|
||||
operand_type: Word;
|
||||
operand_value: Word;
|
||||
operand_length: Word;
|
||||
pseudo_symbol1: Word;
|
||||
pseudo_symbol: Word;
|
||||
old_instruction: ^ElnaInstructionList;
|
||||
begin
|
||||
instruction_kind := elna_rtl_instruction_get_kind(instruction);
|
||||
|
||||
@@ -1394,7 +1426,7 @@ begin
|
||||
operand_length := elna_rtl_instruction_get_operand_length(instruction, 1);
|
||||
|
||||
if operand_type = ElnaRtlOperand.pseudo then
|
||||
pseudo_symbol1 := elna_alloc_variable(operand_value, operand_length);
|
||||
pseudo_symbol := elna_alloc_variable(operand_value, operand_length);
|
||||
elna_rtl_instruction_set_kind(instruction, ElnaRtlOperator.sw);
|
||||
|
||||
operand_type := elna_rtl_instruction_get_operand_type(instruction, 2);
|
||||
@@ -1402,7 +1434,7 @@ begin
|
||||
operand_length := elna_rtl_instruction_get_operand_length(instruction, 2);
|
||||
|
||||
elna_rtl_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length);
|
||||
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, pseudo_symbol1);
|
||||
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, pseudo_symbol);
|
||||
|
||||
goto elna_alloc_instruction_end
|
||||
end;
|
||||
@@ -1412,9 +1444,9 @@ begin
|
||||
operand_length := elna_rtl_instruction_get_operand_length(instruction, 2);
|
||||
|
||||
if operand_type = ElnaRtlOperand.pseudo then
|
||||
pseudo_symbol1 := elna_alloc_variable(operand_value, operand_length);
|
||||
pseudo_symbol := elna_alloc_variable(operand_value, operand_length);
|
||||
elna_rtl_instruction_set_kind(instruction, ElnaRtlOperator.lw);
|
||||
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, pseudo_symbol1);
|
||||
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, pseudo_symbol);
|
||||
|
||||
goto elna_alloc_instruction_end
|
||||
end
|
||||
@@ -1424,15 +1456,31 @@ begin
|
||||
operand_length := elna_rtl_instruction_get_operand_length(instruction, 2);
|
||||
|
||||
if operand_type = ElnaRtlOperand.pseudo then
|
||||
(* Debug. Error stream output.
|
||||
printf("# %i %.*s\n\0", operand_length, operand_length, operand_value);
|
||||
fflush(nil); *)
|
||||
|
||||
pseudo_symbol1 := elna_alloc_variable(operand_value, operand_length);
|
||||
pseudo_symbol := elna_alloc_variable(operand_value, operand_length);
|
||||
elna_rtl_instruction_set_kind(instruction, ElnaRtlOperator.addi);
|
||||
|
||||
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlOperand.register, ElnaRtlRegister.sp, 0);
|
||||
elna_rtl_instruction_set_operand(instruction, 3, ElnaRtlOperand.immediate, pseudo_symbol1, 0);
|
||||
elna_rtl_instruction_set_operand(instruction, 3, ElnaRtlOperand.immediate, pseudo_symbol, 0);
|
||||
|
||||
goto elna_alloc_instruction_end
|
||||
end
|
||||
elsif instruction_kind = ElnaRtlOperator.sw then
|
||||
operand_type := elna_rtl_instruction_get_operand_type(instruction, 2);
|
||||
operand_value := elna_rtl_instruction_get_operand_value(instruction, 2);
|
||||
operand_length := elna_rtl_instruction_get_operand_length(instruction, 2);
|
||||
|
||||
if operand_type = ElnaRtlOperand.pseudo then
|
||||
old_instruction := malloc(elna_rtl_instruction_size());
|
||||
memcpy(old_instruction, instruction, elna_rtl_instruction_size());
|
||||
|
||||
pseudo_symbol := elna_alloc_variable(operand_value, operand_length);
|
||||
elna_rtl_instruction_set_kind(instruction, ElnaRtlOperator.lw);
|
||||
|
||||
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0);
|
||||
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, pseudo_symbol);
|
||||
|
||||
instruction^.next := old_instruction;
|
||||
elna_rtl_instruction_set_operand(old_instruction, 2, ElnaRtlOperand.offset, ElnaRtlRegister.t2, 0);
|
||||
|
||||
goto elna_alloc_instruction_end
|
||||
end
|
||||
@@ -1541,7 +1589,7 @@ var
|
||||
stack_instruction: ^ElnaInstructionList;
|
||||
begin
|
||||
.elna_alloc_procedure_loop;
|
||||
temporary_variable_counter := 60;
|
||||
temporary_variable_counter := 32;
|
||||
variable_map := 0;
|
||||
|
||||
elna_alloc_instructions(rtl_declaration^.body);
|
||||
@@ -2148,17 +2196,8 @@ begin
|
||||
lhs_value := 0;
|
||||
lhs_length := 0;
|
||||
instruction := _elna_tac_unary_expression(parser_node^.rhs, symbol_table, @lhs_type, @lhs_value, @lhs_length);
|
||||
|
||||
current_instruction := elna_instruction_list_concatenate(current_instruction, instruction);
|
||||
|
||||
(* Load the left expression from the stack; *)
|
||||
instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
|
||||
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 7, 0);
|
||||
_elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.pseudo, "$lhs", 4);
|
||||
|
||||
elna_instruction_list_concatenate(current_instruction, instruction);
|
||||
current_instruction := instruction;
|
||||
|
||||
if parser_node^.operator = ElnaLexerKind.plus then
|
||||
instruction := _elna_tac_instruction_create(ElnaTacOperator.add)
|
||||
elsif parser_node^.operator = ElnaLexerKind.minus then
|
||||
@@ -2277,10 +2316,9 @@ end;
|
||||
|
||||
proc _elna_tac_call(parsed_call: Word, symbol_table: Word);
|
||||
var
|
||||
argument_count1: Word;
|
||||
argument_count: Word;
|
||||
name_length: Word;
|
||||
name: Word;
|
||||
stack_offset: Word;
|
||||
parsed_expression: ^ElnaTreeVariableExpression;
|
||||
instruction: Word;
|
||||
first_instruction: Word;
|
||||
@@ -2288,16 +2326,33 @@ var
|
||||
operand_type: Word;
|
||||
operand_value: Word;
|
||||
operand_length: Word;
|
||||
arguments_operand: Word;
|
||||
call_instruction: Word;
|
||||
name_buffer: Word;
|
||||
begin
|
||||
parsed_expression := _call_get_name(parsed_call);
|
||||
name := parsed_expression^.name;
|
||||
name_length := parsed_expression^.length;
|
||||
argument_count1 := 0;
|
||||
argument_count := 0;
|
||||
first_instruction := 0;
|
||||
|
||||
.elna_tac_call_count;
|
||||
parsed_expression := _call_get_argument(parsed_call, argument_count + 1);
|
||||
|
||||
if parsed_expression <> nil ten
|
||||
argument_count := argument_count + 1;
|
||||
goto elna_tac_call_count
|
||||
end;
|
||||
arguments_operand := malloc(argument_count * 12);
|
||||
|
||||
call_instruction := _elna_tac_instruction_create(ElnaTacOperator.proc_call);
|
||||
_elna_tac_instruction_set_operand(call_instruction, 1, ElnaTacOperand.symbol, name, name_length);
|
||||
_elna_tac_instruction_set_operand(call_instruction, 2, ElnaTacOperand.list, arguments_operand, argument_count);
|
||||
|
||||
argument_count := 0;
|
||||
.elna_tac_call_loop;
|
||||
|
||||
parsed_expression := _call_get_argument(parsed_call, argument_count1 + 1);
|
||||
parsed_expression := _call_get_argument(parsed_call, argument_count + 1);
|
||||
if parsed_expression = 0 then
|
||||
goto elna_tac_call_finalize
|
||||
else
|
||||
@@ -2315,11 +2370,11 @@ begin
|
||||
end;
|
||||
|
||||
(* Save the argument on the stack. *)
|
||||
stack_offset := argument_count1 * 4;
|
||||
|
||||
instruction := _elna_tac_instruction_create(ElnaTacOperator.store);
|
||||
_elna_tac_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length);
|
||||
_elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 56 - stack_offset, 0);
|
||||
name_buffer := malloc(4);
|
||||
sprintf(name_buffer, "$ar%i\0", argument_count);
|
||||
instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
|
||||
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.pseudo, name_buffer, 4);
|
||||
_elna_tac_instruction_set_operand(instruction, 2, operand_type, operand_value, operand_length);
|
||||
if first_instruction = 0 then
|
||||
first_instruction := instruction
|
||||
else
|
||||
@@ -2327,32 +2382,22 @@ begin
|
||||
end;
|
||||
current_instruction := instruction;
|
||||
|
||||
argument_count1 := argument_count1 + 1;
|
||||
arguments_operand^ := ElnaTacOperand.pseudo;
|
||||
arguments_operand := arguments_operand + 4;
|
||||
arguments_operand^ := name_buffer;
|
||||
arguments_operand := arguments_operand + 4;
|
||||
arguments_operand^ := 4;
|
||||
arguments_operand := arguments_operand + 4;
|
||||
|
||||
argument_count := argument_count + 1;
|
||||
goto elna_tac_call_loop
|
||||
end;
|
||||
.elna_tac_call_finalize;
|
||||
|
||||
(* Load the argument from the stack. *)
|
||||
if argument_count1 <> 0 then
|
||||
(* Decrement the argument counter. *)
|
||||
argument_count1 := argument_count1 - 1;
|
||||
stack_offset := argument_count1 * 4;
|
||||
|
||||
(* Calculate the stack offset: 56 - (4 * argument_counter) *)
|
||||
instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
|
||||
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 11 + argument_count1, 0);
|
||||
_elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 56 - stack_offset, 0);
|
||||
elna_instruction_list_concatenate(current_instruction, instruction);
|
||||
current_instruction := instruction;
|
||||
|
||||
goto elna_tac_call_finalize
|
||||
end;
|
||||
instruction := _elna_tac_instruction_create(ElnaTacOperator.proc_call);
|
||||
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.symbol, name, name_length);
|
||||
if first_instruction = 0 then
|
||||
first_instruction := instruction
|
||||
if first_instruction = nil then
|
||||
first_instruction := call_instruction
|
||||
else
|
||||
elna_instruction_list_concatenate(current_instruction, instruction)
|
||||
elna_instruction_list_concatenate(current_instruction, call_instruction)
|
||||
end;
|
||||
return first_instruction
|
||||
end;
|
||||
@@ -2551,15 +2596,9 @@ begin
|
||||
elsif parser_node^.kind = ElnaTreeKind.call then
|
||||
first_instruction := _elna_tac_call(parser_node, symbol_table);
|
||||
|
||||
last_instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
|
||||
_elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.temporary, 6, 0);
|
||||
_elna_tac_instruction_set_operand(last_instruction, 2, ElnaTacOperand.temporary, 11, 0);
|
||||
|
||||
operand_type^ := ElnaTacOperand.temporary;
|
||||
operand_value^ := 6;
|
||||
operand_value^ := 11;
|
||||
operand_length^ := 0;
|
||||
|
||||
elna_instruction_list_concatenate(first_instruction, last_instruction);
|
||||
is_address^ := 0
|
||||
else
|
||||
first_instruction := _elna_tac_simple_expression(parser_node, symbol_table, operand_type, operand_value, operand_length);
|
||||
@@ -2621,11 +2660,10 @@ begin
|
||||
first_instruction := elna_instruction_list_concatenate(first_instruction, current_instruction);
|
||||
|
||||
(* Save the assignee address on the stack. *)
|
||||
current_instruction := _elna_tac_instruction_create(ElnaTacOperator.store);
|
||||
_elna_tac_instruction_set_operand(current_instruction, 1, ElnaTacOperand.temporary, 6, 0);
|
||||
_elna_tac_instruction_set_operand(current_instruction, 2, ElnaTacOperand.stack, 0, 0);
|
||||
current_instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
|
||||
_elna_tac_instruction_set_operand(current_instruction, 1, ElnaTacOperand.pseudo, "$assign", 7);
|
||||
_elna_tac_instruction_set_operand(current_instruction, 2, ElnaTacOperand.temporary, 6, 0);
|
||||
elna_instruction_list_concatenate(first_instruction, current_instruction);
|
||||
|
||||
(* Compile the assignment. *)
|
||||
operand_type := 0;
|
||||
operand_value := 0;
|
||||
@@ -2637,16 +2675,9 @@ begin
|
||||
current_instruction := instruction
|
||||
end;
|
||||
|
||||
instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
|
||||
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 7, 0);
|
||||
_elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 0, 0);
|
||||
|
||||
elna_instruction_list_concatenate(current_instruction, instruction);
|
||||
current_instruction := instruction;
|
||||
|
||||
instruction := _elna_tac_instruction_create(ElnaTacOperator.store);
|
||||
_elna_tac_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length);
|
||||
_elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.temporary, 7, 0);
|
||||
_elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.pseudo, "$assign", 7);
|
||||
|
||||
elna_instruction_list_concatenate(current_instruction, instruction);
|
||||
end;
|
||||
|
||||
Reference in New Issue
Block a user