3 * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
4 * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
6 * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
7 * See http://libmpeg2.sourceforge.net/ for updates.
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.
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.
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
23 * Modified for use with MPlayer, see libmpeg-0.4.1.diff for the exact changes.
24 * detailed changelog at http://svn.mplayerhq.hu/mplayer/trunk/
29 #include "cpudetect.h"
34 #include "attributes.h"
35 #include "mpeg2_internal.h"
38 #if defined(ARCH_X86) || defined(ARCH_X86_64)
40 /* MPlayer imports libmpeg2 as decoder, which detects MMX / 3DNow!
41 * instructions via assembly. However, it is regarded as duplicated work
42 * in MPlayer, so that we enforce using MPlayer's implementation.
44 #define USE_MPLAYER_CPUDETECT
46 static inline uint32_t arch_accel (void)
48 #if !defined(USE_MPLAYER_CPUDETECT)
49 uint32_t eax
, ebx
, ecx
, edx
;
53 #if defined(__x86_64__) || (!defined(PIC) && !defined(__PIC__))
54 #define cpuid(op,eax,ebx,ecx,edx) \
62 #else /* PIC version : save ebx (not needed on x86_64) */
63 #define cpuid(op,eax,ebx,ecx,edx) \
64 __asm__ ("pushl %%ebx\n\t" \
76 #ifndef __x86_64__ /* x86_64 supports the cpuid op */
81 "xorl $0x200000,%0\n\t"
92 if (eax
== ebx
) /* no cpuid */
96 cpuid (0x00000000, eax
, ebx
, ecx
, edx
);
97 if (!eax
) /* vendor string only */
100 AMD
= (ebx
== 0x68747541) && (ecx
== 0x444d4163) && (edx
== 0x69746e65);
102 cpuid (0x00000001, eax
, ebx
, ecx
, edx
);
103 if (! (edx
& 0x00800000)) /* no MMX */
106 caps
= MPEG2_ACCEL_X86_MMX
;
107 if (edx
& 0x02000000) /* SSE - identical to AMD MMX extensions */
108 caps
= MPEG2_ACCEL_X86_MMX
| MPEG2_ACCEL_X86_MMXEXT
;
110 cpuid (0x80000000, eax
, ebx
, ecx
, edx
);
111 if (eax
< 0x80000001) /* no extended capabilities */
114 cpuid (0x80000001, eax
, ebx
, ecx
, edx
);
116 if (edx
& 0x80000000)
117 caps
|= MPEG2_ACCEL_X86_3DNOW
;
119 if (AMD
&& (edx
& 0x00400000)) /* AMD MMX extensions */
120 caps
|= MPEG2_ACCEL_X86_MMXEXT
;
123 #else /* USE_MPLAYER_CPUDETECT: Use MPlayer's CPU capability property. */
126 caps
|= MPEG2_ACCEL_X86_MMX
;
127 if (gCpuCaps
.hasSSE2
)
128 caps
|= MPEG2_ACCEL_X86_SSE2
;
129 if (gCpuCaps
.hasMMX2
)
130 caps
|= MPEG2_ACCEL_X86_MMXEXT
;
131 if (gCpuCaps
.has3DNow
)
132 caps
|= MPEG2_ACCEL_X86_3DNOW
;
136 #endif /* USE_MPLAYER_CPUDETECT */
138 #endif /* ARCH_X86 || ARCH_X86_64 */
140 #if defined(ARCH_PPC) || defined(ARCH_SPARC)
144 static sigjmp_buf jmpbuf
;
145 static volatile sig_atomic_t canjump
= 0;
147 static RETSIGTYPE
sigill_handler (int sig
)
150 signal (sig
, SIG_DFL
);
155 siglongjmp (jmpbuf
, 1);
159 static uint32_t arch_accel (void)
161 static RETSIGTYPE (* oldsig
) (int);
163 oldsig
= signal (SIGILL
, sigill_handler
);
164 if (sigsetjmp (jmpbuf
, 1)) {
165 signal (SIGILL
, oldsig
);
171 #if defined(__APPLE_CC__) /* apple */
172 #define VAND(a,b,c) "vand v" #a ",v" #b ",v" #c "\n\t"
174 #define VAND(a,b,c) "vand " #a "," #b "," #c "\n\t"
176 asm volatile ("mtspr 256, %0\n\t"
183 signal (SIGILL
, oldsig
);
184 return MPEG2_ACCEL_PPC_ALTIVEC
;
186 #endif /* ARCH_PPC */
189 static uint32_t arch_accel (void)
191 static RETSIGTYPE (* oldsig
) (int);
193 oldsig
= signal (SIGILL
, sigill_handler
);
194 if (sigsetjmp (jmpbuf
, 1)) {
195 signal (SIGILL
, oldsig
);
201 /* pdist %f0, %f0, %f0 */
202 __asm__
__volatile__(".word\t0x81b007c0");
206 if (sigsetjmp (jmpbuf
, 1)) {
207 signal (SIGILL
, oldsig
);
208 return MPEG2_ACCEL_SPARC_VIS
;
213 /* edge8n %g0, %g0, %g0 */
214 __asm__
__volatile__(".word\t0x81b00020");
218 signal (SIGILL
, oldsig
);
219 return MPEG2_ACCEL_SPARC_VIS
| MPEG2_ACCEL_SPARC_VIS2
;
221 #endif /* ARCH_SPARC */
222 #endif /* ARCH_PPC || ARCH_SPARC */
225 static uint32_t arch_accel (void)
229 asm volatile ("amask %1, %0"
231 : "rI" (256)); /* AMASK_MVI */
232 return no_mvi
? MPEG2_ACCEL_ALPHA
: (MPEG2_ACCEL_ALPHA
|
233 MPEG2_ACCEL_ALPHA_MVI
);
235 #endif /* ARCH_ALPHA */
236 #endif /* ACCEL_DETECT */
238 uint32_t mpeg2_detect_accel (void)
244 #if defined (ARCH_X86) || defined (ARCH_X86_64) || defined (ARCH_PPC) || defined (ARCH_ALPHA) || defined (ARCH_SPARC)
245 accel
= arch_accel ();