aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2022-01-06 16:13:05 -0800
committerAndrew Waterman <andrew@sifive.com>2022-01-06 17:20:02 -0800
commit2fbc6cde0b6b0e7d4ef77ae092c4ae286a77e2bf (patch)
tree44e2c7d7769f4b6b65a7a66fc664450fab043d4a
parent94381783d67b8f3faa033058f0361e6a95ce0ecc (diff)
downloadspike-2fbc6cde0b6b0e7d4ef77ae092c4ae286a77e2bf.zip
spike-2fbc6cde0b6b0e7d4ef77ae092c4ae286a77e2bf.tar.gz
spike-2fbc6cde0b6b0e7d4ef77ae092c4ae286a77e2bf.tar.bz2
Parse RV32E/RV64E base ISA strings; improve error messages
-rw-r--r--riscv/processor.cc45
1 files changed, 30 insertions, 15 deletions
diff --git a/riscv/processor.cc b/riscv/processor.cc
index 6e6252c..ede80fe 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -198,7 +198,7 @@ void processor_t::parse_priv_string(const char* str)
void processor_t::parse_isa_string(const char* str)
{
isa_string = strtolower(str);
- const char* all_subsets = "imafdqchp"
+ const char* all_subsets = "mafdqchp"
#ifdef __SIZEOF_INT128__
"v"
#endif
@@ -210,24 +210,39 @@ void processor_t::parse_isa_string(const char* str)
else if (isa_string.compare(0, 4, "rv64") == 0)
max_xlen = 64;
else
- bad_isa_string(str, "Spike supports either RV32I or RV64I");
+ 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;
- if (isa_string[4] == '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);
- }
+ case 'e':
+ max_isa |= 1L << ('e' - 'a');
+ break;
- if (isa_string[4] != 'i')
- bad_isa_string(str, "'I' extension is required");
+ 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;
- for (p += 4; islower(*p) && !strchr("zsx", *p); ++p) {
- while (*all_subsets && (*p != *all_subsets))
- ++all_subsets;
- if (!*all_subsets)
- bad_isa_string(str, "Wrong order");
+ 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;