8284563: AArch64: bitperm feature detection for SVE2 on Linux

Reviewed-by: aph, njian
This commit is contained in:
Eric Liu 2022-04-20 00:55:56 +00:00 committed by Pengfei Li
parent 98d54e8eb2
commit 72726c4182
6 changed files with 69 additions and 47 deletions

View File

@ -1575,7 +1575,7 @@ void MacroAssembler::atomic_incw(Register counter_addr, Register tmp, Register t
return;
}
Label retry_load;
if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH))
if (VM_Version::supports_stxr_prefetch())
prfm(Address(counter_addr), PSTL1STRM);
bind(retry_load);
// flush and load exclusive from the memory location
@ -2297,7 +2297,7 @@ void MacroAssembler::cmpxchgptr(Register oldv, Register newv, Register addr, Reg
membar(AnyAny);
} else {
Label retry_load, nope;
if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH))
if (VM_Version::supports_stxr_prefetch())
prfm(Address(addr), PSTL1STRM);
bind(retry_load);
// flush and load exclusive from the memory location
@ -2340,7 +2340,7 @@ void MacroAssembler::cmpxchgw(Register oldv, Register newv, Register addr, Regis
membar(AnyAny);
} else {
Label retry_load, nope;
if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH))
if (VM_Version::supports_stxr_prefetch())
prfm(Address(addr), PSTL1STRM);
bind(retry_load);
// flush and load exclusive from the memory location
@ -2382,7 +2382,7 @@ void MacroAssembler::cmpxchg(Register addr, Register expected,
compare_eq(result, expected, size);
} else {
Label retry_load, done;
if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH))
if (VM_Version::supports_stxr_prefetch())
prfm(Address(addr), PSTL1STRM);
bind(retry_load);
load_exclusive(result, addr, size, acquire);
@ -2441,7 +2441,7 @@ void MacroAssembler::atomic_##NAME(Register prev, RegisterOrConstant incr, Regis
result = different(prev, incr, addr) ? prev : rscratch2; \
\
Label retry_load; \
if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH)) \
if (VM_Version::supports_stxr_prefetch()) \
prfm(Address(addr), PSTL1STRM); \
bind(retry_load); \
LDXR(result, addr); \
@ -2472,7 +2472,7 @@ void MacroAssembler::atomic_##OP(Register prev, Register newv, Register addr) {
result = different(prev, newv, addr) ? prev : rscratch2; \
\
Label retry_load; \
if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH)) \
if (VM_Version::supports_stxr_prefetch()) \
prfm(Address(addr), PSTL1STRM); \
bind(retry_load); \
LDXR(result, addr); \
@ -5210,7 +5210,7 @@ void MacroAssembler::cache_wb(Address line) {
assert(line.offset() == 0, "offset should be 0");
// would like to assert this
// assert(line._ext.shift == 0, "shift should be zero");
if (VM_Version::features() & VM_Version::CPU_DCPOP) {
if (VM_Version::supports_dcpop()) {
// writeback using clear virtual address to point of persistence
dc(Assembler::CVAP, line.base());
} else {

View File

@ -432,7 +432,7 @@ class MacroAssembler: public Assembler {
#define WRAP(INSN) \
void INSN(Register Rd, Register Rn, Register Rm, Register Ra) { \
if ((VM_Version::features() & VM_Version::CPU_A53MAC) && Ra != zr) \
if (VM_Version::supports_a53mac() && Ra != zr) \
nop(); \
Assembler::INSN(Rd, Rn, Rm, Ra); \
}

View File

@ -124,7 +124,7 @@ void VM_Version::initialize() {
// if dcpop is available publish data cache line flush size via
// generic field, otherwise let if default to zero thereby
// disabling writeback
if (_features & CPU_DCPOP) {
if (VM_Version::supports_dcpop()) {
_data_cache_line_flush_size = dcache_line;
}
}
@ -226,17 +226,17 @@ void VM_Version::initialize() {
char buf[512];
sprintf(buf, "0x%02x:0x%x:0x%03x:%d", _cpu, _variant, _model, _revision);
if (_model2) sprintf(buf+strlen(buf), "(0x%03x)", _model2);
#define ADD_FEATURE_IF_SUPPORTED(id, name, bit) if (_features & CPU_##id) strcat(buf, ", " name);
#define ADD_FEATURE_IF_SUPPORTED(id, name, bit) if (VM_Version::supports_##name()) strcat(buf, ", " #name);
CPU_FEATURE_FLAGS(ADD_FEATURE_IF_SUPPORTED)
#undef ADD_FEATURE_IF_SUPPORTED
_features_string = os::strdup(buf);
if (FLAG_IS_DEFAULT(UseCRC32)) {
UseCRC32 = (_features & CPU_CRC32) != 0;
UseCRC32 = VM_Version::supports_crc32();
}
if (UseCRC32 && (_features & CPU_CRC32) == 0) {
if (UseCRC32 && !VM_Version::supports_crc32()) {
warning("UseCRC32 specified, but not supported on this CPU");
FLAG_SET_DEFAULT(UseCRC32, false);
}
@ -250,7 +250,7 @@ void VM_Version::initialize() {
FLAG_SET_DEFAULT(UseVectorizedMismatchIntrinsic, false);
}
if (_features & CPU_LSE) {
if (VM_Version::supports_lse()) {
if (FLAG_IS_DEFAULT(UseLSE))
FLAG_SET_DEFAULT(UseLSE, true);
} else {
@ -260,7 +260,7 @@ void VM_Version::initialize() {
}
}
if (_features & CPU_AES) {
if (VM_Version::supports_aes()) {
UseAES = UseAES || FLAG_IS_DEFAULT(UseAES);
UseAESIntrinsics =
UseAESIntrinsics || (UseAES && FLAG_IS_DEFAULT(UseAESIntrinsics));
@ -291,7 +291,7 @@ void VM_Version::initialize() {
UseCRC32Intrinsics = true;
}
if (_features & CPU_CRC32) {
if (VM_Version::supports_crc32()) {
if (FLAG_IS_DEFAULT(UseCRC32CIntrinsics)) {
FLAG_SET_DEFAULT(UseCRC32CIntrinsics, true);
}
@ -308,7 +308,8 @@ void VM_Version::initialize() {
UseMD5Intrinsics = true;
}
if (_features & (CPU_SHA1 | CPU_SHA2 | CPU_SHA3 | CPU_SHA512)) {
if (VM_Version::supports_sha1() || VM_Version::supports_sha2() ||
VM_Version::supports_sha3() || VM_Version::supports_sha512()) {
if (FLAG_IS_DEFAULT(UseSHA)) {
FLAG_SET_DEFAULT(UseSHA, true);
}
@ -317,7 +318,7 @@ void VM_Version::initialize() {
FLAG_SET_DEFAULT(UseSHA, false);
}
if (UseSHA && (_features & CPU_SHA1)) {
if (UseSHA && VM_Version::supports_sha1()) {
if (FLAG_IS_DEFAULT(UseSHA1Intrinsics)) {
FLAG_SET_DEFAULT(UseSHA1Intrinsics, true);
}
@ -326,7 +327,7 @@ void VM_Version::initialize() {
FLAG_SET_DEFAULT(UseSHA1Intrinsics, false);
}
if (UseSHA && (_features & CPU_SHA2)) {
if (UseSHA && VM_Version::supports_sha2()) {
if (FLAG_IS_DEFAULT(UseSHA256Intrinsics)) {
FLAG_SET_DEFAULT(UseSHA256Intrinsics, true);
}
@ -335,7 +336,7 @@ void VM_Version::initialize() {
FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
}
if (UseSHA && (_features & CPU_SHA3)) {
if (UseSHA && VM_Version::supports_sha3()) {
// Do not auto-enable UseSHA3Intrinsics until it has been fully tested on hardware
// if (FLAG_IS_DEFAULT(UseSHA3Intrinsics)) {
// FLAG_SET_DEFAULT(UseSHA3Intrinsics, true);
@ -345,7 +346,7 @@ void VM_Version::initialize() {
FLAG_SET_DEFAULT(UseSHA3Intrinsics, false);
}
if (UseSHA && (_features & CPU_SHA512)) {
if (UseSHA && VM_Version::supports_sha512()) {
// Do not auto-enable UseSHA512Intrinsics until it has been fully tested on hardware
// if (FLAG_IS_DEFAULT(UseSHA512Intrinsics)) {
// FLAG_SET_DEFAULT(UseSHA512Intrinsics, true);
@ -359,7 +360,7 @@ void VM_Version::initialize() {
FLAG_SET_DEFAULT(UseSHA, false);
}
if (_features & CPU_PMULL) {
if (VM_Version::supports_pmull()) {
if (FLAG_IS_DEFAULT(UseGHASHIntrinsics)) {
FLAG_SET_DEFAULT(UseGHASHIntrinsics, true);
}
@ -384,18 +385,26 @@ void VM_Version::initialize() {
FLAG_SET_DEFAULT(UseBlockZeroing, false);
}
if (_features & CPU_SVE) {
if (VM_Version::supports_sve2()) {
if (FLAG_IS_DEFAULT(UseSVE)) {
FLAG_SET_DEFAULT(UseSVE, (_features & CPU_SVE2) ? 2 : 1);
FLAG_SET_DEFAULT(UseSVE, 2);
}
if (UseSVE > 0) {
_initial_sve_vector_length = get_current_sve_vector_length();
} else if (VM_Version::supports_sve()) {
if (FLAG_IS_DEFAULT(UseSVE)) {
FLAG_SET_DEFAULT(UseSVE, 1);
} else if (UseSVE > 1) {
warning("SVE2 specified, but not supported on current CPU. Using SVE.");
FLAG_SET_DEFAULT(UseSVE, 1);
}
} else if (UseSVE > 0) {
warning("UseSVE specified, but not supported on current CPU. Disabling SVE.");
FLAG_SET_DEFAULT(UseSVE, 0);
}
if (UseSVE > 0) {
_initial_sve_vector_length = get_current_sve_vector_length();
}
// This machine allows unaligned memory accesses
if (FLAG_IS_DEFAULT(UseUnalignedAccesses)) {
FLAG_SET_DEFAULT(UseUnalignedAccesses, true);
@ -416,14 +425,14 @@ void VM_Version::initialize() {
_rop_protection = false;
// Enable PAC if this code has been built with branch-protection and the CPU/OS supports it.
#ifdef __ARM_FEATURE_PAC_DEFAULT
if ((_features & CPU_PACA) != 0) {
if (VM_Version::supports_paca()) {
_rop_protection = true;
}
#endif
} else if (strcmp(UseBranchProtection, "pac-ret") == 0) {
_rop_protection = true;
#ifdef __ARM_FEATURE_PAC_DEFAULT
if ((_features & CPU_PACA) == 0) {
if (!VM_Version::supports_paca()) {
warning("ROP-protection specified, but not supported on this CPU.");
// Disable PAC to prevent illegal instruction crashes.
_rop_protection = false;

View File

@ -100,32 +100,39 @@ public:
CPU_APPLE = 'a',
};
enum Feature_Flag {
#define CPU_FEATURE_FLAGS(decl) \
decl(FP, "fp", 0) \
decl(ASIMD, "simd", 1) \
decl(EVTSTRM, "evtstrm", 2) \
decl(AES, "aes", 3) \
decl(PMULL, "pmull", 4) \
decl(SHA1, "sha1", 5) \
decl(SHA2, "sha256", 6) \
decl(CRC32, "crc", 7) \
decl(LSE, "lse", 8) \
decl(DCPOP, "dcpop", 16) \
decl(SHA3, "sha3", 17) \
decl(SHA512, "sha512", 21) \
decl(SVE, "sve", 22) \
decl(PACA, "paca", 30) \
decl(FP, fp, 0) \
decl(ASIMD, simd, 1) \
decl(EVTSTRM, evtstrm, 2) \
decl(AES, aes, 3) \
decl(PMULL, pmull, 4) \
decl(SHA1, sha1, 5) \
decl(SHA2, sha2, 6) \
decl(CRC32, crc32, 7) \
decl(LSE, lse, 8) \
decl(DCPOP, dcpop, 16) \
decl(SHA3, sha3, 17) \
decl(SHA512, sha512, 21) \
decl(SVE, sve, 22) \
decl(PACA, paca, 30) \
/* flags above must follow Linux HWCAP */ \
decl(SVE2, "sve2", 28) \
decl(STXR_PREFETCH, "stxr_prefetch", 29) \
decl(A53MAC, "a53mac", 31)
decl(SVEBITPERM, svebitperm, 27) \
decl(SVE2, sve2, 28) \
decl(STXR_PREFETCH, stxr_prefetch, 29) \
decl(A53MAC, a53mac, 31)
enum Feature_Flag {
#define DECLARE_CPU_FEATURE_FLAG(id, name, bit) CPU_##id = (1 << bit),
CPU_FEATURE_FLAGS(DECLARE_CPU_FEATURE_FLAG)
#undef DECLARE_CPU_FEATURE_FLAG
};
// Feature identification
#define CPU_FEATURE_DETECTION(id, name, bit) \
static bool supports_##name() { return (_features & CPU_##id) != 0; };
CPU_FEATURE_FLAGS(CPU_FEATURE_DETECTION)
#undef CPU_FEATURE_DETECTION
static int cpu_family() { return _cpu; }
static int cpu_model() { return _model; }
static int cpu_model2() { return _model2; }

View File

@ -80,6 +80,10 @@
#define HWCAP2_SVE2 (1 << 1)
#endif
#ifndef HWCAP2_SVEBITPERM
#define HWCAP2_SVEBITPERM (1 << 4)
#endif
#ifndef PR_SVE_GET_VL
// For old toolchains which do not have SVE related macros defined.
#define PR_SVE_SET_VL 50
@ -87,12 +91,12 @@
#endif
int VM_Version::get_current_sve_vector_length() {
assert(_features & CPU_SVE, "should not call this");
assert(VM_Version::supports_sve(), "should not call this");
return prctl(PR_SVE_GET_VL);
}
int VM_Version::set_and_get_current_sve_vector_length(int length) {
assert(_features & CPU_SVE, "should not call this");
assert(VM_Version::supports_sve(), "should not call this");
int new_length = prctl(PR_SVE_SET_VL, length);
return new_length;
}
@ -133,6 +137,7 @@ void VM_Version::get_os_cpu_info() {
HWCAP_PACA);
if (auxv2 & HWCAP2_SVE2) _features |= CPU_SVE2;
if (auxv2 & HWCAP2_SVEBITPERM) _features |= CPU_SVEBITPERM;
uint64_t ctr_el0;
uint64_t dczid_el0;

View File

@ -178,6 +178,7 @@ public class AArch64 extends Architecture {
SHA512,
SVE,
PACA,
SVEBITPERM,
SVE2,
STXR_PREFETCH,
A53MAC,