This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

soft-fp: fix negation NaN handling (bug 16034)


Floating-point negation is, in IEEE 754-2008, a quiet-computational
operation affecting only the sign bit and not handling signaling NaNs
specially.  The soft-fp code for negation uses cooked packing and
unpacking, meaning signaling NaNs are wrongly quieted (bug 16034); it
uses the peculiar "FP_CLEAR_EXCEPTIONS; FP_HANDLE_EXCEPTIONS;"
combination so exception processing takes place for an empty set of
exceptions.  This patch makes it use raw packing / unpacking and not
handle exceptions at all.  (The immediate motivation is that the
cooked packing, without FP_INIT_ROUNDMODE having been used to
initialize rounding / exception state, causes warnings building for
e500, as the rounding (which does nothing) in the cooked packing uses
an uninitialized rounding mode value.  Some architectures use default
initializations in their _FP_DECL_EX to avoid such warnings, but I
don't think this should be necessary and it could hide bugs in cases
where a non-default initialization is actually needed.)

These function won't generally be used, in that negation will
generally be expanded inline for soft-float, but of course they should
have the correct semantics in case they are used.

Tested for powerpc-nofpu.  Note that I haven't tested the SPARC
change.

2013-10-09  Joseph Myers  <joseph@codesourcery.com>

	[BZ #16034]
	* soft-fp/op-common.h (_FP_NEG): Document input as raw.  Do not
	copy class of input value.
	* soft-fp/negdf2.c (__negdf2): Use raw unpacking and packing.  Do
	not handle exceptions.
	* soft-fp/negsf2.c (__negsf2): Likewise.
	* soft-fp/negtf2.c (__negtf2): Likewise.
	* sysdeps/sparc/sparc32/soft-fp/q_neg.c (_Q_neg): Likewise.

diff --git a/soft-fp/negdf2.c b/soft-fp/negdf2.c
index 3cc6f5f..1dedc71 100644
--- a/soft-fp/negdf2.c
+++ b/soft-fp/negdf2.c
@@ -33,15 +33,12 @@
 
 DFtype __negdf2(DFtype a)
 {
-  FP_DECL_EX;
   FP_DECL_D(A); FP_DECL_D(R);
   DFtype r;
 
-  FP_UNPACK_D(A, a);
+  FP_UNPACK_RAW_D(A, a);
   FP_NEG_D(R, A);
-  FP_PACK_D(r, R);
-  FP_CLEAR_EXCEPTIONS;
-  FP_HANDLE_EXCEPTIONS;
+  FP_PACK_RAW_D(r, R);
 
   return r;
 }
diff --git a/soft-fp/negsf2.c b/soft-fp/negsf2.c
index d8d5910..35ece56 100644
--- a/soft-fp/negsf2.c
+++ b/soft-fp/negsf2.c
@@ -33,15 +33,12 @@
 
 SFtype __negsf2(SFtype a)
 {
-  FP_DECL_EX;
   FP_DECL_S(A); FP_DECL_S(R);
   SFtype r;
 
-  FP_UNPACK_S(A, a);
+  FP_UNPACK_RAW_S(A, a);
   FP_NEG_S(R, A);
-  FP_PACK_S(r, R);
-  FP_CLEAR_EXCEPTIONS;
-  FP_HANDLE_EXCEPTIONS;
+  FP_PACK_RAW_S(r, R);
 
   return r;
 }
diff --git a/soft-fp/negtf2.c b/soft-fp/negtf2.c
index 1c08441..f51a621 100644
--- a/soft-fp/negtf2.c
+++ b/soft-fp/negtf2.c
@@ -33,15 +33,12 @@
 
 TFtype __negtf2(TFtype a)
 {
-  FP_DECL_EX;
   FP_DECL_Q(A); FP_DECL_Q(R);
   TFtype r;
 
-  FP_UNPACK_Q(A, a);
+  FP_UNPACK_RAW_Q(A, a);
   FP_NEG_Q(R, A);
-  FP_PACK_Q(r, R);
-  FP_CLEAR_EXCEPTIONS;
-  FP_HANDLE_EXCEPTIONS;
+  FP_PACK_RAW_Q(r, R);
 
   return r;
 }
diff --git a/soft-fp/op-common.h b/soft-fp/op-common.h
index 75ea352..5dfb73c 100644
--- a/soft-fp/op-common.h
+++ b/soft-fp/op-common.h
@@ -771,14 +771,12 @@ do {									 \
 
 
 /*
- * Main negation routine.  FIXME -- when we care about setting exception
- * bits reliably, this will not do.  We should examine all of the fp classes.
+ * Main negation routine.  The input value is raw.
  */
 
 #define _FP_NEG(fs, wc, R, X)		\
   do {					\
     _FP_FRAC_COPY_##wc(R, X);		\
-    R##_c = X##_c;			\
     R##_e = X##_e;			\
     R##_s = 1 ^ X##_s;			\
   } while (0)
diff --git a/sysdeps/sparc/sparc32/soft-fp/q_neg.c b/sysdeps/sparc/sparc32/soft-fp/q_neg.c
index 551c408..5e2449c 100644
--- a/sysdeps/sparc/sparc32/soft-fp/q_neg.c
+++ b/sysdeps/sparc/sparc32/soft-fp/q_neg.c
@@ -24,7 +24,6 @@
 
 long double _Q_neg(const long double a)
 {
-  FP_DECL_EX;
   long double c = a;
 
 #if (__BYTE_ORDER == __BIG_ENDIAN)
@@ -36,11 +35,9 @@ long double _Q_neg(const long double a)
 #else
   FP_DECL_Q(A); FP_DECL_Q(C);
 
-  FP_UNPACK_Q(A, a);
+  FP_UNPACK_RAW_Q(A, a);
   FP_NEG_Q(C, A);
-  FP_PACK_Q(c, C);
+  FP_PACK_RAW_Q(c, C);
 #endif
-  FP_CLEAR_EXCEPTIONS;
-  FP_HANDLE_EXCEPTIONS;
   return c;
 }

-- 
Joseph S. Myers
joseph@codesourcery.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]