Move procedure call register allocation to RTL

This commit is contained in:
2025-12-12 18:32:01 +01:00
parent 305032b534
commit 1cf71f1a5f

View File

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