diff options
author | Andrew Waterman <andrew@sifive.com> | 2022-01-06 16:13:05 -0800 |
---|---|---|
committer | Andrew Waterman <andrew@sifive.com> | 2022-01-06 17:20:02 -0800 |
commit | 2fbc6cde0b6b0e7d4ef77ae092c4ae286a77e2bf (patch) | |
tree | 44e2c7d7769f4b6b65a7a66fc664450fab043d4a | |
parent | 94381783d67b8f3faa033058f0361e6a95ce0ecc (diff) | |
download | spike-2fbc6cde0b6b0e7d4ef77ae092c4ae286a77e2bf.zip spike-2fbc6cde0b6b0e7d4ef77ae092c4ae286a77e2bf.tar.gz spike-2fbc6cde0b6b0e7d4ef77ae092c4ae286a77e2bf.tar.bz2 |
Parse RV32E/RV64E base ISA strings; improve error messages
-rw-r--r-- | riscv/processor.cc | 45 |
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; |