aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--riscv/csrs.cc4
-rw-r--r--riscv/dts.cc4
-rw-r--r--riscv/insns/vmv_x_s.h4
-rw-r--r--riscv/interactive.cc8
-rw-r--r--riscv/processor.cc27
-rw-r--r--riscv/processor.h17
-rw-r--r--riscv/sim.cc5
-rw-r--r--riscv/sim.h1
-rw-r--r--spike_main/spike-log-parser.cc7
9 files changed, 46 insertions, 31 deletions
diff --git a/riscv/csrs.cc b/riscv/csrs.cc
index 44fd959..5e8c0ba 100644
--- a/riscv/csrs.cc
+++ b/riscv/csrs.cc
@@ -304,8 +304,8 @@ reg_t cause_csr_t::read() const noexcept {
// When reading, the interrupt bit needs to adjust to xlen. Spike does
// not generally support dynamic xlen, but this code was (partly)
// there since at least 2015 (ea58df8 and c4350ef).
- if (proc->get_max_xlen() > proc->get_xlen()) // Move interrupt bit to top of xlen
- return val | ((val >> (proc->get_max_xlen()-1)) << (proc->get_xlen()-1));
+ if (proc->get_isa().get_max_xlen() > proc->get_xlen()) // Move interrupt bit to top of xlen
+ return val | ((val >> (proc->get_isa().get_max_xlen()-1)) << (proc->get_xlen()-1));
return val;
}
diff --git a/riscv/dts.cc b/riscv/dts.cc
index 09accf9..c86fc2f 100644
--- a/riscv/dts.cc
+++ b/riscv/dts.cc
@@ -55,8 +55,8 @@ std::string make_dts(size_t insns_per_rtc_tick, size_t cpu_hz,
" reg = <" << i << ">;\n"
" status = \"okay\";\n"
" compatible = \"riscv\";\n"
- " riscv,isa = \"" << procs[i]->get_isa_string() << "\";\n"
- " mmu-type = \"riscv," << (procs[i]->get_max_xlen() <= 32 ? "sv32" : "sv48") << "\";\n"
+ " riscv,isa = \"" << procs[i]->get_isa().get_isa_string() << "\";\n"
+ " mmu-type = \"riscv," << (procs[i]->get_isa().get_max_xlen() <= 32 ? "sv32" : "sv48") << "\";\n"
" riscv,pmpregions = <16>;\n"
" riscv,pmpgranularity = <4>;\n"
" clock-frequency = <" << cpu_hz << ">;\n"
diff --git a/riscv/insns/vmv_x_s.h b/riscv/insns/vmv_x_s.h
index 39752f9..f0e805b 100644
--- a/riscv/insns/vmv_x_s.h
+++ b/riscv/insns/vmv_x_s.h
@@ -1,7 +1,7 @@
// vmv_x_s: rd = vs2[rs1]
require_vector(true);
require(insn.v_vm() == 1);
-uint64_t xmask = UINT64_MAX >> (64 - P.get_max_xlen());
+uint64_t xmask = UINT64_MAX >> (64 - P.get_isa().get_max_xlen());
reg_t rs1 = RS1;
reg_t sew = P.VU.vsew;
reg_t rs2_num = insn.rs2();
@@ -20,7 +20,7 @@ if (!(rs1 >= 0 && rs1 < (P.VU.get_vlen() / sew))) {
WRITE_RD(P.VU.elt<int32_t>(rs2_num, rs1));
break;
case e64:
- if (P.get_max_xlen() <= sew)
+ if (P.get_isa().get_max_xlen() <= sew)
WRITE_RD(P.VU.elt<uint64_t>(rs2_num, rs1) & xmask);
else
WRITE_RD(P.VU.elt<uint64_t>(rs2_num, rs1));
diff --git a/riscv/interactive.cc b/riscv/interactive.cc
index 172cd33..88eb86b 100644
--- a/riscv/interactive.cc
+++ b/riscv/interactive.cc
@@ -273,7 +273,7 @@ void sim_t::interactive_pc(const std::string& cmd, const std::vector<std::string
throw trap_interactive();
processor_t *p = get_core(args[0]);
- int max_xlen = p->get_max_xlen();
+ int max_xlen = p->get_isa().get_max_xlen();
std::ostream out(sout_.rdbuf());
out << std::hex << std::setfill('0') << "0x" << std::setw(max_xlen/4)
@@ -379,7 +379,7 @@ void sim_t::interactive_reg(const std::string& cmd, const std::vector<std::strin
throw trap_interactive();
processor_t *p = get_core(args[0]);
- int max_xlen = p->get_max_xlen();
+ int max_xlen = p->get_isa().get_max_xlen();
std::ostream out(sout_.rdbuf());
out << std::hex;
@@ -481,7 +481,7 @@ reg_t sim_t::get_mem(const std::vector<std::string>& args)
void sim_t::interactive_mem(const std::string& cmd, const std::vector<std::string>& args)
{
- int max_xlen = procs[0]->get_max_xlen();
+ int max_xlen = procs[0]->get_isa().get_max_xlen();
std::ostream out(sout_.rdbuf());
out << std::hex << "0x" << std::setfill('0') << std::setw(max_xlen/4)
@@ -541,7 +541,7 @@ void sim_t::interactive_until(const std::string& cmd, const std::vector<std::str
throw trap_interactive();
// mask bits above max_xlen
- int max_xlen = procs[strtol(args[1].c_str(),NULL,10)]->get_max_xlen();
+ int max_xlen = procs[strtol(args[1].c_str(),NULL,10)]->get_isa().get_max_xlen();
if (max_xlen == 32) val &= 0xFFFFFFFF;
std::vector<std::string> args2;
diff --git a/riscv/processor.cc b/riscv/processor.cc
index 438c989..dfb85da 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -23,10 +23,10 @@
#undef STATE
#define STATE state
-processor_t::processor_t(const char* isa, const char* priv, const char* varch,
+processor_t::processor_t(isa_parser_t isa, const char* varch,
simif_t* sim, uint32_t id, bool halt_on_reset,
FILE* log_file, std::ostream& sout_)
- : isa_parser_t(isa, priv), debug(false), halt_request(HR_NONE), sim(sim), id(id), xlen(0),
+ : debug(false), halt_request(HR_NONE), isa(isa), sim(sim), id(id), xlen(0),
histogram_enabled(false), log_commits_enabled(false),
log_file(log_file), sout_(sout_.rdbuf()), halt_on_reset(halt_on_reset),
impl_table(256, false), last_pc(1), executions(1)
@@ -45,16 +45,16 @@ processor_t::processor_t(const char* isa, const char* priv, const char* varch,
register_base_instructions();
mmu = new mmu_t(sim, this);
- disassembler = new disassembler_t(this);
- for (auto e : isa_extensions)
+ disassembler = new disassembler_t(&isa);
+ for (auto e : isa.get_extensions())
register_extension(e.second);
set_pmp_granularity(1 << PMP_SHIFT);
set_pmp_num(state.max_pmp);
- if (max_xlen == 32)
+ if (isa.get_max_xlen() == 32)
set_mmu_capability(IMPL_MMU_SV32);
- else if (max_xlen == 64)
+ else if (isa.get_max_xlen() == 64)
set_mmu_capability(IMPL_MMU_SV48);
reset();
@@ -355,7 +355,7 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv)
bad_isa_string(str, "single 'X' is not a proper name");
} else if (ext_str != "xdummy") {
extension_t* x = find_extension(ext_str.substr(1).c_str())();
- if (!isa_extensions.insert(std::make_pair(x->name(), x)).second) {
+ if (!extensions.insert(std::make_pair(x->name(), x)).second) {
fprintf(stderr, "extensions must have unique names (got two named \"%s\"!)\n", x->name());
abort();
}
@@ -411,7 +411,7 @@ void state_t::reset(processor_t* const proc, reg_t max_isa)
// This assumes xlen is always max_xlen, which is true today (see
// mstatus_csr_t::unlogged_write()):
- auto xlen = proc->get_max_xlen();
+ auto xlen = proc->get_isa().get_max_xlen();
prv = PRV_M;
v = false;
@@ -716,8 +716,8 @@ void processor_t::enable_log_commits()
void processor_t::reset()
{
- xlen = max_xlen;
- state.reset(this, max_isa);
+ xlen = isa.get_max_xlen();
+ state.reset(this, isa.get_max_isa());
state.dcsr->halt = halt_on_reset;
halt_on_reset = false;
VU.reset();
@@ -852,7 +852,7 @@ void processor_t::take_interrupt(reg_t pending_interrupts)
else
abort();
- throw trap_t(((reg_t)1 << (max_xlen-1)) | ctz(enabled_interrupts));
+ throw trap_t(((reg_t)1 << (isa.get_max_xlen()-1)) | ctz(enabled_interrupts));
}
}
@@ -916,6 +916,8 @@ void processor_t::debug_output_log(std::stringstream *s)
void processor_t::take_trap(trap_t& t, reg_t epc)
{
+ unsigned max_xlen = isa.get_max_xlen();
+
if (debug) {
std::stringstream s; // first put everything in a string, later send it to output
s << "core " << std::dec << std::setfill(' ') << std::setw(3) << id
@@ -1039,6 +1041,8 @@ void processor_t::disasm(insn_t insn)
<< ": Executed " << executions << " times" << std::endl;
}
+ unsigned max_xlen = isa.get_max_xlen();
+
s << "core " << std::dec << std::setfill(' ') << std::setw(3) << id
<< std::hex << ": 0x" << std::setfill('0') << std::setw(max_xlen/4)
<< zext(state.pc, max_xlen) << " (0x" << std::setw(8) << bits << ") "
@@ -1056,6 +1060,7 @@ void processor_t::disasm(insn_t insn)
int processor_t::paddr_bits()
{
+ unsigned max_xlen = isa.get_max_xlen();
assert(xlen == max_xlen);
return max_xlen == 64 ? 50 : 34;
}
diff --git a/riscv/processor.h b/riscv/processor.h
index 2fe5ede..3e9a743 100644
--- a/riscv/processor.h
+++ b/riscv/processor.h
@@ -322,23 +322,28 @@ public:
else
return extension_table[ext];
}
+ const std::unordered_map<std::string, extension_t*> &
+ get_extensions() const { return extensions; }
+
protected:
unsigned max_xlen;
reg_t max_isa;
std::vector<bool> extension_table;
std::string isa_string;
- std::unordered_map<std::string, extension_t*> isa_extensions;
+ std::unordered_map<std::string, extension_t*> extensions;
};
// this class represents one processor in a RISC-V machine.
-class processor_t : public abstract_device_t, public isa_parser_t
+class processor_t : public abstract_device_t
{
public:
- processor_t(const char* isa, const char* priv, const char* varch,
+ processor_t(isa_parser_t isa, const char* varch,
simif_t* sim, uint32_t id, bool halt_on_reset,
FILE *log_file, std::ostream& sout_); // because of command line option --log and -s we need both
~processor_t();
+ const isa_parser_t &get_isa() { return isa; }
+
void set_debug(bool value);
void set_histogram(bool value);
#ifdef RISCV_ENABLE_COMMITLOG
@@ -374,7 +379,7 @@ public:
if (ext >= 'A' && ext <= 'Z')
return state.misa->extension_enabled(ext);
else
- return extension_table[ext];
+ return isa.extension_enabled(ext);
}
// Is this extension enabled? and abort if this extension can
// possibly be disabled dynamically. Useful for documenting
@@ -383,7 +388,7 @@ public:
if (ext >= 'A' && ext <= 'Z')
return state.misa->extension_enabled_const(ext);
else
- return extension_table[ext]; // assume this can't change
+ return isa.extension_enabled(ext); // assume this can't change
}
void set_impl(uint8_t impl, bool val) { impl_table[impl] = val; }
bool supports_impl(uint8_t impl) const {
@@ -512,6 +517,8 @@ public:
const char* get_symbol(uint64_t addr);
private:
+ isa_parser_t isa;
+
simif_t* sim;
mmu_t* mmu; // main memory is always accessed via the mmu
std::unordered_map<std::string, extension_t*> custom_extensions;
diff --git a/riscv/sim.cc b/riscv/sim.cc
index 8648d5a..064a493 100644
--- a/riscv/sim.cc
+++ b/riscv/sim.cc
@@ -28,7 +28,7 @@ static void handle_signal(int sig)
signal(sig, &handle_signal);
}
-sim_t::sim_t(const char* isa, const char* priv, const char* varch,
+sim_t::sim_t(const char* isa_string, const char* priv, const char* varch,
size_t nprocs, bool halted, bool real_time_clint,
reg_t initrd_start, reg_t initrd_end, const char* bootargs,
reg_t start_pc, std::vector<std::pair<reg_t, mem_t*>> mems,
@@ -43,6 +43,7 @@ sim_t::sim_t(const char* isa, const char* priv, const char* varch,
#endif
FILE *cmd_file) // needed for command line option --cmd
: htif_t(args),
+ isa(isa_string, priv),
mems(mems),
plugin_devices(plugin_devices),
procs(std::max(nprocs, size_t(1))),
@@ -91,7 +92,7 @@ sim_t::sim_t(const char* isa, const char* priv, const char* varch,
for (size_t i = 0; i < nprocs; i++) {
int hart_id = hartids.empty() ? i : hartids[i];
- procs[i] = new processor_t(isa, priv, varch, this, hart_id, halted,
+ procs[i] = new processor_t(isa, varch, this, hart_id, halted,
log_file.get(), sout_);
}
diff --git a/riscv/sim.h b/riscv/sim.h
index a425da4..518d75e 100644
--- a/riscv/sim.h
+++ b/riscv/sim.h
@@ -70,6 +70,7 @@ public:
void proc_reset(unsigned id);
private:
+ isa_parser_t isa;
std::vector<std::pair<reg_t, mem_t*>> mems;
std::vector<std::pair<reg_t, abstract_device_t*>> plugin_devices;
mmu_t* debug_mmu; // debug port into main memory
diff --git a/spike_main/spike-log-parser.cc b/spike_main/spike-log-parser.cc
index 9481fb4..0a4442f 100644
--- a/spike_main/spike-log-parser.cc
+++ b/spike_main/spike-log-parser.cc
@@ -19,15 +19,16 @@ using namespace std;
int main(int argc, char** argv)
{
string s;
- const char* isa = DEFAULT_ISA;
+ const char* isa_string = DEFAULT_ISA;
std::function<extension_t*()> extension;
option_parser_t parser;
parser.option(0, "extension", 1, [&](const char* s){extension = find_extension(s);});
- parser.option(0, "isa", 1, [&](const char* s){isa = s;});
+ parser.option(0, "isa", 1, [&](const char* s){isa_string = s;});
parser.parse(argv);
- processor_t p(isa, DEFAULT_PRIV, DEFAULT_VARCH, 0, 0, false, nullptr, cerr);
+ isa_parser_t isa(isa_string, DEFAULT_PRIV);
+ processor_t p(isa, DEFAULT_VARCH, 0, 0, false, nullptr, cerr);
if (extension) {
p.register_extension(extension());
}