Merge "Support for extended feature flags enumeration leaf in CPUID instruction"

This commit is contained in:
Yunqing Wang 2013-11-20 12:01:39 -08:00 committed by Gerrit Code Review
commit 82f8ae4c5b
2 changed files with 21 additions and 14 deletions

View File

@ -35,51 +35,53 @@ typedef enum {
#if defined(__GNUC__) && __GNUC__ || defined(__ANDROID__) #if defined(__GNUC__) && __GNUC__ || defined(__ANDROID__)
#if ARCH_X86_64 #if ARCH_X86_64
#define cpuid(func,ax,bx,cx,dx)\ #define cpuid(func, func2, ax, bx, cx, dx)\
__asm__ __volatile__ (\ __asm__ __volatile__ (\
"cpuid \n\t" \ "cpuid \n\t" \
: "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) \ : "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) \
: "a" (func)); : "a" (func), "c" (func2));
#else #else
#define cpuid(func,ax,bx,cx,dx)\ #define cpuid(func, func2, ax, bx, cx, dx)\
__asm__ __volatile__ (\ __asm__ __volatile__ (\
"mov %%ebx, %%edi \n\t" \ "mov %%ebx, %%edi \n\t" \
"cpuid \n\t" \ "cpuid \n\t" \
"xchg %%edi, %%ebx \n\t" \ "xchg %%edi, %%ebx \n\t" \
: "=a" (ax), "=D" (bx), "=c" (cx), "=d" (dx) \ : "=a" (ax), "=D" (bx), "=c" (cx), "=d" (dx) \
: "a" (func)); : "a" (func), "c" (func2));
#endif #endif
#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* end __GNUC__ or __ANDROID__*/ #elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* end __GNUC__ or __ANDROID__*/
#if ARCH_X86_64 #if ARCH_X86_64
#define cpuid(func,ax,bx,cx,dx)\ #define cpuid(func, func2, ax, bx, cx, dx)\
asm volatile (\ asm volatile (\
"xchg %rsi, %rbx \n\t" \ "xchg %rsi, %rbx \n\t" \
"cpuid \n\t" \ "cpuid \n\t" \
"movl %ebx, %edi \n\t" \ "movl %ebx, %edi \n\t" \
"xchg %rsi, %rbx \n\t" \ "xchg %rsi, %rbx \n\t" \
: "=a" (ax), "=D" (bx), "=c" (cx), "=d" (dx) \ : "=a" (ax), "=D" (bx), "=c" (cx), "=d" (dx) \
: "a" (func)); : "a" (func), "c" (func2));
#else #else
#define cpuid(func,ax,bx,cx,dx)\ #define cpuid(func, func2, ax, bx, cx, dx)\
asm volatile (\ asm volatile (\
"pushl %ebx \n\t" \ "pushl %ebx \n\t" \
"cpuid \n\t" \ "cpuid \n\t" \
"movl %ebx, %edi \n\t" \ "movl %ebx, %edi \n\t" \
"popl %ebx \n\t" \ "popl %ebx \n\t" \
: "=a" (ax), "=D" (bx), "=c" (cx), "=d" (dx) \ : "=a" (ax), "=D" (bx), "=c" (cx), "=d" (dx) \
: "a" (func)); : "a" (func), "c" (func2));
#endif #endif
#else /* end __SUNPRO__ */ #else /* end __SUNPRO__ */
#if ARCH_X86_64 #if ARCH_X86_64
void __cpuid(int CPUInfo[4], int info_type); void __cpuid(int CPUInfo[4], int info_type);
#pragma intrinsic(__cpuid) #pragma intrinsic(__cpuid)
#define cpuid(func,a,b,c,d) do{\ #define cpuid(func, func2, a, b, c, d) do {\
int regs[4];\ int regs[4];\
__cpuid(regs,func); a=regs[0]; b=regs[1]; c=regs[2]; d=regs[3];\ __cpuid(regs, func, func2);
a = regs[0]; b = regs[1]; c = regs[2]; d = regs[3];\
} while(0) } while(0)
#else #else
#define cpuid(func,a,b,c,d)\ #define cpuid(func, func2, a, b, c, d)\
__asm mov eax, func\ __asm mov eax, func\
__asm mov ecx, func2\
__asm cpuid\ __asm cpuid\
__asm mov a, eax\ __asm mov a, eax\
__asm mov b, ebx\ __asm mov b, ebx\
@ -120,13 +122,13 @@ x86_simd_caps(void) {
mask = strtol(env, NULL, 0); mask = strtol(env, NULL, 0);
/* Ensure that the CPUID instruction supports extended features */ /* Ensure that the CPUID instruction supports extended features */
cpuid(0, reg_eax, reg_ebx, reg_ecx, reg_edx); cpuid(0, 0, reg_eax, reg_ebx, reg_ecx, reg_edx);
if (reg_eax < 1) if (reg_eax < 1)
return 0; return 0;
/* Get the standard feature flags */ /* Get the standard feature flags */
cpuid(1, reg_eax, reg_ebx, reg_ecx, reg_edx); cpuid(1, 0, reg_eax, reg_ebx, reg_ecx, reg_edx);
if (reg_edx & BIT(23)) flags |= HAS_MMX; if (reg_edx & BIT(23)) flags |= HAS_MMX;
@ -142,6 +144,11 @@ x86_simd_caps(void) {
if (reg_ecx & BIT(28)) flags |= HAS_AVX; if (reg_ecx & BIT(28)) flags |= HAS_AVX;
/* Get the leaf 7 feature flags. Needed to check for AVX2 support */
reg_eax = 7;
reg_ecx = 0;
cpuid(7, 0, reg_eax, reg_ebx, reg_ecx, reg_edx);
if (reg_ebx & BIT(5)) flags |= HAS_AVX2; if (reg_ebx & BIT(5)) flags |= HAS_AVX2;
return flags & mask; return flags & mask;

View File

@ -38,7 +38,7 @@ vpx_cpu_t vpx_x86_vendor(void) {
int i; int i;
/* Get the Vendor String from the CPU */ /* Get the Vendor String from the CPU */
cpuid(0, reg_eax, vs[0], vs[2], vs[1]); cpuid(0, 0, reg_eax, vs[0], vs[2], vs[1]);
for (i = 0; i < VPX_CPU_LAST; i++) { for (i = 0; i < VPX_CPU_LAST; i++) {
if (strncmp((const char *)vs, cpuid_vendor_list[i].vendor_string, 12) == 0) if (strncmp((const char *)vs, cpuid_vendor_list[i].vendor_string, 12) == 0)