~ubuntu-dev/mplayer/ubuntu-feisty

« back to all changes in this revision

Viewing changes to libmpeg2/cpu_accel.c

  • Committer: Reinhard Tartler
  • Date: 2006-07-08 08:45:33 UTC
  • Revision ID: siretart@tauware.de-20060708084533-dbc155bde7122e78
imported mplayer_0.99+1.0pre7try2+cvs20060117

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * cpu_accel.c
 
3
 * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
 
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
 * 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 $
 
26
 */
 
27
 
 
28
#include "config.h"
 
29
 
 
30
#include <inttypes.h>
 
31
 
 
32
#include "mpeg2.h"
 
33
#include "attributes.h"
 
34
#include "mpeg2_internal.h"
 
35
 
 
36
#ifdef ACCEL_DETECT
 
37
#if defined(ARCH_X86) || defined(ARCH_X86_64)
 
38
static inline uint32_t arch_accel (void)
 
39
{
 
40
    uint32_t eax, ebx, ecx, edx;
 
41
    int AMD;
 
42
    uint32_t caps;
 
43
 
 
44
#if !defined(PIC) && !defined(__PIC__)
 
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
}
 
113
#endif /* ARCH_X86 || ARCH_X86_64 */
 
114
 
 
115
#if defined(ARCH_PPC) || (defined(ARCH_SPARC) && defined(HAVE_VIS))
 
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
 
 
133
#ifdef ARCH_PPC
 
134
static inline uint32_t arch_accel (void)
 
135
{
 
136
    static RETSIGTYPE (* oldsig) (int);
 
137
 
 
138
    oldsig = signal (SIGILL, sigill_handler);
 
139
    if (sigsetjmp (jmpbuf, 1)) {
 
140
        signal (SIGILL, oldsig);
 
141
        return 0;
 
142
    }
 
143
 
 
144
    canjump = 1;
 
145
 
 
146
#if defined( __APPLE_CC__ ) && defined( __APPLE_ALTIVEC__ ) /* apple */
 
147
#define VAND(a,b,c) "vand v" #a ",v" #b ",v" #c "\n\t"
 
148
#else                   /* gnu */
 
149
#define VAND(a,b,c) "vand " #a "," #b "," #c "\n\t"
 
150
#endif
 
151
    asm volatile ("mtspr 256, %0\n\t"
 
152
                  VAND (0, 0, 0)
 
153
                  :
 
154
                  : "r" (-1));
 
155
 
 
156
    canjump = 0;
 
157
 
 
158
    signal (SIGILL, oldsig);
 
159
    return MPEG2_ACCEL_PPC_ALTIVEC;
 
160
}
 
161
#endif /* ARCH_PPC */
 
162
 
 
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
 
 
199
#ifdef ARCH_ALPHA
 
200
static inline uint32_t arch_accel (void)
 
201
{
 
202
#ifdef CAN_COMPILE_ALPHA_MVI
 
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);
 
210
#else
 
211
    return MPEG2_ACCEL_ALPHA;
 
212
#endif
 
213
}
 
214
#endif /* ARCH_ALPHA */
 
215
#endif /* ACCEL_DETECT */
 
216
 
 
217
uint32_t mpeg2_detect_accel (void)
 
218
{
 
219
    uint32_t accel;
 
220
 
 
221
    accel = 0;
 
222
#ifdef ACCEL_DETECT
 
223
#if defined (ARCH_X86) || defined (ARCH_X86_64) || defined (ARCH_PPC) || defined (ARCH_ALPHA) || defined (ARCH_SPARC)
 
224
    accel = arch_accel ();
 
225
#endif
 
226
#endif
 
227
    return accel;
 
228
}