Mercurial > mplayer.hg
annotate libmpeg2/cpu_accel.c @ 13980:e0d400094e88
24bit LPCM is signed...
author | reimar |
---|---|
date | Fri, 19 Nov 2004 14:42:17 +0000 |
parents | 96259a2f2142 |
children | 1385ec491ffb |
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 | |
22 */ | |
23 | |
24 #include "config.h" | |
25 | |
26 #include <inttypes.h> | |
27 | |
28 #include "mpeg2.h" | |
12932 | 29 #include "attributes.h" |
30 #include "mpeg2_internal.h" | |
9857 | 31 |
32 #ifdef ACCEL_DETECT | |
13864 | 33 #if defined(ARCH_X86) || defined(ARCH_X86_64) |
9857 | 34 static inline uint32_t arch_accel (void) |
35 { | |
36 uint32_t eax, ebx, ecx, edx; | |
37 int AMD; | |
38 uint32_t caps; | |
39 | |
12932 | 40 #if !defined(PIC) && !defined(__PIC__) |
9857 | 41 #define cpuid(op,eax,ebx,ecx,edx) \ |
42 __asm__ ("cpuid" \ | |
43 : "=a" (eax), \ | |
44 "=b" (ebx), \ | |
45 "=c" (ecx), \ | |
46 "=d" (edx) \ | |
47 : "a" (op) \ | |
48 : "cc") | |
49 #else /* PIC version : save ebx */ | |
50 #define cpuid(op,eax,ebx,ecx,edx) \ | |
51 __asm__ ("push %%ebx\n\t" \ | |
52 "cpuid\n\t" \ | |
53 "movl %%ebx,%1\n\t" \ | |
54 "pop %%ebx" \ | |
55 : "=a" (eax), \ | |
56 "=r" (ebx), \ | |
57 "=c" (ecx), \ | |
58 "=d" (edx) \ | |
59 : "a" (op) \ | |
60 : "cc") | |
61 #endif | |
62 | |
63 __asm__ ("pushf\n\t" | |
64 "pushf\n\t" | |
65 "pop %0\n\t" | |
66 "movl %0,%1\n\t" | |
67 "xorl $0x200000,%0\n\t" | |
68 "push %0\n\t" | |
69 "popf\n\t" | |
70 "pushf\n\t" | |
71 "pop %0\n\t" | |
72 "popf" | |
73 : "=r" (eax), | |
74 "=r" (ebx) | |
75 : | |
76 : "cc"); | |
77 | |
78 if (eax == ebx) /* no cpuid */ | |
79 return 0; | |
80 | |
81 cpuid (0x00000000, eax, ebx, ecx, edx); | |
82 if (!eax) /* vendor string only */ | |
83 return 0; | |
84 | |
85 AMD = (ebx == 0x68747541) && (ecx == 0x444d4163) && (edx == 0x69746e65); | |
86 | |
87 cpuid (0x00000001, eax, ebx, ecx, edx); | |
88 if (! (edx & 0x00800000)) /* no MMX */ | |
89 return 0; | |
90 | |
91 caps = MPEG2_ACCEL_X86_MMX; | |
92 if (edx & 0x02000000) /* SSE - identical to AMD MMX extensions */ | |
93 caps = MPEG2_ACCEL_X86_MMX | MPEG2_ACCEL_X86_MMXEXT; | |
94 | |
95 cpuid (0x80000000, eax, ebx, ecx, edx); | |
96 if (eax < 0x80000001) /* no extended capabilities */ | |
97 return caps; | |
98 | |
99 cpuid (0x80000001, eax, ebx, ecx, edx); | |
100 | |
101 if (edx & 0x80000000) | |
102 caps |= MPEG2_ACCEL_X86_3DNOW; | |
103 | |
104 if (AMD && (edx & 0x00400000)) /* AMD MMX extensions */ | |
105 caps |= MPEG2_ACCEL_X86_MMXEXT; | |
106 | |
107 return caps; | |
108 } | |
13864 | 109 #endif /* ARCH_X86 || ARCH_X86_64 */ |
9857 | 110 |
13018
adb93ef6b07f
Improved SPARC CPU detection and SPARC compilation fixes.
diego
parents:
12932
diff
changeset
|
111 #if defined(ARCH_PPC) || (defined(ARCH_SPARC) && defined(HAVE_VIS)) |
9857 | 112 #include <signal.h> |
113 #include <setjmp.h> | |
114 | |
115 static sigjmp_buf jmpbuf; | |
116 static volatile sig_atomic_t canjump = 0; | |
117 | |
118 static RETSIGTYPE sigill_handler (int sig) | |
119 { | |
120 if (!canjump) { | |
121 signal (sig, SIG_DFL); | |
122 raise (sig); | |
123 } | |
124 | |
125 canjump = 0; | |
126 siglongjmp (jmpbuf, 1); | |
127 } | |
128 | |
12932 | 129 #ifdef ARCH_PPC |
9857 | 130 static inline uint32_t arch_accel (void) |
131 { | |
10303 | 132 static RETSIGTYPE (* oldsig) (int); |
133 | |
134 oldsig = signal (SIGILL, sigill_handler); | |
9857 | 135 if (sigsetjmp (jmpbuf, 1)) { |
10303 | 136 signal (SIGILL, oldsig); |
9857 | 137 return 0; |
138 } | |
139 | |
140 canjump = 1; | |
141 | |
10303 | 142 #ifdef HAVE_ALTIVEC_H /* gnu */ |
143 #define VAND(a,b,c) "vand " #a "," #b "," #c "\n\t" | |
144 #else /* apple */ | |
145 #define VAND(a,b,c) "vand v" #a ",v" #b ",v" #c "\n\t" | |
146 #endif | |
9857 | 147 asm volatile ("mtspr 256, %0\n\t" |
10303 | 148 VAND (0, 0, 0) |
9857 | 149 : |
150 : "r" (-1)); | |
151 | |
12932 | 152 canjump = 0; |
153 | |
10303 | 154 signal (SIGILL, oldsig); |
9857 | 155 return MPEG2_ACCEL_PPC_ALTIVEC; |
156 } | |
157 #endif /* ARCH_PPC */ | |
158 | |
12932 | 159 #ifdef ARCH_SPARC |
160 static inline uint32_t arch_accel (void) | |
161 { | |
162 static RETSIGTYPE (* oldsig) (int); | |
163 | |
164 oldsig = signal (SIGILL, sigill_handler); | |
165 if (sigsetjmp (jmpbuf, 1)) { | |
166 signal (SIGILL, oldsig); | |
167 return 0; | |
168 } | |
169 | |
170 canjump = 1; | |
171 | |
172 /* pdist %f0, %f0, %f0 */ | |
173 __asm__ __volatile__(".word\t0x81b007c0"); | |
174 | |
175 canjump = 0; | |
176 | |
177 if (sigsetjmp (jmpbuf, 1)) { | |
178 signal (SIGILL, oldsig); | |
179 return MPEG2_ACCEL_SPARC_VIS; | |
180 } | |
181 | |
182 canjump = 1; | |
183 | |
184 /* edge8n %g0, %g0, %g0 */ | |
185 __asm__ __volatile__(".word\t0x81b00020"); | |
186 | |
187 canjump = 0; | |
188 | |
189 signal (SIGILL, oldsig); | |
190 return MPEG2_ACCEL_SPARC_VIS | MPEG2_ACCEL_SPARC_VIS2; | |
191 } | |
192 #endif /* ARCH_SPARC */ | |
193 #endif /* ARCH_PPC || ARCH_SPARC */ | |
194 | |
9857 | 195 #ifdef ARCH_ALPHA |
196 static inline uint32_t arch_accel (void) | |
197 { | |
10488 | 198 #ifdef CAN_COMPILE_ALPHA_MVI |
9857 | 199 uint64_t no_mvi; |
200 | |
201 asm volatile ("amask %1, %0" | |
202 : "=r" (no_mvi) | |
203 : "rI" (256)); /* AMASK_MVI */ | |
204 return no_mvi ? MPEG2_ACCEL_ALPHA : (MPEG2_ACCEL_ALPHA | | |
205 MPEG2_ACCEL_ALPHA_MVI); | |
10488 | 206 #else |
207 return MPEG2_ACCEL_ALPHA; | |
208 #endif | |
9857 | 209 } |
210 #endif /* ARCH_ALPHA */ | |
12932 | 211 #endif /* ACCEL_DETECT */ |
9857 | 212 |
213 uint32_t mpeg2_detect_accel (void) | |
214 { | |
215 uint32_t accel; | |
216 | |
217 accel = 0; | |
218 #ifdef ACCEL_DETECT | |
13864 | 219 #if defined (ARCH_X86) || defined (ARCH_X86_64) || defined (ARCH_PPC) || defined (ARCH_ALPHA) || defined (ARCH_SPARC) |
12932 | 220 accel = arch_accel (); |
9857 | 221 #endif |
222 #endif | |
223 return accel; | |
224 } |