Replace ! with a function call writei
This commit is contained in:
@ -76,9 +76,8 @@ namespace elna::riscv
|
||||
return reinterpret_cast<const std::byte *>(&this->representation) + sizeof(this->representation);
|
||||
}
|
||||
|
||||
visitor::visitor(std::function<void(const std::string&, const std::byte *, std::size_t)> write_text,
|
||||
std::function<std::string_view(const std::byte *, std::size_t)> write_read_only)
|
||||
: write_text(write_text), write_read_only(write_read_only)
|
||||
visitor::visitor(std::shared_ptr<source::writer> writer)
|
||||
: writer(writer)
|
||||
{
|
||||
}
|
||||
|
||||
@ -127,40 +126,67 @@ namespace elna::riscv
|
||||
|
||||
void visitor::visit(source::program *program)
|
||||
{
|
||||
this->writer->sink("printf");
|
||||
auto format_string = this->writer->sink(reinterpret_cast<const std::byte *>("%d\n\0"), 4);
|
||||
|
||||
this->instructions.push_back(instruction(base_opcode::opImm)
|
||||
.i(x_register::sp, funct3_t::addi, x_register::sp, -8));
|
||||
this->instructions.push_back(instruction(base_opcode::store)
|
||||
.s(4, funct3_t::sw, x_register::sp, x_register::s0));
|
||||
this->instructions.push_back(instruction(base_opcode::store)
|
||||
.s(0, funct3_t::sw, x_register::sp, x_register::ra));
|
||||
this->instructions.push_back(instruction(base_opcode::opImm)
|
||||
.i(x_register::s0, funct3_t::addi, x_register::sp, -8));
|
||||
|
||||
this->references.push_back(reference());
|
||||
this->references.back().name = format_string;
|
||||
this->references.back().offset = writer->size() + 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 = format_string;
|
||||
this->references.back().offset = writer->size() + 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 = writer->size() + 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));
|
||||
|
||||
this->instructions.push_back(instruction(base_opcode::load)
|
||||
.i(x_register::s0, funct3_t::lw, x_register::sp, 4));
|
||||
this->instructions.push_back(instruction(base_opcode::load)
|
||||
.i(x_register::ra, funct3_t::lw, x_register::sp, 0));
|
||||
this->instructions.push_back(instruction(base_opcode::opImm)
|
||||
.i(x_register::sp, funct3_t::addi, x_register::sp, 8));
|
||||
this->instructions.push_back(instruction(base_opcode::jalr)
|
||||
.i(x_register::zero, funct3_t::jalr, x_register::ra, 0));
|
||||
|
||||
this->writer->sink("writei", reinterpret_cast<const std::byte *>(this->instructions.data()),
|
||||
this->instructions.size() * sizeof(instruction));
|
||||
|
||||
this->instructions.clear();
|
||||
visit(dynamic_cast<source::block *>(program));
|
||||
write_text("main", reinterpret_cast<const std::byte *>(this->instructions.data()),
|
||||
this->writer->sink("main", reinterpret_cast<const std::byte *>(this->instructions.data()),
|
||||
this->instructions.size() * sizeof(instruction));
|
||||
}
|
||||
|
||||
void visitor::visit(source::bang_statement *statement)
|
||||
void visitor::visit(source::call_statement *statement)
|
||||
{
|
||||
statement->body().accept(this);
|
||||
statement->arguments().accept(this);
|
||||
|
||||
// Print the result.
|
||||
this->instructions.push_back(instruction(base_opcode::opImm)
|
||||
.i(x_register::a1, funct3_t::addi, x_register::a0, 0));
|
||||
|
||||
auto format_string = write_read_only(reinterpret_cast<const std::byte *>("%d\n\0"), 4);
|
||||
|
||||
this->references.push_back(reference());
|
||||
this->references.back().name = format_string;
|
||||
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 = format_string;
|
||||
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));
|
||||
.i(x_register::ra, funct3_t::jalr, x_register::ra, -instructions.size() * 4 - 40));
|
||||
}
|
||||
|
||||
void visitor::visit(source::question_mark_statement *statement)
|
||||
@ -171,23 +197,23 @@ namespace elna::riscv
|
||||
this->instructions.push_back(instruction(base_opcode::opImm)
|
||||
.i(x_register::a1, funct3_t::addi, x_register::a0, 0));
|
||||
|
||||
auto format_string = write_read_only(reinterpret_cast<const std::byte *>("%d\n\0"), 4);
|
||||
auto format_string = this->writer->sink(reinterpret_cast<const std::byte *>("%d\n\0"), 4);
|
||||
|
||||
this->references.push_back(reference());
|
||||
this->references.back().name = format_string;
|
||||
this->references.back().offset = instructions.size() * 4;
|
||||
this->references.back().offset = writer->size() + 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 = format_string;
|
||||
this->references.back().offset = instructions.size() * 4;
|
||||
this->references.back().offset = writer->size() + 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().offset = writer->size() + 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)
|
||||
@ -224,7 +250,7 @@ namespace elna::riscv
|
||||
instructions.push_back(instruction(base_opcode::branch));
|
||||
statement->body().accept(this);
|
||||
instructions[before_branch]
|
||||
.b((instructions.size() - before_branch) * 4 - 3, 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)
|
||||
|
Reference in New Issue
Block a user