1 /* |
1 /* |
2 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
303 #define CPU_VZEROUPPER ((uint64_t)UCONST64(0x1000000000)) // Vzeroupper instruction |
303 #define CPU_VZEROUPPER ((uint64_t)UCONST64(0x1000000000)) // Vzeroupper instruction |
304 |
304 |
305 enum Extended_Family { |
305 enum Extended_Family { |
306 // AMD |
306 // AMD |
307 CPU_FAMILY_AMD_11H = 0x11, |
307 CPU_FAMILY_AMD_11H = 0x11, |
|
308 // ZX |
|
309 CPU_FAMILY_ZX_CORE_F6 = 6, |
|
310 CPU_FAMILY_ZX_CORE_F7 = 7, |
308 // Intel |
311 // Intel |
309 CPU_FAMILY_INTEL_CORE = 6, |
312 CPU_FAMILY_INTEL_CORE = 6, |
310 CPU_MODEL_NEHALEM = 0x1e, |
313 CPU_MODEL_NEHALEM = 0x1e, |
311 CPU_MODEL_NEHALEM_EP = 0x1a, |
314 CPU_MODEL_NEHALEM_EP = 0x1a, |
312 CPU_MODEL_NEHALEM_EX = 0x2e, |
315 CPU_MODEL_NEHALEM_EX = 0x2e, |
547 if (_cpuid_info.ext_cpuid1_ecx.bits.misalignsse != 0) { |
550 if (_cpuid_info.ext_cpuid1_ecx.bits.misalignsse != 0) { |
548 result |= CPU_3DNOW_PREFETCH; |
551 result |= CPU_3DNOW_PREFETCH; |
549 } |
552 } |
550 } |
553 } |
551 |
554 |
|
555 // ZX features. |
|
556 if (is_zx()) { |
|
557 if (_cpuid_info.ext_cpuid1_ecx.bits.lzcnt_intel != 0) |
|
558 result |= CPU_LZCNT; |
|
559 // for ZX, ecx.bits.misalignsse bit (bit 8) indicates support for prefetchw |
|
560 if (_cpuid_info.ext_cpuid1_ecx.bits.misalignsse != 0) { |
|
561 result |= CPU_3DNOW_PREFETCH; |
|
562 } |
|
563 } |
|
564 |
552 return result; |
565 return result; |
553 } |
566 } |
554 |
567 |
555 static bool os_supports_avx_vectors() { |
568 static bool os_supports_avx_vectors() { |
556 bool retVal = false; |
569 bool retVal = false; |
655 // |
668 // |
656 static int cpu_family() { return _cpu;} |
669 static int cpu_family() { return _cpu;} |
657 static bool is_P6() { return cpu_family() >= 6; } |
670 static bool is_P6() { return cpu_family() >= 6; } |
658 static bool is_amd() { assert_is_initialized(); return _cpuid_info.std_vendor_name_0 == 0x68747541; } // 'htuA' |
671 static bool is_amd() { assert_is_initialized(); return _cpuid_info.std_vendor_name_0 == 0x68747541; } // 'htuA' |
659 static bool is_intel() { assert_is_initialized(); return _cpuid_info.std_vendor_name_0 == 0x756e6547; } // 'uneG' |
672 static bool is_intel() { assert_is_initialized(); return _cpuid_info.std_vendor_name_0 == 0x756e6547; } // 'uneG' |
|
673 static bool is_zx() { assert_is_initialized(); return (_cpuid_info.std_vendor_name_0 == 0x746e6543) || (_cpuid_info.std_vendor_name_0 == 0x68532020); } // 'tneC'||'hS ' |
660 static bool is_atom_family() { return ((cpu_family() == 0x06) && ((extended_cpu_model() == 0x36) || (extended_cpu_model() == 0x37) || (extended_cpu_model() == 0x4D))); } //Silvermont and Centerton |
674 static bool is_atom_family() { return ((cpu_family() == 0x06) && ((extended_cpu_model() == 0x36) || (extended_cpu_model() == 0x37) || (extended_cpu_model() == 0x4D))); } //Silvermont and Centerton |
661 static bool is_knights_family() { return ((cpu_family() == 0x06) && ((extended_cpu_model() == 0x57) || (extended_cpu_model() == 0x85))); } // Xeon Phi 3200/5200/7200 and Future Xeon Phi |
675 static bool is_knights_family() { return ((cpu_family() == 0x06) && ((extended_cpu_model() == 0x57) || (extended_cpu_model() == 0x85))); } // Xeon Phi 3200/5200/7200 and Future Xeon Phi |
662 |
676 |
663 static bool supports_processor_topology() { |
677 static bool supports_processor_topology() { |
664 return (_cpuid_info.std_max_function >= 0xB) && |
678 return (_cpuid_info.std_max_function >= 0xB) && |
678 if (!supports_topology || result == 0) { |
692 if (!supports_topology || result == 0) { |
679 result = (_cpuid_info.dcp_cpuid4_eax.bits.cores_per_cpu + 1); |
693 result = (_cpuid_info.dcp_cpuid4_eax.bits.cores_per_cpu + 1); |
680 } |
694 } |
681 } else if (is_amd()) { |
695 } else if (is_amd()) { |
682 result = (_cpuid_info.ext_cpuid8_ecx.bits.cores_per_cpu + 1); |
696 result = (_cpuid_info.ext_cpuid8_ecx.bits.cores_per_cpu + 1); |
|
697 } else if (is_zx()) { |
|
698 bool supports_topology = supports_processor_topology(); |
|
699 if (supports_topology) { |
|
700 result = _cpuid_info.tpl_cpuidB1_ebx.bits.logical_cpus / |
|
701 _cpuid_info.tpl_cpuidB0_ebx.bits.logical_cpus; |
|
702 } |
|
703 if (!supports_topology || result == 0) { |
|
704 result = (_cpuid_info.dcp_cpuid4_eax.bits.cores_per_cpu + 1); |
|
705 } |
683 } |
706 } |
684 return result; |
707 return result; |
685 } |
708 } |
686 |
709 |
687 static uint threads_per_core() { |
710 static uint threads_per_core() { |
688 uint result = 1; |
711 uint result = 1; |
689 if (is_intel() && supports_processor_topology()) { |
712 if (is_intel() && supports_processor_topology()) { |
|
713 result = _cpuid_info.tpl_cpuidB0_ebx.bits.logical_cpus; |
|
714 } else if (is_zx() && supports_processor_topology()) { |
690 result = _cpuid_info.tpl_cpuidB0_ebx.bits.logical_cpus; |
715 result = _cpuid_info.tpl_cpuidB0_ebx.bits.logical_cpus; |
691 } else if (_cpuid_info.std_cpuid1_edx.bits.ht != 0) { |
716 } else if (_cpuid_info.std_cpuid1_edx.bits.ht != 0) { |
692 if (cpu_family() >= 0x17) { |
717 if (cpu_family() >= 0x17) { |
693 result = _cpuid_info.ext_cpuid1E_ebx.bits.threads_per_core + 1; |
718 result = _cpuid_info.ext_cpuid1E_ebx.bits.threads_per_core + 1; |
694 } else { |
719 } else { |
703 intx result = 0; |
728 intx result = 0; |
704 if (is_intel()) { |
729 if (is_intel()) { |
705 result = (_cpuid_info.dcp_cpuid4_ebx.bits.L1_line_size + 1); |
730 result = (_cpuid_info.dcp_cpuid4_ebx.bits.L1_line_size + 1); |
706 } else if (is_amd()) { |
731 } else if (is_amd()) { |
707 result = _cpuid_info.ext_cpuid5_ecx.bits.L1_line_size; |
732 result = _cpuid_info.ext_cpuid5_ecx.bits.L1_line_size; |
|
733 } else if (is_zx()) { |
|
734 result = (_cpuid_info.dcp_cpuid4_ebx.bits.L1_line_size + 1); |
708 } |
735 } |
709 if (result < 32) // not defined ? |
736 if (result < 32) // not defined ? |
710 result = 32; // 32 bytes by default on x86 and other x64 |
737 result = 32; // 32 bytes by default on x86 and other x64 |
711 return result; |
738 return result; |
712 } |
739 } |