8265403: consolidate definition of CPU features

Reviewed-by: kvn, iklam
This commit is contained in:
Doug Simon 2021-04-23 23:32:41 +00:00
parent 20a373a0d0
commit 5aed446e20
15 changed files with 257 additions and 346 deletions
src
hotspot
jdk.internal.vm.ci/share/classes
jdk.vm.ci.aarch64/src/jdk/vm/ci/aarch64
jdk.vm.ci.amd64/src/jdk/vm/ci/amd64
jdk.vm.ci.code/src/jdk/vm/ci/code
jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64
jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64
jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -39,4 +39,7 @@
#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#define DECLARE_INT_CPU_FEATURE_CONSTANT(id, name, bit) GENERATE_VM_INT_CONSTANT_ENTRY(VM_Version::CPU_##id)
#define VM_INT_CPU_FEATURE_CONSTANTS CPU_FEATURE_FLAGS(DECLARE_INT_CPU_FEATURE_CONSTANT)
#endif // CPU_AARCH64_VMSTRUCTS_AARCH64_HPP

@ -195,16 +195,9 @@ 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);
if (_features & CPU_ASIMD) strcat(buf, ", simd");
if (_features & CPU_CRC32) strcat(buf, ", crc");
if (_features & CPU_AES) strcat(buf, ", aes");
if (_features & CPU_SHA1) strcat(buf, ", sha1");
if (_features & CPU_SHA2) strcat(buf, ", sha256");
if (_features & CPU_SHA3) strcat(buf, ", sha3");
if (_features & CPU_SHA512) strcat(buf, ", sha512");
if (_features & CPU_LSE) strcat(buf, ", lse");
if (_features & CPU_SVE) strcat(buf, ", sve");
if (_features & CPU_SVE2) strcat(buf, ", sve2");
#define ADD_FEATURE_IF_SUPPORTED(id, name, bit) if (_features & CPU_##id) strcat(buf, ", " name);
CPU_FEATURE_FLAGS(ADD_FEATURE_IF_SUPPORTED)
#undef ADD_FEATURE_IF_SUPPORTED
_features_string = os::strdup(buf);

@ -97,23 +97,28 @@ public:
};
enum Feature_Flag {
CPU_FP = (1<<0),
CPU_ASIMD = (1<<1),
CPU_EVTSTRM = (1<<2),
CPU_AES = (1<<3),
CPU_PMULL = (1<<4),
CPU_SHA1 = (1<<5),
CPU_SHA2 = (1<<6),
CPU_CRC32 = (1<<7),
CPU_LSE = (1<<8),
CPU_DCPOP = (1<<16),
CPU_SHA3 = (1<<17),
CPU_SHA512 = (1<<21),
CPU_SVE = (1<<22),
// flags above must follow Linux HWCAP
CPU_SVE2 = (1<<28),
CPU_STXR_PREFETCH= (1<<29),
CPU_A53MAC = (1<<30),
#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) \
/* flags above must follow Linux HWCAP */ \
decl(SVE2, "sve2", 28) \
decl(STXR_PREFETCH, "stxr_prefetch", 29) \
decl(A53MAC, "a53mac", 30)
#define DECLARE_CPU_FEATURE_FLAG(id, name, bit) CPU_##id = (1 << bit),
CPU_FEATURE_FLAGS(DECLARE_CPU_FEATURE_FLAG)
#undef DECLARE_CPU_FEATURE_FLAG
};
static int cpu_family() { return _cpu; }

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -39,52 +39,9 @@
declare_constant(frame::interpreter_frame_sender_sp_offset) \
declare_constant(frame::interpreter_frame_last_sp_offset)
#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \
declare_constant(VM_Version::CPU_CX8) \
declare_constant(VM_Version::CPU_CMOV) \
declare_constant(VM_Version::CPU_FXSR) \
declare_constant(VM_Version::CPU_HT) \
declare_constant(VM_Version::CPU_MMX) \
declare_constant(VM_Version::CPU_3DNOW_PREFETCH) \
declare_constant(VM_Version::CPU_SSE) \
declare_constant(VM_Version::CPU_SSE2) \
declare_constant(VM_Version::CPU_SSE3) \
declare_constant(VM_Version::CPU_SSSE3) \
declare_constant(VM_Version::CPU_SSE4A) \
declare_constant(VM_Version::CPU_SSE4_1) \
declare_constant(VM_Version::CPU_SSE4_2) \
declare_constant(VM_Version::CPU_POPCNT) \
declare_constant(VM_Version::CPU_LZCNT) \
declare_constant(VM_Version::CPU_TSC) \
declare_constant(VM_Version::CPU_TSCINV) \
declare_constant(VM_Version::CPU_AVX) \
declare_constant(VM_Version::CPU_AVX2) \
declare_constant(VM_Version::CPU_AES) \
declare_constant(VM_Version::CPU_ERMS) \
declare_constant(VM_Version::CPU_CLMUL) \
declare_constant(VM_Version::CPU_BMI1) \
declare_constant(VM_Version::CPU_BMI2) \
declare_constant(VM_Version::CPU_RTM) \
declare_constant(VM_Version::CPU_ADX) \
declare_constant(VM_Version::CPU_AVX512F) \
declare_constant(VM_Version::CPU_AVX512DQ) \
declare_constant(VM_Version::CPU_AVX512PF) \
declare_constant(VM_Version::CPU_AVX512ER) \
declare_constant(VM_Version::CPU_AVX512CD) \
declare_constant(VM_Version::CPU_AVX512BW) \
declare_constant(VM_Version::CPU_AVX512VL) \
declare_constant(VM_Version::CPU_SHA) \
declare_constant(VM_Version::CPU_FMA) \
declare_constant(VM_Version::CPU_VZEROUPPER) \
declare_constant(VM_Version::CPU_AVX512_VPOPCNTDQ) \
declare_constant(VM_Version::CPU_AVX512_VPCLMULQDQ) \
declare_constant(VM_Version::CPU_AVX512_VAES) \
declare_constant(VM_Version::CPU_AVX512_VNNI) \
declare_constant(VM_Version::CPU_FLUSH) \
declare_constant(VM_Version::CPU_FLUSHOPT) \
declare_constant(VM_Version::CPU_CLWB) \
declare_constant(VM_Version::CPU_AVX512_VBMI2) \
declare_constant(VM_Version::CPU_AVX512_VBMI) \
declare_constant(VM_Version::CPU_HV)
#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#define DECLARE_LONG_CPU_FEATURE_CONSTANT(id, name, bit) GENERATE_VM_LONG_CONSTANT_ENTRY(VM_Version::CPU_##id)
#define VM_LONG_CPU_FEATURE_CONSTANTS CPU_FEATURE_FLAGS(DECLARE_LONG_CPU_FEATURE_CONSTANT)
#endif // CPU_X86_VMSTRUCTS_X86_HPP

