PATCH: Fix SSE and SSE2

H. J. Lu hjl@lucon.org
Thu May 22 06:46:00 GMT 2003


MMX is not that useful when we have to support x87. I don't think we
should even bother with it. We should support SSE and SSE2 instead.
I fixed a typo in sysdeps/i386/fpu/feenablxcpt.c. We switched stmxcsr
with ldmxcsr.  Also we should left shift MXCSR control word by 7.


H.J.
-------------- next part --------------
2003-05-22  H.J. Lu <hongjiu.lu@intel.com>

	* sysdeps/i386/fpu/fclrexcpt.c: Include <unistd.h>, <ldsodefs.h>
	and <dl-procinfo.h>.
	(__feclearexcept): Clear MXCSR if needed.
	* sysdeps/i386/fpu/fsetexcptflg.c: Likewise.

	* sysdeps/i386/fpu/fedisblxcpt.c (fedisableexcept): Set MXCSR
	for HWCAP_I386_XMM2. Left shift MXCSR control word by 7.
	* sysdeps/i386/fpu/feenablxcpt.c (feenableexcept): Likewise.
	Fix typo.

	* sysdeps/i386/fpu/feholdexcpt.c (feholdexcept): Set MXCSR for
	HWCAP_I386_XMM2.
	* sysdeps/i386/fpu/fesetround.c (fesetround): Likewise.
	* sysdeps/i386/fpu/ftestexcept.c (fetestexcept): Likewise.

	* sysdeps/unix/sysv/linux/i386/dl-procinfo.h (HWCAP_IMPORTANT):
	Set to (HWCAP_I386_XMM | HWCAP_I386_XMM2).

--- sysdeps/i386/fpu/fclrexcpt.c.p4	2001-07-05 21:55:53.000000000 -0700
+++ sysdeps/i386/fpu/fclrexcpt.c	2003-05-21 22:06:49.000000000 -0700
@@ -19,6 +19,9 @@
    02111-1307 USA.  */
 
 #include <fenv.h>
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
 
 int
 __feclearexcept (int excepts)
@@ -38,6 +41,21 @@ __feclearexcept (int excepts)
   /* Put the new data in effect.  */
   __asm__ ("fldenv %0" : : "m" (*&temp));
 
+  /* If the CPU supports SSE, we clear the MXCSR as well.  */
+  if ((GL(dl_hwcap_mask) & (HWCAP_I386_XMM | HWCAP_I386_XMM2)) != 0)
+    {
+      unsigned int xnew_exc;
+
+      /* Get the current MXCSR.  */
+      __asm__ ("stmxcsr %0" : "=m" (*&xnew_exc));
+      
+      /* Clear the relevant bits.  */
+      xnew_exc &= excepts ^ FE_ALL_EXCEPT;
+      
+      /* Put the new data in effect.  */
+      __asm__ ("ldmxcsr %0" : : "m" (*&xnew_exc));
+    }
+
   /* Success.  */
   return 0;
 }
--- sysdeps/i386/fpu/fedisblxcpt.c.p4	2003-04-29 08:38:11.000000000 -0700
+++ sysdeps/i386/fpu/fedisblxcpt.c	2003-05-21 22:07:01.000000000 -0700
@@ -38,15 +38,15 @@ fedisableexcept (int excepts)
   new_exc |= excepts;
   __asm__ ("fldcw %0" : : "m" (*&new_exc));
 
-  /* If the CPU supports SSE we set the MXCSR as well.  */
-  if ((GL(dl_hwcap_mask) & HWCAP_I386_XMM) != 0)
+  /* If the CPU supports SSE, we set the MXCSR as well.  */
+  if ((GL(dl_hwcap_mask) & (HWCAP_I386_XMM | HWCAP_I386_XMM2)) != 0)
     {
       unsigned int xnew_exc;
 
-      /* Get the current control word.  */
+      /* Get the current MXCSR.  */
       __asm__ ("stmxcsr %0" : "=m" (*&xnew_exc));
 
-      xnew_exc |= excepts;
+      xnew_exc |= excepts << 7;
 
       __asm__ ("ldmxcsr %0" : : "m" (*&xnew_exc));
     }
--- sysdeps/i386/fpu/feenablxcpt.c.p4	2003-04-29 08:38:11.000000000 -0700
+++ sysdeps/i386/fpu/feenablxcpt.c	2003-05-21 22:07:15.000000000 -0700
@@ -38,17 +38,17 @@ feenableexcept (int excepts)
   new_exc &= ~excepts;
   __asm__ ("fldcw %0" : : "m" (*&new_exc));
 
-  /* If the CPU supports SSE we set the MXCSR as well.  */
-  if ((GL(dl_hwcap_mask) & HWCAP_I386_XMM) != 0)
+  /* If the CPU supports SSE, we set the MXCSR as well.  */
+  if ((GL(dl_hwcap_mask) & (HWCAP_I386_XMM | HWCAP_I386_XMM2)) != 0)
     {
       unsigned int xnew_exc;
 
-      /* Get the current control word.  */
-      __asm__ ("ldmxcsr %0" : "=m" (*&xnew_exc));
+      /* Get the current MXCSR.  */
+      __asm__ ("stmxcsr %0" : "=m" (*&xnew_exc));
 
-      xnew_exc &= ~excepts;
+      xnew_exc &= (~excepts) << 7;
 
-      __asm__ ("stmxcsr %0" : : "m" (*&xnew_exc));
+      __asm__ ("ldmxcsr %0" : : "m" (*&xnew_exc));
     }
 
   return old_exc;
