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() {