Mercurial > mplayer.hg
annotate libmpeg2/cpu_accel.c @ 15020:3f80d5095f3e
usable downmixing for fixed point mode (take 2, previous patch reversed immediately on account of 1000l error :)
author | rfelker |
---|---|
date | Tue, 29 Mar 2005 18:14:24 +0000 |
parents | 1385ec491ffb |
children | 52838f825747 |
rev | line source |
---|---|
9857 | 1 /* |
2 * cpu_accel.c | |
10303 | 3 * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> |
9857 | 4 * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> |
5 * | |
6 * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. | |
7 * See http://libmpeg2.sourceforge.net/ for updates. | |
8 * | |
9 * mpeg2dec is free software; you can redistribute it and/or modify | |
10 * it under the terms of the GNU General Public License as published by | |
11 * the Free Software Foundation; either version 2 of the License, or | |
12 * (at your option) any later version. | |
13 * | |
14 * mpeg2dec is distributed in the hope that it will be useful, | |
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 * GNU General Public License for more details. | |
18 * | |
19 * You should have received a copy of the GNU General Public License | |
20 * along with this program; if not, write to the Free Software | |
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
14732
1385ec491ffb
Mark locally modified files as such to comply more closely with GPL 2a.
diego
parents:
13864
diff
changeset
|
22 * |
1385ec491ffb
Mark locally modified files as such to comply more closely with GPL 2a.
diego
parents:
13864
diff
changeset
|
23 * Modified for use with MPlayer, see libmpeg-0.4.0.diff for the exact changes. |
1385ec491ffb
Mark locally modified files as such to comply more closely with GPL 2a.
diego
parents:
13864
diff
changeset
|
24 * detailed CVS changelog at http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/ |
1385ec491ffb
Mark locally modified files as such to comply more closely with GPL 2a.
diego
parents:
13864
diff
changeset
|
25 * $Id$ |
9857 | 26 */ |
27 | |
28 #include "config.h" | |
29 | |
30 #include <inttypes.h> | |
31 | |
32 #include "mpeg2.h" | |
12932 | 33 #include "attributes.h" |
34 #include "mpeg2_internal.h" | |
9857 | 35 |
36 #ifdef ACCEL_DETECT | |
13864 | 37 #if defined(ARCH_X86) || defined(ARCH_X86_64) |
9857 | 38 static inline uint32_t arch_accel (void) |
39 { | |
40 uint32_t eax, ebx, ecx, edx; | |
41 int AMD; | |
42 uint32_t caps; | |
43 | |
12932 | 44 #if !defined(PIC) && !defined(__PIC__) |
9857 | 45 #define cpuid(op,eax,ebx,ecx,edx) \ |
46 __asm__ ("cpuid" \ | |
47 : "=a" (eax), \ | |
48 "=b" (ebx), \ | |
49 "=c" (ecx), \ | |
50 "=d" (edx) \ | |
51 : "a" (op) \ | |
52 : "cc") | |
53 #else /* PIC version : save ebx */ | |
54 #define cpuid(op,eax,ebx,ecx,edx) \ | |
55 __asm__ ("push %%ebx\n\t" \ | |
56 "cpuid\n\t" \ | |
57 "movl %%ebx,%1\n\t" \ | |
58 "pop %%ebx" \ | |
59 : "=a" (eax), \ | |
60 "=r" (ebx), \ | |
61 "=c" (ecx), \ | |
62 "=d" (edx) \ | |
63 : "a" (op) \ | |
64 : "cc") | |
65 #endif | |
66 | |
67 __asm__ ("pushf\n\t" | |
68 "pushf\n\t" | |
69 "pop %0\n\t" | |
70 "movl %0,%1\n\t" | |
71 "xorl $0x200000,%0\n\t" | |
72 "push %0\n\t" | |
73 "popf\n\t" | |
74 "pushf\n\t" | |
75 "pop %0\n\t" | |
76 "popf" | |
77 : "=r" (eax), | |
78 "=r" (ebx) | |
79 : | |
80 : "cc"); | |
81 | |
82 if (eax == ebx) /* no cpuid */ | |
83 return 0; | |
84 | |
85 cpuid (0x00000000, eax, ebx, ecx, edx); | |
86 if (!eax) /* vendor string only */ | |
87 return 0; | |
88 | |
89 AMD = (ebx == 0x68747541) && (ecx == 0x444d4163) && (edx == 0x69746e65); | |
90 | |
91 cpuid (0x00000001, eax, ebx, ecx, edx); | |
92 if (! (edx & 0x00800000)) /* no MMX */ | |
93 return 0; | |
94 | |
95 caps = MPEG2_ACCEL_X86_MMX; | |
96 if (edx & 0x02000000) /* SSE - identical to AMD MMX extensions */ | |
97 caps = MPEG2_ACCEL_X86_MMX | MPEG2_ACCEL_X86_MMXEXT; | |
98 | |
99 cpuid (0x80000000, eax, ebx, ecx, edx); | |
100 if (eax < 0x80000001) /* no extended capabilities */ | |
101 return caps; | |
102 | |
103 cpuid (0x80000001, eax, ebx, ecx, edx); | |
104 | |
105 if (edx & 0x80000000) | |
106 caps |= MPEG2_ACCEL_X86_3DNOW; | |
107 | |
108 if (AMD && (edx & 0x00400000)) /* AMD MMX extensions */ | |
109 caps |= MPEG2_ACCEL_X86_MMXEXT; | |
110 | |
111 return caps; | |
112 } | |
13864 | 113 #endif /* ARCH_X86 || ARCH_X86_64 */ |
9857 | 114 |
13018
adb93ef6b07f
Improved SPARC CPU detection and SPARC compilation fixes.
diego
parents:
12932
diff
changeset
|
115 #if defined(ARCH_PPC) || (defined(ARCH_SPARC) && defined(HAVE_VIS)) |
9857 | 116 #include <signal.h> |
117 #include <setjmp.h> | |
118 | |
119 static sigjmp_buf jmpbuf; | |
120 static volatile sig_atomic_t canjump = 0; | |
121 | |
122 static RETSIGTYPE sigill_handler (int sig) | |
123 { | |
124 if (!canjump) { | |
125 signal (sig, SIG_DFL); | |
126 raise (sig); | |
127 } | |
128 | |
129 canjump = 0; | |
130 siglongjmp (jmpbuf, 1); | |
131 } | |
132 | |
12932 | 133 #ifdef ARCH_PPC |
9857 | 134 static inline uint32_t arch_accel (void) |
135 { | |
10303 | 136 static RETSIGTYPE (* oldsig) (int); |
137 | |
138 oldsig = signal (SIGILL, sigill_handler); | |
9857 | 139 if (sigsetjmp (jmpbuf, 1)) { |
10303 | 140 signal (SIGILL, oldsig); |
9857 | 141 return 0; |
142 } | |
143 | |
144 canjump = 1; | |
145 | |
10303 | 146 #ifdef HAVE_ALTIVEC_H /* gnu */ |
147 #define VAND(a,b,c) "vand " #a "," #b "," #c "\n\t" | |
148 #else /* apple */ | |
149 #define VAND(a,b,c) "vand v" #a ",v" #b ",v" #c "\n\t" | |
150 #endif | |
9857 | 151 asm volatile ("mtspr 256, %0\n\t" |
10303 | 152 VAND (0, 0, 0) |
9857 | 153 : |
154 : "r" (-1)); | |
155 | |
12932 | 156 canjump = 0; |
157 | |
10303 | 158 signal (SIGILL, oldsig); |
9857 | 159 return MPEG2_ACCEL_PPC_ALTIVEC; |
160 } | |
161 #endif /* ARCH_PPC */ | |
162 | |
12932 | 163 #ifdef ARCH_SPARC |
164 static inline uint32_t arch_accel (void) | |
165 { | |
166 static RETSIGTYPE (* oldsig) (int); | |
167 | |
168 oldsig = signal (SIGILL, sigill_handler); | |
169 if (sigsetjmp (jmpbuf, 1)) { | |
170 signal (SIGILL, oldsig); | |
171 return 0; | |
172 } | |
173 | |
174 canjump = 1; | |
175 | |
176 /* pdist %f0, %f0, %f0 */ | |
177 __asm__ __volatile__(".word\t0x81b007c0"); | |
178 | |
179 canjump = 0; | |
180 | |
181 if (sigsetjmp (jmpbuf, 1)) { | |
182 signal (SIGILL, oldsig); | |
183 return MPEG2_ACCEL_SPARC_VIS; | |
184 } | |
185 | |
186 canjump = 1; | |
187 | |
188 /* edge8n %g0, %g0, %g0 */ | |
189 __asm__ __volatile__(".word\t0x81b00020"); | |
190 | |
191 canjump = 0; | |
192 | |
193 signal (SIGILL, oldsig); | |
194 return MPEG2_ACCEL_SPARC_VIS | MPEG2_ACCEL_SPARC_VIS2; | |
195 } | |
196 #endif /* ARCH_SPARC */ | |
197 #endif /* ARCH_PPC || ARCH_SPARC */ | |
198 | |
9857 | 199 #ifdef ARCH_ALPHA |
200 static inline uint32_t arch_accel (void) | |
201 { | |
10488 | 202 #ifdef CAN_COMPILE_ALPHA_MVI |
9857 | 203 uint64_t no_mvi; |
204 | |
205 asm volatile ("amask %1, %0" | |
206 : "=r" (no_mvi) | |
207 : "rI" (256)); /* AMASK_MVI */ | |
208 return no_mvi ? MPEG2_ACCEL_ALPHA : (MPEG2_ACCEL_ALPHA | | |
209 MPEG2_ACCEL_ALPHA_MVI); | |
10488 | 210 #else |
211 return MPEG2_ACCEL_ALPHA; | |
212 #endif | |
9857 | 213 } |
214 #endif /* ARCH_ALPHA */ | |
12932 | 215 #endif /* ACCEL_DETECT */ |
9857 | 216 |
217 uint32_t mpeg2_detect_accel (void) | |
218 { | |
219 uint32_t accel; | |
220 | |
221 accel = 0; | |
222 #ifdef ACCEL_DETECT | |
13864 | 223 #if defined (ARCH_X86) || defined (ARCH_X86_64) || defined (ARCH_PPC) || defined (ARCH_ALPHA) || defined (ARCH_SPARC) |
12932 | 224 accel = arch_accel (); |
9857 | 225 #endif |
226 #endif | |
227 return accel; | |
228 } |