From 9c7614dd25bbbb13a3406b7e51ecdd2d5a7cf8ae Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Fri, 12 Apr 2024 00:07:46 +0200 Subject: [PATCH] Don't relax function calls --- TODO | 8 +++---- backend/riscv.cpp | 25 ++++++++++++++------ backend/target.cpp | 6 ++--- source/parser.cpp | 5 ++++ tests/expectations/if_condition.txt | 1 + tests/expectations/pointer_in_expression.txt | 1 + tests/expectations/print_in_loop.txt | 5 ++++ tests/if_condition.eln | 4 +++- tests/pointer_in_expression.eln | 6 +++++ tests/print_in_loop.eln | 10 ++++++++ 10 files changed, 55 insertions(+), 16 deletions(-) create mode 100644 tests/expectations/pointer_in_expression.txt create mode 100644 tests/expectations/print_in_loop.txt create mode 100644 tests/pointer_in_expression.eln create mode 100644 tests/print_in_loop.eln diff --git a/TODO b/TODO index 6a0e433..9a85cbe 100644 --- a/TODO +++ b/TODO @@ -2,6 +2,7 @@ - Catch exceptions thrown by the argument parser and print them normally. - Structs or records. +- Unions. - While loop. - Type checking. - Calculate additional stack space needed for subexpressions in the allocator @@ -9,8 +10,9 @@ - Support immediates greater than 12 bits. - It seems instructions are correctly encoded only if the compiler is running on a little endian architecture. -- Pointer. +- Assignment to a pointer. - Static array. +- Syscalls. # Shell - Persist the history. @@ -24,7 +26,3 @@ - Send the word under the cursor to fzf as initial input. - Home directory expansion. - Show files in the PATH if starting at the beginning of the prompt - -## Appearance - -- Add a bar with additional information under the prompt (edit_bar), like the hostname. diff --git a/backend/riscv.cpp b/backend/riscv.cpp index c36693c..66df852 100644 --- a/backend/riscv.cpp +++ b/backend/riscv.cpp @@ -280,7 +280,7 @@ namespace elna::riscv instructions.push_back(instruction(base_opcode::branch)); statement->body().accept(this); instructions[before_branch] - .b((instructions.size() - before_branch) * 4 - 4, funct3_t::beq, x_register::zero, free_register); + .b((instructions.size() - before_branch) * 4, funct3_t::beq, x_register::zero, free_register); } void visitor::visit(source::while_statement *statement) @@ -400,13 +400,24 @@ namespace elna::riscv void visitor::visit(source::unary_expression *expression) { - const auto free_register = this->register_in_use ? x_register::a0 : x_register::t0; - auto operand_identifier = dynamic_cast(expression->operand()).name(); - auto variable_symbol = - std::dynamic_pointer_cast(this->table->lookup(operand_identifier)); + switch (expression->operation()) + { + case source::unary_operator::dereference: + expression->operand().accept(this); - this->instructions.push_back(instruction(base_opcode::opImm) - .i(free_register, funct3_t::addi, x_register::s0, variable_symbol->offset)); + this->instructions.push_back(instruction(base_opcode::load) + .i(x_register::a0, funct3_t::lw, x_register::a0, 0)); + break; + case source::unary_operator::reference: + const auto free_register = this->register_in_use ? x_register::a0 : x_register::t0; + auto operand_identifier = dynamic_cast(expression->operand()).name(); + auto variable_symbol = + std::dynamic_pointer_cast(this->table->lookup(operand_identifier)); + + this->instructions.push_back(instruction(base_opcode::opImm) + .i(free_register, funct3_t::addi, x_register::s0, variable_symbol->offset)); + break; + } } void visitor::visit(source::integer_literal *number) diff --git a/backend/target.cpp b/backend/target.cpp index 7586f03..b53092a 100644 --- a/backend/target.cpp +++ b/backend/target.cpp @@ -211,15 +211,15 @@ namespace elna::riscv { case address_t::high20: rela.add_entry(reference.offset, relocated_symbol, 26 /* ELFIO::R_RISCV_HI20 */); - rela.add_entry(reference.offset, relocated_symbol, 51 /* ELFIO::R_RISCV_RELAX */); + // rela.add_entry(reference.offset, relocated_symbol, 51 /* ELFIO::R_RISCV_RELAX */); break; case address_t::lower12i: rela.add_entry(reference.offset, relocated_symbol, 27 /* ELFIO::R_RISCV_LO12_I */); - rela.add_entry(reference.offset, relocated_symbol, 51 /* ELFIO::R_RISCV_RELAX */); + // rela.add_entry(reference.offset, relocated_symbol, 51 /* ELFIO::R_RISCV_RELAX */); break; case address_t::text: rela.add_entry(reference.offset, relocated_symbol, 18 /* ELFIO::R_RISCV_CALL */); - rela.add_entry(reference.offset, relocated_symbol, 51 /* ELFIO::R_RISCV_RELAX */); + // rela.add_entry(reference.offset, relocated_symbol, 51 /* ELFIO::R_RISCV_RELAX */); break; } } diff --git a/source/parser.cpp b/source/parser.cpp index 254ac9f..ad15afa 100644 --- a/source/parser.cpp +++ b/source/parser.cpp @@ -375,6 +375,11 @@ namespace elna::source return *m_operand; } + unary_operator unary_expression::operation() const noexcept + { + return this->m_operator; + } + call_statement::call_statement(const struct position position, const std::string& name) : statement(position), m_name(name) { diff --git a/tests/expectations/if_condition.txt b/tests/expectations/if_condition.txt index 45a4fb7..512858e 100644 --- a/tests/expectations/if_condition.txt +++ b/tests/expectations/if_condition.txt @@ -1 +1,2 @@ 8 +9 diff --git a/tests/expectations/pointer_in_expression.txt b/tests/expectations/pointer_in_expression.txt new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/tests/expectations/pointer_in_expression.txt @@ -0,0 +1 @@ +5 diff --git a/tests/expectations/print_in_loop.txt b/tests/expectations/print_in_loop.txt new file mode 100644 index 0000000..8a1218a --- /dev/null +++ b/tests/expectations/print_in_loop.txt @@ -0,0 +1,5 @@ +1 +2 +3 +4 +5 diff --git a/tests/if_condition.eln b/tests/if_condition.eln index 51cccd0..1dcc3cb 100644 --- a/tests/if_condition.eln +++ b/tests/if_condition.eln @@ -5,5 +5,7 @@ begin writei(5); writei(5); writei(5) - end + end; + if 1 < 2 then writei(9); + if 1 > 2 then writei(10) end. diff --git a/tests/pointer_in_expression.eln b/tests/pointer_in_expression.eln new file mode 100644 index 0000000..8542d3b --- /dev/null +++ b/tests/pointer_in_expression.eln @@ -0,0 +1,6 @@ +var a: Int, b: ^Int; +begin + a := 5; + b := @a; + writei(b^) +end. diff --git a/tests/print_in_loop.eln b/tests/print_in_loop.eln new file mode 100644 index 0000000..e303ee6 --- /dev/null +++ b/tests/print_in_loop.eln @@ -0,0 +1,10 @@ +var i: Int; +begin + i := 1; + + while i <= 6 do + begin + writei(i); + i := i + 1 + end; +end.