1
/* CpuArch.c -- CPU specific code
2
2010-10-26: Igor Pavlov : Public domain */
6
#ifdef MY_CPU_X86_OR_AMD64
8
#if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__)
12
#if defined(USE_ASM) && !defined(MY_CPU_AMD64)
13
static UInt32 CheckFlag(UInt32 flag)
29
__asm__ __volatile__ (
32
"movl %%EAX,%%EDX\n\t"
38
"xorl %%EDX,%%EAX\n\t"
42
"=c" (flag) : "c" (flag));
46
#define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) return False;
48
#define CHECK_CPUID_IS_SUPPORTED
51
static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
57
UInt32 a2, b2, c2, d2;
61
__asm mov EAX, function;
75
__asm__ __volatile__ (
88
__cpuid(CPUInfo, function);
97
Bool x86cpuid_CheckAndRead(Cx86cpuid *p)
99
CHECK_CPUID_IS_SUPPORTED
100
MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]);
101
MyCPUID(1, &p->ver, &p->b, &p->c, &p->d);
105
static UInt32 kVendors[][3] =
107
{ 0x756E6547, 0x49656E69, 0x6C65746E},
108
{ 0x68747541, 0x69746E65, 0x444D4163},
109
{ 0x746E6543, 0x48727561, 0x736C7561}
112
int x86cpuid_GetFirm(const Cx86cpuid *p)
115
for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++)
117
const UInt32 *v = kVendors[i];
118
if (v[0] == p->vendor[0] &&
119
v[1] == p->vendor[1] &&
120
v[2] == p->vendor[2])
126
Bool CPU_Is_InOrder()
130
UInt32 family, model;
131
if (!x86cpuid_CheckAndRead(&p))
133
family = x86cpuid_GetFamily(&p);
134
model = x86cpuid_GetModel(&p);
135
firm = x86cpuid_GetFirm(&p);
138
case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && model == 0x100C));
139
case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
140
case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));
145
#if !defined(MY_CPU_AMD64) && defined(_WIN32)
146
static Bool CPU_Sys_Is_SSE_Supported()
149
vi.dwOSVersionInfoSize = sizeof(vi);
150
if (!GetVersionEx(&vi))
152
return (vi.dwMajorVersion >= 5);
154
#define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False;
156
#define CHECK_SYS_SSE_SUPPORT
159
Bool CPU_Is_Aes_Supported()
162
CHECK_SYS_SSE_SUPPORT
163
if (!x86cpuid_CheckAndRead(&p))
165
return (p.c >> 25) & 1;