From a3bb9137b7d4f2d25a2600d4c17e052ad9e4c891 Mon Sep 17 00:00:00 2001 From: hamlin Date: Mon, 8 Sep 2025 09:58:26 +0000 Subject: [PATCH 01/13] initial commit --- src/hotspot/cpu/riscv/vm_version_riscv.cpp | 16 +- src/hotspot/cpu/riscv/vm_version_riscv.hpp | 211 +++++++++++++++------ 2 files changed, 168 insertions(+), 59 deletions(-) diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.cpp b/src/hotspot/cpu/riscv/vm_version_riscv.cpp index 4b437896dcda5..f35e45d236c58 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.cpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.cpp @@ -35,15 +35,19 @@ uint32_t VM_Version::_initial_vector_length = 0; -#define DEF_RV_FEATURE(NAME, PRETTY, BIT, FSTRING, FLAGF) \ -VM_Version::NAME##RVFeatureValue VM_Version::NAME(PRETTY, BIT, FSTRING); +#define DEF_RV_FEATURE(NAME, PRETTY, LINUX_BIT, CPU_FEATURE_INDEX, FSTRING, FLAGF) \ +VM_Version::NAME##RVFeatureValue VM_Version::NAME(#PRETTY, LINUX_BIT, CPU_FEATURE_INDEX, FSTRING); RV_FEATURE_FLAGS(DEF_RV_FEATURE) +#undef DEF_RV_FEATURE -#define ADD_RV_FEATURE_IN_LIST(NAME, PRETTY, BIT, FSTRING, FLAGF) \ - &VM_Version::NAME, -VM_Version::RVFeatureValue* VM_Version::_feature_list[] = { -RV_FEATURE_FLAGS(ADD_RV_FEATURE_IN_LIST) +#define ADD_RV_FEATURE_IN_LIST(NAME, PRETTY, LINUX_BIT, CPU_FEATURE_INDEX, FSTRING, FLAGF) \ + &VM_Version::NAME, + VM_Version::RVFeatureValue* VM_Version::_feature_list[] = { + RV_FEATURE_FLAGS(ADD_RV_FEATURE_IN_LIST) nullptr}; +#undef ADD_RV_FEATURE_IN_LIST + +VM_Version::RVFeatures* VM_Version::_rv_features = new VM_Version::RVFeatures(); void VM_Version::useRVA20U64Profile() { RV_USE_RVA20U64; diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.hpp b/src/hotspot/cpu/riscv/vm_version_riscv.hpp index a0a42fb546336..e9c3a0587f90c 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.hpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.hpp @@ -46,27 +46,33 @@ class VM_Version : public Abstract_VM_Version { RIVOS = 0x6cf, // JEDEC: 0x4f, Bank: 14 }; + class RVFeatures; + class RVFeatureValue { const char* const _pretty; const bool _feature_string; - const uint64_t _feature_bit; + const uint64_t _linux_feature_bit; + const uint32_t _cpu_feature_index; bool _enabled; int64_t _value; public: - RVFeatureValue(const char* pretty, int bit_num, bool fstring) : - _pretty(pretty), _feature_string(fstring), _feature_bit(nth_bit(bit_num)), - _enabled(false), _value(-1) { + RVFeatureValue(const char* pretty, int linux_bit_num, uint32_t cpu_feature_index, bool fstring) : + _pretty(pretty), _feature_string(fstring), _linux_feature_bit(nth_bit(linux_bit_num)), + _cpu_feature_index(cpu_feature_index), _enabled(false), _value(-1) { } void enable_feature(int64_t value = 0) { _enabled = true; _value = value; + RVFeatures::own()->set_feature(_cpu_feature_index); } + // TODO: when user override the default VM flag, needs to enable or disable the CPU feature accordingly. void disable_feature() { _enabled = false; _value = -1; + RVFeatures::own()->clear_feature(_cpu_feature_index); } const char* pretty() { return _pretty; } - uint64_t feature_bit() { return _feature_bit; } + uint64_t feature_bit() { return _linux_feature_bit; } bool feature_string() { return _feature_string; } bool enabled() { return _enabled; } int64_t value() { return _value; } @@ -159,58 +165,155 @@ class VM_Version : public Abstract_VM_Version { #define RV_NO_FLAG_BIT (BitsPerWord+1) // nth_bit will return 0 on values larger than BitsPerWord // Note: the order matters, depender should be after their dependee. E.g. ext_V before ext_Zvbb. - // declaration name , extension name, bit pos ,in str, mapped flag) - #define RV_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)) \ - decl(mvendorid , "VendorId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ - decl(marchid , "ArchId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ - decl(mimpid , "ImpId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ - decl(unaligned_access, "Unaligned" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ - decl(satp_mode , "SATP" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ - - #define DECLARE_RV_FEATURE(NAME, PRETTY, BIT, FSTRING, FLAGF) \ - struct NAME##RVFeatureValue : public RVFeatureValue { \ - NAME##RVFeatureValue(const char* pretty, int bit, bool fstring) : \ - RVFeatureValue(pretty, bit, fstring) {} \ - FLAGF; \ - }; \ - static NAME##RVFeatureValue NAME; \ + // + // Fields description in `decl`: + // declaration name, extension name, bit value from linux, cpu feature index, feature string?, mapped flag) + #define RV_FEATURE_FLAGS(decl) \ + decl(ext_I , i , ('I' - 'A'), 0, true , NO_UPDATE_DEFAULT) \ + decl(ext_M , m , ('M' - 'A'), 1, true , NO_UPDATE_DEFAULT) \ + decl(ext_A , a , ('A' - 'A'), 2, true , NO_UPDATE_DEFAULT) \ + decl(ext_F , f , ('F' - 'A'), 3, true , NO_UPDATE_DEFAULT) \ + decl(ext_D , d , ('D' - 'A'), 4, true , NO_UPDATE_DEFAULT) \ + decl(ext_C , c , ('C' - 'A'), 5, true , UPDATE_DEFAULT(UseRVC)) \ + decl(ext_Q , q , ('Q' - 'A'), 6, true , NO_UPDATE_DEFAULT) \ + decl(ext_H , h , ('H' - 'A'), 7, true , NO_UPDATE_DEFAULT) \ + decl(ext_V , v , ('V' - 'A'), 8, true , UPDATE_DEFAULT(UseRVV)) \ + decl(ext_Zicbom , Zicbom , RV_NO_FLAG_BIT, 9, true , UPDATE_DEFAULT(UseZicbom)) \ + decl(ext_Zicboz , Zicboz , RV_NO_FLAG_BIT, 10, true , UPDATE_DEFAULT(UseZicboz)) \ + decl(ext_Zicbop , Zicbop , RV_NO_FLAG_BIT, 11, true , UPDATE_DEFAULT(UseZicbop)) \ + decl(ext_Zba , Zba , RV_NO_FLAG_BIT, 12, true , UPDATE_DEFAULT(UseZba)) \ + decl(ext_Zbb , Zbb , RV_NO_FLAG_BIT, 13, true , UPDATE_DEFAULT(UseZbb)) \ + decl(ext_Zbc , Zbc , RV_NO_FLAG_BIT, 14, true , NO_UPDATE_DEFAULT) \ + decl(ext_Zbs , Zbs , RV_NO_FLAG_BIT, 15, true , UPDATE_DEFAULT(UseZbs)) \ + decl(ext_Zbkb , Zbkb , RV_NO_FLAG_BIT, 16, true , UPDATE_DEFAULT(UseZbkb)) \ + decl(ext_Zcb , Zcb , RV_NO_FLAG_BIT, 17, true , UPDATE_DEFAULT(UseZcb)) \ + decl(ext_Zfa , Zfa , RV_NO_FLAG_BIT, 18, true , UPDATE_DEFAULT(UseZfa)) \ + decl(ext_Zfh , Zfh , RV_NO_FLAG_BIT, 19, true , UPDATE_DEFAULT(UseZfh)) \ + decl(ext_Zfhmin , Zfhmin , RV_NO_FLAG_BIT, 20, true , UPDATE_DEFAULT(UseZfhmin)) \ + decl(ext_Zicsr , Zicsr , RV_NO_FLAG_BIT, 21, true , NO_UPDATE_DEFAULT) \ + decl(ext_Zicntr , Zicntr , RV_NO_FLAG_BIT, 22, true , NO_UPDATE_DEFAULT) \ + decl(ext_Zifencei , Zifencei , RV_NO_FLAG_BIT, 23, true , NO_UPDATE_DEFAULT) \ + decl(ext_Zic64b , Zic64b , RV_NO_FLAG_BIT, 24, true , UPDATE_DEFAULT(UseZic64b)) \ + decl(ext_Ztso , Ztso , RV_NO_FLAG_BIT, 25, true , UPDATE_DEFAULT(UseZtso)) \ + decl(ext_Zihintpause , Zihintpause , RV_NO_FLAG_BIT, 26, true , UPDATE_DEFAULT(UseZihintpause)) \ + decl(ext_Zacas , Zacas , RV_NO_FLAG_BIT, 27, true , UPDATE_DEFAULT(UseZacas)) \ + decl(ext_Zvbb , Zvbb , RV_NO_FLAG_BIT, 28, true , UPDATE_DEFAULT_DEP(UseZvbb, ext_V)) \ + decl(ext_Zvbc , Zvbc , RV_NO_FLAG_BIT, 29, true , UPDATE_DEFAULT_DEP(UseZvbc, ext_V)) \ + decl(ext_Zvfh , Zvfh , RV_NO_FLAG_BIT, 30, true , UPDATE_DEFAULT_DEP(UseZvfh, ext_V)) \ + decl(ext_Zvkn , Zvkn , RV_NO_FLAG_BIT, 31, true , UPDATE_DEFAULT_DEP(UseZvkn, ext_V)) \ + decl(ext_Zicond , Zicond , RV_NO_FLAG_BIT, 32, true , UPDATE_DEFAULT(UseZicond)) \ + decl(unaligned_access , Unaligned , RV_NO_FLAG_BIT, 33, false, NO_UPDATE_DEFAULT) \ + decl(mvendorid , VendorId , RV_NO_FLAG_BIT, 34, false, NO_UPDATE_DEFAULT) \ + decl(marchid , ArchId , RV_NO_FLAG_BIT, 35, false, NO_UPDATE_DEFAULT) \ + decl(mimpid , ImpId , RV_NO_FLAG_BIT, 36, false, NO_UPDATE_DEFAULT) \ + decl(satp_mode , SATP , RV_NO_FLAG_BIT, 37, false, NO_UPDATE_DEFAULT) \ + + #define DECLARE_RV_FEATURE(NAME, PRETTY, LINUX_BIT, CPU_FEATURE_INDEX, FSTRING, FLAGF) \ + struct NAME##RVFeatureValue : public RVFeatureValue { \ + NAME##RVFeatureValue(const char* pretty, int linux_bit_num, uint32_t cpu_feature_index, bool fstring) : \ + RVFeatureValue(pretty, linux_bit_num, cpu_feature_index, fstring) {} \ + FLAGF; \ + }; \ + static NAME##RVFeatureValue NAME; \ + // TODO: move `NAME##RVFeatureValue NAME` into RVFeatures RV_FEATURE_FLAGS(DECLARE_RV_FEATURE) #undef DECLARE_RV_FEATURE +private: + // Utility for AOT CPU feature store/check. + class RVFeatures : public CHeapObj { + public: + enum RVFeatureIndex { + #define DECLARE_RV_FEATURE_ENUM(NAME, PRETTY, LINUX_BIT, CPU_FEATURE_INDEX, FSTRING, FLAGF) CPU_##NAME=(CPU_FEATURE_INDEX), + + RV_FEATURE_FLAGS(DECLARE_RV_FEATURE_ENUM) + MAX_CPU_FEATURE_INDEX + #undef DECLARE_RV_FEATURE_ENUM + }; + private: + // TODO: move VM_Version::_feature_list here. + // static RVFeatureValue* _feature_list[] = { + // RV_FEATURE_FLAGS(ADD_RV_FEATURE_IN_LIST) + // nullptr + // }; + // #undef ADD_RV_FEATURE_IN_LIST + + uint64_t _features_bitmap[(MAX_CPU_FEATURE_INDEX / BitsPerLong) + 1]; + STATIC_ASSERT(sizeof(_features_bitmap) * BitsPerByte >= MAX_CPU_FEATURE_INDEX); + + // Number of 8-byte elements in _bitmap. + constexpr static int features_bitmap_element_count() { + return sizeof(_features_bitmap) / sizeof(uint64_t); + } + + constexpr static int features_bitmap_element_shift_count() { + return LogBitsPerLong; + } + + constexpr static uint64_t features_bitmap_element_mask() { + return (1ULL << features_bitmap_element_shift_count()) - 1; + } + + static int index(RVFeatureIndex feature) { + int idx = feature >> features_bitmap_element_shift_count(); + assert(idx < features_bitmap_element_count(), "Features array index out of bounds"); + return idx; + } + + static uint64_t bit_mask(RVFeatureIndex feature) { + return (1ULL << (feature & features_bitmap_element_mask())); + } + + static RVFeatureIndex convert(uint32_t index) { + assert(index < MAX_CPU_FEATURE_INDEX, "must"); + return (RVFeatureIndex)index; + } + + public: + static RVFeatures* own() { + return _rv_features; + } + + RVFeatures() { + for (int i = 0; i < features_bitmap_element_count(); i++) { + _features_bitmap[i] = 0; + } + } + + void set_feature(uint32_t feature) { + RVFeatureIndex f = convert(feature); + int idx = index(f); + _features_bitmap[idx] |= bit_mask(f); + } + + void clear_feature(uint32_t feature) { + RVFeatureIndex f = convert(feature); + int idx = index(f); + _features_bitmap[idx] &= ~bit_mask(f); + } + + bool supports_feature(uint32_t feature) { + RVFeatureIndex f = convert(feature); + int idx = index(f); + return (_features_bitmap[idx] & bit_mask(f)) != 0; + } + + bool supports_features(RVFeatures* features_to_test) { + for (int i = 0; i < features_bitmap_element_count(); i++) { + if ((_features_bitmap[i] & features_to_test->_features_bitmap[i]) != features_to_test->_features_bitmap[i]) { + return false; + } + } + return true; + } + + RVFeatureValue* operator [](int cpu_feature_index) { + assert(cpu_feature_index < MAX_CPU_FEATURE_INDEX - 1, "must"); + return VM_Version::_feature_list[cpu_feature_index]; + } + }; + // enable extensions based on profile, current supported profiles: // RVA20U64 // RVA22U64 @@ -281,8 +384,10 @@ class VM_Version : public Abstract_VM_Version { MISALIGNED_UNSUPPORTED = 4 }; + // TODO: move into RVFeatures // Null terminated list static RVFeatureValue* _feature_list[]; + static RVFeatures* _rv_features; // Enables features in _feature_list static void setup_cpu_available_features(); From 39deeb8fd4f769ad49bf319aa9ebc359c8bb1096 Mon Sep 17 00:00:00 2001 From: hamlin Date: Mon, 8 Sep 2025 13:11:11 +0000 Subject: [PATCH 02/13] rename own to current --- src/hotspot/cpu/riscv/vm_version_riscv.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.hpp b/src/hotspot/cpu/riscv/vm_version_riscv.hpp index e9c3a0587f90c..5c714e8eff1f0 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.hpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.hpp @@ -63,13 +63,13 @@ class VM_Version : public Abstract_VM_Version { void enable_feature(int64_t value = 0) { _enabled = true; _value = value; - RVFeatures::own()->set_feature(_cpu_feature_index); + RVFeatures::current()->set_feature(_cpu_feature_index); } // TODO: when user override the default VM flag, needs to enable or disable the CPU feature accordingly. void disable_feature() { _enabled = false; _value = -1; - RVFeatures::own()->clear_feature(_cpu_feature_index); + RVFeatures::current()->clear_feature(_cpu_feature_index); } const char* pretty() { return _pretty; } uint64_t feature_bit() { return _linux_feature_bit; } @@ -271,7 +271,7 @@ class VM_Version : public Abstract_VM_Version { } public: - static RVFeatures* own() { + static RVFeatures* current() { return _rv_features; } From 0b6fe73dccf262ea1a779a0984a9aa17f8df83e8 Mon Sep 17 00:00:00 2001 From: hamlin Date: Mon, 8 Sep 2025 13:19:33 +0000 Subject: [PATCH 03/13] remove RVFeatureValue::_enabled --- src/hotspot/cpu/riscv/vm_version_riscv.hpp | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.hpp b/src/hotspot/cpu/riscv/vm_version_riscv.hpp index 5c714e8eff1f0..bfe840152aec0 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.hpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.hpp @@ -53,28 +53,24 @@ class VM_Version : public Abstract_VM_Version { const bool _feature_string; const uint64_t _linux_feature_bit; const uint32_t _cpu_feature_index; - bool _enabled; int64_t _value; public: RVFeatureValue(const char* pretty, int linux_bit_num, uint32_t cpu_feature_index, bool fstring) : _pretty(pretty), _feature_string(fstring), _linux_feature_bit(nth_bit(linux_bit_num)), - _cpu_feature_index(cpu_feature_index), _enabled(false), _value(-1) { + _cpu_feature_index(cpu_feature_index), _value(-1) { } void enable_feature(int64_t value = 0) { - _enabled = true; _value = value; RVFeatures::current()->set_feature(_cpu_feature_index); } - // TODO: when user override the default VM flag, needs to enable or disable the CPU feature accordingly. void disable_feature() { - _enabled = false; _value = -1; RVFeatures::current()->clear_feature(_cpu_feature_index); } const char* pretty() { return _pretty; } uint64_t feature_bit() { return _linux_feature_bit; } bool feature_string() { return _feature_string; } - bool enabled() { return _enabled; } + bool enabled() { return RVFeatures::current()->supports_feature(_cpu_feature_index); } int64_t value() { return _value; } virtual void update_flag() = 0; }; @@ -215,7 +211,6 @@ class VM_Version : public Abstract_VM_Version { FLAGF; \ }; \ static NAME##RVFeatureValue NAME; \ - // TODO: move `NAME##RVFeatureValue NAME` into RVFeatures RV_FEATURE_FLAGS(DECLARE_RV_FEATURE) #undef DECLARE_RV_FEATURE @@ -232,13 +227,6 @@ class VM_Version : public Abstract_VM_Version { #undef DECLARE_RV_FEATURE_ENUM }; private: - // TODO: move VM_Version::_feature_list here. - // static RVFeatureValue* _feature_list[] = { - // RV_FEATURE_FLAGS(ADD_RV_FEATURE_IN_LIST) - // nullptr - // }; - // #undef ADD_RV_FEATURE_IN_LIST - uint64_t _features_bitmap[(MAX_CPU_FEATURE_INDEX / BitsPerLong) + 1]; STATIC_ASSERT(sizeof(_features_bitmap) * BitsPerByte >= MAX_CPU_FEATURE_INDEX); From 9c1df0956669a1bee28f320c2ec852285f5c249a Mon Sep 17 00:00:00 2001 From: hamlin Date: Mon, 8 Sep 2025 19:06:21 +0000 Subject: [PATCH 04/13] split extension and non-extension features --- src/hotspot/cpu/riscv/vm_version_riscv.cpp | 23 +++-- src/hotspot/cpu/riscv/vm_version_riscv.hpp | 115 ++++++++++++++------- 2 files changed, 91 insertions(+), 47 deletions(-) diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.cpp b/src/hotspot/cpu/riscv/vm_version_riscv.cpp index f35e45d236c58..552f0ec220ebf 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.cpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.cpp @@ -35,17 +35,26 @@ uint32_t VM_Version::_initial_vector_length = 0; -#define DEF_RV_FEATURE(NAME, PRETTY, LINUX_BIT, CPU_FEATURE_INDEX, FSTRING, FLAGF) \ -VM_Version::NAME##RVFeatureValue VM_Version::NAME(#PRETTY, LINUX_BIT, CPU_FEATURE_INDEX, FSTRING); -RV_FEATURE_FLAGS(DEF_RV_FEATURE) -#undef DEF_RV_FEATURE +#define DEF_RV_EXT_FEATURE(NAME, PRETTY, LINUX_BIT, CPU_FEATURE_INDEX, FSTRING, FLAGF) \ +VM_Version::NAME##RVExtFeatureValue VM_Version::NAME(#PRETTY, LINUX_BIT, CPU_FEATURE_INDEX, FSTRING); +RV_EXT_FEATURE_FLAGS(DEF_RV_EXT_FEATURE) +#undef DEF_RV_EXT_FEATURE -#define ADD_RV_FEATURE_IN_LIST(NAME, PRETTY, LINUX_BIT, CPU_FEATURE_INDEX, FSTRING, FLAGF) \ +#define DEF_RV_NON_EXT_FEATURE(NAME, PRETTY, LINUX_BIT, FSTRING, FLAGF) \ +VM_Version::NAME##RVNonExtFeatureValue VM_Version::NAME(#PRETTY, LINUX_BIT, FSTRING); +RV_NON_EXT_FEATURE_FLAGS(DEF_RV_NON_EXT_FEATURE) +#undef DEF_RV_NON_EXT_FEATURE + +#define ADD_RV_EXT_FEATURE_IN_LIST(NAME, PRETTY, LINUX_BIT, CPU_FEATURE_INDEX, FSTRING, FLAGF) \ + &VM_Version::NAME, +#define ADD_RV_NON_EXT_FEATURE_IN_LIST(NAME, PRETTY, LINUX_BIT, FSTRING, FLAGF) \ &VM_Version::NAME, VM_Version::RVFeatureValue* VM_Version::_feature_list[] = { - RV_FEATURE_FLAGS(ADD_RV_FEATURE_IN_LIST) + RV_EXT_FEATURE_FLAGS(ADD_RV_EXT_FEATURE_IN_LIST) + RV_NON_EXT_FEATURE_FLAGS(ADD_RV_NON_EXT_FEATURE_IN_LIST) nullptr}; -#undef ADD_RV_FEATURE_IN_LIST +#undef ADD_RV_NON_EXT_FEATURE_IN_LIST +#undef ADD_RV_EXT_FEATURE_IN_LIST VM_Version::RVFeatures* VM_Version::_rv_features = new VM_Version::RVFeatures(); diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.hpp b/src/hotspot/cpu/riscv/vm_version_riscv.hpp index bfe840152aec0..defbc7c6b74bd 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.hpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.hpp @@ -52,26 +52,23 @@ class VM_Version : public Abstract_VM_Version { const char* const _pretty; const bool _feature_string; const uint64_t _linux_feature_bit; - const uint32_t _cpu_feature_index; int64_t _value; public: - RVFeatureValue(const char* pretty, int linux_bit_num, uint32_t cpu_feature_index, bool fstring) : + RVFeatureValue(const char* pretty, int linux_bit_num, bool fstring) : _pretty(pretty), _feature_string(fstring), _linux_feature_bit(nth_bit(linux_bit_num)), - _cpu_feature_index(cpu_feature_index), _value(-1) { + _value(-1) { } - void enable_feature(int64_t value = 0) { + virtual void enable_feature(int64_t value = 0) { _value = value; - RVFeatures::current()->set_feature(_cpu_feature_index); } - void disable_feature() { + virtual void disable_feature() { _value = -1; - RVFeatures::current()->clear_feature(_cpu_feature_index); } const char* pretty() { return _pretty; } uint64_t feature_bit() { return _linux_feature_bit; } bool feature_string() { return _feature_string; } - bool enabled() { return RVFeatures::current()->supports_feature(_cpu_feature_index); } int64_t value() { return _value; } + virtual bool enabled() = 0; virtual void update_flag() = 0; }; @@ -111,6 +108,45 @@ class VM_Version : public Abstract_VM_Version { #define NO_UPDATE_DEFAULT \ void update_flag() {} \ + + class RVExtFeatureValue : public RVFeatureValue { + const uint32_t _cpu_feature_index; + public: + RVExtFeatureValue(const char* pretty, int linux_bit_num, uint32_t cpu_feature_index, bool fstring) : + RVFeatureValue(pretty, linux_bit_num, fstring), + _cpu_feature_index(cpu_feature_index) { + } + bool enabled() { + return RVFeatures::current()->supports_feature(_cpu_feature_index); + } + void enable_feature(int64_t value = 0) { + RVFeatureValue::enable_feature(value); + RVFeatures::current()->set_feature(_cpu_feature_index); + } + void disable_feature() { + RVFeatureValue::disable_feature(); + RVFeatures::current()->clear_feature(_cpu_feature_index); + } + }; + + class RVNonExtFeatureValue : public RVFeatureValue { + bool _enabled; + public: + RVNonExtFeatureValue(const char* pretty, int linux_bit_num, bool fstring) : + RVFeatureValue(pretty, linux_bit_num, fstring), + _enabled(false) { + } + bool enabled() { return _enabled; } + void enable_feature(int64_t value = 0) { + RVFeatureValue::enable_feature(value); + _enabled = true; + } + void disable_feature() { + RVFeatureValue::disable_feature(); + _enabled = false; + } + }; + // Frozen standard extensions // I RV64I // M Integer Multiplication and Division @@ -164,7 +200,7 @@ class VM_Version : public Abstract_VM_Version { // // Fields description in `decl`: // declaration name, extension name, bit value from linux, cpu feature index, feature string?, mapped flag) - #define RV_FEATURE_FLAGS(decl) \ + #define RV_EXT_FEATURE_FLAGS(decl) \ decl(ext_I , i , ('I' - 'A'), 0, true , NO_UPDATE_DEFAULT) \ decl(ext_M , m , ('M' - 'A'), 1, true , NO_UPDATE_DEFAULT) \ decl(ext_A , a , ('A' - 'A'), 2, true , NO_UPDATE_DEFAULT) \ @@ -198,22 +234,35 @@ class VM_Version : public Abstract_VM_Version { decl(ext_Zvfh , Zvfh , RV_NO_FLAG_BIT, 30, true , UPDATE_DEFAULT_DEP(UseZvfh, ext_V)) \ decl(ext_Zvkn , Zvkn , RV_NO_FLAG_BIT, 31, true , UPDATE_DEFAULT_DEP(UseZvkn, ext_V)) \ decl(ext_Zicond , Zicond , RV_NO_FLAG_BIT, 32, true , UPDATE_DEFAULT(UseZicond)) \ - decl(unaligned_access , Unaligned , RV_NO_FLAG_BIT, 33, false, NO_UPDATE_DEFAULT) \ - decl(mvendorid , VendorId , RV_NO_FLAG_BIT, 34, false, NO_UPDATE_DEFAULT) \ - decl(marchid , ArchId , RV_NO_FLAG_BIT, 35, false, NO_UPDATE_DEFAULT) \ - decl(mimpid , ImpId , RV_NO_FLAG_BIT, 36, false, NO_UPDATE_DEFAULT) \ - decl(satp_mode , SATP , RV_NO_FLAG_BIT, 37, false, NO_UPDATE_DEFAULT) \ - - #define DECLARE_RV_FEATURE(NAME, PRETTY, LINUX_BIT, CPU_FEATURE_INDEX, FSTRING, FLAGF) \ - struct NAME##RVFeatureValue : public RVFeatureValue { \ - NAME##RVFeatureValue(const char* pretty, int linux_bit_num, uint32_t cpu_feature_index, bool fstring) : \ - RVFeatureValue(pretty, linux_bit_num, cpu_feature_index, fstring) {} \ - FLAGF; \ - }; \ - static NAME##RVFeatureValue NAME; \ - - RV_FEATURE_FLAGS(DECLARE_RV_FEATURE) - #undef DECLARE_RV_FEATURE + + #define DECLARE_RV_EXT_FEATURE(NAME, PRETTY, LINUX_BIT, CPU_FEATURE_INDEX, FSTRING, FLAGF) \ + struct NAME##RVExtFeatureValue : public RVExtFeatureValue { \ + NAME##RVExtFeatureValue(const char* pretty, int linux_bit_num, uint32_t cpu_feature_index, bool fstring) : \ + RVExtFeatureValue(pretty, linux_bit_num, cpu_feature_index, fstring) {} \ + FLAGF; \ + }; \ + static NAME##RVExtFeatureValue NAME; \ + + RV_EXT_FEATURE_FLAGS(DECLARE_RV_EXT_FEATURE) + + // Non-extension features + // + #define RV_NON_EXT_FEATURE_FLAGS(decl) \ + decl(unaligned_access , Unaligned , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ + decl(mvendorid , VendorId , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ + decl(marchid , ArchId , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ + decl(mimpid , ImpId , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ + decl(satp_mode , SATP , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ + + #define DECLARE_RV_NON_EXT_FEATURE(NAME, PRETTY, LINUX_BIT, FSTRING, FLAGF) \ + struct NAME##RVNonExtFeatureValue : public RVNonExtFeatureValue { \ + NAME##RVNonExtFeatureValue(const char* pretty, int linux_bit_num, bool fstring) : \ + RVNonExtFeatureValue(pretty, linux_bit_num, fstring) {} \ + FLAGF; \ + }; \ + static NAME##RVNonExtFeatureValue NAME; \ + + RV_NON_EXT_FEATURE_FLAGS(DECLARE_RV_NON_EXT_FEATURE) private: // Utility for AOT CPU feature store/check. @@ -222,7 +271,7 @@ class VM_Version : public Abstract_VM_Version { enum RVFeatureIndex { #define DECLARE_RV_FEATURE_ENUM(NAME, PRETTY, LINUX_BIT, CPU_FEATURE_INDEX, FSTRING, FLAGF) CPU_##NAME=(CPU_FEATURE_INDEX), - RV_FEATURE_FLAGS(DECLARE_RV_FEATURE_ENUM) + RV_EXT_FEATURE_FLAGS(DECLARE_RV_FEATURE_ENUM) MAX_CPU_FEATURE_INDEX #undef DECLARE_RV_FEATURE_ENUM }; @@ -286,20 +335,6 @@ class VM_Version : public Abstract_VM_Version { int idx = index(f); return (_features_bitmap[idx] & bit_mask(f)) != 0; } - - bool supports_features(RVFeatures* features_to_test) { - for (int i = 0; i < features_bitmap_element_count(); i++) { - if ((_features_bitmap[i] & features_to_test->_features_bitmap[i]) != features_to_test->_features_bitmap[i]) { - return false; - } - } - return true; - } - - RVFeatureValue* operator [](int cpu_feature_index) { - assert(cpu_feature_index < MAX_CPU_FEATURE_INDEX - 1, "must"); - return VM_Version::_feature_list[cpu_feature_index]; - } }; // enable extensions based on profile, current supported profiles: From 9c6c32f8ae6c357474de2036773c243222a76bc8 Mon Sep 17 00:00:00 2001 From: hamlin Date: Mon, 8 Sep 2025 19:50:21 +0000 Subject: [PATCH 05/13] refine --- src/hotspot/cpu/riscv/vm_version_riscv.cpp | 2 +- src/hotspot/cpu/riscv/vm_version_riscv.hpp | 21 ++++++++++----------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.cpp b/src/hotspot/cpu/riscv/vm_version_riscv.cpp index 552f0ec220ebf..f6c8fac16431e 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.cpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.cpp @@ -56,7 +56,7 @@ RV_NON_EXT_FEATURE_FLAGS(DEF_RV_NON_EXT_FEATURE) #undef ADD_RV_NON_EXT_FEATURE_IN_LIST #undef ADD_RV_EXT_FEATURE_IN_LIST -VM_Version::RVFeatures* VM_Version::_rv_features = new VM_Version::RVFeatures(); +VM_Version::RVExtFeatures* VM_Version::_rv_ext_features = new VM_Version::RVExtFeatures(); void VM_Version::useRVA20U64Profile() { RV_USE_RVA20U64; diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.hpp b/src/hotspot/cpu/riscv/vm_version_riscv.hpp index defbc7c6b74bd..4e5833e10882f 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.hpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.hpp @@ -46,7 +46,7 @@ class VM_Version : public Abstract_VM_Version { RIVOS = 0x6cf, // JEDEC: 0x4f, Bank: 14 }; - class RVFeatures; + class RVExtFeatures; class RVFeatureValue { const char* const _pretty; @@ -117,15 +117,15 @@ class VM_Version : public Abstract_VM_Version { _cpu_feature_index(cpu_feature_index) { } bool enabled() { - return RVFeatures::current()->supports_feature(_cpu_feature_index); + return RVExtFeatures::current()->supports_feature(_cpu_feature_index); } void enable_feature(int64_t value = 0) { RVFeatureValue::enable_feature(value); - RVFeatures::current()->set_feature(_cpu_feature_index); + RVExtFeatures::current()->set_feature(_cpu_feature_index); } void disable_feature() { RVFeatureValue::disable_feature(); - RVFeatures::current()->clear_feature(_cpu_feature_index); + RVExtFeatures::current()->clear_feature(_cpu_feature_index); } }; @@ -266,7 +266,7 @@ class VM_Version : public Abstract_VM_Version { private: // Utility for AOT CPU feature store/check. - class RVFeatures : public CHeapObj { + class RVExtFeatures : public CHeapObj { public: enum RVFeatureIndex { #define DECLARE_RV_FEATURE_ENUM(NAME, PRETTY, LINUX_BIT, CPU_FEATURE_INDEX, FSTRING, FLAGF) CPU_##NAME=(CPU_FEATURE_INDEX), @@ -279,7 +279,7 @@ class VM_Version : public Abstract_VM_Version { uint64_t _features_bitmap[(MAX_CPU_FEATURE_INDEX / BitsPerLong) + 1]; STATIC_ASSERT(sizeof(_features_bitmap) * BitsPerByte >= MAX_CPU_FEATURE_INDEX); - // Number of 8-byte elements in _bitmap. + // Number of 8-byte elements in _features_bitmap. constexpr static int features_bitmap_element_count() { return sizeof(_features_bitmap) / sizeof(uint64_t); } @@ -308,11 +308,11 @@ class VM_Version : public Abstract_VM_Version { } public: - static RVFeatures* current() { - return _rv_features; + static RVExtFeatures* current() { + return _rv_ext_features; } - RVFeatures() { + RVExtFeatures() { for (int i = 0; i < features_bitmap_element_count(); i++) { _features_bitmap[i] = 0; } @@ -407,10 +407,9 @@ class VM_Version : public Abstract_VM_Version { MISALIGNED_UNSUPPORTED = 4 }; - // TODO: move into RVFeatures // Null terminated list static RVFeatureValue* _feature_list[]; - static RVFeatures* _rv_features; + static RVExtFeatures* _rv_ext_features; // Enables features in _feature_list static void setup_cpu_available_features(); From e27247ba8fb95ab7b4872c63fb684cb95344d573 Mon Sep 17 00:00:00 2001 From: hamlin Date: Fri, 12 Sep 2025 09:04:32 +0000 Subject: [PATCH 06/13] initial commit --- src/hotspot/cpu/riscv/nativeInst_riscv.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hotspot/cpu/riscv/nativeInst_riscv.cpp b/src/hotspot/cpu/riscv/nativeInst_riscv.cpp index 9722fd49d4d3a..72cc95a595dbf 100644 --- a/src/hotspot/cpu/riscv/nativeInst_riscv.cpp +++ b/src/hotspot/cpu/riscv/nativeInst_riscv.cpp @@ -28,6 +28,7 @@ #include "code/compiledIC.hpp" #include "nativeInst_riscv.hpp" #include "oops/oop.inline.hpp" +#include "runtime/atomicAccess.hpp" #include "runtime/handles.hpp" #include "runtime/orderAccess.hpp" #include "runtime/safepoint.hpp" @@ -99,10 +100,10 @@ void NativeCall::optimize_call(address dest, bool mt_safe) { if (Assembler::reachable_from_branch_at(jmp_ins_pc, dest)) { int64_t distance = dest - jmp_ins_pc; uint32_t new_jal = Assembler::encode_jal(ra, distance); - Atomic::store((uint32_t *)jmp_ins_pc, new_jal); + AtomicAccess::store((uint32_t *)jmp_ins_pc, new_jal); } else if (!MacroAssembler::is_jalr_at(jmp_ins_pc)) { // The jalr is always identical: jalr ra, 0(t1) uint32_t new_jalr = Assembler::encode_jalr(ra, t1, 0); - Atomic::store((uint32_t *)jmp_ins_pc, new_jalr); + AtomicAccess::store((uint32_t *)jmp_ins_pc, new_jalr); } else { // No change to instruction stream return; From 0ef68423130e72f10e745da6846938a2c5e1e672 Mon Sep 17 00:00:00 2001 From: hamlin Date: Mon, 15 Sep 2025 13:01:51 +0000 Subject: [PATCH 07/13] refine --- src/hotspot/cpu/riscv/vm_version_riscv.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.hpp b/src/hotspot/cpu/riscv/vm_version_riscv.hpp index 1650b20eae984..d378a6e5f5a02 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.hpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.hpp @@ -119,7 +119,7 @@ class VM_Version : public Abstract_VM_Version { _cpu_feature_index(cpu_feature_index) { } bool enabled() { - return RVExtFeatures::current()->supports_feature(_cpu_feature_index); + return RVExtFeatures::current()->support_feature(_cpu_feature_index); } void enable_feature(int64_t value = 0) { RVFeatureValue::enable_feature(value); @@ -295,7 +295,7 @@ class VM_Version : public Abstract_VM_Version { return (1ULL << features_bitmap_element_shift_count()) - 1; } - static int index(RVFeatureIndex feature) { + static int element_index(RVFeatureIndex feature) { int idx = feature >> features_bitmap_element_shift_count(); assert(idx < features_bitmap_element_count(), "Features array index out of bounds"); return idx; @@ -323,19 +323,19 @@ class VM_Version : public Abstract_VM_Version { void set_feature(uint32_t feature) { RVFeatureIndex f = convert(feature); - int idx = index(f); + int idx = element_index(f); _features_bitmap[idx] |= bit_mask(f); } void clear_feature(uint32_t feature) { RVFeatureIndex f = convert(feature); - int idx = index(f); + int idx = element_index(f); _features_bitmap[idx] &= ~bit_mask(f); } - bool supports_feature(uint32_t feature) { + bool support_feature(uint32_t feature) { RVFeatureIndex f = convert(feature); - int idx = index(f); + int idx = element_index(f); return (_features_bitmap[idx] & bit_mask(f)) != 0; } }; From 6b33210c28119559b6afb025dd2b37fe01469770 Mon Sep 17 00:00:00 2001 From: hamlin Date: Wed, 17 Sep 2025 08:13:59 +0000 Subject: [PATCH 08/13] fix typo --- src/hotspot/cpu/riscv/vm_version_riscv.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.hpp b/src/hotspot/cpu/riscv/vm_version_riscv.hpp index d378a6e5f5a02..a096f4411b359 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.hpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.hpp @@ -255,7 +255,7 @@ class VM_Version : public Abstract_VM_Version { decl(marchid , ArchId , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ decl(mimpid , ImpId , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ decl(satp_mode , SATP , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ - decl(zicboz_block_size, "ZicbozBlockSize", RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ + decl(zicboz_block_size, ZicbozBlockSize , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ #define DECLARE_RV_NON_EXT_FEATURE(NAME, PRETTY, LINUX_BIT, FSTRING, FLAGF) \ struct NAME##RVNonExtFeatureValue : public RVNonExtFeatureValue { \ From eac955a1e43a6f611179a396d63f1d2cd6286bfc Mon Sep 17 00:00:00 2001 From: hamlin Date: Mon, 22 Sep 2025 09:19:14 +0000 Subject: [PATCH 09/13] simplify names --- src/hotspot/cpu/riscv/vm_version_riscv.hpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.hpp b/src/hotspot/cpu/riscv/vm_version_riscv.hpp index a096f4411b359..becbe9891202d 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.hpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.hpp @@ -283,26 +283,26 @@ class VM_Version : public Abstract_VM_Version { STATIC_ASSERT(sizeof(_features_bitmap) * BitsPerByte >= MAX_CPU_FEATURE_INDEX); // Number of 8-byte elements in _features_bitmap. - constexpr static int features_bitmap_element_count() { + constexpr static int element_count() { return sizeof(_features_bitmap) / sizeof(uint64_t); } - constexpr static int features_bitmap_element_shift_count() { + constexpr static int element_shift_count() { return LogBitsPerLong; } - constexpr static uint64_t features_bitmap_element_mask() { - return (1ULL << features_bitmap_element_shift_count()) - 1; + constexpr static uint64_t element_mask() { + return (1ULL << element_shift_count()) - 1; } static int element_index(RVFeatureIndex feature) { - int idx = feature >> features_bitmap_element_shift_count(); - assert(idx < features_bitmap_element_count(), "Features array index out of bounds"); + int idx = feature >> element_shift_count(); + assert(idx < element_count(), "Features array index out of bounds"); return idx; } static uint64_t bit_mask(RVFeatureIndex feature) { - return (1ULL << (feature & features_bitmap_element_mask())); + return (1ULL << (feature & element_mask())); } static RVFeatureIndex convert(uint32_t index) { @@ -316,7 +316,7 @@ class VM_Version : public Abstract_VM_Version { } RVExtFeatures() { - for (int i = 0; i < features_bitmap_element_count(); i++) { + for (int i = 0; i < element_count(); i++) { _features_bitmap[i] = 0; } } From 414f1463efc3df5202c9f0f17faf0363066852d8 Mon Sep 17 00:00:00 2001 From: hamlin Date: Wed, 24 Sep 2025 10:45:58 +0000 Subject: [PATCH 10/13] refine --- src/hotspot/cpu/riscv/vm_version_riscv.hpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.hpp b/src/hotspot/cpu/riscv/vm_version_riscv.hpp index becbe9891202d..e9008d6783dea 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.hpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.hpp @@ -291,18 +291,15 @@ class VM_Version : public Abstract_VM_Version { return LogBitsPerLong; } - constexpr static uint64_t element_mask() { - return (1ULL << element_shift_count()) - 1; - } - static int element_index(RVFeatureIndex feature) { int idx = feature >> element_shift_count(); assert(idx < element_count(), "Features array index out of bounds"); return idx; } - static uint64_t bit_mask(RVFeatureIndex feature) { - return (1ULL << (feature & element_mask())); + static uint64_t feature_bit(RVFeatureIndex feature) { + constexpr static uint64_t m = (1ULL << element_shift_count()) - 1; + return (1ULL << (feature & m)); } static RVFeatureIndex convert(uint32_t index) { @@ -324,19 +321,19 @@ class VM_Version : public Abstract_VM_Version { void set_feature(uint32_t feature) { RVFeatureIndex f = convert(feature); int idx = element_index(f); - _features_bitmap[idx] |= bit_mask(f); + _features_bitmap[idx] |= feature_bit(f); } void clear_feature(uint32_t feature) { RVFeatureIndex f = convert(feature); int idx = element_index(f); - _features_bitmap[idx] &= ~bit_mask(f); + _features_bitmap[idx] &= ~feature_bit(f); } bool support_feature(uint32_t feature) { RVFeatureIndex f = convert(feature); int idx = element_index(f); - return (_features_bitmap[idx] & bit_mask(f)) != 0; + return (_features_bitmap[idx] & feature_bit(f)) != 0; } }; From 8a00f21504c9cac6b7ab9154d05da881a702518e Mon Sep 17 00:00:00 2001 From: hamlin Date: Wed, 24 Sep 2025 13:21:36 +0000 Subject: [PATCH 11/13] remove explicit cpu feature index in RV_EXT_FEATURE_FLAGS --- src/hotspot/cpu/riscv/vm_version_riscv.cpp | 10 +- src/hotspot/cpu/riscv/vm_version_riscv.hpp | 118 ++++++++++----------- 2 files changed, 64 insertions(+), 64 deletions(-) diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.cpp b/src/hotspot/cpu/riscv/vm_version_riscv.cpp index a1d7a1e715bbc..d9654813adbc2 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.cpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.cpp @@ -35,17 +35,17 @@ uint32_t VM_Version::_initial_vector_length = 0; -#define DEF_RV_EXT_FEATURE(NAME, PRETTY, LINUX_BIT, CPU_FEATURE_INDEX, FSTRING, FLAGF) \ -VM_Version::NAME##RVExtFeatureValue VM_Version::NAME(#PRETTY, LINUX_BIT, CPU_FEATURE_INDEX, FSTRING); +#define DEF_RV_EXT_FEATURE(NAME, PRETTY, LINUX_BIT, FSTRING, FLAGF) \ +VM_Version::NAME##RVExtFeatureValue VM_Version::NAME; RV_EXT_FEATURE_FLAGS(DEF_RV_EXT_FEATURE) #undef DEF_RV_EXT_FEATURE -#define DEF_RV_NON_EXT_FEATURE(NAME, PRETTY, LINUX_BIT, FSTRING, FLAGF) \ -VM_Version::NAME##RVNonExtFeatureValue VM_Version::NAME(#PRETTY, LINUX_BIT, FSTRING); +#define DEF_RV_NON_EXT_FEATURE(NAME, PRETTY, LINUX_BIT, FSTRING, FLAGF) \ +VM_Version::NAME##RVNonExtFeatureValue VM_Version::NAME; RV_NON_EXT_FEATURE_FLAGS(DEF_RV_NON_EXT_FEATURE) #undef DEF_RV_NON_EXT_FEATURE -#define ADD_RV_EXT_FEATURE_IN_LIST(NAME, PRETTY, LINUX_BIT, CPU_FEATURE_INDEX, FSTRING, FLAGF) \ +#define ADD_RV_EXT_FEATURE_IN_LIST(NAME, PRETTY, LINUX_BIT, FSTRING, FLAGF) \ &VM_Version::NAME, #define ADD_RV_NON_EXT_FEATURE_IN_LIST(NAME, PRETTY, LINUX_BIT, FSTRING, FLAGF) \ &VM_Version::NAME, diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.hpp b/src/hotspot/cpu/riscv/vm_version_riscv.hpp index e9008d6783dea..a0197b2c8af5a 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.hpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.hpp @@ -201,69 +201,69 @@ class VM_Version : public Abstract_VM_Version { // Note: the order matters, depender should be after their dependee. E.g. ext_V before ext_Zvbb. // // Fields description in `decl`: - // declaration name, extension name, bit value from linux, cpu feature index, feature string?, mapped flag) - #define RV_EXT_FEATURE_FLAGS(decl) \ - decl(ext_I , i , ('I' - 'A'), 0, true , NO_UPDATE_DEFAULT) \ - decl(ext_M , m , ('M' - 'A'), 1, true , NO_UPDATE_DEFAULT) \ - decl(ext_A , a , ('A' - 'A'), 2, true , NO_UPDATE_DEFAULT) \ - decl(ext_F , f , ('F' - 'A'), 3, true , NO_UPDATE_DEFAULT) \ - decl(ext_D , d , ('D' - 'A'), 4, true , NO_UPDATE_DEFAULT) \ - decl(ext_C , c , ('C' - 'A'), 5, true , UPDATE_DEFAULT(UseRVC)) \ - decl(ext_Q , q , ('Q' - 'A'), 6, true , NO_UPDATE_DEFAULT) \ - decl(ext_H , h , ('H' - 'A'), 7, true , NO_UPDATE_DEFAULT) \ - decl(ext_V , v , ('V' - 'A'), 8, true , UPDATE_DEFAULT(UseRVV)) \ - decl(ext_Zicbom , Zicbom , RV_NO_FLAG_BIT, 9, true , UPDATE_DEFAULT(UseZicbom)) \ - decl(ext_Zicboz , Zicboz , RV_NO_FLAG_BIT, 10, true , UPDATE_DEFAULT(UseZicboz)) \ - decl(ext_Zicbop , Zicbop , RV_NO_FLAG_BIT, 11, true , UPDATE_DEFAULT(UseZicbop)) \ - decl(ext_Zba , Zba , RV_NO_FLAG_BIT, 12, true , UPDATE_DEFAULT(UseZba)) \ - decl(ext_Zbb , Zbb , RV_NO_FLAG_BIT, 13, true , UPDATE_DEFAULT(UseZbb)) \ - decl(ext_Zbc , Zbc , RV_NO_FLAG_BIT, 14, true , NO_UPDATE_DEFAULT) \ - decl(ext_Zbs , Zbs , RV_NO_FLAG_BIT, 15, true , UPDATE_DEFAULT(UseZbs)) \ - decl(ext_Zbkb , Zbkb , RV_NO_FLAG_BIT, 16, true , UPDATE_DEFAULT(UseZbkb)) \ - decl(ext_Zcb , Zcb , RV_NO_FLAG_BIT, 17, true , UPDATE_DEFAULT(UseZcb)) \ - decl(ext_Zfa , Zfa , RV_NO_FLAG_BIT, 18, true , UPDATE_DEFAULT(UseZfa)) \ - decl(ext_Zfh , Zfh , RV_NO_FLAG_BIT, 19, true , UPDATE_DEFAULT(UseZfh)) \ - decl(ext_Zfhmin , Zfhmin , RV_NO_FLAG_BIT, 20, true , UPDATE_DEFAULT(UseZfhmin)) \ - decl(ext_Zicsr , Zicsr , RV_NO_FLAG_BIT, 21, true , NO_UPDATE_DEFAULT) \ - decl(ext_Zicntr , Zicntr , RV_NO_FLAG_BIT, 22, true , NO_UPDATE_DEFAULT) \ - decl(ext_Zifencei , Zifencei , RV_NO_FLAG_BIT, 23, true , NO_UPDATE_DEFAULT) \ - decl(ext_Zic64b , Zic64b , RV_NO_FLAG_BIT, 24, true , UPDATE_DEFAULT(UseZic64b)) \ - decl(ext_Ztso , Ztso , RV_NO_FLAG_BIT, 25, true , UPDATE_DEFAULT(UseZtso)) \ - decl(ext_Zihintpause , Zihintpause , RV_NO_FLAG_BIT, 26, true , UPDATE_DEFAULT(UseZihintpause)) \ - decl(ext_Zacas , Zacas , RV_NO_FLAG_BIT, 27, true , UPDATE_DEFAULT(UseZacas)) \ - decl(ext_Zvbb , Zvbb , RV_NO_FLAG_BIT, 28, true , UPDATE_DEFAULT_DEP(UseZvbb, ext_V)) \ - decl(ext_Zvbc , Zvbc , RV_NO_FLAG_BIT, 29, true , UPDATE_DEFAULT_DEP(UseZvbc, ext_V)) \ - decl(ext_Zvfh , Zvfh , RV_NO_FLAG_BIT, 30, true , UPDATE_DEFAULT_DEP(UseZvfh, ext_V)) \ - decl(ext_Zvkn , Zvkn , RV_NO_FLAG_BIT, 31, true , UPDATE_DEFAULT_DEP(UseZvkn, ext_V)) \ - decl(ext_Zicond , Zicond , RV_NO_FLAG_BIT, 32, true , UPDATE_DEFAULT(UseZicond)) \ - - #define DECLARE_RV_EXT_FEATURE(NAME, PRETTY, LINUX_BIT, CPU_FEATURE_INDEX, FSTRING, FLAGF) \ - struct NAME##RVExtFeatureValue : public RVExtFeatureValue { \ - NAME##RVExtFeatureValue(const char* pretty, int linux_bit_num, uint32_t cpu_feature_index, bool fstring) : \ - RVExtFeatureValue(pretty, linux_bit_num, cpu_feature_index, fstring) {} \ - FLAGF; \ - }; \ - static NAME##RVExtFeatureValue NAME; \ + // 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 DECLARE_RV_EXT_FEATURE(NAME, PRETTY, LINUX_BIT, FSTRING, FLAGF) \ + struct NAME##RVExtFeatureValue : public RVExtFeatureValue { \ + NAME##RVExtFeatureValue() : \ + RVExtFeatureValue(#PRETTY, LINUX_BIT, RVExtFeatures::CPU_##NAME, FSTRING) {} \ + FLAGF; \ + }; \ + static NAME##RVExtFeatureValue NAME; \ RV_EXT_FEATURE_FLAGS(DECLARE_RV_EXT_FEATURE) // Non-extension features // - #define RV_NON_EXT_FEATURE_FLAGS(decl) \ - decl(unaligned_access , Unaligned , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ - decl(mvendorid , VendorId , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ - decl(marchid , ArchId , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ - decl(mimpid , ImpId , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ - decl(satp_mode , SATP , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ - decl(zicboz_block_size, ZicbozBlockSize , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ - - #define DECLARE_RV_NON_EXT_FEATURE(NAME, PRETTY, LINUX_BIT, FSTRING, FLAGF) \ - struct NAME##RVNonExtFeatureValue : public RVNonExtFeatureValue { \ - NAME##RVNonExtFeatureValue(const char* pretty, int linux_bit_num, bool fstring) : \ - RVNonExtFeatureValue(pretty, linux_bit_num, fstring) {} \ - FLAGF; \ - }; \ - static NAME##RVNonExtFeatureValue NAME; \ + #define RV_NON_EXT_FEATURE_FLAGS(decl) \ + decl(unaligned_access , Unaligned , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ + decl(mvendorid , VendorId , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ + decl(marchid , ArchId , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ + decl(mimpid , ImpId , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ + decl(satp_mode , SATP , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ + decl(zicboz_block_size, ZicbozBlockSize , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ + + #define DECLARE_RV_NON_EXT_FEATURE(NAME, PRETTY, LINUX_BIT, FSTRING, FLAGF) \ + struct NAME##RVNonExtFeatureValue : public RVNonExtFeatureValue { \ + NAME##RVNonExtFeatureValue() : \ + RVNonExtFeatureValue(#PRETTY, LINUX_BIT, FSTRING) {} \ + FLAGF; \ + }; \ + static NAME##RVNonExtFeatureValue NAME; \ RV_NON_EXT_FEATURE_FLAGS(DECLARE_RV_NON_EXT_FEATURE) @@ -272,7 +272,7 @@ class VM_Version : public Abstract_VM_Version { class RVExtFeatures : public CHeapObj { public: enum RVFeatureIndex { - #define DECLARE_RV_FEATURE_ENUM(NAME, PRETTY, LINUX_BIT, CPU_FEATURE_INDEX, FSTRING, FLAGF) CPU_##NAME=(CPU_FEATURE_INDEX), + #define DECLARE_RV_FEATURE_ENUM(NAME, PRETTY, LINUX_BIT, FSTRING, FLAGF) CPU_##NAME, RV_EXT_FEATURE_FLAGS(DECLARE_RV_FEATURE_ENUM) MAX_CPU_FEATURE_INDEX From 3131ab7027380f105551e0a6afc642507d6758e8 Mon Sep 17 00:00:00 2001 From: hamlin Date: Wed, 24 Sep 2025 15:50:23 +0000 Subject: [PATCH 12/13] undef macros --- src/hotspot/cpu/riscv/vm_version_riscv.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.hpp b/src/hotspot/cpu/riscv/vm_version_riscv.hpp index a0197b2c8af5a..48c45371ea1d5 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.hpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.hpp @@ -246,6 +246,7 @@ class VM_Version : public Abstract_VM_Version { static NAME##RVExtFeatureValue NAME; \ RV_EXT_FEATURE_FLAGS(DECLARE_RV_EXT_FEATURE) + #undef DECLARE_RV_EXT_FEATURE // Non-extension features // @@ -266,6 +267,7 @@ class VM_Version : public Abstract_VM_Version { static NAME##RVNonExtFeatureValue NAME; \ RV_NON_EXT_FEATURE_FLAGS(DECLARE_RV_NON_EXT_FEATURE) + #undef DECLARE_RV_NON_EXT_FEATURE private: // Utility for AOT CPU feature store/check. From f19196ffc64bb7bc5cc157870d147300aad37c64 Mon Sep 17 00:00:00 2001 From: hamlin Date: Thu, 25 Sep 2025 08:49:53 +0000 Subject: [PATCH 13/13] refine --- src/hotspot/cpu/riscv/vm_version_riscv.hpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.hpp b/src/hotspot/cpu/riscv/vm_version_riscv.hpp index 48c45371ea1d5..aec975d27bef3 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.hpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.hpp @@ -289,19 +289,14 @@ class VM_Version : public Abstract_VM_Version { return sizeof(_features_bitmap) / sizeof(uint64_t); } - constexpr static int element_shift_count() { - return LogBitsPerLong; - } - static int element_index(RVFeatureIndex feature) { - int idx = feature >> element_shift_count(); + int idx = feature / BitsPerLong; assert(idx < element_count(), "Features array index out of bounds"); return idx; } static uint64_t feature_bit(RVFeatureIndex feature) { - constexpr static uint64_t m = (1ULL << element_shift_count()) - 1; - return (1ULL << (feature & m)); + return (1ULL << (feature % BitsPerLong)); } static RVFeatureIndex convert(uint32_t index) {