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]

[PATCH] [BZ #2749] soft-fp fixes updated again


Moved fenv-libc.h to ports and will submit a separate patch for that.
Jakub provided an alternative to the _FP_PACK_SEMIRAW change to fix
FP_TRUNC directly. Finally updated math/basic-test.c to verify correct
truncation (double to float, long double to float, and long double to
double) of NaN and Infinity values.

The ldbl-128ibm patch
<http://sources.redhat.com/ml/libc-alpha/2007-01/msg00023.html> is still
applicable and has not changed.

2007-01-14  Steven Munroe  <sjmunroe@us.ibm.com>
	    Joe Kerian  <jkerian@us.us.ibm.com>

	[BZ #2749]
	* soft-fp/op-4.h (__FP_FRAC_SUB_3, __FP_FRAC_SUB_4): Correct borrow
	handling for high words.
	* soft-fp/op-common.h (_FP_OVERFLOW_SEMIRAW): Always set inexact
	and overflow for infinity.
	(_FP_PACK_SEMIRAW): Update comment.  Do not round if NaN or Inf.

	* math/basic-test.c (truncdfsf_test): New function.
	[!NO_LONG_DOUBLE] (trunctfsf_test): New function.
	[!NO_LONG_DOUBLE] (trunctfdf_test): New function.
	Change main() to do_test. Define TEST_FUNCTION. Include test-skeleton.c. 
	(do_test): Run new tests.

2007-01-15  Jakub Jelinek  <jakub@redhat.com>

	* soft-fp/op-common.h (FP_TRUNC): When truncating a NaN, clear
	workbits in semi-raw fraction.


diff -urN libc25-cvstip-20070104/math/basic-test.c libc24/math/basic-test.c
--- libc25-cvstip-20070104/math/basic-test.c	2001-07-05 23:55:35.000000000 -0500
+++ libc24/math/basic-test.c	2007-01-15 11:41:17.260963824 -0600
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1999, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Andreas Jaeger <aj@suse.de>, 1999.
 
@@ -107,17 +107,90 @@
 TEST_FUNC (double_test, double, nan, DBL_EPSILON, HUGE_VAL)
 #ifndef NO_LONG_DOUBLE
 TEST_FUNC (ldouble_test, long double, nanl, LDBL_EPSILON, HUGE_VALL)
+
+void
+trunctfsf_test(void)
+{
+  volatile long double Inf_var, NaN_var, zero_var, one_var;
+  float x1, x2;
+
+  zero_var = 0.0;
+  one_var = 1.0;
+  NaN_var = zero_var/zero_var;
+  Inf_var = one_var / zero_var;
+
+  (void) &zero_var;
+  (void) &one_var;
+  (void) &NaN_var;
+  (void) &Inf_var;
+
+  x1 = (float)NaN_var;
+  check (" float x = (float)((long double)NaN))", isnan (x1) != 0);
+  x2 = (float)Inf_var;
+  check (" float x = (float)((long double)Inf))", isinf (x2) != 0);
+}
+
+void
+trunctfdf_test(void)
+{
+  volatile long double Inf_var, NaN_var, zero_var, one_var;
+  double x1, x2;
+
+  zero_var = 0.0;
+  one_var = 1.0;
+  NaN_var = zero_var/zero_var;
+  Inf_var = one_var / zero_var;
+
+  (void) &zero_var;
+  (void) &one_var;
+  (void) &NaN_var;
+  (void) &Inf_var;
+
+  x1 = (double)NaN_var;
+  check (" double x = (double)((long double)NaN))", isnan (x1) != 0);
+  x2 = (double)Inf_var;
+  check (" double x = (double)((long double)Inf))", isinf (x2) != 0);
+}
+
 #endif
 
+void
+truncdfsf_test(void)
+{
+  volatile double Inf_var, NaN_var, zero_var, one_var;
+  float x1, x2;
+
+  zero_var = 0.0;
+  one_var = 1.0;
+  NaN_var = zero_var/zero_var;
+  Inf_var = one_var / zero_var;
+
+  (void) &zero_var;
+  (void) &one_var;
+  (void) &NaN_var;
+  (void) &Inf_var;
+
+  x1 = (float)NaN_var;
+  check (" float x = (float)((double)NaN))", isnan (x1) != 0);
+  x2 = (float)Inf_var;
+  check (" float x = (float)((double)Inf))", isinf (x2) != 0);
+}
+
 int
-main (void)
+do_test (void)
 {
   float_test ();
   double_test ();
+  truncdfsf_test();
 
 #ifndef NO_LONG_DOUBLE
   ldouble_test ();
+  trunctfsf_test();
+  trunctfdf_test();
 #endif
 
   return errors != 0;
 }
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff -urN libc25-cvstip-20070104/soft-fp/op-4.h libc24/soft-fp/op-4.h
--- libc25-cvstip-20070104/soft-fp/op-4.h	2006-04-04 03:24:47.000000000 -0500
+++ libc24/soft-fp/op-4.h	2007-01-11 11:00:53.000000000 -0600
@@ -564,7 +564,7 @@
     r1 = x1 - y1;						\
     _c2 = r1 > x1;						\
     r1 -= _c1;							\
-    _c2 |= r1 > _c1;						\
+    _c2 |= _c1 && (y1 == x1);					\
     r2 = x2 - y2 - _c2;						\
   } while (0)
 #endif
@@ -578,11 +578,11 @@
     r1 = x1 - y1;						\
     _c2 = r1 > x1;						\
     r1 -= _c1;							\
-    _c2 |= r1 > _c1;						\
+    _c2 |= _c1 && (y1 == x1);					\
     r2 = x2 - y2;						\
     _c3 = r2 > x2;						\
     r2 -= _c2;							\
-    _c3 |= r2 > _c2;						\
+    _c3 |= _c2 && (y2 == x2);					\
     r3 = x3 - y3 - _c3;						\
   } while (0)
 #endif
