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