refactor: make extensions accept processor as an argument

This commit is contained in:
Alexander Romanov
2025-04-07 16:29:23 +03:00
parent c1c0b8b18c
commit 69ae3a866c
9 changed files with 42 additions and 52 deletions

View File

@@ -20,15 +20,15 @@ class dummycsr_t: public csr_t {
// dummy extension with dummy CSRs. Nice.
struct xdummycsr_t : public extension_t {
const char *name() { return "dummycsr"; }
const char *name() const override { return "dummycsr"; }
xdummycsr_t() {}
std::vector<insn_desc_t> get_instructions() override {
std::vector<insn_desc_t> get_instructions(const processor_t &) override {
return {};
}
std::vector<disasm_insn_t *> get_disasms() override {
std::vector<disasm_insn_t *> get_disasms(const processor_t *) override {
return {};
}

View File

@@ -26,11 +26,11 @@ static reg_t do_nop4([[maybe_unused]] processor_t *p,
// dummy extension that uses the same prefix as standard zba extension
struct xslliuw_dummy_t : public extension_t {
const char *name() { return "dummyslliuw"; }
const char *name() const { return "dummyslliuw"; }
xslliuw_dummy_t() {}
std::vector<insn_desc_t> get_instructions() {
std::vector<insn_desc_t> get_instructions(const processor_t &) {
std::vector<insn_desc_t> insns;
insns.push_back(insn_desc_t{MATCH_SLLI_UW, MASK_SLLI_UW, do_nop4, do_nop4,
do_nop4, do_nop4, do_nop4, do_nop4, do_nop4,
@@ -38,7 +38,7 @@ struct xslliuw_dummy_t : public extension_t {
return insns;
}
std::vector<disasm_insn_t *> get_disasms() {
std::vector<disasm_insn_t *> get_disasms(const processor_t *) {
std::vector<disasm_insn_t *> insns;
insns.push_back(new disasm_insn_t("dummy_slliuw", MATCH_SLLI_UW,
MASK_SLLI_UW, {&xrd, &xrs1, &shamt}));

View File

@@ -19,11 +19,11 @@ static reg_t custom_cflush(processor_t* p, insn_t insn, reg_t pc)
class cflush_t : public extension_t
{
public:
const char* name() { return "cflush"; }
const char* name() const { return "cflush"; }
cflush_t() {}
std::vector<insn_desc_t> get_instructions() {
std::vector<insn_desc_t> get_instructions(const processor_t &) override {
std::vector<insn_desc_t> insns;
insns.push_back((insn_desc_t){0xFC000073, 0xFFF07FFF, custom_cflush, custom_cflush, custom_cflush, custom_cflush, custom_cflush, custom_cflush, custom_cflush, custom_cflush});
insns.push_back((insn_desc_t){0xFC200073, 0xFFF07FFF, custom_cflush, custom_cflush, custom_cflush, custom_cflush, custom_cflush, custom_cflush, custom_cflush, custom_cflush});
@@ -31,7 +31,7 @@ class cflush_t : public extension_t
return insns;
}
std::vector<disasm_insn_t*> get_disasms() {
std::vector<disasm_insn_t *> get_disasms(const processor_t *) override {
std::vector<disasm_insn_t*> insns;
insns.push_back(new disasm_insn_t("cflush.d.l1", 0xFC000073, 0xFFF07FFF, {&xrs1}));
insns.push_back(new disasm_insn_t("cdiscard.d.l1", 0xFC200073, 0xFFF07FFF, {&xrs1}));

View File

@@ -5,14 +5,14 @@
class dummy_rocc_t : public rocc_t
{
public:
const char* name() { return "dummy_rocc"; }
const char* name() const { return "dummy_rocc"; }
reg_t custom0(rocc_insn_t insn, reg_t xs1, reg_t UNUSED xs2)
reg_t custom0(processor_t *p, rocc_insn_t insn, reg_t xs1, reg_t UNUSED xs2)
{
reg_t prev_acc = acc[insn.rs2];
if (insn.rs2 >= num_acc)
illegal_instruction();
illegal_instruction(*p);
switch (insn.funct)
{
@@ -28,7 +28,7 @@ class dummy_rocc_t : public rocc_t
acc[insn.rs2] += xs1;
break;
default:
illegal_instruction();
illegal_instruction(*p);
}
return prev_acc; // in all cases, xd <- previous value of acc[rs2]

View File

@@ -3,21 +3,15 @@
#include "extension.h"
#include "trap.h"
extension_t::~extension_t()
{
}
void extension_t::illegal_instruction()
void extension_t::illegal_instruction([[maybe_unused]] processor_t &proc)
{
throw trap_illegal_instruction(0);
}
void extension_t::raise_interrupt()
void extension_t::raise_interrupt([[maybe_unused]] processor_t &proc)
{
p->take_interrupt((reg_t)1 << IRQ_COP); // must not return
proc.take_interrupt((reg_t)1 << IRQ_COP); // must not return
throw std::logic_error("a COP exception was posted, but interrupts are disabled!");
}
void extension_t::clear_interrupt()
{
}
void extension_t::clear_interrupt([[maybe_unused]] processor_t &proc) {}

View File

@@ -11,21 +11,18 @@
class extension_t
{
public:
virtual std::vector<insn_desc_t> get_instructions() = 0;
virtual std::vector<disasm_insn_t*> get_disasms() = 0;
virtual std::vector<csr_t_p> get_csrs ([[maybe_unused]] processor_t &proc) const { return {}; };
virtual const char* name() = 0;
virtual void reset() {};
virtual void set_debug(bool UNUSED value) {}
virtual ~extension_t();
virtual std::vector<insn_desc_t> get_instructions(const processor_t &proc) = 0;
virtual std::vector<disasm_insn_t*> get_disasms(const processor_t *proc = nullptr) = 0;
virtual std::vector<csr_t_p> get_csrs(processor_t &) const { return {}; };
virtual const char* name() const = 0;
virtual void reset(processor_t &) {};
virtual void set_debug(bool UNUSED value, const processor_t &) {}
virtual ~extension_t() = default;
void set_processor(processor_t* _p) { p = _p; }
protected:
processor_t* p;
void illegal_instruction();
void raise_interrupt();
void clear_interrupt();
void illegal_instruction(processor_t &proc);
void raise_interrupt(processor_t &proc);
void clear_interrupt(processor_t &proc);
};
std::function<extension_t*()> find_extension(const char* name);

View File

@@ -169,7 +169,7 @@ void processor_t::set_debug(bool value)
debug = value;
for (auto e : custom_extensions)
e.second->set_debug(value);
e.second->set_debug(value, *this);
}
void processor_t::set_histogram(bool value)
@@ -200,7 +200,7 @@ void processor_t::reset()
for (auto e : custom_extensions) { // reset any extensions
for (auto &csr: e.second->get_csrs(*this))
state.add_csr(csr->address, csr);
e.second->reset();
e.second->reset(*this);
}
if (sim)
@@ -703,18 +703,17 @@ void processor_t::build_opcode_map()
}
void processor_t::register_extension(extension_t *x) {
for (auto insn : x->get_instructions())
for (auto insn : x->get_instructions(*this))
register_custom_insn(insn);
build_opcode_map();
for (auto disasm_insn : x->get_disasms())
for (auto disasm_insn : x->get_disasms(this))
disassembler->add_insn(disasm_insn);
if (!custom_extensions.insert(std::make_pair(x->name(), x)).second) {
fprintf(stderr, "extensions must have unique names (got two named \"%s\"!)\n", x->name());
abort();
}
x->set_processor(this);
}
void processor_t::register_base_instructions()

View File

@@ -14,15 +14,15 @@
u.i = insn; \
reg_t xs1 = u.r.xs1 ? RS1 : -1; \
reg_t xs2 = u.r.xs2 ? RS2 : -1; \
reg_t xd = rocc->custom##n(u.r, xs1, xs2); \
reg_t xd = rocc->custom##n(p, u.r, xs1, xs2); \
if (u.r.xd) \
WRITE_RD(xd); \
return pc+4; \
} \
\
reg_t rocc_t::custom##n(rocc_insn_t UNUSED insn, reg_t UNUSED xs1, reg_t UNUSED xs2) \
reg_t rocc_t::custom##n(processor_t *p, rocc_insn_t UNUSED insn, reg_t UNUSED xs1, reg_t UNUSED xs2) \
{ \
illegal_instruction(); \
illegal_instruction(*p); \
return 0; \
}
@@ -31,7 +31,7 @@ customX(1)
customX(2)
customX(3)
std::vector<insn_desc_t> rocc_t::get_instructions()
std::vector<insn_desc_t> rocc_t::get_instructions(const processor_t &)
{
std::vector<insn_desc_t> insns;
insns.push_back((insn_desc_t){0x0b, 0x7f,
@@ -49,7 +49,7 @@ std::vector<insn_desc_t> rocc_t::get_instructions()
return insns;
}
std::vector<disasm_insn_t*> rocc_t::get_disasms()
std::vector<disasm_insn_t *> rocc_t::get_disasms(const processor_t *)
{
std::vector<disasm_insn_t*> insns;
return insns;

View File

@@ -24,12 +24,12 @@ union rocc_insn_union_t
class rocc_t : public extension_t
{
public:
virtual reg_t custom0(rocc_insn_t insn, reg_t xs1, reg_t xs2);
virtual reg_t custom1(rocc_insn_t insn, reg_t xs1, reg_t xs2);
virtual reg_t custom2(rocc_insn_t insn, reg_t xs1, reg_t xs2);
virtual reg_t custom3(rocc_insn_t insn, reg_t xs1, reg_t xs2);
std::vector<insn_desc_t> get_instructions();
std::vector<disasm_insn_t*> get_disasms();
virtual reg_t custom0(processor_t *, rocc_insn_t insn, reg_t xs1, reg_t xs2);
virtual reg_t custom1(processor_t *, rocc_insn_t insn, reg_t xs1, reg_t xs2);
virtual reg_t custom2(processor_t *, rocc_insn_t insn, reg_t xs1, reg_t xs2);
virtual reg_t custom3(processor_t *, rocc_insn_t insn, reg_t xs1, reg_t xs2);
std::vector<insn_desc_t> get_instructions(const processor_t &proc) override;
std::vector<disasm_insn_t *> get_disasms(const processor_t *proc = nullptr) override;
};
#define define_custom_func(type_name, ext_name_str, func_name, method_name) \