diff options
Diffstat (limited to 'src/common/x64/cpu_detect.cpp')
| -rw-r--r-- | src/common/x64/cpu_detect.cpp | 52 |
1 files changed, 20 insertions, 32 deletions
diff --git a/src/common/x64/cpu_detect.cpp b/src/common/x64/cpu_detect.cpp index fbeacc7e2..fee00914a 100644 --- a/src/common/x64/cpu_detect.cpp +++ b/src/common/x64/cpu_detect.cpp | |||
| @@ -1,8 +1,8 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project / 2015 Citra Emulator Project | 1 | // Copyright 2013 Dolphin Emulator Project / 2015 Citra Emulator Project / 2022 Yuzu Emulator |
| 2 | // Licensed under GPLv2 or any later version | 2 | // Project Licensed under GPLv2 or any later version Refer to the license.txt file included. |
| 3 | // Refer to the license.txt file included. | ||
| 4 | 3 | ||
| 5 | #include <cstring> | 4 | #include <cstring> |
| 5 | #include "common/bit_util.h" | ||
| 6 | #include "common/common_types.h" | 6 | #include "common/common_types.h" |
| 7 | #include "common/x64/cpu_detect.h" | 7 | #include "common/x64/cpu_detect.h" |
| 8 | 8 | ||
| @@ -81,29 +81,22 @@ static CPUCaps Detect() { | |||
| 81 | // Detect family and other miscellaneous features | 81 | // Detect family and other miscellaneous features |
| 82 | if (max_std_fn >= 1) { | 82 | if (max_std_fn >= 1) { |
| 83 | __cpuid(cpu_id, 0x00000001); | 83 | __cpuid(cpu_id, 0x00000001); |
| 84 | if ((cpu_id[3] >> 25) & 1) | 84 | caps.sse = Common::Bit<25>(cpu_id[3]); |
| 85 | caps.sse = true; | 85 | caps.sse2 = Common::Bit<26>(cpu_id[3]); |
| 86 | if ((cpu_id[3] >> 26) & 1) | 86 | caps.sse3 = Common::Bit<0>(cpu_id[2]); |
| 87 | caps.sse2 = true; | 87 | caps.ssse3 = Common::Bit<9>(cpu_id[2]); |
| 88 | if ((cpu_id[2]) & 1) | 88 | caps.sse4_1 = Common::Bit<19>(cpu_id[2]); |
| 89 | caps.sse3 = true; | 89 | caps.sse4_2 = Common::Bit<20>(cpu_id[2]); |
| 90 | if ((cpu_id[2] >> 9) & 1) | 90 | caps.aes = Common::Bit<25>(cpu_id[2]); |
| 91 | caps.ssse3 = true; | ||
| 92 | if ((cpu_id[2] >> 19) & 1) | ||
| 93 | caps.sse4_1 = true; | ||
| 94 | if ((cpu_id[2] >> 20) & 1) | ||
| 95 | caps.sse4_2 = true; | ||
| 96 | if ((cpu_id[2] >> 25) & 1) | ||
| 97 | caps.aes = true; | ||
| 98 | 91 | ||
| 99 | // AVX support requires 3 separate checks: | 92 | // AVX support requires 3 separate checks: |
| 100 | // - Is the AVX bit set in CPUID? | 93 | // - Is the AVX bit set in CPUID? |
| 101 | // - Is the XSAVE bit set in CPUID? | 94 | // - Is the XSAVE bit set in CPUID? |
| 102 | // - XGETBV result has the XCR bit set. | 95 | // - XGETBV result has the XCR bit set. |
| 103 | if (((cpu_id[2] >> 28) & 1) && ((cpu_id[2] >> 27) & 1)) { | 96 | if (Common::Bit<28>(cpu_id[2]) && Common::Bit<27>(cpu_id[2])) { |
| 104 | if ((_xgetbv(_XCR_XFEATURE_ENABLED_MASK) & 0x6) == 0x6) { | 97 | if ((_xgetbv(_XCR_XFEATURE_ENABLED_MASK) & 0x6) == 0x6) { |
| 105 | caps.avx = true; | 98 | caps.avx = true; |
| 106 | if ((cpu_id[2] >> 12) & 1) | 99 | if (Common::Bit<12>(cpu_id[2])) |
| 107 | caps.fma = true; | 100 | caps.fma = true; |
| 108 | } | 101 | } |
| 109 | } | 102 | } |
| @@ -111,15 +104,13 @@ static CPUCaps Detect() { | |||
| 111 | if (max_std_fn >= 7) { | 104 | if (max_std_fn >= 7) { |
| 112 | __cpuidex(cpu_id, 0x00000007, 0x00000000); | 105 | __cpuidex(cpu_id, 0x00000007, 0x00000000); |
| 113 | // Can't enable AVX2 unless the XSAVE/XGETBV checks above passed | 106 | // Can't enable AVX2 unless the XSAVE/XGETBV checks above passed |
| 114 | if ((cpu_id[1] >> 5) & 1) | 107 | caps.avx2 = caps.avx && Common::Bit<5>(cpu_id[1]); |
| 115 | caps.avx2 = caps.avx; | 108 | caps.bmi1 = Common::Bit<3>(cpu_id[1]); |
| 116 | if ((cpu_id[1] >> 3) & 1) | 109 | caps.bmi2 = Common::Bit<8>(cpu_id[1]); |
| 117 | caps.bmi1 = true; | ||
| 118 | if ((cpu_id[1] >> 8) & 1) | ||
| 119 | caps.bmi2 = true; | ||
| 120 | // Checks for AVX512F, AVX512CD, AVX512VL, AVX512DQ, AVX512BW (Intel Skylake-X/SP) | 110 | // Checks for AVX512F, AVX512CD, AVX512VL, AVX512DQ, AVX512BW (Intel Skylake-X/SP) |
| 121 | if ((cpu_id[1] >> 16) & 1 && (cpu_id[1] >> 28) & 1 && (cpu_id[1] >> 31) & 1 && | 111 | if (Common::Bit<16>(cpu_id[1]) && Common::Bit<28>(cpu_id[1]) && |
| 122 | (cpu_id[1] >> 17) & 1 && (cpu_id[1] >> 30) & 1) { | 112 | Common::Bit<31>(cpu_id[1]) && Common::Bit<17>(cpu_id[1]) && |
| 113 | Common::Bit<30>(cpu_id[1])) { | ||
| 123 | caps.avx512 = caps.avx2; | 114 | caps.avx512 = caps.avx2; |
| 124 | } | 115 | } |
| 125 | } | 116 | } |
| @@ -138,15 +129,12 @@ static CPUCaps Detect() { | |||
| 138 | if (max_ex_fn >= 0x80000001) { | 129 | if (max_ex_fn >= 0x80000001) { |
| 139 | // Check for more features | 130 | // Check for more features |
| 140 | __cpuid(cpu_id, 0x80000001); | 131 | __cpuid(cpu_id, 0x80000001); |
| 141 | if ((cpu_id[2] >> 16) & 1) | 132 | caps.fma4 = Common::Bit<16>(cpu_id[2]); |
| 142 | caps.fma4 = true; | ||
| 143 | } | 133 | } |
| 144 | 134 | ||
| 145 | if (max_ex_fn >= 0x80000007) { | 135 | if (max_ex_fn >= 0x80000007) { |
| 146 | __cpuid(cpu_id, 0x80000007); | 136 | __cpuid(cpu_id, 0x80000007); |
| 147 | if (cpu_id[3] & (1 << 8)) { | 137 | caps.invariant_tsc = Common::Bit<8>(cpu_id[3]); |
| 148 | caps.invariant_tsc = true; | ||
| 149 | } | ||
| 150 | } | 138 | } |
| 151 | 139 | ||
| 152 | if (max_std_fn >= 0x16) { | 140 | if (max_std_fn >= 0x16) { |