2 #include "cpu_features.h"
5 #define EDX_CX8 (1 << 8) /* CMPXCHG8B */
6 #define EDX_CMOV (1 << 15)
7 #define EDX_MMX (1 << 23)
8 #define EDX_FXSR (1 << 24) /* FXSAVE and FXRSTOR */
9 #define EDX_SSE (1 << 25)
10 #define EDX_SSE2 (1 << 26)
12 /* level 1 ecx bits */
13 #define ECX_SSE3 (1 << 0)
14 #define ECX_CX16 (1 << 13) /* CMPXCHG16B */
16 /* extended level 0x80000001 edx bits */
17 #define EDX_3DNOW (1 << 31)
18 #define EDX_3DNOWP (1 << 30)
19 #define EDX_LM (1 << 29) /*LONG MODE */
21 #define __cpuid(level,a,b,c,d) \
22 asm volatile ("cpuid;" \
23 : "=a" (a), "=b" (b), "=c" (c), "=d" (d)\
26 /* Combine the different cpuid flags into a single bitmap. */
28 unsigned int __cpu_features = 0;
30 void __cpu_features_init (void)
32 unsigned int eax, ebx, ecx, edx;
33 /* Try to change the value of CPUID bit (bit 21) in EFLAGS.
34 If the bit can be toggled, CPUID is supported. */
35 asm volatile ("pushfl; pushfl; popl %0;"
36 "movl %0,%1; xorl %2,%0;"
37 "pushl %0; popfl; pushfl; popl %0; popfl"
38 : "=&r" (eax), "=&r" (ebx)
41 if (((eax ^ ebx) & 0x00200000) == 0)
44 __cpuid (0, eax, ebx, ecx, edx);
48 __cpuid (1, eax, ebx, ecx, edx);
51 __cpu_features |= _CRT_CMPXCHG8B;
53 __cpu_features |= _CRT_CMOV;
56 __cpu_features |= _CRT_MMX;
58 __cpu_features |= _CRT_FXSR;
60 __cpu_features |= _CRT_SSE;
62 __cpu_features |= _CRT_SSE2;
66 __cpu_features |= _CRT_SSE3;
68 __cpu_features |= _CRT_CMPXCHG16B;
70 __cpuid (0x80000000, eax, ebx, ecx, edx);
73 __cpuid (0x80000001, eax, ebx, ecx, edx);
75 __cpu_features |= _CRT_3DNOW;
77 __cpu_features |= _CRT_3DNOWP;
85 #define report(feature) \
86 if ((feature) & __cpu_features) printf( #feature " found\n")
90 __cpu_features_init();
92 report(_CRT_CMPXCHG8B);
99 report(_CRT_CMPXCHG16B);