* soft-fp/op-common.h (FP_TRUNC): When truncating a NaN, clear
authorjakub <jakub>
Mon, 15 Jan 2007 23:43:03 +0000 (23:43 +0000)
committerjakub <jakub>
Mon, 15 Jan 2007 23:43:03 +0000 (23:43 +0000)
workbits in semi-raw fraction.

* math/test-misc.c: Add new tests.

* math/basic-test.c: Include test-skeleton.c.
(TEST_TRUNC): Define.
(truncdfsf_test, trunctfsf_test, trunctfdf_test): New.
(main): Rename to ...
(do_test): ...this.  Run new tests.
(TEST_FUNCTION): Define.

[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.

ChangeLog
math/basic-test.c
math/test-misc.c
soft-fp/op-4.h
soft-fp/op-common.h

index f33e50a..7e45574 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+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.
+
+       * math/test-misc.c: Add new tests.
+
+2007-01-14  Steven Munroe  <sjmunroe@us.ibm.com>
+
+       * math/basic-test.c: Include test-skeleton.c.
+       (TEST_TRUNC): Define.
+       (truncdfsf_test, trunctfsf_test, trunctfdf_test): New.
+       (main): Rename to ...
+       (do_test): ...this.  Run new tests.
+       (TEST_FUNCTION): Define.
+
+2006-10-05  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.
+
 2007-01-15  Ulrich Drepper  <drepper@redhat.com>
 
        * nscd/connections.c (handle_request): Add a __builtin_expect.
index e42c014..e48a3ae 100644 (file)
@@ -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.
 
@@ -44,7 +44,7 @@ NAME (void)                                                                 \
                                                                              \
   zero_var = 0.0;                                                            \
   one_var = 1.0;                                                             \
-  NaN_var = zero_var/zero_var;                                               \
+  NaN_var = zero_var / zero_var;                                             \
   Inf_var = one_var / zero_var;                                                      \
                                                                              \
   (void) &zero_var;                                                          \
@@ -103,21 +103,51 @@ NAME (void)                                                                     \
   check (#FLOAT " isinf (-HUGE_VALx) == -1", isinf (x1) == -1);                      \
 }
 
+#define TEST_TRUNC(NAME, FLOAT, DOUBLE) \
+void                                                                         \
+NAME (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) &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);       \
+}
+
 TEST_FUNC (float_test, float, nanf, FLT_EPSILON, HUGE_VALF)
 TEST_FUNC (double_test, double, nan, DBL_EPSILON, HUGE_VAL)
+TEST_TRUNC (truncdfsf_test, float, double)
 #ifndef NO_LONG_DOUBLE
 TEST_FUNC (ldouble_test, long double, nanl, LDBL_EPSILON, HUGE_VALL)
+TEST_TRUNC (trunctfsf_test, float, long double)
+TEST_TRUNC (trunctfdf_test, double, long double)
 #endif
 
 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"
index d2393cc..862e11f 100644 (file)
@@ -1,5 +1,5 @@
 /* Miscellaneous tests which don't fit anywhere else.
-   Copyright (C) 2000, 2001, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2004, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -44,7 +44,6 @@ main (void)
       }
   }
 
-# if __GNUC__ >= 3 || __GNUC_MINOR__ >= 96
   {
     long double x;
     long double m;
@@ -52,17 +51,17 @@ main (void)
     int e;
     int i;
 
-#  if LDBL_MANT_DIG == 64
+# if LDBL_MANT_DIG == 64
     m = 0xf.fffffffffffffffp-4L;
-#  elif LDBL_MANT_DIG == 106
+# elif LDBL_MANT_DIG == 106
     /* This has to match the mantissa of LDBL_MAX which actually does have a
        missing bit in the middle.  */
     m = 0x1.fffffffffffff7ffffffffffff8p-1L;
-#  elif LDBL_MANT_DIG == 113
+# elif LDBL_MANT_DIG == 113
     m = 0x1.ffffffffffffffffffffffffffffp-1L;
-#  else
-#   error "Please adjust"
-#  endif
+# else
+#  error "Please adjust"
+# endif
 
     for (i = LDBL_MAX_EXP, x = LDBL_MAX; i >= LDBL_MIN_EXP; --i, x /= 2.0L)
       {
@@ -106,9 +105,8 @@ main (void)
       }
 
   }
-# endif
 
-#if 0
+# if 0
   {
     int e;
     long double r = frexpl (LDBL_MIN * LDBL_EPSILON, &e);
@@ -126,7 +124,7 @@ main (void)
        result = 1;
       }
   }
-#endif
+# endif
 #endif
 
   {
@@ -1183,5 +1181,59 @@ main (void)
     }
 #endif
 
+  volatile float f1 = FLT_MAX;
+  volatile float f2 = FLT_MAX / 2;
+  (void) &f1;
+  (void) &f2;
+  feclearexcept (FE_ALL_EXCEPT);
+  f2 += f1;
+  int fe = fetestexcept (FE_ALL_EXCEPT);
+  if (fe != (FE_OVERFLOW | FE_INEXACT))
+    {
+      printf ("float overflow test failed: %x\n", fe);
+      result = 1;
+    }
+
+  volatile double d1 = DBL_MAX;
+  volatile double d2 = DBL_MAX / 2;
+  (void) &d1;
+  (void) &d2;
+  feclearexcept (FE_ALL_EXCEPT);
+  d2 += d1;
+  fe = fetestexcept (FE_ALL_EXCEPT);
+  if (fe != (FE_OVERFLOW | FE_INEXACT))
+    {
+      printf ("double overflow test failed: %x\n", fe);
+      result = 1;
+    }
+
+#ifndef NO_LONG_DOUBLE
+  volatile long double ld1 = LDBL_MAX;
+  volatile long double ld2 = LDBL_MAX / 2;
+  (void) &ld1;
+  (void) &ld2;
+  feclearexcept (FE_ALL_EXCEPT);
+  ld2 += ld1;
+  fe = fetestexcept (FE_ALL_EXCEPT);
+  if (fe != (FE_OVERFLOW | FE_INEXACT))
+    {
+      printf ("long double overflow test failed: %x\n", fe);
+      result = 1;
+    }
+#endif
+
+#if !defined NO_LONG_DOUBLE && LDBL_MANT_DIG == 113
+  volatile long double ld3 = 0x1.0000000000010000000100000001p+1;
+  volatile long double ld4 = 0x1.0000000000000000000000000001p+1;
+  (void) &ld3;
+  (void) &ld4;
+  ld3 -= ld4;
+  if (ld3 != 0x1.0p-47)
+    {
+      printf ("long double subtraction test failed %.28La\n", ld3);
+      result = 1;
+    }
+#endif
+
   return result;
 }
index 34f5098..1b90535 100644 (file)
     r1 = x1 - y1;                                              \
     _c2 = r1 > x1;                                             \
     r1 -= _c1;                                                 \
-    _c2 |= r1 > _c1;                                           \
+    _c2 |= _c1 && (y1 == x1);                                  \
     r2 = x2 - y2 - _c2;                                                \
   } while (0)
 #endif
     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
index 4ec7fad..0aa6e3e 100644 (file)
@@ -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 @@ do {                                                        \
   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 @@ do {                                                                           \
              _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;                \
            }                                                                \
        }                                                                    \