aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2023-03-30 19:12:03 -0700
committerAndrew Waterman <andrew@sifive.com>2023-03-30 19:12:03 -0700
commit54dd9179a35fc8beeb78a5f80ba1a9501af56d23 (patch)
treecb0f7640ae0841ea8005bf5f1c9a38b97c9af8f8
parent929ff56a09462978628c59c22fe6cb6895aa136f (diff)
downloadspike-rva-profile-support.zip
spike-rva-profile-support.tar.gz
spike-rva-profile-support.tar.bz2
-rw-r--r--riscv/isa_parser.cc83
1 files changed, 52 insertions, 31 deletions
diff --git a/riscv/isa_parser.cc b/riscv/isa_parser.cc
index 2a8e33f..08ce7b8 100644
--- a/riscv/isa_parser.cc
+++ b/riscv/isa_parser.cc
@@ -27,17 +27,36 @@ static void bad_priv_string(const char* priv)
abort();
}
+static std::string expand_rva_profile_string(const std::string& str)
+{
+ std::map<std::string, std::string> profile_choices;
+ profile_choices["rva20"] = "rv64gc_zicsr_zicntr_zifencei";
+ profile_choices["rva22"] = profile_choices["rva20"] + "_zihpm_zihintpause_zba_zbb_zbs_zicbom_zicbop_zicboz_zfhmin_zkt";
+
+ for (const auto& [name, expansion] : profile_choices) {
+ if (str.compare(0, name.length(), name) == 0) {
+ if (str.length() == name.length())
+ return expansion;
+
+ return expansion + "_" + str.substr(name.length());
+ }
+ }
+
+ return str;
+}
+
isa_parser_t::isa_parser_t(const char* str, const char *priv)
{
- isa_string = strtolower(str);
const char* all_subsets = "mafdqchpv";
+ isa_string = expand_rva_profile_string(strtolower(str));
+
if (isa_string.compare(0, 4, "rv32") == 0)
max_xlen = 32;
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");
+ bad_isa_string(str, "ISA strings must begin with RV32, RV64, or a valid profile name");
switch (isa_string[4]) {
case 'g':
@@ -58,38 +77,40 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv)
}
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());
- }
+ auto p = isa_str + 5;
- 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 'v': // even rv32iv implies double float
- case 'q': extension_table['D'] = true;
- // Fall through
- case 'd': extension_table['F'] = true;
- }
- extension_table[toupper(*p)] = true;
- while (isdigit(*(p + 1))) {
- ++p; // skip major version, point, and minor version if presented
- if (*(p + 1) == 'p') ++p;
+ while (true) {
+ // Ignore underscores
+ while (*p == '_')
+ p++;
+
+ if (!islower(*p))
+ break;
+
+ if (strchr(all_subsets, *p)) {
+ // Handle single-letter extensions
+ 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 'v': // even rv32iv implies double float
+ case 'q': extension_table['D'] = true;
+ // Fall through
+ case 'd': extension_table['F'] = true;
+ }
+
+ 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;
+ continue;
}
- 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);