diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.cpp b/src/hotspot/cpu/riscv/vm_version_riscv.cpp index 87366116b3b68..ad8d452f50de6 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.cpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.cpp @@ -234,36 +234,6 @@ void VM_Version::common_initialize() { warning("CRC32C intrinsics are not available on this CPU."); FLAG_SET_DEFAULT(UseCRC32CIntrinsics, false); } - - // UseZvbb (depends on RVV). - if (UseZvbb && !UseRVV) { - warning("Cannot enable UseZvbb on cpu without RVV support."); - FLAG_SET_DEFAULT(UseZvbb, false); - } - - // UseZvbc (depends on RVV). - if (UseZvbc && !UseRVV) { - warning("Cannot enable UseZvbc on cpu without RVV support."); - FLAG_SET_DEFAULT(UseZvbc, false); - } - - // UseZvkn (depends on RVV). - if (UseZvkn && !UseRVV) { - warning("Cannot enable UseZvkn on cpu without RVV support."); - FLAG_SET_DEFAULT(UseZvkn, false); - } - - // UseZvfh (depends on RVV) - if (UseZvfh) { - if (!UseRVV) { - warning("Cannot enable UseZvfh on cpu without RVV support."); - FLAG_SET_DEFAULT(UseZvfh, false); - } - if (!UseZfh) { - warning("Cannot enable UseZvfh on cpu without Zfh support."); - FLAG_SET_DEFAULT(UseZvfh, false); - } - } } #ifdef COMPILER2 diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.hpp b/src/hotspot/cpu/riscv/vm_version_riscv.hpp index aec975d27bef3..782f264965d59 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.hpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.hpp @@ -70,6 +70,35 @@ class VM_Version : public Abstract_VM_Version { int64_t value() { return _value; } virtual bool enabled() = 0; virtual void update_flag() = 0; + + protected: + bool deps_all_enabled(RVFeatureValue* dep0, ...) { + assert(dep0 != nullptr, "must not"); + + va_list va; + va_start(va, dep0); + RVFeatureValue* next = dep0; + bool enabled = true; + while (next != nullptr && enabled) { + enabled = next->enabled(); + next = va_arg(va, RVFeatureValue*); + } + va_end(va); + return enabled; + } + + void deps_string(stringStream& ss, RVFeatureValue* dep0, ...) { + assert(dep0 != nullptr, "must not"); + ss.print("%s (%s)", dep0->pretty(), dep0->enabled() ? "enabled" : "disabled"); + + va_list va; + va_start(va, dep0); + RVFeatureValue* next = nullptr; + while ((next = va_arg(va, RVFeatureValue*)) != nullptr) { + ss.print(", %s (%s)", next->pretty(), next->enabled() ? "enabled" : "disabled"); + } + va_end(va); + } }; #define UPDATE_DEFAULT(flag) \ @@ -85,27 +114,34 @@ class VM_Version : public Abstract_VM_Version { } \ } \ - #define UPDATE_DEFAULT_DEP(flag, dep) \ - void update_flag() { \ - assert(enabled(), "Must be."); \ - /* dep must be declared before */ \ - assert((uintptr_t)(this) > \ - (uintptr_t)(&dep), "Invalid"); \ - if (FLAG_IS_DEFAULT(flag)) { \ - if (dep.enabled()) { \ - FLAG_SET_DEFAULT(flag, true); \ - } else { \ - FLAG_SET_DEFAULT(flag, false); \ - /* Sync CPU features with flags */ \ - disable_feature(); \ - } \ - } else { \ - /* Sync CPU features with flags */ \ - if (!flag) { \ - disable_feature(); \ - } \ - } \ - } \ + #define UPDATE_DEFAULT_DEP(flag, dep0, ...) \ + void update_flag() { \ + assert(enabled(), "Must be."); \ + if (FLAG_IS_DEFAULT(flag)) { \ + if (this->deps_all_enabled(dep0, ##__VA_ARGS__)) { \ + FLAG_SET_DEFAULT(flag, true); \ + } else { \ + FLAG_SET_DEFAULT(flag, false); \ + stringStream ss; \ + deps_string(ss, dep0, ##__VA_ARGS__); \ + warning("Cannot enable " #flag ", it's missing dependent extension(s) %s", ss.as_string(true)); \ + /* Sync CPU features with flags */ \ + disable_feature(); \ + } \ + } else { \ + /* Sync CPU features with flags */ \ + if (!flag) { \ + disable_feature(); \ + } else if (!deps_all_enabled(dep0, ##__VA_ARGS__)) { \ + FLAG_SET_DEFAULT(flag, false); \ + stringStream ss; \ + deps_string(ss, dep0, ##__VA_ARGS__); \ + warning("Cannot enable " #flag ", it's missing dependent extension(s) %s", ss.as_string(true)); \ + /* Sync CPU features with flags */ \ + disable_feature(); \ + } \ + } \ + } \ #define NO_UPDATE_DEFAULT \ void update_flag() {} \ @@ -202,40 +238,40 @@ class VM_Version : public Abstract_VM_Version { // // Fields description in `decl`: // declaration name, extension name, bit value from linux, feature string?, mapped flag) - #define RV_EXT_FEATURE_FLAGS(decl) \ - decl(ext_I , i , ('I' - 'A'), true , NO_UPDATE_DEFAULT) \ - decl(ext_M , m , ('M' - 'A'), true , NO_UPDATE_DEFAULT) \ - decl(ext_A , a , ('A' - 'A'), true , NO_UPDATE_DEFAULT) \ - decl(ext_F , f , ('F' - 'A'), true , NO_UPDATE_DEFAULT) \ - decl(ext_D , d , ('D' - 'A'), true , NO_UPDATE_DEFAULT) \ - decl(ext_C , c , ('C' - 'A'), true , UPDATE_DEFAULT(UseRVC)) \ - decl(ext_Q , q , ('Q' - 'A'), true , NO_UPDATE_DEFAULT) \ - decl(ext_H , h , ('H' - 'A'), true , NO_UPDATE_DEFAULT) \ - decl(ext_V , v , ('V' - 'A'), true , UPDATE_DEFAULT(UseRVV)) \ - decl(ext_Zicbom , Zicbom , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicbom)) \ - decl(ext_Zicboz , Zicboz , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicboz)) \ - decl(ext_Zicbop , Zicbop , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicbop)) \ - decl(ext_Zba , Zba , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZba)) \ - decl(ext_Zbb , Zbb , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbb)) \ - decl(ext_Zbc , Zbc , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \ - decl(ext_Zbs , Zbs , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbs)) \ - decl(ext_Zbkb , Zbkb , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbkb)) \ - decl(ext_Zcb , Zcb , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZcb)) \ - decl(ext_Zfa , Zfa , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZfa)) \ - decl(ext_Zfh , Zfh , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZfh)) \ - decl(ext_Zfhmin , Zfhmin , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZfhmin)) \ - decl(ext_Zicsr , Zicsr , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \ - decl(ext_Zicntr , Zicntr , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \ - decl(ext_Zifencei , Zifencei , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \ - decl(ext_Zic64b , Zic64b , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZic64b)) \ - decl(ext_Ztso , Ztso , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZtso)) \ - decl(ext_Zihintpause , Zihintpause , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZihintpause)) \ - decl(ext_Zacas , Zacas , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZacas)) \ - decl(ext_Zvbb , Zvbb , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT_DEP(UseZvbb, ext_V)) \ - decl(ext_Zvbc , Zvbc , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT_DEP(UseZvbc, ext_V)) \ - decl(ext_Zvfh , Zvfh , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT_DEP(UseZvfh, ext_V)) \ - decl(ext_Zvkn , Zvkn , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT_DEP(UseZvkn, ext_V)) \ - decl(ext_Zicond , Zicond , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicond)) \ + #define RV_EXT_FEATURE_FLAGS(decl) \ + decl(ext_I , i , ('I' - 'A'), true , NO_UPDATE_DEFAULT) \ + decl(ext_M , m , ('M' - 'A'), true , NO_UPDATE_DEFAULT) \ + decl(ext_A , a , ('A' - 'A'), true , NO_UPDATE_DEFAULT) \ + decl(ext_F , f , ('F' - 'A'), true , NO_UPDATE_DEFAULT) \ + decl(ext_D , d , ('D' - 'A'), true , NO_UPDATE_DEFAULT) \ + decl(ext_C , c , ('C' - 'A'), true , UPDATE_DEFAULT(UseRVC)) \ + decl(ext_Q , q , ('Q' - 'A'), true , NO_UPDATE_DEFAULT) \ + decl(ext_H , h , ('H' - 'A'), true , NO_UPDATE_DEFAULT) \ + decl(ext_V , v , ('V' - 'A'), true , UPDATE_DEFAULT(UseRVV)) \ + decl(ext_Zicbom , Zicbom , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicbom)) \ + decl(ext_Zicboz , Zicboz , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicboz)) \ + decl(ext_Zicbop , Zicbop , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicbop)) \ + decl(ext_Zba , Zba , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZba)) \ + decl(ext_Zbb , Zbb , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbb)) \ + decl(ext_Zbc , Zbc , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \ + decl(ext_Zbs , Zbs , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbs)) \ + decl(ext_Zbkb , Zbkb , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbkb)) \ + decl(ext_Zcb , Zcb , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZcb)) \ + decl(ext_Zfa , Zfa , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZfa)) \ + decl(ext_Zfh , Zfh , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZfh)) \ + decl(ext_Zfhmin , Zfhmin , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZfhmin)) \ + decl(ext_Zicsr , Zicsr , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \ + decl(ext_Zicntr , Zicntr , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \ + decl(ext_Zifencei , Zifencei , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \ + decl(ext_Zic64b , Zic64b , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZic64b)) \ + decl(ext_Ztso , Ztso , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZtso)) \ + decl(ext_Zihintpause , Zihintpause , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZihintpause)) \ + decl(ext_Zacas , Zacas , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZacas)) \ + decl(ext_Zvbb , Zvbb , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT_DEP(UseZvbb, &ext_V, nullptr)) \ + decl(ext_Zvbc , Zvbc , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT_DEP(UseZvbc, &ext_V, nullptr)) \ + decl(ext_Zvfh , Zvfh , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT_DEP(UseZvfh, &ext_V, &ext_Zfh, nullptr)) \ + decl(ext_Zvkn , Zvkn , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT_DEP(UseZvkn, &ext_V, nullptr)) \ + decl(ext_Zicond , Zicond , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicond)) \ #define DECLARE_RV_EXT_FEATURE(NAME, PRETTY, LINUX_BIT, FSTRING, FLAGF) \ struct NAME##RVExtFeatureValue : public RVExtFeatureValue { \