mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 12:09:14 +00:00
8367103: RISC-V: store cpu features in a bitmap
Reviewed-by: fyang, luhenry
This commit is contained in:
parent
26b5708c47
commit
d1ea6ea22d
@ -35,15 +35,28 @@
|
||||
|
||||
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);
|
||||
RV_FEATURE_FLAGS(DEF_RV_FEATURE)
|
||||
#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 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 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, 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_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_NON_EXT_FEATURE_IN_LIST
|
||||
#undef ADD_RV_EXT_FEATURE_IN_LIST
|
||||
|
||||
VM_Version::RVExtFeatures* VM_Version::_rv_ext_features = new VM_Version::RVExtFeatures();
|
||||
|
||||
void VM_Version::useRVA20U64Profile() {
|
||||
RV_USE_RVA20U64;
|
||||
|
||||
@ -46,30 +46,29 @@ class VM_Version : public Abstract_VM_Version {
|
||||
RIVOS = 0x6cf, // JEDEC: 0x4f, Bank: 14
|
||||
};
|
||||
|
||||
class RVExtFeatures;
|
||||
|
||||
class RVFeatureValue {
|
||||
const char* const _pretty;
|
||||
const bool _feature_string;
|
||||
const uint64_t _feature_bit;
|
||||
bool _enabled;
|
||||
const uint64_t _linux_feature_bit;
|
||||
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, bool fstring) :
|
||||
_pretty(pretty), _feature_string(fstring), _linux_feature_bit(nth_bit(linux_bit_num)),
|
||||
_value(-1) {
|
||||
}
|
||||
void enable_feature(int64_t value = 0) {
|
||||
_enabled = true;
|
||||
virtual void enable_feature(int64_t value = 0) {
|
||||
_value = value;
|
||||
}
|
||||
void disable_feature() {
|
||||
_enabled = false;
|
||||
virtual void disable_feature() {
|
||||
_value = -1;
|
||||
}
|
||||
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; }
|
||||
virtual bool enabled() = 0;
|
||||
virtual void update_flag() = 0;
|
||||
};
|
||||
|
||||
@ -111,6 +110,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 RVExtFeatures::current()->support_feature(_cpu_feature_index);
|
||||
}
|
||||
void enable_feature(int64_t value = 0) {
|
||||
RVFeatureValue::enable_feature(value);
|
||||
RVExtFeatures::current()->set_feature(_cpu_feature_index);
|
||||
}
|
||||
void disable_feature() {
|
||||
RVFeatureValue::disable_feature();
|
||||
RVExtFeatures::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
|
||||
@ -161,58 +199,140 @@ 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) \
|
||||
decl(zicboz_block_size, "ZicbozBlockSize", RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
|
||||
//
|
||||
// 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 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; \
|
||||
#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_FEATURE_FLAGS(DECLARE_RV_FEATURE)
|
||||
#undef DECLARE_RV_FEATURE
|
||||
RV_EXT_FEATURE_FLAGS(DECLARE_RV_EXT_FEATURE)
|
||||
#undef 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() : \
|
||||
RVNonExtFeatureValue(#PRETTY, LINUX_BIT, FSTRING) {} \
|
||||
FLAGF; \
|
||||
}; \
|
||||
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.
|
||||
class RVExtFeatures : public CHeapObj<mtCode> {
|
||||
public:
|
||||
enum RVFeatureIndex {
|
||||
#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
|
||||
#undef DECLARE_RV_FEATURE_ENUM
|
||||
};
|
||||
private:
|
||||
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 _features_bitmap.
|
||||
constexpr static int element_count() {
|
||||
return sizeof(_features_bitmap) / sizeof(uint64_t);
|
||||
}
|
||||
|
||||
static int element_index(RVFeatureIndex feature) {
|
||||
int idx = feature / BitsPerLong;
|
||||
assert(idx < element_count(), "Features array index out of bounds");
|
||||
return idx;
|
||||
}
|
||||
|
||||
static uint64_t feature_bit(RVFeatureIndex feature) {
|
||||
return (1ULL << (feature % BitsPerLong));
|
||||
}
|
||||
|
||||
static RVFeatureIndex convert(uint32_t index) {
|
||||
assert(index < MAX_CPU_FEATURE_INDEX, "must");
|
||||
return (RVFeatureIndex)index;
|
||||
}
|
||||
|
||||
public:
|
||||
static RVExtFeatures* current() {
|
||||
return _rv_ext_features;
|
||||
}
|
||||
|
||||
RVExtFeatures() {
|
||||
for (int i = 0; i < element_count(); i++) {
|
||||
_features_bitmap[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void set_feature(uint32_t feature) {
|
||||
RVFeatureIndex f = convert(feature);
|
||||
int idx = element_index(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] &= ~feature_bit(f);
|
||||
}
|
||||
|
||||
bool support_feature(uint32_t feature) {
|
||||
RVFeatureIndex f = convert(feature);
|
||||
int idx = element_index(f);
|
||||
return (_features_bitmap[idx] & feature_bit(f)) != 0;
|
||||
}
|
||||
};
|
||||
|
||||
// enable extensions based on profile, current supported profiles:
|
||||
// RVA20U64
|
||||
@ -286,6 +406,7 @@ class VM_Version : public Abstract_VM_Version {
|
||||
|
||||
// Null terminated list
|
||||
static RVFeatureValue* _feature_list[];
|
||||
static RVExtFeatures* _rv_ext_features;
|
||||
|
||||
// Enables features in _feature_list
|
||||
static void setup_cpu_available_features();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user