src/cpu/x86/vm/vm_version_x86.hpp

changeset 6388
98af1e198e73
parent 6378
8a8ff6b577ed
child 6429
606acabe7b5c
     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();

mercurial