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

src/cpu/x86/vm/vm_version_x86_32.hpp

Print this page




  51     } bits;
  52   };
  53 
  54   union StdCpuid1Ecx {
  55     uint32_t value;
  56     struct {
  57       uint32_t sse3     : 1,
  58                         : 2,
  59                monitor  : 1,
  60                         : 1,
  61                vmx      : 1,
  62                         : 1,
  63                est      : 1,
  64                         : 1,
  65                ssse3    : 1,
  66                cid      : 1,
  67                         : 2,
  68                cmpxchg16: 1,
  69                         : 4,
  70                dca      : 1,
  71                         : 4,
  72                popcnt   : 1,
  73                         : 8;
  74     } bits;
  75   };
  76 
  77   union StdCpuid1Edx {
  78     uint32_t value;
  79     struct {
  80       uint32_t          : 4,
  81                tsc      : 1,
  82                         : 3,
  83                cmpxchg8 : 1,
  84                         : 6,
  85                cmov     : 1,
  86                         : 7,
  87                mmx      : 1,
  88                fxsr     : 1,
  89                sse      : 1,
  90                sse2     : 1,
  91                         : 1,
  92                ht       : 1,
  93                         : 3;


 160 
 161 protected:
 162    static int _cpu;
 163    static int _model;
 164    static int _stepping;
 165    static int _cpuFeatures;     // features returned by the "cpuid" instruction
 166                                 // 0 if this instruction is not available
 167    static const char* _features_str;
 168 
 169    enum {
 170      CPU_CX8  = (1 << 0), // next bits are from cpuid 1 (EDX)
 171      CPU_CMOV = (1 << 1),
 172      CPU_FXSR = (1 << 2),
 173      CPU_HT   = (1 << 3),
 174      CPU_MMX  = (1 << 4),
 175      CPU_3DNOW= (1 << 5), // 3DNow comes from cpuid 0x80000001 (EDX)
 176      CPU_SSE  = (1 << 6),
 177      CPU_SSE2 = (1 << 7),
 178      CPU_SSE3 = (1 << 8), // sse3  comes from cpuid 1 (ECX)
 179      CPU_SSSE3= (1 << 9),
 180      CPU_SSE4 = (1 <<10),
 181      CPU_SSE4A= (1 <<11)

 182    } cpuFeatureFlags;
 183 
 184   // cpuid information block.  All info derived from executing cpuid with
 185   // various function numbers is stored here.  Intel and AMD info is
 186   // merged in this block: accessor methods disentangle it.
 187   //
 188   // The info block is laid out in subblocks of 4 dwords corresponding to
 189   // rax, rbx, rcx and rdx, whether or not they contain anything useful.
 190   struct CpuidInfo {
 191     // cpuid function 0
 192     uint32_t std_max_function;
 193     uint32_t std_vendor_name_0;
 194     uint32_t std_vendor_name_1;
 195     uint32_t std_vendor_name_2;
 196 
 197     // cpuid function 1
 198     StdCpuid1Eax std_cpuid1_rax;
 199     StdCpuid1Ebx std_cpuid1_rbx;
 200     StdCpuid1Ecx std_cpuid1_rcx;
 201     StdCpuid1Edx std_cpuid1_rdx;


 223     uint32_t proc_name_4, proc_name_5, proc_name_6, proc_name_7;
 224     uint32_t proc_name_8, proc_name_9, proc_name_10,proc_name_11;
 225 
 226     // cpuid function 0x80000005 //AMD L1, Intel reserved
 227     uint32_t     ext_cpuid5_rax; // unused currently
 228     uint32_t     ext_cpuid5_rbx; // reserved
 229     ExtCpuid5Ex  ext_cpuid5_rcx; // L1 data cache info (AMD)
 230     ExtCpuid5Ex  ext_cpuid5_rdx; // L1 instruction cache info (AMD)
 231 
 232     // cpuid function 0x80000008
 233     uint32_t     ext_cpuid8_rax; // unused currently
 234     uint32_t     ext_cpuid8_rbx; // reserved
 235     ExtCpuid8Ecx ext_cpuid8_rcx;
 236     uint32_t     ext_cpuid8_rdx; // reserved
 237   };
 238 
 239   // The actual cpuid info block
 240   static CpuidInfo _cpuid_info;
 241 
 242   // Extractors and predicates
 243   static bool is_extended_cpu_family() {
 244     const uint32_t Extended_Cpu_Family = 0xf;
 245     return _cpuid_info.std_cpuid1_rax.bits.family == Extended_Cpu_Family;
 246   }
 247   static uint32_t extended_cpu_family() {
 248     uint32_t result = _cpuid_info.std_cpuid1_rax.bits.family;
 249     if (is_extended_cpu_family()) {
 250       result += _cpuid_info.std_cpuid1_rax.bits.ext_family;
 251     }
 252     return result;
 253   }
 254   static uint32_t extended_cpu_model() {
 255     uint32_t result = _cpuid_info.std_cpuid1_rax.bits.model;
 256     if (is_extended_cpu_family()) {
 257       result |= _cpuid_info.std_cpuid1_rax.bits.ext_model << 4;
 258     }
 259     return result;
 260   }
 261   static uint32_t cpu_stepping() {
 262     uint32_t result = _cpuid_info.std_cpuid1_rax.bits.stepping;
 263     return result;
 264   }
 265   static uint logical_processor_count() {
 266     uint result = threads_per_core();
 267     return result;
 268   }
 269   static uint32_t feature_flags() {
 270     uint32_t result = 0;
 271     if (_cpuid_info.std_cpuid1_rdx.bits.cmpxchg8 != 0)
 272       result |= CPU_CX8;
 273     if (_cpuid_info.std_cpuid1_rdx.bits.cmov != 0)
 274       result |= CPU_CMOV;
 275     if (_cpuid_info.std_cpuid1_rdx.bits.fxsr != 0 || is_amd() &&
 276         _cpuid_info.ext_cpuid1_rdx.bits.fxsr != 0)
 277       result |= CPU_FXSR;
 278     // HT flag is set for multi-core processors also.
 279     if (threads_per_core() > 1)
 280       result |= CPU_HT;
 281     if (_cpuid_info.std_cpuid1_rdx.bits.mmx != 0 || is_amd() &&
 282         _cpuid_info.ext_cpuid1_rdx.bits.mmx != 0)
 283       result |= CPU_MMX;
 284     if (is_amd() && _cpuid_info.ext_cpuid1_rdx.bits.tdnow != 0)
 285       result |= CPU_3DNOW;
 286     if (_cpuid_info.std_cpuid1_rdx.bits.sse != 0)
 287       result |= CPU_SSE;
 288     if (_cpuid_info.std_cpuid1_rdx.bits.sse2 != 0)
 289       result |= CPU_SSE2;
 290     if (_cpuid_info.std_cpuid1_rcx.bits.sse3 != 0)
 291       result |= CPU_SSE3;
 292     if (_cpuid_info.std_cpuid1_rcx.bits.ssse3 != 0)
 293       result |= CPU_SSSE3;
 294     if (is_amd() && _cpuid_info.ext_cpuid1_rcx.bits.sse4a != 0)
 295       result |= CPU_SSE4A;




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


 363       result = _cpuid_info.ext_cpuid5_rcx.bits.L1_line_size;
 364     }
 365     if (result < 32) // not defined ?
 366       result = 32;   // 32 bytes by default on x86
 367     return result;
 368   }
 369 
 370   //
 371   // Feature identification
 372   //
 373   static bool supports_cpuid()    { return _cpuFeatures  != 0; }
 374   static bool supports_cmpxchg8() { return (_cpuFeatures & CPU_CX8) != 0; }
 375   static bool supports_cmov()     { return (_cpuFeatures & CPU_CMOV) != 0; }
 376   static bool supports_fxsr()     { return (_cpuFeatures & CPU_FXSR) != 0; }
 377   static bool supports_ht()       { return (_cpuFeatures & CPU_HT) != 0; }
 378   static bool supports_mmx()      { return (_cpuFeatures & CPU_MMX) != 0; }
 379   static bool supports_sse()      { return (_cpuFeatures & CPU_SSE) != 0; }
 380   static bool supports_sse2()     { return (_cpuFeatures & CPU_SSE2) != 0; }
 381   static bool supports_sse3()     { return (_cpuFeatures & CPU_SSE3) != 0; }
 382   static bool supports_ssse3()    { return (_cpuFeatures & CPU_SSSE3)!= 0; }
 383   static bool supports_sse4()     { return (_cpuFeatures & CPU_SSE4) != 0; }

 384   //
 385   // AMD features
 386   //
 387   static bool supports_3dnow()    { return (_cpuFeatures & CPU_3DNOW) != 0; }
 388   static bool supports_mmx_ext()  { return is_amd() && _cpuid_info.ext_cpuid1_rdx.bits.mmx_amd != 0; }
 389   static bool supports_3dnow2()   { return is_amd() && _cpuid_info.ext_cpuid1_rdx.bits.tdnow2 != 0; }
 390   static bool supports_sse4a()    { return (_cpuFeatures & CPU_SSE4A) != 0; }
 391 
 392   static bool supports_compare_and_exchange() { return true; }
 393 
 394   static const char* cpu_features()           { return _features_str; }
 395 
 396   static intx allocate_prefetch_distance() {
 397     // This method should be called before allocate_prefetch_style().
 398     //
 399     // Hardware prefetching (distance/size in bytes):
 400     // Pentium 3 -  64 /  32
 401     // Pentium 4 - 256 / 128
 402     // Athlon    -  64 /  32 ????
 403     // Opteron   - 128 /  64 only when 2 sequential cache lines accessed




  51     } bits;
  52   };
  53 
  54   union StdCpuid1Ecx {
  55     uint32_t value;
  56     struct {
  57       uint32_t sse3     : 1,
  58                         : 2,
  59                monitor  : 1,
  60                         : 1,
  61                vmx      : 1,
  62                         : 1,
  63                est      : 1,
  64                         : 1,
  65                ssse3    : 1,
  66                cid      : 1,
  67                         : 2,
  68                cmpxchg16: 1,
  69                         : 4,
  70                dca      : 1,
  71                sse4_1   : 1,
  72                sse4_2   : 1,
  73                         : 11;
  74     } bits;
  75   };
  76 
  77   union StdCpuid1Edx {
  78     uint32_t value;
  79     struct {
  80       uint32_t          : 4,
  81                tsc      : 1,
  82                         : 3,
  83                cmpxchg8 : 1,
  84                         : 6,
  85                cmov     : 1,
  86                         : 7,
  87                mmx      : 1,
  88                fxsr     : 1,
  89                sse      : 1,
  90                sse2     : 1,
  91                         : 1,
  92                ht       : 1,
  93                         : 3;


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


 224     uint32_t proc_name_4, proc_name_5, proc_name_6, proc_name_7;
 225     uint32_t proc_name_8, proc_name_9, proc_name_10,proc_name_11;
 226 
 227     // cpuid function 0x80000005 //AMD L1, Intel reserved
 228     uint32_t     ext_cpuid5_rax; // unused currently
 229     uint32_t     ext_cpuid5_rbx; // reserved
 230     ExtCpuid5Ex  ext_cpuid5_rcx; // L1 data cache info (AMD)
 231     ExtCpuid5Ex  ext_cpuid5_rdx; // L1 instruction cache info (AMD)
 232 
 233     // cpuid function 0x80000008
 234     uint32_t     ext_cpuid8_rax; // unused currently
 235     uint32_t     ext_cpuid8_rbx; // reserved
 236     ExtCpuid8Ecx ext_cpuid8_rcx;
 237     uint32_t     ext_cpuid8_rdx; // reserved
 238   };
 239 
 240   // The actual cpuid info block
 241   static CpuidInfo _cpuid_info;
 242 
 243   // Extractors and predicates




 244   static uint32_t extended_cpu_family() {
 245     uint32_t result = _cpuid_info.std_cpuid1_rax.bits.family;

 246     result += _cpuid_info.std_cpuid1_rax.bits.ext_family;

 247     return result;
 248   }
 249   static uint32_t extended_cpu_model() {
 250     uint32_t result = _cpuid_info.std_cpuid1_rax.bits.model;

 251     result |= _cpuid_info.std_cpuid1_rax.bits.ext_model << 4;

 252     return result;
 253   }
 254   static uint32_t cpu_stepping() {
 255     uint32_t result = _cpuid_info.std_cpuid1_rax.bits.stepping;
 256     return result;
 257   }
 258   static uint logical_processor_count() {
 259     uint result = threads_per_core();
 260     return result;
 261   }
 262   static uint32_t feature_flags() {
 263     uint32_t result = 0;
 264     if (_cpuid_info.std_cpuid1_rdx.bits.cmpxchg8 != 0)
 265       result |= CPU_CX8;
 266     if (_cpuid_info.std_cpuid1_rdx.bits.cmov != 0)
 267       result |= CPU_CMOV;
 268     if (_cpuid_info.std_cpuid1_rdx.bits.fxsr != 0 || is_amd() &&
 269         _cpuid_info.ext_cpuid1_rdx.bits.fxsr != 0)
 270       result |= CPU_FXSR;
 271     // HT flag is set for multi-core processors also.
 272     if (threads_per_core() > 1)
 273       result |= CPU_HT;
 274     if (_cpuid_info.std_cpuid1_rdx.bits.mmx != 0 || is_amd() &&
 275         _cpuid_info.ext_cpuid1_rdx.bits.mmx != 0)
 276       result |= CPU_MMX;
 277     if (is_amd() && _cpuid_info.ext_cpuid1_rdx.bits.tdnow != 0)
 278       result |= CPU_3DNOW;
 279     if (_cpuid_info.std_cpuid1_rdx.bits.sse != 0)
 280       result |= CPU_SSE;
 281     if (_cpuid_info.std_cpuid1_rdx.bits.sse2 != 0)
 282       result |= CPU_SSE2;
 283     if (_cpuid_info.std_cpuid1_rcx.bits.sse3 != 0)
 284       result |= CPU_SSE3;
 285     if (_cpuid_info.std_cpuid1_rcx.bits.ssse3 != 0)
 286       result |= CPU_SSSE3;
 287     if (is_amd() && _cpuid_info.ext_cpuid1_rcx.bits.sse4a != 0)
 288       result |= CPU_SSE4A;
 289     if (_cpuid_info.std_cpuid1_rcx.bits.sse4_1 != 0)
 290       result |= CPU_SSE4_1;
 291     if (_cpuid_info.std_cpuid1_rcx.bits.sse4_2 != 0)
 292       result |= CPU_SSE4_2;
 293     return result;
 294   }
 295 
 296   static void get_processor_features();
 297 
 298 public:
 299   // Offsets for cpuid asm stub
 300   static ByteSize std_cpuid0_offset() { return byte_offset_of(CpuidInfo, std_max_function); }
 301   static ByteSize std_cpuid1_offset() { return byte_offset_of(CpuidInfo, std_cpuid1_rax); }
 302   static ByteSize dcp_cpuid4_offset() { return byte_offset_of(CpuidInfo, dcp_cpuid4_rax); }
 303   static ByteSize ext_cpuid1_offset() { return byte_offset_of(CpuidInfo, ext_cpuid1_rax); }
 304   static ByteSize ext_cpuid5_offset() { return byte_offset_of(CpuidInfo, ext_cpuid5_rax); }
 305   static ByteSize ext_cpuid8_offset() { return byte_offset_of(CpuidInfo, ext_cpuid8_rax); }
 306 
 307   // Initialization
 308   static void initialize();
 309 
 310   // Asserts
 311   static void assert_is_initialized() {
 312     assert(_cpuid_info.std_cpuid1_rax.bits.family != 0, "VM_Version not initialized");


 360       result = _cpuid_info.ext_cpuid5_rcx.bits.L1_line_size;
 361     }
 362     if (result < 32) // not defined ?
 363       result = 32;   // 32 bytes by default on x86
 364     return result;
 365   }
 366 
 367   //
 368   // Feature identification
 369   //
 370   static bool supports_cpuid()    { return _cpuFeatures  != 0; }
 371   static bool supports_cmpxchg8() { return (_cpuFeatures & CPU_CX8) != 0; }
 372   static bool supports_cmov()     { return (_cpuFeatures & CPU_CMOV) != 0; }
 373   static bool supports_fxsr()     { return (_cpuFeatures & CPU_FXSR) != 0; }
 374   static bool supports_ht()       { return (_cpuFeatures & CPU_HT) != 0; }
 375   static bool supports_mmx()      { return (_cpuFeatures & CPU_MMX) != 0; }
 376   static bool supports_sse()      { return (_cpuFeatures & CPU_SSE) != 0; }
 377   static bool supports_sse2()     { return (_cpuFeatures & CPU_SSE2) != 0; }
 378   static bool supports_sse3()     { return (_cpuFeatures & CPU_SSE3) != 0; }
 379   static bool supports_ssse3()    { return (_cpuFeatures & CPU_SSSE3)!= 0; }
 380   static bool supports_sse4_1()   { return (_cpuFeatures & CPU_SSE4_1) != 0; }
 381   static bool supports_sse4_2()   { return (_cpuFeatures & CPU_SSE4_2) != 0; }
 382   //
 383   // AMD features
 384   //
 385   static bool supports_3dnow()    { return (_cpuFeatures & CPU_3DNOW) != 0; }
 386   static bool supports_mmx_ext()  { return is_amd() && _cpuid_info.ext_cpuid1_rdx.bits.mmx_amd != 0; }
 387   static bool supports_3dnow2()   { return is_amd() && _cpuid_info.ext_cpuid1_rdx.bits.tdnow2 != 0; }
 388   static bool supports_sse4a()    { return (_cpuFeatures & CPU_SSE4A) != 0; }
 389 
 390   static bool supports_compare_and_exchange() { return true; }
 391 
 392   static const char* cpu_features()           { return _features_str; }
 393 
 394   static intx allocate_prefetch_distance() {
 395     // This method should be called before allocate_prefetch_style().
 396     //
 397     // Hardware prefetching (distance/size in bytes):
 398     // Pentium 3 -  64 /  32
 399     // Pentium 4 - 256 / 128
 400     // Athlon    -  64 /  32 ????
 401     // Opteron   - 128 /  64 only when 2 sequential cache lines accessed


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