00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdlib.h>
00024 #include <string.h>
00025 #include "libavutil/x86_cpu.h"
00026 #include "libavutil/cpu.h"
00027
00028
00029 #define cpuid(index,eax,ebx,ecx,edx)\
00030 __asm__ volatile\
00031 ("mov %%"REG_b", %%"REG_S"\n\t"\
00032 "cpuid\n\t"\
00033 "xchg %%"REG_b", %%"REG_S\
00034 : "=a" (eax), "=S" (ebx),\
00035 "=c" (ecx), "=d" (edx)\
00036 : "0" (index));
00037
00038
00039 int ff_get_cpu_flags_x86(void)
00040 {
00041 int rval = 0;
00042 int eax, ebx, ecx, edx;
00043 int max_std_level, max_ext_level, std_caps=0, ext_caps=0;
00044 int family=0, model=0;
00045 union { int i[3]; char c[12]; } vendor;
00046
00047 #if ARCH_X86_32
00048 x86_reg a, c;
00049 __asm__ volatile (
00050
00051
00052 "pushfl\n\t"
00053 "pop %0\n\t"
00054 "mov %0, %1\n\t"
00055
00056
00057
00058 "xor $0x200000, %0\n\t"
00059 "push %0\n\t"
00060 "popfl\n\t"
00061
00062
00063 "pushfl\n\t"
00064 "pop %0\n\t"
00065 : "=a" (a), "=c" (c)
00066 :
00067 : "cc"
00068 );
00069
00070 if (a == c)
00071 return 0;
00072 #endif
00073
00074 cpuid(0, max_std_level, vendor.i[0], vendor.i[2], vendor.i[1]);
00075
00076 if(max_std_level >= 1){
00077 cpuid(1, eax, ebx, ecx, std_caps);
00078 family = ((eax>>8)&0xf) + ((eax>>20)&0xff);
00079 model = ((eax>>4)&0xf) + ((eax>>12)&0xf0);
00080 if (std_caps & (1<<23))
00081 rval |= AV_CPU_FLAG_MMX;
00082 if (std_caps & (1<<25))
00083 rval |= AV_CPU_FLAG_MMX2
00084 #if HAVE_SSE
00085 | AV_CPU_FLAG_SSE;
00086 if (std_caps & (1<<26))
00087 rval |= AV_CPU_FLAG_SSE2;
00088 if (ecx & 1)
00089 rval |= AV_CPU_FLAG_SSE3;
00090 if (ecx & 0x00000200 )
00091 rval |= AV_CPU_FLAG_SSSE3;
00092 if (ecx & 0x00080000 )
00093 rval |= AV_CPU_FLAG_SSE4;
00094 if (ecx & 0x00100000 )
00095 rval |= AV_CPU_FLAG_SSE42;
00096 #endif
00097 ;
00098 }
00099
00100 cpuid(0x80000000, max_ext_level, ebx, ecx, edx);
00101
00102 if(max_ext_level >= 0x80000001){
00103 cpuid(0x80000001, eax, ebx, ecx, ext_caps);
00104 if (ext_caps & (1<<31))
00105 rval |= AV_CPU_FLAG_3DNOW;
00106 if (ext_caps & (1<<30))
00107 rval |= AV_CPU_FLAG_3DNOWEXT;
00108 if (ext_caps & (1<<23))
00109 rval |= AV_CPU_FLAG_MMX;
00110 if (ext_caps & (1<<22))
00111 rval |= AV_CPU_FLAG_MMX2;
00112 }
00113
00114 if (!strncmp(vendor.c, "GenuineIntel", 12) &&
00115 family == 6 && (model == 9 || model == 13 || model == 14)) {
00116
00117
00118
00119 if (rval & AV_CPU_FLAG_SSE2) rval ^= AV_CPU_FLAG_SSE2SLOW|AV_CPU_FLAG_SSE2;
00120 if (rval & AV_CPU_FLAG_SSE3) rval ^= AV_CPU_FLAG_SSE3SLOW|AV_CPU_FLAG_SSE3;
00121 }
00122
00123 return rval;
00124 }