b730cc11a9a65fd63a892b8f9fc0df7e347ef37b
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)
33 unsigned int eax
, ebx
, ecx
, edx
;
34 /* Try to change the value of CPUID bit (bit 21) in EFLAGS.
35 If the bit can be toggled, CPUID is supported. */
36 asm volatile ("pushfl; pushfl; popl %0;"
37 "movl %0,%1; xorl %2,%0;"
38 "pushl %0; popfl; pushfl; popl %0; popfl"
39 : "=&r" (eax
), "=&r" (ebx
)
42 if (((eax
^ ebx
) & 0x00200000) == 0)
45 __cpuid (0, eax
, ebx
, ecx
, edx
);
49 __cpuid (1, eax
, ebx
, ecx
, edx
);
52 __cpu_features
|= _CRT_CMPXCHG8B
;
54 __cpu_features
|= _CRT_CMOV
;
57 __cpu_features
|= _CRT_MMX
;
59 __cpu_features
|= _CRT_FXSR
;
61 __cpu_features
|= _CRT_SSE
;
63 __cpu_features
|= _CRT_SSE2
;
67 __cpu_features
|= _CRT_SSE3
;
69 __cpu_features
|= _CRT_CMPXCHG16B
;
71 __cpuid (0x80000000, eax
, ebx
, ecx
, edx
);
74 __cpuid (0x80000001, eax
, ebx
, ecx
, edx
);
76 __cpu_features
|= _CRT_3DNOW
;
78 __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
);