+++ /dev/null
-/*
- * cpu_accel.c
- * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
- *
- * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
- *
- * mpeg2dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * mpeg2dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-//#include "config.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <inttypes.h>
-#include <signal.h>
-#include <setjmp.h>
-#include <dlfcn.h>
-
-#define LOG_MODULE "cpu_accel"
-#define LOG_VERBOSE
-/*
-#define LOG
-*/
-
-#include "xineutils.h"
-
-#if defined(ARCH_X86) || defined(ARCH_X86_64)
-#if defined __x86_64__
-static uint32_t arch_accel (void)
-{
- uint32_t caps;
- /* No need to test for this on AMD64, we know what the
- platform has. */
- caps = MM_ACCEL_X86_MMX | MM_ACCEL_X86_SSE | MM_ACCEL_X86_MMXEXT | MM_ACCEL_X86_SSE2;
-
- return caps;
-}
-#else
-static uint32_t arch_accel (void)
-{
-#ifndef _MSC_VER
-
- uint32_t eax, ebx, ecx, edx;
- int AMD;
- uint32_t caps;
-
-#ifndef PIC
-#define cpuid(op,eax,ebx,ecx,edx) \
- __asm__ ("cpuid" \
- : "=a" (eax), \
- "=b" (ebx), \
- "=c" (ecx), \
- "=d" (edx) \
- : "a" (op) \
- : "cc")
-#else /* PIC version : save ebx */
-#define cpuid(op,eax,ebx,ecx,edx) \
- __asm__ ("pushl %%ebx\n\t" \
- "cpuid\n\t" \
- "movl %%ebx,%1\n\t" \
- "popl %%ebx" \
- : "=a" (eax), \
- "=r" (ebx), \
- "=c" (ecx), \
- "=d" (edx) \
- : "a" (op) \
- : "cc")
-#endif
-
- __asm__ ("pushfl\n\t"
- "pushfl\n\t"
- "popl %0\n\t"
- "movl %0,%1\n\t"
- "xorl $0x200000,%0\n\t"
- "pushl %0\n\t"
- "popfl\n\t"
- "pushfl\n\t"
- "popl %0\n\t"
- "popfl"
- : "=r" (eax),
- "=r" (ebx)
- :
- : "cc");
-
- if (eax == ebx) /* no cpuid */
- return 0;
-
- cpuid (0x00000000, eax, ebx, ecx, edx);
- if (!eax) /* vendor string only */
- return 0;
-
- AMD = (ebx == 0x68747541) && (ecx == 0x444d4163) && (edx == 0x69746e65);
-
- cpuid (0x00000001, eax, ebx, ecx, edx);
- if (! (edx & 0x00800000)) /* no MMX */
- return 0;
-
- caps = MM_ACCEL_X86_MMX;
- if (edx & 0x02000000) /* SSE - identical to AMD MMX extensions */
- caps |= MM_ACCEL_X86_SSE | MM_ACCEL_X86_MMXEXT;
-
- if (edx & 0x04000000) /* SSE2 */
- caps |= MM_ACCEL_X86_SSE2;
-
- cpuid (0x80000000, eax, ebx, ecx, edx);
- if (eax < 0x80000001) /* no extended capabilities */
- return caps;
-
- cpuid (0x80000001, eax, ebx, ecx, edx);
-
- if (edx & 0x80000000)
- caps |= MM_ACCEL_X86_3DNOW;
-
- if (AMD && (edx & 0x00400000)) /* AMD MMX extensions */
- caps |= MM_ACCEL_X86_MMXEXT;
-
- return caps;
-#else /* _MSC_VER */
- return 0;
-#endif
-}
-#endif /* x86_64 */
-
-static jmp_buf sigill_return;
-
-static void sigill_handler (int n) {
- longjmp(sigill_return, 1);
-}
-#endif /* ARCH_X86 */
-
-#if defined (ARCH_PPC) && defined (ENABLE_ALTIVEC)
-static sigjmp_buf jmpbuf;
-static volatile sig_atomic_t canjump = 0;
-
-static void sigill_handler (int sig)
-{
- if (!canjump) {
- signal (sig, SIG_DFL);
- raise (sig);
- }
-
- canjump = 0;
- siglongjmp (jmpbuf, 1);
-}
-
-static uint32_t arch_accel (void)
-{
- signal (SIGILL, sigill_handler);
- if (sigsetjmp (jmpbuf, 1)) {
- signal (SIGILL, SIG_DFL);
- return 0;
- }
-
- canjump = 1;
-
- __asm__ volatile ("mtspr 256, %0\n\t"
- "vand %%v0, %%v0, %%v0"
- :
- : "r" (-1));
-
- signal (SIGILL, SIG_DFL);
- return MM_ACCEL_PPC_ALTIVEC;
-}
-#endif /* ARCH_PPC */
-
-uint32_t xine_mm_accel (void)
-{
- static int initialized = 0;
- static uint32_t accel;
-
- if (!initialized) {
-#if defined (ARCH_X86) || (defined (ARCH_PPC) && defined (ENABLE_ALTIVEC))
- accel = arch_accel ();
-#elif defined (HAVE_MLIB)
-#ifdef MLIB_LAZYLOAD
- void *hndl;
-
- if ((hndl = dlopen("libmlib.so.2", RTLD_LAZY | RTLD_GLOBAL | RTLD_NODELETE)) == NULL) {
- accel = 0;
- }
- else {
- dlclose(hndl);
- accel = MM_ACCEL_MLIB;
- }
-#else
- accel = MM_ACCEL_MLIB;
-#endif
-#else
- accel = 0;
-#endif
-
-#if defined(ARCH_X86) || defined(ARCH_X86_64)
-#ifndef _MSC_VER
- /* test OS support for SSE */
- if( accel & MM_ACCEL_X86_SSE ) {
- void (*old_sigill_handler)(int);
-
- old_sigill_handler = signal (SIGILL, sigill_handler);
-
- if (setjmp(sigill_return)) {
- lprintf ("OS doesn't support SSE instructions.\n");
- accel &= ~(MM_ACCEL_X86_SSE|MM_ACCEL_X86_SSE2);
- } else {
- __asm__ volatile ("xorps %xmm0, %xmm0");
- }
-
- signal (SIGILL, old_sigill_handler);
- }
-#endif /* _MSC_VER */
-#endif /* ARCH_X86 || ARCH_X86_64 */
-
- if(getenv("XINE_NO_ACCEL")) {
- accel = 0;
- }
-
- initialized = 1;
- }
-
- return accel;
-}