aboutsummaryrefslogtreecommitdiff
path: root/disasm/isa_parser.cc
diff options
context:
space:
mode:
authorJerry Zhao <jerryz123@berkeley.edu>2024-06-21 17:23:55 -0700
committerGitHub <noreply@github.com>2024-06-21 17:23:55 -0700
commitf03e97c89fb5fa952f1a1264734aecf39619b65d (patch)
treec65e4bf6c71d8e42e5539d7650581c0168eafc75 /disasm/isa_parser.cc
parent3d4027a2bb559af758a2a9d624a3848ae2485453 (diff)
parentc790f73ae94d358e9493187fdbcc9053ed7af7d8 (diff)
downloadspike-f03e97c89fb5fa952f1a1264734aecf39619b65d.zip
spike-f03e97c89fb5fa952f1a1264734aecf39619b65d.tar.gz
spike-f03e97c89fb5fa952f1a1264734aecf39619b65d.tar.bz2
Merge pull request #1701 from riscv-software-src/zvl_zve
Correctly determine vector capability from v/zve/zvl ISA strings, remove --varch
Diffstat (limited to 'disasm/isa_parser.cc')
-rw-r--r--disasm/isa_parser.cc65
1 files changed, 61 insertions, 4 deletions
diff --git a/disasm/isa_parser.cc b/disasm/isa_parser.cc
index 7c607d7..cba5516 100644
--- a/disasm/isa_parser.cc
+++ b/disasm/isa_parser.cc
@@ -38,6 +38,11 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv)
else
bad_isa_string(str, "ISA strings must begin with RV32 or RV64");
+ vlen = 0;
+ elen = 0;
+ zvf = false;
+ zvd = false;
+
switch (isa_string[4]) {
case 'g':
// G = IMAFD_Zicsr_Zifencei, but Spike includes the latter two
@@ -70,7 +75,8 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv)
}
switch (*p) {
- case 'v': // even rv32iv implies double float
+ case 'v': vlen = 128; elen = 64; zvf = true; zvd = true;
+ // even rv32iv implies double float
case 'q': extension_table['D'] = true;
// Fall through
case 'd': extension_table['F'] = true;
@@ -95,9 +101,6 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv)
if (ext_str == "zfh")
extension_table[EXT_ZFH] = true;
} else if (ext_str == "zvfh" || ext_str == "zvfhmin") {
- if (!extension_table['V'])
- bad_isa_string(str, ("'" + ext_str + "' extension requires 'V'").c_str());
-
extension_table[EXT_ZVFHMIN] = true;
if (ext_str == "zvfh") {
@@ -314,6 +317,35 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv)
extension_table[EXT_ZICFILP] = true;
} else if (ext_str == "zicfiss") {
extension_table[EXT_ZICFISS] = true;
+ } else if (ext_str.substr(0, 3) == "zvl") {
+ reg_t new_vlen;
+ try {
+ new_vlen = std::stol(ext_str.substr(3, ext_str.size() - 4));
+ } catch (std::logic_error& e) {
+ new_vlen = 0;
+ }
+ if ((new_vlen & (new_vlen - 1)) != 0 || new_vlen < 32)
+ bad_isa_string(str, ("Invalid Zvl string: " + ext_str).c_str());
+ vlen = std::max(vlen, new_vlen);
+ } else if (ext_str.substr(0, 3) == "zve") {
+ reg_t new_elen;
+ try {
+ new_elen = std::stol(ext_str.substr(3, ext_str.size() - 4));
+ } catch (std::logic_error& e) {
+ new_elen = 0;
+ }
+ if (ext_str.substr(5) == "d") {
+ zvd |= true; zvf |= true;
+ } else if (ext_str.substr(5) == "f") {
+ zvf |= true;
+ } else if (ext_str.substr(5) == "x") {
+ /* do nothing */
+ } else {
+ new_elen = 0;
+ }
+ if (new_elen != 32 && new_elen != 64)
+ bad_isa_string(str, ("Invalid Zve string: " + ext_str).c_str());
+ elen = std::max(elen, new_elen);
} else if (ext_str[0] == 'x') {
extension_table['X'] = true;
if (ext_str.size() == 1) {
@@ -424,6 +456,31 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv)
"extensions are incompatible with WORDS_BIGENDIAN setups.");
}
#endif
+
+ if (vlen > 4096) {
+ bad_isa_string(str, "Spike does not currently support VLEN > 4096b");
+ }
+
+ if ((vlen != 0) ^ (elen != 0)) {
+ bad_isa_string(str, "Invalid Zvl/Zve configuration");
+ }
+
+ if (extension_table[EXT_ZVFHMIN] && (vlen == 0 || elen == 0 || !zvf)) {
+ bad_isa_string(str, "'Zvfhmin' extension requires Zve32f");
+ }
+
+ if (extension_table[EXT_ZVFH] && (vlen == 0 || elen == 0 || !zvf || !extension_table[EXT_ZVFHMIN])) {
+ bad_isa_string(str, "'Zvfh' extension requires Zve32f and 'Zvfhmin'");
+ }
+
+ if (zvd && !extension_table['D'] && elen < 64) {
+ bad_isa_string(str, "'ZveXXd' extension requires D");
+ }
+
+ if (zvf && !extension_table['F']) {
+ bad_isa_string(str, "'ZveXXf' extension requires F");
+ }
+
std::string lowercase = strtolower(priv);
bool user = false, supervisor = false;