535 // during signal processing. 536 int nreg = 2 LP64_ONLY(+2); 537 retVal = true; 538 for (int i = 0; i < 16 * nreg; i++) { // 64 bytes per zmm register 539 if (_cpuid_info.zmm_save[i] != ymm_test_value()) { 540 retVal = false; 541 break; 542 } 543 } 544 } else if (supports_avx()) { 545 // Verify that OS save/restore all bits of AVX registers 546 // during signal processing. 547 int nreg = 2 LP64_ONLY(+2); 548 retVal = true; 549 for (int i = 0; i < 8 * nreg; i++) { // 32 bytes per ymm register 550 if (_cpuid_info.ymm_save[i] != ymm_test_value()) { 551 retVal = false; 552 break; 553 } 554 } 555 } 556 return retVal; 557 } 558 559 static void get_processor_features(); 560 561 public: 562 // Offsets for cpuid asm stub 563 static ByteSize std_cpuid0_offset() { return byte_offset_of(CpuidInfo, std_max_function); } 564 static ByteSize std_cpuid1_offset() { return byte_offset_of(CpuidInfo, std_cpuid1_eax); } 565 static ByteSize dcp_cpuid4_offset() { return byte_offset_of(CpuidInfo, dcp_cpuid4_eax); } 566 static ByteSize sef_cpuid7_offset() { return byte_offset_of(CpuidInfo, sef_cpuid7_eax); } 567 static ByteSize ext_cpuid1_offset() { return byte_offset_of(CpuidInfo, ext_cpuid1_eax); } 568 static ByteSize ext_cpuid5_offset() { return byte_offset_of(CpuidInfo, ext_cpuid5_eax); } 569 static ByteSize ext_cpuid7_offset() { return byte_offset_of(CpuidInfo, ext_cpuid7_eax); } 570 static ByteSize ext_cpuid8_offset() { return byte_offset_of(CpuidInfo, ext_cpuid8_eax); } 571 static ByteSize tpl_cpuidB0_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB0_eax); } 572 static ByteSize tpl_cpuidB1_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB1_eax); } 573 static ByteSize tpl_cpuidB2_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB2_eax); } 574 static ByteSize xem_xcr0_offset() { return byte_offset_of(CpuidInfo, xem_xcr0_eax); } 689 static bool supports_popcnt() { return (_cpuFeatures & CPU_POPCNT) != 0; } 690 static bool supports_avx() { return (_cpuFeatures & CPU_AVX) != 0; } 691 static bool supports_avx2() { return (_cpuFeatures & CPU_AVX2) != 0; } 692 static bool supports_tsc() { return (_cpuFeatures & CPU_TSC) != 0; } 693 static bool supports_aes() { return (_cpuFeatures & CPU_AES) != 0; } 694 static bool supports_erms() { return (_cpuFeatures & CPU_ERMS) != 0; } 695 static bool supports_clmul() { return (_cpuFeatures & CPU_CLMUL) != 0; } 696 static bool supports_rtm() { return (_cpuFeatures & CPU_RTM) != 0; } 697 static bool supports_bmi1() { return (_cpuFeatures & CPU_BMI1) != 0; } 698 static bool supports_bmi2() { return (_cpuFeatures & CPU_BMI2) != 0; } 699 static bool supports_adx() { return (_cpuFeatures & CPU_ADX) != 0; } 700 static bool supports_evex() { return (_cpuFeatures & CPU_AVX512F) != 0; } 701 static bool supports_avx512dq() { return (_cpuFeatures & CPU_AVX512DQ) != 0; } 702 static bool supports_avx512pf() { return (_cpuFeatures & CPU_AVX512PF) != 0; } 703 static bool supports_avx512er() { return (_cpuFeatures & CPU_AVX512ER) != 0; } 704 static bool supports_avx512cd() { return (_cpuFeatures & CPU_AVX512CD) != 0; } 705 static bool supports_avx512bw() { return (_cpuFeatures & CPU_AVX512BW) != 0; } 706 static bool supports_avx512vl() { return (_cpuFeatures & CPU_AVX512VL) != 0; } 707 static bool supports_avx512vlbw() { return (supports_avx512bw() && supports_avx512vl()); } 708 static bool supports_avx512novl() { return (supports_evex() && !supports_avx512vl()); } 709 // Intel features 710 static bool is_intel_family_core() { return is_intel() && 711 extended_cpu_family() == CPU_FAMILY_INTEL_CORE; } 712 713 static bool is_intel_tsc_synched_at_init() { 714 if (is_intel_family_core()) { 715 uint32_t ext_model = extended_cpu_model(); 716 if (ext_model == CPU_MODEL_NEHALEM_EP || 717 ext_model == CPU_MODEL_WESTMERE_EP || 718 ext_model == CPU_MODEL_SANDYBRIDGE_EP || 719 ext_model == CPU_MODEL_IVYBRIDGE_EP) { 720 // <= 2-socket invariant tsc support. EX versions are usually used 721 // in > 2-socket systems and likely don't synchronize tscs at 722 // initialization. 723 // Code that uses tsc values must be prepared for them to arbitrarily 724 // jump forward or backward. 725 return true; 726 } 727 } 728 return false; | 535 // during signal processing. 536 int nreg = 2 LP64_ONLY(+2); 537 retVal = true; 538 for (int i = 0; i < 16 * nreg; i++) { // 64 bytes per zmm register 539 if (_cpuid_info.zmm_save[i] != ymm_test_value()) { 540 retVal = false; 541 break; 542 } 543 } 544 } else if (supports_avx()) { 545 // Verify that OS save/restore all bits of AVX registers 546 // during signal processing. 547 int nreg = 2 LP64_ONLY(+2); 548 retVal = true; 549 for (int i = 0; i < 8 * nreg; i++) { // 32 bytes per ymm register 550 if (_cpuid_info.ymm_save[i] != ymm_test_value()) { 551 retVal = false; 552 break; 553 } 554 } 555 // zmm_save will be set on a EVEX enabled machine even if we choose AVX code gen 556 if (retVal == false) { 557 // Verify that OS save/restore all bits of EVEX registers 558 // during signal processing. 559 int nreg = 2 LP64_ONLY(+2); 560 retVal = true; 561 for (int i = 0; i < 16 * nreg; i++) { // 64 bytes per zmm register 562 if (_cpuid_info.zmm_save[i] != ymm_test_value()) { 563 retVal = false; 564 break; 565 } 566 } 567 } 568 } 569 return retVal; 570 } 571 572 static void get_processor_features(); 573 574 public: 575 // Offsets for cpuid asm stub 576 static ByteSize std_cpuid0_offset() { return byte_offset_of(CpuidInfo, std_max_function); } 577 static ByteSize std_cpuid1_offset() { return byte_offset_of(CpuidInfo, std_cpuid1_eax); } 578 static ByteSize dcp_cpuid4_offset() { return byte_offset_of(CpuidInfo, dcp_cpuid4_eax); } 579 static ByteSize sef_cpuid7_offset() { return byte_offset_of(CpuidInfo, sef_cpuid7_eax); } 580 static ByteSize ext_cpuid1_offset() { return byte_offset_of(CpuidInfo, ext_cpuid1_eax); } 581 static ByteSize ext_cpuid5_offset() { return byte_offset_of(CpuidInfo, ext_cpuid5_eax); } 582 static ByteSize ext_cpuid7_offset() { return byte_offset_of(CpuidInfo, ext_cpuid7_eax); } 583 static ByteSize ext_cpuid8_offset() { return byte_offset_of(CpuidInfo, ext_cpuid8_eax); } 584 static ByteSize tpl_cpuidB0_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB0_eax); } 585 static ByteSize tpl_cpuidB1_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB1_eax); } 586 static ByteSize tpl_cpuidB2_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB2_eax); } 587 static ByteSize xem_xcr0_offset() { return byte_offset_of(CpuidInfo, xem_xcr0_eax); } 702 static bool supports_popcnt() { return (_cpuFeatures & CPU_POPCNT) != 0; } 703 static bool supports_avx() { return (_cpuFeatures & CPU_AVX) != 0; } 704 static bool supports_avx2() { return (_cpuFeatures & CPU_AVX2) != 0; } 705 static bool supports_tsc() { return (_cpuFeatures & CPU_TSC) != 0; } 706 static bool supports_aes() { return (_cpuFeatures & CPU_AES) != 0; } 707 static bool supports_erms() { return (_cpuFeatures & CPU_ERMS) != 0; } 708 static bool supports_clmul() { return (_cpuFeatures & CPU_CLMUL) != 0; } 709 static bool supports_rtm() { return (_cpuFeatures & CPU_RTM) != 0; } 710 static bool supports_bmi1() { return (_cpuFeatures & CPU_BMI1) != 0; } 711 static bool supports_bmi2() { return (_cpuFeatures & CPU_BMI2) != 0; } 712 static bool supports_adx() { return (_cpuFeatures & CPU_ADX) != 0; } 713 static bool supports_evex() { return (_cpuFeatures & CPU_AVX512F) != 0; } 714 static bool supports_avx512dq() { return (_cpuFeatures & CPU_AVX512DQ) != 0; } 715 static bool supports_avx512pf() { return (_cpuFeatures & CPU_AVX512PF) != 0; } 716 static bool supports_avx512er() { return (_cpuFeatures & CPU_AVX512ER) != 0; } 717 static bool supports_avx512cd() { return (_cpuFeatures & CPU_AVX512CD) != 0; } 718 static bool supports_avx512bw() { return (_cpuFeatures & CPU_AVX512BW) != 0; } 719 static bool supports_avx512vl() { return (_cpuFeatures & CPU_AVX512VL) != 0; } 720 static bool supports_avx512vlbw() { return (supports_avx512bw() && supports_avx512vl()); } 721 static bool supports_avx512novl() { return (supports_evex() && !supports_avx512vl()); } 722 static bool supports_avx512nobw() { return (supports_evex() && !supports_avx512bw()); } 723 static bool supports_avx256only() { return (supports_avx2() && !supports_evex()); } 724 static bool supports_avxonly() { return ((supports_avx2() || supports_avx()) && !supports_evex()); } 725 // Intel features 726 static bool is_intel_family_core() { return is_intel() && 727 extended_cpu_family() == CPU_FAMILY_INTEL_CORE; } 728 729 static bool is_intel_tsc_synched_at_init() { 730 if (is_intel_family_core()) { 731 uint32_t ext_model = extended_cpu_model(); 732 if (ext_model == CPU_MODEL_NEHALEM_EP || 733 ext_model == CPU_MODEL_WESTMERE_EP || 734 ext_model == CPU_MODEL_SANDYBRIDGE_EP || 735 ext_model == CPU_MODEL_IVYBRIDGE_EP) { 736 // <= 2-socket invariant tsc support. EX versions are usually used 737 // in > 2-socket systems and likely don't synchronize tscs at 738 // initialization. 739 // Code that uses tsc values must be prepared for them to arbitrarily 740 // jump forward or backward. 741 return true; 742 } 743 } 744 return false; |