Files
FC1/CrySystem/CPUDetect.h
romkazvo 34d6c5d489 123
2023-08-07 19:29:24 +08:00

164 lines
3.2 KiB
C++

/*=============================================================================
CPUDetect.cpp : CPU detection.
Copyright 2001 Crytek Studios. All Rights Reserved.
Revision history:
* Created by Honitch Andrey
=============================================================================*/
#ifndef __CPUDETECT_H__
#define __CPUDETECT_H__
//-------------------------------------------------------
/// Cpu class
//-------------------------------------------------------
#define MAX_CPU 32
/// Cpu Features
#define CFI_FPUEMULATION 1
#define CFI_MMX 2
#define CFI_3DNOW 4
#define CFI_SSE 8
#define CFI_SSE2 0x10
/// Type of Cpu Vendor.
enum ECpuVendor
{
eCVendor_Unknown,
eCVendor_Intel,
eCVendor_Cyrix,
eCVendor_AMD,
eCVendor_Centaur,
eCVendor_NexGen,
eCVendor_UMC,
eCVendor_M68K
};
/// Type of Cpu Model.
enum ECpuModel
{
eCpu_Unknown,
eCpu_8086,
eCpu_80286,
eCpu_80386,
eCpu_80486,
eCpu_Pentium,
eCpu_PentiumPro,
eCpu_Pentium2,
eCpu_Pentium3,
eCpu_Pentium4,
eCpu_Pentium2Xeon,
eCpu_Pentium3Xeon,
eCpu_Celeron,
eCpu_CeleronA,
eCpu_Am5x86,
eCpu_AmK5,
eCpu_AmK6,
eCpu_AmK6_2,
eCpu_AmK6_3,
eCpu_AmK6_3D,
eCpu_AmAthlon,
eCpu_AmDuron,
eCpu_CyrixMediaGX,
eCpu_Cyrix6x86,
eCpu_CyrixGXm,
eCpu_Cyrix6x86MX,
eCpu_CenWinChip,
eCpu_CenWinChip2,
};
struct SCpu
{
ECpuVendor meVendor;
ECpuModel meModel;
unsigned long mFeatures;
bool mbSerialPresent;
char mSerialNumber[30];
int mFamily;
int mModel;
int mStepping;
char mVendor[64];
char mCpuType[64];
char mFpuType[64];
int mSpeed;
double m_SecondsPerCycle;
};
class CCpuFeatures
{
private:
int m_NumSystemProcessors;
int m_NumAvailProcessors;
bool m_bOS_ISSE;
bool m_bOS_ISSE_EXCEPTIONS;
public:
SCpu m_Cpu[MAX_CPU];
public:
CCpuFeatures()
{
m_NumSystemProcessors = 0;
m_NumAvailProcessors = 0;
m_bOS_ISSE = 0;
m_bOS_ISSE_EXCEPTIONS = 0;
}
void Detect(void);
bool hasSSE() { return (m_Cpu[0].mFeatures & CFI_SSE) != 0; }
bool hasSSE2() { return (m_Cpu[0].mFeatures & CFI_SSE2) != 0; }
bool has3DNow() { return (m_Cpu[0].mFeatures & CFI_3DNOW) != 0; }
bool hasMMX() { return (m_Cpu[0].mFeatures & CFI_MMX) != 0; }
};
#if defined(WIN64) || defined(LINUX64)
inline bool IsAMD64()
{
#ifdef _AMD64_
return true;
#else
#error not supported here
#endif
}
#else
inline bool
IsAMD64()
{
#if defined(LINUX32)
return false;
#else
_asm
{
// make sure cpuid is available
pushfd // save EFLAGS
pop eax // store EFLAGS in EAX
mov ebx, eax // save in EBX for later testing
xor eax, 00200000h // toggle bit 21
push eax // push to stack
popfd // save changed EAX to EFLAGS
pushfd // push EFLAGS to TOS
pop eax // store EFLAGS in EAX
cmp eax, ebx // see if bit 21 has changed
mov eax, 0 // clear eax to return "false"
jz QUIT // if no change, no CPUID
// perform AMD64 detection
mov eax, 0x80000001 // load argument "Processor Signature and AMD Features" to call cpuid
cpuid // call cpuid
mov eax, edx // edx contains "AMD Feature Support" flags
shr eax, 29 // test bit 29 (support for "Long Mode")
and eax, 0x00000001 // mask out bit for proper return value
QUIT:
}
#endif
}
#endif // WIN32
#endif