diff options
Diffstat (limited to 'gcc/testsuite/gcc.dg/i386-cpuid.h')
| -rw-r--r-- | gcc/testsuite/gcc.dg/i386-cpuid.h | 59 |
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) { |
