aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--riscv/processor.cc28
-rw-r--r--riscv/processor.h29
-rw-r--r--spike_dasm/spike-dasm.cc17
-rw-r--r--spike_dasm/spike_dasm.mk.in1
4 files changed, 37 insertions, 38 deletions
diff --git a/riscv/processor.cc b/riscv/processor.cc
index 920792f..65879f9 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -26,14 +26,13 @@
processor_t::processor_t(const char* isa, const char* priv, const char* varch,
simif_t* sim, uint32_t id, bool halt_on_reset,
FILE* log_file, std::ostream& sout_)
- : debug(false), halt_request(HR_NONE), sim(sim), id(id), xlen(0),
+ : isa_parser_t(isa), debug(false), halt_request(HR_NONE), 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),
- extension_table(256, false), impl_table(256, false), last_pc(1), executions(1)
+ impl_table(256, false), last_pc(1), executions(1)
{
VU.p = this;
- parse_isa_string(isa);
parse_priv_string(priv);
parse_varch_string(varch);
@@ -42,8 +41,7 @@ processor_t::processor_t(const char* isa, const char* priv, const char* varch,
disassembler = new disassembler_t(max_xlen);
for (auto e : custom_extensions)
- for (auto disasm_insn : e.second->get_disasms())
- disassembler->add_insn(disasm_insn);
+ register_extension(e.second);
set_pmp_granularity(1 << PMP_SHIFT);
set_pmp_num(state.max_pmp);
@@ -195,7 +193,8 @@ void processor_t::parse_priv_string(const char* str)
}
}
-void processor_t::parse_isa_string(const char* str)
+isa_parser_t::isa_parser_t(const char* str)
+ : extension_table(256, false)
{
isa_string = strtolower(str);
const char* all_subsets = "mafdqchp"
@@ -344,7 +343,12 @@ void processor_t::parse_isa_string(const char* str)
} else if (ext_str.size() == 1) {
bad_isa_string(str, "single 'X' is not a proper name");
} else if (ext_str != "xdummy") {
- register_extension(find_extension(ext_str.substr(1).c_str())());
+ extension_t* x = find_extension(ext_str.substr(1).c_str())();
+ 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();
+ }
+
}
} else {
bad_isa_string(str, ("unsupported extension: " + ext_str).c_str());
@@ -1095,14 +1099,8 @@ void processor_t::register_extension(extension_t* x)
register_insn(insn);
build_opcode_map();
- if (disassembler)
- for (auto disasm_insn : x->get_disasms())
- 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();
- }
+ for (auto disasm_insn : x->get_disasms())
+ disassembler->add_insn(disasm_insn);
x->set_processor(this);
}
diff --git a/riscv/processor.h b/riscv/processor.h
index 35f8afc..5d5f51b 100644
--- a/riscv/processor.h
+++ b/riscv/processor.h
@@ -288,8 +288,28 @@ static int cto(reg_t val)
return res;
}
+class isa_parser_t {
+public:
+ isa_parser_t(const char* str);
+ ~isa_parser_t(){};
+ unsigned get_max_xlen() { return max_xlen; }
+ std::string get_isa_string() { return isa_string; }
+ bool extension_enabled(unsigned char ext) const {
+ if (ext >= 'A' && ext <= 'Z')
+ return (max_isa >> (ext - 'A')) & 1;
+ else
+ return extension_table[ext];
+ }
+protected:
+ unsigned max_xlen;
+ reg_t max_isa;
+ std::vector<bool> extension_table;
+ std::string isa_string;
+ std::unordered_map<std::string, extension_t*> custom_extensions;
+};
+
// this class represents one processor in a RISC-V machine.
-class processor_t : public abstract_device_t
+class processor_t : public abstract_device_t, public isa_parser_t
{
public:
processor_t(const char* isa, const char* priv, const char* varch,
@@ -318,8 +338,6 @@ public:
// variable xlen, this method should be removed.
return xlen;
}
- unsigned get_max_xlen() { return max_xlen; }
- std::string get_isa_string() { return isa_string; }
unsigned get_flen() {
return extension_enabled('Q') ? 128 :
extension_enabled('D') ? 64 :
@@ -478,16 +496,12 @@ private:
disassembler_t* disassembler;
state_t state;
uint32_t id;
- unsigned max_xlen;
unsigned xlen;
- reg_t max_isa;
- std::string isa_string;
bool histogram_enabled;
bool log_commits_enabled;
FILE *log_file;
std::ostream sout_; // needed for socket command interface -s, also used for -d and -l, but not for --log
bool halt_on_reset;
- std::vector<bool> extension_table;
std::vector<bool> impl_table;
std::vector<insn_desc_t> instructions;
@@ -512,7 +526,6 @@ private:
void parse_varch_string(const char*);
void parse_priv_string(const char*);
- void parse_isa_string(const char*);
void build_opcode_map();
void register_base_instructions();
insn_func_t decode_insn(insn_t insn);
diff --git a/spike_dasm/spike-dasm.cc b/spike_dasm/spike-dasm.cc
index fa6a25a..d40ac5d 100644
--- a/spike_dasm/spike-dasm.cc
+++ b/spike_dasm/spike-dasm.cc
@@ -27,21 +27,8 @@ int main(int argc, char** argv)
parser.option(0, "isa", 1, [&](const char* s){isa = s;});
parser.parse(argv);
- std::string lowercase;
- for (const char *p = isa; *p; p++)
- lowercase += std::tolower(*p);
-
- int xlen;
- if (lowercase.compare(0, 4, "rv32") == 0) {
- xlen = 32;
- } else if (lowercase.compare(0, 4, "rv64") == 0) {
- xlen = 64;
- } else {
- fprintf(stderr, "bad ISA string: %s\n", isa);
- return 1;
- }
-
- disassembler_t* disassembler = new disassembler_t(xlen);
+ isa_parser_t isa_parser(isa);
+ disassembler_t* disassembler = new disassembler_t(isa_parser.get_max_xlen());
if (extension) {
for (auto disasm_insn : extension()->get_disasms()) {
disassembler->add_insn(disasm_insn);
diff --git a/spike_dasm/spike_dasm.mk.in b/spike_dasm/spike_dasm.mk.in
index b6118fd..0233e62 100644
--- a/spike_dasm/spike_dasm.mk.in
+++ b/spike_dasm/spike_dasm.mk.in
@@ -1,5 +1,6 @@
spike_dasm_subproject_deps = \
disasm \
+ softfloat \
$(if $(HAVE_DLOPEN),riscv,) \
spike_dasm_srcs = \