1 /* Helper file for i386 platform. Runtime check for MMX/SSE/SSE2 support.
2 Used by 20020523-2.c and i386-sse-6.c, and possibly others. */
3 /* Plagarized from 20020523-2.c. */
6 #define bit_SSE3 (1 << 0)
7 #define bit_SSSE3 (1 << 9)
8 #define bit_SSE4_1 (1 << 19)
9 #define bit_SSE4_2 (1 << 20)
10 #define bit_POPCNT (1 << 23)
13 #define bit_CMOV (1 << 15)
14 #define bit_MMX (1 << 23)
15 #define bit_SSE (1 << 25)
16 #define bit_SSE2 (1 << 26)
18 /* Extended Features */
20 #define bit_SSE4a (1 << 6)
23 #define NOINLINE __attribute__ ((noinline))
26 static inline unsigned int
27 i386_get_cpuid (unsigned int *ecx, unsigned int *edx)
34 /* See if we can use cpuid. On AMD64 we always can. */
35 __asm__ ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;"
36 "pushl %0; popfl; pushfl; popl %0; popfl"
37 : "=&r" (fl1), "=&r" (fl2)
39 if (((fl1 ^ fl2) & 0x00200000) == 0)
43 /* Host supports cpuid. See if cpuid gives capabilities, try
44 CPUID(0). Preserve %ebx and %ecx; cpuid insn clobbers these, we
45 don't need their CPUID values here, and %ebx may be the PIC
48 __asm__ ("pushq %%rcx; pushq %%rbx; cpuid; popq %%rbx; popq %%rcx"
49 : "=a" (fl1) : "0" (0) : "rdx", "cc");
51 __asm__ ("pushl %%ecx; pushl %%ebx; cpuid; popl %%ebx; popl %%ecx"
52 : "=a" (fl1) : "0" (0) : "edx", "cc");
57 /* Invoke CPUID(1), return %ecx and %edx; caller can examine bits to
58 determine what's supported. */
60 __asm__ ("pushq %%rbx; cpuid; popq %%rbx"
61 : "=c" (*ecx), "=d" (*edx), "=a" (fl1) : "2" (1) : "cc");
63 __asm__ ("pushl %%ebx; cpuid; popl %%ebx"
64 : "=c" (*ecx), "=d" (*edx), "=a" (fl1) : "2" (1) : "cc");
70 static inline unsigned int
71 i386_get_extended_cpuid (unsigned int *ecx, unsigned int *edx)
74 if (!(i386_get_cpuid (ecx, edx)))
77 /* Invoke CPUID(0x80000000) to get the highest supported extended function
81 : "=a" (fl1) : "0" (0x80000000) : "edx", "ecx", "ebx");
83 __asm__ ("pushl %%ebx; cpuid; popl %%ebx"
84 : "=a" (fl1) : "0" (0x80000000) : "edx", "ecx");
86 /* Check if highest supported extended function used below are supported */
90 /* Invoke CPUID(0x80000001), return %ecx and %edx; caller can examine bits to
91 determine what's supported. */
94 : "=c" (*ecx), "=d" (*edx), "=a" (fl1) : "2" (0x80000001) : "ebx");
96 __asm__ ("pushl %%ebx; cpuid; popl %%ebx"
97 : "=c" (*ecx), "=d" (*edx), "=a" (fl1) : "2" (0x80000001));
103 unsigned int i386_cpuid_ecx (void) NOINLINE;
104 unsigned int i386_cpuid_edx (void) NOINLINE;
105 unsigned int i386_extended_cpuid_ecx (void) NOINLINE;
106 unsigned int i386_extended_cpuid_edx (void) NOINLINE;
108 unsigned int NOINLINE
109 i386_cpuid_ecx (void)
111 unsigned int ecx, edx;
112 if (i386_get_cpuid (&ecx, &edx))
118 unsigned int NOINLINE
119 i386_cpuid_edx (void)
121 unsigned int ecx, edx;
122 if (i386_get_cpuid (&ecx, &edx))
128 unsigned int NOINLINE
129 i386_extended_cpuid_ecx (void)
131 unsigned int ecx, edx;
132 if (i386_get_extended_cpuid (&ecx, &edx))
138 unsigned int NOINLINE
139 i386_extended_cpuid_edx (void)
141 unsigned int ecx, edx;
142 if (i386_get_extended_cpuid (&ecx, &edx))
148 static inline unsigned int
151 return i386_cpuid_edx ();