From d449e35e2db08980721dcce968cc65808fe4c534 Mon Sep 17 00:00:00 2001 From: myT Date: Sat, 31 Dec 2016 02:16:36 +0100 Subject: [PATCH] simplified the code implementing Sys_GetProcessorId (and removed the inline asm) --- code/win32/win_shared.cpp | 113 ++++++-------------------------------- 1 file changed, 18 insertions(+), 95 deletions(-) diff --git a/code/win32/win_shared.cpp b/code/win32/win_shared.cpp index 36ade30..6a4d076 100644 --- a/code/win32/win_shared.cpp +++ b/code/win32/win_shared.cpp @@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "../qcommon/q_shared.h" #include "../qcommon/qcommon.h" #include "win_local.h" +#include int Sys_Milliseconds() @@ -36,134 +37,56 @@ int Sys_Milliseconds() } -// disable all optimizations temporarily so this code works correctly! -#ifdef _MSC_VER -#pragma optimize( "", off ) -#pragma warning(disable : 4748) // don't fkn WHINE about using that pragma -#endif - - -static void CPUID( int func, unsigned regs[4] ) -{ - unsigned regEAX, regEBX, regECX, regEDX; - - __asm mov eax, func - __asm __emit 00fh - __asm __emit 0a2h - __asm mov regEAX, eax - __asm mov regEBX, ebx - __asm mov regECX, ecx - __asm mov regEDX, edx - - regs[0] = regEAX; - regs[1] = regEBX; - regs[2] = regECX; - regs[3] = regEDX; -} - -static qbool IsPentium() -{ - __asm - { - pushfd // save eflags - pop eax - test eax, 0x00200000 // check ID bit - jz set21 // bit 21 is not set, so jump to set_21 - and eax, 0xffdfffff // clear bit 21 - push eax // save new value in register - popfd // store new value in flags - pushfd - pop eax - test eax, 0x00200000 // check ID bit - jz good - jmp err // cpuid not supported -set21: - or eax, 0x00200000 // set ID bit - push eax // store new value - popfd // store new value in EFLAGS - pushfd - pop eax - test eax, 0x00200000 // if bit 21 is on - jnz good - jmp err - } - -err: - return qfalse; -good: - return qtrue; -} - static const char* CPU_Name() { - static unsigned regs[4]; - - CPUID( 0, regs ); + static int regs[4]; + __cpuid( regs, 0 ); regs[0] = regs[1]; regs[1] = regs[3]; regs[3] = 0; + return (const char*)regs; } -static int CPU_Cores() -{ - unsigned regs[4]; - CPUID( 1, regs ); - return ((regs[1] & 0x00FF0000) >> 16); -} struct CPU_FeatureBit { const char* s; int reg, bit; } CPU_FeatureBits[] = { +#if id386 // x64 always has those anyway { " MMX", 3, 23 }, { " SSE", 3, 25 }, { " SSE2", 3, 26 }, - { " SSE3", 2, 26 }, - { 0 } +#endif + { " SSE3", 2, 0 }, + { " SSSE3", 2, 9 }, + { " SSE4.1", 2, 19 }, + { " SSE4.2", 2, 20 }, + { " AVX", 2, 28 } + // for AVX2 and later, you'd need to call cpuid with eax=7 and ecx=0 ("extended features") }; +static const int CPU_FeatureBitCount = sizeof(CPU_FeatureBits) / sizeof(CPU_FeatureBits[0]); int Sys_GetProcessorId() { -#if defined _M_ALPHA - return CPUID_AXP; -#elif !defined _M_IX86 - return CPUID_GENERIC; -#else - - // verify we're at least a Pentium or 486 w/ CPUID support - if ( !IsPentium() ) { - Cvar_Set( "sys_cpustring", "x86 (pre-Pentium)" ); - return CPUID_UNSUPPORTED; - } - - char s[64] = ""; + char s[256] = ""; Q_strcat( s, sizeof(s), CPU_Name() ); - if (CPU_Cores() > 1) - Q_strcat( s, sizeof(s), va(" %d cores", CPU_Cores()) ); + int regs[4]; + __cpuid( regs, 1 ); - unsigned regs[4]; - CPUID( 1, regs ); - - for (int i = 0; CPU_FeatureBits[i].s; ++i) { + for (int i = 0; i < CPU_FeatureBitCount; ++i) { if (regs[CPU_FeatureBits[i].reg] & (1 << regs[CPU_FeatureBits[i].bit])) { Q_strcat( s, sizeof(s), CPU_FeatureBits[i].s ); } } Cvar_Set( "sys_cpustring", s ); + return CPUID_GENERIC; - -#endif } -#ifdef _MSC_VER -#pragma optimize( "", on ) -#endif - - const char* Sys_GetCurrentUser() { return "player";