diff options
Diffstat (limited to 'Source/Core/Common/Src/CPUDetect.cpp')
| -rw-r--r-- | Source/Core/Common/Src/CPUDetect.cpp | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/Source/Core/Common/Src/CPUDetect.cpp b/Source/Core/Common/Src/CPUDetect.cpp new file mode 100644 index 0000000000..718754354d --- /dev/null +++ b/Source/Core/Common/Src/CPUDetect.cpp @@ -0,0 +1,246 @@ +// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifdef _WIN32
+#include <intrin.h>
+#endif
+
+#ifdef __linux__
+//#include <config/i386/cpuid.h>
+#include <xmmintrin.h>
+void __cpuid(int info[4], int x) {}
+
+
+#endif
+
+#include <memory.h>
+
+#include "Common.h"
+#include "CPUDetect.h"
+
+// This code was adapted from an example in MSDN:
+CPUInfoStruct cpu_info;
+
+void CPUInfoStruct::Detect()
+{
+#ifdef _M_IX86
+ Mode64bit = false;
+#elif defined (_M_X64)
+ Mode64bit = true;
+ OS64bit = true;
+#endif
+ numCores = 1;
+
+#ifdef _WIN32
+#ifdef _M_IX86
+ BOOL f64 = FALSE;
+ OS64bit = IsWow64Process(GetCurrentProcess(), &f64) && f64;
+#endif
+#endif
+
+ // __cpuid with an InfoType argument of 0 returns the number of
+ // valid Ids in CPUInfo[0] and the CPU identification string in
+ // the other three array elements. The CPU identification string is
+ // not in linear order. The code below arranges the information
+ // in a human readable form.
+ __cpuid(CPUInfo, 0);
+ nIds = CPUInfo[0];
+ memset(CPUString, 0, sizeof(CPUString));
+ *((int*)CPUString) = CPUInfo[1];
+ *((int*)(CPUString + 4)) = CPUInfo[3];
+ *((int*)(CPUString + 8)) = CPUInfo[2];
+
+ // Assume that everything non-intel is AMD
+ if (memcmp(CPUString, "GenuineIntel", 12) == 0)
+ {
+ isAMD = false;
+ }
+ else
+ {
+ isAMD = true;
+ }
+
+ // Get the information associated with each valid Id
+ for (unsigned int i = 0; i <= nIds; ++i)
+ {
+ __cpuid(CPUInfo, i);
+
+ // Interpret CPU feature information.
+ if (i == 1)
+ {
+ nSteppingID = CPUInfo[0] & 0xf;
+ nModel = (CPUInfo[0] >> 4) & 0xf;
+ nFamily = (CPUInfo[0] >> 8) & 0xf;
+ nProcessorType = (CPUInfo[0] >> 12) & 0x3;
+ nExtendedmodel = (CPUInfo[0] >> 16) & 0xf;
+ nExtendedfamily = (CPUInfo[0] >> 20) & 0xff;
+ nBrandIndex = CPUInfo[1] & 0xff;
+ nCLFLUSHcachelinesize = ((CPUInfo[1] >> 8) & 0xff) * 8;
+ nAPICPhysicalID = (CPUInfo[1] >> 24) & 0xff;
+ bSSE3NewInstructions = (CPUInfo[2] & 0x1) || false;
+ bMONITOR_MWAIT = (CPUInfo[2] & 0x8) || false;
+ bCPLQualifiedDebugStore = (CPUInfo[2] & 0x10) || false;
+ bThermalMonitor2 = (CPUInfo[2] & 0x100) || false;
+ nFeatureInfo = CPUInfo[3];
+
+ if (CPUInfo[2] & (1 << 23))
+ {
+ bPOPCNT = true;
+ }
+
+ if (CPUInfo[2] & (1 << 19))
+ {
+ bSSE4_1 = true;
+ }
+
+ if (CPUInfo[2] & (1 << 20))
+ {
+ bSSE4_2 = true;
+ }
+ }
+ }
+
+ // Calling __cpuid with 0x80000000 as the InfoType argument
+ // gets the number of valid extended IDs.
+ __cpuid(CPUInfo, 0x80000000);
+ nExIds = CPUInfo[0];
+ memset(CPUBrandString, 0, sizeof(CPUBrandString));
+
+ // Get the information associated with each extended ID.
+ for (unsigned int i = 0x80000000; i <= nExIds; ++i)
+ {
+ __cpuid(CPUInfo, i);
+
+ // Interpret CPU brand string and cache information.
+ if (i == 0x80000001)
+ {
+ nFeatureInfo2 = CPUInfo[1]; // ECX
+ bSSE5 = (nFeatureInfo2 & (1 << 11)) ? true : false;
+ bLZCNT = (nFeatureInfo2 & (1 << 5)) ? true : false;
+ bSSE4A = (nFeatureInfo2 & (1 << 6)) ? true : false;
+ bLAHFSAHF64 = (nFeatureInfo2 & (1 << 0)) ? true : false;
+
+ CPU64bit = (CPUInfo[2] & (1 << 29)) ? true : false;
+ }
+ else if (i == 0x80000002)
+ {
+ memcpy(CPUBrandString, CPUInfo, sizeof(CPUInfo));
+ }
+ else if (i == 0x80000003)
+ {
+ memcpy(CPUBrandString + 16, CPUInfo, sizeof(CPUInfo));
+ }
+ else if (i == 0x80000004)
+ {
+ memcpy(CPUBrandString + 32, CPUInfo, sizeof(CPUInfo));
+ }
+ else if (i == 0x80000006)
+ {
+ nCacheLineSize = CPUInfo[2] & 0xff;
+ nL2Associativity = (CPUInfo[2] >> 12) & 0xf;
+ nCacheSizeK = (CPUInfo[2] >> 16) & 0xffff;
+ }
+ else if (i == 0x80000008)
+ {
+ int numLSB = (CPUInfo[2] >> 12) & 0xF;
+ numCores = 1 << numLSB;
+ //int coresPerDie = CPUInfo[2] & 0xFF;
+ // numCores = coresPerDie;
+ }
+ }
+
+ // Display all the information in user-friendly format.
+ // printf_s("\n\nCPU String: %s\n", CPUString);
+
+ if (nIds < 1)
+ {
+ bOldCPU = true;
+ }
+
+ nIds = 1;
+ bx87FPUOnChip = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+ bVirtual_8086ModeEnhancement = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+ bDebuggingExtensions = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+ bPageSizeExtensions = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+ bTimeStampCounter = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+ bRDMSRandWRMSRSupport = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+ bPhysicalAddressExtensions = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+ bMachineCheckException = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+ bCMPXCHG8BInstruction = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+ bAPICOnChip = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+ bUnknown1 = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+ bSYSENTERandSYSEXIT = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+ bMemoryTypeRangeRegisters = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+ bPTEGlobalBit = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+ bMachineCheckArchitecture = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+ bConditionalMove_CompareInstruction = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+ bPageAttributeTable = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+ bPageSizeExtension = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+ bProcessorSerialNumber = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+ bCFLUSHExtension = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+ bUnknown2 = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+ bDebugStore = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+ bThermalMonitorandClockCtrl = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+ bMMXTechnology = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+ bFXSAVE_FXRSTOR = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+ bSSEExtensions = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+ bSSE2Extensions = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+ bSelfSnoop = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+ bHyper_threadingTechnology = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+ bThermalMonitor = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+ bUnknown4 = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+ bPendBrkEN = (nFeatureInfo & nIds) ? true : false;
+ nIds <<= 1;
+
+ if (nExIds < 0x80000004)
+ {
+ strcpy(CPUBrandString, "(unknown)");
+ }
+}
+
+
|