--- sysdeps/i386/fpu/feholdexcpt.c.p4	2003-04-29 08:38:11.000000000 -0700
+++ sysdeps/i386/fpu/feholdexcpt.c	2003-05-21 22:15:04.000000000 -0700
@@ -35,12 +35,12 @@ feholdexcept (fenv_t *envp)
   work = envp->__control_word | 0x3f;
   __asm__ ("fldcw %0" : : "m" (*&work));
 
-  /* If the CPU supports SSE we set the MXCSR as well.  */
-  if ((GL(dl_hwcap_mask) & HWCAP_I386_XMM) != 0)
+  /* If the CPU supports SSE, we set the MXCSR as well.  */
+  if ((GL(dl_hwcap_mask) & (HWCAP_I386_XMM | HWCAP_I386_XMM2)) != 0)
     {
       unsigned int xwork;
 
-      /* Get the current control word.  */
+      /* Get the current MXCSR.  */
       __asm__ ("stmxcsr %0" : "=m" (*&xwork));
 
       /* Set all exceptions to non-stop.  */
--- sysdeps/i386/fpu/fesetround.c.p4	2003-05-01 20:06:49.000000000 -0700
+++ sysdeps/i386/fpu/fesetround.c	2003-05-21 22:16:15.000000000 -0700
@@ -37,8 +37,8 @@ fesetround (int round)
   cw |= round;
   __asm__ ("fldcw %0" : : "m" (*&cw));
 
-  /* If the CPU supports SSE we set the MXCSR as well.  */
-  if ((GL(dl_hwcap_mask) & HWCAP_I386_XMM) != 0)
+  /* If the CPU supports SSE, we set the MXCSR as well.  */
+  if ((GL(dl_hwcap_mask) & (HWCAP_I386_XMM | HWCAP_I386_XMM2)) != 0)
     {
       unsigned int xcw;
 
--- sysdeps/i386/fpu/fsetexcptflg.c.p4	2001-07-05 21:55:53.000000000 -0700
+++ sysdeps/i386/fpu/fsetexcptflg.c	2003-05-21 23:30:15.000000000 -0700
@@ -21,6 +21,9 @@
 #include <fenv.h>
 #include <math.h>
 #include <bp-sym.h>
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
 
 int
 __fesetexceptflag (const fexcept_t *flagp, int excepts)
@@ -39,6 +42,22 @@ __fesetexceptflag (const fexcept_t *flag
      the next floating-point instruction.  */
   __asm__ ("fldenv %0" : : "m" (*&temp));
 
+  /* If the CPU supports SSE, we set the MXCSR as well.  */
+  if ((GL(dl_hwcap_mask) & (HWCAP_I386_XMM | HWCAP_I386_XMM2)) != 0)
+    {
+      unsigned int xnew_exc;
+
+      /* Get the current MXCSR.  */
+      __asm__ ("stmxcsr %0" : "=m" (*&xnew_exc));
+
+      /* Set the relevant bits.  */
+      xnew_exc &= ~(excepts & FE_ALL_EXCEPT);
+      xnew_exc |= *flagp & excepts & FE_ALL_EXCEPT;
+
+      /* Put the new data in effect.  */
+      __asm__ ("ldmxcsr %0" : : "m" (*&xnew_exc));
+    }
+  
   /* Success.  */
   return 0;
 }
--- sysdeps/i386/fpu/ftestexcept.c.p4	2003-05-01 20:06:49.000000000 -0700
+++ sysdeps/i386/fpu/ftestexcept.c	2003-05-21 23:27:44.000000000 -0700
@@ -32,8 +32,8 @@ fetestexcept (int excepts)
   /* Get current exceptions.  */
   __asm__ ("fnstsw %0" : "=a" (temp));
 
-  /* If the CPU supports SSE we test the MXCSR as well.  */
-  if ((GL(dl_hwcap_mask) & HWCAP_I386_XMM) != 0)
+  /* If the CPU supports SSE, we test the MXCSR as well.  */
+  if ((GL(dl_hwcap_mask) & (HWCAP_I386_XMM | HWCAP_I386_XMM2)) != 0)
     __asm__ ("stmxcsr %0" : "=m" (*&xtemp));
 
   return (temp | xtemp) & excepts & FE_ALL_EXCEPT;
--- sysdeps/unix/sysv/linux/i386/dl-procinfo.h.p4	2002-09-21 14:14:11.000000000 -0700
+++ sysdeps/unix/sysv/linux/i386/dl-procinfo.h	2003-05-21 22:06:13.000000000 -0700
@@ -92,7 +92,7 @@ enum
   HWCAP_I386_AMD3D = 1 << 31,
 
   /* XXX Which others to add here?  */
-  HWCAP_IMPORTANT = (HWCAP_I386_MMX)
+  HWCAP_IMPORTANT = (HWCAP_I386_XMM | HWCAP_I386_XMM2)
 
 };
 


More information about the Libc-alpha mailing list