summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin KAY <komadori@users.sourceforge.net>2004-06-25 07:32:22 +0000
committerRobin KAY <komadori@users.sourceforge.net>2004-06-25 07:32:22 +0000
commiteecd260b1964fd92954f67898c612a2cb82f978b (patch)
tree3b0069143a106059f44ed79d5a135d09e84d43d3
parent2263f5fb2e425f69fea0bc33ca9ca4591c9976bd (diff)
downloadxine-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.c146
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;
}