|
|
|
@ -48,6 +48,376 @@ static void bad_priv_string(const char* priv) |
|
|
|
abort(); |
|
|
|
} |
|
|
|
|
|
|
|
void isa_parser_t::add_extension(const std::string& ext_str, const char* str) |
|
|
|
{ |
|
|
|
if (ext_str == "zfh") { |
|
|
|
extension_table[EXT_ZFH] = true; |
|
|
|
add_extension("zfhmin", str); |
|
|
|
} else if (ext_str == "zfhmin") { |
|
|
|
extension_table['F'] = true; |
|
|
|
extension_table[EXT_ZFHMIN] = true; |
|
|
|
} else if (ext_str == "zvfh") { |
|
|
|
extension_table[EXT_ZVFH] = true; |
|
|
|
add_extension("zvfhmin", str); |
|
|
|
add_extension("zfhmin", str); |
|
|
|
} else if (ext_str == "zvfhmin") { |
|
|
|
extension_table[EXT_ZVFHMIN] = true; |
|
|
|
add_extension("zve32f", str); |
|
|
|
} else if (ext_str == "zvfbfa") { |
|
|
|
extension_table[EXT_ZVFBFA] = true; |
|
|
|
add_extension("zve32f", str); |
|
|
|
add_extension("zfbfmin", str); |
|
|
|
} else if (ext_str == "zvfofp4min") { |
|
|
|
extension_table[EXT_ZVFOFP4MIN] = true; |
|
|
|
add_extension("zve32f", str); |
|
|
|
} else if (ext_str == "zvfofp8min") { |
|
|
|
extension_table[EXT_ZVFOFP8MIN] = true; |
|
|
|
add_extension("zve32f", str); |
|
|
|
} 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 == "zihintntl") { |
|
|
|
// HINTs encoded in base-ISA instructions are always present.
|
|
|
|
} else if (ext_str == "ziccid") { |
|
|
|
extension_table[EXT_ZICCID] = true; |
|
|
|
} else if (ext_str == "ziccif") { |
|
|
|
// aligned instruction fetch is always atomic in Spike
|
|
|
|
} else if (ext_str == "zaamo") { |
|
|
|
extension_table[EXT_ZAAMO] = true; |
|
|
|
} else if (ext_str == "zalrsc") { |
|
|
|
extension_table[EXT_ZALRSC] = true; |
|
|
|
} else if (ext_str == "zacas") { |
|
|
|
extension_table[EXT_ZACAS] = true; |
|
|
|
extension_table[EXT_ZAAMO] = true; |
|
|
|
} else if (ext_str == "zabha") { |
|
|
|
extension_table[EXT_ZABHA] = true; |
|
|
|
extension_table[EXT_ZAAMO] = true; |
|
|
|
} else if (ext_str == "zawrs") { |
|
|
|
extension_table[EXT_ZAWRS] = true; |
|
|
|
extension_table[EXT_ZALRSC] = true; |
|
|
|
} 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 == "zdinx") { |
|
|
|
extension_table[EXT_ZFINX] = true; |
|
|
|
extension_table[EXT_ZDINX] = true; |
|
|
|
} else if (ext_str == "zfbfmin") { |
|
|
|
extension_table['F'] = true; |
|
|
|
extension_table[EXT_ZFBFMIN] = true; |
|
|
|
} else if (ext_str == "zfinx") { |
|
|
|
extension_table[EXT_ZFINX] = true; |
|
|
|
} else if (ext_str == "zhinx") { |
|
|
|
extension_table[EXT_ZFINX] = true; |
|
|
|
extension_table[EXT_ZHINX] = true; |
|
|
|
extension_table[EXT_ZHINXMIN] = true; |
|
|
|
} else if (ext_str == "zhinxmin") { |
|
|
|
extension_table[EXT_ZFINX] = true; |
|
|
|
extension_table[EXT_ZHINXMIN] = true; |
|
|
|
} else if (ext_str == "zce") { |
|
|
|
extension_table[EXT_ZCA] = true; |
|
|
|
extension_table[EXT_ZCB] = true; |
|
|
|
extension_table[EXT_ZCMT] = true; |
|
|
|
extension_table[EXT_ZCMP] = true; |
|
|
|
extension_table[EXT_ZCE] = true; |
|
|
|
} else if (ext_str == "zca") { |
|
|
|
extension_table[EXT_ZCA] = true; |
|
|
|
} else if (ext_str == "zcf") { |
|
|
|
if (max_xlen != 32) |
|
|
|
bad_isa_string(str, "'Zcf' requires RV32"); |
|
|
|
extension_table['F'] = true; |
|
|
|
extension_table[EXT_ZCA] = true; |
|
|
|
extension_table[EXT_ZCF] = true; |
|
|
|
} else if (ext_str == "zcb") { |
|
|
|
extension_table[EXT_ZCB] = true; |
|
|
|
extension_table[EXT_ZCA] = true; |
|
|
|
} else if (ext_str == "zcd") { |
|
|
|
extension_table[EXT_ZCD] = true; |
|
|
|
extension_table[EXT_ZCA] = true; |
|
|
|
extension_table['F'] = true; |
|
|
|
extension_table['D'] = true; |
|
|
|
} else if (ext_str == "zcmp") { |
|
|
|
extension_table[EXT_ZCMP] = true; |
|
|
|
extension_table[EXT_ZCA] = true; |
|
|
|
} else if (ext_str == "zcmt") { |
|
|
|
extension_table[EXT_ZCMT] = true; |
|
|
|
extension_table[EXT_ZCA] = true; |
|
|
|
} else if (ext_str == "zibi") { |
|
|
|
extension_table[EXT_ZIBI] = 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 == "smepmp") { |
|
|
|
extension_table[EXT_SMEPMP] = true; |
|
|
|
} else if (ext_str == "smstateen") { |
|
|
|
extension_table[EXT_SMSTATEEN] = true; |
|
|
|
} else if (ext_str == "smpmpmt") { |
|
|
|
extension_table[EXT_SMPMPMT] = true; |
|
|
|
} else if (ext_str == "smrnmi") { |
|
|
|
extension_table[EXT_SMRNMI] = true; |
|
|
|
} else if (ext_str == "sscofpmf") { |
|
|
|
extension_table[EXT_SSCOFPMF] = true; |
|
|
|
} else if (ext_str == "svadu") { |
|
|
|
extension_table[EXT_SVADU] = true; |
|
|
|
} else if (ext_str == "svade") { |
|
|
|
extension_table[EXT_SVADE] = true; |
|
|
|
} 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 == "svukte") { |
|
|
|
if (max_xlen != 64) |
|
|
|
bad_isa_string(str, "'svukte' requires RV64"); |
|
|
|
extension_table[EXT_SVUKTE] = true; |
|
|
|
} else if (ext_str == "zfa") { |
|
|
|
extension_table[EXT_ZFA] = 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 == "zicclsm") { |
|
|
|
extension_table[EXT_ZICCLSM] = true; |
|
|
|
} else if (ext_str == "zicntr") { |
|
|
|
extension_table[EXT_ZICNTR] = true; |
|
|
|
} else if (ext_str == "zicond") { |
|
|
|
extension_table[EXT_ZICOND] = true; |
|
|
|
} else if (ext_str == "zihpm") { |
|
|
|
extension_table[EXT_ZIHPM] = true; |
|
|
|
} else if (ext_str == "zilsd") { |
|
|
|
if (max_xlen != 32) |
|
|
|
bad_isa_string(str, "'Zilsd' requires RV32"); |
|
|
|
extension_table[EXT_ZILSD] = true; |
|
|
|
} else if (ext_str == "zclsd") { |
|
|
|
if (max_xlen != 32) |
|
|
|
bad_isa_string(str, "'Zclsd' requires RV32"); |
|
|
|
extension_table[EXT_ZCLSD] = true; |
|
|
|
extension_table[EXT_ZCA] = true; |
|
|
|
extension_table[EXT_ZILSD] = true; |
|
|
|
} else if (ext_str == "zvkb") { |
|
|
|
extension_table[EXT_ZVKB] = true; |
|
|
|
} else if (ext_str == "zvbb") { |
|
|
|
extension_table[EXT_ZVKB] = true; |
|
|
|
extension_table[EXT_ZVBB] = true; |
|
|
|
} else if (ext_str == "zvbc") { |
|
|
|
extension_table[EXT_ZVBC] = true; |
|
|
|
} else if (ext_str == "zvfbfmin") { |
|
|
|
extension_table[EXT_ZVFBFMIN] = true; |
|
|
|
add_extension("zve32f", str); |
|
|
|
} else if (ext_str == "zvfbfwma") { |
|
|
|
extension_table[EXT_ZVFBFWMA] = true; |
|
|
|
add_extension("zfbfmin", str); |
|
|
|
add_extension("zvfbfmin", str); |
|
|
|
} else if (ext_str == "zvkg") { |
|
|
|
extension_table[EXT_ZVKG] = true; |
|
|
|
} else if (ext_str == "zvkn") { |
|
|
|
extension_table[EXT_ZVKB] = true; |
|
|
|
extension_table[EXT_ZVBB] = true; |
|
|
|
extension_table[EXT_ZVKNED] = true; |
|
|
|
extension_table[EXT_ZVKNHB] = true; |
|
|
|
} else if (ext_str == "zvknc") { |
|
|
|
extension_table[EXT_ZVKB] = true; |
|
|
|
extension_table[EXT_ZVBB] = true; |
|
|
|
extension_table[EXT_ZVBC] = true; |
|
|
|
extension_table[EXT_ZVKNED] = true; |
|
|
|
extension_table[EXT_ZVKNHB] = true; |
|
|
|
} else if (ext_str == "zvkng") { |
|
|
|
extension_table[EXT_ZVKB] = true; |
|
|
|
extension_table[EXT_ZVBB] = true; |
|
|
|
extension_table[EXT_ZVKG] = true; |
|
|
|
extension_table[EXT_ZVKNED] = true; |
|
|
|
extension_table[EXT_ZVKNHB] = true; |
|
|
|
} else if (ext_str == "zvkned") { |
|
|
|
extension_table[EXT_ZVKNED] = true; |
|
|
|
} else if (ext_str == "zvknha") { |
|
|
|
extension_table[EXT_ZVKNHA] = true; |
|
|
|
} else if (ext_str == "zvknhb") { |
|
|
|
extension_table[EXT_ZVKNHB] = true; |
|
|
|
} else if (ext_str == "zvks") { |
|
|
|
extension_table[EXT_ZVKB] = true; |
|
|
|
extension_table[EXT_ZVBB] = true; |
|
|
|
extension_table[EXT_ZVKSED] = true; |
|
|
|
extension_table[EXT_ZVKSH] = true; |
|
|
|
} else if (ext_str == "zvksc") { |
|
|
|
extension_table[EXT_ZVKB] = true; |
|
|
|
extension_table[EXT_ZVBB] = true; |
|
|
|
extension_table[EXT_ZVBC] = true; |
|
|
|
extension_table[EXT_ZVKSED] = true; |
|
|
|
extension_table[EXT_ZVKSH] = true; |
|
|
|
} else if (ext_str == "zvksg") { |
|
|
|
extension_table[EXT_ZVKB] = true; |
|
|
|
extension_table[EXT_ZVBB] = true; |
|
|
|
extension_table[EXT_ZVKG] = true; |
|
|
|
extension_table[EXT_ZVKSED] = true; |
|
|
|
extension_table[EXT_ZVKSH] = true; |
|
|
|
} else if (ext_str == "zvksed") { |
|
|
|
extension_table[EXT_ZVKSED] = true; |
|
|
|
} else if (ext_str == "zvksh") { |
|
|
|
extension_table[EXT_ZVKSH] = true; |
|
|
|
} else if (ext_str == "zvqdotq") { |
|
|
|
extension_table[EXT_ZVQDOTQ] = true; |
|
|
|
} else if (ext_str == "zvqbdot8i") { |
|
|
|
extension_table[EXT_ZVQBDOT8I] = true; |
|
|
|
} else if (ext_str == "zvqbdot16i") { |
|
|
|
extension_table[EXT_ZVQBDOT16I] = true; |
|
|
|
} else if (ext_str == "zvfqbdot8f") { |
|
|
|
extension_table[EXT_ZVFQBDOT8F] = true; |
|
|
|
} else if (ext_str == "zvfwbdot16bf") { |
|
|
|
extension_table[EXT_ZVFWBDOT16BF] = true; |
|
|
|
} else if (ext_str == "zvfbdot32f") { |
|
|
|
extension_table[EXT_ZVFBDOT32F] = true; |
|
|
|
} else if (ext_str == "zvqldot8i") { |
|
|
|
extension_table[EXT_ZVQLDOT8I] = true; |
|
|
|
} else if (ext_str == "zvqldot16i") { |
|
|
|
extension_table[EXT_ZVQLDOT16I] = true; |
|
|
|
} else if (ext_str == "zvfqldot8f") { |
|
|
|
extension_table[EXT_ZVFQLDOT8F] = true; |
|
|
|
} else if (ext_str == "zvfwldot16bf") { |
|
|
|
extension_table[EXT_ZVFWLDOT16BF] = true; |
|
|
|
} else if (ext_str == "zvkt") { |
|
|
|
} else if (ext_str == "sstc") { |
|
|
|
extension_table[EXT_SSTC] = true; |
|
|
|
} else if (ext_str == "smcsrind") { |
|
|
|
extension_table[EXT_SMCSRIND] = true; |
|
|
|
} else if (ext_str == "sscsrind") { |
|
|
|
extension_table[EXT_SSCSRIND] = true; |
|
|
|
} else if (ext_str == "smcntrpmf") { |
|
|
|
extension_table[EXT_SMCNTRPMF] = true; |
|
|
|
} else if (ext_str == "smcdeleg") { |
|
|
|
extension_table[EXT_SMCDELEG] = true; |
|
|
|
} else if (ext_str == "ssccfg") { |
|
|
|
extension_table[EXT_SSCCFG] = true; |
|
|
|
} else if (ext_str == "zimop") { |
|
|
|
extension_table[EXT_ZIMOP] = true; |
|
|
|
} else if (ext_str == "zcmop") { |
|
|
|
extension_table[EXT_ZCMOP] = true; |
|
|
|
} else if (ext_str == "zalasr") { |
|
|
|
extension_table[EXT_ZALASR] = true; |
|
|
|
} else if (ext_str == "ssqosid") { |
|
|
|
extension_table[EXT_SSQOSID] = true; |
|
|
|
} else if (ext_str == "zicfilp") { |
|
|
|
extension_table[EXT_ZICFILP] = true; |
|
|
|
} else if (ext_str == "zicfiss") { |
|
|
|
extension_table[EXT_ZICFISS] = true; |
|
|
|
extension_table[EXT_ZAAMO] = true; |
|
|
|
extension_table[EXT_ZIMOP] = true; |
|
|
|
} else if (ext_str == "smmpm") { |
|
|
|
extension_table[EXT_SMMPM] = true; |
|
|
|
} else if (ext_str == "smnpm") { |
|
|
|
extension_table[EXT_SMNPM] = true; |
|
|
|
} else if (ext_str == "ssnpm") { |
|
|
|
extension_table[EXT_SSNPM] = true; |
|
|
|
} else if (ext_str.substr(0, 3) == "zvl") { |
|
|
|
reg_t new_vlen; |
|
|
|
try { |
|
|
|
new_vlen = safe_stoul(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 || ext_str.back() != 'b') |
|
|
|
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") { |
|
|
|
if (ext_str.size() != 6) { |
|
|
|
bad_isa_string(str, ("Invalid Zve string: " + ext_str).c_str()); |
|
|
|
} |
|
|
|
reg_t new_elen; |
|
|
|
try { |
|
|
|
new_elen = safe_stoul(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; |
|
|
|
extension_table['F'] = true; |
|
|
|
extension_table['D'] = true; |
|
|
|
} else if (ext_str.substr(5) == "f") { |
|
|
|
zvf |= true; |
|
|
|
extension_table['F'] = 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); |
|
|
|
vlen = std::max(vlen, new_elen); |
|
|
|
} else if (ext_str == "ssdbltrp") { |
|
|
|
extension_table[EXT_SSDBLTRP] = true; |
|
|
|
} else if (ext_str == "smdbltrp") { |
|
|
|
extension_table[EXT_SMDBLTRP] = true; |
|
|
|
} else if (ext_str == "smaia") { |
|
|
|
extension_table[EXT_SMAIA] = true; |
|
|
|
extension_table[EXT_SSAIA] = true; |
|
|
|
extension_table[EXT_SMCSRIND] = true; |
|
|
|
extension_table[EXT_SSCSRIND] = true; |
|
|
|
} else if (ext_str == "ssaia") { |
|
|
|
extension_table[EXT_SSAIA] = true; |
|
|
|
extension_table[EXT_SSCSRIND] = true; |
|
|
|
} else if (ext_str[0] == 'x') { |
|
|
|
extension_table['X'] = true; |
|
|
|
if (ext_str.size() == 1) { |
|
|
|
bad_isa_string(str, "single 'X' is not a proper name"); |
|
|
|
} else if (ext_str != "xdummy") { |
|
|
|
extensions.insert(ext_str.substr(1)); |
|
|
|
} |
|
|
|
} else { |
|
|
|
bad_isa_string(str, ("unsupported extension: " + ext_str).c_str()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
isa_parser_t::isa_parser_t(const char* str, const char *priv) |
|
|
|
{ |
|
|
|
isa_string = strtolower(str); |
|
|
|
@ -97,7 +467,7 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv) |
|
|
|
} |
|
|
|
|
|
|
|
switch (*p) { |
|
|
|
case 'v': vlen = 128; elen = 64; zvf = true; zvd = true; |
|
|
|
case 'v': add_extension("zve64d", str); vlen = 128; |
|
|
|
[[fallthrough]]; |
|
|
|
case 'q': extension_table['D'] = true; |
|
|
|
[[fallthrough]]; |
|
|
|
@ -116,346 +486,8 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv) |
|
|
|
auto end = p; |
|
|
|
do ++end; while (*end && *end != '_'); |
|
|
|
auto ext_str = std::string(p, end); |
|
|
|
if (ext_str == "zfh" || ext_str == "zfhmin") { |
|
|
|
if (!extension_table['F']) |
|
|
|
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 == "zvfh" || ext_str == "zvfhmin") { |
|
|
|
extension_table[EXT_ZVFHMIN] = true; |
|
|
|
|
|
|
|
if (ext_str == "zvfh") { |
|
|
|
extension_table[EXT_ZVFH] = true; |
|
|
|
// Zvfh implies Zfhmin
|
|
|
|
extension_table[EXT_ZFHMIN] = true; |
|
|
|
} |
|
|
|
} else if (ext_str == "zvfbfa") { |
|
|
|
extension_table[EXT_ZVFBFA] = true; |
|
|
|
} else if (ext_str == "zvfofp4min") { |
|
|
|
extension_table[EXT_ZVFOFP4MIN] = true; |
|
|
|
} else if (ext_str == "zvfofp8min") { |
|
|
|
extension_table[EXT_ZVFOFP8MIN] = 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 == "zihintntl") { |
|
|
|
// HINTs encoded in base-ISA instructions are always present.
|
|
|
|
} else if (ext_str == "ziccid") { |
|
|
|
extension_table[EXT_ZICCID] = true; |
|
|
|
} else if (ext_str == "ziccif") { |
|
|
|
// aligned instruction fetch is always atomic in Spike
|
|
|
|
} else if (ext_str == "zaamo") { |
|
|
|
extension_table[EXT_ZAAMO] = true; |
|
|
|
} else if (ext_str == "zalrsc") { |
|
|
|
extension_table[EXT_ZALRSC] = true; |
|
|
|
} else if (ext_str == "zacas") { |
|
|
|
extension_table[EXT_ZACAS] = true; |
|
|
|
} else if (ext_str == "zabha") { |
|
|
|
extension_table[EXT_ZABHA] = true; |
|
|
|
} else if (ext_str == "zawrs") { |
|
|
|
extension_table[EXT_ZAWRS] = true; |
|
|
|
} 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 == "zdinx") { |
|
|
|
extension_table[EXT_ZFINX] = true; |
|
|
|
extension_table[EXT_ZDINX] = true; |
|
|
|
} else if (ext_str == "zfbfmin") { |
|
|
|
extension_table[EXT_ZFBFMIN] = true; |
|
|
|
} else if (ext_str == "zfinx") { |
|
|
|
extension_table[EXT_ZFINX] = true; |
|
|
|
} else if (ext_str == "zhinx") { |
|
|
|
extension_table[EXT_ZFINX] = true; |
|
|
|
extension_table[EXT_ZHINX] = true; |
|
|
|
extension_table[EXT_ZHINXMIN] = true; |
|
|
|
} else if (ext_str == "zhinxmin") { |
|
|
|
extension_table[EXT_ZFINX] = true; |
|
|
|
extension_table[EXT_ZHINXMIN] = true; |
|
|
|
} else if (ext_str == "zce") { |
|
|
|
extension_table[EXT_ZCA] = true; |
|
|
|
extension_table[EXT_ZCB] = true; |
|
|
|
extension_table[EXT_ZCMT] = true; |
|
|
|
extension_table[EXT_ZCMP] = true; |
|
|
|
if (extension_table['F'] && max_xlen == 32) |
|
|
|
extension_table[EXT_ZCF] = true; |
|
|
|
} else if (ext_str == "zca") { |
|
|
|
extension_table[EXT_ZCA] = true; |
|
|
|
} else if (ext_str == "zcf") { |
|
|
|
if (max_xlen != 32) |
|
|
|
bad_isa_string(str, "'Zcf' requires RV32"); |
|
|
|
extension_table[EXT_ZCF] = true; |
|
|
|
} else if (ext_str == "zcb") { |
|
|
|
extension_table[EXT_ZCB] = true; |
|
|
|
} else if (ext_str == "zcd") { |
|
|
|
extension_table[EXT_ZCD] = true; |
|
|
|
} else if (ext_str == "zcmp") { |
|
|
|
extension_table[EXT_ZCMP] = true; |
|
|
|
} else if (ext_str == "zcmt") { |
|
|
|
extension_table[EXT_ZCMT] = true; |
|
|
|
} else if (ext_str == "zibi") { |
|
|
|
extension_table[EXT_ZIBI] = 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 == "smepmp") { |
|
|
|
extension_table[EXT_SMEPMP] = true; |
|
|
|
} else if (ext_str == "smstateen") { |
|
|
|
extension_table[EXT_SMSTATEEN] = true; |
|
|
|
} else if (ext_str == "smpmpmt") { |
|
|
|
extension_table[EXT_SMPMPMT] = true; |
|
|
|
} else if (ext_str == "smrnmi") { |
|
|
|
extension_table[EXT_SMRNMI] = true; |
|
|
|
} else if (ext_str == "sscofpmf") { |
|
|
|
extension_table[EXT_SSCOFPMF] = true; |
|
|
|
} else if (ext_str == "svadu") { |
|
|
|
extension_table[EXT_SVADU] = true; |
|
|
|
} else if (ext_str == "svade") { |
|
|
|
extension_table[EXT_SVADE] = true; |
|
|
|
} 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 == "svukte") { |
|
|
|
if (max_xlen != 64) |
|
|
|
bad_isa_string(str, "'svukte' requires RV64"); |
|
|
|
extension_table[EXT_SVUKTE] = true; |
|
|
|
} else if (ext_str == "zfa") { |
|
|
|
extension_table[EXT_ZFA] = 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 == "zicclsm") { |
|
|
|
extension_table[EXT_ZICCLSM] = true; |
|
|
|
} else if (ext_str == "zicntr") { |
|
|
|
extension_table[EXT_ZICNTR] = true; |
|
|
|
} else if (ext_str == "zicond") { |
|
|
|
extension_table[EXT_ZICOND] = true; |
|
|
|
} else if (ext_str == "zihpm") { |
|
|
|
extension_table[EXT_ZIHPM] = true; |
|
|
|
} else if (ext_str == "zilsd") { |
|
|
|
if (max_xlen != 32) |
|
|
|
bad_isa_string(str, "'Zilsd' requires RV32"); |
|
|
|
extension_table[EXT_ZILSD] = true; |
|
|
|
} else if (ext_str == "zclsd") { |
|
|
|
extension_table[EXT_ZCLSD] = true; |
|
|
|
} else if (ext_str == "zvkb") { |
|
|
|
extension_table[EXT_ZVKB] = true; |
|
|
|
} else if (ext_str == "zvbb") { |
|
|
|
extension_table[EXT_ZVKB] = true; |
|
|
|
extension_table[EXT_ZVBB] = true; |
|
|
|
} else if (ext_str == "zvbc") { |
|
|
|
extension_table[EXT_ZVBC] = true; |
|
|
|
} else if (ext_str == "zvfbfmin") { |
|
|
|
extension_table[EXT_ZVFBFMIN] = true; |
|
|
|
} else if (ext_str == "zvfbfwma") { |
|
|
|
extension_table[EXT_ZVFBFWMA] = true; |
|
|
|
} else if (ext_str == "zvkg") { |
|
|
|
extension_table[EXT_ZVKG] = true; |
|
|
|
} else if (ext_str == "zvkn") { |
|
|
|
extension_table[EXT_ZVKB] = true; |
|
|
|
extension_table[EXT_ZVBB] = true; |
|
|
|
extension_table[EXT_ZVKNED] = true; |
|
|
|
extension_table[EXT_ZVKNHB] = true; |
|
|
|
} else if (ext_str == "zvknc") { |
|
|
|
extension_table[EXT_ZVKB] = true; |
|
|
|
extension_table[EXT_ZVBB] = true; |
|
|
|
extension_table[EXT_ZVBC] = true; |
|
|
|
extension_table[EXT_ZVKNED] = true; |
|
|
|
extension_table[EXT_ZVKNHB] = true; |
|
|
|
} else if (ext_str == "zvkng") { |
|
|
|
extension_table[EXT_ZVKB] = true; |
|
|
|
extension_table[EXT_ZVBB] = true; |
|
|
|
extension_table[EXT_ZVKG] = true; |
|
|
|
extension_table[EXT_ZVKNED] = true; |
|
|
|
extension_table[EXT_ZVKNHB] = true; |
|
|
|
} else if (ext_str == "zvkned") { |
|
|
|
extension_table[EXT_ZVKNED] = true; |
|
|
|
} else if (ext_str == "zvknha") { |
|
|
|
extension_table[EXT_ZVKNHA] = true; |
|
|
|
} else if (ext_str == "zvknhb") { |
|
|
|
extension_table[EXT_ZVKNHB] = true; |
|
|
|
} else if (ext_str == "zvks") { |
|
|
|
extension_table[EXT_ZVKB] = true; |
|
|
|
extension_table[EXT_ZVBB] = true; |
|
|
|
extension_table[EXT_ZVKSED] = true; |
|
|
|
extension_table[EXT_ZVKSH] = true; |
|
|
|
} else if (ext_str == "zvksc") { |
|
|
|
extension_table[EXT_ZVKB] = true; |
|
|
|
extension_table[EXT_ZVBB] = true; |
|
|
|
extension_table[EXT_ZVBC] = true; |
|
|
|
extension_table[EXT_ZVKSED] = true; |
|
|
|
extension_table[EXT_ZVKSH] = true; |
|
|
|
} else if (ext_str == "zvksg") { |
|
|
|
extension_table[EXT_ZVKB] = true; |
|
|
|
extension_table[EXT_ZVBB] = true; |
|
|
|
extension_table[EXT_ZVKG] = true; |
|
|
|
extension_table[EXT_ZVKSED] = true; |
|
|
|
extension_table[EXT_ZVKSH] = true; |
|
|
|
} else if (ext_str == "zvksed") { |
|
|
|
extension_table[EXT_ZVKSED] = true; |
|
|
|
} else if (ext_str == "zvksh") { |
|
|
|
extension_table[EXT_ZVKSH] = true; |
|
|
|
} else if (ext_str == "zvqdotq") { |
|
|
|
extension_table[EXT_ZVQDOTQ] = true; |
|
|
|
} else if (ext_str == "zvqbdot8i") { |
|
|
|
extension_table[EXT_ZVQBDOT8I] = true; |
|
|
|
} else if (ext_str == "zvqbdot16i") { |
|
|
|
extension_table[EXT_ZVQBDOT16I] = true; |
|
|
|
} else if (ext_str == "zvfqbdot8f") { |
|
|
|
extension_table[EXT_ZVFQBDOT8F] = true; |
|
|
|
} else if (ext_str == "zvfwbdot16bf") { |
|
|
|
extension_table[EXT_ZVFWBDOT16BF] = true; |
|
|
|
} else if (ext_str == "zvfbdot32f") { |
|
|
|
extension_table[EXT_ZVFBDOT32F] = true; |
|
|
|
} else if (ext_str == "zvqldot8i") { |
|
|
|
extension_table[EXT_ZVQLDOT8I] = true; |
|
|
|
} else if (ext_str == "zvqldot16i") { |
|
|
|
extension_table[EXT_ZVQLDOT16I] = true; |
|
|
|
} else if (ext_str == "zvfqldot8f") { |
|
|
|
extension_table[EXT_ZVFQLDOT8F] = true; |
|
|
|
} else if (ext_str == "zvfwldot16bf") { |
|
|
|
extension_table[EXT_ZVFWLDOT16BF] = true; |
|
|
|
} else if (ext_str == "zvkt") { |
|
|
|
} else if (ext_str == "sstc") { |
|
|
|
extension_table[EXT_SSTC] = true; |
|
|
|
} else if (ext_str == "smcsrind") { |
|
|
|
extension_table[EXT_SMCSRIND] = true; |
|
|
|
} else if (ext_str == "sscsrind") { |
|
|
|
extension_table[EXT_SSCSRIND] = true; |
|
|
|
} else if (ext_str == "smcntrpmf") { |
|
|
|
extension_table[EXT_SMCNTRPMF] = true; |
|
|
|
} else if (ext_str == "smcdeleg") { |
|
|
|
extension_table[EXT_SMCDELEG] = true; |
|
|
|
} else if (ext_str == "ssccfg") { |
|
|
|
extension_table[EXT_SSCCFG] = true; |
|
|
|
} else if (ext_str == "zimop") { |
|
|
|
extension_table[EXT_ZIMOP] = true; |
|
|
|
} else if (ext_str == "zcmop") { |
|
|
|
extension_table[EXT_ZCMOP] = true; |
|
|
|
} else if (ext_str == "zalasr") { |
|
|
|
extension_table[EXT_ZALASR] = true; |
|
|
|
} else if (ext_str == "ssqosid") { |
|
|
|
extension_table[EXT_SSQOSID] = true; |
|
|
|
} else if (ext_str == "zicfilp") { |
|
|
|
extension_table[EXT_ZICFILP] = true; |
|
|
|
} else if (ext_str == "zicfiss") { |
|
|
|
extension_table[EXT_ZICFISS] = true; |
|
|
|
} else if (ext_str == "smmpm") { |
|
|
|
extension_table[EXT_SMMPM] = true; |
|
|
|
} else if (ext_str == "smnpm") { |
|
|
|
extension_table[EXT_SMNPM] = true; |
|
|
|
} else if (ext_str == "ssnpm") { |
|
|
|
extension_table[EXT_SSNPM] = true; |
|
|
|
} else if (ext_str.substr(0, 3) == "zvl") { |
|
|
|
reg_t new_vlen; |
|
|
|
try { |
|
|
|
new_vlen = safe_stoul(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 || ext_str.back() != 'b') |
|
|
|
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") { |
|
|
|
if (ext_str.size() != 6) { |
|
|
|
bad_isa_string(str, ("Invalid Zve string: " + ext_str).c_str()); |
|
|
|
} |
|
|
|
reg_t new_elen; |
|
|
|
try { |
|
|
|
new_elen = safe_stoul(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); |
|
|
|
vlen = std::max(vlen, new_elen); |
|
|
|
} else if (ext_str == "ssdbltrp") { |
|
|
|
extension_table[EXT_SSDBLTRP] = true; |
|
|
|
} else if (ext_str == "smdbltrp") { |
|
|
|
extension_table[EXT_SMDBLTRP] = true; |
|
|
|
} else if (ext_str == "smaia") { |
|
|
|
extension_table[EXT_SMAIA] = true; |
|
|
|
extension_table[EXT_SSAIA] = true; |
|
|
|
extension_table[EXT_SMCSRIND] = true; |
|
|
|
extension_table[EXT_SSCSRIND] = true; |
|
|
|
} else if (ext_str == "ssaia") { |
|
|
|
extension_table[EXT_SSAIA] = true; |
|
|
|
extension_table[EXT_SSCSRIND] = true; |
|
|
|
} else if (ext_str[0] == 'x') { |
|
|
|
extension_table['X'] = true; |
|
|
|
if (ext_str.size() == 1) { |
|
|
|
bad_isa_string(str, "single 'X' is not a proper name"); |
|
|
|
} else if (ext_str != "xdummy") { |
|
|
|
extensions.insert(ext_str.substr(1)); |
|
|
|
} |
|
|
|
} else { |
|
|
|
bad_isa_string(str, ("unsupported extension: " + ext_str).c_str()); |
|
|
|
} |
|
|
|
p = end; |
|
|
|
add_extension(ext_str, str); |
|
|
|
} |
|
|
|
if (*p) { |
|
|
|
bad_isa_string(str, ("can't parse: " + std::string(p)).c_str()); |
|
|
|
@ -478,90 +510,33 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv) |
|
|
|
|
|
|
|
if (extension_table['C']) { |
|
|
|
extension_table[EXT_ZCA] = true; |
|
|
|
if (extension_table['F'] && max_xlen == 32) |
|
|
|
extension_table[EXT_ZCF] = true; |
|
|
|
if (extension_table['D']) |
|
|
|
extension_table[EXT_ZCD] = true; |
|
|
|
} |
|
|
|
|
|
|
|
if (extension_table[EXT_ZCLSD] && extension_table[EXT_ZCF]) { |
|
|
|
bad_isa_string(str, "'Zclsd' extension conflicts with 'Zcf' extensions"); |
|
|
|
if (extension_table['C'] || extension_table[EXT_ZCE]) { |
|
|
|
if (extension_table['F'] && max_xlen == 32) |
|
|
|
extension_table[EXT_ZCF] = true; |
|
|
|
} |
|
|
|
|
|
|
|
if (extension_table[EXT_ZCLSD] && (!extension_table[EXT_ZCA] || !extension_table[EXT_ZILSD])) { |
|
|
|
bad_isa_string(str, "'Zclsd' extension requires 'Zca' and 'Zilsd' extensions"); |
|
|
|
} |
|
|
|
if (extension_table[EXT_ZICFISS] && extension_table[EXT_ZCA]) |
|
|
|
extension_table[EXT_ZCMOP] = true; |
|
|
|
|
|
|
|
if (extension_table[EXT_ZFBFMIN] || extension_table[EXT_ZFHMIN]) { |
|
|
|
extension_table[EXT_INTERNAL_ZFH_MOVE] = true; |
|
|
|
} |
|
|
|
|
|
|
|
if (extension_table[EXT_ZFBFMIN] && (!extension_table['F'])) { |
|
|
|
bad_isa_string(str, "'Zfbfmin' extension requires 'F' extension"); |
|
|
|
} |
|
|
|
|
|
|
|
if (extension_table[EXT_ZVFBFMIN] && (vlen == 0 || !zvf)) { |
|
|
|
bad_isa_string(str, "'Zvfbfmin' extension requires 'Zve32f' extension"); |
|
|
|
} |
|
|
|
|
|
|
|
if (extension_table[EXT_ZVFBFA] && (!has_any_vector() || !extension_table[EXT_ZFBFMIN] || !get_zvf())) { |
|
|
|
bad_isa_string(str, "'zvfbfa' extension requires at least 'Zve32f', and 'Zfbfmin'"); |
|
|
|
} |
|
|
|
|
|
|
|
if (extension_table[EXT_ZVFBFWMA] && (!extension_table[EXT_ZFBFMIN] || !extension_table[EXT_ZVFBFMIN])) { |
|
|
|
bad_isa_string(str, "'Zvfbfwma' extension requires 'Zfbfmin' and 'Zvfbfmin' extensions"); |
|
|
|
} |
|
|
|
|
|
|
|
if (extension_table[EXT_ZVFOFP4MIN] && (!has_any_vector() || !get_zvf())) { |
|
|
|
bad_isa_string(str, "'Zvfofp4min' extension requires either 'V' or 'Zve32f' extension"); |
|
|
|
} |
|
|
|
|
|
|
|
if (extension_table[EXT_ZVFOFP8MIN] && (!has_any_vector() || !get_zvf())) { |
|
|
|
bad_isa_string(str, "'Zvfofp8min' extension requires either 'V' or 'Zve32f' extension"); |
|
|
|
if (extension_table[EXT_ZCLSD] && extension_table[EXT_ZCF]) { |
|
|
|
bad_isa_string(str, "'Zclsd' extension conflicts with 'Zcf' extensions"); |
|
|
|
} |
|
|
|
|
|
|
|
if (extension_table[EXT_ZFINX] && extension_table['F']) { |
|
|
|
bad_isa_string(str, ("Zfinx/Zdinx/Zhinx{min} extensions conflict with 'F/D/Q/Zfh{min}' extensions")); |
|
|
|
} |
|
|
|
|
|
|
|
if (extension_table[EXT_ZCF] && !extension_table['F']) { |
|
|
|
bad_isa_string(str, "'Zcf' extension requires 'F' extension"); |
|
|
|
} |
|
|
|
|
|
|
|
if (extension_table[EXT_ZCD] && !extension_table['D']) { |
|
|
|
bad_isa_string(str, "'Zcd' extension requires 'D' extension"); |
|
|
|
} |
|
|
|
|
|
|
|
if ((extension_table[EXT_ZCMP] || extension_table[EXT_ZCMT]) && extension_table[EXT_ZCD]) { |
|
|
|
bad_isa_string(str, "Zcmp' and 'Zcmt' extensions are incompatible with 'Zcd' extension"); |
|
|
|
} |
|
|
|
|
|
|
|
if ((extension_table[EXT_ZCF] || extension_table[EXT_ZCD] || extension_table[EXT_ZCB] || |
|
|
|
extension_table[EXT_ZCMP] || extension_table[EXT_ZCMT]) && !extension_table[EXT_ZCA]) { |
|
|
|
bad_isa_string(str, "'Zcf/Zcd/Zcb/Zcmp/Zcmt' extensions require 'Zca' extension"); |
|
|
|
} |
|
|
|
|
|
|
|
if (extension_table[EXT_ZACAS] && !extension_table[EXT_ZAAMO]) { |
|
|
|
bad_isa_string(str, "'Zacas' extension requires either the 'A' or the 'Zaamo' extension"); |
|
|
|
} |
|
|
|
|
|
|
|
if (extension_table[EXT_ZABHA] && !extension_table[EXT_ZAAMO]) { |
|
|
|
bad_isa_string(str, "'Zabha' extension requires either the 'A' or the 'Zaamo' extension"); |
|
|
|
} |
|
|
|
|
|
|
|
if (extension_table[EXT_ZAWRS] && !extension_table[EXT_ZALRSC]) { |
|
|
|
bad_isa_string(str, "'Zawrs' extension requires either the 'A' or the 'Zalrsc' extension"); |
|
|
|
} |
|
|
|
|
|
|
|
// When SSE is 0, Zicfiss behavior is defined by Zicmop
|
|
|
|
if (extension_table[EXT_ZICFISS] && !extension_table[EXT_ZIMOP]) { |
|
|
|
bad_isa_string(str, "'Zicfiss' extension requires 'Zimop' extension"); |
|
|
|
} |
|
|
|
|
|
|
|
if (extension_table[EXT_ZICFISS] && extension_table[EXT_ZCA] && |
|
|
|
!extension_table[EXT_ZCMOP]) { |
|
|
|
bad_isa_string(str, "'Zicfiss' extension requires 'Zcmop' extension when `Zca` is supported"); |
|
|
|
} |
|
|
|
#ifdef WORDS_BIGENDIAN |
|
|
|
// Access to the vector registers as element groups is unimplemented on big-endian setups.
|
|
|
|
if (extension_table[EXT_ZVKG] || extension_table[EXT_ZVKNHA] || extension_table[EXT_ZVKNHB] || |
|
|
|
@ -576,22 +551,6 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv) |
|
|
|
bad_isa_string(str, "Spike does not support VLEN > 4096"); |
|
|
|
} |
|
|
|
|
|
|
|
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; |
|
|
|
|
|
|
|
|