Mercurial > libavcodec.hg
annotate i386/cputest.c @ 2299:eb0c851db536 libavcodec
xvid fake divx version workaround
author | michael |
---|---|
date | Fri, 15 Oct 2004 11:48:50 +0000 |
parents | 15cfba1b97b5 |
children | 40542ea560d5 |
rev | line source |
---|---|
0 | 1 /* Cpu detection code, extracted from mmx.h ((c)1997-99 by H. Dietz |
429 | 2 and R. Fisher). Converted to C and improved by Fabrice Bellard */ |
0 | 3 |
4 #include <stdlib.h> | |
5 #include "../dsputil.h" | |
6 | |
2293
15cfba1b97b5
adapting existing mmx/mmx2/sse/3dnow optimizations so they work on x86_64 patch by (Aurelien Jacobs <aurel at gnuage dot org>)
michael
parents:
2129
diff
changeset
|
7 #ifdef ARCH_X86_64 |
15cfba1b97b5
adapting existing mmx/mmx2/sse/3dnow optimizations so they work on x86_64 patch by (Aurelien Jacobs <aurel at gnuage dot org>)
michael
parents:
2129
diff
changeset
|
8 # define REG_b "rbx" |
15cfba1b97b5
adapting existing mmx/mmx2/sse/3dnow optimizations so they work on x86_64 patch by (Aurelien Jacobs <aurel at gnuage dot org>)
michael
parents:
2129
diff
changeset
|
9 # define REG_S "rsi" |
15cfba1b97b5
adapting existing mmx/mmx2/sse/3dnow optimizations so they work on x86_64 patch by (Aurelien Jacobs <aurel at gnuage dot org>)
michael
parents:
2129
diff
changeset
|
10 #else |
15cfba1b97b5
adapting existing mmx/mmx2/sse/3dnow optimizations so they work on x86_64 patch by (Aurelien Jacobs <aurel at gnuage dot org>)
michael
parents:
2129
diff
changeset
|
11 # define REG_b "ebx" |
15cfba1b97b5
adapting existing mmx/mmx2/sse/3dnow optimizations so they work on x86_64 patch by (Aurelien Jacobs <aurel at gnuage dot org>)
michael
parents:
2129
diff
changeset
|
12 # define REG_S "esi" |
15cfba1b97b5
adapting existing mmx/mmx2/sse/3dnow optimizations so they work on x86_64 patch by (Aurelien Jacobs <aurel at gnuage dot org>)
michael
parents:
2129
diff
changeset
|
13 #endif |
15cfba1b97b5
adapting existing mmx/mmx2/sse/3dnow optimizations so they work on x86_64 patch by (Aurelien Jacobs <aurel at gnuage dot org>)
michael
parents:
2129
diff
changeset
|
14 |
22
c31fb57d17a6
Suppressing external gas stuff to improve portability to Win32
nickols_k
parents:
16
diff
changeset
|
15 /* ebx saving is necessary for PIC. gcc seems unable to see it alone */ |
c31fb57d17a6
Suppressing external gas stuff to improve portability to Win32
nickols_k
parents:
16
diff
changeset
|
16 #define cpuid(index,eax,ebx,ecx,edx)\ |
43 | 17 __asm __volatile\ |
2293
15cfba1b97b5
adapting existing mmx/mmx2/sse/3dnow optimizations so they work on x86_64 patch by (Aurelien Jacobs <aurel at gnuage dot org>)
michael
parents:
2129
diff
changeset
|
18 ("mov %%"REG_b", %%"REG_S"\n\t"\ |
22
c31fb57d17a6
Suppressing external gas stuff to improve portability to Win32
nickols_k
parents:
16
diff
changeset
|
19 "cpuid\n\t"\ |
2293
15cfba1b97b5
adapting existing mmx/mmx2/sse/3dnow optimizations so they work on x86_64 patch by (Aurelien Jacobs <aurel at gnuage dot org>)
michael
parents:
2129
diff
changeset
|
20 "xchg %%"REG_b", %%"REG_S\ |
22
c31fb57d17a6
Suppressing external gas stuff to improve portability to Win32
nickols_k
parents:
16
diff
changeset
|
21 : "=a" (eax), "=S" (ebx),\ |
c31fb57d17a6
Suppressing external gas stuff to improve portability to Win32
nickols_k
parents:
16
diff
changeset
|
22 "=c" (ecx), "=d" (edx)\ |
43 | 23 : "0" (index)); |
0 | 24 |
25 /* Function to test if multimedia instructions are supported... */ | |
26 int mm_support(void) | |
27 { | |
28 int rval; | |
29 int eax, ebx, ecx, edx; | |
30 | |
31 __asm__ __volatile__ ( | |
32 /* See if CPUID instruction is supported ... */ | |
33 /* ... Get copies of EFLAGS into eax and ecx */ | |
34 "pushf\n\t" | |
2293
15cfba1b97b5
adapting existing mmx/mmx2/sse/3dnow optimizations so they work on x86_64 patch by (Aurelien Jacobs <aurel at gnuage dot org>)
michael
parents:
2129
diff
changeset
|
35 "pop %0\n\t" |
0 | 36 "movl %0, %1\n\t" |
37 | |
38 /* ... Toggle the ID bit in one copy and store */ | |
39 /* to the EFLAGS reg */ | |
40 "xorl $0x200000, %0\n\t" | |
41 "push %0\n\t" | |
42 "popf\n\t" | |
43 | |
44 /* ... Get the (hopefully modified) EFLAGS */ | |
45 "pushf\n\t" | |
2293
15cfba1b97b5
adapting existing mmx/mmx2/sse/3dnow optimizations so they work on x86_64 patch by (Aurelien Jacobs <aurel at gnuage dot org>)
michael
parents:
2129
diff
changeset
|
46 "pop %0\n\t" |
0 | 47 : "=a" (eax), "=c" (ecx) |
48 : | |
49 : "cc" | |
50 ); | |
51 | |
52 if (eax == ecx) | |
53 return 0; /* CPUID not supported */ | |
54 | |
22
c31fb57d17a6
Suppressing external gas stuff to improve portability to Win32
nickols_k
parents:
16
diff
changeset
|
55 cpuid(0, eax, ebx, ecx, edx); |
0 | 56 |
57 if (ebx == 0x756e6547 && | |
58 edx == 0x49656e69 && | |
59 ecx == 0x6c65746e) { | |
60 | |
61 /* intel */ | |
62 inteltest: | |
22
c31fb57d17a6
Suppressing external gas stuff to improve portability to Win32
nickols_k
parents:
16
diff
changeset
|
63 cpuid(1, eax, ebx, ecx, edx); |
0 | 64 if ((edx & 0x00800000) == 0) |
65 return 0; | |
66 rval = MM_MMX; | |
67 if (edx & 0x02000000) | |
68 rval |= MM_MMXEXT | MM_SSE; | |
69 if (edx & 0x04000000) | |
70 rval |= MM_SSE2; | |
71 return rval; | |
72 } else if (ebx == 0x68747541 && | |
73 edx == 0x69746e65 && | |
74 ecx == 0x444d4163) { | |
75 /* AMD */ | |
22
c31fb57d17a6
Suppressing external gas stuff to improve portability to Win32
nickols_k
parents:
16
diff
changeset
|
76 cpuid(0x80000000, eax, ebx, ecx, edx); |
0 | 77 if ((unsigned)eax < 0x80000001) |
78 goto inteltest; | |
22
c31fb57d17a6
Suppressing external gas stuff to improve portability to Win32
nickols_k
parents:
16
diff
changeset
|
79 cpuid(0x80000001, eax, ebx, ecx, edx); |
0 | 80 if ((edx & 0x00800000) == 0) |
81 return 0; | |
82 rval = MM_MMX; | |
83 if (edx & 0x80000000) | |
84 rval |= MM_3DNOW; | |
85 if (edx & 0x00400000) | |
86 rval |= MM_MMXEXT; | |
87 return rval; | |
889
6a9c3ecf2dec
via c3 detection patch by (Francisco Javier Cabello Torres <fjcabello at visual-tools dot com>)
michaelni
parents:
429
diff
changeset
|
88 } else if (ebx == 0x746e6543 && |
6a9c3ecf2dec
via c3 detection patch by (Francisco Javier Cabello Torres <fjcabello at visual-tools dot com>)
michaelni
parents:
429
diff
changeset
|
89 edx == 0x48727561 && |
6a9c3ecf2dec
via c3 detection patch by (Francisco Javier Cabello Torres <fjcabello at visual-tools dot com>)
michaelni
parents:
429
diff
changeset
|
90 ecx == 0x736c7561) { /* "CentaurHauls" */ |
6a9c3ecf2dec
via c3 detection patch by (Francisco Javier Cabello Torres <fjcabello at visual-tools dot com>)
michaelni
parents:
429
diff
changeset
|
91 /* VIA C3 */ |
6a9c3ecf2dec
via c3 detection patch by (Francisco Javier Cabello Torres <fjcabello at visual-tools dot com>)
michaelni
parents:
429
diff
changeset
|
92 cpuid(0x80000000, eax, ebx, ecx, edx); |
6a9c3ecf2dec
via c3 detection patch by (Francisco Javier Cabello Torres <fjcabello at visual-tools dot com>)
michaelni
parents:
429
diff
changeset
|
93 if ((unsigned)eax < 0x80000001) |
6a9c3ecf2dec
via c3 detection patch by (Francisco Javier Cabello Torres <fjcabello at visual-tools dot com>)
michaelni
parents:
429
diff
changeset
|
94 goto inteltest; |
6a9c3ecf2dec
via c3 detection patch by (Francisco Javier Cabello Torres <fjcabello at visual-tools dot com>)
michaelni
parents:
429
diff
changeset
|
95 cpuid(0x80000001, eax, ebx, ecx, edx); |
6a9c3ecf2dec
via c3 detection patch by (Francisco Javier Cabello Torres <fjcabello at visual-tools dot com>)
michaelni
parents:
429
diff
changeset
|
96 rval = 0; |
6a9c3ecf2dec
via c3 detection patch by (Francisco Javier Cabello Torres <fjcabello at visual-tools dot com>)
michaelni
parents:
429
diff
changeset
|
97 if( edx & ( 1 << 31) ) |
6a9c3ecf2dec
via c3 detection patch by (Francisco Javier Cabello Torres <fjcabello at visual-tools dot com>)
michaelni
parents:
429
diff
changeset
|
98 rval |= MM_3DNOW; |
6a9c3ecf2dec
via c3 detection patch by (Francisco Javier Cabello Torres <fjcabello at visual-tools dot com>)
michaelni
parents:
429
diff
changeset
|
99 if( edx & ( 1 << 23) ) |
6a9c3ecf2dec
via c3 detection patch by (Francisco Javier Cabello Torres <fjcabello at visual-tools dot com>)
michaelni
parents:
429
diff
changeset
|
100 rval |= MM_MMX; |
6a9c3ecf2dec
via c3 detection patch by (Francisco Javier Cabello Torres <fjcabello at visual-tools dot com>)
michaelni
parents:
429
diff
changeset
|
101 if( edx & ( 1 << 24) ) |
896
d774ded81bf6
via c3 fix patch by (Francisco Javier Cabello Torres <fjcabello at visual-tools dot com>)
michaelni
parents:
889
diff
changeset
|
102 rval |= MM_MMXEXT; |
2129 | 103 if(rval==0) |
104 goto inteltest; | |
896
d774ded81bf6
via c3 fix patch by (Francisco Javier Cabello Torres <fjcabello at visual-tools dot com>)
michaelni
parents:
889
diff
changeset
|
105 return rval; |
0 | 106 } else if (ebx == 0x69727943 && |
107 edx == 0x736e4978 && | |
108 ecx == 0x64616574) { | |
109 /* Cyrix Section */ | |
110 /* See if extended CPUID level 80000001 is supported */ | |
111 /* The value of CPUID/80000001 for the 6x86MX is undefined | |
112 according to the Cyrix CPU Detection Guide (Preliminary | |
113 Rev. 1.01 table 1), so we'll check the value of eax for | |
114 CPUID/0 to see if standard CPUID level 2 is supported. | |
115 According to the table, the only CPU which supports level | |
116 2 is also the only one which supports extended CPUID levels. | |
117 */ | |
118 if (eax != 2) | |
119 goto inteltest; | |
22
c31fb57d17a6
Suppressing external gas stuff to improve portability to Win32
nickols_k
parents:
16
diff
changeset
|
120 cpuid(0x80000001, eax, ebx, ecx, edx); |
0 | 121 if ((eax & 0x00800000) == 0) |
122 return 0; | |
123 rval = MM_MMX; | |
124 if (eax & 0x01000000) | |
125 rval |= MM_MMXEXT; | |
126 return rval; | |
2092
58b6b0ce1c20
transmeta crusoe mmx detection by "Nobody/Anonymous - nobody" / sf feature request tracker
michael
parents:
896
diff
changeset
|
127 } else if (ebx == 0x756e6547 && |
58b6b0ce1c20
transmeta crusoe mmx detection by "Nobody/Anonymous - nobody" / sf feature request tracker
michael
parents:
896
diff
changeset
|
128 edx == 0x54656e69 && |
58b6b0ce1c20
transmeta crusoe mmx detection by "Nobody/Anonymous - nobody" / sf feature request tracker
michael
parents:
896
diff
changeset
|
129 ecx == 0x3638784d) { |
58b6b0ce1c20
transmeta crusoe mmx detection by "Nobody/Anonymous - nobody" / sf feature request tracker
michael
parents:
896
diff
changeset
|
130 /* Tranmeta Crusoe */ |
58b6b0ce1c20
transmeta crusoe mmx detection by "Nobody/Anonymous - nobody" / sf feature request tracker
michael
parents:
896
diff
changeset
|
131 cpuid(0x80000000, eax, ebx, ecx, edx); |
58b6b0ce1c20
transmeta crusoe mmx detection by "Nobody/Anonymous - nobody" / sf feature request tracker
michael
parents:
896
diff
changeset
|
132 if ((unsigned)eax < 0x80000001) |
58b6b0ce1c20
transmeta crusoe mmx detection by "Nobody/Anonymous - nobody" / sf feature request tracker
michael
parents:
896
diff
changeset
|
133 return 0; |
58b6b0ce1c20
transmeta crusoe mmx detection by "Nobody/Anonymous - nobody" / sf feature request tracker
michael
parents:
896
diff
changeset
|
134 cpuid(0x80000001, eax, ebx, ecx, edx); |
58b6b0ce1c20
transmeta crusoe mmx detection by "Nobody/Anonymous - nobody" / sf feature request tracker
michael
parents:
896
diff
changeset
|
135 if ((edx & 0x00800000) == 0) |
58b6b0ce1c20
transmeta crusoe mmx detection by "Nobody/Anonymous - nobody" / sf feature request tracker
michael
parents:
896
diff
changeset
|
136 return 0; |
58b6b0ce1c20
transmeta crusoe mmx detection by "Nobody/Anonymous - nobody" / sf feature request tracker
michael
parents:
896
diff
changeset
|
137 return MM_MMX; |
0 | 138 } else { |
139 return 0; | |
140 } | |
141 } | |
43 | 142 |
143 #ifdef __TEST__ | |
144 int main ( void ) | |
145 { | |
146 int mm_flags; | |
147 mm_flags = mm_support(); | |
2129 | 148 printf("mm_support = 0x%08X\n",mm_flags); |
43 | 149 return 0; |
150 } | |
151 #endif |