34 #if defined(HAVE_MLIB) && defined(MLIB_LAZYLOAD) 38 #if defined (__SVR4) && defined (__sun) 39 #include <sys/systeminfo.h> 43 #define LOG_MODULE "cpu_accel" 53 #include <xine/xineutils.h> 58 #define lprintf printf 62 #if defined(PIC) && ! defined(__PIC__) 66 #if defined(__i386__) || defined(__x86_64__) 71 static jmp_buf sigill_return;
73 static __attribute__((noreturn))
void sigill_handler (
int n) {
75 longjmp(sigill_return, 1);
78 static uint32_t arch_accel (
void)
81 static uint32_t caps = 0;
83 #if defined(__x86_64__) || \ 84 ( defined(__SSE__) && defined(__SSE2__) && defined(__MMX__) ) 88 # if defined(__3dNOW__) 94 void (*old_sigill_handler)(int);
95 uint32_t eax, ebx, ecx, edx;
97 #if defined(__x86_64__) 98 #define cpuid(op,eax,ebx,ecx,edx) \ 99 __asm__ ("push %%rbx\n\t" \ 101 "movl %%ebx,%1\n\t" \ 109 #elif !defined(__PIC__) 110 #define cpuid(op,eax,ebx,ecx,edx) \ 119 #define cpuid(op,eax,ebx,ecx,edx) \ 120 __asm__ ("pushl %%ebx\n\t" \ 122 "movl %%ebx,%1\n\t" \ 133 __asm__ (
"pushfl\n\t" 137 "xorl $0x200000,%0\n\t" 153 cpuid (0x00000000, eax, ebx, ecx, edx);
159 int AMD = (ebx == 0x68747541) && (ecx == 0x444d4163) && (edx == 0x69746e65);
163 cpuid (0x00000001, eax, ebx, ecx, edx);
166 if (edx & 0x00800000) {
171 if (edx & 0x02000000) {
176 if (edx & 0x04000000) {
182 if (ecx & 0x00000001) {
185 if (ecx & 0x00000200) {
188 if (ecx & 0x00080000) {
191 if (ecx & 0x00100000) {
196 if ((ecx & 0x18000000) == 0x18000000) {
199 old_sigill_handler = signal (SIGILL, sigill_handler);
201 if (setjmp(sigill_return)) {
202 lprintf(
"OS doesn't support AVX instructions.\n");
205 __asm__ (
".byte 0x0f, 0x01, 0xd0" :
"=a"(eax),
"=d"(edx) :
"c" (0));
206 if ((eax & 0x6) == 0x6) {
212 signal(SIGILL, old_sigill_handler);
216 cpuid (0x80000000, eax, ebx, ecx, edx);
217 if (eax >= 0x80000001) {
218 cpuid (0x80000001, eax, ebx, ecx, edx);
220 if (edx & 0x80000000) {
225 if (AMD && (edx & 0x00400000)) {
235 old_sigill_handler = signal (SIGILL, sigill_handler);
237 if (setjmp(sigill_return)) {
238 lprintf(
"OS doesn't support SSE instructions.\n");
243 __asm__
volatile (
"xorps %xmm0, %xmm0");
246 signal(SIGILL, old_sigill_handler);
256 #if defined(ARCH_PPC) && defined(ENABLE_ALTIVEC) 260 static sigjmp_buf jmpbuf;
261 static volatile sig_atomic_t canjump = 0;
263 static void sigill_handler (
int sig)
266 signal (sig, SIG_DFL);
271 siglongjmp (jmpbuf, 1);
274 static uint32_t arch_accel (
void)
279 signal (SIGILL, sigill_handler);
280 if (sigsetjmp (jmpbuf, 1)) {
281 signal (SIGILL, SIG_DFL);
286 #ifndef HOST_OS_DARWIN 287 __asm__
volatile (
"mtspr 256, %0\n\t" 288 "vand %%v0, %%v0, %%v0" 292 __asm__
volatile (
"mtspr 256, r0\n\t" 298 signal (SIGILL, SIG_DFL);
299 return flags|MM_ACCEL_PPC_ALTIVEC;
303 #if defined(ARCH_SPARC) && defined(ENABLE_VIS) 304 #if defined (__SVR4) && defined (__sun) 305 static uint32_t arch_accel (
void)
309 char isalist_[257], *isalist, *s1, *last, *token;
311 len = sysinfo(SI_ISALIST, isalist_, 257);
314 isalist = malloc(len);
315 sysinfo(SI_ISALIST, isalist, len);
322 while (token = strtok_r(s1,
" ", &last)) {
323 if (strlen(token) > 4) {
324 if (strcmp(token + (strlen(token) - 4),
"+vis") == 0) {
325 flags |= MM_ACCEL_SPARC_VIS;
329 if (strlen(token) > 5) {
330 if (strcmp(token + (strlen(token) - 5),
"+vis2") == 0) {
331 flags |= MM_ACCEL_SPARC_VIS2;
338 if (isalist != isalist_) {
347 static sigjmp_buf jmpbuf;
348 static volatile sig_atomic_t canjump = 0;
350 static void sigill_handler (
int sig)
353 signal(sig, SIG_DFL);
358 siglongjmp(jmpbuf, 1);
361 static uint32_t arch_accel (
void)
365 signal(SIGILL, sigill_handler);
366 if (sigsetjmp(jmpbuf, 1)) {
367 signal(SIGILL, SIG_DFL);
374 __asm__ __volatile__(
".word\t0x81b007c0");
377 flags |= MM_ACCEL_SPARC_VIS;
379 if (sigsetjmp(jmpbuf, 1)) {
380 signal(SIGILL, SIG_DFL);
387 __asm__ __volatile__(
".word\t0x81b00020");
390 flags |= MM_ACCEL_SPARC_VIS2;
392 signal(SIGILL, SIG_DFL);
400 static int initialized = 0;
401 static uint32_t accel = 0;
408 if ((hndl = dlopen(
"libmlib.so.2", RTLD_LAZY | RTLD_GLOBAL | RTLD_NODELETE)) != NULL) {
410 accel |= MM_ACCEL_MLIB;
413 accel |= MM_ACCEL_MLIB;
417 #if defined(__i386__) || defined(__x86_64__) || (defined(ARCH_PPC) && defined(ENABLE_ALTIVEC)) || (defined(ARCH_SPARC) && defined(ENABLE_VIS)) 418 accel |= arch_accel();
#define MM_ACCEL_X86_SSE2
#define MM_ACCEL_X86_3DNOW
#define MM_ACCEL_X86_SSE4
#define MM_ACCEL_X86_SSSE3
#define MM_ACCEL_X86_SSE3
#define MM_ACCEL_X86_MMXEXT
#define MM_ACCEL_X86_SSE42
uint32_t xine_mm_accel(void)