From 775dc8a9c0c83f7a2f776e97f5b90385c759535a Mon Sep 17 00:00:00 2001 From: hrydgard Date: Sat, 12 Jul 2008 17:40:22 +0000 Subject: Initial megacommit. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Common/Src/CPUDetect.cpp | 246 +++++++++++++++++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 Source/Core/Common/Src/CPUDetect.cpp (limited to 'Source/Core/Common/Src/CPUDetect.cpp') 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 +#endif + +#ifdef __linux__ +//#include +#include +void __cpuid(int info[4], int x) {} + + +#endif + +#include + +#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)"); + } +} + + -- cgit v1.2.3