src/cpu/x86/vm/vm_version_x86.hpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File
*** old/src/cpu/x86/vm/vm_version_x86.hpp	Fri May  8 11:59:26 2015
--- new/src/cpu/x86/vm/vm_version_x86.hpp	Fri May  8 11:59:26 2015

*** 207,237 **** --- 207,250 ---- : 2, bmi2 : 1, erms : 1, : 1, rtm : 1, ! : 7, ! : 4, + avx512f : 1, + avx512dq : 1, + : 1, adx : 1, : 12; + : 6, + avx512pf : 1, + avx512er : 1, + avx512cd : 1, + : 1, + avx512bw : 1, + avx512vl : 1; } bits; }; union XemXcr0Eax { uint32_t value; struct { uint32_t x87 : 1, sse : 1, ymm : 1, : 29; + : 2, + opmask : 1, + zmm512 : 1, + zmm32 : 1, + : 24; } bits; }; protected: static int _cpu; static int _model; static int _stepping; ! static int _cpuFeatures; // features returned by the "cpuid" instruction ! static uint64_t _cpuFeatures; // features returned by the "cpuid" instruction // 0 if this instruction is not available static const char* _features_str; 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
*** 261,273 **** --- 274,294 ---- 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), + CPU_AVX512BW = (1 << 31) } cpuFeatureFlags; + #define CPU_AVX512VL 0x100000000 // EVEX instructions with smaller vector length : enums are limited to 32bit + enum { // AMD CPU_FAMILY_AMD_11H = 0x11, // Intel CPU_FAMILY_INTEL_CORE = 6,
*** 280,290 **** --- 301,312 ---- CPU_MODEL_SANDYBRIDGE = 0x2a, CPU_MODEL_SANDYBRIDGE_EP = 0x2d, CPU_MODEL_IVYBRIDGE_EP = 0x3a, CPU_MODEL_HASWELL_E3 = 0x3c, CPU_MODEL_HASWELL_E7 = 0x3f, ! CPU_MODEL_BROADWELL = 0x3d, + CPU_MODEL_SKYLAKE = CPU_MODEL_HASWELL_E3 } cpuExtendedFamily; // cpuid information block. All info derived from executing cpuid with // various function numbers is stored here. Intel and AMD info is // merged in this block: accessor methods disentangle it.
*** 374,383 **** --- 396,408 ---- XemXcr0Eax xem_xcr0_eax; uint32_t xem_xcr0_edx; // reserved // Space to save ymm registers after signal handle int ymm_save[8*4]; // Save ymm0, ymm7, ymm8, ymm15 + + // Space to save zmm registers after signal handle + int zmm_save[16*4]; // Save zmm0, zmm7, zmm8, zmm31 }; // The actual cpuid info block static CpuidInfo _cpuid_info;
*** 402,413 **** --- 427,438 ---- static uint logical_processor_count() { uint result = threads_per_core(); return result; } ! static uint32_t feature_flags() { ! uint32_t result = 0; ! static uint64_t feature_flags() { ! uint64_t result = 0; if (_cpuid_info.std_cpuid1_edx.bits.cmpxchg8 != 0) result |= CPU_CX8; if (_cpuid_info.std_cpuid1_edx.bits.cmov != 0) result |= CPU_CMOV; if (_cpuid_info.std_cpuid1_edx.bits.fxsr != 0 || (is_amd() &&
*** 438,447 **** --- 463,490 ---- _cpuid_info.xem_xcr0_eax.bits.sse != 0 && _cpuid_info.xem_xcr0_eax.bits.ymm != 0) { result |= CPU_AVX; if (_cpuid_info.sef_cpuid7_ebx.bits.avx2 != 0) result |= CPU_AVX2; + if (_cpuid_info.sef_cpuid7_ebx.bits.avx512f != 0 && + _cpuid_info.xem_xcr0_eax.bits.opmask != 0 && + _cpuid_info.xem_xcr0_eax.bits.zmm512 != 0 && + _cpuid_info.xem_xcr0_eax.bits.zmm32 != 0) { + result |= CPU_AVX512F; + if (_cpuid_info.sef_cpuid7_ebx.bits.avx512cd != 0) + result |= CPU_AVX512CD; + if (_cpuid_info.sef_cpuid7_ebx.bits.avx512dq != 0) + result |= CPU_AVX512DQ; + if (_cpuid_info.sef_cpuid7_ebx.bits.avx512pf != 0) + result |= CPU_AVX512PF; + if (_cpuid_info.sef_cpuid7_ebx.bits.avx512er != 0) + result |= CPU_AVX512ER; + if (_cpuid_info.sef_cpuid7_ebx.bits.avx512bw != 0) + result |= CPU_AVX512BW; + if (_cpuid_info.sef_cpuid7_ebx.bits.avx512vl != 0) + result |= CPU_AVX512VL; + } } if(_cpuid_info.sef_cpuid7_ebx.bits.bmi1 != 0) result |= CPU_BMI1; if (_cpuid_info.std_cpuid1_edx.bits.tsc != 0) result |= CPU_TSC;
*** 482,503 **** --- 525,559 ---- return result; } static bool os_supports_avx_vectors() { if (!supports_avx()) { return false; + bool retVal = false; + if (supports_evex()) { + // Verify that OS save/restore all bits of EVEX registers + // during signal processing. + int nreg = 2 LP64_ONLY(+2); + retVal = true; + for (int i = 0; i < 16 * nreg; i++) { // 64 bytes per zmm register + if (_cpuid_info.zmm_save[i] != ymm_test_value()) { + retVal = false; + break; + } } + } else if (supports_avx()) { // Verify that OS save/restore all bits of AVX registers // during signal processing. int nreg = 2 LP64_ONLY(+2); + retVal = true; for (int i = 0; i < 8 * nreg; i++) { // 32 bytes per ymm register if (_cpuid_info.ymm_save[i] != ymm_test_value()) { ! return false; ! retVal = false; + break; } } return true; + } + return retVal; } static void get_processor_features(); public:
*** 513,522 **** --- 569,579 ---- static ByteSize tpl_cpuidB0_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB0_eax); } static ByteSize tpl_cpuidB1_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB1_eax); } static ByteSize tpl_cpuidB2_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB2_eax); } static ByteSize xem_xcr0_offset() { return byte_offset_of(CpuidInfo, xem_xcr0_eax); } static ByteSize ymm_save_offset() { return byte_offset_of(CpuidInfo, ymm_save); } + static ByteSize zmm_save_offset() { return byte_offset_of(CpuidInfo, zmm_save); } // The value used to check ymm register after signal handle static int ymm_test_value() { return 0xCAFEBABE; } static void get_cpu_info_wrapper();
*** 525,534 **** --- 582,592 ---- static void set_cpuinfo_cont_addr(address pc) { _cpuinfo_cont_addr = pc; } static address cpuinfo_cont_addr() { return _cpuinfo_cont_addr; } static void clean_cpuFeatures() { _cpuFeatures = 0; } static void set_avx_cpuFeatures() { _cpuFeatures = (CPU_SSE | CPU_SSE2 | CPU_AVX); } + static void set_evex_cpuFeatures() { _cpuFeatures = (CPU_AVX512F | CPU_SSE | CPU_SSE2 ); } // Initialization static void initialize();
*** 635,644 **** --- 693,709 ---- static bool supports_clmul() { return (_cpuFeatures & CPU_CLMUL) != 0; } static bool supports_rtm() { return (_cpuFeatures & CPU_RTM) != 0; } static bool supports_bmi1() { return (_cpuFeatures & CPU_BMI1) != 0; } static bool supports_bmi2() { return (_cpuFeatures & CPU_BMI2) != 0; } static bool supports_adx() { return (_cpuFeatures & CPU_ADX) != 0; } + static bool supports_evex() { return (_cpuFeatures & CPU_AVX512F) != 0; } + static bool supports_avx512dq() { return (_cpuFeatures & CPU_AVX512DQ) != 0; } + static bool supports_avx512pf() { return (_cpuFeatures & CPU_AVX512PF) != 0; } + static bool supports_avx512er() { return (_cpuFeatures & CPU_AVX512ER) != 0; } + static bool supports_avx512cd() { return (_cpuFeatures & CPU_AVX512CD) != 0; } + static bool supports_avx512bw() { return (_cpuFeatures & CPU_AVX512BW) != 0; } + static bool supports_avx512vl() { return (_cpuFeatures & CPU_AVX512VL) != 0; } // Intel features static bool is_intel_family_core() { return is_intel() && extended_cpu_family() == CPU_FAMILY_INTEL_CORE; } static bool is_intel_tsc_synched_at_init() {

src/cpu/x86/vm/vm_version_x86.hpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File