diff -urN libc25-cvstip-20070104/soft-fp/op-common.h libc24/soft-fp/op-common.h
--- libc25-cvstip-20070104/soft-fp/op-common.h	2006-04-04 03:24:47.000000000 -0500
+++ libc24/soft-fp/op-common.h	2007-01-15 11:46:17.290882288 -0600
@@ -1,5 +1,5 @@
 /* Software floating-point emulation. Common operations.
-   Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc.
+   Copyright (C) 1997,1998,1999,2006,2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Richard Henderson (rth@cygnus.com),
 		  Jakub Jelinek (jj@ultra.linux.cz),
@@ -99,10 +99,10 @@
   else							\
     {							\
       X##_e = _FP_EXPMAX_##fs - 1;			\
-      FP_SET_EXCEPTION(FP_EX_OVERFLOW);			\
-      FP_SET_EXCEPTION(FP_EX_INEXACT);			\
       _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc);		\
     }							\
+    FP_SET_EXCEPTION(FP_EX_INEXACT);			\
+    FP_SET_EXCEPTION(FP_EX_OVERFLOW);			\
 } while (0)
 
 /* Check for a semi-raw value being a signaling NaN and raise the
@@ -1252,6 +1252,9 @@
 	      _FP_FRAC_SRL_##swc(S, (_FP_WFRACBITS_##sfs		     \
 				     - _FP_WFRACBITS_##dfs));		     \
 	      _FP_FRAC_COPY_##dwc##_##swc(D, S);			     \
+	      /* Semi-raw NaN must have all workbits cleared.  */	     \
+	      _FP_FRAC_LOW_##dwc(D)					     \
+		&= ~(_FP_W_TYPE) ((1 << _FP_WORKBITS) - 1);		     \
 	      _FP_FRAC_HIGH_##dfs(D) |= _FP_QNANBIT_SH_##dfs;		     \
 	    }								     \
 	}								     \

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