aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.dg/i386-cpuid.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/testsuite/gcc.dg/i386-cpuid.h')
-rw-r--r--gcc/testsuite/gcc.dg/i386-cpuid.h59
1 files changed, 59 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.dg/i386-cpuid.h b/gcc/testsuite/gcc.dg/i386-cpuid.h
index 695b4c9..c7b999c 100644
--- a/gcc/testsuite/gcc.dg/i386-cpuid.h
+++ b/gcc/testsuite/gcc.dg/i386-cpuid.h
@@ -12,6 +12,10 @@
#define bit_SSE (1 << 25)
#define bit_SSE2 (1 << 26)
+/* Extended Features */
+/* %ecx */
+#define bit_SSE4a (1 << 6)
+
#ifndef NOINLINE
#define NOINLINE __attribute__ ((noinline))
#endif
@@ -60,8 +64,43 @@ i386_get_cpuid (unsigned int *ecx, unsigned int *edx)
return 1;
}
+static inline unsigned int
+i386_get_extended_cpuid (unsigned int *ecx, unsigned int *edx)
+{
+ int fl1;
+ if (!(i386_get_cpuid (ecx, edx)))
+ return 0;
+
+ /* Invoke CPUID(0x80000000) to get the highest supported extended function
+ number */
+#ifdef __x86_64__
+ __asm__ ("cpuid"
+ : "=a" (fl1) : "0" (0x80000000) : "edx", "ecx", "ebx");
+#else
+ __asm__ ("pushl %%ebx; cpuid; popl %%ebx"
+ : "=a" (fl1) : "0" (0x80000000) : "edx", "ecx");
+#endif
+ /* Check if highest supported extended function used below are supported */
+ if (fl1 < 0x80000001)
+ return 0;
+
+ /* Invoke CPUID(0x80000001), return %ecx and %edx; caller can examine bits to
+ determine what's supported. */
+#ifdef __x86_64__
+ __asm__ ("cpuid"
+ : "=c" (*ecx), "=d" (*edx), "=a" (fl1) : "2" (0x80000001) : "ebx");
+#else
+ __asm__ ("pushl %%ebx; cpuid; popl %%ebx"
+ : "=c" (*ecx), "=d" (*edx), "=a" (fl1) : "2" (0x80000001));
+#endif
+ return 1;
+}
+
+
unsigned int i386_cpuid_ecx (void) NOINLINE;
unsigned int i386_cpuid_edx (void) NOINLINE;
+unsigned int i386_extended_cpuid_ecx (void) NOINLINE;
+unsigned int i386_extended_cpuid_edx (void) NOINLINE;
unsigned int NOINLINE
i386_cpuid_ecx (void)
@@ -83,6 +122,26 @@ i386_cpuid_edx (void)
return 0;
}
+unsigned int NOINLINE
+i386_extended_cpuid_ecx (void)
+{
+ unsigned int ecx, edx;
+ if (i386_get_extended_cpuid (&ecx, &edx))
+ return ecx;
+ else
+ return 0;
+}
+
+unsigned int NOINLINE
+i386_extended_cpuid_edx (void)
+{
+ unsigned int ecx, edx;
+ if (i386_get_extended_cpuid (&ecx, &edx))
+ return edx;
+ else
+ return 0;
+}
+
static inline unsigned int
i386_cpuid (void)
{