8239090: Improve CPU feature support in VM_Version
Reviewed-by: iveresov, simonis
This commit is contained in:
parent
8f7c9a7b18
commit
9e453d9792
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2020, 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
|
||||
@ -37,7 +37,9 @@
|
||||
#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_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::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) \
|
||||
@ -68,22 +70,21 @@
|
||||
declare_constant(VM_Version::CPU_AVX512DQ) \
|
||||
declare_constant(VM_Version::CPU_AVX512PF) \
|
||||
declare_constant(VM_Version::CPU_AVX512ER) \
|
||||
declare_constant(VM_Version::CPU_AVX512CD)
|
||||
|
||||
#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \
|
||||
declare_preprocessor_constant("VM_Version::CPU_AVX512BW", CPU_AVX512BW) \
|
||||
declare_preprocessor_constant("VM_Version::CPU_AVX512VL", CPU_AVX512VL) \
|
||||
declare_preprocessor_constant("VM_Version::CPU_SHA", CPU_SHA) \
|
||||
declare_preprocessor_constant("VM_Version::CPU_FMA", CPU_FMA) \
|
||||
declare_preprocessor_constant("VM_Version::CPU_VZEROUPPER", CPU_VZEROUPPER) \
|
||||
declare_preprocessor_constant("VM_Version::CPU_AVX512_VPOPCNTDQ", CPU_AVX512_VPOPCNTDQ) \
|
||||
declare_preprocessor_constant("VM_Version::CPU_AVX512_VPCLMULQDQ", CPU_AVX512_VPCLMULQDQ) \
|
||||
declare_preprocessor_constant("VM_Version::CPU_AVX512_VAES", CPU_AVX512_VAES) \
|
||||
declare_preprocessor_constant("VM_Version::CPU_AVX512_VNNI", CPU_AVX512_VNNI) \
|
||||
declare_preprocessor_constant("VM_Version::CPU_FLUSH", CPU_FLUSH) \
|
||||
declare_preprocessor_constant("VM_Version::CPU_FLUSHOPT", CPU_FLUSHOPT) \
|
||||
declare_preprocessor_constant("VM_Version::CPU_CLWB", CPU_CLWB) \
|
||||
declare_preprocessor_constant("VM_Version::CPU_AVX512_VBMI2", CPU_AVX512_VBMI2) \
|
||||
declare_preprocessor_constant("VM_Version::CPU_AVX512_VBMI", CPU_AVX512_VBMI)
|
||||
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)
|
||||
|
||||
#endif // CPU_X86_VMSTRUCTS_X86_HPP
|
||||
|
@ -44,6 +44,7 @@ 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 };
|
||||
|
||||
// Address of instruction which causes SEGV
|
||||
address VM_Version::_cpuinfo_segv_addr = 0;
|
||||
@ -772,65 +773,14 @@ void VM_Version::get_processor_features() {
|
||||
}
|
||||
|
||||
char buf[512];
|
||||
int res = jio_snprintf(buf, sizeof(buf),
|
||||
"(%u cores per cpu, %u threads per core) family %d model %d stepping %d microcode 0x%x"
|
||||
"%s%s%s%s%s%s%s%s%s%s" "%s%s%s%s%s%s%s%s%s%s" "%s%s%s%s%s%s%s%s%s%s" "%s%s%s%s%s%s%s%s%s%s" "%s%s%s%s%s%s",
|
||||
|
||||
cores_per_cpu(), threads_per_core(),
|
||||
cpu_family(), _model, _stepping, os::cpu_microcode_revision(),
|
||||
|
||||
(supports_cmov() ? ", cmov" : ""),
|
||||
(supports_cmpxchg8() ? ", cx8" : ""),
|
||||
(supports_fxsr() ? ", fxsr" : ""),
|
||||
(supports_mmx() ? ", mmx" : ""),
|
||||
(supports_sse() ? ", sse" : ""),
|
||||
(supports_sse2() ? ", sse2" : ""),
|
||||
(supports_sse3() ? ", sse3" : ""),
|
||||
(supports_ssse3()? ", ssse3": ""),
|
||||
(supports_sse4_1() ? ", sse4.1" : ""),
|
||||
(supports_sse4_2() ? ", sse4.2" : ""),
|
||||
|
||||
(supports_popcnt() ? ", popcnt" : ""),
|
||||
(supports_vzeroupper() ? ", vzeroupper" : ""),
|
||||
(supports_avx() ? ", avx" : ""),
|
||||
(supports_avx2() ? ", avx2" : ""),
|
||||
(supports_aes() ? ", aes" : ""),
|
||||
(supports_clmul() ? ", clmul" : ""),
|
||||
(supports_erms() ? ", erms" : ""),
|
||||
(supports_rtm() ? ", rtm" : ""),
|
||||
(supports_3dnow_prefetch() ? ", 3dnowpref" : ""),
|
||||
(supports_lzcnt() ? ", lzcnt": ""),
|
||||
|
||||
(supports_sse4a() ? ", sse4a": ""),
|
||||
(supports_ht() ? ", ht": ""),
|
||||
(supports_tsc() ? ", tsc": ""),
|
||||
(supports_tscinv_bit() ? ", tscinvbit": ""),
|
||||
(supports_tscinv() ? ", tscinv": ""),
|
||||
(supports_bmi1() ? ", bmi1" : ""),
|
||||
(supports_bmi2() ? ", bmi2" : ""),
|
||||
(supports_adx() ? ", adx" : ""),
|
||||
(supports_evex() ? ", avx512f" : ""),
|
||||
(supports_avx512dq() ? ", avx512dq" : ""),
|
||||
|
||||
(supports_avx512pf() ? ", avx512pf" : ""),
|
||||
(supports_avx512er() ? ", avx512er" : ""),
|
||||
(supports_avx512cd() ? ", avx512cd" : ""),
|
||||
(supports_avx512bw() ? ", avx512bw" : ""),
|
||||
(supports_avx512vl() ? ", avx512vl" : ""),
|
||||
(supports_avx512_vpopcntdq() ? ", avx512_vpopcntdq" : ""),
|
||||
(supports_avx512_vpclmulqdq() ? ", avx512_vpclmulqdq" : ""),
|
||||
(supports_avx512_vbmi() ? ", avx512_vbmi" : ""),
|
||||
(supports_avx512_vbmi2() ? ", avx512_vbmi2" : ""),
|
||||
(supports_avx512_vaes() ? ", avx512_vaes" : ""),
|
||||
|
||||
(supports_avx512_vnni() ? ", avx512_vnni" : ""),
|
||||
(supports_sha() ? ", sha" : ""),
|
||||
(supports_fma() ? ", fma" : ""),
|
||||
(supports_clflush() ? ", clflush" : ""),
|
||||
(supports_clflushopt() ? ", clflushopt" : ""),
|
||||
(supports_clwb() ? ", clwb" : ""));
|
||||
|
||||
assert(res > 0, "not enough temporary space allocated"); // increase 'buf' size
|
||||
int res = 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(res > 0, "not enough temporary space allocated");
|
||||
assert(exact_log2(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);
|
||||
|
||||
|
@ -298,59 +298,87 @@ protected:
|
||||
static address _cpuinfo_segv_addr; // address of instruction which causes SEGV
|
||||
static address _cpuinfo_cont_addr; // address of instruction after the one which causes SEGV
|
||||
|
||||
enum Feature_Flag {
|
||||
CPU_CX8 = (1 << 0), // next bits are from cpuid 1 (EDX)
|
||||
CPU_CMOV = (1 << 1),
|
||||
CPU_FXSR = (1 << 2),
|
||||
CPU_HT = (1 << 3),
|
||||
CPU_MMX = (1 << 4),
|
||||
CPU_3DNOW_PREFETCH = (1 << 5), // Processor supports 3dnow prefetch and prefetchw instructions
|
||||
// may not necessarily support other 3dnow instructions
|
||||
CPU_SSE = (1 << 6),
|
||||
CPU_SSE2 = (1 << 7),
|
||||
CPU_SSE3 = (1 << 8), // SSE3 comes from cpuid 1 (ECX)
|
||||
CPU_SSSE3 = (1 << 9),
|
||||
CPU_SSE4A = (1 << 10),
|
||||
CPU_SSE4_1 = (1 << 11),
|
||||
CPU_SSE4_2 = (1 << 12),
|
||||
CPU_POPCNT = (1 << 13),
|
||||
CPU_LZCNT = (1 << 14),
|
||||
CPU_TSC = (1 << 15),
|
||||
CPU_TSCINV = (1 << 16),
|
||||
CPU_AVX = (1 << 17),
|
||||
CPU_AVX2 = (1 << 18),
|
||||
CPU_AES = (1 << 19),
|
||||
CPU_ERMS = (1 << 20), // enhanced 'rep movsb/stosb' instructions
|
||||
CPU_CLMUL = (1 << 21), // carryless multiply for CRC
|
||||
CPU_BMI1 = (1 << 22),
|
||||
CPU_BMI2 = (1 << 23),
|
||||
CPU_RTM = (1 << 24), // Restricted Transactional Memory instructions
|
||||
CPU_ADX = (1 << 25),
|
||||
CPU_AVX512F = (1 << 26), // AVX 512bit foundation instructions
|
||||
CPU_AVX512DQ = (1 << 27),
|
||||
CPU_AVX512PF = (1 << 28),
|
||||
CPU_AVX512ER = (1 << 29),
|
||||
CPU_AVX512CD = (1 << 30)
|
||||
// Keeping sign bit 31 unassigned.
|
||||
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),
|
||||
|
||||
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 CPU_AVX512BW ((uint64_t)UCONST64( 0x100000000)) // enums are limited to 31 bit
|
||||
#define CPU_AVX512VL ((uint64_t)UCONST64( 0x200000000)) // EVEX instructions with smaller vector length
|
||||
#define CPU_SHA ((uint64_t)UCONST64( 0x400000000)) // SHA instructions
|
||||
#define CPU_FMA ((uint64_t)UCONST64( 0x800000000)) // FMA instructions
|
||||
#define CPU_VZEROUPPER ((uint64_t)UCONST64( 0x1000000000)) // Vzeroupper instruction
|
||||
#define CPU_AVX512_VPOPCNTDQ ((uint64_t)UCONST64( 0x2000000000)) // Vector popcount
|
||||
#define CPU_AVX512_VPCLMULQDQ ((uint64_t)UCONST64( 0x4000000000)) // Vector carryless multiplication
|
||||
#define CPU_AVX512_VAES ((uint64_t)UCONST64( 0x8000000000)) // Vector AES instructions
|
||||
#define CPU_AVX512_VNNI ((uint64_t)UCONST64( 0x10000000000)) // Vector Neural Network Instructions
|
||||
#define CPU_FLUSH ((uint64_t)UCONST64( 0x20000000000)) // flush instruction
|
||||
#define CPU_FLUSHOPT ((uint64_t)UCONST64( 0x40000000000)) // flushopt instruction
|
||||
#define CPU_CLWB ((uint64_t)UCONST64( 0x80000000000)) // clwb instruction
|
||||
#define CPU_AVX512_VBMI2 ((uint64_t)UCONST64(0x100000000000)) // VBMI2 shift left double instructions
|
||||
#define CPU_AVX512_VBMI ((uint64_t)UCONST64(0x200000000000)) // Vector BMI instructions
|
||||
#define CPU_HV_PRESENT ((uint64_t)UCONST64(0x400000000000)) // for hypervisor detection
|
||||
#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"
|
||||
|
||||
// NB! When adding new CPU feature detection consider updating vmStructs_x86.hpp, vmStructs_jvmci.hpp, and VM_Version::get_processor_features().
|
||||
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
|
||||
@ -582,13 +610,13 @@ enum Extended_Family {
|
||||
}
|
||||
}
|
||||
if (_cpuid_info.std_cpuid1_ecx.bits.hv != 0)
|
||||
result |= CPU_HV_PRESENT;
|
||||
result |= CPU_HV;
|
||||
if (_cpuid_info.sef_cpuid7_ebx.bits.bmi1 != 0)
|
||||
result |= CPU_BMI1;
|
||||
if (_cpuid_info.std_cpuid1_edx.bits.tsc != 0)
|
||||
result |= CPU_TSC;
|
||||
if (_cpuid_info.ext_cpuid7_edx.bits.tsc_invariance != 0)
|
||||
result |= CPU_TSCINV;
|
||||
result |= CPU_TSCINV_BIT;
|
||||
if (_cpuid_info.std_cpuid1_ecx.bits.aes != 0)
|
||||
result |= CPU_AES;
|
||||
if (_cpuid_info.sef_cpuid7_ebx.bits.erms != 0)
|
||||
@ -618,6 +646,7 @@ enum Extended_Family {
|
||||
if (_cpuid_info.ext_cpuid1_ecx.bits.sse4a != 0)
|
||||
result |= CPU_SSE4A;
|
||||
}
|
||||
|
||||
// Intel features.
|
||||
if (is_intel()) {
|
||||
if (_cpuid_info.ext_cpuid1_ecx.bits.lzcnt_intel != 0)
|
||||
@ -641,6 +670,13 @@ enum Extended_Family {
|
||||
}
|
||||
}
|
||||
|
||||
// Composite features.
|
||||
if (supports_tscinv_bit() &&
|
||||
((is_amd_family() && !is_amd_Barcelona()) ||
|
||||
is_intel_tsc_synched_at_init())) {
|
||||
result |= CPU_TSCINV;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -827,54 +863,54 @@ public:
|
||||
//
|
||||
// Feature identification
|
||||
//
|
||||
static bool supports_cpuid() { return _features != 0; }
|
||||
static bool supports_cmpxchg8() { return (_features & CPU_CX8) != 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_aes() { return (_features & CPU_AES) != 0; }
|
||||
static bool supports_erms() { return (_features & CPU_ERMS) != 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_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_avx512vlbw() { return (supports_evex() && supports_avx512bw() && supports_avx512vl()); }
|
||||
static bool supports_avx512vldq() { return (supports_evex() && supports_avx512dq() && supports_avx512vl()); }
|
||||
static bool supports_cpuid() { return _features != 0; }
|
||||
static bool supports_cmpxchg8() { return (_features & CPU_CX8) != 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_aes() { return (_features & CPU_AES) != 0; }
|
||||
static bool supports_erms() { return (_features & CPU_ERMS) != 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_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_avx512vlbw() { return (supports_evex() && supports_avx512bw() && supports_avx512vl()); }
|
||||
static bool supports_avx512vldq() { return (supports_evex() && supports_avx512dq() && supports_avx512vl()); }
|
||||
static bool supports_avx512vlbwdq() { return (supports_evex() && supports_avx512vl() &&
|
||||
supports_avx512bw() && supports_avx512dq()); }
|
||||
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_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_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_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_avx512_vnni() { return (_features & CPU_AVX512_VNNI) != 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_hv() { return (_features & CPU_HV_PRESENT) != 0; }
|
||||
static bool supports_avx512_vaes() { return (_features & CPU_AVX512_VAES) != 0; }
|
||||
static bool supports_avx512_vnni() { return (_features & CPU_AVX512_VNNI) != 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_hv() { return (_features & CPU_HV) != 0; }
|
||||
|
||||
// Intel features
|
||||
static bool is_intel_family_core() { return is_intel() &&
|
||||
@ -917,12 +953,10 @@ public:
|
||||
|
||||
// Intel and AMD newer cores support fast timestamps well
|
||||
static bool supports_tscinv_bit() {
|
||||
return (_features & CPU_TSCINV) != 0;
|
||||
return (_features & CPU_TSCINV_BIT) != 0;
|
||||
}
|
||||
static bool supports_tscinv() {
|
||||
return supports_tscinv_bit() &&
|
||||
((is_amd_family() && !is_amd_Barcelona()) ||
|
||||
is_intel_tsc_synched_at_init());
|
||||
return (_features & CPU_TSCINV) != 0;
|
||||
}
|
||||
|
||||
// Intel Core and newer cpus have fast IDIV instruction (excluding Atom).
|
||||
@ -998,10 +1032,10 @@ public:
|
||||
// not synchronize with other memory ops. it needs a preceding
|
||||
// and trailing StoreStore fence
|
||||
//
|
||||
// clwb is an optional, intel-specific instruction optional which
|
||||
// clwb is an optional intel-specific instruction which
|
||||
// writes back without evicting the line. it also does not
|
||||
// synchronize with other memory ops. so, it also needs a preceding
|
||||
// and trailing StoreStore fence.
|
||||
// synchronize with other memory ops. so, it needs preceding
|
||||
// and trailing StoreStore fences.
|
||||
|
||||
#ifdef _LP64
|
||||
static bool supports_clflush() {
|
||||
@ -1017,13 +1051,12 @@ public:
|
||||
assert ((!Universe::is_fully_initialized() || (_features & CPU_FLUSH) != 0), "clflush should be available");
|
||||
return true;
|
||||
}
|
||||
static bool supports_clflushopt() { return ((_features & CPU_FLUSHOPT) != 0); }
|
||||
static bool supports_clwb() { return ((_features & CPU_CLWB) != 0); }
|
||||
#else
|
||||
static bool supports_clflush() { return ((_features & CPU_FLUSH) != 0); }
|
||||
static bool supports_clflushopt() { return false; }
|
||||
static bool supports_clwb() { return false; }
|
||||
#endif // _LP64
|
||||
// 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); }
|
||||
|
||||
// support functions for virtualization detection
|
||||
private:
|
||||
|
@ -49,7 +49,8 @@
|
||||
static_field(CompilerToVM::Data, SharedRuntime_ic_miss_stub, address) \
|
||||
static_field(CompilerToVM::Data, SharedRuntime_handle_wrong_method_stub, address) \
|
||||
static_field(CompilerToVM::Data, SharedRuntime_deopt_blob_unpack, address) \
|
||||
static_field(CompilerToVM::Data, SharedRuntime_deopt_blob_unpack_with_exception_in_tls, address) \
|
||||
static_field(CompilerToVM::Data, SharedRuntime_deopt_blob_unpack_with_exception_in_tls, \
|
||||
address) \
|
||||
static_field(CompilerToVM::Data, SharedRuntime_deopt_blob_uncommon_trap, address) \
|
||||
\
|
||||
static_field(CompilerToVM::Data, ThreadLocalAllocBuffer_alignment_reserve, size_t) \
|
||||
@ -752,7 +753,9 @@
|
||||
#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_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::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) \
|
||||
@ -783,23 +786,22 @@
|
||||
declare_constant(VM_Version::CPU_AVX512DQ) \
|
||||
declare_constant(VM_Version::CPU_AVX512PF) \
|
||||
declare_constant(VM_Version::CPU_AVX512ER) \
|
||||
declare_constant(VM_Version::CPU_AVX512CD)
|
||||
|
||||
#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \
|
||||
declare_preprocessor_constant("VM_Version::CPU_AVX512BW", CPU_AVX512BW) \
|
||||
declare_preprocessor_constant("VM_Version::CPU_AVX512VL", CPU_AVX512VL) \
|
||||
declare_preprocessor_constant("VM_Version::CPU_SHA", CPU_SHA) \
|
||||
declare_preprocessor_constant("VM_Version::CPU_FMA", CPU_FMA) \
|
||||
declare_preprocessor_constant("VM_Version::CPU_VZEROUPPER", CPU_VZEROUPPER) \
|
||||
declare_preprocessor_constant("VM_Version::CPU_AVX512_VPOPCNTDQ", CPU_AVX512_VPOPCNTDQ) \
|
||||
declare_preprocessor_constant("VM_Version::CPU_AVX512_VPCLMULQDQ", CPU_AVX512_VPCLMULQDQ) \
|
||||
declare_preprocessor_constant("VM_Version::CPU_AVX512_VAES", CPU_AVX512_VAES) \
|
||||
declare_preprocessor_constant("VM_Version::CPU_AVX512_VNNI", CPU_AVX512_VNNI) \
|
||||
declare_preprocessor_constant("VM_Version::CPU_FLUSH", CPU_FLUSH) \
|
||||
declare_preprocessor_constant("VM_Version::CPU_FLUSHOPT", CPU_FLUSHOPT) \
|
||||
declare_preprocessor_constant("VM_Version::CPU_CLWB", CPU_CLWB) \
|
||||
declare_preprocessor_constant("VM_Version::CPU_AVX512_VBMI2", CPU_AVX512_VBMI2) \
|
||||
declare_preprocessor_constant("VM_Version::CPU_AVX512_VBMI", CPU_AVX512_VBMI)
|
||||
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)
|
||||
|
||||
#endif
|
||||
|
||||
@ -822,7 +824,6 @@
|
||||
#define VM_ADDRESSES_OS(declare_address, declare_preprocessor_address, declare_function)
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// Instantiation of VMStructEntries, VMTypeEntries and VMIntConstantEntries
|
||||
//
|
||||
|
@ -291,6 +291,22 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
bool Abstract_VM_Version::print_matching_lines_from_file(const char* filename, outputStream* st, const char* keywords_to_match[]) {
|
||||
char line[500];
|
||||
FILE* fp = fopen(filename, "r");
|
||||
|
@ -119,13 +119,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 uint64_t features() { return _features; }
|
||||
static const char* features_string() { return _features_string; }
|
||||
static void insert_features_names(char* buf, size_t buflen, const char* features_names[]);
|
||||
|
||||
static VirtualizationType get_detected_virtualization() {
|
||||
return _detected_virtualization;
|
||||
|
Loading…
Reference in New Issue
Block a user