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)
10 #define bit_CMOV (1 << 15)
11 #define bit_MMX (1 << 23)
12 #define bit_SSE (1 << 25)
13 #define bit_SSE2 (1 << 26)
15 /* Extended Features */
17 #define bit_SSE4a (1 << 6)
20 #define NOINLINE __attribute__ ((noinline))
23 static inline unsigned int
24 i386_get_cpuid (unsigned int *ecx, unsigned int *edx)
31 /* See if we can use cpuid. On AMD64 we always can. */
32 __asm__ ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;"
33 "pushl %0; popfl; pushfl; popl %0; popfl"
34 : "=&r" (fl1), "=&r" (fl2)
36 if (((fl1 ^ fl2) & 0x00200000) == 0)
40 /* Host supports cpuid. See if cpuid gives capabilities, try
41 CPUID(0). Preserve %ebx and %ecx; cpuid insn clobbers these, we
42 don't need their CPUID values here, and %ebx may be the PIC
45 __asm__ ("pushq %%rcx; pushq %%rbx; cpuid; popq %%rbx; popq %%rcx"
46 : "=a" (fl1) : "0" (0) : "rdx", "cc");
48 __asm__ ("pushl %%ecx; pushl %%ebx; cpuid; popl %%ebx; popl %%ecx"
49 : "=a" (fl1) : "0" (0) : "edx", "cc");
54 /* Invoke CPUID(1), return %ecx and %edx; caller can examine bits to
55 determine what's supported. */
57 __asm__ ("pushq %%rbx; cpuid; popq %%rbx"
58 : "=c" (*ecx), "=d" (*edx), "=a" (fl1) : "2" (1) : "cc");
60 __asm__ ("pushl %%ebx; cpuid; popl %%ebx"
61 : "=c" (*ecx), "=d" (*edx), "=a" (fl1) : "2" (1) : "cc");
67 static inline unsigned int
68 i386_get_extended_cpuid (unsigned int *ecx, unsigned int *edx)
71 if (!(i386_get_cpuid (ecx, edx)))
74 /* Invoke CPUID(0x80000000) to get the highest supported extended function
78 : "=a" (fl1) : "0" (0x80000000) : "edx", "ecx", "ebx");
80 __asm__ ("pushl %%ebx; cpuid; popl %%ebx"
81 : "=a" (fl1) : "0" (0x80000000) : "edx", "ecx");
83 /* Check if highest supported extended function used below are supported */
87 /* Invoke CPUID(0x80000001), return %ecx and %edx; caller can examine bits to
88 determine what's supported. */
91 : "=c" (*ecx), "=d" (*edx), "=a" (fl1) : "2" (0x80000001) : "ebx");
93 __asm__ ("pushl %%ebx; cpuid; popl %%ebx"
94 : "=c" (*ecx), "=d" (*edx), "=a" (fl1) : "2" (0x80000001));
100 unsigned int i386_cpuid_ecx (void) NOINLINE;
101 unsigned int i386_cpuid_edx (void) NOINLINE;
102 unsigned int i386_extended_cpuid_ecx (void) NOINLINE;
103 unsigned int i386_extended_cpuid_edx (void) NOINLINE;
105 unsigned int NOINLINE
106 i386_cpuid_ecx (void)
108 unsigned int ecx, edx;
109 if (i386_get_cpuid (&ecx, &edx))
115 unsigned int NOINLINE
116 i386_cpuid_edx (void)
118 unsigned int ecx, edx;
119 if (i386_get_cpuid (&ecx, &edx))
125 unsigned int NOINLINE
126 i386_extended_cpuid_ecx (void)
128 unsigned int ecx, edx;
129 if (i386_get_extended_cpuid (&ecx, &edx))
135 unsigned int NOINLINE
136 i386_extended_cpuid_edx (void)
138 unsigned int ecx, edx;
139 if (i386_get_extended_cpuid (&ecx, &edx))
145 static inline unsigned int
148 return i386_cpuid_edx ();