OSDN Git Service

2006-12-15 H.J. Lu <hongjiu.lu@intel.com>
[pf3gnuchains/gcc-fork.git] / gcc / testsuite / gcc.dg / i386-cpuid.h
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.  */
4
5 /* %ecx */
6 #define bit_SSE3 (1 << 0)
7 #define bit_SSSE3 (1 << 9)
8
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)
14
15 #ifndef NOINLINE
16 #define NOINLINE __attribute__ ((noinline))
17 #endif
18
19 static inline unsigned int
20 i386_get_cpuid (unsigned int *ecx, unsigned int *edx)
21 {
22   int fl1;
23
24 #ifndef __x86_64__
25   int fl2;
26
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
35
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);
49
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
59
60   return 1;
61 }
62
63 unsigned int i386_cpuid_ecx (void) NOINLINE;
64 unsigned int i386_cpuid_edx (void) NOINLINE;
65
66 unsigned int NOINLINE
67 i386_cpuid_ecx (void)
68 {
69   unsigned int ecx, edx;
70   if (i386_get_cpuid (&ecx, &edx))
71     return ecx;
72   else
73     return 0;
74 }
75
76 unsigned int NOINLINE
77 i386_cpuid_edx (void)
78 {
79   unsigned int ecx, edx;
80   if (i386_get_cpuid (&ecx, &edx))
81     return edx;
82   else
83     return 0;
84 }
85
86 static inline unsigned int
87 i386_cpuid (void)
88 {
89   return i386_cpuid_edx ();
90 }