2006-12-15 H.J. Lu <hongjiu.lu@intel.com>
[official-gcc.git] / gcc / testsuite / gcc.dg / i386-cpuid.h
blob695b4c9ce72675a986d6d27a0670a04393b44b3c
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. */
5 /* %ecx */
6 #define bit_SSE3 (1 << 0)
7 #define bit_SSSE3 (1 << 9)
9 /* %edx */
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 #ifndef NOINLINE
16 #define NOINLINE __attribute__ ((noinline))
17 #endif
19 static inline unsigned int
20 i386_get_cpuid (unsigned int *ecx, unsigned int *edx)
22 int fl1;
24 #ifndef __x86_64__
25 int fl2;
27 /* See if we can use cpuid. On AMD64 we always can. */
28 __asm__ ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;"
29 "pushl %0; popfl; pushfl; popl %0; popfl"
30 : "=&r" (fl1), "=&r" (fl2)
31 : "i" (0x00200000));
32 if (((fl1 ^ fl2) & 0x00200000) == 0)
33 return (0);
34 #endif
36 /* Host supports cpuid. See if cpuid gives capabilities, try
37 CPUID(0). Preserve %ebx and %ecx; cpuid insn clobbers these, we
38 don't need their CPUID values here, and %ebx may be the PIC
39 register. */
40 #ifdef __x86_64__
41 __asm__ ("pushq %%rcx; pushq %%rbx; cpuid; popq %%rbx; popq %%rcx"
42 : "=a" (fl1) : "0" (0) : "rdx", "cc");
43 #else
44 __asm__ ("pushl %%ecx; pushl %%ebx; cpuid; popl %%ebx; popl %%ecx"
45 : "=a" (fl1) : "0" (0) : "edx", "cc");
46 #endif
47 if (fl1 == 0)
48 return (0);
50 /* Invoke CPUID(1), return %ecx and %edx; caller can examine bits to
51 determine what's supported. */
52 #ifdef __x86_64__
53 __asm__ ("pushq %%rbx; cpuid; popq %%rbx"
54 : "=c" (*ecx), "=d" (*edx), "=a" (fl1) : "2" (1) : "cc");
55 #else
56 __asm__ ("pushl %%ebx; cpuid; popl %%ebx"
57 : "=c" (*ecx), "=d" (*edx), "=a" (fl1) : "2" (1) : "cc");
58 #endif
60 return 1;
63 unsigned int i386_cpuid_ecx (void) NOINLINE;
64 unsigned int i386_cpuid_edx (void) NOINLINE;
66 unsigned int NOINLINE
67 i386_cpuid_ecx (void)
69 unsigned int ecx, edx;
70 if (i386_get_cpuid (&ecx, &edx))
71 return ecx;
72 else
73 return 0;
76 unsigned int NOINLINE
77 i386_cpuid_edx (void)
79 unsigned int ecx, edx;
80 if (i386_get_cpuid (&ecx, &edx))
81 return edx;
82 else
83 return 0;
86 static inline unsigned int
87 i386_cpuid (void)
89 return i386_cpuid_edx ();