mirror of
https://github.com/riscv-software-src/riscv-isa-sim.git
synced 2025-10-14 02:07:30 +08:00
refactor: make extensions accept processor as an argument
This commit is contained in:
@@ -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 {};
|
||||
}
|
||||
|
||||
|
@@ -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}));
|
||||
|
@@ -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}));
|
||||
|
@@ -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]
|
||||
|
@@ -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) {}
|
||||
|
@@ -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);
|
||||
|
@@ -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()
|
||||
|
@@ -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;
|
||||
|
12
riscv/rocc.h
12
riscv/rocc.h
@@ -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) \
|
||||
|
Reference in New Issue
Block a user