|
|
|
@ -3,8 +3,6 @@ |
|
|
|
// Refer to the license.txt file included.
|
|
|
|
|
|
|
|
#include <cstring>
|
|
|
|
#include <string>
|
|
|
|
#include <thread>
|
|
|
|
#include "common/common_types.h"
|
|
|
|
#include "common/x64/cpu_detect.h"
|
|
|
|
|
|
|
|
@ -51,8 +49,6 @@ namespace Common { |
|
|
|
static CPUCaps Detect() { |
|
|
|
CPUCaps caps = {}; |
|
|
|
|
|
|
|
caps.num_cores = std::thread::hardware_concurrency(); |
|
|
|
|
|
|
|
// Assumes the CPU supports the CPUID instruction. Those that don't would likely not support
|
|
|
|
// yuzu at all anyway
|
|
|
|
|
|
|
|
@ -70,12 +66,6 @@ static CPUCaps Detect() { |
|
|
|
__cpuid(cpu_id, 0x80000000); |
|
|
|
|
|
|
|
u32 max_ex_fn = cpu_id[0]; |
|
|
|
if (!strcmp(caps.brand_string, "GenuineIntel")) |
|
|
|
caps.vendor = CPUVendor::INTEL; |
|
|
|
else if (!strcmp(caps.brand_string, "AuthenticAMD")) |
|
|
|
caps.vendor = CPUVendor::AMD; |
|
|
|
else |
|
|
|
caps.vendor = CPUVendor::OTHER; |
|
|
|
|
|
|
|
// Set reasonable default brand string even if brand string not available
|
|
|
|
strcpy(caps.cpu_string, caps.brand_string); |
|
|
|
@ -96,15 +86,9 @@ static CPUCaps Detect() { |
|
|
|
caps.sse4_1 = true; |
|
|
|
if ((cpu_id[2] >> 20) & 1) |
|
|
|
caps.sse4_2 = true; |
|
|
|
if ((cpu_id[2] >> 22) & 1) |
|
|
|
caps.movbe = true; |
|
|
|
if ((cpu_id[2] >> 25) & 1) |
|
|
|
caps.aes = true; |
|
|
|
|
|
|
|
if ((cpu_id[3] >> 24) & 1) { |
|
|
|
caps.fxsave_fxrstor = true; |
|
|
|
} |
|
|
|
|
|
|
|
// AVX support requires 3 separate checks:
|
|
|
|
// - Is the AVX bit set in CPUID?
|
|
|
|
// - Is the XSAVE bit set in CPUID?
|
|
|
|
@ -129,8 +113,6 @@ static CPUCaps Detect() { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
caps.flush_to_zero = caps.sse; |
|
|
|
|
|
|
|
if (max_ex_fn >= 0x80000004) { |
|
|
|
// Extract CPU model string
|
|
|
|
__cpuid(cpu_id, 0x80000002); |
|
|
|
@ -144,14 +126,8 @@ static CPUCaps Detect() { |
|
|
|
if (max_ex_fn >= 0x80000001) { |
|
|
|
// Check for more features
|
|
|
|
__cpuid(cpu_id, 0x80000001); |
|
|
|
if (cpu_id[2] & 1) |
|
|
|
caps.lahf_sahf_64 = true; |
|
|
|
if ((cpu_id[2] >> 5) & 1) |
|
|
|
caps.lzcnt = true; |
|
|
|
if ((cpu_id[2] >> 16) & 1) |
|
|
|
caps.fma4 = true; |
|
|
|
if ((cpu_id[3] >> 29) & 1) |
|
|
|
caps.long_mode = true; |
|
|
|
} |
|
|
|
|
|
|
|
return caps; |
|
|
|
@ -162,48 +138,4 @@ const CPUCaps& GetCPUCaps() { |
|
|
|
return caps; |
|
|
|
} |
|
|
|
|
|
|
|
std::string GetCPUCapsString() { |
|
|
|
auto caps = GetCPUCaps(); |
|
|
|
|
|
|
|
std::string sum(caps.cpu_string); |
|
|
|
sum += " ("; |
|
|
|
sum += caps.brand_string; |
|
|
|
sum += ")"; |
|
|
|
|
|
|
|
if (caps.sse) |
|
|
|
sum += ", SSE"; |
|
|
|
if (caps.sse2) { |
|
|
|
sum += ", SSE2"; |
|
|
|
if (!caps.flush_to_zero) |
|
|
|
sum += " (without DAZ)"; |
|
|
|
} |
|
|
|
|
|
|
|
if (caps.sse3) |
|
|
|
sum += ", SSE3"; |
|
|
|
if (caps.ssse3) |
|
|
|
sum += ", SSSE3"; |
|
|
|
if (caps.sse4_1) |
|
|
|
sum += ", SSE4.1"; |
|
|
|
if (caps.sse4_2) |
|
|
|
sum += ", SSE4.2"; |
|
|
|
if (caps.avx) |
|
|
|
sum += ", AVX"; |
|
|
|
if (caps.avx2) |
|
|
|
sum += ", AVX2"; |
|
|
|
if (caps.bmi1) |
|
|
|
sum += ", BMI1"; |
|
|
|
if (caps.bmi2) |
|
|
|
sum += ", BMI2"; |
|
|
|
if (caps.fma) |
|
|
|
sum += ", FMA"; |
|
|
|
if (caps.aes) |
|
|
|
sum += ", AES"; |
|
|
|
if (caps.movbe) |
|
|
|
sum += ", MOVBE"; |
|
|
|
if (caps.long_mode) |
|
|
|
sum += ", 64-bit support"; |
|
|
|
|
|
|
|
return sum; |
|
|
|
} |
|
|
|
|
|
|
|
} // namespace Common
|