Mercurial > hg > truffle
comparison src/cpu/x86/vm/vm_version_x86.hpp @ 18041:52b4284cb496
Merge with jdk8u20-b26
author | Gilles Duboscq <duboscq@ssw.jku.at> |
---|---|
date | Wed, 15 Oct 2014 16:02:50 +0200 |
parents | eefb0224149d 0118c8c7b80f |
children | 7848fc12602b |
comparison
equal
deleted
inserted
replaced
17606:45d7b2c7029d | 18041:52b4284cb496 |
---|---|
140 union ExtCpuid1Ecx { | 140 union ExtCpuid1Ecx { |
141 uint32_t value; | 141 uint32_t value; |
142 struct { | 142 struct { |
143 uint32_t LahfSahf : 1, | 143 uint32_t LahfSahf : 1, |
144 CmpLegacy : 1, | 144 CmpLegacy : 1, |
145 : 4, | 145 : 3, |
146 lzcnt_intel : 1, | |
146 lzcnt : 1, | 147 lzcnt : 1, |
147 sse4a : 1, | 148 sse4a : 1, |
148 misalignsse : 1, | 149 misalignsse : 1, |
149 prefetchw : 1, | 150 prefetchw : 1, |
150 : 22; | 151 : 22; |
205 : 1, | 206 : 1, |
206 avx2 : 1, | 207 avx2 : 1, |
207 : 2, | 208 : 2, |
208 bmi2 : 1, | 209 bmi2 : 1, |
209 erms : 1, | 210 erms : 1, |
210 : 22; | 211 : 1, |
212 rtm : 1, | |
213 : 20; | |
211 } bits; | 214 } bits; |
212 }; | 215 }; |
213 | 216 |
214 union XemXcr0Eax { | 217 union XemXcr0Eax { |
215 uint32_t value; | 218 uint32_t value; |
226 static int _model; | 229 static int _model; |
227 static int _stepping; | 230 static int _stepping; |
228 static int _cpuFeatures; // features returned by the "cpuid" instruction | 231 static int _cpuFeatures; // features returned by the "cpuid" instruction |
229 // 0 if this instruction is not available | 232 // 0 if this instruction is not available |
230 static const char* _features_str; | 233 static const char* _features_str; |
234 | |
235 static address _cpuinfo_segv_addr; // address of instruction which causes SEGV | |
236 static address _cpuinfo_cont_addr; // address of instruction after the one which causes SEGV | |
231 | 237 |
232 enum { | 238 enum { |
233 CPU_CX8 = (1 << 0), // next bits are from cpuid 1 (EDX) | 239 CPU_CX8 = (1 << 0), // next bits are from cpuid 1 (EDX) |
234 CPU_CMOV = (1 << 1), | 240 CPU_CMOV = (1 << 1), |
235 CPU_FXSR = (1 << 2), | 241 CPU_FXSR = (1 << 2), |
250 CPU_TSCINV = (1 << 16), | 256 CPU_TSCINV = (1 << 16), |
251 CPU_AVX = (1 << 17), | 257 CPU_AVX = (1 << 17), |
252 CPU_AVX2 = (1 << 18), | 258 CPU_AVX2 = (1 << 18), |
253 CPU_AES = (1 << 19), | 259 CPU_AES = (1 << 19), |
254 CPU_ERMS = (1 << 20), // enhanced 'rep movsb/stosb' instructions | 260 CPU_ERMS = (1 << 20), // enhanced 'rep movsb/stosb' instructions |
255 CPU_CLMUL = (1 << 21) // carryless multiply for CRC | 261 CPU_CLMUL = (1 << 21), // carryless multiply for CRC |
262 CPU_BMI1 = (1 << 22), | |
263 CPU_BMI2 = (1 << 23), | |
264 CPU_RTM = (1 << 24) // Restricted Transactional Memory instructions | |
256 } cpuFeatureFlags; | 265 } cpuFeatureFlags; |
257 | 266 |
258 enum { | 267 enum { |
259 // AMD | 268 // AMD |
260 CPU_FAMILY_AMD_11H = 0x11, | 269 CPU_FAMILY_AMD_11H = 0x11, |
357 uint32_t ext_cpuid8_edx; // reserved | 366 uint32_t ext_cpuid8_edx; // reserved |
358 | 367 |
359 // extended control register XCR0 (the XFEATURE_ENABLED_MASK register) | 368 // extended control register XCR0 (the XFEATURE_ENABLED_MASK register) |
360 XemXcr0Eax xem_xcr0_eax; | 369 XemXcr0Eax xem_xcr0_eax; |
361 uint32_t xem_xcr0_edx; // reserved | 370 uint32_t xem_xcr0_edx; // reserved |
371 | |
372 // Space to save ymm registers after signal handle | |
373 int ymm_save[8*4]; // Save ymm0, ymm7, ymm8, ymm15 | |
362 }; | 374 }; |
363 | 375 |
364 // The actual cpuid info block | 376 // The actual cpuid info block |
365 static CpuidInfo _cpuid_info; | 377 static CpuidInfo _cpuid_info; |
366 | 378 |
422 _cpuid_info.xem_xcr0_eax.bits.ymm != 0) { | 434 _cpuid_info.xem_xcr0_eax.bits.ymm != 0) { |
423 result |= CPU_AVX; | 435 result |= CPU_AVX; |
424 if (_cpuid_info.sef_cpuid7_ebx.bits.avx2 != 0) | 436 if (_cpuid_info.sef_cpuid7_ebx.bits.avx2 != 0) |
425 result |= CPU_AVX2; | 437 result |= CPU_AVX2; |
426 } | 438 } |
439 if(_cpuid_info.sef_cpuid7_ebx.bits.bmi1 != 0) | |
440 result |= CPU_BMI1; | |
427 if (_cpuid_info.std_cpuid1_edx.bits.tsc != 0) | 441 if (_cpuid_info.std_cpuid1_edx.bits.tsc != 0) |
428 result |= CPU_TSC; | 442 result |= CPU_TSC; |
429 if (_cpuid_info.ext_cpuid7_edx.bits.tsc_invariance != 0) | 443 if (_cpuid_info.ext_cpuid7_edx.bits.tsc_invariance != 0) |
430 result |= CPU_TSCINV; | 444 result |= CPU_TSCINV; |
431 if (_cpuid_info.std_cpuid1_ecx.bits.aes != 0) | 445 if (_cpuid_info.std_cpuid1_ecx.bits.aes != 0) |
432 result |= CPU_AES; | 446 result |= CPU_AES; |
433 if (_cpuid_info.sef_cpuid7_ebx.bits.erms != 0) | 447 if (_cpuid_info.sef_cpuid7_ebx.bits.erms != 0) |
434 result |= CPU_ERMS; | 448 result |= CPU_ERMS; |
435 if (_cpuid_info.std_cpuid1_ecx.bits.clmul != 0) | 449 if (_cpuid_info.std_cpuid1_ecx.bits.clmul != 0) |
436 result |= CPU_CLMUL; | 450 result |= CPU_CLMUL; |
451 if (_cpuid_info.sef_cpuid7_ebx.bits.rtm != 0) | |
452 result |= CPU_RTM; | |
437 | 453 |
438 // AMD features. | 454 // AMD features. |
439 if (is_amd()) { | 455 if (is_amd()) { |
440 if ((_cpuid_info.ext_cpuid1_edx.bits.tdnow != 0) || | 456 if ((_cpuid_info.ext_cpuid1_edx.bits.tdnow != 0) || |
441 (_cpuid_info.ext_cpuid1_ecx.bits.prefetchw != 0)) | 457 (_cpuid_info.ext_cpuid1_ecx.bits.prefetchw != 0)) |
443 if (_cpuid_info.ext_cpuid1_ecx.bits.lzcnt != 0) | 459 if (_cpuid_info.ext_cpuid1_ecx.bits.lzcnt != 0) |
444 result |= CPU_LZCNT; | 460 result |= CPU_LZCNT; |
445 if (_cpuid_info.ext_cpuid1_ecx.bits.sse4a != 0) | 461 if (_cpuid_info.ext_cpuid1_ecx.bits.sse4a != 0) |
446 result |= CPU_SSE4A; | 462 result |= CPU_SSE4A; |
447 } | 463 } |
464 // Intel features. | |
465 if(is_intel()) { | |
466 if(_cpuid_info.sef_cpuid7_ebx.bits.bmi2 != 0) | |
467 result |= CPU_BMI2; | |
468 if(_cpuid_info.ext_cpuid1_ecx.bits.lzcnt_intel != 0) | |
469 result |= CPU_LZCNT; | |
470 } | |
448 | 471 |
449 return result; | 472 return result; |
473 } | |
474 | |
475 static bool os_supports_avx_vectors() { | |
476 if (!supports_avx()) { | |
477 return false; | |
478 } | |
479 // Verify that OS save/restore all bits of AVX registers | |
480 // during signal processing. | |
481 int nreg = 2 LP64_ONLY(+2); | |
482 for (int i = 0; i < 8 * nreg; i++) { // 32 bytes per ymm register | |
483 if (_cpuid_info.ymm_save[i] != ymm_test_value()) { | |
484 return false; | |
485 } | |
486 } | |
487 return true; | |
450 } | 488 } |
451 | 489 |
452 static void get_processor_features(); | 490 static void get_processor_features(); |
453 | 491 |
454 public: | 492 public: |
463 static ByteSize ext_cpuid8_offset() { return byte_offset_of(CpuidInfo, ext_cpuid8_eax); } | 501 static ByteSize ext_cpuid8_offset() { return byte_offset_of(CpuidInfo, ext_cpuid8_eax); } |
464 static ByteSize tpl_cpuidB0_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB0_eax); } | 502 static ByteSize tpl_cpuidB0_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB0_eax); } |
465 static ByteSize tpl_cpuidB1_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB1_eax); } | 503 static ByteSize tpl_cpuidB1_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB1_eax); } |
466 static ByteSize tpl_cpuidB2_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB2_eax); } | 504 static ByteSize tpl_cpuidB2_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB2_eax); } |
467 static ByteSize xem_xcr0_offset() { return byte_offset_of(CpuidInfo, xem_xcr0_eax); } | 505 static ByteSize xem_xcr0_offset() { return byte_offset_of(CpuidInfo, xem_xcr0_eax); } |
506 static ByteSize ymm_save_offset() { return byte_offset_of(CpuidInfo, ymm_save); } | |
507 | |
508 // The value used to check ymm register after signal handle | |
509 static int ymm_test_value() { return 0xCAFEBABE; } | |
510 | |
511 static void get_cpu_info_wrapper(); | |
512 static void set_cpuinfo_segv_addr(address pc) { _cpuinfo_segv_addr = pc; } | |
513 static bool is_cpuinfo_segv_addr(address pc) { return _cpuinfo_segv_addr == pc; } | |
514 static void set_cpuinfo_cont_addr(address pc) { _cpuinfo_cont_addr = pc; } | |
515 static address cpuinfo_cont_addr() { return _cpuinfo_cont_addr; } | |
516 | |
517 static void clean_cpuFeatures() { _cpuFeatures = 0; } | |
518 static void set_avx_cpuFeatures() { _cpuFeatures = (CPU_SSE | CPU_SSE2 | CPU_AVX); } | |
519 | |
468 | 520 |
469 // Initialization | 521 // Initialization |
470 static void initialize(); | 522 static void initialize(); |
523 | |
524 // Override Abstract_VM_Version implementation | |
525 static bool use_biased_locking(); | |
471 | 526 |
472 // Asserts | 527 // Asserts |
473 static void assert_is_initialized() { | 528 static void assert_is_initialized() { |
474 assert(_cpuid_info.std_cpuid1_eax.bits.family != 0, "VM_Version not initialized"); | 529 assert(_cpuid_info.std_cpuid1_eax.bits.family != 0, "VM_Version not initialized"); |
475 } | 530 } |
559 static bool supports_avx2() { return (_cpuFeatures & CPU_AVX2) != 0; } | 614 static bool supports_avx2() { return (_cpuFeatures & CPU_AVX2) != 0; } |
560 static bool supports_tsc() { return (_cpuFeatures & CPU_TSC) != 0; } | 615 static bool supports_tsc() { return (_cpuFeatures & CPU_TSC) != 0; } |
561 static bool supports_aes() { return (_cpuFeatures & CPU_AES) != 0; } | 616 static bool supports_aes() { return (_cpuFeatures & CPU_AES) != 0; } |
562 static bool supports_erms() { return (_cpuFeatures & CPU_ERMS) != 0; } | 617 static bool supports_erms() { return (_cpuFeatures & CPU_ERMS) != 0; } |
563 static bool supports_clmul() { return (_cpuFeatures & CPU_CLMUL) != 0; } | 618 static bool supports_clmul() { return (_cpuFeatures & CPU_CLMUL) != 0; } |
564 | 619 static bool supports_rtm() { return (_cpuFeatures & CPU_RTM) != 0; } |
620 static bool supports_bmi1() { return (_cpuFeatures & CPU_BMI1) != 0; } | |
621 static bool supports_bmi2() { return (_cpuFeatures & CPU_BMI2) != 0; } | |
565 // Intel features | 622 // Intel features |
566 static bool is_intel_family_core() { return is_intel() && | 623 static bool is_intel_family_core() { return is_intel() && |
567 extended_cpu_family() == CPU_FAMILY_INTEL_CORE; } | 624 extended_cpu_family() == CPU_FAMILY_INTEL_CORE; } |
568 | 625 |
569 static bool is_intel_tsc_synched_at_init() { | 626 static bool is_intel_tsc_synched_at_init() { |