comparison src/cpu/x86/vm/vm_version_x86.hpp @ 4768:8940fd98d540

Merge
author kvn
date Thu, 29 Dec 2011 11:37:50 -0800
parents 127b3692c168
children 22cee0ee8927
comparison
equal deleted inserted replaced
4730:7faca6dfa2ed 4768:8940fd98d540
76 dca : 1, 76 dca : 1,
77 sse4_1 : 1, 77 sse4_1 : 1,
78 sse4_2 : 1, 78 sse4_2 : 1,
79 : 2, 79 : 2,
80 popcnt : 1, 80 popcnt : 1,
81 : 8; 81 : 3,
82 osxsave : 1,
83 avx : 1,
84 : 3;
82 } bits; 85 } bits;
83 }; 86 };
84 87
85 union StdCpuid1Edx { 88 union StdCpuid1Edx {
86 uint32_t value; 89 uint32_t value;
174 uint32_t cores_per_cpu : 8, 177 uint32_t cores_per_cpu : 8,
175 : 24; 178 : 24;
176 } bits; 179 } bits;
177 }; 180 };
178 181
182 union SefCpuid7Eax {
183 uint32_t value;
184 };
185
186 union SefCpuid7Ebx {
187 uint32_t value;
188 struct {
189 uint32_t fsgsbase : 1,
190 : 2,
191 bmi1 : 1,
192 : 1,
193 avx2 : 1,
194 : 2,
195 bmi2 : 1,
196 : 23;
197 } bits;
198 };
199
200 union XemXcr0Eax {
201 uint32_t value;
202 struct {
203 uint32_t x87 : 1,
204 sse : 1,
205 ymm : 1,
206 : 29;
207 } bits;
208 };
209
179 protected: 210 protected:
180 static int _cpu; 211 static int _cpu;
181 static int _model; 212 static int _model;
182 static int _stepping; 213 static int _stepping;
183 static int _cpuFeatures; // features returned by the "cpuid" instruction 214 static int _cpuFeatures; // features returned by the "cpuid" instruction
198 CPU_SSSE3 = (1 << 9), 229 CPU_SSSE3 = (1 << 9),
199 CPU_SSE4A = (1 << 10), 230 CPU_SSE4A = (1 << 10),
200 CPU_SSE4_1 = (1 << 11), 231 CPU_SSE4_1 = (1 << 11),
201 CPU_SSE4_2 = (1 << 12), 232 CPU_SSE4_2 = (1 << 12),
202 CPU_POPCNT = (1 << 13), 233 CPU_POPCNT = (1 << 13),
203 CPU_LZCNT = (1 << 14) 234 CPU_LZCNT = (1 << 14),
235 CPU_AVX = (1 << 15),
236 CPU_AVX2 = (1 << 16)
204 } cpuFeatureFlags; 237 } cpuFeatureFlags;
205 238
206 // cpuid information block. All info derived from executing cpuid with 239 // cpuid information block. All info derived from executing cpuid with
207 // various function numbers is stored here. Intel and AMD info is 240 // various function numbers is stored here. Intel and AMD info is
208 // merged in this block: accessor methods disentangle it. 241 // merged in this block: accessor methods disentangle it.
226 DcpCpuid4Eax dcp_cpuid4_eax; 259 DcpCpuid4Eax dcp_cpuid4_eax;
227 DcpCpuid4Ebx dcp_cpuid4_ebx; 260 DcpCpuid4Ebx dcp_cpuid4_ebx;
228 uint32_t dcp_cpuid4_ecx; // unused currently 261 uint32_t dcp_cpuid4_ecx; // unused currently
229 uint32_t dcp_cpuid4_edx; // unused currently 262 uint32_t dcp_cpuid4_edx; // unused currently
230 263
264 // cpuid function 7 (structured extended features)
265 SefCpuid7Eax sef_cpuid7_eax;
266 SefCpuid7Ebx sef_cpuid7_ebx;
267 uint32_t sef_cpuid7_ecx; // unused currently
268 uint32_t sef_cpuid7_edx; // unused currently
269
231 // cpuid function 0xB (processor topology) 270 // cpuid function 0xB (processor topology)
232 // ecx = 0 271 // ecx = 0
233 uint32_t tpl_cpuidB0_eax; 272 uint32_t tpl_cpuidB0_eax;
234 TplCpuidBEbx tpl_cpuidB0_ebx; 273 TplCpuidBEbx tpl_cpuidB0_ebx;
235 uint32_t tpl_cpuidB0_ecx; // unused currently 274 uint32_t tpl_cpuidB0_ecx; // unused currently
273 // cpuid function 0x80000008 312 // cpuid function 0x80000008
274 uint32_t ext_cpuid8_eax; // unused currently 313 uint32_t ext_cpuid8_eax; // unused currently
275 uint32_t ext_cpuid8_ebx; // reserved 314 uint32_t ext_cpuid8_ebx; // reserved
276 ExtCpuid8Ecx ext_cpuid8_ecx; 315 ExtCpuid8Ecx ext_cpuid8_ecx;
277 uint32_t ext_cpuid8_edx; // reserved 316 uint32_t ext_cpuid8_edx; // reserved
317
318 // extended control register XCR0 (the XFEATURE_ENABLED_MASK register)
319 XemXcr0Eax xem_xcr0_eax;
320 uint32_t xem_xcr0_edx; // reserved
278 }; 321 };
279 322
280 // The actual cpuid info block 323 // The actual cpuid info block
281 static CpuidInfo _cpuid_info; 324 static CpuidInfo _cpuid_info;
282 325
326 result |= CPU_SSE4_1; 369 result |= CPU_SSE4_1;
327 if (_cpuid_info.std_cpuid1_ecx.bits.sse4_2 != 0) 370 if (_cpuid_info.std_cpuid1_ecx.bits.sse4_2 != 0)
328 result |= CPU_SSE4_2; 371 result |= CPU_SSE4_2;
329 if (_cpuid_info.std_cpuid1_ecx.bits.popcnt != 0) 372 if (_cpuid_info.std_cpuid1_ecx.bits.popcnt != 0)
330 result |= CPU_POPCNT; 373 result |= CPU_POPCNT;
374 if (_cpuid_info.std_cpuid1_ecx.bits.avx != 0 &&
375 _cpuid_info.std_cpuid1_ecx.bits.osxsave != 0 &&
376 _cpuid_info.xem_xcr0_eax.bits.sse != 0 &&
377 _cpuid_info.xem_xcr0_eax.bits.ymm != 0) {
378 result |= CPU_AVX;
379 if (_cpuid_info.sef_cpuid7_ebx.bits.avx2 != 0)
380 result |= CPU_AVX2;
381 }
331 382
332 // AMD features. 383 // AMD features.
333 if (is_amd()) { 384 if (is_amd()) {
334 if ((_cpuid_info.ext_cpuid1_edx.bits.tdnow != 0) || 385 if ((_cpuid_info.ext_cpuid1_edx.bits.tdnow != 0) ||
335 (_cpuid_info.ext_cpuid1_ecx.bits.prefetchw != 0)) 386 (_cpuid_info.ext_cpuid1_ecx.bits.prefetchw != 0))
348 public: 399 public:
349 // Offsets for cpuid asm stub 400 // Offsets for cpuid asm stub
350 static ByteSize std_cpuid0_offset() { return byte_offset_of(CpuidInfo, std_max_function); } 401 static ByteSize std_cpuid0_offset() { return byte_offset_of(CpuidInfo, std_max_function); }
351 static ByteSize std_cpuid1_offset() { return byte_offset_of(CpuidInfo, std_cpuid1_eax); } 402 static ByteSize std_cpuid1_offset() { return byte_offset_of(CpuidInfo, std_cpuid1_eax); }
352 static ByteSize dcp_cpuid4_offset() { return byte_offset_of(CpuidInfo, dcp_cpuid4_eax); } 403 static ByteSize dcp_cpuid4_offset() { return byte_offset_of(CpuidInfo, dcp_cpuid4_eax); }
404 static ByteSize sef_cpuid7_offset() { return byte_offset_of(CpuidInfo, sef_cpuid7_eax); }
353 static ByteSize ext_cpuid1_offset() { return byte_offset_of(CpuidInfo, ext_cpuid1_eax); } 405 static ByteSize ext_cpuid1_offset() { return byte_offset_of(CpuidInfo, ext_cpuid1_eax); }
354 static ByteSize ext_cpuid5_offset() { return byte_offset_of(CpuidInfo, ext_cpuid5_eax); } 406 static ByteSize ext_cpuid5_offset() { return byte_offset_of(CpuidInfo, ext_cpuid5_eax); }
355 static ByteSize ext_cpuid8_offset() { return byte_offset_of(CpuidInfo, ext_cpuid8_eax); } 407 static ByteSize ext_cpuid8_offset() { return byte_offset_of(CpuidInfo, ext_cpuid8_eax); }
356 static ByteSize tpl_cpuidB0_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB0_eax); } 408 static ByteSize tpl_cpuidB0_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB0_eax); }
357 static ByteSize tpl_cpuidB1_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB1_eax); } 409 static ByteSize tpl_cpuidB1_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB1_eax); }
358 static ByteSize tpl_cpuidB2_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB2_eax); } 410 static ByteSize tpl_cpuidB2_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB2_eax); }
411 static ByteSize xem_xcr0_offset() { return byte_offset_of(CpuidInfo, xem_xcr0_eax); }
359 412
360 // Initialization 413 // Initialization
361 static void initialize(); 414 static void initialize();
362 415
363 // Asserts 416 // Asserts
445 static bool supports_sse3() { return (_cpuFeatures & CPU_SSE3) != 0; } 498 static bool supports_sse3() { return (_cpuFeatures & CPU_SSE3) != 0; }
446 static bool supports_ssse3() { return (_cpuFeatures & CPU_SSSE3)!= 0; } 499 static bool supports_ssse3() { return (_cpuFeatures & CPU_SSSE3)!= 0; }
447 static bool supports_sse4_1() { return (_cpuFeatures & CPU_SSE4_1) != 0; } 500 static bool supports_sse4_1() { return (_cpuFeatures & CPU_SSE4_1) != 0; }
448 static bool supports_sse4_2() { return (_cpuFeatures & CPU_SSE4_2) != 0; } 501 static bool supports_sse4_2() { return (_cpuFeatures & CPU_SSE4_2) != 0; }
449 static bool supports_popcnt() { return (_cpuFeatures & CPU_POPCNT) != 0; } 502 static bool supports_popcnt() { return (_cpuFeatures & CPU_POPCNT) != 0; }
503 static bool supports_avx() { return (_cpuFeatures & CPU_AVX) != 0; }
504 static bool supports_avx2() { return (_cpuFeatures & CPU_AVX2) != 0; }
450 // 505 //
451 // AMD features 506 // AMD features
452 // 507 //
453 static bool supports_3dnow_prefetch() { return (_cpuFeatures & CPU_3DNOW_PREFETCH) != 0; } 508 static bool supports_3dnow_prefetch() { return (_cpuFeatures & CPU_3DNOW_PREFETCH) != 0; }
454 static bool supports_mmx_ext() { return is_amd() && _cpuid_info.ext_cpuid1_edx.bits.mmx_amd != 0; } 509 static bool supports_mmx_ext() { return is_amd() && _cpuid_info.ext_cpuid1_edx.bits.mmx_amd != 0; }