Remove unused and unsupported Cyrix's "Extended MMX",
[ffmpeg.git] / libavcodec / i386 / cputest.c
1 /* Cpu detection code, extracted from mmx.h ((c)1997-99 by H. Dietz
2    and R. Fisher). Converted to C and improved by Fabrice Bellard */
3
4 #include <stdlib.h>
5 #include "../dsputil.h"
6
7 #ifdef ARCH_X86_64
8 #  define REG_b "rbx"
9 #  define REG_S "rsi"
10 #else
11 #  define REG_b "ebx"
12 #  define REG_S "esi"
13 #endif
14
15 /* ebx saving is necessary for PIC. gcc seems unable to see it alone */
16 #define cpuid(index,eax,ebx,ecx,edx)\
17     __asm __volatile\
18         ("mov %%"REG_b", %%"REG_S"\n\t"\
19          "cpuid\n\t"\
20          "xchg %%"REG_b", %%"REG_S\
21          : "=a" (eax), "=S" (ebx),\
22            "=c" (ecx), "=d" (edx)\
23          : "0" (index));
24
25 /* Function to test if multimedia instructions are supported...  */
26 int mm_support(void)
27 {
28     int rval = 0;
29     int eax, ebx, ecx, edx;
30     int max_std_level, max_ext_level, std_caps=0, ext_caps=0;
31     long a, c;
32
33     __asm__ __volatile__ (
34                           /* See if CPUID instruction is supported ... */
35                           /* ... Get copies of EFLAGS into eax and ecx */
36                           "pushf\n\t"
37                           "pop %0\n\t"
38                           "mov %0, %1\n\t"
39
40                           /* ... Toggle the ID bit in one copy and store */
41                           /*     to the EFLAGS reg */
42                           "xor $0x200000, %0\n\t"
43                           "push %0\n\t"
44                           "popf\n\t"
45
46                           /* ... Get the (hopefully modified) EFLAGS */
47                           "pushf\n\t"
48                           "pop %0\n\t"
49                           : "=a" (a), "=c" (c)
50                           :
51                           : "cc"
52                           );
53
54     if (a == c)
55         return 0; /* CPUID not supported */
56
57     cpuid(0, max_std_level, ebx, ecx, edx);
58
59     if(max_std_level >= 1){
60         cpuid(1, eax, ebx, ecx, std_caps);
61         if (std_caps & (1<<23))
62             rval |= MM_MMX;
63         if (std_caps & (1<<25))
64             rval |= MM_MMXEXT | MM_SSE;
65         if (std_caps & (1<<26))
66             rval |= MM_SSE2;
67         if (ecx & 1)
68             rval |= MM_SSE3;
69     }
70
71     cpuid(0x80000000, max_ext_level, ebx, ecx, edx);
72
73     if(max_ext_level >= 0x80000001){
74         cpuid(0x80000001, eax, ebx, ecx, ext_caps);
75         if (ext_caps & (1<<31))
76             rval |= MM_3DNOW;
77         if (ext_caps & (1<<30))
78             rval |= MM_3DNOWEXT;
79         if (ext_caps & (1<<23))
80             rval |= MM_MMX;
81         if (ext_caps & (1<<22))
82             rval |= MM_MMXEXT;
83     }
84
85 #if 0
86     av_log(NULL, AV_LOG_DEBUG, "%s%s%s%s%s%s\n",
87         (rval&MM_MMX) ? "MMX ":"",
88         (rval&MM_MMXEXT) ? "MMX2 ":"",
89         (rval&MM_SSE) ? "SSE ":"",
90         (rval&MM_SSE2) ? "SSE2 ":"",
91         (rval&MM_3DNOW) ? "3DNow ":"",
92         (rval&MM_3DNOWEXT) ? "3DNowExt ":"");
93 #endif
94     return rval;
95 }
96
97 #ifdef __TEST__
98 int main ( void )
99 {
100   int mm_flags;
101   mm_flags = mm_support();
102   printf("mm_support = 0x%08X\n",mm_flags);
103   return 0;
104 }
105 #endif