CPU detection C code
Posted: 18 Oct 2004, 13:33
Here's some handy cpu detection C code, I found whilst trawling the web - you may find it useful >
///////////////////////////////////////////////////////////////////////////////
////////// Source code to detect which CPU is in the user's computer.
//////////Update 14/7/04- fix for SSE and Windows XP
///////////////////////////////////////////////////////////////////////////////
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define FALSE 0
#define TRUE 1
int AvailCPUID (void)
{
/* Tests for availability of CPUID by flipping ID bit eflags */
int f=FALSE;
__asm
{
pushfd
pop eax
mov ebx,eax
xor eax,0x00200000
push eax
popfd
pushfd
pop eax
push ebx
popfd
xor eax,ebx
mov f,eax
}
return f;
}
int FirstCPUID (char *s)
{
int Level;
// Find processor manufacturer and number of supported CPUID modes
__asm
{
xor eax,eax
cpuid
mov Level,eax
mov esi,s
mov dword ptr [esi],ebx
mov dword ptr 4[esi],edx
mov dword ptr 8[esi],ecx
}
s [12] = 0;
return Level;
}
int FirstAMDCPUID (void)
{
int Level;
// Finds number of supported AMD extended CPUID modes
__asm
{
mov eax,80000000H
cpuid
mov Level,eax
}
return Level;
}
unsigned int VersionCPUID (void)
{
unsigned int Features;
// Finds features of CPU
__asm
{
mov eax,1
cpuid
mov Features,edx
}
return Features;
}
int FamilyCPUID (void)
{
unsigned int Family;
// Finds family of CPU
__asm
{
mov eax,1
cpuid
mov Family,eax
}
return Family;
}
unsigned int AMDVersionCPUID (void)
{
unsigned int Features;
// Finds AMD extended features of CPU
__asm
{
mov eax,80000001H
cpuid
mov Features,edx
}
return Features;
}
int isPentium (void)
{
char Brand [64];
unsigned int Features;
// Returns TRUE if processor is a Pentium or compatible.
if (!AvailCPUID ()) return FALSE; // no CPUID
if (FamilyCPUID () < 5) return FALSE; // must be 486
Features = VersionCPUID ();
if (!(Features & 0x1)) return FALSE; // no float
return TRUE;
}
int isPentiumMMX (void)
{
char Brand [64];
unsigned int Features;
// Returns TRUE if processor is a Pentium with MMX or compatible.
if (!AvailCPUID ()) return FALSE;
if (FamilyCPUID () < 5) return FALSE;
Features = VersionCPUID ();
if (!(Features & 0x1)) return FALSE; // no float
if (!(Features & 0x800000)) return FALSE; // no MMX
return TRUE;
}
int isPentiumPro (void)
{
char Brand [64];
unsigned int Features;
// Returns TRUE if processor is a Pentium Pro or compatible.
if (!AvailCPUID ()) return FALSE;
if (FamilyCPUID () < 6) return FALSE;
Features = VersionCPUID ();
if (!(Features & 0x1)) return FALSE; // no float
if (!(Features & 0x8000)) return FALSE; // no CMOV/FCMOV/FCOMI
return TRUE;
}
int isPentiumII (void)
{
char Brand [64];
unsigned int Features;
// Returns TRUE if processor is a Pentium II or compatible.
if (!AvailCPUID ()) return FALSE;
if (FamilyCPUID () < 6) return FALSE;
Features = VersionCPUID ();
if (!(Features & 0x1)) return FALSE; // no float
if (!(Features & 0x8000)) return FALSE; // no CMOV/FCMOV/FCOMI
if (!(Features & 0x800000)) return FALSE; // no MMX
return TRUE;
}
int isPentiumIII (void)
{
char Brand [64];
unsigned int Features;
// Returns TRUE if processor is a Pentium III or compatible.
// Returns FALSE if Pentium III with no operating system support
if (!AvailCPUID ()) return FALSE;
if (FamilyCPUID () < 6) return FALSE;
Features = VersionCPUID ();
if (!(Features & 0x1)) return FALSE; // no float
if (!(Features & 0x8000)) return FALSE; // no CMOV/FCMOV/FCOMI
if (!(Features & 0x800000)) return FALSE; // no MMX
if (!(Features & 0x2000000)) return FALSE; // no Streaming SIMD
return TRUE;
}
int isAMDK6 (void)
{
char Brand [64];
unsigned int Features;
// Returns TRUE if processor is an AMD K6 with MMX or compatible.
// Returns FALSE if processor is a Pentium MMX, even though this
// is a compatible processor. Use isPentiumMMX for that.
if (!AvailCPUID ()) return FALSE;
if (FamilyCPUID () < 5) return FALSE; // not Pentium class or above
if (FirstCPUID (Brand) < 1) return FALSE;
if (FirstAMDCPUID () < 0x80000001) return FALSE;
Features = AMDVersionCPUID ();
if (!(Features & 0x1)) return FALSE; // no float
if (!(Features & 0x800000)) return FALSE; // no MMX
return TRUE;
}
int isAMDK62 (void)
{
char Brand [64];
unsigned int Features;
// Returns TRUE if processor is an AMD K6 with MMX and 3DNow! or compatible.
if (!AvailCPUID ()) return FALSE;
if (FamilyCPUID () < 5) return FALSE; // not Pentium class or above
if (FirstCPUID (Brand) < 1) return FALSE;
if (FirstAMDCPUID () < 0x80000001) return FALSE;
Features = AMDVersionCPUID ();
if (!(Features & 0x1)) return FALSE; // no float
if (!(Features & 0x800000)) return FALSE; // no MMX
if (!(Features & 0x80000000)) return FALSE; // no 3DNow!
return TRUE;
}
int isAthlon (void)
{
char Brand [64];
unsigned int Features;
// Returns TRUE if processor is an AMD Athlon with MMX and Advanced 3DNow! or compatible.
if (!AvailCPUID ()) return FALSE;
if (FamilyCPUID () < 6) return FALSE; // not Pentium Pro class or above
if (FirstCPUID (Brand) < 1) return FALSE;
if (FirstAMDCPUID () < 0x80000001) return FALSE;
Features = AMDVersionCPUID ();
if (!(Features & 0x1)) return FALSE; // no float
if (!(Features & 0x8000)) return FALSE; // no CMOV/FCMOV/FCOMI
if (!(Features & 0x800000)) return FALSE; // no MMX
if (!(Features & 0x400000)) return FALSE; // no K7 MMX
if (!(Features & 0x80000000)) return FALSE; // no 3DNow!
if (!(Features & 0x40000000)) return FALSE; // no Advanced 3DNow!
return TRUE;
}
void main (void)
{
int Avail, Level;
unsigned int Features, AMDLevel, AMDFeatures;
char Brand [64];
if (AvailCPUID ())
{
printf ("CPUID available\n");
Level = FirstCPUID (Brand);
printf ("CPUID brand: %s, max eax value: %d\n", Brand, Level);
if (Level >= 1)
{
printf ("Family = %d\n", (FamilyCPUID () >> 8) & 0xF);
Features = VersionCPUID ();
if (Features & 1) printf ("Floating-point\n");
if (Features & 0x8000) printf ("CMOV / FCMOV / FCOMI supported\n");
if (Features & 0x800000) printf ("MMX supported\n");
if (Features & 0x2000000)
{
printf ("Streaming SIMD Extensions supported by processor\n");
}
AMDLevel = FirstAMDCPUID ();
if (AMDLevel >= 0x80000001)
{
AMDFeatures = AMDVersionCPUID ();
if (AMDFeatures & 0x400000) printf ("AMD K7 MMX Extensions\n");
if (AMDFeatures & 0x40000000) printf ("AMD K7 3DNow! Extensions\n");
if (AMDFeatures & 0x80000000) printf ("AMD 3DNow! Extensions\n");
}
}
}
else
printf ("CPUID not available - must be 486 or less\n");
if (isPentium ()) printf ("isPentium\n");
if (isPentiumMMX ()) printf ("isPentiumMMX\n");
if (isPentiumPro ()) printf ("isPentiumPro\n");
if (isPentiumII ()) printf ("isPentiumII\n");
if (isPentiumIII ()) printf ("isPentiumIII\n");
if (isAMDK6 ()) printf ("isAMDK6\n");
if (isAMDK62 ()) printf ("isAMDK62\n");
if (isAthlon ()) printf ("isAthlon\n");
}
//////////////////// code end ///////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
////////// Source code to detect which CPU is in the user's computer.
//////////Update 14/7/04- fix for SSE and Windows XP
///////////////////////////////////////////////////////////////////////////////
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define FALSE 0
#define TRUE 1
int AvailCPUID (void)
{
/* Tests for availability of CPUID by flipping ID bit eflags */
int f=FALSE;
__asm
{
pushfd
pop eax
mov ebx,eax
xor eax,0x00200000
push eax
popfd
pushfd
pop eax
push ebx
popfd
xor eax,ebx
mov f,eax
}
return f;
}
int FirstCPUID (char *s)
{
int Level;
// Find processor manufacturer and number of supported CPUID modes
__asm
{
xor eax,eax
cpuid
mov Level,eax
mov esi,s
mov dword ptr [esi],ebx
mov dword ptr 4[esi],edx
mov dword ptr 8[esi],ecx
}
s [12] = 0;
return Level;
}
int FirstAMDCPUID (void)
{
int Level;
// Finds number of supported AMD extended CPUID modes
__asm
{
mov eax,80000000H
cpuid
mov Level,eax
}
return Level;
}
unsigned int VersionCPUID (void)
{
unsigned int Features;
// Finds features of CPU
__asm
{
mov eax,1
cpuid
mov Features,edx
}
return Features;
}
int FamilyCPUID (void)
{
unsigned int Family;
// Finds family of CPU
__asm
{
mov eax,1
cpuid
mov Family,eax
}
return Family;
}
unsigned int AMDVersionCPUID (void)
{
unsigned int Features;
// Finds AMD extended features of CPU
__asm
{
mov eax,80000001H
cpuid
mov Features,edx
}
return Features;
}
int isPentium (void)
{
char Brand [64];
unsigned int Features;
// Returns TRUE if processor is a Pentium or compatible.
if (!AvailCPUID ()) return FALSE; // no CPUID
if (FamilyCPUID () < 5) return FALSE; // must be 486
Features = VersionCPUID ();
if (!(Features & 0x1)) return FALSE; // no float
return TRUE;
}
int isPentiumMMX (void)
{
char Brand [64];
unsigned int Features;
// Returns TRUE if processor is a Pentium with MMX or compatible.
if (!AvailCPUID ()) return FALSE;
if (FamilyCPUID () < 5) return FALSE;
Features = VersionCPUID ();
if (!(Features & 0x1)) return FALSE; // no float
if (!(Features & 0x800000)) return FALSE; // no MMX
return TRUE;
}
int isPentiumPro (void)
{
char Brand [64];
unsigned int Features;
// Returns TRUE if processor is a Pentium Pro or compatible.
if (!AvailCPUID ()) return FALSE;
if (FamilyCPUID () < 6) return FALSE;
Features = VersionCPUID ();
if (!(Features & 0x1)) return FALSE; // no float
if (!(Features & 0x8000)) return FALSE; // no CMOV/FCMOV/FCOMI
return TRUE;
}
int isPentiumII (void)
{
char Brand [64];
unsigned int Features;
// Returns TRUE if processor is a Pentium II or compatible.
if (!AvailCPUID ()) return FALSE;
if (FamilyCPUID () < 6) return FALSE;
Features = VersionCPUID ();
if (!(Features & 0x1)) return FALSE; // no float
if (!(Features & 0x8000)) return FALSE; // no CMOV/FCMOV/FCOMI
if (!(Features & 0x800000)) return FALSE; // no MMX
return TRUE;
}
int isPentiumIII (void)
{
char Brand [64];
unsigned int Features;
// Returns TRUE if processor is a Pentium III or compatible.
// Returns FALSE if Pentium III with no operating system support
if (!AvailCPUID ()) return FALSE;
if (FamilyCPUID () < 6) return FALSE;
Features = VersionCPUID ();
if (!(Features & 0x1)) return FALSE; // no float
if (!(Features & 0x8000)) return FALSE; // no CMOV/FCMOV/FCOMI
if (!(Features & 0x800000)) return FALSE; // no MMX
if (!(Features & 0x2000000)) return FALSE; // no Streaming SIMD
return TRUE;
}
int isAMDK6 (void)
{
char Brand [64];
unsigned int Features;
// Returns TRUE if processor is an AMD K6 with MMX or compatible.
// Returns FALSE if processor is a Pentium MMX, even though this
// is a compatible processor. Use isPentiumMMX for that.
if (!AvailCPUID ()) return FALSE;
if (FamilyCPUID () < 5) return FALSE; // not Pentium class or above
if (FirstCPUID (Brand) < 1) return FALSE;
if (FirstAMDCPUID () < 0x80000001) return FALSE;
Features = AMDVersionCPUID ();
if (!(Features & 0x1)) return FALSE; // no float
if (!(Features & 0x800000)) return FALSE; // no MMX
return TRUE;
}
int isAMDK62 (void)
{
char Brand [64];
unsigned int Features;
// Returns TRUE if processor is an AMD K6 with MMX and 3DNow! or compatible.
if (!AvailCPUID ()) return FALSE;
if (FamilyCPUID () < 5) return FALSE; // not Pentium class or above
if (FirstCPUID (Brand) < 1) return FALSE;
if (FirstAMDCPUID () < 0x80000001) return FALSE;
Features = AMDVersionCPUID ();
if (!(Features & 0x1)) return FALSE; // no float
if (!(Features & 0x800000)) return FALSE; // no MMX
if (!(Features & 0x80000000)) return FALSE; // no 3DNow!
return TRUE;
}
int isAthlon (void)
{
char Brand [64];
unsigned int Features;
// Returns TRUE if processor is an AMD Athlon with MMX and Advanced 3DNow! or compatible.
if (!AvailCPUID ()) return FALSE;
if (FamilyCPUID () < 6) return FALSE; // not Pentium Pro class or above
if (FirstCPUID (Brand) < 1) return FALSE;
if (FirstAMDCPUID () < 0x80000001) return FALSE;
Features = AMDVersionCPUID ();
if (!(Features & 0x1)) return FALSE; // no float
if (!(Features & 0x8000)) return FALSE; // no CMOV/FCMOV/FCOMI
if (!(Features & 0x800000)) return FALSE; // no MMX
if (!(Features & 0x400000)) return FALSE; // no K7 MMX
if (!(Features & 0x80000000)) return FALSE; // no 3DNow!
if (!(Features & 0x40000000)) return FALSE; // no Advanced 3DNow!
return TRUE;
}
void main (void)
{
int Avail, Level;
unsigned int Features, AMDLevel, AMDFeatures;
char Brand [64];
if (AvailCPUID ())
{
printf ("CPUID available\n");
Level = FirstCPUID (Brand);
printf ("CPUID brand: %s, max eax value: %d\n", Brand, Level);
if (Level >= 1)
{
printf ("Family = %d\n", (FamilyCPUID () >> 8) & 0xF);
Features = VersionCPUID ();
if (Features & 1) printf ("Floating-point\n");
if (Features & 0x8000) printf ("CMOV / FCMOV / FCOMI supported\n");
if (Features & 0x800000) printf ("MMX supported\n");
if (Features & 0x2000000)
{
printf ("Streaming SIMD Extensions supported by processor\n");
}
AMDLevel = FirstAMDCPUID ();
if (AMDLevel >= 0x80000001)
{
AMDFeatures = AMDVersionCPUID ();
if (AMDFeatures & 0x400000) printf ("AMD K7 MMX Extensions\n");
if (AMDFeatures & 0x40000000) printf ("AMD K7 3DNow! Extensions\n");
if (AMDFeatures & 0x80000000) printf ("AMD 3DNow! Extensions\n");
}
}
}
else
printf ("CPUID not available - must be 486 or less\n");
if (isPentium ()) printf ("isPentium\n");
if (isPentiumMMX ()) printf ("isPentiumMMX\n");
if (isPentiumPro ()) printf ("isPentiumPro\n");
if (isPentiumII ()) printf ("isPentiumII\n");
if (isPentiumIII ()) printf ("isPentiumIII\n");
if (isAMDK6 ()) printf ("isAMDK6\n");
if (isAMDK62 ()) printf ("isAMDK62\n");
if (isAthlon ()) printf ("isAthlon\n");
}
//////////////////// code end ///////////////////////////////////////////////