Support compound statements

This commit is contained in:
2024-03-11 10:43:26 +01:00
parent 2c396ece17
commit 25657ac36d
12 changed files with 242 additions and 86 deletions

View File

@ -57,6 +57,10 @@ namespace elna::riscv
return reinterpret_cast<const std::byte *>(&this->representation) + sizeof(this->representation);
}
void visitor::visit(source::declaration *declaration)
{
}
void visitor::visit(source::definition *definition)
{
constants[definition->identifier()] = definition->body().number();
@ -64,60 +68,40 @@ namespace elna::riscv
void visitor::visit(source::block *block)
{
this->instructions.push_back(instruction(base_opcode::opImm));
this->instructions.push_back(instruction(base_opcode::store));
this->instructions.push_back(instruction(base_opcode::store));
this->instructions.push_back(instruction(base_opcode::opImm));
for (const auto& block_definition : block->definitions())
{
block_definition->accept(this);
}
for (const auto& block_declaration : block->declarations())
{
block_declaration->accept(this);
}
block->body().accept(this);
// Prologue.
const uint stackSize = static_cast<std::uint32_t>(variable_counter * 4 + 12);
std::vector<instruction> prologue{
instruction(base_opcode::opImm)
.i(x_register::sp, funct3_t::addi, x_register::sp, -stackSize),
instruction(base_opcode::store)
.s(stackSize - 4, funct3_t::sw, x_register::sp, x_register::s0),
instruction(base_opcode::store)
.s(stackSize - 8, funct3_t::sw, x_register::sp, x_register::ra),
instruction(base_opcode::opImm)
.i(x_register::s0, funct3_t::addi, x_register::sp, stackSize)
};
this->instructions.insert(this->instructions.cbegin(), prologue.begin(), prologue.end());
// Print the result.
this->instructions.push_back(instruction(base_opcode::opImm)
.i(x_register::a1, funct3_t::addi, x_register::a0, 0));
this->references[0] = reference();
this->references[0].name = ".CL0";
this->references[0].offset = instructions.size() * 4;
this->references[0].target = address_t::high20;
this->instructions.push_back(instruction(base_opcode::lui).u(x_register::a5, 0));
this->references[1] = reference();
this->references[1].name = ".CL0";
this->references[1].offset = instructions.size() * 4;
this->references[1].target = address_t::lower12i;
this->instructions.push_back(instruction(base_opcode::opImm)
.i(x_register::a0, funct3_t::addi, x_register::a5, 0));
this->references[2] = reference();
this->references[2].name = "printf";
this->references[2].offset = instructions.size() * 4;
this->references[2].target = address_t::text;
this->instructions.push_back(instruction(base_opcode::auipc).u(x_register::ra, 0));
this->instructions.push_back(instruction(base_opcode::jalr)
.i(x_register::ra, funct3_t::jalr, x_register::ra, 0));
// Set the return value (0).
this->instructions.push_back(instruction(base_opcode::op)
.r(x_register::a0, funct3_t::_and, x_register::zero, x_register::zero));
// Prologue.
const uint stack_size = static_cast<std::uint32_t>(variable_counter * 4 + 12);
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[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, stackSize - 4));
.i(x_register::s0, funct3_t::lw, x_register::sp, stack_size - 4));
this->instructions.push_back(instruction(base_opcode::load)
.i(x_register::ra, funct3_t::lw, x_register::sp, stackSize - 8));
.i(x_register::ra, funct3_t::lw, x_register::sp, stack_size - 8));
this->instructions.push_back(instruction(base_opcode::opImm)
.i(x_register::sp, funct3_t::addi, x_register::sp, stackSize));
.i(x_register::sp, funct3_t::addi, x_register::sp, stack_size));
this->instructions.push_back(instruction(base_opcode::jalr)
.i(x_register::zero, funct3_t::jalr, x_register::ra, 0));
}
@ -125,6 +109,42 @@ namespace elna::riscv
void visitor::visit(source::bang_statement *statement)
{
statement->body().accept(this);
// Print the result.
this->instructions.push_back(instruction(base_opcode::opImm)
.i(x_register::a1, funct3_t::addi, x_register::a0, 0));
this->references.push_back(reference());
this->references.back().name = ".CL0";
this->references.back().offset = instructions.size() * 4;
this->references.back().target = address_t::high20;
this->instructions.push_back(instruction(base_opcode::lui).u(x_register::a5, 0));
this->references.push_back(reference());
this->references.back().name = ".CL0";
this->references.back().offset = instructions.size() * 4;
this->references.back().target = address_t::lower12i;
this->instructions.push_back(instruction(base_opcode::opImm)
.i(x_register::a0, funct3_t::addi, x_register::a5, 0));
this->references.push_back(reference());
this->references.back().name = "printf";
this->references.back().offset = instructions.size() * 4;
this->references.back().target = address_t::text;
this->instructions.push_back(instruction(base_opcode::auipc).u(x_register::ra, 0));
this->instructions.push_back(instruction(base_opcode::jalr)
.i(x_register::ra, funct3_t::jalr, x_register::ra, 0));
}
void visitor::visit(source::compound_statement *statement)
{
for (auto& nested_statement : statement->statements())
{
nested_statement->accept(this);
}
}
void visitor::visit(source::assignment_statement *statement)
{
}
void visitor::visit(source::variable_expression *variable)