mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Common: Detect x86 features with cpu_features.
This commit is contained in:
parent
489411359e
commit
368aba3c8d
2 changed files with 70 additions and 1 deletions
|
@ -19,6 +19,12 @@
|
|||
#include "ppsspp_config.h"
|
||||
#if PPSSPP_ARCH(X86) || PPSSPP_ARCH(AMD64)
|
||||
|
||||
#include "ext/cpu_features/include/cpuinfo_x86.h"
|
||||
|
||||
#if defined(CPU_FEATURES_OS_FREEBSD) || defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID) || defined(CPU_FEATURES_OS_MACOS) || defined(CPU_FEATURES_OS_WINDOWS)
|
||||
#define USE_CPU_FEATURES 1
|
||||
#endif
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
@ -141,6 +147,10 @@ static std::vector<int> ParseCPUList(const std::string &filename) {
|
|||
|
||||
// Detects the various cpu features
|
||||
void CPUInfo::Detect() {
|
||||
#ifdef USE_CPU_FEATURES
|
||||
cpu_features::X86Info info = cpu_features::GetX86Info();
|
||||
#endif
|
||||
|
||||
memset(this, 0, sizeof(*this));
|
||||
#if PPSSPP_ARCH(X86)
|
||||
Mode64bit = false;
|
||||
|
@ -185,7 +195,50 @@ void CPUInfo::Detect() {
|
|||
vendor = VENDOR_OTHER;
|
||||
|
||||
// Set reasonable default brand string even if brand string not available.
|
||||
strcpy(brand_string, cpu_string);
|
||||
#ifdef USE_CPU_FEATURES
|
||||
if (info.brand_string[0])
|
||||
strcpy(brand_string, info.brand_string);
|
||||
else
|
||||
#endif
|
||||
strcpy(brand_string, cpu_string);
|
||||
|
||||
#ifdef USE_CPU_FEATURES
|
||||
switch (cpu_features::GetX86Microarchitecture(&info)) {
|
||||
case cpu_features::INTEL_ATOM_BNL:
|
||||
case cpu_features::INTEL_ATOM_SMT:
|
||||
case cpu_features::INTEL_ATOM_GMT:
|
||||
case cpu_features::INTEL_ATOM_GMT_PLUS:
|
||||
case cpu_features::INTEL_ATOM_TMT:
|
||||
bAtom = true;
|
||||
break;
|
||||
default:
|
||||
bAtom = false;
|
||||
break;
|
||||
}
|
||||
|
||||
bPOPCNT = info.features.popcnt;
|
||||
bBMI1 = info.features.bmi1;
|
||||
bBMI2 = info.features.bmi2;
|
||||
bBMI2_fast = bBMI2 && (vendor != VENDOR_AMD || info.family >= 0x19);
|
||||
bMOVBE = info.features.movbe;
|
||||
bLZCNT = info.features.lzcnt;
|
||||
bRTM = info.features.rtm;
|
||||
|
||||
bSSE = info.features.sse;
|
||||
bSSE2 = info.features.sse2;
|
||||
bSSE3 = info.features.sse3;
|
||||
bSSSE3 = info.features.ssse3;
|
||||
bSSE4_1 = info.features.sse4_1;
|
||||
bSSE4_2 = info.features.sse4_2;
|
||||
bSSE4A = info.features.sse4a;
|
||||
bAES = info.features.aes;
|
||||
bSHA = info.features.sha;
|
||||
bF16C = info.features.f16c;
|
||||
bAVX = info.features.avx;
|
||||
bAVX2 = info.features.avx2;
|
||||
bFMA3 = info.features.fma3;
|
||||
bFMA4 = info.features.fma4;
|
||||
#endif
|
||||
|
||||
// Detect family and other misc stuff.
|
||||
bool ht = false;
|
||||
|
@ -193,16 +246,19 @@ void CPUInfo::Detect() {
|
|||
logical_cpu_count = 1;
|
||||
if (max_std_fn >= 1) {
|
||||
do_cpuid(cpu_id, 0x00000001);
|
||||
#ifndef USE_CPU_FEATURES
|
||||
int family = ((cpu_id[0] >> 8) & 0xf) + ((cpu_id[0] >> 20) & 0xff);
|
||||
int model = ((cpu_id[0] >> 4) & 0xf) + ((cpu_id[0] >> 12) & 0xf0);
|
||||
// Detect people unfortunate enough to be running PPSSPP on an Atom
|
||||
if (family == 6 && (model == 0x1C || model == 0x26 || model == 0x27 || model == 0x35 || model == 0x36 ||
|
||||
model == 0x37 || model == 0x4A || model == 0x4D || model == 0x5A || model == 0x5D))
|
||||
bAtom = true;
|
||||
#endif
|
||||
|
||||
logical_cpu_count = (cpu_id[1] >> 16) & 0xFF;
|
||||
ht = (cpu_id[3] >> 28) & 1;
|
||||
|
||||
#ifndef USE_CPU_FEATURES
|
||||
if ((cpu_id[3] >> 25) & 1) bSSE = true;
|
||||
if ((cpu_id[3] >> 26) & 1) bSSE2 = true;
|
||||
if ((cpu_id[2]) & 1) bSSE3 = true;
|
||||
|
@ -215,6 +271,7 @@ void CPUInfo::Detect() {
|
|||
bFMA3 = true;
|
||||
}
|
||||
if ((cpu_id[2] >> 25) & 1) bAES = true;
|
||||
#endif
|
||||
|
||||
if ((cpu_id[3] >> 24) & 1)
|
||||
{
|
||||
|
@ -222,6 +279,7 @@ void CPUInfo::Detect() {
|
|||
bFXSR = true;
|
||||
}
|
||||
|
||||
#ifndef USE_CPU_FEATURES
|
||||
// AVX support requires 3 separate checks:
|
||||
// - Is the AVX bit set in CPUID? (>>28)
|
||||
// - Is the XSAVE bit set in CPUID? ( >>26)
|
||||
|
@ -257,8 +315,10 @@ void CPUInfo::Detect() {
|
|||
}
|
||||
|
||||
bBMI2_fast = bBMI2 && (vendor != VENDOR_AMD || family >= 0x19);
|
||||
#endif
|
||||
}
|
||||
if (max_ex_fn >= 0x80000004) {
|
||||
#ifndef USE_CPU_FEATURES
|
||||
// Extract brand string
|
||||
do_cpuid(cpu_id, 0x80000002);
|
||||
memcpy(brand_string, cpu_id, sizeof(cpu_id));
|
||||
|
@ -266,13 +326,16 @@ void CPUInfo::Detect() {
|
|||
memcpy(brand_string + 16, cpu_id, sizeof(cpu_id));
|
||||
do_cpuid(cpu_id, 0x80000004);
|
||||
memcpy(brand_string + 32, cpu_id, sizeof(cpu_id));
|
||||
#endif
|
||||
}
|
||||
if (max_ex_fn >= 0x80000001) {
|
||||
// Check for more features.
|
||||
do_cpuid(cpu_id, 0x80000001);
|
||||
if (cpu_id[2] & 1) bLAHFSAHF64 = true;
|
||||
#ifndef USE_CPU_FEATURES
|
||||
if ((cpu_id[2] >> 6) & 1) bSSE4A = true;
|
||||
if ((cpu_id[2] >> 16) & 1) bFMA4 = true;
|
||||
#endif
|
||||
if ((cpu_id[2] >> 11) & 1) bXOP = true;
|
||||
// CmpLegacy (bit 2) is deprecated.
|
||||
if ((cpu_id[3] >> 29) & 1) bLongMode = true;
|
||||
|
@ -445,6 +508,11 @@ std::string CPUInfo::Summarize()
|
|||
if (bSHA) sum += ", SHA";
|
||||
if (bXOP) sum += ", XOP";
|
||||
if (bRTM) sum += ", TSX";
|
||||
if (bF16C) sum += ", F16C";
|
||||
if (bBMI1) sum += ", BMI1";
|
||||
if (bPOPCNT) sum += ", POPCNT";
|
||||
if (bMOVBE) sum += ", MOVBE";
|
||||
if (bLZCNT) sum += ", LZCNT";
|
||||
if (bLongMode) sum += ", 64-bit support";
|
||||
return sum;
|
||||
}
|
||||
|
|
|
@ -68,6 +68,7 @@ struct CPUInfo {
|
|||
bool bSSE4A;
|
||||
bool bAES;
|
||||
bool bSHA;
|
||||
bool bF16C;
|
||||
// x86 : SIMD 256 bit
|
||||
bool bAVX;
|
||||
bool bAVX2;
|
||||
|
|
Loading…
Add table
Reference in a new issue