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.0.diff for the exact changes.
24
* detailed CVS changelog at http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
25
* $Id: cpu_accel.c,v 1.8 2005/05/15 20:11:34 nplourde Exp $
33
#include "attributes.h"
34
#include "mpeg2_internal.h"
37
#if defined(ARCH_X86) || defined(ARCH_X86_64)
38
static inline uint32_t arch_accel (void)
40
uint32_t eax, ebx, ecx, edx;
44
#if !defined(PIC) && !defined(__PIC__)
45
#define cpuid(op,eax,ebx,ecx,edx) \
53
#else /* PIC version : save ebx */
54
#define cpuid(op,eax,ebx,ecx,edx) \
55
__asm__ ("push %%ebx\n\t" \
71
"xorl $0x200000,%0\n\t"
82
if (eax == ebx) /* no cpuid */
85
cpuid (0x00000000, eax, ebx, ecx, edx);
86
if (!eax) /* vendor string only */
89
AMD = (ebx == 0x68747541) && (ecx == 0x444d4163) && (edx == 0x69746e65);
91
cpuid (0x00000001, eax, ebx, ecx, edx);
92
if (! (edx & 0x00800000)) /* no MMX */
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;
99
cpuid (0x80000000, eax, ebx, ecx, edx);
100
if (eax < 0x80000001) /* no extended capabilities */
103
cpuid (0x80000001, eax, ebx, ecx, edx);
105
if (edx & 0x80000000)
106
caps |= MPEG2_ACCEL_X86_3DNOW;
108
if (AMD && (edx & 0x00400000)) /* AMD MMX extensions */
109
caps |= MPEG2_ACCEL_X86_MMXEXT;
113
#endif /* ARCH_X86 || ARCH_X86_64 */
115
#if defined(ARCH_PPC) || (defined(ARCH_SPARC) && defined(HAVE_VIS))
119
static sigjmp_buf jmpbuf;
120
static volatile sig_atomic_t canjump = 0;
122
static RETSIGTYPE sigill_handler (int sig)
125
signal (sig, SIG_DFL);
130
siglongjmp (jmpbuf, 1);
134
static inline uint32_t arch_accel (void)
136
static RETSIGTYPE (* oldsig) (int);
138
oldsig = signal (SIGILL, sigill_handler);
139
if (sigsetjmp (jmpbuf, 1)) {
140
signal (SIGILL, oldsig);
146
#if defined( __APPLE_CC__ ) && defined( __APPLE_ALTIVEC__ ) /* apple */
147
#define VAND(a,b,c) "vand v" #a ",v" #b ",v" #c "\n\t"
149
#define VAND(a,b,c) "vand " #a "," #b "," #c "\n\t"
151
asm volatile ("mtspr 256, %0\n\t"
158
signal (SIGILL, oldsig);
159
return MPEG2_ACCEL_PPC_ALTIVEC;
161
#endif /* ARCH_PPC */
164
static inline uint32_t arch_accel (void)
166
static RETSIGTYPE (* oldsig) (int);
168
oldsig = signal (SIGILL, sigill_handler);
169
if (sigsetjmp (jmpbuf, 1)) {
170
signal (SIGILL, oldsig);
176
/* pdist %f0, %f0, %f0 */
177
__asm__ __volatile__(".word\t0x81b007c0");
181
if (sigsetjmp (jmpbuf, 1)) {
182
signal (SIGILL, oldsig);
183
return MPEG2_ACCEL_SPARC_VIS;
188
/* edge8n %g0, %g0, %g0 */
189
__asm__ __volatile__(".word\t0x81b00020");
193
signal (SIGILL, oldsig);
194
return MPEG2_ACCEL_SPARC_VIS | MPEG2_ACCEL_SPARC_VIS2;
196
#endif /* ARCH_SPARC */
197
#endif /* ARCH_PPC || ARCH_SPARC */
200
static inline uint32_t arch_accel (void)
202
#ifdef CAN_COMPILE_ALPHA_MVI
205
asm volatile ("amask %1, %0"
207
: "rI" (256)); /* AMASK_MVI */
208
return no_mvi ? MPEG2_ACCEL_ALPHA : (MPEG2_ACCEL_ALPHA |
209
MPEG2_ACCEL_ALPHA_MVI);
211
return MPEG2_ACCEL_ALPHA;
214
#endif /* ARCH_ALPHA */
215
#endif /* ACCEL_DETECT */
217
uint32_t mpeg2_detect_accel (void)
223
#if defined (ARCH_X86) || defined (ARCH_X86_64) || defined (ARCH_PPC) || defined (ARCH_ALPHA) || defined (ARCH_SPARC)
224
accel = arch_accel ();