diff options
author | Robin KAY <komadori@users.sourceforge.net> | 2004-06-25 07:32:22 +0000 |
---|---|---|
committer | Robin KAY <komadori@users.sourceforge.net> | 2004-06-25 07:32:22 +0000 |
commit | eecd260b1964fd92954f67898c612a2cb82f978b (patch) | |
tree | 3b0069143a106059f44ed79d5a135d09e84d43d3 | |
parent | 2263f5fb2e425f69fea0bc33ca9ca4591c9976bd (diff) | |
download | xine-lib-eecd260b1964fd92954f67898c612a2cb82f978b.tar.gz xine-lib-eecd260b1964fd92954f67898c612a2cb82f978b.tar.bz2 |
Move IA32 specific code out of the generic code into the ISA-specific arch_accel(). On Solaris/SPARC, use sysinfo(2) to detect supported extensions rather than by trapping SIGILL.
CVS patchset: 6740
CVS date: 2004/06/25 07:32:22
-rw-r--r-- | src/xine-utils/cpu_accel.c | 146 |
1 files changed, 98 insertions, 48 deletions
diff --git a/src/xine-utils/cpu_accel.c b/src/xine-utils/cpu_accel.c index 60ae51cba..5e721debf 100644 --- a/src/xine-utils/cpu_accel.c +++ b/src/xine-utils/cpu_accel.c @@ -28,6 +28,10 @@ #include <setjmp.h> #include <dlfcn.h> +#if defined (__SVR4) && defined (__sun) +#include <sys/systeminfo.h> +#endif + #define LOG_MODULE "cpu_accel" #define LOG_VERBOSE /* @@ -37,28 +41,24 @@ #include "xineutils.h" #if defined(ARCH_X86) || defined(ARCH_X86_64) -#if defined __x86_64__ static uint32_t arch_accel (void) { uint32_t caps; + +#ifdef __x86_64__ /* 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 +#ifndef _MSC_VER uint32_t eax, ebx, ecx, edx; int AMD; - uint32_t caps; + caps = 0; #ifndef PIC #define cpuid(op,eax,ebx,ecx,edx) \ - __asm__ ("cpuid" \ + __asm__ ("cpuid" \ : "=a" (eax), \ "=b" (ebx), \ "=c" (ecx), \ @@ -67,7 +67,7 @@ static uint32_t arch_accel (void) : "cc") #else /* PIC version : save ebx */ #define cpuid(op,eax,ebx,ecx,edx) \ - __asm__ ("pushl %%ebx\n\t" \ + __asm__ ("pushl %%ebx\n\t" \ "cpuid\n\t" \ "movl %%ebx,%1\n\t" \ "popl %%ebx" \ @@ -94,44 +94,73 @@ static uint32_t arch_accel (void) : : "cc"); - if (eax == ebx) /* no cpuid */ + if (eax == ebx) { + /* no cpuid */ return 0; + } cpuid (0x00000000, eax, ebx, ecx, edx); - if (!eax) /* vendor string only */ + 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; + if (edx & 0x00800000) { + /* MMX */ + caps |= MM_ACCEL_X86_MMX; + } - caps = MM_ACCEL_X86_MMX; - if (edx & 0x02000000) /* SSE - identical to AMD MMX extensions */ + if (edx & 0x02000000) { + /* SSE - identical to AMD MMX extensions */ caps |= MM_ACCEL_X86_SSE | MM_ACCEL_X86_MMXEXT; + } - if (edx & 0x04000000) /* SSE2 */ + if (edx & 0x04000000) { + /* SSE2 */ caps |= MM_ACCEL_X86_SSE2; + } cpuid (0x80000000, eax, ebx, ecx, edx); - if (eax < 0x80000001) /* no extended capabilities */ - return caps; + if (eax >= 0x80000001) { + cpuid (0x80000001, eax, ebx, ecx, edx); + + if (edx & 0x80000000) { + /* AMD 3DNow extensions */ + caps |= MM_ACCEL_X86_3DNOW; + } - cpuid (0x80000001, eax, ebx, ecx, edx); + if (AMD && (edx & 0x00400000)) { + /* AMD MMX extensions */ + caps |= MM_ACCEL_X86_MMXEXT; + } + } +#else + caps = 0; +#endif /* _MSC_VER */ - if (edx & 0x80000000) - caps |= MM_ACCEL_X86_3DNOW; + /* test OS support for SSE */ + if (caps & MM_ACCEL_X86_SSE) { + void (*old_sigill_handler)(int); - if (AMD && (edx & 0x00400000)) /* AMD MMX extensions */ - caps |= MM_ACCEL_X86_MMXEXT; + old_sigill_handler = signal (SIGILL, sigill_handler); + + if (setjmp(sigill_return)) { + lprintf("OS doesn't support SSE instructions.\n"); + caps &= ~(MM_ACCEL_X86_SSE|MM_ACCEL_X86_SSE2); + } else { + __asm__ volatile ("xorps %xmm0, %xmm0"); + } + + signal(SIGILL, old_sigill_handler); + } + +#endif /* x86_64 */ return caps; -#else /* _MSC_VER */ - return 0; -#endif } -#endif /* x86_64 */ static jmp_buf sigill_return; @@ -178,6 +207,46 @@ static uint32_t arch_accel (void) #endif /* ARCH_PPC */ #if defined(ARCH_SPARC) && defined(ENABLE_VIS) +#if defined (__SVR4) && defined (__sun) +static uint32_t arch_accel (void) +{ + uint32_t flags = 0; + long len; + char isalist_[257], *isalist, *s1, *last, *token; + + len = sysinfo(SI_ISALIST, isalist_, 257); + + if (len > 257) { + isalist = malloc(len); + sysinfo(SI_ISALIST, isalist, len); + } + else { + isalist = isalist_; + } + + s1 = isalist; + while (token = strtok_r(s1, " ", &last)) { + if (strlen(token) > 4) { + if (strcmp(token + (strlen(token) - 4), "+vis") == 0) { + flags |= MM_ACCEL_SPARC_VIS; + } + } + + if (strlen(token) > 5) { + if (strcmp(token + (strlen(token) - 5), "+vis2") == 0) { + flags |= MM_ACCEL_SPARC_VIS2; + } + } + + s1 = NULL; + } + + if (isalist != isalist_) { + free(isalist); + } + return flags; +} +#else static sigjmp_buf jmpbuf; static volatile sig_atomic_t canjump = 0; @@ -226,6 +295,7 @@ static uint32_t arch_accel (void) signal(SIGILL, SIG_DFL); return flags; } +#endif #endif /* ARCH_SPARC */ uint32_t xine_mm_accel (void) @@ -251,26 +321,6 @@ uint32_t xine_mm_accel (void) accel |= arch_accel(); #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; } |