[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[patches] PowerPC fesetexceptflag fixes



The e500 and -msoft-float versions of fesetexceptflag set the state
of all exceptions.  They're supposed to leave the state of other
exceptions alone, based on the text in C99.  While I was there I
updated some of the functions which should raise (or should not raise)
exceptions to match my understanding of the language standard.  I
don't know of anything that tests whether these functions raise
signals in particular conditions, though.

Does this look OK to commit?  If so I'd like to apply it everywhere
(that's trunk, 2.6, 2.5, and FSF libc-ports).

-- 
Daniel Jacobowitz
CodeSourcery

2007-08-24  Daniel Jacobowitz  <dan@xxxxxxxxxxxxxxxx>

	* sysdeps/powerpc/powerpc32/e500/fpu/fsetexcptflg.c
	(__fesetexceptflag): Do not clobber other exceptions.  Do not raise
	exceptions.
	* sysdeps/powerpc/nofpu/fsetexcptflg.c (__fesetexceptflag): Do not
	clobber other exceptions.
	* sysdeps/powerpc/nofpu/feupdateenv.c (__feupdateenv): Raise new
	exceptions.
	* sysdeps/powerpc/nofpu/fraiseexcpt.c (__feraiseexcept): Handle
	multiple new exceptions if some are disabled.
	* sysdeps/powerpc/nofpu/sim-full.c (__simulate_exceptions): Likewise.

Index: sysdeps/powerpc/powerpc32/e500/fpu/fsetexcptflg.c
===================================================================
--- sysdeps/powerpc/powerpc32/e500/fpu/fsetexcptflg.c	(revision 179541)
+++ sysdeps/powerpc/powerpc32/e500/fpu/fsetexcptflg.c	(working copy)
@@ -33,13 +33,10 @@ __fesetexceptflag (const fexcept_t *flag
   flag = *flagp & excepts;
 
   /* Replace the exception status */
-  spefscr = (spefscr & ~FE_ALL_EXCEPT) | flag;
+  spefscr = (spefscr & ~(FE_ALL_EXCEPT & excepts)) | flag;
 
-  /* Store the new status word (along with the rest of the environment).
-     This may cause floating-point exceptions if the restored state
-     requests it.  */
+  /* Store the new status word (along with the rest of the environment).  */
   fesetenv_register (spefscr);
-  feraiseexcept (spefscr & FE_ALL_EXCEPT);
 
   /* Success.  */
   return 0;
Index: sysdeps/powerpc/nofpu/fsetexcptflg.c
===================================================================
--- sysdeps/powerpc/nofpu/fsetexcptflg.c	(revision 179541)
+++ sysdeps/powerpc/nofpu/fsetexcptflg.c	(working copy)
@@ -26,7 +26,7 @@ int
 __fesetexceptflag(const fexcept_t *flagp, int excepts)
 {
   /* Ignore exceptions not listed in 'excepts'.  */
-  __sim_exceptions = *flagp & excepts;
+  __sim_exceptions = (__sim_exceptions & ~excepts) | (*flagp & excepts);
 
   return 0;
 }
Index: sysdeps/powerpc/nofpu/feupdateenv.c
===================================================================
--- sysdeps/powerpc/nofpu/feupdateenv.c	(revision 179541)
+++ sysdeps/powerpc/nofpu/feupdateenv.c	(working copy)
@@ -21,12 +21,12 @@
 
 #include "soft-fp.h"
 #include "soft-supp.h"
+#include <signal.h>
 #include <bp-sym.h>
 
 int
 __feupdateenv (const fenv_t *envp)
 {
-  fenv_union_t u;
   int saved_exceptions;
 
   /* Save currently set exceptions.  */
@@ -37,6 +37,8 @@ __feupdateenv (const fenv_t *envp)
 
   /* Raise old exceptions.  */
   __sim_exceptions |= saved_exceptions;
+  if (saved_exceptions & ~__sim_disabled_exceptions)
+    raise (SIGFPE);
 
   return 0;
 }
Index: sysdeps/powerpc/nofpu/fraiseexcpt.c
===================================================================
--- sysdeps/powerpc/nofpu/fraiseexcpt.c	(revision 179541)
+++ sysdeps/powerpc/nofpu/fraiseexcpt.c	(working copy)
@@ -28,10 +28,7 @@ int
 __feraiseexcept (int x)
 {
   __sim_exceptions |= x;
-  if (x == 0 || __sim_disabled_exceptions & x)
-    /* Ignore exception.  */
-    ;
-  else
+  if (x & ~__sim_disabled_exceptions)
     raise (SIGFPE);
   return 0;
 }
Index: sysdeps/powerpc/nofpu/sim-full.c
===================================================================
--- sysdeps/powerpc/nofpu/sim-full.c	(revision 179541)
+++ sysdeps/powerpc/nofpu/sim-full.c	(working copy)
@@ -37,9 +37,6 @@ void
 __simulate_exceptions (int x)
 {
   __sim_exceptions |= x;
-  if (x == 0 || __sim_disabled_exceptions & x)
-    /* Ignore exception.  */
-    ;
-  else
+  if (x & ~__sim_disabled_exceptions)
     raise (SIGFPE);
 }