8352675: Support Intel AVX10 converged vector ISA feature detection
Reviewed-by: sviswanathan, vlivanov, yzheng
This commit is contained in:
parent
0f2a6c266b
commit
3b336a9da0
@ -35,8 +35,7 @@
|
||||
static_field(VM_Version, _rop_protection, bool) \
|
||||
static_field(VM_Version, _pac_mask, uintptr_t)
|
||||
|
||||
#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type) \
|
||||
declare_toplevel_type(VM_Version)
|
||||
#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type)
|
||||
|
||||
#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant)
|
||||
|
||||
|
@ -29,15 +29,20 @@
|
||||
// constants required by the Serviceability Agent. This file is
|
||||
// referenced by vmStructs.cpp.
|
||||
|
||||
#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field) \
|
||||
volatile_nonstatic_field(JavaFrameAnchor, _last_Java_fp, intptr_t*)
|
||||
#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field) \
|
||||
volatile_nonstatic_field(JavaFrameAnchor, _last_Java_fp, intptr_t*) \
|
||||
static_field(VM_Version, _features, VM_Version::VM_Features) \
|
||||
nonstatic_field(VM_Version::VM_Features, _features_bitmap[0], uint64_t) \
|
||||
static_field(VM_Version::VM_Features, _features_bitmap_size, int)
|
||||
|
||||
#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type) \
|
||||
declare_toplevel_type(VM_Version::VM_Features)
|
||||
|
||||
#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant) \
|
||||
LP64_ONLY(declare_constant(frame::arg_reg_save_area_bytes)) \
|
||||
declare_constant(frame::interpreter_frame_sender_sp_offset) \
|
||||
declare_constant(frame::interpreter_frame_last_sp_offset)
|
||||
declare_constant(frame::arg_reg_save_area_bytes) \
|
||||
declare_constant(frame::interpreter_frame_sender_sp_offset) \
|
||||
declare_constant(frame::interpreter_frame_last_sp_offset) \
|
||||
declare_constant(frame::entry_frame_call_wrapper_offset)
|
||||
|
||||
#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant)
|
||||
|
||||
|
@ -63,6 +63,11 @@ address VM_Version::_cpuinfo_cont_addr_apx = nullptr;
|
||||
static BufferBlob* stub_blob;
|
||||
static const int stub_size = 2000;
|
||||
|
||||
int VM_Version::VM_Features::_features_bitmap_size = sizeof(VM_Version::VM_Features::_features_bitmap) / BytesPerLong;
|
||||
|
||||
VM_Version::VM_Features VM_Version::_features;
|
||||
VM_Version::VM_Features VM_Version::_cpu_features;
|
||||
|
||||
extern "C" {
|
||||
typedef void (*get_cpu_info_stub_t)(void*);
|
||||
typedef void (*detect_virt_stub_t)(uint32_t, uint32_t*);
|
||||
@ -82,7 +87,7 @@ bool VM_Version::supports_clflush() {
|
||||
// up. Assembler::flush calls this routine to check that clflush
|
||||
// is allowed. So, we give the caller a free pass if Universe init
|
||||
// is still in progress.
|
||||
assert ((!Universe::is_fully_initialized() || (_features & CPU_FLUSH) != 0), "clflush should be available");
|
||||
assert ((!Universe::is_fully_initialized() || _features.supports_feature(CPU_FLUSH)), "clflush should be available");
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -133,7 +138,7 @@ class VM_Version_StubGenerator: public StubCodeGenerator {
|
||||
const uint32_t CPU_FAMILY_486 = (4 << CPU_FAMILY_SHIFT);
|
||||
bool use_evex = FLAG_IS_DEFAULT(UseAVX) || (UseAVX > 2);
|
||||
|
||||
Label detect_486, cpu486, detect_586, std_cpuid1, std_cpuid4;
|
||||
Label detect_486, cpu486, detect_586, std_cpuid1, std_cpuid4, std_cpuid24;
|
||||
Label sef_cpuid, sefsl1_cpuid, ext_cpuid, ext_cpuid1, ext_cpuid5, ext_cpuid7;
|
||||
Label ext_cpuid8, done, wrapup, vector_save_restore, apx_save_restore_warning;
|
||||
Label legacy_setup, save_restore_except, legacy_save_restore, start_simd_check;
|
||||
@ -332,6 +337,17 @@ class VM_Version_StubGenerator: public StubCodeGenerator {
|
||||
__ movl(Address(rsi, 0), rax);
|
||||
__ movl(Address(rsi, 4), rdx);
|
||||
|
||||
//
|
||||
// cpuid(0x24) Converged Vector ISA Main Leaf (EAX = 24H, ECX = 0).
|
||||
//
|
||||
__ bind(std_cpuid24);
|
||||
__ movl(rax, 0x24);
|
||||
__ movl(rcx, 0);
|
||||
__ cpuid();
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version::std_cpuid24_offset())));
|
||||
__ movl(Address(rsi, 0), rax);
|
||||
__ movl(Address(rsi, 4), rbx);
|
||||
|
||||
//
|
||||
// Extended cpuid(0x80000000)
|
||||
//
|
||||
@ -418,13 +434,11 @@ class VM_Version_StubGenerator: public StubCodeGenerator {
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version::sefsl1_cpuid7_offset())));
|
||||
__ movl(rax, 0x200000);
|
||||
__ andl(rax, Address(rsi, 4));
|
||||
__ cmpl(rax, 0x200000);
|
||||
__ jcc(Assembler::notEqual, vector_save_restore);
|
||||
__ jcc(Assembler::equal, vector_save_restore);
|
||||
// check _cpuid_info.xem_xcr0_eax.bits.apx_f
|
||||
__ movl(rax, 0x80000);
|
||||
__ andl(rax, Address(rbp, in_bytes(VM_Version::xem_xcr0_offset()))); // xcr0 bits apx_f
|
||||
__ cmpl(rax, 0x80000);
|
||||
__ jcc(Assembler::notEqual, vector_save_restore);
|
||||
__ jcc(Assembler::equal, vector_save_restore);
|
||||
|
||||
#ifndef PRODUCT
|
||||
bool save_apx = UseAPX;
|
||||
@ -477,11 +491,15 @@ class VM_Version_StubGenerator: public StubCodeGenerator {
|
||||
// If UseAVX is uninitialized or is set by the user to include EVEX
|
||||
if (use_evex) {
|
||||
// check _cpuid_info.sef_cpuid7_ebx.bits.avx512f
|
||||
// OR check _cpuid_info.sefsl1_cpuid7_edx.bits.avx10
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version::sef_cpuid7_offset())));
|
||||
__ movl(rax, 0x10000);
|
||||
__ andl(rax, Address(rsi, 4)); // xcr0 bits sse | ymm
|
||||
__ cmpl(rax, 0x10000);
|
||||
__ jccb(Assembler::notEqual, legacy_setup); // jump if EVEX is not supported
|
||||
__ andl(rax, Address(rsi, 4));
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version::sefsl1_cpuid7_offset())));
|
||||
__ movl(rbx, 0x80000);
|
||||
__ andl(rbx, Address(rsi, 4));
|
||||
__ orl(rax, rbx);
|
||||
__ jccb(Assembler::equal, legacy_setup); // jump if EVEX is not supported
|
||||
// check _cpuid_info.xem_xcr0_eax.bits.opmask
|
||||
// check _cpuid_info.xem_xcr0_eax.bits.zmm512
|
||||
// check _cpuid_info.xem_xcr0_eax.bits.zmm32
|
||||
@ -562,8 +580,7 @@ class VM_Version_StubGenerator: public StubCodeGenerator {
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version::sef_cpuid7_offset())));
|
||||
__ movl(rax, 0x10000);
|
||||
__ andl(rax, Address(rsi, 4));
|
||||
__ cmpl(rax, 0x10000);
|
||||
__ jcc(Assembler::notEqual, legacy_save_restore);
|
||||
__ jcc(Assembler::equal, legacy_save_restore);
|
||||
// check _cpuid_info.xem_xcr0_eax.bits.opmask
|
||||
// check _cpuid_info.xem_xcr0_eax.bits.zmm512
|
||||
// check _cpuid_info.xem_xcr0_eax.bits.zmm32
|
||||
@ -835,7 +852,6 @@ void VM_Version::get_processor_features() {
|
||||
_cpu = 4; // 486 by default
|
||||
_model = 0;
|
||||
_stepping = 0;
|
||||
_features = 0;
|
||||
_logical_processors_per_package = 1;
|
||||
// i486 internal cache is both I&D and has a 16-byte line size
|
||||
_L1_data_cache_line_size = 16;
|
||||
@ -851,7 +867,7 @@ void VM_Version::get_processor_features() {
|
||||
|
||||
if (cpu_family() > 4) { // it supports CPUID
|
||||
_features = _cpuid_info.feature_flags(); // These can be changed by VM settings
|
||||
_cpu_features = _features; // Preserve features
|
||||
_cpu_features = _features; // Preserve features
|
||||
// Logical processors are only available on P4s and above,
|
||||
// and only if hyperthreading is available.
|
||||
_logical_processors_per_package = logical_processor_count();
|
||||
@ -900,21 +916,21 @@ void VM_Version::get_processor_features() {
|
||||
}
|
||||
|
||||
if (UseSSE < 4) {
|
||||
_features &= ~CPU_SSE4_1;
|
||||
_features &= ~CPU_SSE4_2;
|
||||
_features.clear_feature(CPU_SSE4_1);
|
||||
_features.clear_feature(CPU_SSE4_2);
|
||||
}
|
||||
|
||||
if (UseSSE < 3) {
|
||||
_features &= ~CPU_SSE3;
|
||||
_features &= ~CPU_SSSE3;
|
||||
_features &= ~CPU_SSE4A;
|
||||
_features.clear_feature(CPU_SSE3);
|
||||
_features.clear_feature(CPU_SSSE3);
|
||||
_features.clear_feature(CPU_SSE4A);
|
||||
}
|
||||
|
||||
if (UseSSE < 2)
|
||||
_features &= ~CPU_SSE2;
|
||||
_features.clear_feature(CPU_SSE2);
|
||||
|
||||
if (UseSSE < 1)
|
||||
_features &= ~CPU_SSE;
|
||||
_features.clear_feature(CPU_SSE);
|
||||
|
||||
//since AVX instructions is slower than SSE in some ZX cpus, force USEAVX=0.
|
||||
if (is_zx() && ((cpu_family() == 6) || (cpu_family() == 7))) {
|
||||
@ -980,21 +996,25 @@ void VM_Version::get_processor_features() {
|
||||
}
|
||||
|
||||
if (UseAVX < 3) {
|
||||
_features &= ~CPU_AVX512F;
|
||||
_features &= ~CPU_AVX512DQ;
|
||||
_features &= ~CPU_AVX512CD;
|
||||
_features &= ~CPU_AVX512BW;
|
||||
_features &= ~CPU_AVX512VL;
|
||||
_features &= ~CPU_AVX512_VPOPCNTDQ;
|
||||
_features &= ~CPU_AVX512_VPCLMULQDQ;
|
||||
_features &= ~CPU_AVX512_VAES;
|
||||
_features &= ~CPU_AVX512_VNNI;
|
||||
_features &= ~CPU_AVX512_VBMI;
|
||||
_features &= ~CPU_AVX512_VBMI2;
|
||||
_features &= ~CPU_AVX512_BITALG;
|
||||
_features &= ~CPU_AVX512_IFMA;
|
||||
_features &= ~CPU_APX_F;
|
||||
_features &= ~CPU_AVX512_FP16;
|
||||
_features.clear_feature(CPU_AVX512F);
|
||||
_features.clear_feature(CPU_AVX512DQ);
|
||||
_features.clear_feature(CPU_AVX512CD);
|
||||
_features.clear_feature(CPU_AVX512BW);
|
||||
_features.clear_feature(CPU_AVX512ER);
|
||||
_features.clear_feature(CPU_AVX512PF);
|
||||
_features.clear_feature(CPU_AVX512VL);
|
||||
_features.clear_feature(CPU_AVX512_VPOPCNTDQ);
|
||||
_features.clear_feature(CPU_AVX512_VPCLMULQDQ);
|
||||
_features.clear_feature(CPU_AVX512_VAES);
|
||||
_features.clear_feature(CPU_AVX512_VNNI);
|
||||
_features.clear_feature(CPU_AVX512_VBMI);
|
||||
_features.clear_feature(CPU_AVX512_VBMI2);
|
||||
_features.clear_feature(CPU_AVX512_BITALG);
|
||||
_features.clear_feature(CPU_AVX512_IFMA);
|
||||
_features.clear_feature(CPU_APX_F);
|
||||
_features.clear_feature(CPU_AVX512_FP16);
|
||||
_features.clear_feature(CPU_AVX10_1);
|
||||
_features.clear_feature(CPU_AVX10_2);
|
||||
}
|
||||
|
||||
// Currently APX support is only enabled for targets supporting AVX512VL feature.
|
||||
@ -1007,45 +1027,47 @@ void VM_Version::get_processor_features() {
|
||||
}
|
||||
|
||||
if (!UseAPX) {
|
||||
_features &= ~CPU_APX_F;
|
||||
_features.clear_feature(CPU_APX_F);
|
||||
}
|
||||
|
||||
if (UseAVX < 2) {
|
||||
_features &= ~CPU_AVX2;
|
||||
_features &= ~CPU_AVX_IFMA;
|
||||
_features.clear_feature(CPU_AVX2);
|
||||
_features.clear_feature(CPU_AVX_IFMA);
|
||||
}
|
||||
|
||||
if (UseAVX < 1) {
|
||||
_features &= ~CPU_AVX;
|
||||
_features &= ~CPU_VZEROUPPER;
|
||||
_features &= ~CPU_F16C;
|
||||
_features &= ~CPU_SHA512;
|
||||
_features.clear_feature(CPU_AVX);
|
||||
_features.clear_feature(CPU_VZEROUPPER);
|
||||
_features.clear_feature(CPU_F16C);
|
||||
_features.clear_feature(CPU_SHA512);
|
||||
}
|
||||
|
||||
if (logical_processors_per_package() == 1) {
|
||||
// HT processor could be installed on a system which doesn't support HT.
|
||||
_features &= ~CPU_HT;
|
||||
_features.clear_feature(CPU_HT);
|
||||
}
|
||||
|
||||
if (is_intel()) { // Intel cpus specific settings
|
||||
if (is_knights_family()) {
|
||||
_features &= ~CPU_VZEROUPPER;
|
||||
_features &= ~CPU_AVX512BW;
|
||||
_features &= ~CPU_AVX512VL;
|
||||
_features &= ~CPU_AVX512DQ;
|
||||
_features &= ~CPU_AVX512_VNNI;
|
||||
_features &= ~CPU_AVX512_VAES;
|
||||
_features &= ~CPU_AVX512_VPOPCNTDQ;
|
||||
_features &= ~CPU_AVX512_VPCLMULQDQ;
|
||||
_features &= ~CPU_AVX512_VBMI;
|
||||
_features &= ~CPU_AVX512_VBMI2;
|
||||
_features &= ~CPU_CLWB;
|
||||
_features &= ~CPU_FLUSHOPT;
|
||||
_features &= ~CPU_GFNI;
|
||||
_features &= ~CPU_AVX512_BITALG;
|
||||
_features &= ~CPU_AVX512_IFMA;
|
||||
_features &= ~CPU_AVX_IFMA;
|
||||
_features &= ~CPU_AVX512_FP16;
|
||||
_features.clear_feature(CPU_VZEROUPPER);
|
||||
_features.clear_feature(CPU_AVX512BW);
|
||||
_features.clear_feature(CPU_AVX512VL);
|
||||
_features.clear_feature(CPU_AVX512DQ);
|
||||
_features.clear_feature(CPU_AVX512_VNNI);
|
||||
_features.clear_feature(CPU_AVX512_VAES);
|
||||
_features.clear_feature(CPU_AVX512_VPOPCNTDQ);
|
||||
_features.clear_feature(CPU_AVX512_VPCLMULQDQ);
|
||||
_features.clear_feature(CPU_AVX512_VBMI);
|
||||
_features.clear_feature(CPU_AVX512_VBMI2);
|
||||
_features.clear_feature(CPU_CLWB);
|
||||
_features.clear_feature(CPU_FLUSHOPT);
|
||||
_features.clear_feature(CPU_GFNI);
|
||||
_features.clear_feature(CPU_AVX512_BITALG);
|
||||
_features.clear_feature(CPU_AVX512_IFMA);
|
||||
_features.clear_feature(CPU_AVX_IFMA);
|
||||
_features.clear_feature(CPU_AVX512_FP16);
|
||||
_features.clear_feature(CPU_AVX10_1);
|
||||
_features.clear_feature(CPU_AVX10_2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1055,7 +1077,6 @@ void VM_Version::get_processor_features() {
|
||||
_has_intel_jcc_erratum = IntelJccErratumMitigation;
|
||||
}
|
||||
|
||||
assert(supports_cpuid(), "Always present");
|
||||
assert(supports_clflush(), "Always present");
|
||||
if (X86ICacheSync == -1) {
|
||||
// Auto-detect, choosing the best performant one that still flushes
|
||||
@ -1079,14 +1100,15 @@ void VM_Version::get_processor_features() {
|
||||
}
|
||||
}
|
||||
|
||||
char buf[1024];
|
||||
int cpu_info_size = jio_snprintf(
|
||||
char buf[2048];
|
||||
size_t cpu_info_size = jio_snprintf(
|
||||
buf, sizeof(buf),
|
||||
"(%u cores per cpu, %u threads per core) family %d model %d stepping %d microcode 0x%x",
|
||||
cores_per_cpu(), threads_per_core(),
|
||||
cpu_family(), _model, _stepping, os::cpu_microcode_revision());
|
||||
assert(cpu_info_size > 0, "not enough temporary space allocated");
|
||||
insert_features_names(buf + cpu_info_size, sizeof(buf) - cpu_info_size, _features_names);
|
||||
|
||||
insert_features_names(_features, buf + cpu_info_size, sizeof(buf) - cpu_info_size);
|
||||
|
||||
_cpu_info_string = os::strdup(buf);
|
||||
|
||||
@ -2088,6 +2110,7 @@ static bool _vm_version_initialized = false;
|
||||
|
||||
void VM_Version::initialize() {
|
||||
ResourceMark rm;
|
||||
|
||||
// Making this stub must be FIRST use of assembler
|
||||
stub_blob = BufferBlob::create("VM_Version stub", stub_size);
|
||||
if (stub_blob == nullptr) {
|
||||
@ -2863,185 +2886,212 @@ int64_t VM_Version::maximum_qualified_cpu_frequency(void) {
|
||||
return _max_qualified_cpu_frequency;
|
||||
}
|
||||
|
||||
uint64_t VM_Version::CpuidInfo::feature_flags() const {
|
||||
uint64_t result = 0;
|
||||
VM_Version::VM_Features VM_Version::CpuidInfo::feature_flags() const {
|
||||
VM_Features vm_features;
|
||||
if (std_cpuid1_edx.bits.cmpxchg8 != 0)
|
||||
result |= CPU_CX8;
|
||||
vm_features.set_feature(CPU_CX8);
|
||||
if (std_cpuid1_edx.bits.cmov != 0)
|
||||
result |= CPU_CMOV;
|
||||
vm_features.set_feature(CPU_CMOV);
|
||||
if (std_cpuid1_edx.bits.clflush != 0)
|
||||
result |= CPU_FLUSH;
|
||||
vm_features.set_feature(CPU_FLUSH);
|
||||
// clflush should always be available on x86_64
|
||||
// if not we are in real trouble because we rely on it
|
||||
// to flush the code cache.
|
||||
assert ((result & CPU_FLUSH) != 0, "clflush should be available");
|
||||
assert (vm_features.supports_feature(CPU_FLUSH), "clflush should be available");
|
||||
if (std_cpuid1_edx.bits.fxsr != 0 || (is_amd_family() &&
|
||||
ext_cpuid1_edx.bits.fxsr != 0))
|
||||
result |= CPU_FXSR;
|
||||
vm_features.set_feature(CPU_FXSR);
|
||||
// HT flag is set for multi-core processors also.
|
||||
if (threads_per_core() > 1)
|
||||
result |= CPU_HT;
|
||||
vm_features.set_feature(CPU_HT);
|
||||
if (std_cpuid1_edx.bits.mmx != 0 || (is_amd_family() &&
|
||||
ext_cpuid1_edx.bits.mmx != 0))
|
||||
result |= CPU_MMX;
|
||||
vm_features.set_feature(CPU_MMX);
|
||||
if (std_cpuid1_edx.bits.sse != 0)
|
||||
result |= CPU_SSE;
|
||||
vm_features.set_feature(CPU_SSE);
|
||||
if (std_cpuid1_edx.bits.sse2 != 0)
|
||||
result |= CPU_SSE2;
|
||||
vm_features.set_feature(CPU_SSE2);
|
||||
if (std_cpuid1_ecx.bits.sse3 != 0)
|
||||
result |= CPU_SSE3;
|
||||
vm_features.set_feature(CPU_SSE3);
|
||||
if (std_cpuid1_ecx.bits.ssse3 != 0)
|
||||
result |= CPU_SSSE3;
|
||||
vm_features.set_feature(CPU_SSSE3);
|
||||
if (std_cpuid1_ecx.bits.sse4_1 != 0)
|
||||
result |= CPU_SSE4_1;
|
||||
vm_features.set_feature(CPU_SSE4_1);
|
||||
if (std_cpuid1_ecx.bits.sse4_2 != 0)
|
||||
result |= CPU_SSE4_2;
|
||||
vm_features.set_feature(CPU_SSE4_2);
|
||||
if (std_cpuid1_ecx.bits.popcnt != 0)
|
||||
result |= CPU_POPCNT;
|
||||
vm_features.set_feature(CPU_POPCNT);
|
||||
if (sefsl1_cpuid7_edx.bits.apx_f != 0 &&
|
||||
xem_xcr0_eax.bits.apx_f != 0) {
|
||||
result |= CPU_APX_F;
|
||||
vm_features.set_feature(CPU_APX_F);
|
||||
}
|
||||
if (std_cpuid1_ecx.bits.avx != 0 &&
|
||||
std_cpuid1_ecx.bits.osxsave != 0 &&
|
||||
xem_xcr0_eax.bits.sse != 0 &&
|
||||
xem_xcr0_eax.bits.ymm != 0) {
|
||||
result |= CPU_AVX;
|
||||
result |= CPU_VZEROUPPER;
|
||||
vm_features.set_feature(CPU_AVX);
|
||||
vm_features.set_feature(CPU_VZEROUPPER);
|
||||
if (sefsl1_cpuid7_eax.bits.sha512 != 0)
|
||||
result |= CPU_SHA512;
|
||||
vm_features.set_feature(CPU_SHA512);
|
||||
if (std_cpuid1_ecx.bits.f16c != 0)
|
||||
result |= CPU_F16C;
|
||||
vm_features.set_feature(CPU_F16C);
|
||||
if (sef_cpuid7_ebx.bits.avx2 != 0) {
|
||||
result |= CPU_AVX2;
|
||||
vm_features.set_feature(CPU_AVX2);
|
||||
if (sefsl1_cpuid7_eax.bits.avx_ifma != 0)
|
||||
result |= CPU_AVX_IFMA;
|
||||
vm_features.set_feature(CPU_AVX_IFMA);
|
||||
}
|
||||
if (sef_cpuid7_ecx.bits.gfni != 0)
|
||||
result |= CPU_GFNI;
|
||||
vm_features.set_feature(CPU_GFNI);
|
||||
if (sef_cpuid7_ebx.bits.avx512f != 0 &&
|
||||
xem_xcr0_eax.bits.opmask != 0 &&
|
||||
xem_xcr0_eax.bits.zmm512 != 0 &&
|
||||
xem_xcr0_eax.bits.zmm32 != 0) {
|
||||
result |= CPU_AVX512F;
|
||||
vm_features.set_feature(CPU_AVX512F);
|
||||
if (sef_cpuid7_ebx.bits.avx512cd != 0)
|
||||
result |= CPU_AVX512CD;
|
||||
vm_features.set_feature(CPU_AVX512CD);
|
||||
if (sef_cpuid7_ebx.bits.avx512dq != 0)
|
||||
result |= CPU_AVX512DQ;
|
||||
vm_features.set_feature(CPU_AVX512DQ);
|
||||
if (sef_cpuid7_ebx.bits.avx512ifma != 0)
|
||||
result |= CPU_AVX512_IFMA;
|
||||
vm_features.set_feature(CPU_AVX512_IFMA);
|
||||
if (sef_cpuid7_ebx.bits.avx512pf != 0)
|
||||
result |= CPU_AVX512PF;
|
||||
vm_features.set_feature(CPU_AVX512PF);
|
||||
if (sef_cpuid7_ebx.bits.avx512er != 0)
|
||||
result |= CPU_AVX512ER;
|
||||
vm_features.set_feature(CPU_AVX512ER);
|
||||
if (sef_cpuid7_ebx.bits.avx512bw != 0)
|
||||
result |= CPU_AVX512BW;
|
||||
vm_features.set_feature(CPU_AVX512BW);
|
||||
if (sef_cpuid7_ebx.bits.avx512vl != 0)
|
||||
result |= CPU_AVX512VL;
|
||||
vm_features.set_feature(CPU_AVX512VL);
|
||||
if (sef_cpuid7_ecx.bits.avx512_vpopcntdq != 0)
|
||||
result |= CPU_AVX512_VPOPCNTDQ;
|
||||
vm_features.set_feature(CPU_AVX512_VPOPCNTDQ);
|
||||
if (sef_cpuid7_ecx.bits.avx512_vpclmulqdq != 0)
|
||||
result |= CPU_AVX512_VPCLMULQDQ;
|
||||
vm_features.set_feature(CPU_AVX512_VPCLMULQDQ);
|
||||
if (sef_cpuid7_ecx.bits.vaes != 0)
|
||||
result |= CPU_AVX512_VAES;
|
||||
vm_features.set_feature(CPU_AVX512_VAES);
|
||||
if (sef_cpuid7_ecx.bits.avx512_vnni != 0)
|
||||
result |= CPU_AVX512_VNNI;
|
||||
vm_features.set_feature(CPU_AVX512_VNNI);
|
||||
if (sef_cpuid7_ecx.bits.avx512_bitalg != 0)
|
||||
result |= CPU_AVX512_BITALG;
|
||||
vm_features.set_feature(CPU_AVX512_BITALG);
|
||||
if (sef_cpuid7_ecx.bits.avx512_vbmi != 0)
|
||||
result |= CPU_AVX512_VBMI;
|
||||
vm_features.set_feature(CPU_AVX512_VBMI);
|
||||
if (sef_cpuid7_ecx.bits.avx512_vbmi2 != 0)
|
||||
result |= CPU_AVX512_VBMI2;
|
||||
vm_features.set_feature(CPU_AVX512_VBMI2);
|
||||
}
|
||||
if (is_intel()) {
|
||||
if (sefsl1_cpuid7_edx.bits.avx10 != 0 &&
|
||||
std_cpuid24_ebx.bits.avx10_vlen_512 !=0 &&
|
||||
std_cpuid24_ebx.bits.avx10_converged_isa_version >= 1 &&
|
||||
xem_xcr0_eax.bits.opmask != 0 &&
|
||||
xem_xcr0_eax.bits.zmm512 != 0 &&
|
||||
xem_xcr0_eax.bits.zmm32 != 0) {
|
||||
vm_features.set_feature(CPU_AVX10_1);
|
||||
vm_features.set_feature(CPU_AVX512F);
|
||||
vm_features.set_feature(CPU_AVX512CD);
|
||||
vm_features.set_feature(CPU_AVX512DQ);
|
||||
vm_features.set_feature(CPU_AVX512PF);
|
||||
vm_features.set_feature(CPU_AVX512ER);
|
||||
vm_features.set_feature(CPU_AVX512BW);
|
||||
vm_features.set_feature(CPU_AVX512VL);
|
||||
vm_features.set_feature(CPU_AVX512_VPOPCNTDQ);
|
||||
vm_features.set_feature(CPU_AVX512_VPCLMULQDQ);
|
||||
vm_features.set_feature(CPU_AVX512_VAES);
|
||||
vm_features.set_feature(CPU_AVX512_VNNI);
|
||||
vm_features.set_feature(CPU_AVX512_BITALG);
|
||||
vm_features.set_feature(CPU_AVX512_VBMI);
|
||||
vm_features.set_feature(CPU_AVX512_VBMI2);
|
||||
if (std_cpuid24_ebx.bits.avx10_converged_isa_version >= 2) {
|
||||
vm_features.set_feature(CPU_AVX10_2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (std_cpuid1_ecx.bits.hv != 0)
|
||||
result |= CPU_HV;
|
||||
vm_features.set_feature(CPU_HV);
|
||||
if (sef_cpuid7_ebx.bits.bmi1 != 0)
|
||||
result |= CPU_BMI1;
|
||||
vm_features.set_feature(CPU_BMI1);
|
||||
if (std_cpuid1_edx.bits.tsc != 0)
|
||||
result |= CPU_TSC;
|
||||
vm_features.set_feature(CPU_TSC);
|
||||
if (ext_cpuid7_edx.bits.tsc_invariance != 0)
|
||||
result |= CPU_TSCINV_BIT;
|
||||
vm_features.set_feature(CPU_TSCINV_BIT);
|
||||
if (std_cpuid1_ecx.bits.aes != 0)
|
||||
result |= CPU_AES;
|
||||
vm_features.set_feature(CPU_AES);
|
||||
if (ext_cpuid1_ecx.bits.lzcnt != 0)
|
||||
result |= CPU_LZCNT;
|
||||
vm_features.set_feature(CPU_LZCNT);
|
||||
if (ext_cpuid1_ecx.bits.prefetchw != 0)
|
||||
result |= CPU_3DNOW_PREFETCH;
|
||||
vm_features.set_feature(CPU_3DNOW_PREFETCH);
|
||||
if (sef_cpuid7_ebx.bits.erms != 0)
|
||||
result |= CPU_ERMS;
|
||||
vm_features.set_feature(CPU_ERMS);
|
||||
if (sef_cpuid7_edx.bits.fast_short_rep_mov != 0)
|
||||
result |= CPU_FSRM;
|
||||
vm_features.set_feature(CPU_FSRM);
|
||||
if (std_cpuid1_ecx.bits.clmul != 0)
|
||||
result |= CPU_CLMUL;
|
||||
vm_features.set_feature(CPU_CLMUL);
|
||||
if (sef_cpuid7_ebx.bits.rtm != 0)
|
||||
result |= CPU_RTM;
|
||||
vm_features.set_feature(CPU_RTM);
|
||||
if (sef_cpuid7_ebx.bits.adx != 0)
|
||||
result |= CPU_ADX;
|
||||
vm_features.set_feature(CPU_ADX);
|
||||
if (sef_cpuid7_ebx.bits.bmi2 != 0)
|
||||
result |= CPU_BMI2;
|
||||
vm_features.set_feature(CPU_BMI2);
|
||||
if (sef_cpuid7_ebx.bits.sha != 0)
|
||||
result |= CPU_SHA;
|
||||
vm_features.set_feature(CPU_SHA);
|
||||
if (std_cpuid1_ecx.bits.fma != 0)
|
||||
result |= CPU_FMA;
|
||||
vm_features.set_feature(CPU_FMA);
|
||||
if (sef_cpuid7_ebx.bits.clflushopt != 0)
|
||||
result |= CPU_FLUSHOPT;
|
||||
vm_features.set_feature(CPU_FLUSHOPT);
|
||||
if (sef_cpuid7_ebx.bits.clwb != 0)
|
||||
result |= CPU_CLWB;
|
||||
vm_features.set_feature(CPU_CLWB);
|
||||
if (ext_cpuid1_edx.bits.rdtscp != 0)
|
||||
result |= CPU_RDTSCP;
|
||||
vm_features.set_feature(CPU_RDTSCP);
|
||||
if (sef_cpuid7_ecx.bits.rdpid != 0)
|
||||
result |= CPU_RDPID;
|
||||
vm_features.set_feature(CPU_RDPID);
|
||||
|
||||
// AMD|Hygon additional features.
|
||||
if (is_amd_family()) {
|
||||
// PREFETCHW was checked above, check TDNOW here.
|
||||
if ((ext_cpuid1_edx.bits.tdnow != 0))
|
||||
result |= CPU_3DNOW_PREFETCH;
|
||||
vm_features.set_feature(CPU_3DNOW_PREFETCH);
|
||||
if (ext_cpuid1_ecx.bits.sse4a != 0)
|
||||
result |= CPU_SSE4A;
|
||||
vm_features.set_feature(CPU_SSE4A);
|
||||
}
|
||||
|
||||
// Intel additional features.
|
||||
if (is_intel()) {
|
||||
if (sef_cpuid7_edx.bits.serialize != 0)
|
||||
result |= CPU_SERIALIZE;
|
||||
vm_features.set_feature(CPU_SERIALIZE);
|
||||
if (_cpuid_info.sef_cpuid7_edx.bits.avx512_fp16 != 0)
|
||||
result |= CPU_AVX512_FP16;
|
||||
vm_features.set_feature(CPU_AVX512_FP16);
|
||||
}
|
||||
|
||||
// ZX additional features.
|
||||
if (is_zx()) {
|
||||
// We do not know if these are supported by ZX, so we cannot trust
|
||||
// common CPUID bit for them.
|
||||
assert((result & CPU_CLWB) == 0, "Check if it is supported?");
|
||||
result &= ~CPU_CLWB;
|
||||
assert(vm_features.supports_feature(CPU_CLWB), "Check if it is supported?");
|
||||
vm_features.clear_feature(CPU_CLWB);
|
||||
}
|
||||
|
||||
// Protection key features.
|
||||
if (sef_cpuid7_ecx.bits.pku != 0) {
|
||||
result |= CPU_PKU;
|
||||
vm_features.set_feature(CPU_PKU);
|
||||
}
|
||||
if (sef_cpuid7_ecx.bits.ospke != 0) {
|
||||
result |= CPU_OSPKE;
|
||||
vm_features.set_feature(CPU_OSPKE);
|
||||
}
|
||||
|
||||
// Control flow enforcement (CET) features.
|
||||
if (sef_cpuid7_ecx.bits.cet_ss != 0) {
|
||||
result |= CPU_CET_SS;
|
||||
vm_features.set_feature(CPU_CET_SS);
|
||||
}
|
||||
if (sef_cpuid7_edx.bits.cet_ibt != 0) {
|
||||
result |= CPU_CET_IBT;
|
||||
vm_features.set_feature(CPU_CET_IBT);
|
||||
}
|
||||
|
||||
// Composite features.
|
||||
if (supports_tscinv_bit() &&
|
||||
((is_amd_family() && !is_amd_Barcelona()) ||
|
||||
is_intel_tsc_synched_at_init())) {
|
||||
result |= CPU_TSCINV;
|
||||
vm_features.set_feature(CPU_TSCINV);
|
||||
}
|
||||
|
||||
return result;
|
||||
return vm_features;
|
||||
}
|
||||
|
||||
bool VM_Version::os_supports_avx_vectors() {
|
||||
@ -3231,3 +3281,14 @@ bool VM_Version::is_intrinsic_supported(vmIntrinsicID id) {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void VM_Version::insert_features_names(VM_Version::VM_Features features, char* buf, size_t buflen) {
|
||||
for (int i = 0; i < MAX_CPU_FEATURES; i++) {
|
||||
if (features.supports_feature((VM_Version::Feature_Flag)i)) {
|
||||
int res = jio_snprintf(buf, buflen, ", %s", _features_names[i]);
|
||||
assert(res > 0, "not enough temporary space allocated");
|
||||
buf += res;
|
||||
buflen -= res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -295,12 +295,32 @@ class VM_Version : public Abstract_VM_Version {
|
||||
union SefCpuid7SubLeaf1Edx {
|
||||
uint32_t value;
|
||||
struct {
|
||||
uint32_t : 21,
|
||||
uint32_t : 19,
|
||||
avx10 : 1,
|
||||
: 1,
|
||||
apx_f : 1,
|
||||
: 10;
|
||||
} bits;
|
||||
};
|
||||
|
||||
union StdCpuid24MainLeafEax {
|
||||
uint32_t value;
|
||||
struct {
|
||||
uint32_t sub_leaves_cnt : 31;
|
||||
} bits;
|
||||
};
|
||||
|
||||
union StdCpuid24MainLeafEbx {
|
||||
uint32_t value;
|
||||
struct {
|
||||
uint32_t avx10_converged_isa_version : 8,
|
||||
: 8,
|
||||
: 2,
|
||||
avx10_vlen_512 : 1,
|
||||
: 13;
|
||||
} bits;
|
||||
};
|
||||
|
||||
union ExtCpuid1EEbx {
|
||||
uint32_t value;
|
||||
struct {
|
||||
@ -342,9 +362,9 @@ protected:
|
||||
/*
|
||||
* Update following files when declaring new flags:
|
||||
* test/lib-test/jdk/test/whitebox/CPUInfoTest.java
|
||||
* src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.amd64/src/jdk/vm/ci/amd64/AMD64.java
|
||||
* src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/amd64/AMD64.java
|
||||
*/
|
||||
enum Feature_Flag : uint64_t {
|
||||
enum Feature_Flag {
|
||||
#define CPU_FEATURE_FLAGS(decl) \
|
||||
decl(CX8, "cx8", 0) /* next bits are from cpuid 1 (EDX) */ \
|
||||
decl(CMOV, "cmov", 1) \
|
||||
@ -420,15 +440,85 @@ protected:
|
||||
decl(AVX_IFMA, "avx_ifma", 59) /* 256-bit VEX-coded variant of AVX512-IFMA*/ \
|
||||
decl(APX_F, "apx_f", 60) /* Intel Advanced Performance Extensions*/ \
|
||||
decl(SHA512, "sha512", 61) /* SHA512 instructions*/ \
|
||||
decl(AVX512_FP16, "avx512_fp16", 62) /* AVX512 FP16 ISA support*/
|
||||
decl(AVX512_FP16, "avx512_fp16", 62) /* AVX512 FP16 ISA support*/ \
|
||||
decl(AVX10_1, "avx10_1", 63) /* AVX10 512 bit vector ISA Version 1 support*/ \
|
||||
decl(AVX10_2, "avx10_2", 64) /* AVX10 512 bit vector ISA Version 2 support*/
|
||||
|
||||
#define DECLARE_CPU_FEATURE_FLAG(id, name, bit) CPU_##id = (1ULL << bit),
|
||||
#define DECLARE_CPU_FEATURE_FLAG(id, name, bit) CPU_##id = (bit),
|
||||
CPU_FEATURE_FLAGS(DECLARE_CPU_FEATURE_FLAG)
|
||||
#undef DECLARE_CPU_FEATURE_FLAG
|
||||
MAX_CPU_FEATURES
|
||||
};
|
||||
|
||||
class VM_Features {
|
||||
friend class VMStructs;
|
||||
friend class JVMCIVMStructs;
|
||||
|
||||
private:
|
||||
uint64_t _features_bitmap[(MAX_CPU_FEATURES / BitsPerLong) + 1];
|
||||
|
||||
STATIC_ASSERT(sizeof(_features_bitmap) * BitsPerByte >= MAX_CPU_FEATURES);
|
||||
|
||||
// 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(Feature_Flag 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(Feature_Flag feature) {
|
||||
return (1ULL << (feature & features_bitmap_element_mask()));
|
||||
}
|
||||
|
||||
static int _features_bitmap_size; // for JVMCI purposes
|
||||
public:
|
||||
VM_Features() {
|
||||
for (int i = 0; i < features_bitmap_element_count(); i++) {
|
||||
_features_bitmap[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void set_feature(Feature_Flag feature) {
|
||||
int idx = index(feature);
|
||||
_features_bitmap[idx] |= bit_mask(feature);
|
||||
}
|
||||
|
||||
void clear_feature(VM_Version::Feature_Flag feature) {
|
||||
int idx = index(feature);
|
||||
_features_bitmap[idx] &= ~bit_mask(feature);
|
||||
}
|
||||
|
||||
bool supports_feature(VM_Version::Feature_Flag feature) {
|
||||
int idx = index(feature);
|
||||
return (_features_bitmap[idx] & bit_mask(feature)) != 0;
|
||||
}
|
||||
};
|
||||
|
||||
// CPU feature flags vector, can be affected by VM settings.
|
||||
static VM_Features _features;
|
||||
|
||||
// Original CPU feature flags vector, not affected by VM settings.
|
||||
static VM_Features _cpu_features;
|
||||
|
||||
static const char* _features_names[];
|
||||
|
||||
static void clear_cpu_features() {
|
||||
_features = VM_Features();
|
||||
_cpu_features = VM_Features();
|
||||
}
|
||||
|
||||
enum Extended_Family {
|
||||
// AMD
|
||||
CPU_FAMILY_AMD_11H = 0x11,
|
||||
@ -492,6 +582,11 @@ protected:
|
||||
SefCpuid7SubLeaf1Eax sefsl1_cpuid7_eax;
|
||||
SefCpuid7SubLeaf1Edx sefsl1_cpuid7_edx;
|
||||
|
||||
// cpuid function 24 converged vector ISA main leaf
|
||||
// eax = 24, ecx = 0
|
||||
StdCpuid24MainLeafEax std_cpuid24_eax;
|
||||
StdCpuid24MainLeafEbx std_cpuid24_ebx;
|
||||
|
||||
// cpuid function 0xB (processor topology)
|
||||
// ecx = 0
|
||||
uint32_t tpl_cpuidB0_eax;
|
||||
@ -565,7 +660,7 @@ protected:
|
||||
// Space to save apx registers after signal handle
|
||||
jlong apx_save[2]; // Save r16 and r31
|
||||
|
||||
uint64_t feature_flags() const;
|
||||
VM_Features feature_flags() const;
|
||||
|
||||
// Asserts
|
||||
void assert_is_initialized() const {
|
||||
@ -611,6 +706,7 @@ public:
|
||||
// Offsets for cpuid asm stub
|
||||
static ByteSize std_cpuid0_offset() { return byte_offset_of(CpuidInfo, std_max_function); }
|
||||
static ByteSize std_cpuid1_offset() { return byte_offset_of(CpuidInfo, std_cpuid1_eax); }
|
||||
static ByteSize std_cpuid24_offset() { return byte_offset_of(CpuidInfo, std_cpuid24_eax); }
|
||||
static ByteSize dcp_cpuid4_offset() { return byte_offset_of(CpuidInfo, dcp_cpuid4_eax); }
|
||||
static ByteSize sef_cpuid7_offset() { return byte_offset_of(CpuidInfo, sef_cpuid7_eax); }
|
||||
static ByteSize sefsl1_cpuid7_offset() { return byte_offset_of(CpuidInfo, sefsl1_cpuid7_eax); }
|
||||
@ -644,11 +740,29 @@ public:
|
||||
|
||||
static void clear_apx_test_state();
|
||||
|
||||
static void clean_cpuFeatures() { _features = 0; }
|
||||
static void set_avx_cpuFeatures() { _features |= (CPU_SSE | CPU_SSE2 | CPU_AVX | CPU_VZEROUPPER ); }
|
||||
static void set_evex_cpuFeatures() { _features |= (CPU_AVX512F | CPU_SSE | CPU_SSE2 | CPU_VZEROUPPER ); }
|
||||
static void set_apx_cpuFeatures() { _features |= CPU_APX_F; }
|
||||
static void set_bmi_cpuFeatures() { _features |= (CPU_BMI1 | CPU_BMI2 | CPU_LZCNT | CPU_POPCNT); }
|
||||
static void clean_cpuFeatures() {
|
||||
VM_Version::clear_cpu_features();
|
||||
}
|
||||
static void set_avx_cpuFeatures() {
|
||||
_features.set_feature(CPU_SSE);
|
||||
_features.set_feature(CPU_SSE2);
|
||||
_features.set_feature(CPU_AVX);
|
||||
_features.set_feature(CPU_VZEROUPPER);
|
||||
}
|
||||
static void set_evex_cpuFeatures() {
|
||||
_features.set_feature(CPU_AVX10_1);
|
||||
_features.set_feature(CPU_AVX512F);
|
||||
_features.set_feature(CPU_SSE);
|
||||
_features.set_feature(CPU_SSE2);
|
||||
_features.set_feature(CPU_VZEROUPPER);
|
||||
}
|
||||
static void set_apx_cpuFeatures() { _features.set_feature(CPU_APX_F); }
|
||||
static void set_bmi_cpuFeatures() {
|
||||
_features.set_feature(CPU_BMI1);
|
||||
_features.set_feature(CPU_BMI2);
|
||||
_features.set_feature(CPU_LZCNT);
|
||||
_features.set_feature(CPU_POPCNT);
|
||||
}
|
||||
|
||||
// Initialization
|
||||
static void initialize();
|
||||
@ -703,40 +817,39 @@ public:
|
||||
//
|
||||
// Feature identification which can be affected by VM settings
|
||||
//
|
||||
static bool supports_cpuid() { return _features != 0; }
|
||||
static bool supports_cmov() { return (_features & CPU_CMOV) != 0; }
|
||||
static bool supports_fxsr() { return (_features & CPU_FXSR) != 0; }
|
||||
static bool supports_ht() { return (_features & CPU_HT) != 0; }
|
||||
static bool supports_mmx() { return (_features & CPU_MMX) != 0; }
|
||||
static bool supports_sse() { return (_features & CPU_SSE) != 0; }
|
||||
static bool supports_sse2() { return (_features & CPU_SSE2) != 0; }
|
||||
static bool supports_sse3() { return (_features & CPU_SSE3) != 0; }
|
||||
static bool supports_ssse3() { return (_features & CPU_SSSE3)!= 0; }
|
||||
static bool supports_sse4_1() { return (_features & CPU_SSE4_1) != 0; }
|
||||
static bool supports_sse4_2() { return (_features & CPU_SSE4_2) != 0; }
|
||||
static bool supports_popcnt() { return (_features & CPU_POPCNT) != 0; }
|
||||
static bool supports_avx() { return (_features & CPU_AVX) != 0; }
|
||||
static bool supports_avx2() { return (_features & CPU_AVX2) != 0; }
|
||||
static bool supports_tsc() { return (_features & CPU_TSC) != 0; }
|
||||
static bool supports_rdtscp() { return (_features & CPU_RDTSCP) != 0; }
|
||||
static bool supports_rdpid() { return (_features & CPU_RDPID) != 0; }
|
||||
static bool supports_aes() { return (_features & CPU_AES) != 0; }
|
||||
static bool supports_erms() { return (_features & CPU_ERMS) != 0; }
|
||||
static bool supports_fsrm() { return (_features & CPU_FSRM) != 0; }
|
||||
static bool supports_clmul() { return (_features & CPU_CLMUL) != 0; }
|
||||
static bool supports_rtm() { return (_features & CPU_RTM) != 0; }
|
||||
static bool supports_bmi1() { return (_features & CPU_BMI1) != 0; }
|
||||
static bool supports_bmi2() { return (_features & CPU_BMI2) != 0; }
|
||||
static bool supports_adx() { return (_features & CPU_ADX) != 0; }
|
||||
static bool supports_evex() { return (_features & CPU_AVX512F) != 0; }
|
||||
static bool supports_avx512dq() { return (_features & CPU_AVX512DQ) != 0; }
|
||||
static bool supports_avx512ifma() { return (_features & CPU_AVX512_IFMA) != 0; }
|
||||
static bool supports_avxifma() { return (_features & CPU_AVX_IFMA) != 0; }
|
||||
static bool supports_avx512pf() { return (_features & CPU_AVX512PF) != 0; }
|
||||
static bool supports_avx512er() { return (_features & CPU_AVX512ER) != 0; }
|
||||
static bool supports_avx512cd() { return (_features & CPU_AVX512CD) != 0; }
|
||||
static bool supports_avx512bw() { return (_features & CPU_AVX512BW) != 0; }
|
||||
static bool supports_avx512vl() { return (_features & CPU_AVX512VL) != 0; }
|
||||
static bool supports_cmov() { return _features.supports_feature(CPU_CMOV); }
|
||||
static bool supports_fxsr() { return _features.supports_feature(CPU_FXSR); }
|
||||
static bool supports_ht() { return _features.supports_feature(CPU_HT); }
|
||||
static bool supports_mmx() { return _features.supports_feature(CPU_MMX); }
|
||||
static bool supports_sse() { return _features.supports_feature(CPU_SSE); }
|
||||
static bool supports_sse2() { return _features.supports_feature(CPU_SSE2); }
|
||||
static bool supports_sse3() { return _features.supports_feature(CPU_SSE3); }
|
||||
static bool supports_ssse3() { return _features.supports_feature(CPU_SSSE3); }
|
||||
static bool supports_sse4_1() { return _features.supports_feature(CPU_SSE4_1); }
|
||||
static bool supports_sse4_2() { return _features.supports_feature(CPU_SSE4_2); }
|
||||
static bool supports_popcnt() { return _features.supports_feature(CPU_POPCNT); }
|
||||
static bool supports_avx() { return _features.supports_feature(CPU_AVX); }
|
||||
static bool supports_avx2() { return _features.supports_feature(CPU_AVX2); }
|
||||
static bool supports_tsc() { return _features.supports_feature(CPU_TSC); }
|
||||
static bool supports_rdtscp() { return _features.supports_feature(CPU_RDTSCP); }
|
||||
static bool supports_rdpid() { return _features.supports_feature(CPU_RDPID); }
|
||||
static bool supports_aes() { return _features.supports_feature(CPU_AES); }
|
||||
static bool supports_erms() { return _features.supports_feature(CPU_ERMS); }
|
||||
static bool supports_fsrm() { return _features.supports_feature(CPU_FSRM); }
|
||||
static bool supports_clmul() { return _features.supports_feature(CPU_CLMUL); }
|
||||
static bool supports_rtm() { return _features.supports_feature(CPU_RTM); }
|
||||
static bool supports_bmi1() { return _features.supports_feature(CPU_BMI1); }
|
||||
static bool supports_bmi2() { return _features.supports_feature(CPU_BMI2); }
|
||||
static bool supports_adx() { return _features.supports_feature(CPU_ADX); }
|
||||
static bool supports_evex() { return _features.supports_feature(CPU_AVX512F); }
|
||||
static bool supports_avx512dq() { return _features.supports_feature(CPU_AVX512DQ); }
|
||||
static bool supports_avx512ifma() { return _features.supports_feature(CPU_AVX512_IFMA); }
|
||||
static bool supports_avxifma() { return _features.supports_feature(CPU_AVX_IFMA); }
|
||||
static bool supports_avx512pf() { return _features.supports_feature(CPU_AVX512PF); }
|
||||
static bool supports_avx512er() { return _features.supports_feature(CPU_AVX512ER); }
|
||||
static bool supports_avx512cd() { return _features.supports_feature(CPU_AVX512CD); }
|
||||
static bool supports_avx512bw() { return _features.supports_feature(CPU_AVX512BW); }
|
||||
static bool supports_avx512vl() { return _features.supports_feature(CPU_AVX512VL); }
|
||||
static bool supports_avx512vlbw() { return (supports_evex() && supports_avx512bw() && supports_avx512vl()); }
|
||||
static bool supports_avx512bwdq() { return (supports_evex() && supports_avx512bw() && supports_avx512dq()); }
|
||||
static bool supports_avx512vldq() { return (supports_evex() && supports_avx512dq() && supports_avx512vl()); }
|
||||
@ -745,33 +858,39 @@ public:
|
||||
static bool supports_avx512novl() { return (supports_evex() && !supports_avx512vl()); }
|
||||
static bool supports_avx512nobw() { return (supports_evex() && !supports_avx512bw()); }
|
||||
static bool supports_avx256only() { return (supports_avx2() && !supports_evex()); }
|
||||
static bool supports_apx_f() { return (_features & CPU_APX_F) != 0; }
|
||||
static bool supports_apx_f() { return _features.supports_feature(CPU_APX_F); }
|
||||
static bool supports_avxonly() { return ((supports_avx2() || supports_avx()) && !supports_evex()); }
|
||||
static bool supports_sha() { return (_features & CPU_SHA) != 0; }
|
||||
static bool supports_fma() { return (_features & CPU_FMA) != 0 && supports_avx(); }
|
||||
static bool supports_vzeroupper() { return (_features & CPU_VZEROUPPER) != 0; }
|
||||
static bool supports_avx512_vpopcntdq() { return (_features & CPU_AVX512_VPOPCNTDQ) != 0; }
|
||||
static bool supports_avx512_vpclmulqdq() { return (_features & CPU_AVX512_VPCLMULQDQ) != 0; }
|
||||
static bool supports_avx512_vaes() { return (_features & CPU_AVX512_VAES) != 0; }
|
||||
static bool supports_gfni() { return (_features & CPU_GFNI) != 0; }
|
||||
static bool supports_avx512_vnni() { return (_features & CPU_AVX512_VNNI) != 0; }
|
||||
static bool supports_avx512_bitalg() { return (_features & CPU_AVX512_BITALG) != 0; }
|
||||
static bool supports_avx512_vbmi() { return (_features & CPU_AVX512_VBMI) != 0; }
|
||||
static bool supports_avx512_vbmi2() { return (_features & CPU_AVX512_VBMI2) != 0; }
|
||||
static bool supports_avx512_fp16() { return (_features & CPU_AVX512_FP16) != 0; }
|
||||
static bool supports_hv() { return (_features & CPU_HV) != 0; }
|
||||
static bool supports_serialize() { return (_features & CPU_SERIALIZE) != 0; }
|
||||
static bool supports_f16c() { return (_features & CPU_F16C) != 0; }
|
||||
static bool supports_pku() { return (_features & CPU_PKU) != 0; }
|
||||
static bool supports_ospke() { return (_features & CPU_OSPKE) != 0; }
|
||||
static bool supports_cet_ss() { return (_features & CPU_CET_SS) != 0; }
|
||||
static bool supports_cet_ibt() { return (_features & CPU_CET_IBT) != 0; }
|
||||
static bool supports_sha512() { return (_features & CPU_SHA512) != 0; }
|
||||
static bool supports_sha() { return _features.supports_feature(CPU_SHA); }
|
||||
static bool supports_fma() { return _features.supports_feature(CPU_FMA) && supports_avx(); }
|
||||
static bool supports_vzeroupper() { return _features.supports_feature(CPU_VZEROUPPER); }
|
||||
static bool supports_avx512_vpopcntdq() { return _features.supports_feature(CPU_AVX512_VPOPCNTDQ); }
|
||||
static bool supports_avx512_vpclmulqdq() { return _features.supports_feature(CPU_AVX512_VPCLMULQDQ); }
|
||||
static bool supports_avx512_vaes() { return _features.supports_feature(CPU_AVX512_VAES); }
|
||||
static bool supports_gfni() { return _features.supports_feature(CPU_GFNI); }
|
||||
static bool supports_avx512_vnni() { return _features.supports_feature(CPU_AVX512_VNNI); }
|
||||
static bool supports_avx512_bitalg() { return _features.supports_feature(CPU_AVX512_BITALG); }
|
||||
static bool supports_avx512_vbmi() { return _features.supports_feature(CPU_AVX512_VBMI); }
|
||||
static bool supports_avx512_vbmi2() { return _features.supports_feature(CPU_AVX512_VBMI2); }
|
||||
static bool supports_avx512_fp16() { return _features.supports_feature(CPU_AVX512_FP16); }
|
||||
static bool supports_hv() { return _features.supports_feature(CPU_HV); }
|
||||
static bool supports_serialize() { return _features.supports_feature(CPU_SERIALIZE); }
|
||||
static bool supports_f16c() { return _features.supports_feature(CPU_F16C); }
|
||||
static bool supports_pku() { return _features.supports_feature(CPU_PKU); }
|
||||
static bool supports_ospke() { return _features.supports_feature(CPU_OSPKE); }
|
||||
static bool supports_cet_ss() { return _features.supports_feature(CPU_CET_SS); }
|
||||
static bool supports_cet_ibt() { return _features.supports_feature(CPU_CET_IBT); }
|
||||
static bool supports_sha512() { return _features.supports_feature(CPU_SHA512); }
|
||||
|
||||
// Intel® AVX10 introduces a versioned approach for enumeration that is monotonically increasing, inclusive,
|
||||
// and supporting all vector lengths. Feature set supported by an AVX10 vector ISA version is also supported
|
||||
// by all the versions above it.
|
||||
static bool supports_avx10_1() { return _features.supports_feature(CPU_AVX10_1);}
|
||||
static bool supports_avx10_2() { return _features.supports_feature(CPU_AVX10_2);}
|
||||
|
||||
//
|
||||
// Feature identification not affected by VM flags
|
||||
//
|
||||
static bool cpu_supports_evex() { return (_cpu_features & CPU_AVX512F) != 0; }
|
||||
static bool cpu_supports_evex() { return _cpu_features.supports_feature(CPU_AVX512F); }
|
||||
|
||||
static bool supports_avx512_simd_sort() {
|
||||
if (supports_avx512dq()) {
|
||||
@ -802,6 +921,8 @@ public:
|
||||
|
||||
static bool is_intel_tsc_synched_at_init();
|
||||
|
||||
static void insert_features_names(VM_Version::VM_Features features, char* buf, size_t buflen);
|
||||
|
||||
// This checks if the JVM is potentially affected by an erratum on Intel CPUs (SKX102)
|
||||
// that causes unpredictable behaviour when jcc crosses 64 byte boundaries. Its microcode
|
||||
// mitigation causes regressions when jumps or fused conditional branches cross or end at
|
||||
@ -809,19 +930,19 @@ public:
|
||||
static bool has_intel_jcc_erratum() { return _has_intel_jcc_erratum; }
|
||||
|
||||
// AMD features
|
||||
static bool supports_3dnow_prefetch() { return (_features & CPU_3DNOW_PREFETCH) != 0; }
|
||||
static bool supports_lzcnt() { return (_features & CPU_LZCNT) != 0; }
|
||||
static bool supports_sse4a() { return (_features & CPU_SSE4A) != 0; }
|
||||
static bool supports_3dnow_prefetch() { return _features.supports_feature(CPU_3DNOW_PREFETCH); }
|
||||
static bool supports_lzcnt() { return _features.supports_feature(CPU_LZCNT); }
|
||||
static bool supports_sse4a() { return _features.supports_feature(CPU_SSE4A); }
|
||||
|
||||
static bool is_amd_Barcelona() { return is_amd() &&
|
||||
extended_cpu_family() == CPU_FAMILY_AMD_11H; }
|
||||
|
||||
// Intel and AMD newer cores support fast timestamps well
|
||||
static bool supports_tscinv_bit() {
|
||||
return (_features & CPU_TSCINV_BIT) != 0;
|
||||
return _features.supports_feature(CPU_TSCINV_BIT);
|
||||
}
|
||||
static bool supports_tscinv() {
|
||||
return (_features & CPU_TSCINV) != 0;
|
||||
return _features.supports_feature(CPU_TSCINV);
|
||||
}
|
||||
|
||||
// Intel Core and newer cpus have fast IDIV instruction (excluding Atom).
|
||||
@ -882,8 +1003,8 @@ public:
|
||||
static bool supports_clflush(); // Can't inline due to header file conflict
|
||||
|
||||
// Note: CPU_FLUSHOPT and CPU_CLWB bits should always be zero for 32-bit
|
||||
static bool supports_clflushopt() { return ((_features & CPU_FLUSHOPT) != 0); }
|
||||
static bool supports_clwb() { return ((_features & CPU_CLWB) != 0); }
|
||||
static bool supports_clflushopt() { return (_features.supports_feature(CPU_FLUSHOPT)); }
|
||||
static bool supports_clwb() { return (_features.supports_feature(CPU_CLWB)); }
|
||||
|
||||
// Old CPUs perform lea on AGU which causes additional latency transferring the
|
||||
// value from/to ALU for other operations
|
||||
|
@ -470,6 +470,7 @@ jobjectArray readConfiguration0(JNIEnv *env, JVMCI_TRAPS) {
|
||||
strcmp(vmField.typeString, "intptr_t") == 0 ||
|
||||
strcmp(vmField.typeString, "uintptr_t") == 0 ||
|
||||
strcmp(vmField.typeString, "OopHandle") == 0 ||
|
||||
strcmp(vmField.typeString, "VM_Version::VM_Features") == 0 ||
|
||||
strcmp(vmField.typeString, "size_t") == 0 ||
|
||||
// All foo* types are addresses.
|
||||
vmField.typeString[strlen(vmField.typeString) - 1] == '*') {
|
||||
|
@ -150,7 +150,7 @@
|
||||
\
|
||||
static_field(CompilerToVM::Data, data_section_item_alignment, int) \
|
||||
\
|
||||
JVMTI_ONLY(static_field(CompilerToVM::Data, _should_notify_object_alloc, int*)) \
|
||||
JVMTI_ONLY(static_field(CompilerToVM::Data, _should_notify_object_alloc, int*)) \
|
||||
\
|
||||
static_field(Abstract_VM_Version, _features, uint64_t) \
|
||||
\
|
||||
@ -997,7 +997,11 @@
|
||||
|
||||
#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field) \
|
||||
volatile_nonstatic_field(JavaFrameAnchor, _last_Java_fp, intptr_t*) \
|
||||
static_field(VM_Version, _has_intel_jcc_erratum, bool)
|
||||
static_field(VM_Version, _features, VM_Version::VM_Features) \
|
||||
\
|
||||
nonstatic_field(VM_Version::VM_Features, _features_bitmap[0], uint64_t) \
|
||||
static_field(VM_Version::VM_Features, _features_bitmap_size, int) \
|
||||
static_field(VM_Version, _has_intel_jcc_erratum, bool)
|
||||
|
||||
#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant) \
|
||||
LP64_ONLY(declare_constant(frame::arg_reg_save_area_bytes)) \
|
||||
@ -1005,7 +1009,8 @@
|
||||
declare_constant(frame::interpreter_frame_last_sp_offset)
|
||||
|
||||
#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)
|
||||
#define VM_LONG_CPU_FEATURE_CONSTANTS \
|
||||
CPU_FEATURE_FLAGS(DECLARE_LONG_CPU_FEATURE_CONSTANT)
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -325,22 +325,6 @@ unsigned int Abstract_VM_Version::jvm_version() {
|
||||
(Abstract_VM_Version::vm_build_number() & 0xFF);
|
||||
}
|
||||
|
||||
void Abstract_VM_Version::insert_features_names(char* buf, size_t buflen, const char* features_names[]) {
|
||||
uint64_t features = _features;
|
||||
uint features_names_index = 0;
|
||||
|
||||
while (features != 0) {
|
||||
if (features & 1) {
|
||||
int res = jio_snprintf(buf, buflen, ", %s", features_names[features_names_index]);
|
||||
assert(res > 0, "not enough temporary space allocated");
|
||||
buf += res;
|
||||
buflen -= res;
|
||||
}
|
||||
features >>= 1;
|
||||
++features_names_index;
|
||||
}
|
||||
}
|
||||
|
||||
const char* Abstract_VM_Version::extract_features_string(const char* cpu_info_string,
|
||||
size_t cpu_info_string_len,
|
||||
size_t features_offset) {
|
||||
|
@ -56,6 +56,7 @@ class Abstract_VM_Version: AllStatic {
|
||||
|
||||
// CPU feature flags, can be affected by VM settings.
|
||||
static uint64_t _features;
|
||||
|
||||
static const char* _features_string;
|
||||
|
||||
static const char* _cpu_info_string;
|
||||
@ -128,10 +129,9 @@ class Abstract_VM_Version: AllStatic {
|
||||
static const char* jdk_debug_level();
|
||||
static const char* printable_jdk_debug_level();
|
||||
|
||||
static uint64_t features() { return _features; }
|
||||
static const char* features_string() { return _features_string; }
|
||||
|
||||
static const char* cpu_info_string() { return _cpu_info_string; }
|
||||
static void insert_features_names(char* buf, size_t buflen, const char* features_names[]);
|
||||
static const char* extract_features_string(const char* cpu_info_string,
|
||||
size_t cpu_info_string_len,
|
||||
size_t features_offset);
|
||||
|
@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@ -1164,6 +1165,7 @@
|
||||
/********************/ \
|
||||
\
|
||||
declare_toplevel_type(Abstract_VM_Version) \
|
||||
declare_toplevel_type(VM_Version) \
|
||||
\
|
||||
/*************/ \
|
||||
/* Arguments */ \
|
||||
@ -1716,7 +1718,6 @@
|
||||
/**********************/ \
|
||||
NOT_ZERO(PPC64_ONLY(declare_constant(frame::entry_frame_locals_size))) \
|
||||
\
|
||||
NOT_ZERO(X86_ONLY(declare_constant(frame::entry_frame_call_wrapper_offset))) \
|
||||
declare_constant(frame::pc_return_offset) \
|
||||
\
|
||||
/*************/ \
|
||||
@ -2146,3 +2147,4 @@ void vmStructs_init() {
|
||||
VMStructs::init();
|
||||
}
|
||||
#endif // ASSERT
|
||||
|
||||
|
@ -258,6 +258,8 @@ public class AMD64 extends Architecture {
|
||||
APX_F,
|
||||
SHA512,
|
||||
AVX512_FP16,
|
||||
AVX10_1,
|
||||
AVX10_2
|
||||
}
|
||||
|
||||
private final EnumSet<CPUFeature> features;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2025, 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
|
||||
@ -30,6 +30,7 @@ import java.util.Map.Entry;
|
||||
|
||||
import jdk.vm.ci.common.JVMCIError;
|
||||
import jdk.vm.ci.runtime.JVMCIBackend;
|
||||
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
|
||||
|
||||
public interface HotSpotJVMCIBackendFactory {
|
||||
|
||||
@ -80,4 +81,58 @@ public interface HotSpotJVMCIBackendFactory {
|
||||
}
|
||||
return outFeatures;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts CPU features bit map into 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 featuresBitMapAddress pointer to {@code VM_Features::_features_bitmap} field of {@code VM_Version::_features}
|
||||
* @param featuresBitMapSize size of feature bit map in bytes
|
||||
* @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 featuresBitMapAddress,
|
||||
long featuresBitMapSize,
|
||||
Map<String, String> renaming) {
|
||||
EnumSet<CPUFeatureType> outFeatures = EnumSet.noneOf(enumType);
|
||||
List<String> missing = new ArrayList<>();
|
||||
|
||||
for (Entry<String, Long> e : constants.entrySet()) {
|
||||
String key = e.getKey();
|
||||
long bitIndex = e.getValue();
|
||||
if (key.startsWith("VM_Version::CPU_")) {
|
||||
String name = key.substring("VM_Version::CPU_".length());
|
||||
try {
|
||||
final long featuresElementShiftCount = 6; // log (# of bits per long)
|
||||
final long featuresElementMask = (1L << featuresElementShiftCount) - 1;
|
||||
|
||||
CPUFeatureType feature = Enum.valueOf(enumType, renaming.getOrDefault(name, name));
|
||||
|
||||
long featureIndex = bitIndex >>> featuresElementShiftCount;
|
||||
long featureBitMask = 1L << (bitIndex & featuresElementMask);
|
||||
assert featureIndex < featuresBitMapSize;
|
||||
|
||||
long featuresElement = UNSAFE.getLong(featuresBitMapAddress + featureIndex * Long.BYTES);
|
||||
|
||||
if ((featuresElement & featureBitMask) != 0) {
|
||||
outFeatures.add(feature);
|
||||
}
|
||||
} catch (IllegalArgumentException iae) {
|
||||
missing.add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!missing.isEmpty()) {
|
||||
throw new JVMCIError("Missing CPU feature constants: %s", missing);
|
||||
}
|
||||
return outFeatures;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2025, 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
|
||||
@ -50,7 +50,12 @@ public class AMD64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFacto
|
||||
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);
|
||||
long featuresBitMapAddress = config.vmVersionFeatures + config.vmFeaturesFeaturesOffset;
|
||||
EnumSet<CPUFeature> features = HotSpotJVMCIBackendFactory.convertFeatures(CPUFeature.class,
|
||||
constants,
|
||||
featuresBitMapAddress,
|
||||
config.vmFeaturesFeaturesSize,
|
||||
renaming);
|
||||
features.add(AMD64.CPUFeature.SSE);
|
||||
features.add(AMD64.CPUFeature.SSE2);
|
||||
return features;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2025, 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
|
||||
@ -42,12 +42,14 @@ class AMD64HotSpotVMConfig extends HotSpotVMConfigAccess {
|
||||
final boolean useCountTrailingZerosInstruction = getFlag("UseCountTrailingZerosInstruction", Boolean.class);
|
||||
final boolean useCompressedOops = getFlag("UseCompressedOops", Boolean.class);
|
||||
|
||||
final long vmVersionFeatures = getFieldAddress("VM_Version::_features", "VM_Version::VM_Features");
|
||||
final long vmFeaturesFeaturesOffset = getFieldOffset("VM_Version::VM_Features::_features_bitmap[0]", Long.class, "uint64_t");
|
||||
final long vmFeaturesFeaturesSize = getFieldValue("VM_Version::VM_Features::_features_bitmap_size", Long.class, "int");
|
||||
|
||||
// CPU capabilities
|
||||
final int useSSE = getFlag("UseSSE", Integer.class);
|
||||
final int useAVX = getFlag("UseAVX", Integer.class);
|
||||
|
||||
final long vmVersionFeatures = getFieldValue("Abstract_VM_Version::_features", Long.class, "uint64_t");
|
||||
|
||||
// CPU feature flags
|
||||
final long amd64CX8 = getConstant("VM_Version::CPU_CX8", Long.class);
|
||||
final long amd64CMOV = getConstant("VM_Version::CPU_CMOV", Long.class);
|
||||
@ -88,4 +90,6 @@ class AMD64HotSpotVMConfig extends HotSpotVMConfigAccess {
|
||||
final long amd64OSPKE = getConstant("VM_Version::CPU_OSPKE", Long.class);
|
||||
final long amd64CET_IBT = getConstant("VM_Version::CPU_CET_IBT", Long.class);
|
||||
final long amd64CET_SS = getConstant("VM_Version::CPU_CET_SS", Long.class);
|
||||
final long amd64AVX10_1 = getConstant("VM_Version::CPU_AVX10_1", Long.class);
|
||||
final long amd64AVX10_2 = getConstant("VM_Version::CPU_AVX10_2", Long.class);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2017, 2025, 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
|
||||
@ -92,7 +92,7 @@ public class ClhsdbLongConstant {
|
||||
|
||||
// Expected output snippet is of the form (on x64-64):
|
||||
// ...
|
||||
// longConstant VM_Version::CPU_SHA 17179869184
|
||||
// longConstant VM_Version::CPU_SHA 34
|
||||
// longConstant markWord::age_shift 3
|
||||
// longConstant markWord::hash_mask_in_place 4398046509056
|
||||
// ...
|
||||
@ -106,7 +106,7 @@ public class ClhsdbLongConstant {
|
||||
// Expected value obtained from the CPU_SHA definition in vm_version_x86.hpp
|
||||
checkLongValue("VM_Version::CPU_SHA ",
|
||||
longConstantOutput,
|
||||
17179869184L);
|
||||
34L);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2025, 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
|
||||
@ -66,7 +66,7 @@ public class CPUInfoTest {
|
||||
"hv", "fsrm", "avx512_bitalg", "gfni",
|
||||
"f16c", "pku", "ospke", "cet_ibt",
|
||||
"cet_ss", "avx512_ifma", "serialize", "avx_ifma",
|
||||
"apx_f"
|
||||
"apx_f", "avx10_1", "avx10_2"
|
||||
);
|
||||
// @formatter:on
|
||||
// Checkstyle: resume
|
||||
|
Loading…
x
Reference in New Issue
Block a user