1.1 --- a/src/cpu/x86/vm/vm_version_x86.hpp Mon Mar 17 13:42:16 2014 +0100 1.2 +++ b/src/cpu/x86/vm/vm_version_x86.hpp Fri Mar 14 17:28:58 2014 -0700 1.3 @@ -229,6 +229,9 @@ 1.4 // 0 if this instruction is not available 1.5 static const char* _features_str; 1.6 1.7 + static address _cpuinfo_segv_addr; // address of instruction which causes SEGV 1.8 + static address _cpuinfo_cont_addr; // address of instruction after the one which causes SEGV 1.9 + 1.10 enum { 1.11 CPU_CX8 = (1 << 0), // next bits are from cpuid 1 (EDX) 1.12 CPU_CMOV = (1 << 1), 1.13 @@ -361,6 +364,9 @@ 1.14 // extended control register XCR0 (the XFEATURE_ENABLED_MASK register) 1.15 XemXcr0Eax xem_xcr0_eax; 1.16 uint32_t xem_xcr0_edx; // reserved 1.17 + 1.18 + // Space to save ymm registers after signal handle 1.19 + int ymm_save[8*4]; // Save ymm0, ymm7, ymm8, ymm15 1.20 }; 1.21 1.22 // The actual cpuid info block 1.23 @@ -460,6 +466,21 @@ 1.24 return result; 1.25 } 1.26 1.27 + static bool os_supports_avx_vectors() { 1.28 + if (!supports_avx()) { 1.29 + return false; 1.30 + } 1.31 + // Verify that OS save/restore all bits of AVX registers 1.32 + // during signal processing. 1.33 + int nreg = 2 LP64_ONLY(+2); 1.34 + for (int i = 0; i < 8 * nreg; i++) { // 32 bytes per ymm register 1.35 + if (_cpuid_info.ymm_save[i] != ymm_test_value()) { 1.36 + return false; 1.37 + } 1.38 + } 1.39 + return true; 1.40 + } 1.41 + 1.42 static void get_processor_features(); 1.43 1.44 public: 1.45 @@ -476,6 +497,19 @@ 1.46 static ByteSize tpl_cpuidB1_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB1_eax); } 1.47 static ByteSize tpl_cpuidB2_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB2_eax); } 1.48 static ByteSize xem_xcr0_offset() { return byte_offset_of(CpuidInfo, xem_xcr0_eax); } 1.49 + static ByteSize ymm_save_offset() { return byte_offset_of(CpuidInfo, ymm_save); } 1.50 + 1.51 + // The value used to check ymm register after signal handle 1.52 + static int ymm_test_value() { return 0xCAFEBABE; } 1.53 + 1.54 + static void set_cpuinfo_segv_addr(address pc) { _cpuinfo_segv_addr = pc; } 1.55 + static bool is_cpuinfo_segv_addr(address pc) { return _cpuinfo_segv_addr == pc; } 1.56 + static void set_cpuinfo_cont_addr(address pc) { _cpuinfo_cont_addr = pc; } 1.57 + static address cpuinfo_cont_addr() { return _cpuinfo_cont_addr; } 1.58 + 1.59 + static void clean_cpuFeatures() { _cpuFeatures = 0; } 1.60 + static void set_avx_cpuFeatures() { _cpuFeatures = (CPU_SSE | CPU_SSE2 | CPU_AVX); } 1.61 + 1.62 1.63 // Initialization 1.64 static void initialize();