Handle immediate values in RTL
This commit is contained in:
@@ -831,41 +831,33 @@ var
|
|||||||
operand_length: Word;
|
operand_length: Word;
|
||||||
operand_type: Word;
|
operand_type: Word;
|
||||||
next_instruction: Word;
|
next_instruction: Word;
|
||||||
instruction_size: Word;
|
|
||||||
begin
|
begin
|
||||||
instruction_size := elna_rtl_instruction_size();
|
|
||||||
operand_value := _elna_tac_instruction_get_operand_value(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_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);
|
||||||
result := malloc(instruction_size);
|
|
||||||
|
|
||||||
if operand_type = ElnaTacOperand.immediate then
|
if operand_type = ElnaTacOperand.immediate then
|
||||||
elna_rtl_instruction_set_kind(result, ElnaRtlOperator.load_immediate);
|
result := elna_rtl_instruction_create(ElnaRtlOperator.load_immediate);
|
||||||
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.immediate, operand_value, operand_length);
|
elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.immediate, operand_value, operand_length)
|
||||||
ElnaInstructionList_set_next(result, 0)
|
|
||||||
elsif operand_type = ElnaTacOperand.stack then
|
elsif operand_type = ElnaTacOperand.stack then
|
||||||
elna_rtl_instruction_set_kind(result, ElnaRtlOperator.load_word);
|
result := elna_rtl_instruction_create(ElnaRtlOperator.load_word);
|
||||||
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.offset, ElnaRtlRegister.sp, operand_value);
|
elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, operand_value)
|
||||||
ElnaInstructionList_set_next(result, 0)
|
|
||||||
elsif operand_type = ElnaTacOperand.symbol then
|
elsif operand_type = ElnaTacOperand.symbol then
|
||||||
elna_rtl_instruction_set_kind(result, ElnaRtlOperator.load_address);
|
result := elna_rtl_instruction_create(ElnaRtlOperator.load_address);
|
||||||
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);
|
||||||
|
|
||||||
next_instruction := malloc(instruction_size);
|
next_instruction := elna_rtl_instruction_create(ElnaRtlOperator.load_word);
|
||||||
elna_rtl_instruction_set_kind(next_instruction, ElnaRtlOperator.load_word);
|
|
||||||
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);
|
||||||
ElnaInstructionList_set_next(next_instruction, 0);
|
|
||||||
|
|
||||||
ElnaInstructionList_set_next(result, next_instruction)
|
ElnaInstructionList_set_next(result, next_instruction)
|
||||||
elsif operand_type = ElnaTacOperand.register then
|
elsif operand_type = ElnaTacOperand.register then
|
||||||
elna_rtl_instruction_set_kind(result, ElnaRtlOperator.move);
|
result := elna_rtl_instruction_create(ElnaRtlOperator.move);
|
||||||
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.register, operand_value, 0);
|
elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.register, operand_value, 0)
|
||||||
ElnaInstructionList_set_next(result, 0)
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@@ -882,15 +874,12 @@ 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);
|
||||||
|
|
||||||
result := malloc(elna_rtl_instruction_size());
|
|
||||||
ElnaInstructionList_set_next(result, 0);
|
|
||||||
|
|
||||||
if operand_type = ElnaTacOperand.stack then
|
if operand_type = ElnaTacOperand.stack then
|
||||||
elna_rtl_instruction_set_kind(result, ElnaRtlOperator.add_immediate);
|
result := elna_rtl_instruction_create(ElnaRtlOperator.add_immediate);
|
||||||
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.offset, ElnaRtlRegister.sp, operand_value);
|
elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, operand_value)
|
||||||
elsif operand_type = ElnaTacOperand.symbol then
|
elsif operand_type = ElnaTacOperand.symbol then
|
||||||
elna_rtl_instruction_set_kind(result, ElnaRtlOperator.load_address);
|
result := elna_rtl_instruction_create(ElnaRtlOperator.load_address);
|
||||||
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)
|
||||||
end;
|
end;
|
||||||
@@ -920,13 +909,18 @@ begin
|
|||||||
return lhs
|
return lhs
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_rtl_binary_arithmetic(tac_instruction: Word, binary_result: Word, next_instruction: Word);
|
proc elna_rtl_binary_arithmetic(tac_instruction: Word, next_instruction: Word, operation: Word);
|
||||||
var
|
var
|
||||||
lhs: Word;
|
lhs: Word;
|
||||||
|
binary_result: Word;
|
||||||
begin
|
begin
|
||||||
lhs := elna_rtl_binary_operands(tac_instruction, next_instruction);
|
lhs := elna_rtl_binary_operands(tac_instruction, next_instruction);
|
||||||
|
binary_result := elna_rtl_instruction_create(operation);
|
||||||
|
|
||||||
|
elna_rtl_copy_operand(tac_instruction, 1, binary_result);
|
||||||
elna_rtl_instruction_set_operand(binary_result, 2, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0);
|
elna_rtl_instruction_set_operand(binary_result, 2, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0);
|
||||||
elna_rtl_instruction_set_operand(binary_result, 3, ElnaRtlOperand.register, ElnaRtlRegister.t3, 0);
|
elna_rtl_instruction_set_operand(binary_result, 3, ElnaRtlOperand.register, ElnaRtlRegister.t3, 0);
|
||||||
|
elna_rtl_instruction_set_kind(binary_result, operation);
|
||||||
|
|
||||||
ElnaInstructionList_set_next(next_instruction^, binary_result);
|
ElnaInstructionList_set_next(next_instruction^, binary_result);
|
||||||
next_instruction^ := binary_result;
|
next_instruction^ := binary_result;
|
||||||
@@ -955,6 +949,19 @@ begin
|
|||||||
return operands
|
return operands
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
proc elna_rtl_copy_operand(tac_instruction: Word, number: Word, rtl_instruction: Word);
|
||||||
|
var
|
||||||
|
operand_length: Word;
|
||||||
|
operand_type: Word;
|
||||||
|
operand_value: Word;
|
||||||
|
begin
|
||||||
|
operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, number);
|
||||||
|
operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, number);
|
||||||
|
operand_length := _elna_tac_instruction_get_operand_length(tac_instruction, number);
|
||||||
|
|
||||||
|
elna_rtl_instruction_set_operand(rtl_instruction, number, operand_type, operand_value, operand_length)
|
||||||
|
end;
|
||||||
|
|
||||||
proc elna_rtl_instruction(tac_instruction: Word, next_instruction: Word);
|
proc elna_rtl_instruction(tac_instruction: Word, next_instruction: Word);
|
||||||
var
|
var
|
||||||
result: Word;
|
result: Word;
|
||||||
@@ -976,22 +983,24 @@ begin
|
|||||||
|
|
||||||
if operand_type = ElnaTacOperand.stack then
|
if operand_type = ElnaTacOperand.stack then
|
||||||
operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2);
|
operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2);
|
||||||
|
result := elna_rtl_instruction_create(ElnaRtlOperator.add);
|
||||||
|
|
||||||
|
elna_rtl_copy_operand(tac_instruction, 1, result);
|
||||||
elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.register, ElnaRtlRegister.sp, 0);
|
elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.register, ElnaRtlRegister.sp, 0);
|
||||||
elna_rtl_instruction_set_operand(result, 3, ElnaRtlOperand.immediate, operand_value, 0);
|
elna_rtl_instruction_set_operand(result, 3, ElnaRtlOperand.immediate, operand_value, 0)
|
||||||
elna_rtl_instruction_set_kind(result, ElnaRtlOperator.add)
|
|
||||||
elsif operand_type = ElnaTacOperand.symbol then
|
elsif operand_type = ElnaTacOperand.symbol then
|
||||||
elna_rtl_instruction_set_kind(result, ElnaRtlOperator.load_address)
|
result := elna_rtl_instruction_create(ElnaRtlOperator.load_address);
|
||||||
|
|
||||||
|
elna_rtl_copy_operand(tac_instruction, 1, result);
|
||||||
|
elna_rtl_copy_operand(tac_instruction, 2, result)
|
||||||
elsif operand_type = ElnaTacOperand.register then
|
elsif operand_type = ElnaTacOperand.register then
|
||||||
elna_rtl_instruction_set_kind(result, ElnaRtlOperator.move);
|
result := elna_rtl_instruction_create(ElnaRtlOperator.move);
|
||||||
else
|
|
||||||
(* Debug. Error stream output.
|
elna_rtl_copy_operand(tac_instruction, 1, result);
|
||||||
_syscall(2, name_pointer, name_length, 0, 0, 0, 64); *)
|
elna_rtl_copy_operand(tac_instruction, 2, result)
|
||||||
printf("# here %i\n\0", operand_type);
|
end
|
||||||
fflush(0);
|
|
||||||
end;
|
|
||||||
elsif instruction_kind = ElnaTacOperator.add then
|
elsif instruction_kind = ElnaTacOperator.add then
|
||||||
result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction);
|
result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.add)
|
||||||
elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.add)
|
|
||||||
elsif instruction_kind = ElnaTacOperator.load_word then
|
elsif instruction_kind = ElnaTacOperator.load_word then
|
||||||
operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, 2);
|
operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, 2);
|
||||||
|
|
||||||
@@ -1007,33 +1016,37 @@ begin
|
|||||||
end;
|
end;
|
||||||
elna_rtl_instruction_set_kind(result, ElnaRtlOperator.load_word)
|
elna_rtl_instruction_set_kind(result, ElnaRtlOperator.load_word)
|
||||||
elsif instruction_kind = ElnaTacOperator.store_word then
|
elsif instruction_kind = ElnaTacOperator.store_word then
|
||||||
elna_rtl_instruction_set_kind(result, ElnaRtlOperator.store_word)
|
operands := elna_rtl_load_operand_value(tac_instruction, 1, ElnaRtlRegister.t0);
|
||||||
|
next_instruction^ := result;
|
||||||
|
result := operands;
|
||||||
|
operands := ElnaInstructionList_get_next(result);
|
||||||
|
|
||||||
|
elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.store_word);
|
||||||
|
elna_rtl_instruction_set_operand(next_instruction^, 1, ElnaRtlOperand.register, ElnaRtlRegister.t0, 0);
|
||||||
|
|
||||||
|
if operands = 0 then
|
||||||
|
ElnaInstructionList_set_next(result, next_instruction^)
|
||||||
|
else
|
||||||
|
ElnaInstructionList_set_next(operands, next_instruction^)
|
||||||
|
end
|
||||||
elsif instruction_kind = ElnaTacOperator.jal then
|
elsif instruction_kind = ElnaTacOperator.jal then
|
||||||
elna_rtl_instruction_set_kind(result, ElnaRtlOperator.jal)
|
elna_rtl_instruction_set_kind(result, ElnaRtlOperator.jal)
|
||||||
elsif instruction_kind = ElnaTacOperator.sub then
|
elsif instruction_kind = ElnaTacOperator.sub then
|
||||||
result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction);
|
result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.sub)
|
||||||
elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.sub)
|
|
||||||
elsif instruction_kind = ElnaTacOperator.mul then
|
elsif instruction_kind = ElnaTacOperator.mul then
|
||||||
result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction);
|
result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.mul)
|
||||||
elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.mul)
|
|
||||||
elsif instruction_kind = ElnaTacOperator.div then
|
elsif instruction_kind = ElnaTacOperator.div then
|
||||||
result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction);
|
result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.div)
|
||||||
elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.div)
|
|
||||||
elsif instruction_kind = ElnaTacOperator.rem then
|
elsif instruction_kind = ElnaTacOperator.rem then
|
||||||
result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction);
|
result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.rem)
|
||||||
elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.rem)
|
|
||||||
elsif instruction_kind = ElnaTacOperator._xor then
|
elsif instruction_kind = ElnaTacOperator._xor then
|
||||||
result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction);
|
result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator._xor)
|
||||||
elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator._xor)
|
|
||||||
elsif instruction_kind = ElnaTacOperator._or then
|
elsif instruction_kind = ElnaTacOperator._or then
|
||||||
result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction);
|
result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator._or)
|
||||||
elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator._or)
|
|
||||||
elsif instruction_kind = ElnaTacOperator.and then
|
elsif instruction_kind = ElnaTacOperator.and then
|
||||||
result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction);
|
result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.and)
|
||||||
elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.and)
|
|
||||||
elsif instruction_kind = ElnaTacOperator.slt then
|
elsif instruction_kind = ElnaTacOperator.slt then
|
||||||
result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction);
|
result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.slt)
|
||||||
elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.slt)
|
|
||||||
elsif instruction_kind = ElnaTacOperator.sgt then
|
elsif instruction_kind = ElnaTacOperator.sgt then
|
||||||
operands := elna_rtl_binary_operands(tac_instruction, next_instruction);
|
operands := elna_rtl_binary_operands(tac_instruction, next_instruction);
|
||||||
elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.register, ElnaRtlRegister.t3, 0);
|
elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.register, ElnaRtlRegister.t3, 0);
|
||||||
@@ -1100,9 +1113,27 @@ begin
|
|||||||
elna_rtl_instruction_set_kind(result, ElnaRtlOperator.label)
|
elna_rtl_instruction_set_kind(result, ElnaRtlOperator.label)
|
||||||
elsif instruction_kind = ElnaTacOperator.assign then
|
elsif instruction_kind = ElnaTacOperator.assign then
|
||||||
free(result);
|
free(result);
|
||||||
|
operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, 1);
|
||||||
operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 1);
|
operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 1);
|
||||||
|
|
||||||
|
if operand_type = ElnaTacOperand.register 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^ := ElnaInstructionList_get_next(result)
|
next_instruction^ := ElnaInstructionList_get_next(result)
|
||||||
|
elsif operand_type = ElnaTacOperand.stack then
|
||||||
|
operands := elna_rtl_load_operand_value(tac_instruction, 2, ElnaRtlRegister.t4);
|
||||||
|
result := operands;
|
||||||
|
operands := ElnaInstructionList_get_next(result);
|
||||||
|
|
||||||
|
next_instruction^ := elna_rtl_instruction_create(ElnaRtlOperator.store_word);
|
||||||
|
_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 = 0 then
|
||||||
|
ElnaInstructionList_set_next(result, next_instruction^)
|
||||||
|
else
|
||||||
|
ElnaInstructionList_set_next(operands, next_instruction^)
|
||||||
|
end
|
||||||
|
end
|
||||||
end;
|
end;
|
||||||
if next_instruction^ = 0 then
|
if next_instruction^ = 0 then
|
||||||
next_instruction^ := result;
|
next_instruction^ := result;
|
||||||
@@ -1122,18 +1153,6 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_load_address(target_register: Word, source_symbol: Word, symbol_length: Word);
|
|
||||||
var
|
|
||||||
result: Word;
|
|
||||||
begin
|
|
||||||
result := _elna_tac_instruction_create(ElnaTacOperator.get_address);
|
|
||||||
|
|
||||||
_elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, target_register, 0);
|
|
||||||
_elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.symbol, source_symbol, symbol_length);
|
|
||||||
|
|
||||||
return result
|
|
||||||
end;
|
|
||||||
|
|
||||||
proc _elna_tac_jump(source_symbol: Word, symbol_length: Word);
|
proc _elna_tac_jump(source_symbol: Word, symbol_length: Word);
|
||||||
var
|
var
|
||||||
result: Word;
|
result: Word;
|
||||||
@@ -1145,43 +1164,6 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_add(destination: Word, lhs: Word, rhs_type: Word, rhs: Word);
|
|
||||||
var
|
|
||||||
result: Word;
|
|
||||||
begin
|
|
||||||
result := _elna_tac_instruction_create(ElnaTacOperator.add);
|
|
||||||
|
|
||||||
_elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0);
|
|
||||||
_elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0);
|
|
||||||
_elna_tac_instruction_set_operand(result, 3, rhs_type, rhs, 0);
|
|
||||||
|
|
||||||
return result
|
|
||||||
end;
|
|
||||||
|
|
||||||
proc _elna_tac_sub(destination: Word, lhs: Word, rhs: Word);
|
|
||||||
var
|
|
||||||
result: Word;
|
|
||||||
begin
|
|
||||||
result := _elna_tac_instruction_create(ElnaTacOperator.sub);
|
|
||||||
|
|
||||||
_elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0);
|
|
||||||
_elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0);
|
|
||||||
_elna_tac_instruction_set_operand(result, 3, ElnaTacOperand.register, rhs, 0);
|
|
||||||
|
|
||||||
return result
|
|
||||||
end;
|
|
||||||
|
|
||||||
proc _elna_tac_jal(symbol: Word, length: Word);
|
|
||||||
var
|
|
||||||
result: Word;
|
|
||||||
begin
|
|
||||||
result := _elna_tac_instruction_create(ElnaTacOperator.jal);
|
|
||||||
|
|
||||||
_elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.symbol, symbol, length);
|
|
||||||
|
|
||||||
return result
|
|
||||||
end;
|
|
||||||
|
|
||||||
proc _elna_tac_load_word(target: Word, register: Word, offset: Word);
|
proc _elna_tac_load_word(target: Word, register: Word, offset: Word);
|
||||||
var
|
var
|
||||||
result: Word;
|
result: Word;
|
||||||
@@ -1206,30 +1188,6 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_neg(destination: Word, source: Word);
|
|
||||||
var
|
|
||||||
result: Word;
|
|
||||||
begin
|
|
||||||
result := _elna_tac_instruction_create(ElnaTacOperator.neg);
|
|
||||||
|
|
||||||
_elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0);
|
|
||||||
_elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, source, 0);
|
|
||||||
|
|
||||||
return result
|
|
||||||
end;
|
|
||||||
|
|
||||||
proc _elna_tac_not(destination: Word, source: Word);
|
|
||||||
var
|
|
||||||
result: Word;
|
|
||||||
begin
|
|
||||||
result := _elna_tac_instruction_create(ElnaTacOperator.not);
|
|
||||||
|
|
||||||
_elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0);
|
|
||||||
_elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, source, 0);
|
|
||||||
|
|
||||||
return result
|
|
||||||
end;
|
|
||||||
|
|
||||||
proc _elna_tac_label(counter: Word, length: Word);
|
proc _elna_tac_label(counter: Word, length: Word);
|
||||||
var
|
var
|
||||||
result: Word;
|
result: Word;
|
||||||
@@ -1810,6 +1768,7 @@ var
|
|||||||
is_address: Word;
|
is_address: Word;
|
||||||
first_instruction: Word;
|
first_instruction: Word;
|
||||||
instruction: Word;
|
instruction: Word;
|
||||||
|
temp: Word;
|
||||||
begin
|
begin
|
||||||
operator := 0;
|
operator := 0;
|
||||||
operand := 0;
|
operand := 0;
|
||||||
@@ -1836,17 +1795,11 @@ begin
|
|||||||
|
|
||||||
first_instruction := elna_instruction_list_concatenate(first_instruction, instruction)
|
first_instruction := elna_instruction_list_concatenate(first_instruction, instruction)
|
||||||
else
|
else
|
||||||
|
current_character := operand_type^;
|
||||||
first_instruction := _elna_tac_designator(operand, symbol_table, @is_address, operand_type, operand_value, operand_length);
|
first_instruction := _elna_tac_designator(operand, symbol_table, @is_address, operand_type, operand_value, operand_length);
|
||||||
|
operand := operand_type^;
|
||||||
|
|
||||||
if operand_type^ = ElnaTacOperand.immediate then
|
if first_instruction = 0 then
|
||||||
first_instruction := _elna_tac_instruction_create(ElnaTacOperator.assign);
|
|
||||||
_elna_tac_instruction_set_operand(first_instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0);
|
|
||||||
_elna_tac_instruction_set_operand(first_instruction, 2, operand_type^, operand_value^, operand_length^);
|
|
||||||
|
|
||||||
operand_type^ := ElnaTacOperand.register;
|
|
||||||
operand_value^ := ElnaRtlRegister.t0;
|
|
||||||
operand_length^ := 0
|
|
||||||
elsif first_instruction = 0 then
|
|
||||||
first_instruction := _elna_tac_instruction_create(ElnaTacOperator.get_address);
|
first_instruction := _elna_tac_instruction_create(ElnaTacOperator.get_address);
|
||||||
_elna_tac_instruction_set_operand(first_instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0);
|
_elna_tac_instruction_set_operand(first_instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0);
|
||||||
_elna_tac_instruction_set_operand(first_instruction, 2, operand_type^, operand_value^, operand_length^);
|
_elna_tac_instruction_set_operand(first_instruction, 2, operand_type^, operand_value^, operand_length^);
|
||||||
@@ -1855,7 +1808,6 @@ begin
|
|||||||
operand_value^ := ElnaRtlRegister.t0;
|
operand_value^ := ElnaRtlRegister.t0;
|
||||||
operand_length^ := 0
|
operand_length^ := 0
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if is_address then
|
if is_address then
|
||||||
instruction := _elna_tac_instruction_create(ElnaTacOperator.load_word);
|
instruction := _elna_tac_instruction_create(ElnaTacOperator.load_word);
|
||||||
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0);
|
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0);
|
||||||
@@ -1869,10 +1821,14 @@ begin
|
|||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
if operator = '-' then
|
if operator = '-' then
|
||||||
instruction := _elna_tac_neg(ElnaRtlRegister.t0, ElnaRtlRegister.t0);
|
instruction := _elna_tac_instruction_create(ElnaTacOperator.neg);
|
||||||
|
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0);
|
||||||
|
_elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.register, ElnaRtlRegister.t0, 0);
|
||||||
elna_instruction_list_concatenate(first_instruction, instruction)
|
elna_instruction_list_concatenate(first_instruction, instruction)
|
||||||
elsif operator = '~' then
|
elsif operator = '~' then
|
||||||
instruction := _elna_tac_not(ElnaRtlRegister.t0, ElnaRtlRegister.t0);
|
instruction := _elna_tac_instruction_create(ElnaTacOperator.not);
|
||||||
|
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0);
|
||||||
|
_elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.register, ElnaRtlRegister.t0, 0);
|
||||||
elna_instruction_list_concatenate(first_instruction, instruction)
|
elna_instruction_list_concatenate(first_instruction, instruction)
|
||||||
end;
|
end;
|
||||||
return first_instruction
|
return first_instruction
|
||||||
@@ -1971,11 +1927,15 @@ begin
|
|||||||
first_instruction := _elna_tac_unary_expression(operand_node, symbol_table, @lhs_type, @lhs_value, @lhs_length);
|
first_instruction := _elna_tac_unary_expression(operand_node, symbol_table, @lhs_type, @lhs_value, @lhs_length);
|
||||||
|
|
||||||
(* Save the value of the left expression on the stack. *)
|
(* Save the value of the left expression on the stack. *)
|
||||||
instruction := _elna_tac_instruction_create(ElnaTacOperator.store_word);
|
instruction := _elna_tac_instruction_create(ElnaTacOperator.assign);
|
||||||
_elna_tac_instruction_set_operand(instruction, 1, lhs_type, lhs_value, lhs_length);
|
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.stack, 72, 0);
|
||||||
_elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.offset, ElnaRtlRegister.sp, 72);
|
_elna_tac_instruction_set_operand(instruction, 2, lhs_type, lhs_value, lhs_length);
|
||||||
|
|
||||||
elna_instruction_list_concatenate(first_instruction, instruction);
|
if first_instruction = 0 then
|
||||||
|
first_instruction := instruction
|
||||||
|
else
|
||||||
|
elna_instruction_list_concatenate(first_instruction, instruction)
|
||||||
|
end;
|
||||||
current_instruction := instruction;
|
current_instruction := instruction;
|
||||||
|
|
||||||
operand_node := _binary_expression_get_rhs(parser_node);
|
operand_node := _binary_expression_get_rhs(parser_node);
|
||||||
@@ -1983,13 +1943,22 @@ begin
|
|||||||
lhs_value := 0;
|
lhs_value := 0;
|
||||||
lhs_length := 0;
|
lhs_length := 0;
|
||||||
instruction := _elna_tac_unary_expression(operand_node, symbol_table, @lhs_type, @lhs_value, @lhs_length);
|
instruction := _elna_tac_unary_expression(operand_node, symbol_table, @lhs_type, @lhs_value, @lhs_length);
|
||||||
elna_instruction_list_concatenate(current_instruction, instruction);
|
|
||||||
current_instruction := instruction;
|
(* Debug. Error stream output.
|
||||||
|
_syscall(2, name_pointer, name_length, 0, 0, 0, 64);
|
||||||
|
if lhs_length = 0 then
|
||||||
|
printf("# here %i\n\0", lhs_value);
|
||||||
|
else
|
||||||
|
printf("# here %.*s\n\0", lhs_length, lhs_value);
|
||||||
|
end;
|
||||||
|
fflush(0); *)
|
||||||
|
|
||||||
|
current_instruction := elna_instruction_list_concatenate(current_instruction, instruction);
|
||||||
|
|
||||||
(* Load the left expression from the stack; *)
|
(* Load the left expression from the stack; *)
|
||||||
instruction := _elna_tac_instruction_create(ElnaTacOperator.load_word);
|
instruction := _elna_tac_instruction_create(ElnaTacOperator.assign);
|
||||||
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t1, 0);
|
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t1, 0);
|
||||||
_elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.offset, ElnaRtlRegister.sp, 72);
|
_elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 72, 0);
|
||||||
|
|
||||||
elna_instruction_list_concatenate(current_instruction, instruction);
|
elna_instruction_list_concatenate(current_instruction, instruction);
|
||||||
current_instruction := instruction;
|
current_instruction := instruction;
|
||||||
@@ -2145,7 +2114,9 @@ begin
|
|||||||
else
|
else
|
||||||
elna_instruction_list_concatenate(current_instruction, instruction)
|
elna_instruction_list_concatenate(current_instruction, instruction)
|
||||||
end;
|
end;
|
||||||
current_instruction := instruction;
|
if instruction <> 0 then
|
||||||
|
current_instruction := instruction
|
||||||
|
end;
|
||||||
|
|
||||||
(* Save the argument on the stack. *)
|
(* Save the argument on the stack. *)
|
||||||
stack_offset := argument_count * 4;
|
stack_offset := argument_count * 4;
|
||||||
@@ -2153,8 +2124,11 @@ begin
|
|||||||
instruction := _elna_tac_instruction_create(ElnaTacOperator.store_word);
|
instruction := _elna_tac_instruction_create(ElnaTacOperator.store_word);
|
||||||
_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.offset, ElnaRtlRegister.sp, 132 - stack_offset);
|
_elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.offset, ElnaRtlRegister.sp, 132 - stack_offset);
|
||||||
|
if first_instruction = 0 then
|
||||||
elna_instruction_list_concatenate(current_instruction, instruction);
|
first_instruction := instruction
|
||||||
|
else
|
||||||
|
elna_instruction_list_concatenate(current_instruction, instruction)
|
||||||
|
end;
|
||||||
current_instruction := instruction;
|
current_instruction := instruction;
|
||||||
|
|
||||||
argument_count := argument_count + 1;
|
argument_count := argument_count + 1;
|
||||||
@@ -2176,7 +2150,8 @@ begin
|
|||||||
|
|
||||||
goto elna_tac_call_finalize
|
goto elna_tac_call_finalize
|
||||||
end;
|
end;
|
||||||
instruction := _elna_tac_jal(name, name_length);
|
instruction := _elna_tac_instruction_create(ElnaTacOperator.jal);
|
||||||
|
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.symbol, name, name_length);
|
||||||
if first_instruction = 0 then
|
if first_instruction = 0 then
|
||||||
first_instruction := instruction
|
first_instruction := instruction
|
||||||
else
|
else
|
||||||
@@ -2359,7 +2334,7 @@ begin
|
|||||||
|
|
||||||
first_instruction := elna_instruction_list_concatenate(first_instruction, last_instruction)
|
first_instruction := elna_instruction_list_concatenate(first_instruction, last_instruction)
|
||||||
elsif node_kind = NodeKind.field_access_expression then
|
elsif node_kind = NodeKind.field_access_expression then
|
||||||
_elna_tac_enumeration_value(parser_node, operand_type, operand_value, operand_length);
|
first_instruction := _elna_tac_enumeration_value(parser_node, operand_type, operand_value, operand_length);
|
||||||
is_address^ := 0
|
is_address^ := 0
|
||||||
elsif node_kind = NodeKind.call then
|
elsif node_kind = NodeKind.call then
|
||||||
first_instruction := _elna_tac_call(parser_node, symbol_table);
|
first_instruction := _elna_tac_call(parser_node, symbol_table);
|
||||||
@@ -2435,10 +2410,14 @@ begin
|
|||||||
operand_length := 0;
|
operand_length := 0;
|
||||||
instruction := _elna_tac_binary_expression(current_expression, symbol_table, @operand_type, @operand_value, @operand_length);
|
instruction := _elna_tac_binary_expression(current_expression, symbol_table, @operand_type, @operand_value, @operand_length);
|
||||||
|
|
||||||
|
if instruction <> 0 then
|
||||||
elna_instruction_list_concatenate(current_instruction, instruction);
|
elna_instruction_list_concatenate(current_instruction, instruction);
|
||||||
|
current_instruction := instruction
|
||||||
|
end;
|
||||||
|
|
||||||
current_instruction := _elna_tac_load_word(ElnaRtlRegister.t1, ElnaRtlRegister.sp, 76);
|
instruction := _elna_tac_load_word(ElnaRtlRegister.t1, ElnaRtlRegister.sp, 76);
|
||||||
elna_instruction_list_concatenate(instruction, current_instruction);
|
elna_instruction_list_concatenate(current_instruction, instruction);
|
||||||
|
current_instruction := instruction;
|
||||||
|
|
||||||
instruction := _elna_tac_instruction_create(ElnaTacOperator.store_word);
|
instruction := _elna_tac_instruction_create(ElnaTacOperator.store_word);
|
||||||
_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);
|
||||||
@@ -2489,8 +2468,7 @@ begin
|
|||||||
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.a0, 0);
|
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.a0, 0);
|
||||||
_elna_tac_instruction_set_operand(instruction, 2, operand_type, operand_value, operand_length);
|
_elna_tac_instruction_set_operand(instruction, 2, operand_type, operand_value, operand_length);
|
||||||
|
|
||||||
elna_instruction_list_concatenate(first_instruction, instruction);
|
return elna_instruction_list_concatenate(first_instruction, instruction)
|
||||||
return first_instruction
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
(**
|
(**
|
||||||
@@ -2626,6 +2604,7 @@ proc _elna_parser_statement();
|
|||||||
var
|
var
|
||||||
token_kind: Word;
|
token_kind: Word;
|
||||||
result : Word;
|
result : Word;
|
||||||
|
temporary: Word;
|
||||||
begin
|
begin
|
||||||
result := 0;
|
result := 0;
|
||||||
_elna_lexer_read_token(@token_kind);
|
_elna_lexer_read_token(@token_kind);
|
||||||
@@ -2640,8 +2619,9 @@ begin
|
|||||||
result := _elna_parser_label_declaration()
|
result := _elna_parser_label_declaration()
|
||||||
elsif token_kind = ElnaLexerKind.identifier then
|
elsif token_kind = ElnaLexerKind.identifier then
|
||||||
result := _elna_parser_designator();
|
result := _elna_parser_designator();
|
||||||
|
temporary := _node_get_kind(result);
|
||||||
|
|
||||||
if _node_get_kind(result) <> NodeKind.call then
|
if temporary <> NodeKind.call then
|
||||||
result := _elna_parser_assign_statement(result)
|
result := _elna_parser_assign_statement(result)
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
@@ -3667,59 +3647,61 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_type_field(name_pointer: Word, name_length: Word, field_pointer: Word, field_offset: Word);
|
proc _elna_tac_accessor(name_pointer: Word, name_length: Word, field_pointer: Word, field_offset: Word, result: Word, method: Word);
|
||||||
var
|
var
|
||||||
first_result: Word;
|
instruction: Word;
|
||||||
second_result: Word;
|
|
||||||
new_name: Word;
|
new_name: Word;
|
||||||
|
name_target: Word;
|
||||||
new_length: Word;
|
new_length: Word;
|
||||||
field_length: Word;
|
field_length: Word;
|
||||||
instruction: Word;
|
|
||||||
name_target: Word;
|
|
||||||
next_instruction: Word;
|
|
||||||
begin
|
begin
|
||||||
field_length := field_pointer + 4;
|
field_length := field_pointer + 4;
|
||||||
field_length := field_length^;
|
field_length := field_length^;
|
||||||
new_length := field_length + name_length;
|
new_length := field_length + name_length;
|
||||||
new_length := new_length + 5;
|
new_length := new_length + 5;
|
||||||
|
|
||||||
first_result := malloc(ElnaInstructionDeclaration_size());
|
result^ := malloc(ElnaInstructionDeclaration_size());
|
||||||
ElnaInstructionList_set_next(first_result, 0);
|
ElnaInstructionList_set_next(result^, 0);
|
||||||
|
|
||||||
new_name := malloc(new_length);
|
new_name := malloc(new_length);
|
||||||
|
|
||||||
name_target := new_name;
|
name_target := new_name;
|
||||||
memcpy(name_target, name_pointer, name_length);
|
memcpy(name_target, name_pointer, name_length);
|
||||||
name_target := name_target + name_length;
|
name_target := name_target + name_length;
|
||||||
memcpy(name_target, "_get_", 5);
|
memcpy(name_target, method, 5);
|
||||||
name_target := name_target + 5;
|
name_target := name_target + 5;
|
||||||
memcpy(name_target, field_pointer^, field_length);
|
memcpy(name_target, field_pointer^, field_length);
|
||||||
|
|
||||||
ElnaInstructionDeclaration_set_name(first_result, new_name);
|
ElnaInstructionDeclaration_set_name(result^, new_name);
|
||||||
ElnaInstructionDeclaration_set_length(first_result, new_length);
|
ElnaInstructionDeclaration_set_length(result^, new_length);
|
||||||
|
|
||||||
instruction := _elna_tac_add(ElnaRtlRegister.a0, ElnaRtlRegister.a0, ElnaTacOperand.immediate, field_offset);
|
instruction := _elna_tac_instruction_create(ElnaTacOperator.add);
|
||||||
next_instruction := _elna_tac_load_word(ElnaRtlRegister.a0, ElnaRtlRegister.a0, 0);
|
|
||||||
|
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.a0, 0);
|
||||||
|
_elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.register, ElnaRtlRegister.a0, 0);
|
||||||
|
_elna_tac_instruction_set_operand(instruction, 3, ElnaTacOperand.immediate, field_offset, 0);
|
||||||
|
|
||||||
|
return instruction
|
||||||
|
end;
|
||||||
|
|
||||||
|
proc _elna_tac_type_field(name_pointer: Word, name_length: Word, field_pointer: Word, field_offset: Word);
|
||||||
|
var
|
||||||
|
first_result: Word;
|
||||||
|
second_result: Word;
|
||||||
|
instruction: Word;
|
||||||
|
next_instruction: Word;
|
||||||
|
begin
|
||||||
|
instruction := _elna_tac_accessor(name_pointer, name_length, field_pointer, field_offset, @first_result, "_get_");
|
||||||
|
next_instruction := _elna_tac_instruction_create(ElnaTacOperator.load_word);
|
||||||
|
_elna_tac_instruction_set_operand(next_instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.a0, 0);
|
||||||
|
_elna_tac_instruction_set_operand(next_instruction, 2, ElnaTacOperand.offset, ElnaRtlRegister.a0, 0);
|
||||||
elna_instruction_list_concatenate(instruction, next_instruction);
|
elna_instruction_list_concatenate(instruction, next_instruction);
|
||||||
ElnaInstructionDeclaration_set_body(first_result, instruction);
|
ElnaInstructionDeclaration_set_body(first_result, instruction);
|
||||||
|
|
||||||
second_result := malloc(ElnaInstructionDeclaration_size());
|
instruction := _elna_tac_accessor(name_pointer, name_length, field_pointer, field_offset, @second_result, "_set_");
|
||||||
ElnaInstructionList_set_next(second_result, 0);
|
next_instruction := _elna_tac_instruction_create(ElnaTacOperator.store_word);
|
||||||
|
_elna_tac_instruction_set_operand(next_instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.a1, 0);
|
||||||
new_name := malloc(new_length);
|
_elna_tac_instruction_set_operand(next_instruction, 2, ElnaTacOperand.offset, ElnaRtlRegister.a0, 0);
|
||||||
|
|
||||||
name_target := new_name;
|
|
||||||
memcpy(name_target, name_pointer, name_length);
|
|
||||||
name_target := name_target + name_length;
|
|
||||||
memcpy(name_target, "_set_", 5);
|
|
||||||
name_target := name_target + 5;
|
|
||||||
memcpy(name_target, field_pointer^, field_length);
|
|
||||||
|
|
||||||
ElnaInstructionDeclaration_set_name(second_result, new_name);
|
|
||||||
ElnaInstructionDeclaration_set_length(second_result, new_length);
|
|
||||||
|
|
||||||
instruction := _elna_tac_add(ElnaRtlRegister.a0, ElnaRtlRegister.a0, ElnaTacOperand.immediate, field_offset);
|
|
||||||
next_instruction := _elna_tac_store_word(ElnaRtlRegister.a1, ElnaRtlRegister.a0, 0);
|
|
||||||
elna_instruction_list_concatenate(instruction, next_instruction);
|
elna_instruction_list_concatenate(instruction, next_instruction);
|
||||||
ElnaInstructionDeclaration_set_body(second_result, instruction);
|
ElnaInstructionDeclaration_set_body(second_result, instruction);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user