@ -45,7 +45,10 @@ int VM_Version::_model;
int VM_Version::_stepping;
bool VM_Version::_has_intel_jcc_erratum;
VM_Version::CpuidInfo VM_Version::_cpuid_info = { 0, };
const char* VM_Version::_features_names[] = { FEATURES_NAMES };
#define DECLARE_CPU_FEATURE_NAME(id, name, bit) name,
const char* VM_Version::_features_names[] = { CPU_FEATURE_FLAGS(DECLARE_CPU_FEATURE_NAME)};
#undef DECLARE_CPU_FEATURE_FLAG
// Address of instruction which causes SEGV
address VM_Version::_cpuinfo_segv_addr = 0;
@ -782,7 +785,6 @@ void VM_Version::get_processor_features() {
cores_per_cpu(), threads_per_core(),
cpu_family(), _model, _stepping, os::cpu_microcode_revision());
assert(res > 0, "not enough temporary space allocated");
assert(log2i_exact((uint64_t)CPU_MAX_FEATURE) + 1 == sizeof(_features_names) / sizeof(char*), "wrong size features_names");
insert_features_names(buf + res, sizeof(buf) - res, _features_names);
_features_string = os::strdup(buf);

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -300,87 +300,74 @@ protected:
static address _cpuinfo_cont_addr; // address of instruction after the one which causes SEGV
enum Feature_Flag : uint64_t {
CPU_CX8 = (1ULL << 0), // next bits are from cpuid 1 (EDX)
CPU_CMOV = (1ULL << 1),
CPU_FXSR = (1ULL << 2),
CPU_HT = (1ULL << 3),
#define CPU_FEATURE_FLAGS(decl) \
decl(CX8, "cx8", 0) /* next bits are from cpuid 1 (EDX) */ \
decl(CMOV, "cmov", 1) \
decl(FXSR, "fxsr", 2) \
decl(HT, "ht", 3) \
\
decl(MMX, "mmx", 4) \
decl(3DNOW_PREFETCH, "3dnowpref", 5) /* Processor supports 3dnow prefetch and prefetchw instructions */ \
/* may not necessarily support other 3dnow instructions */ \
decl(SSE, "sse", 6) \
decl(SSE2, "sse2", 7) \
\
decl(SSE3, "sse3", 8 ) /* SSE3 comes from cpuid 1 (ECX) */ \
decl(SSSE3, "ssse3", 9 ) \
decl(SSE4A, "sse4a", 10) \
decl(SSE4_1, "sse4.1", 11) \
\
decl(SSE4_2, "sse4.2", 12) \
decl(POPCNT, "popcnt", 13) \
decl(LZCNT, "lzcnt", 14) \
decl(TSC, "tsc", 15) \
\
decl(TSCINV_BIT, "tscinvbit", 16) \
decl(TSCINV, "tscinv", 17) \
decl(AVX, "avx", 18) \
decl(AVX2, "avx2", 19) \
\
decl(AES, "aes", 20) \
decl(ERMS, "erms", 21) /* enhanced 'rep movsb/stosb' instructions */ \
decl(CLMUL, "clmul", 22) /* carryless multiply for CRC */ \
decl(BMI1, "bmi1", 23) \
\
decl(BMI2, "bmi2", 24) \
decl(RTM, "rtm", 25) /* Restricted Transactional Memory instructions */ \
decl(ADX, "adx", 26) \
decl(AVX512F, "avx512f", 27) /* AVX 512bit foundation instructions */ \
\
decl(AVX512DQ, "avx512dq", 28) \
decl(AVX512PF, "avx512pf", 29) \
decl(AVX512ER, "avx512er", 30) \
decl(AVX512CD, "avx512cd", 31) \
\
decl(AVX512BW, "avx512bw", 32) /* Byte and word vector instructions */ \
decl(AVX512VL, "avx512vl", 33) /* EVEX instructions with smaller vector length */ \
decl(SHA, "sha", 34) /* SHA instructions */ \
decl(FMA, "fma", 35) /* FMA instructions */ \
\
decl(VZEROUPPER, "vzeroupper", 36) /* Vzeroupper instruction */ \
decl(AVX512_VPOPCNTDQ, "avx512_vpopcntdq", 37) /* Vector popcount */ \
decl(AVX512_VPCLMULQDQ, "avx512_vpclmulqdq", 38) /* Vector carryless multiplication */ \
decl(AVX512_VAES, "avx512_vaes", 39) /* Vector AES instruction */ \
\
decl(AVX512_VNNI, "avx512_vnni", 40) /* Vector Neural Network Instructions */ \
decl(FLUSH, "clflush", 41) /* flush instruction */ \
decl(FLUSHOPT, "clflushopt", 42) /* flusopth instruction */ \
decl(CLWB, "clwb", 43) /* clwb instruction */ \
\
decl(AVX512_VBMI2, "avx512_vbmi2", 44) /* VBMI2 shift left double instructions */ \
decl(AVX512_VBMI, "avx512_vbmi", 45) /* Vector BMI instructions */ \
decl(HV, "hv", 46) /* Hypervisor instructions */
CPU_MMX = (1ULL << 4),
CPU_3DNOW_PREFETCH = (1ULL << 5), // Processor supports 3dnow prefetch and prefetchw instructions
// may not necessarily support other 3dnow instructions
CPU_SSE = (1ULL << 6),
CPU_SSE2 = (1ULL << 7),
CPU_SSE3 = (1ULL << 8), // SSE3 comes from cpuid 1 (ECX)
CPU_SSSE3 = (1ULL << 9),
CPU_SSE4A = (1ULL << 10),
CPU_SSE4_1 = (1ULL << 11),
CPU_SSE4_2 = (1ULL << 12),
CPU_POPCNT = (1ULL << 13),
CPU_LZCNT = (1ULL << 14),
CPU_TSC = (1ULL << 15),
CPU_TSCINV_BIT = (1ULL << 16),
CPU_TSCINV = (1ULL << 17),
CPU_AVX = (1ULL << 18),
CPU_AVX2 = (1ULL << 19),
CPU_AES = (1ULL << 20),
CPU_ERMS = (1ULL << 21), // enhanced 'rep movsb/stosb' instructions
CPU_CLMUL = (1ULL << 22), // carryless multiply for CRC
CPU_BMI1 = (1ULL << 23),
CPU_BMI2 = (1ULL << 24),
CPU_RTM = (1ULL << 25), // Restricted Transactional Memory instructions
CPU_ADX = (1ULL << 26),
CPU_AVX512F = (1ULL << 27), // AVX 512bit foundation instructions
CPU_AVX512DQ = (1ULL << 28),
CPU_AVX512PF = (1ULL << 29),
CPU_AVX512ER = (1ULL << 30),
CPU_AVX512CD = (1ULL << 31),
CPU_AVX512BW = (1ULL << 32), // Byte and word vector instructions
CPU_AVX512VL = (1ULL << 33), // EVEX instructions with smaller vector length
CPU_SHA = (1ULL << 34), // SHA instructions
CPU_FMA = (1ULL << 35), // FMA instructions
CPU_VZEROUPPER = (1ULL << 36), // Vzeroupper instruction
CPU_AVX512_VPOPCNTDQ = (1ULL << 37), // Vector popcount
CPU_AVX512_VPCLMULQDQ = (1ULL << 38), // Vector carryless multiplication
CPU_AVX512_VAES = (1ULL << 39), // Vector AES instruction
CPU_AVX512_VNNI = (1ULL << 40), // Vector Neural Network Instructions
CPU_FLUSH = (1ULL << 41), // flush instruction
CPU_FLUSHOPT = (1ULL << 42), // flusopth instruction
CPU_CLWB = (1ULL << 43), // clwb instruction
CPU_AVX512_VBMI2 = (1ULL << 44), // VBMI2 shift left double instructions
CPU_AVX512_VBMI = (1ULL << 45), // Vector BMI instructions
CPU_HV = (1ULL << 46), // Hypervisor instructions
CPU_MAX_FEATURE = CPU_HV
#define DECLARE_CPU_FEATURE_FLAG(id, name, bit) CPU_##id = (1ULL << bit),
CPU_FEATURE_FLAGS(DECLARE_CPU_FEATURE_FLAG)
#undef DECLARE_CPU_FEATURE_FLAG
};
#define FEATURES_NAMES \
"cx8", "cmov", "fxsr", "ht", \
"mmx", "3dnowpref", "sse", "sse2", \
"sse3", "ssse3", "sse4a", "sse4.1", \
"sse4.2", "popcnt", "lzcnt", "tsc", \
"tscinvbit", "tscinv", "avx", "avx2", \
"aes", "erms", "clmul", "bmi1", \
"bmi2", "rtm", "adx", "avx512f", \
"avx512dq", "avx512pf", "avx512er", "avx512cd", \
"avx512bw", "avx512vl", "sha", "fma", \
"vzeroupper", "avx512_vpopcntdq", "avx512_vpclmulqdq", "avx512_vaes", \
"avx512_vnni", "clflush", "clflushopt", "clwb", \
"avx512_vmbi2", "avx512_vmbi", "hv"
static const char* _features_names[];
// NB! When adding new CPU feature detection consider updating vmStructs_x86.hpp, vmStructs_jvmci.hpp, and VM_Version::get_processor_features().
enum Extended_Family {
// AMD
CPU_FAMILY_AMD_11H = 0x11,

@ -750,22 +750,11 @@
static_field(VM_Version, _zva_length, int) \
volatile_nonstatic_field(JavaFrameAnchor, _last_Java_fp, intptr_t*)
#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \
declare_constant(VM_Version::CPU_FP) \
declare_constant(VM_Version::CPU_ASIMD) \
declare_constant(VM_Version::CPU_EVTSTRM) \
declare_constant(VM_Version::CPU_AES) \
declare_constant(VM_Version::CPU_PMULL) \
declare_constant(VM_Version::CPU_SHA1) \
declare_constant(VM_Version::CPU_SHA2) \
declare_constant(VM_Version::CPU_CRC32) \
declare_constant(VM_Version::CPU_LSE) \
declare_constant(VM_Version::CPU_STXR_PREFETCH) \
declare_constant(VM_Version::CPU_A53MAC)
#define DECLARE_INT_CPU_FEATURE_CONSTANT(id, name, bit) GENERATE_VM_INT_CONSTANT_ENTRY(VM_Version::CPU_##id)
#define VM_INT_CPU_FEATURE_CONSTANTS CPU_FEATURE_FLAGS(DECLARE_INT_CPU_FEATURE_CONSTANT)
#endif
#ifdef X86
#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \
@ -777,53 +766,8 @@
declare_constant(frame::interpreter_frame_sender_sp_offset) \
declare_constant(frame::interpreter_frame_last_sp_offset)
#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \
declare_constant(VM_Version::CPU_CX8) \
declare_constant(VM_Version::CPU_CMOV) \
declare_constant(VM_Version::CPU_FXSR) \
declare_constant(VM_Version::CPU_HT) \
declare_constant(VM_Version::CPU_MMX) \
declare_constant(VM_Version::CPU_3DNOW_PREFETCH) \
declare_constant(VM_Version::CPU_SSE) \
declare_constant(VM_Version::CPU_SSE2) \
declare_constant(VM_Version::CPU_SSE3) \
declare_constant(VM_Version::CPU_SSSE3) \
declare_constant(VM_Version::CPU_SSE4A) \
declare_constant(VM_Version::CPU_SSE4_1) \
declare_constant(VM_Version::CPU_SSE4_2) \
declare_constant(VM_Version::CPU_POPCNT) \
declare_constant(VM_Version::CPU_LZCNT) \
declare_constant(VM_Version::CPU_TSC) \
declare_constant(VM_Version::CPU_TSCINV) \
declare_constant(VM_Version::CPU_AVX) \
declare_constant(VM_Version::CPU_AVX2) \
declare_constant(VM_Version::CPU_AES) \
declare_constant(VM_Version::CPU_ERMS) \
declare_constant(VM_Version::CPU_CLMUL) \
declare_constant(VM_Version::CPU_BMI1) \
declare_constant(VM_Version::CPU_BMI2) \
declare_constant(VM_Version::CPU_RTM) \
declare_constant(VM_Version::CPU_ADX) \
declare_constant(VM_Version::CPU_AVX512F) \
declare_constant(VM_Version::CPU_AVX512DQ) \
declare_constant(VM_Version::CPU_AVX512PF) \
declare_constant(VM_Version::CPU_AVX512ER) \
declare_constant(VM_Version::CPU_AVX512CD) \
declare_constant(VM_Version::CPU_AVX512BW) \
declare_constant(VM_Version::CPU_AVX512VL) \
declare_constant(VM_Version::CPU_SHA) \
declare_constant(VM_Version::CPU_FMA) \
declare_constant(VM_Version::CPU_VZEROUPPER) \
declare_constant(VM_Version::CPU_AVX512_VPOPCNTDQ) \
declare_constant(VM_Version::CPU_AVX512_VPCLMULQDQ) \
declare_constant(VM_Version::CPU_AVX512_VAES) \
declare_constant(VM_Version::CPU_AVX512_VNNI) \
declare_constant(VM_Version::CPU_FLUSH) \
declare_constant(VM_Version::CPU_FLUSHOPT) \
declare_constant(VM_Version::CPU_CLWB) \
declare_constant(VM_Version::CPU_AVX512_VBMI2) \
declare_constant(VM_Version::CPU_AVX512_VBMI) \
declare_constant(VM_Version::CPU_HV)
#define DECLARE_LONG_CPU_FEATURE_CONSTANT(id, name, bit) GENERATE_VM_LONG_CONSTANT_ENTRY(VM_Version::CPU_##id)
#define VM_LONG_CPU_FEATURE_CONSTANTS CPU_FEATURE_FLAGS(DECLARE_LONG_CPU_FEATURE_CONSTANT)
#endif
@ -900,7 +844,9 @@ VMIntConstantEntry JVMCIVMStructs::localHotSpotVMIntConstants[] = {
GENERATE_VM_INT_CONSTANT_WITH_VALUE_ENTRY,
GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY)
#endif
#ifdef VM_INT_CPU_FEATURE_CONSTANTS
VM_INT_CPU_FEATURE_CONSTANTS
#endif
GENERATE_VM_INT_CONSTANT_LAST_ENTRY()
};
@ -913,9 +859,12 @@ VMLongConstantEntry JVMCIVMStructs::localHotSpotVMLongConstants[] = {
GENERATE_C1_VM_LONG_CONSTANT_ENTRY,
GENERATE_C2_VM_LONG_CONSTANT_ENTRY,
GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY)
#ifdef VM_LONG_CPU_FEATURE_CONSTANTS
VM_LONG_CPU_FEATURE_CONSTANTS
#endif
GENERATE_VM_LONG_CONSTANT_LAST_ENTRY()
};
#undef DECLARE_CPU_FEATURE_FLAG
VMAddressEntry JVMCIVMStructs::localHotSpotVMAddresses[] = {
VM_ADDRESSES(GENERATE_VM_ADDRESS_ENTRY,

@ -2910,6 +2910,9 @@ VMIntConstantEntry VMStructs::localHotSpotVMIntConstants[] = {
GENERATE_C1_VM_INT_CONSTANT_ENTRY,
GENERATE_C2_VM_INT_CONSTANT_ENTRY,
GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY)
#ifdef VM_INT_CPU_FEATURE_CONSTANTS
VM_INT_CPU_FEATURE_CONSTANTS
#endif
GENERATE_VM_INT_CONSTANT_LAST_ENTRY()
};
@ -2943,6 +2946,9 @@ VMLongConstantEntry VMStructs::localHotSpotVMLongConstants[] = {
GENERATE_C1_VM_LONG_CONSTANT_ENTRY,
GENERATE_C2_VM_LONG_CONSTANT_ENTRY,
GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY)
#ifdef VM_LONG_CPU_FEATURE_CONSTANTS
VM_LONG_CPU_FEATURE_CONSTANTS
#endif
GENERATE_VM_LONG_CONSTANT_LAST_ENTRY()
};

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -26,6 +26,7 @@ import java.nio.ByteOrder;
import java.util.EnumSet;
import jdk.vm.ci.code.Architecture;
import jdk.vm.ci.code.CPUFeatureName;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.Register.RegisterCategory;
import jdk.vm.ci.code.RegisterArray;
@ -162,7 +163,7 @@ public class AArch64 extends Architecture {
* Basic set of CPU features mirroring what is returned from the cpuid instruction. See:
* {@code VM_Version::cpuFeatureFlags}.
*/
public enum CPUFeature {
public enum CPUFeature implements CPUFeatureName {
FP,
ASIMD,
EVTSTRM,
@ -172,8 +173,13 @@ public class AArch64 extends Architecture {
SHA2,
CRC32,
LSE,
DCPOP,
SHA3,
SHA512,
SVE,
SVE2,
STXR_PREFETCH,
A53MAC
A53MAC,
}
private final EnumSet<CPUFeature> features;
@ -198,6 +204,7 @@ public class AArch64 extends Architecture {
this.flags = flags;
}
@Override
public EnumSet<CPUFeature> getFeatures() {
return features;
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -31,6 +31,7 @@ import java.nio.ByteOrder;
import java.util.EnumSet;
import jdk.vm.ci.code.Architecture;
import jdk.vm.ci.code.CPUFeatureName;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.Register.RegisterCategory;
import jdk.vm.ci.code.RegisterArray;
@ -171,7 +172,7 @@ public class AMD64 extends Architecture {
* Basic set of CPU features mirroring what is returned from the cpuid instruction. See:
* {@code VM_Version::cpuFeatureFlags}.
*/
public enum CPUFeature {
public enum CPUFeature implements CPUFeatureName {
CX8,
CMOV,
FXSR,
@ -189,6 +190,7 @@ public class AMD64 extends Architecture {
LZCNT,
TSC,
TSCINV,
TSCINV_BIT,
AVX,
AVX2,
AES,
@ -206,7 +208,18 @@ public class AMD64 extends Architecture {
AVX512BW,
AVX512VL,
SHA,
FMA
FMA,
VZEROUPPER,
AVX512_VPOPCNTDQ,
AVX512_VPCLMULQDQ,
AVX512_VAES,
AVX512_VNNI,
FLUSH,
FLUSHOPT,
CLWB,
AVX512_VBMI2,
AVX512_VBMI,
HV,
}
private final EnumSet<CPUFeature> features;
@ -238,6 +251,7 @@ public class AMD64 extends Architecture {
}
}
@Override
public EnumSet<CPUFeature> getFeatures() {
return features;
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -23,6 +23,7 @@
package jdk.vm.ci.code;
import java.nio.ByteOrder;
import java.util.Set;
import jdk.vm.ci.code.Register.RegisterCategory;
import jdk.vm.ci.meta.JavaKind;
@ -90,6 +91,11 @@ public abstract class Architecture {
this.returnAddressSize = returnAddressSize;
}
/**
* Gets the set of CPU features supported by the current platform.
*/
public abstract Set<? extends CPUFeatureName> getFeatures();
/**
* Converts this architecture to a string.
*

@ -0,0 +1,40 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.vm.ci.code;
/**
* A CPU feature identified by a name.
*/
public interface CPUFeatureName {
/**
* Gets the name of this feature.
*/
String name();
/**
* Determines if {@code other} equals {@link #name()}.
*/
default boolean nameEquals(String other) {
return name().equals(other);
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -22,11 +22,14 @@
*/
package jdk.vm.ci.hotspot.aarch64;
import static java.util.Collections.emptyMap;
import static jdk.vm.ci.common.InitTimer.timer;
import java.util.EnumSet;
import java.util.Map;
import jdk.vm.ci.aarch64.AArch64;
import jdk.vm.ci.aarch64.AArch64.CPUFeature;
import jdk.vm.ci.code.Architecture;
import jdk.vm.ci.code.RegisterConfig;
import jdk.vm.ci.code.TargetDescription;
@ -43,48 +46,13 @@ import jdk.vm.ci.runtime.JVMCIBackend;
public class AArch64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFactory {
private static EnumSet<AArch64.CPUFeature> computeFeatures(@SuppressWarnings("unused") AArch64HotSpotVMConfig config) {
private static EnumSet<AArch64.CPUFeature> computeFeatures(AArch64HotSpotVMConfig config) {
// Configure the feature set using the HotSpot flag settings.
EnumSet<AArch64.CPUFeature> features = EnumSet.noneOf(AArch64.CPUFeature.class);
if ((config.vmVersionFeatures & config.aarch64FP) != 0) {
features.add(AArch64.CPUFeature.FP);
}
if ((config.vmVersionFeatures & config.aarch64ASIMD) != 0) {
features.add(AArch64.CPUFeature.ASIMD);
}
if ((config.vmVersionFeatures & config.aarch64EVTSTRM) != 0) {
features.add(AArch64.CPUFeature.EVTSTRM);
}
if ((config.vmVersionFeatures & config.aarch64AES) != 0) {
features.add(AArch64.CPUFeature.AES);
}
if ((config.vmVersionFeatures & config.aarch64PMULL) != 0) {
features.add(AArch64.CPUFeature.PMULL);
}
if ((config.vmVersionFeatures & config.aarch64SHA1) != 0) {
features.add(AArch64.CPUFeature.SHA1);
}
if ((config.vmVersionFeatures & config.aarch64SHA2) != 0) {
features.add(AArch64.CPUFeature.SHA2);
}
if ((config.vmVersionFeatures & config.aarch64CRC32) != 0) {
features.add(AArch64.CPUFeature.CRC32);
}
if ((config.vmVersionFeatures & config.aarch64LSE) != 0) {
features.add(AArch64.CPUFeature.LSE);
}
if ((config.vmVersionFeatures & config.aarch64STXR_PREFETCH) != 0) {
features.add(AArch64.CPUFeature.STXR_PREFETCH);
}
if ((config.vmVersionFeatures & config.aarch64A53MAC) != 0) {
features.add(AArch64.CPUFeature.A53MAC);
}
return features;
Map<String, Long> constants = config.getStore().getConstants();
return HotSpotJVMCIBackendFactory.convertFeatures(CPUFeature.class, constants, config.vmVersionFeatures, emptyMap());
}
private static EnumSet<AArch64.Flag> computeFlags(@SuppressWarnings("unused") AArch64HotSpotVMConfig config) {
private static EnumSet<AArch64.Flag> computeFlags(AArch64HotSpotVMConfig config) {
EnumSet<AArch64.Flag> flags = EnumSet.noneOf(AArch64.Flag.class);
if (config.useCRC32) {

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,8 +25,10 @@ package jdk.vm.ci.hotspot.amd64;
import static jdk.vm.ci.common.InitTimer.timer;
import java.util.EnumSet;
import java.util.Map;
import jdk.vm.ci.amd64.AMD64;
import jdk.vm.ci.amd64.AMD64.CPUFeature;
import jdk.vm.ci.code.Architecture;
import jdk.vm.ci.code.RegisterConfig;
import jdk.vm.ci.code.TargetDescription;
@ -43,90 +45,14 @@ import jdk.vm.ci.runtime.JVMCIBackend;
public class AMD64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFactory {
private static EnumSet<AMD64.CPUFeature> computeFeatures(AMD64HotSpotVMConfig config) {
private static EnumSet<CPUFeature> computeFeatures(AMD64HotSpotVMConfig config) {
// Configure the feature set using the HotSpot flag settings.
EnumSet<AMD64.CPUFeature> features = EnumSet.noneOf(AMD64.CPUFeature.class);
if ((config.vmVersionFeatures & config.amd643DNOWPREFETCH) != 0) {
features.add(AMD64.CPUFeature.AMD_3DNOW_PREFETCH);
}
Map<String, Long> constants = config.getStore().getConstants();
Map<String, String> renaming = Map.of("3DNOW_PREFETCH", "AMD_3DNOW_PREFETCH");
assert config.useSSE >= 2 : "minimum config for x64";
EnumSet<CPUFeature> features = HotSpotJVMCIBackendFactory.convertFeatures(CPUFeature.class, constants, config.vmVersionFeatures, renaming);
features.add(AMD64.CPUFeature.SSE);
features.add(AMD64.CPUFeature.SSE2);
if ((config.vmVersionFeatures & config.amd64SSE3) != 0) {
features.add(AMD64.CPUFeature.SSE3);
}
if ((config.vmVersionFeatures & config.amd64SSSE3) != 0) {
features.add(AMD64.CPUFeature.SSSE3);
}
if ((config.vmVersionFeatures & config.amd64SSE4A) != 0) {
features.add(AMD64.CPUFeature.SSE4A);
}
if ((config.vmVersionFeatures & config.amd64SSE41) != 0) {
features.add(AMD64.CPUFeature.SSE4_1);
}
if ((config.vmVersionFeatures & config.amd64SSE42) != 0) {
features.add(AMD64.CPUFeature.SSE4_2);
}
if ((config.vmVersionFeatures & config.amd64POPCNT) != 0) {
features.add(AMD64.CPUFeature.POPCNT);
}
if ((config.vmVersionFeatures & config.amd64LZCNT) != 0) {
features.add(AMD64.CPUFeature.LZCNT);
}
if ((config.vmVersionFeatures & config.amd64ERMS) != 0) {
features.add(AMD64.CPUFeature.ERMS);
}
if ((config.vmVersionFeatures & config.amd64AVX) != 0) {
features.add(AMD64.CPUFeature.AVX);
}
if ((config.vmVersionFeatures & config.amd64AVX2) != 0) {
features.add(AMD64.CPUFeature.AVX2);
}
if ((config.vmVersionFeatures & config.amd64AES) != 0) {
features.add(AMD64.CPUFeature.AES);
}
if ((config.vmVersionFeatures & config.amd643DNOWPREFETCH) != 0) {
features.add(AMD64.CPUFeature.AMD_3DNOW_PREFETCH);
}
if ((config.vmVersionFeatures & config.amd64BMI1) != 0) {
features.add(AMD64.CPUFeature.BMI1);
}
if ((config.vmVersionFeatures & config.amd64BMI2) != 0) {
features.add(AMD64.CPUFeature.BMI2);
}
if ((config.vmVersionFeatures & config.amd64RTM) != 0) {
features.add(AMD64.CPUFeature.RTM);
}
if ((config.vmVersionFeatures & config.amd64ADX) != 0) {
features.add(AMD64.CPUFeature.ADX);
}
if ((config.vmVersionFeatures & config.amd64AVX512F) != 0) {
features.add(AMD64.CPUFeature.AVX512F);
}
if ((config.vmVersionFeatures & config.amd64AVX512DQ) != 0) {
features.add(AMD64.CPUFeature.AVX512DQ);
}
if ((config.vmVersionFeatures & config.amd64AVX512PF) != 0) {
features.add(AMD64.CPUFeature.AVX512PF);
}
if ((config.vmVersionFeatures & config.amd64AVX512ER) != 0) {
features.add(AMD64.CPUFeature.AVX512ER);
}
if ((config.vmVersionFeatures & config.amd64AVX512CD) != 0) {
features.add(AMD64.CPUFeature.AVX512CD);
}
if ((config.vmVersionFeatures & config.amd64AVX512BW) != 0) {
features.add(AMD64.CPUFeature.AVX512BW);
}
if ((config.vmVersionFeatures & config.amd64AVX512VL) != 0) {
features.add(AMD64.CPUFeature.AVX512VL);
}
if ((config.vmVersionFeatures & config.amd64SHA) != 0) {
features.add(AMD64.CPUFeature.SHA);
}
if ((config.vmVersionFeatures & config.amd64FMA) != 0) {
features.add(AMD64.CPUFeature.FMA);
}
return features;
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -22,6 +22,13 @@
*/
package jdk.vm.ci.hotspot;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.runtime.JVMCIBackend;
public interface HotSpotJVMCIBackendFactory {
@ -32,4 +39,45 @@ public interface HotSpotJVMCIBackendFactory {
* Gets the CPU architecture of this backend.
*/
String getArchitecture();
/**
* Converts a bit mask of CPU features to enum constants.
*
* @param <CPUFeatureType> CPU feature enum type
* @param enumType the class of {@code CPUFeatureType}
* @param constants VM constants. Each entry whose key starts with {@code "VM_Version::CPU_"}
* specifies a CPU feature and its value is a mask for a bit in {@code features}
* @param features bits specifying CPU features
* @param renaming maps from VM feature names to enum constant names where the two differ
* @throws IllegalArgumentException if any VM CPU feature constant cannot be converted to an
* enum value
* @return the set of converted values
*/
static <CPUFeatureType extends Enum<CPUFeatureType>> EnumSet<CPUFeatureType> convertFeatures(
Class<CPUFeatureType> enumType,
Map<String, Long> constants,
long features,
Map<String, String> renaming) {
EnumSet<CPUFeatureType> outFeatures = EnumSet.noneOf(enumType);
List<String> missing = new ArrayList<>();
for (Entry<String, Long> e : constants.entrySet()) {
long bitMask = e.getValue();
String key = e.getKey();
if (key.startsWith("VM_Version::CPU_")) {
String name = key.substring("VM_Version::CPU_".length());
try {
CPUFeatureType feature = Enum.valueOf(enumType, renaming.getOrDefault(name, name));
if ((features & bitMask) != 0) {
outFeatures.add(feature);
}
} catch (IllegalArgumentException iae) {
missing.add(name);
}
}
}
if (!missing.isEmpty()) {
throw new JVMCIError("Missing CPU feature constants: %s", missing);
}
return outFeatures;
}
}