mirror of
https://bitbucket.org/CPMADevs/cnq3
synced 2024-11-10 06:31:48 +00:00
simplified the code implementing Sys_GetProcessorId (and removed the inline asm)
This commit is contained in:
parent
511291bb97
commit
d449e35e2d
1 changed files with 18 additions and 95 deletions
|
@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
#include "../qcommon/q_shared.h"
|
#include "../qcommon/q_shared.h"
|
||||||
#include "../qcommon/qcommon.h"
|
#include "../qcommon/qcommon.h"
|
||||||
#include "win_local.h"
|
#include "win_local.h"
|
||||||
|
#include <intrin.h>
|
||||||
|
|
||||||
|
|
||||||
int Sys_Milliseconds()
|
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 const char* CPU_Name()
|
||||||
{
|
{
|
||||||
static unsigned regs[4];
|
static int regs[4];
|
||||||
|
|
||||||
CPUID( 0, regs );
|
|
||||||
|
|
||||||
|
__cpuid( regs, 0 );
|
||||||
regs[0] = regs[1];
|
regs[0] = regs[1];
|
||||||
regs[1] = regs[3];
|
regs[1] = regs[3];
|
||||||
regs[3] = 0;
|
regs[3] = 0;
|
||||||
|
|
||||||
return (const char*)regs;
|
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[] =
|
struct CPU_FeatureBit { const char* s; int reg, bit; } CPU_FeatureBits[] =
|
||||||
{
|
{
|
||||||
|
#if id386 // x64 always has those anyway
|
||||||
{ " MMX", 3, 23 },
|
{ " MMX", 3, 23 },
|
||||||
{ " SSE", 3, 25 },
|
{ " SSE", 3, 25 },
|
||||||
{ " SSE2", 3, 26 },
|
{ " SSE2", 3, 26 },
|
||||||
{ " SSE3", 2, 26 },
|
#endif
|
||||||
{ 0 }
|
{ " 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()
|
int Sys_GetProcessorId()
|
||||||
{
|
{
|
||||||
#if defined _M_ALPHA
|
char s[256] = "";
|
||||||
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] = "";
|
|
||||||
Q_strcat( s, sizeof(s), CPU_Name() );
|
Q_strcat( s, sizeof(s), CPU_Name() );
|
||||||
|
|
||||||
if (CPU_Cores() > 1)
|
int regs[4];
|
||||||
Q_strcat( s, sizeof(s), va(" %d cores", CPU_Cores()) );
|
__cpuid( regs, 1 );
|
||||||
|
|
||||||
unsigned regs[4];
|
for (int i = 0; i < CPU_FeatureBitCount; ++i) {
|
||||||
CPUID( 1, regs );
|
|
||||||
|
|
||||||
for (int i = 0; CPU_FeatureBits[i].s; ++i) {
|
|
||||||
if (regs[CPU_FeatureBits[i].reg] & (1 << regs[CPU_FeatureBits[i].bit])) {
|
if (regs[CPU_FeatureBits[i].reg] & (1 << regs[CPU_FeatureBits[i].bit])) {
|
||||||
Q_strcat( s, sizeof(s), CPU_FeatureBits[i].s );
|
Q_strcat( s, sizeof(s), CPU_FeatureBits[i].s );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Cvar_Set( "sys_cpustring", s );
|
Cvar_Set( "sys_cpustring", s );
|
||||||
|
|
||||||
return CPUID_GENERIC;
|
return CPUID_GENERIC;
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma optimize( "", on )
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
const char* Sys_GetCurrentUser()
|
const char* Sys_GetCurrentUser()
|
||||||
{
|
{
|
||||||
return "player";
|
return "player";
|
||||||
|
|
Loading…
Reference in a new issue