aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRupert Swarbrick <rswarbrick@gmail.com>2022-03-29 20:21:21 +0100
committerGitHub <noreply@github.com>2022-03-29 12:21:21 -0700
commitcd2bc70a5d010161588f3cebcd2891514337e059 (patch)
treeb2f666466fca5527f687bd7b86061d3ba7429cb8
parent9a43019bfff59da7c42f1a95c636dd5ff5ec7f32 (diff)
downloadspike-cd2bc70a5d010161588f3cebcd2891514337e059.zip
spike-cd2bc70a5d010161588f3cebcd2891514337e059.tar.gz
spike-cd2bc70a5d010161588f3cebcd2891514337e059.tar.bz2
Split isa_parser_t out of processor.* and into its own file (#955)
The main motivation for this is that we want to move the ISA parsing logic to run before we even construct a simulator. That's probably a bit nicer if we don't depend on the processor header. It also means that we can stop depending on processor.h in disasm.cc or spike_log_parser.cc (both through disasm.h), which feels a bit cleaner: making sense of an instruction trace shouldn't really require knowledge of the internal state of a processor.
-rw-r--r--riscv/disasm.h2
-rw-r--r--riscv/isa_parser.cc246
-rw-r--r--riscv/isa_parser.h87
-rw-r--r--riscv/processor.cc229
-rw-r--r--riscv/processor.h75
-rw-r--r--riscv/riscv.mk.in1
6 files changed, 336 insertions, 304 deletions
diff --git a/riscv/disasm.h b/riscv/disasm.h
index ce844d6..338cac2 100644
--- a/riscv/disasm.h
+++ b/riscv/disasm.h
@@ -4,7 +4,7 @@
#define _RISCV_DISASM_H
#include "decode.h"
-#include "processor.h"
+#include "isa_parser.h"
#include <string>
#include <sstream>
#include <algorithm>
diff --git a/riscv/isa_parser.cc b/riscv/isa_parser.cc
new file mode 100644
index 0000000..766aa3a
--- /dev/null
+++ b/riscv/isa_parser.cc
@@ -0,0 +1,246 @@
+#include "isa_parser.h"
+#include "extension.h"
+
+static std::string strtolower(const char* str)
+{
+ std::string res;
+ for (const char *r = str; *r; r++)
+ res += std::tolower(*r);
+ return res;
+}
+
+static void bad_option_string(const char *option, const char *value,
+ const char *msg)
+{
+ fprintf(stderr, "error: bad %s option '%s'. %s\n", option, value, msg);
+ abort();
+}
+
+static void bad_isa_string(const char* isa, const char* msg)
+{
+ bad_option_string("--isa", isa, msg);
+}
+
+static void bad_priv_string(const char* priv)
+{
+ fprintf(stderr, "error: bad --priv option %s\n", priv);
+ abort();
+}
+
+isa_parser_t::isa_parser_t(const char* str, const char *priv)
+ : extension_table(256, false)
+{
+ isa_string = strtolower(str);
+ const char* all_subsets = "mafdqchpv";
+
+ max_isa = reg_t(2) << 62;
+ // enable zicntr and zihpm unconditionally for backward compatibility
+ extension_table[EXT_ZICNTR] = true;
+ extension_table[EXT_ZIHPM] = true;
+
+ if (isa_string.compare(0, 4, "rv32") == 0)
+ max_xlen = 32, max_isa = reg_t(1) << 30;
+ else if (isa_string.compare(0, 4, "rv64") == 0)
+ max_xlen = 64;
+ else
+ bad_isa_string(str, "ISA strings must begin with RV32 or RV64");
+
+ switch (isa_string[4]) {
+ case 'g':
+ // G = IMAFD_Zicsr_Zifencei, but Spike includes the latter two
+ // unconditionally, so they need not be explicitly added here.
+ isa_string = isa_string.substr(0, 4) + "imafd" + isa_string.substr(5);
+ // Fall through
+ case 'i':
+ max_isa |= 1L << ('i' - 'a');
+ break;
+
+ case 'e':
+ max_isa |= 1L << ('e' - 'a');
+ break;
+
+ default:
+ bad_isa_string(str, ("'" + isa_string.substr(0, 4) + "' must be followed by I, E, or G").c_str());
+ }
+
+ const char* isa_str = isa_string.c_str();
+ auto p = isa_str, subset = all_subsets;
+ for (p += 5; islower(*p) && !strchr("zsx", *p); ++p) {
+ while (*subset && (*p != *subset))
+ ++subset;
+
+ if (!*subset) {
+ if (strchr(all_subsets, *p))
+ bad_isa_string(str, ("Extension '" + std::string(1, *p) + "' appears too late in ISA string").c_str());
+ else
+ bad_isa_string(str, ("Unsupported extension '" + std::string(1, *p) + "'").c_str());
+ }
+
+ switch (*p) {
+ case 'p': extension_table[EXT_ZBPBO] = true;
+ extension_table[EXT_ZPN] = true;
+ extension_table[EXT_ZPSFOPERAND] = true;
+ extension_table[EXT_ZMMUL] = true; break;
+ case 'q': max_isa |= 1L << ('d' - 'a');
+ // Fall through
+ case 'd': max_isa |= 1L << ('f' - 'a');
+ }
+ max_isa |= 1L << (*p - 'a');
+ extension_table[toupper(*p)] = true;
+ while (isdigit(*(p + 1))) {
+ ++p; // skip major version, point, and minor version if presented
+ if (*(p + 1) == 'p') ++p;
+ }
+ p += *(p + 1) == '_'; // underscores may be used to improve readability
+ }
+
+ while (islower(*p) || (*p == '_')) {
+ p += *p == '_'; // first underscore is optional
+ auto end = p;
+ do ++end; while (*end && *end != '_');
+ auto ext_str = std::string(p, end);
+ if (ext_str == "zfh" || ext_str == "zfhmin") {
+ if (!((max_isa >> ('f' - 'a')) & 1))
+ bad_isa_string(str, ("'" + ext_str + "' extension requires 'F'").c_str());
+ extension_table[EXT_ZFHMIN] = true;
+ if (ext_str == "zfh")
+ extension_table[EXT_ZFH] = true;
+ } else if (ext_str == "zicsr") {
+ // Spike necessarily has Zicsr, because
+ // Zicsr is implied by the privileged architecture
+ } else if (ext_str == "zifencei") {
+ // For compatibility with version 2.0 of the base ISAs, we
+ // unconditionally include FENCE.I, so Zifencei adds nothing more.
+ } else if (ext_str == "zihintpause") {
+ // HINTs encoded in base-ISA instructions are always present.
+ } else if (ext_str == "zmmul") {
+ extension_table[EXT_ZMMUL] = true;
+ } else if (ext_str == "zba") {
+ extension_table[EXT_ZBA] = true;
+ } else if (ext_str == "zbb") {
+ extension_table[EXT_ZBB] = true;
+ } else if (ext_str == "zbc") {
+ extension_table[EXT_ZBC] = true;
+ } else if (ext_str == "zbs") {
+ extension_table[EXT_ZBS] = true;
+ } else if (ext_str == "zbkb") {
+ extension_table[EXT_ZBKB] = true;
+ } else if (ext_str == "zbkc") {
+ extension_table[EXT_ZBKC] = true;
+ } else if (ext_str == "zbkx") {
+ extension_table[EXT_ZBKX] = true;
+ } else if (ext_str == "zk") {
+ extension_table[EXT_ZBKB] = true;
+ extension_table[EXT_ZBKC] = true;
+ extension_table[EXT_ZBKX] = true;
+ extension_table[EXT_ZKND] = true;
+ extension_table[EXT_ZKNE] = true;
+ extension_table[EXT_ZKNH] = true;
+ extension_table[EXT_ZKR] = true;
+ } else if (ext_str == "zkn") {
+ extension_table[EXT_ZBKB] = true;
+ extension_table[EXT_ZBKC] = true;
+ extension_table[EXT_ZBKX] = true;
+ extension_table[EXT_ZKND] = true;
+ extension_table[EXT_ZKNE] = true;
+ extension_table[EXT_ZKNH] = true;
+ } else if (ext_str == "zknd") {
+ extension_table[EXT_ZKND] = true;
+ } else if (ext_str == "zkne") {
+ extension_table[EXT_ZKNE] = true;
+ } else if (ext_str == "zknh") {
+ extension_table[EXT_ZKNH] = true;
+ } else if (ext_str == "zks") {
+ extension_table[EXT_ZBKB] = true;
+ extension_table[EXT_ZBKC] = true;
+ extension_table[EXT_ZBKX] = true;
+ extension_table[EXT_ZKSED] = true;
+ extension_table[EXT_ZKSH] = true;
+ } else if (ext_str == "zksed") {
+ extension_table[EXT_ZKSED] = true;
+ } else if (ext_str == "zksh") {
+ extension_table[EXT_ZKSH] = true;
+ } else if (ext_str == "zkr") {
+ extension_table[EXT_ZKR] = true;
+ } else if (ext_str == "zkt") {
+ } else if (ext_str == "svnapot") {
+ extension_table[EXT_SVNAPOT] = true;
+ } else if (ext_str == "svpbmt") {
+ extension_table[EXT_SVPBMT] = true;
+ } else if (ext_str == "svinval") {
+ extension_table[EXT_SVINVAL] = true;
+ } else if (ext_str == "zicbom") {
+ extension_table[EXT_ZICBOM] = true;
+ } else if (ext_str == "zicboz") {
+ extension_table[EXT_ZICBOZ] = true;
+ } else if (ext_str == "zicbop") {
+ } else if (ext_str == "zicntr") {
+ } else if (ext_str == "zihpm") {
+ } else if (ext_str[0] == 'x') {
+ max_isa |= 1L << ('x' - 'a');
+ extension_table[toupper('x')] = true;
+ if (ext_str == "xbitmanip") {
+ extension_table[EXT_XZBP] = true;
+ extension_table[EXT_XZBS] = true;
+ extension_table[EXT_XZBE] = true;
+ extension_table[EXT_XZBF] = true;
+ extension_table[EXT_XZBC] = true;
+ extension_table[EXT_XZBM] = true;
+ extension_table[EXT_XZBR] = true;
+ extension_table[EXT_XZBT] = true;
+ } else if (ext_str == "xzbp") {
+ extension_table[EXT_XZBP] = true;
+ } else if (ext_str == "xzbs") {
+ extension_table[EXT_XZBS] = true;
+ } else if (ext_str == "xzbe") {
+ extension_table[EXT_XZBE] = true;
+ } else if (ext_str == "xzbf") {
+ extension_table[EXT_XZBF] = true;
+ } else if (ext_str == "xzbc") {
+ extension_table[EXT_XZBC] = true;
+ } else if (ext_str == "xzbm") {
+ extension_table[EXT_XZBM] = true;
+ } else if (ext_str == "xzbr") {
+ extension_table[EXT_XZBR] = true;
+ } else if (ext_str == "xzbt") {
+ extension_table[EXT_XZBT] = true;
+ } else if (ext_str.size() == 1) {
+ 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 (!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());
+ }
+ p = end;
+ }
+ if (*p) {
+ bad_isa_string(str, ("can't parse: " + std::string(p)).c_str());
+ }
+
+ std::string lowercase = strtolower(priv);
+ bool user = false, supervisor = false;
+
+ if (lowercase == "m")
+ ;
+ else if (lowercase == "mu")
+ user = true;
+ else if (lowercase == "msu")
+ user = supervisor = true;
+ else
+ bad_priv_string(priv);
+
+ if (user) {
+ max_isa |= reg_t(user) << ('u' - 'a');
+ extension_table['U'] = true;
+ }
+
+ if (supervisor) {
+ max_isa |= reg_t(supervisor) << ('s' - 'a');
+ extension_table['S'] = true;
+ }
+}
diff --git a/riscv/isa_parser.h b/riscv/isa_parser.h
new file mode 100644
index 0000000..f32036c
--- /dev/null
+++ b/riscv/isa_parser.h
@@ -0,0 +1,87 @@
+// See LICENSE for license details.
+#ifndef _RISCV_ISA_PARSER_H
+#define _RISCV_ISA_PARSER_H
+
+#include "decode.h"
+
+#include <vector>
+#include <string>
+#include <unordered_map>
+
+class extension_t;
+
+typedef enum {
+ // 65('A') ~ 90('Z') is reserved for standard isa in misa
+ EXT_ZFH,
+ EXT_ZFHMIN,
+ EXT_ZBA,
+ EXT_ZBB,
+ EXT_ZBC,
+ EXT_ZBS,
+ EXT_ZBKB,
+ EXT_ZBKC,
+ EXT_ZBKX,
+ EXT_ZKND,
+ EXT_ZKNE,
+ EXT_ZKNH,
+ EXT_ZKSED,
+ EXT_ZKSH,
+ EXT_ZKR,
+ EXT_ZMMUL,
+ EXT_ZBPBO,
+ EXT_ZPN,
+ EXT_ZPSFOPERAND,
+ EXT_SVNAPOT,
+ EXT_SVPBMT,
+ EXT_SVINVAL,
+ EXT_ZDINX,
+ EXT_ZFINX,
+ EXT_ZHINX,
+ EXT_ZHINXMIN,
+ EXT_ZICBOM,
+ EXT_ZICBOZ,
+ EXT_ZICNTR,
+ EXT_ZIHPM,
+ EXT_XZBP,
+ EXT_XZBS,
+ EXT_XZBE,
+ EXT_XZBF,
+ EXT_XZBC,
+ EXT_XZBM,
+ EXT_XZBR,
+ EXT_XZBT,
+} isa_extension_t;
+
+typedef enum {
+ IMPL_MMU_SV32,
+ IMPL_MMU_SV39,
+ IMPL_MMU_SV48,
+ IMPL_MMU_SBARE,
+ IMPL_MMU,
+} impl_extension_t;
+
+class isa_parser_t {
+public:
+ isa_parser_t(const char* str, const char *priv);
+ ~isa_parser_t(){};
+ unsigned get_max_xlen() const { return max_xlen; }
+ reg_t get_max_isa() const { return max_isa; }
+ std::string get_isa_string() const { 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];
+ }
+ 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*> extensions;
+};
+
+#endif
diff --git a/riscv/processor.cc b/riscv/processor.cc
index dfb85da..e991afe 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -82,17 +82,6 @@ static void bad_option_string(const char *option, const char *value,
abort();
}
-static void bad_isa_string(const char* isa, const char* msg)
-{
- bad_option_string("--isa", isa, msg);
-}
-
-static void bad_priv_string(const char* priv)
-{
- fprintf(stderr, "error: bad --priv option %s\n", priv);
- abort();
-}
-
static void bad_varch_string(const char* varch, const char *msg)
{
bad_option_string("--varch", varch, msg);
@@ -174,224 +163,6 @@ void processor_t::parse_varch_string(const char* s)
VU.vstart_alu = vstart_alu;
}
-isa_parser_t::isa_parser_t(const char* str, const char *priv)
- : extension_table(256, false)
-{
- isa_string = strtolower(str);
- const char* all_subsets = "mafdqchpv";
-
- max_isa = reg_t(2) << 62;
- // enable zicntr and zihpm unconditionally for backward compatibility
- extension_table[EXT_ZICNTR] = true;
- extension_table[EXT_ZIHPM] = true;
-
- if (isa_string.compare(0, 4, "rv32") == 0)
- max_xlen = 32, max_isa = reg_t(1) << 30;
- else if (isa_string.compare(0, 4, "rv64") == 0)
- max_xlen = 64;
- else
- bad_isa_string(str, "ISA strings must begin with RV32 or RV64");
-
- switch (isa_string[4]) {
- case 'g':
- // G = IMAFD_Zicsr_Zifencei, but Spike includes the latter two
- // unconditionally, so they need not be explicitly added here.
- isa_string = isa_string.substr(0, 4) + "imafd" + isa_string.substr(5);
- // Fall through
- case 'i':
- max_isa |= 1L << ('i' - 'a');
- break;
-
- case 'e':
- max_isa |= 1L << ('e' - 'a');
- break;
-
- default:
- bad_isa_string(str, ("'" + isa_string.substr(0, 4) + "' must be followed by I, E, or G").c_str());
- }
-
- const char* isa_str = isa_string.c_str();
- auto p = isa_str, subset = all_subsets;
- for (p += 5; islower(*p) && !strchr("zsx", *p); ++p) {
- while (*subset && (*p != *subset))
- ++subset;
-
- if (!*subset) {
- if (strchr(all_subsets, *p))
- bad_isa_string(str, ("Extension '" + std::string(1, *p) + "' appears too late in ISA string").c_str());
- else
- bad_isa_string(str, ("Unsupported extension '" + std::string(1, *p) + "'").c_str());
- }
-
- switch (*p) {
- case 'p': extension_table[EXT_ZBPBO] = true;
- extension_table[EXT_ZPN] = true;
- extension_table[EXT_ZPSFOPERAND] = true;
- extension_table[EXT_ZMMUL] = true; break;
- case 'q': max_isa |= 1L << ('d' - 'a');
- // Fall through
- case 'd': max_isa |= 1L << ('f' - 'a');
- }
- max_isa |= 1L << (*p - 'a');
- extension_table[toupper(*p)] = true;
- while (isdigit(*(p + 1))) {
- ++p; // skip major version, point, and minor version if presented
- if (*(p + 1) == 'p') ++p;
- }
- p += *(p + 1) == '_'; // underscores may be used to improve readability
- }
-
- while (islower(*p) || (*p == '_')) {
- p += *p == '_'; // first underscore is optional
- auto end = p;
- do ++end; while (*end && *end != '_');
- auto ext_str = std::string(p, end);
- if (ext_str == "zfh" || ext_str == "zfhmin") {
- if (!((max_isa >> ('f' - 'a')) & 1))
- bad_isa_string(str, ("'" + ext_str + "' extension requires 'F'").c_str());
- extension_table[EXT_ZFHMIN] = true;
- if (ext_str == "zfh")
- extension_table[EXT_ZFH] = true;
- } else if (ext_str == "zicsr") {
- // Spike necessarily has Zicsr, because
- // Zicsr is implied by the privileged architecture
- } else if (ext_str == "zifencei") {
- // For compatibility with version 2.0 of the base ISAs, we
- // unconditionally include FENCE.I, so Zifencei adds nothing more.
- } else if (ext_str == "zihintpause") {
- // HINTs encoded in base-ISA instructions are always present.
- } else if (ext_str == "zmmul") {
- extension_table[EXT_ZMMUL] = true;
- } else if (ext_str == "zba") {
- extension_table[EXT_ZBA] = true;
- } else if (ext_str == "zbb") {
- extension_table[EXT_ZBB] = true;
- } else if (ext_str == "zbc") {
- extension_table[EXT_ZBC] = true;
- } else if (ext_str == "zbs") {
- extension_table[EXT_ZBS] = true;
- } else if (ext_str == "zbkb") {
- extension_table[EXT_ZBKB] = true;
- } else if (ext_str == "zbkc") {
- extension_table[EXT_ZBKC] = true;
- } else if (ext_str == "zbkx") {
- extension_table[EXT_ZBKX] = true;
- } else if (ext_str == "zk") {
- extension_table[EXT_ZBKB] = true;
- extension_table[EXT_ZBKC] = true;
- extension_table[EXT_ZBKX] = true;
- extension_table[EXT_ZKND] = true;
- extension_table[EXT_ZKNE] = true;
- extension_table[EXT_ZKNH] = true;
- extension_table[EXT_ZKR] = true;
- } else if (ext_str == "zkn") {
- extension_table[EXT_ZBKB] = true;
- extension_table[EXT_ZBKC] = true;
- extension_table[EXT_ZBKX] = true;
- extension_table[EXT_ZKND] = true;
- extension_table[EXT_ZKNE] = true;
- extension_table[EXT_ZKNH] = true;
- } else if (ext_str == "zknd") {
- extension_table[EXT_ZKND] = true;
- } else if (ext_str == "zkne") {
- extension_table[EXT_ZKNE] = true;
- } else if (ext_str == "zknh") {
- extension_table[EXT_ZKNH] = true;
- } else if (ext_str == "zks") {
- extension_table[EXT_ZBKB] = true;
- extension_table[EXT_ZBKC] = true;
- extension_table[EXT_ZBKX] = true;
- extension_table[EXT_ZKSED] = true;
- extension_table[EXT_ZKSH] = true;
- } else if (ext_str == "zksed") {
- extension_table[EXT_ZKSED] = true;
- } else if (ext_str == "zksh") {
- extension_table[EXT_ZKSH] = true;
- } else if (ext_str == "zkr") {
- extension_table[EXT_ZKR] = true;
- } else if (ext_str == "zkt") {
- } else if (ext_str == "svnapot") {
- extension_table[EXT_SVNAPOT] = true;
- } else if (ext_str == "svpbmt") {
- extension_table[EXT_SVPBMT] = true;
- } else if (ext_str == "svinval") {
- extension_table[EXT_SVINVAL] = true;
- } else if (ext_str == "zicbom") {
- extension_table[EXT_ZICBOM] = true;
- } else if (ext_str == "zicboz") {
- extension_table[EXT_ZICBOZ] = true;
- } else if (ext_str == "zicbop") {
- } else if (ext_str == "zicntr") {
- } else if (ext_str == "zihpm") {
- } else if (ext_str[0] == 'x') {
- max_isa |= 1L << ('x' - 'a');
- extension_table[toupper('x')] = true;
- if (ext_str == "xbitmanip") {
- extension_table[EXT_XZBP] = true;
- extension_table[EXT_XZBS] = true;
- extension_table[EXT_XZBE] = true;
- extension_table[EXT_XZBF] = true;
- extension_table[EXT_XZBC] = true;
- extension_table[EXT_XZBM] = true;
- extension_table[EXT_XZBR] = true;
- extension_table[EXT_XZBT] = true;
- } else if (ext_str == "xzbp") {
- extension_table[EXT_XZBP] = true;
- } else if (ext_str == "xzbs") {
- extension_table[EXT_XZBS] = true;
- } else if (ext_str == "xzbe") {
- extension_table[EXT_XZBE] = true;
- } else if (ext_str == "xzbf") {
- extension_table[EXT_XZBF] = true;
- } else if (ext_str == "xzbc") {
- extension_table[EXT_XZBC] = true;
- } else if (ext_str == "xzbm") {
- extension_table[EXT_XZBM] = true;
- } else if (ext_str == "xzbr") {
- extension_table[EXT_XZBR] = true;
- } else if (ext_str == "xzbt") {
- extension_table[EXT_XZBT] = true;
- } else if (ext_str.size() == 1) {
- 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 (!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());
- }
- p = end;
- }
- if (*p) {
- bad_isa_string(str, ("can't parse: " + std::string(p)).c_str());
- }
-
- std::string lowercase = strtolower(priv);
- bool user = false, supervisor = false;
-
- if (lowercase == "m")
- ;
- else if (lowercase == "mu")
- user = true;
- else if (lowercase == "msu")
- user = supervisor = true;
- else
- bad_priv_string(priv);
-
- if (user) {
- max_isa |= reg_t(user) << ('u' - 'a');
- extension_table['U'] = true;
- }
-
- if (supervisor) {
- max_isa |= reg_t(supervisor) << ('s' - 'a');
- extension_table['S'] = true;
- }
-}
-
static int xlen_to_uxl(int xlen)
{
if (xlen == 32)
diff --git a/riscv/processor.h b/riscv/processor.h
index 7f64857..7d05346 100644
--- a/riscv/processor.h
+++ b/riscv/processor.h
@@ -14,6 +14,7 @@
#include "debug_rom_defines.h"
#include "entropy_source.h"
#include "csrs.h"
+#include "isa_parser.h"
class processor_t;
class mmu_t;
@@ -250,56 +251,6 @@ typedef enum {
OPERATION_LOAD,
} trigger_operation_t;
-typedef enum {
- // 65('A') ~ 90('Z') is reserved for standard isa in misa
- EXT_ZFH,
- EXT_ZFHMIN,
- EXT_ZBA,
- EXT_ZBB,
- EXT_ZBC,
- EXT_ZBS,
- EXT_ZBKB,
- EXT_ZBKC,
- EXT_ZBKX,
- EXT_ZKND,
- EXT_ZKNE,
- EXT_ZKNH,
- EXT_ZKSED,
- EXT_ZKSH,
- EXT_ZKR,
- EXT_ZMMUL,
- EXT_ZBPBO,
- EXT_ZPN,
- EXT_ZPSFOPERAND,
- EXT_SVNAPOT,
- EXT_SVPBMT,
- EXT_SVINVAL,
- EXT_ZDINX,
- EXT_ZFINX,
- EXT_ZHINX,
- EXT_ZHINXMIN,
- EXT_ZICBOM,
- EXT_ZICBOZ,
- EXT_ZICNTR,
- EXT_ZIHPM,
- EXT_XZBP,
- EXT_XZBS,
- EXT_XZBE,
- EXT_XZBF,
- EXT_XZBC,
- EXT_XZBM,
- EXT_XZBR,
- EXT_XZBT,
-} isa_extension_t;
-
-typedef enum {
- IMPL_MMU_SV32,
- IMPL_MMU_SV39,
- IMPL_MMU_SV48,
- IMPL_MMU_SBARE,
- IMPL_MMU,
-} impl_extension_t;
-
// Count number of contiguous 1 bits starting from the LSB.
static int cto(reg_t val)
{
@@ -309,30 +260,6 @@ static int cto(reg_t val)
return res;
}
-class isa_parser_t {
-public:
- isa_parser_t(const char* str, const char *priv);
- ~isa_parser_t(){};
- unsigned get_max_xlen() const { return max_xlen; }
- reg_t get_max_isa() const { return max_isa; }
- std::string get_isa_string() const { 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];
- }
- 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*> extensions;
-};
-
// this class represents one processor in a RISC-V machine.
class processor_t : public abstract_device_t
{
diff --git a/riscv/riscv.mk.in b/riscv/riscv.mk.in
index a803b2a..ecbda5d 100644
--- a/riscv/riscv.mk.in
+++ b/riscv/riscv.mk.in
@@ -39,6 +39,7 @@ riscv_precompiled_hdrs = \
insn_template.h \
riscv_srcs = \
+ isa_parser.cc \
processor.cc \
execute.cc \
dts.cc \