summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBilly Biggs <vektor@dumbterm.net>2005-09-18 19:55:54 +0000
committerBilly Biggs <vektor@dumbterm.net>2005-09-18 19:55:54 +0000
commit178909580f357f190fd26b437cdd962ce6fc59d0 (patch)
treeb84cb0978b06c75b9497ae3cf63aa347a58871ef
parent4ea8d8544ee254c46a6d20fa4f05a3b6a7c0bf6e (diff)
Bug #4414, reviewed by otaylor, cworth.
Remove CPU detection code, only include xmmintrin.h if USE_SSE is defined. Move CPU detection code out of the MMX file and into the generic code to avoid compiling it with -mmmx and -msse. Using these options causes gcc to use MMX and SSE instructions in the CPU detection code which causes SIGILLs on older processors.
-rw-r--r--pixman/ChangeLog12
-rw-r--r--pixman/src/fbmmx.c115
-rw-r--r--pixman/src/fbpict.c119
3 files changed, 132 insertions, 114 deletions
diff --git a/pixman/ChangeLog b/pixman/ChangeLog
index 85616ba1d..65fcb56a1 100644
--- a/pixman/ChangeLog
+++ b/pixman/ChangeLog
@@ -1,3 +1,15 @@
+2005-09-18 Billy Biggs <vektor@dumbterm.net>
+
+ Bug #4414, reviewed by otaylor, cworth.
+
+ * src/fbmmx.c: Remove CPU detection code, only include
+ xmmintrin.h if USE_SSE is defined.
+ * src/fbpict.c (detectCPUFeatures), (fbHaveMMX): Move CPU
+ detection code out of the MMX file and into the generic code to
+ avoid compiling it with -mmmx and -msse. Using these options
+ causes gcc to use MMX and SSE instructions in the CPU detection
+ code which causes SIGILLs on older processors.
+
2005-08-28 Owen Taylor <otaylor@redhat.com>
Bug #4260, Reviewed by B. Biggs
diff --git a/pixman/src/fbmmx.c b/pixman/src/fbmmx.c
index c71089518..2ba7d8b15 100644
--- a/pixman/src/fbmmx.c
+++ b/pixman/src/fbmmx.c
@@ -44,7 +44,9 @@
#endif
#include <mmintrin.h>
+#ifdef USE_SSE
#include <xmmintrin.h> /* for _mm_shuffle_pi16 and _MM_SHUFFLE */
+#endif
#ifdef RENDER
@@ -2471,117 +2473,4 @@ fbCompositeCopyAreammx (pixman_operator_t op,
width, height);
}
-#if !defined(__amd64__) && !defined(__x86_64__)
-
-enum CPUFeatures {
- NoFeatures = 0,
- MMX = 0x1,
- MMX_Extensions = 0x2,
- SSE = 0x6,
- SSE2 = 0x8,
- CMOV = 0x10
-};
-
-static unsigned int detectCPUFeatures(void) {
- unsigned int result;
- char vendor[13];
- vendor[0] = 0;
- vendor[12] = 0;
- /* see p. 118 of amd64 instruction set manual Vol3 */
- /* We need to be careful about the handling of %ebx and
- * %esp here. We can't declare either one as clobbered
- * since they are special registers (%ebx is the "PIC
- * register" holding an offset to global data, %esp the
- * stack pointer), so we need to make sure they have their
- * original values when we access the output operands.
- */
- __asm__ ("pushf\n"
- "pop %%eax\n"
- "mov %%eax, %%ecx\n"
- "xor $0x00200000, %%eax\n"
- "push %%eax\n"
- "popf\n"
- "pushf\n"
- "pop %%eax\n"
- "mov $0x0, %%edx\n"
- "xor %%ecx, %%eax\n"
- "jz 1f\n"
-
- "mov $0x00000000, %%eax\n"
- "push %%ebx\n"
- "cpuid\n"
- "mov %%ebx, %%eax\n"
- "pop %%ebx\n"
- "mov %%eax, %1\n"
- "mov %%edx, %2\n"
- "mov %%ecx, %3\n"
- "mov $0x00000001, %%eax\n"
- "push %%ebx\n"
- "cpuid\n"
- "pop %%ebx\n"
- "1:\n"
- "mov %%edx, %0\n"
- : "=r" (result),
- "=m" (vendor[0]),
- "=m" (vendor[4]),
- "=m" (vendor[8])
- :
- : "%eax", "%ecx", "%edx"
- );
-
- unsigned int features = 0;
- if (result) {
- /* result now contains the standard feature bits */
- if (result & (1 << 15))
- features |= CMOV;
- if (result & (1 << 23))
- features |= MMX;
- if (result & (1 << 25))
- features |= SSE;
- if (result & (1 << 26))
- features |= SSE2;
- if ((result & MMX) && !(result & SSE) && (strcmp(vendor, "AuthenticAMD") == 0)) {
- /* check for AMD MMX extensions */
-
- unsigned int result;
- __asm__("push %%ebx\n"
- "mov $0x80000000, %%eax\n"
- "cpuid\n"
- "xor %%edx, %%edx\n"
- "cmp $0x1, %%eax\n"
- "jge 1f\n"
- "mov $0x80000001, %%eax\n"
- "cpuid\n"
- "1:\n"
- "pop %%ebx\n"
- "mov %%edx, %0\n"
- : "=r" (result)
- :
- : "%eax", "%ecx", "%edx"
- );
- if (result & (1<<22))
- features |= MMX_Extensions;
- }
- }
- return features;
-}
-
-Bool
-fbHaveMMX (void)
-{
- static Bool initialized = FALSE;
- static Bool mmx_present;
-
- if (!initialized)
- {
- unsigned int features = detectCPUFeatures();
- mmx_present = (features & (MMX|MMX_Extensions)) == (MMX|MMX_Extensions);
- initialized = TRUE;
- }
-
- return mmx_present;
-}
-#endif /* __amd64__ */
-
-
#endif /* RENDER */
diff --git a/pixman/src/fbpict.c b/pixman/src/fbpict.c
index 27f256620..bcb6cc893 100644
--- a/pixman/src/fbpict.c
+++ b/pixman/src/fbpict.c
@@ -1,5 +1,5 @@
/*
- * $Id: fbpict.c,v 1.5.2.1 2005-09-16 13:43:41 otaylor Exp $
+ * $Id: fbpict.c,v 1.5.2.2 2005-09-19 02:55:54 vektor Exp $
*
* Copyright © 2000 SuSE, Inc.
*
@@ -1909,4 +1909,121 @@ pixman_composite (pixman_operator_t op,
pixman_region_destroy (region);
}
slim_hidden_def(pixman_composite);
+
+/* The CPU detection code needs to be in a file not compiled with
+ * "-mmmx -msse", as gcc would generate CMOV instructions otherwise
+ * that would lead to SIGILL instructions on old CPUs that don't have
+ * it.
+ */
+#if defined(USE_MMX) && !defined(__amd64__) && !defined(__x86_64__)
+
+enum CPUFeatures {
+ NoFeatures = 0,
+ MMX = 0x1,
+ MMX_Extensions = 0x2,
+ SSE = 0x6,
+ SSE2 = 0x8,
+ CMOV = 0x10
+};
+
+static unsigned int detectCPUFeatures(void) {
+ unsigned int result;
+ char vendor[13];
+ vendor[0] = 0;
+ vendor[12] = 0;
+ /* see p. 118 of amd64 instruction set manual Vol3 */
+ /* We need to be careful about the handling of %ebx and
+ * %esp here. We can't declare either one as clobbered
+ * since they are special registers (%ebx is the "PIC
+ * register" holding an offset to global data, %esp the
+ * stack pointer), so we need to make sure they have their
+ * original values when we access the output operands.
+ */
+ __asm__ ("pushf\n"
+ "pop %%eax\n"
+ "mov %%eax, %%ecx\n"
+ "xor $0x00200000, %%eax\n"
+ "push %%eax\n"
+ "popf\n"
+ "pushf\n"
+ "pop %%eax\n"
+ "mov $0x0, %%edx\n"
+ "xor %%ecx, %%eax\n"
+ "jz 1f\n"
+
+ "mov $0x00000000, %%eax\n"
+ "push %%ebx\n"
+ "cpuid\n"
+ "mov %%ebx, %%eax\n"
+ "pop %%ebx\n"
+ "mov %%eax, %1\n"
+ "mov %%edx, %2\n"
+ "mov %%ecx, %3\n"
+ "mov $0x00000001, %%eax\n"
+ "push %%ebx\n"
+ "cpuid\n"
+ "pop %%ebx\n"
+ "1:\n"
+ "mov %%edx, %0\n"
+ : "=r" (result),
+ "=m" (vendor[0]),
+ "=m" (vendor[4]),
+ "=m" (vendor[8])
+ :
+ : "%eax", "%ecx", "%edx"
+ );
+
+ unsigned int features = 0;
+ if (result) {
+ /* result now contains the standard feature bits */
+ if (result & (1 << 15))
+ features |= CMOV;
+ if (result & (1 << 23))
+ features |= MMX;
+ if (result & (1 << 25))
+ features |= SSE;
+ if (result & (1 << 26))
+ features |= SSE2;
+ if ((result & MMX) && !(result & SSE) && (strcmp(vendor, "AuthenticAMD") == 0)) {
+ /* check for AMD MMX extensions */
+
+ unsigned int result;
+ __asm__("push %%ebx\n"
+ "mov $0x80000000, %%eax\n"
+ "cpuid\n"
+ "xor %%edx, %%edx\n"
+ "cmp $0x1, %%eax\n"
+ "jge 1f\n"
+ "mov $0x80000001, %%eax\n"
+ "cpuid\n"
+ "1:\n"
+ "pop %%ebx\n"
+ "mov %%edx, %0\n"
+ : "=r" (result)
+ :
+ : "%eax", "%ecx", "%edx"
+ );
+ if (result & (1<<22))
+ features |= MMX_Extensions;
+ }
+ }
+ return features;
+}
+
+Bool
+fbHaveMMX (void)
+{
+ static Bool initialized = FALSE;
+ static Bool mmx_present;
+
+ if (!initialized)
+ {
+ unsigned int features = detectCPUFeatures();
+ mmx_present = (features & (MMX|MMX_Extensions)) == (MMX|MMX_Extensions);
+ initialized = TRUE;
+ }
+
+ return mmx_present;
+}
+#endif /* USE_MMX && !amd64 */
#endif /* RENDER */