xserver/fb fbmmx.c,1.15,1.16 fbpict.c,1.44,1.45

Billy Biggs xserver-commit at pdx.freedesktop.org
Sun Sep 18 21:02:33 PDT 2005


Committed by: vektor

Update of /cvs/xserver/xserver/fb
In directory gabe:/tmp/cvs-serv8004/fb

Modified Files:
	fbmmx.c fbpict.c 
Log Message:
	Bug #4414, reviewed by otaylor, cworth.

	* configure.ac: Remove -msse from the MMX CFLAGS as it causes
	gcc to emit SSE instructions, however the detection code only
	checks for processors supporting MMX and does not require SSE.
	Fix the MMX test to only check for MMX intrinsics and not the
	SSE intrinsics.
	* fb/fbmmx.c: Remove CPU detection code, only include
	xmmintrin.h if USE_SSE is defined.
	* fb/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.



Index: fbmmx.c
===================================================================
RCS file: /cvs/xserver/xserver/fb/fbmmx.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- fbmmx.c	19 Sep 2005 03:41:46 -0000	1.15
+++ fbmmx.c	19 Sep 2005 04:02:31 -0000	1.16
@@ -42,7 +42,9 @@
 #endif
 
 #include <mmintrin.h>
+#ifdef USE_SSE
 #include <xmmintrin.h> /* for _mm_shuffle_pi16 and _MM_SHUFFLE */
+#endif
 
 #ifdef RENDER
 
@@ -2470,117 +2472,4 @@
 		   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 */

Index: fbpict.c
===================================================================
RCS file: /cvs/xserver/xserver/fb/fbpict.c,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -d -r1.44 -r1.45
--- fbpict.c	19 Sep 2005 03:41:46 -0000	1.44
+++ fbpict.c	19 Sep 2005 04:02:31 -0000	1.45
@@ -1901,6 +1901,122 @@
     REGION_UNINIT (pDst->pDrawable->pScreen, &region);
 }
 
+/* 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 */
 
 Bool



More information about the xserver-commit mailing list