Support multiple function arguments
This commit is contained in:
@ -1,4 +1,5 @@
|
||||
#include "elna/backend/riscv.hpp"
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
|
||||
namespace elna::riscv
|
||||
@ -168,15 +169,15 @@ namespace elna::riscv
|
||||
void visitor::epilogue(const std::size_t stack_size)
|
||||
{
|
||||
this->instructions[0].i(x_register::sp, funct3_t::addi, x_register::sp, -stack_size);
|
||||
this->instructions[1].s(stack_size - 4, funct3_t::sw, x_register::sp, x_register::s0);
|
||||
this->instructions[2].s(stack_size - 8, funct3_t::sw, x_register::sp, x_register::ra);
|
||||
this->instructions[1].s(0, funct3_t::sw, x_register::sp, x_register::s0);
|
||||
this->instructions[2].s(4, funct3_t::sw, x_register::sp, x_register::ra);
|
||||
this->instructions[3].i(x_register::s0, funct3_t::addi, x_register::sp, stack_size);
|
||||
|
||||
// Epilogue.
|
||||
this->instructions.push_back(instruction(base_opcode::load)
|
||||
.i(x_register::s0, funct3_t::lw, x_register::sp, stack_size - 4));
|
||||
.i(x_register::s0, funct3_t::lw, x_register::sp, 0));
|
||||
this->instructions.push_back(instruction(base_opcode::load)
|
||||
.i(x_register::ra, funct3_t::lw, x_register::sp, stack_size - 8));
|
||||
.i(x_register::ra, funct3_t::lw, x_register::sp, 4));
|
||||
this->instructions.push_back(instruction(base_opcode::opImm)
|
||||
.i(x_register::sp, funct3_t::addi, x_register::sp, stack_size));
|
||||
this->instructions.push_back(instruction(base_opcode::jalr)
|
||||
@ -226,16 +227,20 @@ namespace elna::riscv
|
||||
this->instructions.push_back(instruction(base_opcode::op)
|
||||
.r(x_register::a0, funct3_t::_and, x_register::zero, x_register::zero));
|
||||
|
||||
epilogue(static_cast<std::uint32_t>(this->variable_counter * 4 + 8 + main_symbol->stack_size()));
|
||||
epilogue(static_cast<std::uint32_t>(this->variable_counter * 4 + 8 + main_symbol->local_stack_size));
|
||||
this->writer->sink("main", reinterpret_cast<const std::byte *>(this->instructions.data()),
|
||||
this->instructions.size() * sizeof(instruction));
|
||||
}
|
||||
|
||||
void visitor::visit(source::call_statement *statement)
|
||||
{
|
||||
std::size_t argument_offset{ 0 };
|
||||
for (auto& argument : statement->arguments())
|
||||
{
|
||||
argument->accept(this);
|
||||
this->instructions.push_back(instruction(base_opcode::store)
|
||||
.s(argument_offset, funct3_t::sw, x_register::sp, x_register::a0));
|
||||
argument_offset += 4;
|
||||
}
|
||||
relocate(statement->name(), address_t::text);
|
||||
this->instructions.push_back(instruction(base_opcode::auipc).u(x_register::ra, 0));
|
||||
@ -297,10 +302,17 @@ namespace elna::riscv
|
||||
else if (auto variable_symbol = std::dynamic_pointer_cast<source::variable_info>(symbol))
|
||||
{
|
||||
this->instructions.push_back(
|
||||
instruction(base_opcode::store)
|
||||
instruction(base_opcode::load)
|
||||
.i(free_register, funct3_t::lw, x_register::s0, variable_symbol->offset)
|
||||
);
|
||||
}
|
||||
else if (auto parameter_symbol = std::dynamic_pointer_cast<source::parameter_info>(symbol))
|
||||
{
|
||||
this->instructions.push_back(
|
||||
instruction(base_opcode::load)
|
||||
.i(free_register, funct3_t::lw, x_register::s0, parameter_symbol->offset)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void visitor::visit(source::binary_expression *expression)
|
||||
|
Reference in New Issue
Block a user