< prev index next >

src/cpu/x86/vm/vm_version_x86.hpp

Print this page




  57                clflush_size     : 8,
  58                threads_per_cpu  : 8,
  59                apic_id          : 8;
  60     } bits;
  61   };
  62 
  63   union StdCpuid1Ecx {
  64     uint32_t value;
  65     struct {
  66       uint32_t sse3     : 1,
  67                clmul    : 1,
  68                         : 1,
  69                monitor  : 1,
  70                         : 1,
  71                vmx      : 1,
  72                         : 1,
  73                est      : 1,
  74                         : 1,
  75                ssse3    : 1,
  76                cid      : 1,
  77                         : 2,

  78                cmpxchg16: 1,
  79                         : 4,
  80                dca      : 1,
  81                sse4_1   : 1,
  82                sse4_2   : 1,
  83                         : 2,
  84                popcnt   : 1,
  85                         : 1,
  86                aes      : 1,
  87                         : 1,
  88                osxsave  : 1,
  89                avx      : 1,
  90                         : 3;
  91     } bits;
  92   };
  93 
  94   union StdCpuid1Edx {
  95     uint32_t value;
  96     struct {
  97       uint32_t          : 4,


 272     CPU_AVX      = (1 << 17),
 273     CPU_AVX2     = (1 << 18),
 274     CPU_AES      = (1 << 19),
 275     CPU_ERMS     = (1 << 20), // enhanced 'rep movsb/stosb' instructions
 276     CPU_CLMUL    = (1 << 21), // carryless multiply for CRC
 277     CPU_BMI1     = (1 << 22),
 278     CPU_BMI2     = (1 << 23),
 279     CPU_RTM      = (1 << 24), // Restricted Transactional Memory instructions
 280     CPU_ADX      = (1 << 25),
 281     CPU_AVX512F  = (1 << 26), // AVX 512bit foundation instructions
 282     CPU_AVX512DQ = (1 << 27),
 283     CPU_AVX512PF = (1 << 28),
 284     CPU_AVX512ER = (1 << 29),
 285     CPU_AVX512CD = (1 << 30)
 286     // Keeping sign bit 31 unassigned.
 287   };
 288 
 289 #define CPU_AVX512BW ((uint64_t)UCONST64(0x100000000)) // enums are limited to 31 bit
 290 #define CPU_AVX512VL ((uint64_t)UCONST64(0x200000000)) // EVEX instructions with smaller vector length
 291 #define CPU_SHA ((uint64_t)UCONST64(0x400000000))      // SHA instructions

 292 
 293   enum Extended_Family {
 294     // AMD
 295     CPU_FAMILY_AMD_11H       = 0x11,
 296     // Intel
 297     CPU_FAMILY_INTEL_CORE    = 6,
 298     CPU_MODEL_NEHALEM        = 0x1e,
 299     CPU_MODEL_NEHALEM_EP     = 0x1a,
 300     CPU_MODEL_NEHALEM_EX     = 0x2e,
 301     CPU_MODEL_WESTMERE       = 0x25,
 302     CPU_MODEL_WESTMERE_EP    = 0x2c,
 303     CPU_MODEL_WESTMERE_EX    = 0x2f,
 304     CPU_MODEL_SANDYBRIDGE    = 0x2a,
 305     CPU_MODEL_SANDYBRIDGE_EP = 0x2d,
 306     CPU_MODEL_IVYBRIDGE_EP   = 0x3a,
 307     CPU_MODEL_HASWELL_E3     = 0x3c,
 308     CPU_MODEL_HASWELL_E7     = 0x3f,
 309     CPU_MODEL_BROADWELL      = 0x3d,
 310     CPU_MODEL_SKYLAKE        = CPU_MODEL_HASWELL_E3
 311   };


 505     // AMD features.
 506     if (is_amd()) {
 507       if ((_cpuid_info.ext_cpuid1_edx.bits.tdnow != 0) ||
 508           (_cpuid_info.ext_cpuid1_ecx.bits.prefetchw != 0))
 509         result |= CPU_3DNOW_PREFETCH;
 510       if (_cpuid_info.ext_cpuid1_ecx.bits.lzcnt != 0)
 511         result |= CPU_LZCNT;
 512       if (_cpuid_info.ext_cpuid1_ecx.bits.sse4a != 0)
 513         result |= CPU_SSE4A;
 514     }
 515     // Intel features.
 516     if(is_intel()) {
 517       if(_cpuid_info.sef_cpuid7_ebx.bits.adx != 0)
 518          result |= CPU_ADX;
 519       if(_cpuid_info.sef_cpuid7_ebx.bits.bmi2 != 0)
 520         result |= CPU_BMI2;
 521       if (_cpuid_info.sef_cpuid7_ebx.bits.sha != 0)
 522         result |= CPU_SHA;
 523       if(_cpuid_info.ext_cpuid1_ecx.bits.lzcnt_intel != 0)
 524         result |= CPU_LZCNT;


 525       // for Intel, ecx.bits.misalignsse bit (bit 8) indicates support for prefetchw
 526       if (_cpuid_info.ext_cpuid1_ecx.bits.misalignsse != 0) {
 527         result |= CPU_3DNOW_PREFETCH;
 528       }
 529     }
 530 
 531     return result;
 532   }
 533 
 534   static bool os_supports_avx_vectors() {
 535     bool retVal = false;
 536     if (supports_evex()) {
 537       // Verify that OS save/restore all bits of EVEX registers
 538       // during signal processing.
 539       int nreg = 2 LP64_ONLY(+2);
 540       retVal = true;
 541       for (int i = 0; i < 16 * nreg; i++) { // 64 bytes per zmm register
 542         if (_cpuid_info.zmm_save[i] != ymm_test_value()) {
 543           retVal = false;
 544           break;


 709   static bool supports_aes()      { return (_features & CPU_AES) != 0; }
 710   static bool supports_erms()     { return (_features & CPU_ERMS) != 0; }
 711   static bool supports_clmul()    { return (_features & CPU_CLMUL) != 0; }
 712   static bool supports_rtm()      { return (_features & CPU_RTM) != 0; }
 713   static bool supports_bmi1()     { return (_features & CPU_BMI1) != 0; }
 714   static bool supports_bmi2()     { return (_features & CPU_BMI2) != 0; }
 715   static bool supports_adx()      { return (_features & CPU_ADX) != 0; }
 716   static bool supports_evex()     { return (_features & CPU_AVX512F) != 0; }
 717   static bool supports_avx512dq() { return (_features & CPU_AVX512DQ) != 0; }
 718   static bool supports_avx512pf() { return (_features & CPU_AVX512PF) != 0; }
 719   static bool supports_avx512er() { return (_features & CPU_AVX512ER) != 0; }
 720   static bool supports_avx512cd() { return (_features & CPU_AVX512CD) != 0; }
 721   static bool supports_avx512bw() { return (_features & CPU_AVX512BW) != 0; }
 722   static bool supports_avx512vl() { return (_features & CPU_AVX512VL) != 0; }
 723   static bool supports_avx512vlbw() { return (supports_avx512bw() && supports_avx512vl()); }
 724   static bool supports_avx512novl() { return (supports_evex() && !supports_avx512vl()); }
 725   static bool supports_avx512nobw() { return (supports_evex() && !supports_avx512bw()); }
 726   static bool supports_avx256only() { return (supports_avx2() && !supports_evex()); }
 727   static bool supports_avxonly()    { return ((supports_avx2() || supports_avx()) && !supports_evex()); }
 728   static bool supports_sha()        { return (_features & CPU_SHA) != 0; }

 729   // Intel features
 730   static bool is_intel_family_core() { return is_intel() &&
 731                                        extended_cpu_family() == CPU_FAMILY_INTEL_CORE; }
 732 
 733   static bool is_intel_tsc_synched_at_init()  {
 734     if (is_intel_family_core()) {
 735       uint32_t ext_model = extended_cpu_model();
 736       if (ext_model == CPU_MODEL_NEHALEM_EP     ||
 737           ext_model == CPU_MODEL_WESTMERE_EP    ||
 738           ext_model == CPU_MODEL_SANDYBRIDGE_EP ||
 739           ext_model == CPU_MODEL_IVYBRIDGE_EP) {
 740         // <= 2-socket invariant tsc support. EX versions are usually used
 741         // in > 2-socket systems and likely don't synchronize tscs at
 742         // initialization.
 743         // Code that uses tsc values must be prepared for them to arbitrarily
 744         // jump forward or backward.
 745         return true;
 746       }
 747     }
 748     return false;




  57                clflush_size     : 8,
  58                threads_per_cpu  : 8,
  59                apic_id          : 8;
  60     } bits;
  61   };
  62 
  63   union StdCpuid1Ecx {
  64     uint32_t value;
  65     struct {
  66       uint32_t sse3     : 1,
  67                clmul    : 1,
  68                         : 1,
  69                monitor  : 1,
  70                         : 1,
  71                vmx      : 1,
  72                         : 1,
  73                est      : 1,
  74                         : 1,
  75                ssse3    : 1,
  76                cid      : 1,
  77                         : 1,
  78                fma      : 1,
  79                cmpxchg16: 1,
  80                         : 4,
  81                dca      : 1,
  82                sse4_1   : 1,
  83                sse4_2   : 1,
  84                         : 2,
  85                popcnt   : 1,
  86                         : 1,
  87                aes      : 1,
  88                         : 1,
  89                osxsave  : 1,
  90                avx      : 1,
  91                         : 3;
  92     } bits;
  93   };
  94 
  95   union StdCpuid1Edx {
  96     uint32_t value;
  97     struct {
  98       uint32_t          : 4,


 273     CPU_AVX      = (1 << 17),
 274     CPU_AVX2     = (1 << 18),
 275     CPU_AES      = (1 << 19),
 276     CPU_ERMS     = (1 << 20), // enhanced 'rep movsb/stosb' instructions
 277     CPU_CLMUL    = (1 << 21), // carryless multiply for CRC
 278     CPU_BMI1     = (1 << 22),
 279     CPU_BMI2     = (1 << 23),
 280     CPU_RTM      = (1 << 24), // Restricted Transactional Memory instructions
 281     CPU_ADX      = (1 << 25),
 282     CPU_AVX512F  = (1 << 26), // AVX 512bit foundation instructions
 283     CPU_AVX512DQ = (1 << 27),
 284     CPU_AVX512PF = (1 << 28),
 285     CPU_AVX512ER = (1 << 29),
 286     CPU_AVX512CD = (1 << 30)
 287     // Keeping sign bit 31 unassigned.
 288   };
 289 
 290 #define CPU_AVX512BW ((uint64_t)UCONST64(0x100000000)) // enums are limited to 31 bit
 291 #define CPU_AVX512VL ((uint64_t)UCONST64(0x200000000)) // EVEX instructions with smaller vector length
 292 #define CPU_SHA ((uint64_t)UCONST64(0x400000000))      // SHA instructions
 293 #define CPU_FMA ((uint64_t)UCONST64(0x800000000))      // FMA instructions
 294 
 295   enum Extended_Family {
 296     // AMD
 297     CPU_FAMILY_AMD_11H       = 0x11,
 298     // Intel
 299     CPU_FAMILY_INTEL_CORE    = 6,
 300     CPU_MODEL_NEHALEM        = 0x1e,
 301     CPU_MODEL_NEHALEM_EP     = 0x1a,
 302     CPU_MODEL_NEHALEM_EX     = 0x2e,
 303     CPU_MODEL_WESTMERE       = 0x25,
 304     CPU_MODEL_WESTMERE_EP    = 0x2c,
 305     CPU_MODEL_WESTMERE_EX    = 0x2f,
 306     CPU_MODEL_SANDYBRIDGE    = 0x2a,
 307     CPU_MODEL_SANDYBRIDGE_EP = 0x2d,
 308     CPU_MODEL_IVYBRIDGE_EP   = 0x3a,
 309     CPU_MODEL_HASWELL_E3     = 0x3c,
 310     CPU_MODEL_HASWELL_E7     = 0x3f,
 311     CPU_MODEL_BROADWELL      = 0x3d,
 312     CPU_MODEL_SKYLAKE        = CPU_MODEL_HASWELL_E3
 313   };


 507     // AMD features.
 508     if (is_amd()) {
 509       if ((_cpuid_info.ext_cpuid1_edx.bits.tdnow != 0) ||
 510           (_cpuid_info.ext_cpuid1_ecx.bits.prefetchw != 0))
 511         result |= CPU_3DNOW_PREFETCH;
 512       if (_cpuid_info.ext_cpuid1_ecx.bits.lzcnt != 0)
 513         result |= CPU_LZCNT;
 514       if (_cpuid_info.ext_cpuid1_ecx.bits.sse4a != 0)
 515         result |= CPU_SSE4A;
 516     }
 517     // Intel features.
 518     if(is_intel()) {
 519       if(_cpuid_info.sef_cpuid7_ebx.bits.adx != 0)
 520          result |= CPU_ADX;
 521       if(_cpuid_info.sef_cpuid7_ebx.bits.bmi2 != 0)
 522         result |= CPU_BMI2;
 523       if (_cpuid_info.sef_cpuid7_ebx.bits.sha != 0)
 524         result |= CPU_SHA;
 525       if(_cpuid_info.ext_cpuid1_ecx.bits.lzcnt_intel != 0)
 526         result |= CPU_LZCNT;
 527       if (_cpuid_info.std_cpuid1_ecx.bits.fma != 0)
 528         result |= CPU_FMA;
 529       // for Intel, ecx.bits.misalignsse bit (bit 8) indicates support for prefetchw
 530       if (_cpuid_info.ext_cpuid1_ecx.bits.misalignsse != 0) {
 531         result |= CPU_3DNOW_PREFETCH;
 532       }
 533     }
 534 
 535     return result;
 536   }
 537 
 538   static bool os_supports_avx_vectors() {
 539     bool retVal = false;
 540     if (supports_evex()) {
 541       // Verify that OS save/restore all bits of EVEX registers
 542       // during signal processing.
 543       int nreg = 2 LP64_ONLY(+2);
 544       retVal = true;
 545       for (int i = 0; i < 16 * nreg; i++) { // 64 bytes per zmm register
 546         if (_cpuid_info.zmm_save[i] != ymm_test_value()) {
 547           retVal = false;
 548           break;


 713   static bool supports_aes()      { return (_features & CPU_AES) != 0; }
 714   static bool supports_erms()     { return (_features & CPU_ERMS) != 0; }
 715   static bool supports_clmul()    { return (_features & CPU_CLMUL) != 0; }
 716   static bool supports_rtm()      { return (_features & CPU_RTM) != 0; }
 717   static bool supports_bmi1()     { return (_features & CPU_BMI1) != 0; }
 718   static bool supports_bmi2()     { return (_features & CPU_BMI2) != 0; }
 719   static bool supports_adx()      { return (_features & CPU_ADX) != 0; }
 720   static bool supports_evex()     { return (_features & CPU_AVX512F) != 0; }
 721   static bool supports_avx512dq() { return (_features & CPU_AVX512DQ) != 0; }
 722   static bool supports_avx512pf() { return (_features & CPU_AVX512PF) != 0; }
 723   static bool supports_avx512er() { return (_features & CPU_AVX512ER) != 0; }
 724   static bool supports_avx512cd() { return (_features & CPU_AVX512CD) != 0; }
 725   static bool supports_avx512bw() { return (_features & CPU_AVX512BW) != 0; }
 726   static bool supports_avx512vl() { return (_features & CPU_AVX512VL) != 0; }
 727   static bool supports_avx512vlbw() { return (supports_avx512bw() && supports_avx512vl()); }
 728   static bool supports_avx512novl() { return (supports_evex() && !supports_avx512vl()); }
 729   static bool supports_avx512nobw() { return (supports_evex() && !supports_avx512bw()); }
 730   static bool supports_avx256only() { return (supports_avx2() && !supports_evex()); }
 731   static bool supports_avxonly()    { return ((supports_avx2() || supports_avx()) && !supports_evex()); }
 732   static bool supports_sha()        { return (_features & CPU_SHA) != 0; }
 733   static bool supports_fma()        { return (_features & CPU_FMA) != 0; }
 734   // Intel features
 735   static bool is_intel_family_core() { return is_intel() &&
 736                                        extended_cpu_family() == CPU_FAMILY_INTEL_CORE; }
 737 
 738   static bool is_intel_tsc_synched_at_init()  {
 739     if (is_intel_family_core()) {
 740       uint32_t ext_model = extended_cpu_model();
 741       if (ext_model == CPU_MODEL_NEHALEM_EP     ||
 742           ext_model == CPU_MODEL_WESTMERE_EP    ||
 743           ext_model == CPU_MODEL_SANDYBRIDGE_EP ||
 744           ext_model == CPU_MODEL_IVYBRIDGE_EP) {
 745         // <= 2-socket invariant tsc support. EX versions are usually used
 746         // in > 2-socket systems and likely don't synchronize tscs at
 747         // initialization.
 748         // Code that uses tsc values must be prepared for them to arbitrarily
 749         // jump forward or backward.
 750         return true;
 751       }
 752     }
 753     return false;


< prev index next >