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

src/cpu/x86/vm/vm_version_x86.hpp

Print this page
rev 743 : [mq]: 6823354


 103                              : 21,
 104                cores_per_cpu : 6;
 105     } bits;
 106   };
 107 
 108   union DcpCpuid4Ebx {
 109     uint32_t value;
 110     struct {
 111       uint32_t L1_line_size  : 12,
 112                partitions    : 10,
 113                associativity : 10;
 114     } bits;
 115   };
 116 
 117   union ExtCpuid1Ecx {
 118     uint32_t value;
 119     struct {
 120       uint32_t LahfSahf     : 1,
 121                CmpLegacy    : 1,
 122                             : 4,
 123                abm          : 1,
 124                sse4a        : 1,
 125                misalignsse  : 1,
 126                prefetchw    : 1,
 127                             : 22;
 128     } bits;
 129   };
 130 
 131   union ExtCpuid1Edx {
 132     uint32_t value;
 133     struct {
 134       uint32_t           : 22,
 135                mmx_amd   : 1,
 136                mmx       : 1,
 137                fxsr      : 1,
 138                          : 4,
 139                long_mode : 1,
 140                tdnow2    : 1,
 141                tdnow     : 1;
 142     } bits;
 143   };


 165    static int _model;
 166    static int _stepping;
 167    static int _cpuFeatures;     // features returned by the "cpuid" instruction
 168                                 // 0 if this instruction is not available
 169    static const char* _features_str;
 170 
 171    enum {
 172      CPU_CX8    = (1 << 0), // next bits are from cpuid 1 (EDX)
 173      CPU_CMOV   = (1 << 1),
 174      CPU_FXSR   = (1 << 2),
 175      CPU_HT     = (1 << 3),
 176      CPU_MMX    = (1 << 4),
 177      CPU_3DNOW  = (1 << 5), // 3DNow comes from cpuid 0x80000001 (EDX)
 178      CPU_SSE    = (1 << 6),
 179      CPU_SSE2   = (1 << 7),
 180      CPU_SSE3   = (1 << 8), // SSE3 comes from cpuid 1 (ECX)
 181      CPU_SSSE3  = (1 << 9),
 182      CPU_SSE4A  = (1 << 10),
 183      CPU_SSE4_1 = (1 << 11),
 184      CPU_SSE4_2 = (1 << 12),
 185      CPU_POPCNT = (1 << 13)

 186    } cpuFeatureFlags;
 187 
 188   // cpuid information block.  All info derived from executing cpuid with
 189   // various function numbers is stored here.  Intel and AMD info is
 190   // merged in this block: accessor methods disentangle it.
 191   //
 192   // The info block is laid out in subblocks of 4 dwords corresponding to
 193   // eax, ebx, ecx and edx, whether or not they contain anything useful.
 194   struct CpuidInfo {
 195     // cpuid function 0
 196     uint32_t std_max_function;
 197     uint32_t std_vendor_name_0;
 198     uint32_t std_vendor_name_1;
 199     uint32_t std_vendor_name_2;
 200 
 201     // cpuid function 1
 202     StdCpuid1Eax std_cpuid1_eax;
 203     StdCpuid1Ebx std_cpuid1_ebx;
 204     StdCpuid1Ecx std_cpuid1_ecx;
 205     StdCpuid1Edx std_cpuid1_edx;


 260   }
 261   static uint logical_processor_count() {
 262     uint result = threads_per_core();
 263     return result;
 264   }
 265   static uint32_t feature_flags() {
 266     uint32_t result = 0;
 267     if (_cpuid_info.std_cpuid1_edx.bits.cmpxchg8 != 0)
 268       result |= CPU_CX8;
 269     if (_cpuid_info.std_cpuid1_edx.bits.cmov != 0)
 270       result |= CPU_CMOV;
 271     if (_cpuid_info.std_cpuid1_edx.bits.fxsr != 0 || is_amd() &&
 272         _cpuid_info.ext_cpuid1_edx.bits.fxsr != 0)
 273       result |= CPU_FXSR;
 274     // HT flag is set for multi-core processors also.
 275     if (threads_per_core() > 1)
 276       result |= CPU_HT;
 277     if (_cpuid_info.std_cpuid1_edx.bits.mmx != 0 || is_amd() &&
 278         _cpuid_info.ext_cpuid1_edx.bits.mmx != 0)
 279       result |= CPU_MMX;
 280     if (is_amd() && _cpuid_info.ext_cpuid1_edx.bits.tdnow != 0)
 281       result |= CPU_3DNOW;
 282     if (_cpuid_info.std_cpuid1_edx.bits.sse != 0)
 283       result |= CPU_SSE;
 284     if (_cpuid_info.std_cpuid1_edx.bits.sse2 != 0)
 285       result |= CPU_SSE2;
 286     if (_cpuid_info.std_cpuid1_ecx.bits.sse3 != 0)
 287       result |= CPU_SSE3;
 288     if (_cpuid_info.std_cpuid1_ecx.bits.ssse3 != 0)
 289       result |= CPU_SSSE3;
 290     if (is_amd() && _cpuid_info.ext_cpuid1_ecx.bits.sse4a != 0)
 291       result |= CPU_SSE4A;
 292     if (_cpuid_info.std_cpuid1_ecx.bits.sse4_1 != 0)
 293       result |= CPU_SSE4_1;
 294     if (_cpuid_info.std_cpuid1_ecx.bits.sse4_2 != 0)
 295       result |= CPU_SSE4_2;
 296     if (_cpuid_info.std_cpuid1_ecx.bits.popcnt != 0)
 297       result |= CPU_POPCNT;











 298     return result;
 299   }
 300 
 301   static void get_processor_features();
 302 
 303 public:
 304   // Offsets for cpuid asm stub
 305   static ByteSize std_cpuid0_offset() { return byte_offset_of(CpuidInfo, std_max_function); }
 306   static ByteSize std_cpuid1_offset() { return byte_offset_of(CpuidInfo, std_cpuid1_eax); }
 307   static ByteSize dcp_cpuid4_offset() { return byte_offset_of(CpuidInfo, dcp_cpuid4_eax); }
 308   static ByteSize ext_cpuid1_offset() { return byte_offset_of(CpuidInfo, ext_cpuid1_eax); }
 309   static ByteSize ext_cpuid5_offset() { return byte_offset_of(CpuidInfo, ext_cpuid5_eax); }
 310   static ByteSize ext_cpuid8_offset() { return byte_offset_of(CpuidInfo, ext_cpuid8_eax); }
 311 
 312   // Initialization
 313   static void initialize();
 314 
 315   // Asserts
 316   static void assert_is_initialized() {
 317     assert(_cpuid_info.std_cpuid1_eax.bits.family != 0, "VM_Version not initialized");


 374   //
 375   static bool supports_cpuid()    { return _cpuFeatures  != 0; }
 376   static bool supports_cmpxchg8() { return (_cpuFeatures & CPU_CX8) != 0; }
 377   static bool supports_cmov()     { return (_cpuFeatures & CPU_CMOV) != 0; }
 378   static bool supports_fxsr()     { return (_cpuFeatures & CPU_FXSR) != 0; }
 379   static bool supports_ht()       { return (_cpuFeatures & CPU_HT) != 0; }
 380   static bool supports_mmx()      { return (_cpuFeatures & CPU_MMX) != 0; }
 381   static bool supports_sse()      { return (_cpuFeatures & CPU_SSE) != 0; }
 382   static bool supports_sse2()     { return (_cpuFeatures & CPU_SSE2) != 0; }
 383   static bool supports_sse3()     { return (_cpuFeatures & CPU_SSE3) != 0; }
 384   static bool supports_ssse3()    { return (_cpuFeatures & CPU_SSSE3)!= 0; }
 385   static bool supports_sse4_1()   { return (_cpuFeatures & CPU_SSE4_1) != 0; }
 386   static bool supports_sse4_2()   { return (_cpuFeatures & CPU_SSE4_2) != 0; }
 387   static bool supports_popcnt()   { return (_cpuFeatures & CPU_POPCNT) != 0; }
 388   //
 389   // AMD features
 390   //
 391   static bool supports_3dnow()    { return (_cpuFeatures & CPU_3DNOW) != 0; }
 392   static bool supports_mmx_ext()  { return is_amd() && _cpuid_info.ext_cpuid1_edx.bits.mmx_amd != 0; }
 393   static bool supports_3dnow2()   { return is_amd() && _cpuid_info.ext_cpuid1_edx.bits.tdnow2 != 0; }

 394   static bool supports_sse4a()    { return (_cpuFeatures & CPU_SSE4A) != 0; }
 395 
 396   static bool supports_compare_and_exchange() { return true; }
 397 
 398   static const char* cpu_features()           { return _features_str; }
 399 
 400   static intx allocate_prefetch_distance() {
 401     // This method should be called before allocate_prefetch_style().
 402     //
 403     // Hardware prefetching (distance/size in bytes):
 404     // Pentium 3 -  64 /  32
 405     // Pentium 4 - 256 / 128
 406     // Athlon    -  64 /  32 ????
 407     // Opteron   - 128 /  64 only when 2 sequential cache lines accessed
 408     // Core      - 128 /  64
 409     //
 410     // Software prefetching (distance in bytes / instruction with best score):
 411     // Pentium 3 - 128 / prefetchnta
 412     // Pentium 4 - 512 / prefetchnta
 413     // Athlon    - 128 / prefetchnta




 103                              : 21,
 104                cores_per_cpu : 6;
 105     } bits;
 106   };
 107 
 108   union DcpCpuid4Ebx {
 109     uint32_t value;
 110     struct {
 111       uint32_t L1_line_size  : 12,
 112                partitions    : 10,
 113                associativity : 10;
 114     } bits;
 115   };
 116 
 117   union ExtCpuid1Ecx {
 118     uint32_t value;
 119     struct {
 120       uint32_t LahfSahf     : 1,
 121                CmpLegacy    : 1,
 122                             : 4,
 123                lzcnt        : 1,
 124                sse4a        : 1,
 125                misalignsse  : 1,
 126                prefetchw    : 1,
 127                             : 22;
 128     } bits;
 129   };
 130 
 131   union ExtCpuid1Edx {
 132     uint32_t value;
 133     struct {
 134       uint32_t           : 22,
 135                mmx_amd   : 1,
 136                mmx       : 1,
 137                fxsr      : 1,
 138                          : 4,
 139                long_mode : 1,
 140                tdnow2    : 1,
 141                tdnow     : 1;
 142     } bits;
 143   };


 165    static int _model;
 166    static int _stepping;
 167    static int _cpuFeatures;     // features returned by the "cpuid" instruction
 168                                 // 0 if this instruction is not available
 169    static const char* _features_str;
 170 
 171    enum {
 172      CPU_CX8    = (1 << 0), // next bits are from cpuid 1 (EDX)
 173      CPU_CMOV   = (1 << 1),
 174      CPU_FXSR   = (1 << 2),
 175      CPU_HT     = (1 << 3),
 176      CPU_MMX    = (1 << 4),
 177      CPU_3DNOW  = (1 << 5), // 3DNow comes from cpuid 0x80000001 (EDX)
 178      CPU_SSE    = (1 << 6),
 179      CPU_SSE2   = (1 << 7),
 180      CPU_SSE3   = (1 << 8), // SSE3 comes from cpuid 1 (ECX)
 181      CPU_SSSE3  = (1 << 9),
 182      CPU_SSE4A  = (1 << 10),
 183      CPU_SSE4_1 = (1 << 11),
 184      CPU_SSE4_2 = (1 << 12),
 185      CPU_POPCNT = (1 << 13),
 186      CPU_LZCNT  = (1 << 14)
 187    } cpuFeatureFlags;
 188 
 189   // cpuid information block.  All info derived from executing cpuid with
 190   // various function numbers is stored here.  Intel and AMD info is
 191   // merged in this block: accessor methods disentangle it.
 192   //
 193   // The info block is laid out in subblocks of 4 dwords corresponding to
 194   // eax, ebx, ecx and edx, whether or not they contain anything useful.
 195   struct CpuidInfo {
 196     // cpuid function 0
 197     uint32_t std_max_function;
 198     uint32_t std_vendor_name_0;
 199     uint32_t std_vendor_name_1;
 200     uint32_t std_vendor_name_2;
 201 
 202     // cpuid function 1
 203     StdCpuid1Eax std_cpuid1_eax;
 204     StdCpuid1Ebx std_cpuid1_ebx;
 205     StdCpuid1Ecx std_cpuid1_ecx;
 206     StdCpuid1Edx std_cpuid1_edx;


 261   }
 262   static uint logical_processor_count() {
 263     uint result = threads_per_core();
 264     return result;
 265   }
 266   static uint32_t feature_flags() {
 267     uint32_t result = 0;
 268     if (_cpuid_info.std_cpuid1_edx.bits.cmpxchg8 != 0)
 269       result |= CPU_CX8;
 270     if (_cpuid_info.std_cpuid1_edx.bits.cmov != 0)
 271       result |= CPU_CMOV;
 272     if (_cpuid_info.std_cpuid1_edx.bits.fxsr != 0 || is_amd() &&
 273         _cpuid_info.ext_cpuid1_edx.bits.fxsr != 0)
 274       result |= CPU_FXSR;
 275     // HT flag is set for multi-core processors also.
 276     if (threads_per_core() > 1)
 277       result |= CPU_HT;
 278     if (_cpuid_info.std_cpuid1_edx.bits.mmx != 0 || is_amd() &&
 279         _cpuid_info.ext_cpuid1_edx.bits.mmx != 0)
 280       result |= CPU_MMX;


 281     if (_cpuid_info.std_cpuid1_edx.bits.sse != 0)
 282       result |= CPU_SSE;
 283     if (_cpuid_info.std_cpuid1_edx.bits.sse2 != 0)
 284       result |= CPU_SSE2;
 285     if (_cpuid_info.std_cpuid1_ecx.bits.sse3 != 0)
 286       result |= CPU_SSE3;
 287     if (_cpuid_info.std_cpuid1_ecx.bits.ssse3 != 0)
 288       result |= CPU_SSSE3;


 289     if (_cpuid_info.std_cpuid1_ecx.bits.sse4_1 != 0)
 290       result |= CPU_SSE4_1;
 291     if (_cpuid_info.std_cpuid1_ecx.bits.sse4_2 != 0)
 292       result |= CPU_SSE4_2;
 293     if (_cpuid_info.std_cpuid1_ecx.bits.popcnt != 0)
 294       result |= CPU_POPCNT;
 295 
 296     // AMD features.
 297     if (is_amd()) {
 298       if (_cpuid_info.ext_cpuid1_edx.bits.tdnow != 0)
 299         result |= CPU_3DNOW;
 300       if (_cpuid_info.ext_cpuid1_ecx.bits.lzcnt != 0)
 301         result |= CPU_LZCNT;
 302       if (_cpuid_info.ext_cpuid1_ecx.bits.sse4a != 0)
 303         result |= CPU_SSE4A;
 304     }
 305 
 306     return result;
 307   }
 308 
 309   static void get_processor_features();
 310 
 311 public:
 312   // Offsets for cpuid asm stub
 313   static ByteSize std_cpuid0_offset() { return byte_offset_of(CpuidInfo, std_max_function); }
 314   static ByteSize std_cpuid1_offset() { return byte_offset_of(CpuidInfo, std_cpuid1_eax); }
 315   static ByteSize dcp_cpuid4_offset() { return byte_offset_of(CpuidInfo, dcp_cpuid4_eax); }
 316   static ByteSize ext_cpuid1_offset() { return byte_offset_of(CpuidInfo, ext_cpuid1_eax); }
 317   static ByteSize ext_cpuid5_offset() { return byte_offset_of(CpuidInfo, ext_cpuid5_eax); }
 318   static ByteSize ext_cpuid8_offset() { return byte_offset_of(CpuidInfo, ext_cpuid8_eax); }
 319 
 320   // Initialization
 321   static void initialize();
 322 
 323   // Asserts
 324   static void assert_is_initialized() {
 325     assert(_cpuid_info.std_cpuid1_eax.bits.family != 0, "VM_Version not initialized");


 382   //
 383   static bool supports_cpuid()    { return _cpuFeatures  != 0; }
 384   static bool supports_cmpxchg8() { return (_cpuFeatures & CPU_CX8) != 0; }
 385   static bool supports_cmov()     { return (_cpuFeatures & CPU_CMOV) != 0; }
 386   static bool supports_fxsr()     { return (_cpuFeatures & CPU_FXSR) != 0; }
 387   static bool supports_ht()       { return (_cpuFeatures & CPU_HT) != 0; }
 388   static bool supports_mmx()      { return (_cpuFeatures & CPU_MMX) != 0; }
 389   static bool supports_sse()      { return (_cpuFeatures & CPU_SSE) != 0; }
 390   static bool supports_sse2()     { return (_cpuFeatures & CPU_SSE2) != 0; }
 391   static bool supports_sse3()     { return (_cpuFeatures & CPU_SSE3) != 0; }
 392   static bool supports_ssse3()    { return (_cpuFeatures & CPU_SSSE3)!= 0; }
 393   static bool supports_sse4_1()   { return (_cpuFeatures & CPU_SSE4_1) != 0; }
 394   static bool supports_sse4_2()   { return (_cpuFeatures & CPU_SSE4_2) != 0; }
 395   static bool supports_popcnt()   { return (_cpuFeatures & CPU_POPCNT) != 0; }
 396   //
 397   // AMD features
 398   //
 399   static bool supports_3dnow()    { return (_cpuFeatures & CPU_3DNOW) != 0; }
 400   static bool supports_mmx_ext()  { return is_amd() && _cpuid_info.ext_cpuid1_edx.bits.mmx_amd != 0; }
 401   static bool supports_3dnow2()   { return is_amd() && _cpuid_info.ext_cpuid1_edx.bits.tdnow2 != 0; }
 402   static bool supports_lzcnt()    { return (_cpuFeatures & CPU_LZCNT) != 0; }
 403   static bool supports_sse4a()    { return (_cpuFeatures & CPU_SSE4A) != 0; }
 404 
 405   static bool supports_compare_and_exchange() { return true; }
 406 
 407   static const char* cpu_features()           { return _features_str; }
 408 
 409   static intx allocate_prefetch_distance() {
 410     // This method should be called before allocate_prefetch_style().
 411     //
 412     // Hardware prefetching (distance/size in bytes):
 413     // Pentium 3 -  64 /  32
 414     // Pentium 4 - 256 / 128
 415     // Athlon    -  64 /  32 ????
 416     // Opteron   - 128 /  64 only when 2 sequential cache lines accessed
 417     // Core      - 128 /  64
 418     //
 419     // Software prefetching (distance in bytes / instruction with best score):
 420     // Pentium 3 - 128 / prefetchnta
 421     // Pentium 4 - 512 / prefetchnta
 422     // Athlon    - 128 / prefetchnta


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