Mercurial > mplayer.hg
comparison libmpeg2/cpu_accel.c @ 9857:89b48bc6c441
Importing libmpeg2 from mpeg2dec-0.3.1
author | arpi |
---|---|
date | Sun, 06 Apr 2003 16:41:49 +0000 |
parents | |
children | 2c0b6ec77d39 |
comparison
equal
deleted
inserted
replaced
9856:08496327b7ec | 9857:89b48bc6c441 |
---|---|
1 /* | |
2 * cpu_accel.c | |
3 * Copyright (C) 2000-2002 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 | |
24 #include "config.h" | |
25 | |
26 #include <inttypes.h> | |
27 | |
28 #include "mpeg2.h" | |
29 | |
30 #ifdef ACCEL_DETECT | |
31 #ifdef ARCH_X86 | |
32 static inline uint32_t arch_accel (void) | |
33 { | |
34 uint32_t eax, ebx, ecx, edx; | |
35 int AMD; | |
36 uint32_t caps; | |
37 | |
38 #ifndef PIC | |
39 #define cpuid(op,eax,ebx,ecx,edx) \ | |
40 __asm__ ("cpuid" \ | |
41 : "=a" (eax), \ | |
42 "=b" (ebx), \ | |
43 "=c" (ecx), \ | |
44 "=d" (edx) \ | |
45 : "a" (op) \ | |
46 : "cc") | |
47 #else /* PIC version : save ebx */ | |
48 #define cpuid(op,eax,ebx,ecx,edx) \ | |
49 __asm__ ("push %%ebx\n\t" \ | |
50 "cpuid\n\t" \ | |
51 "movl %%ebx,%1\n\t" \ | |
52 "pop %%ebx" \ | |
53 : "=a" (eax), \ | |
54 "=r" (ebx), \ | |
55 "=c" (ecx), \ | |
56 "=d" (edx) \ | |
57 : "a" (op) \ | |
58 : "cc") | |
59 #endif | |
60 | |
61 __asm__ ("pushf\n\t" | |
62 "pushf\n\t" | |
63 "pop %0\n\t" | |
64 "movl %0,%1\n\t" | |
65 "xorl $0x200000,%0\n\t" | |
66 "push %0\n\t" | |
67 "popf\n\t" | |
68 "pushf\n\t" | |
69 "pop %0\n\t" | |
70 "popf" | |
71 : "=r" (eax), | |
72 "=r" (ebx) | |
73 : | |
74 : "cc"); | |
75 | |
76 if (eax == ebx) /* no cpuid */ | |
77 return 0; | |
78 | |
79 cpuid (0x00000000, eax, ebx, ecx, edx); | |
80 if (!eax) /* vendor string only */ | |
81 return 0; | |
82 | |
83 AMD = (ebx == 0x68747541) && (ecx == 0x444d4163) && (edx == 0x69746e65); | |
84 | |
85 cpuid (0x00000001, eax, ebx, ecx, edx); | |
86 if (! (edx & 0x00800000)) /* no MMX */ | |
87 return 0; | |
88 | |
89 caps = MPEG2_ACCEL_X86_MMX; | |
90 if (edx & 0x02000000) /* SSE - identical to AMD MMX extensions */ | |
91 caps = MPEG2_ACCEL_X86_MMX | MPEG2_ACCEL_X86_MMXEXT; | |
92 | |
93 cpuid (0x80000000, eax, ebx, ecx, edx); | |
94 if (eax < 0x80000001) /* no extended capabilities */ | |
95 return caps; | |
96 | |
97 cpuid (0x80000001, eax, ebx, ecx, edx); | |
98 | |
99 if (edx & 0x80000000) | |
100 caps |= MPEG2_ACCEL_X86_3DNOW; | |
101 | |
102 if (AMD && (edx & 0x00400000)) /* AMD MMX extensions */ | |
103 caps |= MPEG2_ACCEL_X86_MMXEXT; | |
104 | |
105 return caps; | |
106 } | |
107 #endif /* ARCH_X86 */ | |
108 | |
109 #ifdef ARCH_PPC | |
110 #include <signal.h> | |
111 #include <setjmp.h> | |
112 | |
113 static sigjmp_buf jmpbuf; | |
114 static volatile sig_atomic_t canjump = 0; | |
115 | |
116 static RETSIGTYPE sigill_handler (int sig) | |
117 { | |
118 if (!canjump) { | |
119 signal (sig, SIG_DFL); | |
120 raise (sig); | |
121 } | |
122 | |
123 canjump = 0; | |
124 siglongjmp (jmpbuf, 1); | |
125 } | |
126 | |
127 static inline uint32_t arch_accel (void) | |
128 { | |
129 signal (SIGILL, sigill_handler); | |
130 if (sigsetjmp (jmpbuf, 1)) { | |
131 signal (SIGILL, SIG_DFL); | |
132 return 0; | |
133 } | |
134 | |
135 canjump = 1; | |
136 | |
137 asm volatile ("mtspr 256, %0\n\t" | |
138 "vand %%v0, %%v0, %%v0" | |
139 : | |
140 : "r" (-1)); | |
141 | |
142 signal (SIGILL, SIG_DFL); | |
143 return MPEG2_ACCEL_PPC_ALTIVEC; | |
144 } | |
145 #endif /* ARCH_PPC */ | |
146 | |
147 #ifdef ARCH_ALPHA | |
148 static inline uint32_t arch_accel (void) | |
149 { | |
150 uint64_t no_mvi; | |
151 | |
152 asm volatile ("amask %1, %0" | |
153 : "=r" (no_mvi) | |
154 : "rI" (256)); /* AMASK_MVI */ | |
155 return no_mvi ? MPEG2_ACCEL_ALPHA : (MPEG2_ACCEL_ALPHA | | |
156 MPEG2_ACCEL_ALPHA_MVI); | |
157 } | |
158 #endif /* ARCH_ALPHA */ | |
159 #endif | |
160 | |
161 uint32_t mpeg2_detect_accel (void) | |
162 { | |
163 uint32_t accel; | |
164 | |
165 accel = 0; | |
166 #ifdef ACCEL_DETECT | |
167 #ifdef LIBMPEG2_MLIB | |
168 accel = MPEG2_ACCEL_MLIB; | |
169 #endif | |
170 #if defined (ARCH_X86) || defined (ARCH_PPC) || defined (ARCH_ALPHA) | |
171 accel |= arch_accel (); | |
172 #endif | |
173 #endif | |
174 return accel; | |
175 } |