* soft-fp/op-common.h (FP_TRUNC): Replace raising of FP_EX_INEXACT cvs/fedora-glibc-20070504T0917
authorJakub Jelinek <jakub@redhat.com>
Thu, 3 May 2007 16:36:49 +0000 (16:36 +0000)
committerJakub Jelinek <jakub@redhat.com>
Thu, 3 May 2007 16:36:49 +0000 (16:36 +0000)
with setting the sticky bit.
* math/test-misc.c (main): Add more truncation tests.
* soft-fp/floatunsidf.c (__floatunsidf): Use DFtype instead of
double in the function declaration.
* soft-fp/floatundidf.c (__floatundidf): Use DFtype instead of
double in the function declaration.
* soft-fp/floatunsisf.c (__floatunsisf): Use SFtype instead of
float in the function declaration.
* soft-fp/floatunsisf.c (__floatunsisf): Use SFtype instead of
float in the function declaration.

* soft-fp/extended.h (FP_UNPACK_RAW_E): Do not increase X##_e for
denormal operands.  Do not generate FP_EX_DENORM exception.
(FP_UNPACK_RAW_EP): Ditto.
(FP_UNPACK_SEMIRAW_E): Use FP_UNPACK_RAW_E instead of
undefined _FP_UNPACK_RAW_E.
(FP_UNPACK_SEMIRAW_EP): Use FP_UNPACK_RAW_EP instead of
undefined _FP_UNPACK_RAW_EP.
(FP_PACK_SEMIRAW_E): Use FP_PACK_RAW_E instead of
undefined _FP_PACK_RAW_E.
(FP_PACK_SEMIRAW_EP): Use FP_PACK_RAW_EP instead of
undefined _FP_PACK_RAW_EP.

* op-2.h (_FP_FRAC_COPY_2_2): Define as alias to _FP_FRAC_COPY_2.
* op-4.h (_FP_FRAC_COPY_2_2): Define as alias to _FP_FRAC_COPY_4.

* soft-fp/op-common.h (FP_EXTEND): Do not abort when
_FP_EXPBIAS_##dfs == _FP_EXPBIAS_##sfs.  Handle denormals for
this case.
* soft-fp/op-common.h (FP_TRUNC): Ditto.
* soft-fp/op-common.h (FP_TRUNC): Replace raising of FP_EX_INEXACT
with setting the sticky bit.
* math/test-misc.c (main): Add more truncation tests.

2007-04-14  Uros Bizjak  <ubizjak@gmail.com>

* soft-fp/floatunsidf.c (__floatunsidf): Use DFtype instead of
double in the function declaration.
* soft-fp/floatundidf.c (__floatundidf): Use DFtype instead of
double in the function declaration.
* soft-fp/floatunsisf.c (__floatunsisf): Use SFtype instead of
float in the function declaration.
* soft-fp/floatunsisf.c (__floatunsisf): Use SFtype instead of
float in the function declaration.

* soft-fp/extended.h (FP_UNPACK_RAW_E): Do not increase X##_e for
denormal operands.  Do not generate FP_EX_DENORM exception.
(FP_UNPACK_RAW_EP): Ditto.
(FP_UNPACK_SEMIRAW_E): Use FP_UNPACK_RAW_E instead of
undefined _FP_UNPACK_RAW_E.
(FP_UNPACK_SEMIRAW_EP): Use FP_UNPACK_RAW_EP instead of
undefined _FP_UNPACK_RAW_EP.
(FP_PACK_SEMIRAW_E): Use FP_PACK_RAW_E instead of
undefined _FP_PACK_RAW_E.
(FP_PACK_SEMIRAW_EP): Use FP_PACK_RAW_EP instead of
undefined _FP_PACK_RAW_EP.

* op-2.h (_FP_FRAC_COPY_2_2): Define as alias to _FP_FRAC_COPY_2.
* op-4.h (_FP_FRAC_COPY_2_2): Define as alias to _FP_FRAC_COPY_4.

2007-04-16  Uros Bizjak  <ubizjak@gmail.com>
    Jakub Jelinek  <jakub@redhat.com>

* soft-fp/op-common.h (FP_EXTEND): Do not abort when
_FP_EXPBIAS_##dfs == _FP_EXPBIAS_##sfs.  Handle denormals for
this case.
* soft-fp/op-common.h (FP_TRUNC): Ditto.

2007-05-03  Jakub Jelinek  <jakub@redhat.com>

ChangeLog
math/test-misc.c
soft-fp/extended.h
soft-fp/floatundidf.c
soft-fp/floatundisf.c
soft-fp/floatunsidf.c
soft-fp/floatunsisf.c
soft-fp/op-2.h
soft-fp/op-4.h
soft-fp/op-common.h

index d77d784..e89e7a7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,45 @@
 2007-05-03  Jakub Jelinek  <jakub@redhat.com>
 
+       * soft-fp/op-common.h (FP_TRUNC): Replace raising of FP_EX_INEXACT
+       with setting the sticky bit.
+       * math/test-misc.c (main): Add more truncation tests.
+
+2007-04-14  Uros Bizjak  <ubizjak@gmail.com>
+
+       * soft-fp/floatunsidf.c (__floatunsidf): Use DFtype instead of
+       double in the function declaration.
+       * soft-fp/floatundidf.c (__floatundidf): Use DFtype instead of
+       double in the function declaration.
+       * soft-fp/floatunsisf.c (__floatunsisf): Use SFtype instead of
+       float in the function declaration.
+       * soft-fp/floatunsisf.c (__floatunsisf): Use SFtype instead of
+       float in the function declaration.
+
+       * soft-fp/extended.h (FP_UNPACK_RAW_E): Do not increase X##_e for
+       denormal operands.  Do not generate FP_EX_DENORM exception.
+       (FP_UNPACK_RAW_EP): Ditto.
+       (FP_UNPACK_SEMIRAW_E): Use FP_UNPACK_RAW_E instead of
+       undefined _FP_UNPACK_RAW_E.
+       (FP_UNPACK_SEMIRAW_EP): Use FP_UNPACK_RAW_EP instead of
+       undefined _FP_UNPACK_RAW_EP.
+       (FP_PACK_SEMIRAW_E): Use FP_PACK_RAW_E instead of
+       undefined _FP_PACK_RAW_E.
+       (FP_PACK_SEMIRAW_EP): Use FP_PACK_RAW_EP instead of
+       undefined _FP_PACK_RAW_EP.
+
+       * op-2.h (_FP_FRAC_COPY_2_2): Define as alias to _FP_FRAC_COPY_2.
+       * op-4.h (_FP_FRAC_COPY_2_2): Define as alias to _FP_FRAC_COPY_4.
+
+2007-04-16  Uros Bizjak  <ubizjak@gmail.com>
+           Jakub Jelinek  <jakub@redhat.com>
+
+       * soft-fp/op-common.h (FP_EXTEND): Do not abort when
+       _FP_EXPBIAS_##dfs == _FP_EXPBIAS_##sfs.  Handle denormals for
+       this case.
+       * soft-fp/op-common.h (FP_TRUNC): Ditto.
+
+2007-05-03  Jakub Jelinek  <jakub@redhat.com>
+
        * math/test-misc.c (main): Add tests for rounding long double
        values close to smallest double denormalized value to double.
 
index 1dc4d90..a1ad688 100644 (file)
@@ -1236,20 +1236,83 @@ main (void)
 #endif
 
 #if !defined NO_LONG_DOUBLE && LDBL_MANT_DIG >= DBL_MANT_DIG + 4
-  volatile long double ld5 = nextafter (0.0, 1.0) / 16.0L;
-  volatile double d5;
-  (void) &ld5;
-  int i;
-  for (i = 0; i <= 32; i++)
+  int oldmode = fegetround ();
+  int j;
+  for (j = 0; j < 4; j++)
     {
-      d5 = ld5 * i;
-      (void) &d5;
-      if (d5 != (i <= 8 ? 0 : i < 24 ? 1 : 2) * nextafter (0.0, 1.0))
+      int mode;
+      int i;
+      int k = 0;
+      const char *mstr;
+      switch (j)
        {
-         printf ("%La incorrectly rounded to %a\n", ld5 * i, d5);
-         result = 1;
+#ifdef FE_TONEAREST
+       case 0:
+         mode = FE_TONEAREST;
+         mstr = "nearest";
+         k = 8;
+         break;
+#endif
+#ifdef FE_DOWNWARD
+       case 1:
+         mode = FE_DOWNWARD;
+         mstr = "-inf";
+         break;
+#endif
+#ifdef FE_UPWARD
+       case 2:
+         mode = FE_UPWARD;
+         mstr = "+inf";
+         k = 15;
+         break;
+#endif
+#ifdef FE_TOWARDZERO
+       case 3:
+         mode = FE_TOWARDZERO;
+         mstr = "0";
+         break;
+#endif
+       default:
+         continue;
+       }
+
+      volatile long double ld5 = nextafter (0.0, 1.0) / 16.0L;
+      volatile double d5;
+      (void) &ld5;
+      for (i = 0; i <= 32; i++)
+       {
+         if (fesetround (mode))
+           {
+             printf ("failed to set rounding mode to %s\n", mstr);
+             result = 1;
+             break;
+           }
+         d5 = ld5 * i;
+         (void) &d5;
+         fesetround (oldmode);
+         if (d5 != ((j == 0 && i == 8) ? 0 : (i + k) / 16)
+                   * nextafter (0.0, 1.0))
+           {
+             printf ("%La incorrectly rounded to %s as %a\n",
+                     ld5 * i, mstr, d5);
+             result = 1;
+           }
        }
-    } 
+    }
+
+  volatile long double ld7 = nextafterl (0.0L, 1.0L);
+  volatile double d7;
+  (void) &ld7;
+  fesetround (FE_UPWARD);
+  d7 = ld7;
+  (void) &d7;
+  fesetround (oldmode);
+
+  if (d7 != nextafter (0.0, 1.0))
+    {
+      printf ("%La incorrectly rounded upward to %a\n", ld7, d7);
+      result = 1;
+    }
 #endif
 
   return result;
index 0e2a90c..e5f16de 100644 (file)
@@ -94,12 +94,6 @@ union _FP_UNION_E
     X##_f[1] = _flo.bits.frac1;                                \
     X##_e  = _flo.bits.exp;                            \
     X##_s  = _flo.bits.sign;                           \
-    if (!X##_e && (X##_f[1] || X##_f[0])               \
-        && !(X##_f[1] & _FP_IMPLBIT_E))                        \
-      {                                                        \
-        X##_e++;                                       \
-        FP_SET_EXCEPTION(FP_EX_DENORM);                        \
-      }                                                        \
   } while (0)
 
 #define FP_UNPACK_RAW_EP(X, val)                       \
@@ -112,12 +106,6 @@ union _FP_UNION_E
     X##_f[1] = _flo->bits.frac1;                       \
     X##_e  = _flo->bits.exp;                           \
     X##_s  = _flo->bits.sign;                          \
-    if (!X##_e && (X##_f[1] || X##_f[0])               \
-        && !(X##_f[1] & _FP_IMPLBIT_E))                        \
-      {                                                        \
-        X##_e++;                                       \
-        FP_SET_EXCEPTION(FP_EX_DENORM);                        \
-      }                                                        \
   } while (0)
 
 #define FP_PACK_RAW_E(val, X)                          \
@@ -164,13 +152,13 @@ union _FP_UNION_E
 
 #define FP_UNPACK_SEMIRAW_E(X,val)     \
   do {                                 \
-    _FP_UNPACK_RAW_E(X,val);           \
+    FP_UNPACK_RAW_E(X,val);            \
     _FP_UNPACK_SEMIRAW(E,4,X);         \
   } while (0)
 
 #define FP_UNPACK_SEMIRAW_EP(X,val)    \
   do {                                 \
-    _FP_UNPACK_RAW_EP(X,val);          \
+    FP_UNPACK_RAW_EP(X,val);           \
     _FP_UNPACK_SEMIRAW(E,4,X);         \
   } while (0)
 
@@ -189,13 +177,13 @@ union _FP_UNION_E
 #define FP_PACK_SEMIRAW_E(val,X)       \
   do {                                 \
     _FP_PACK_SEMIRAW(E,4,X);           \
-    _FP_PACK_RAW_E(val,X);             \
+    FP_PACK_RAW_E(val,X);              \
   } while (0)
 
 #define FP_PACK_SEMIRAW_EP(val,X)      \
   do {                                 \
     _FP_PACK_SEMIRAW(E,4,X);           \
-    _FP_PACK_RAW_EP(val,X);            \
+    FP_PACK_RAW_EP(val,X);             \
   } while (0)
 
 #define FP_ISSIGNAN_E(X)       _FP_ISSIGNAN(E,4,X)
@@ -299,11 +287,6 @@ union _FP_UNION_E
     X##_f1 = 0;                                                        \
     X##_e = _flo.bits.exp;                                     \
     X##_s = _flo.bits.sign;                                    \
-    if (!X##_e && X##_f0 && !(X##_f0 & _FP_IMPLBIT_E))         \
-      {                                                                \
-        X##_e++;                                               \
-        FP_SET_EXCEPTION(FP_EX_DENORM);                                \
-      }                                                                \
   } while (0)
 
 #define FP_UNPACK_RAW_EP(X, val)                               \
@@ -315,11 +298,6 @@ union _FP_UNION_E
     X##_f1 = 0;                                                        \
     X##_e = _flo->bits.exp;                                    \
     X##_s = _flo->bits.sign;                                   \
-    if (!X##_e && X##_f0 && !(X##_f0 & _FP_IMPLBIT_E))         \
-      {                                                                \
-        X##_e++;                                               \
-        FP_SET_EXCEPTION(FP_EX_DENORM);                                \
-      }                                                                \
   } while (0)
 
 #define FP_PACK_RAW_E(val, X)                                  \
@@ -365,13 +343,13 @@ union _FP_UNION_E
 
 #define FP_UNPACK_SEMIRAW_E(X,val)     \
   do {                                 \
-    _FP_UNPACK_RAW_E(X,val);           \
+    FP_UNPACK_RAW_E(X,val);            \
     _FP_UNPACK_SEMIRAW(E,2,X);         \
   } while (0)
 
 #define FP_UNPACK_SEMIRAW_EP(X,val)    \
   do {                                 \
-    _FP_UNPACK_RAW_EP(X,val);          \
+    FP_UNPACK_RAW_EP(X,val);           \
     _FP_UNPACK_SEMIRAW(E,2,X);         \
   } while (0)
 
@@ -390,13 +368,13 @@ union _FP_UNION_E
 #define FP_PACK_SEMIRAW_E(val,X)       \
   do {                                 \
     _FP_PACK_SEMIRAW(E,2,X);           \
-    _FP_PACK_RAW_E(val,X);             \
+    FP_PACK_RAW_E(val,X);              \
   } while (0)
 
 #define FP_PACK_SEMIRAW_EP(val,X)      \
   do {                                 \
     _FP_PACK_SEMIRAW(E,2,X);           \
-    _FP_PACK_RAW_EP(val,X);            \
+    FP_PACK_RAW_EP(val,X);             \
   } while (0)
 
 #define FP_ISSIGNAN_E(X)       _FP_ISSIGNAN(E,2,X)
index 2169a3f..af8e4a5 100644 (file)
@@ -1,6 +1,6 @@
 /* Software floating-point emulation.
    Convert a 64bit unsigned integer to IEEE double
-   Copyright (C) 1997,1999, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1999, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Richard Henderson (rth@cygnus.com) and
                  Jakub Jelinek (jj@ultra.linux.cz).
@@ -32,8 +32,7 @@
 #include "soft-fp.h"
 #include "double.h"
 
-double
-__floatundidf(UDItype i)
+DFtype __floatundidf(UDItype i)
 {
   FP_DECL_EX;
   FP_DECL_D(A);
index 5f08764..977f7df 100644 (file)
@@ -1,6 +1,6 @@
 /* Software floating-point emulation.
    Convert a 64bit unsigned integer to IEEE single
-   Copyright (C) 1997,1999, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1999, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Richard Henderson (rth@cygnus.com) and
                  Jakub Jelinek (jj@ultra.linux.cz).
@@ -32,8 +32,7 @@
 #include "soft-fp.h"
 #include "single.h"
 
-float
-__floatundisf(UDItype i)
+SFtype __floatundisf(UDItype i)
 {
   FP_DECL_EX;
   FP_DECL_S(A);
index 97b488a..12d0f25 100644 (file)
@@ -1,6 +1,6 @@
 /* Software floating-point emulation.
    Convert a 32bit unsigned integer to IEEE double
-   Copyright (C) 1997,1999, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1999, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Richard Henderson (rth@cygnus.com) and
                  Jakub Jelinek (jj@ultra.linux.cz).
@@ -32,8 +32,7 @@
 #include "soft-fp.h"
 #include "double.h"
 
-double
-__floatunsidf(USItype i)
+DFtype __floatunsidf(USItype i)
 {
   FP_DECL_EX;
   FP_DECL_D(A);
index 2ec16ba..80c5d3d 100644 (file)
@@ -1,6 +1,6 @@
 /* Software floating-point emulation.
    Convert a 32bit unsigned integer to IEEE single
-   Copyright (C) 1997,1999, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1999, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Richard Henderson (rth@cygnus.com) and
                  Jakub Jelinek (jj@ultra.linux.cz).
@@ -32,8 +32,7 @@
 #include "soft-fp.h"
 #include "single.h"
 
-float
-__floatunsisf(USItype i)
+SFtype __floatunsisf(USItype i)
 {
   FP_DECL_EX;
   FP_DECL_S(A);
index 5c9bce4..3a3b3aa 100644 (file)
@@ -1,6 +1,6 @@
 /* Software floating-point emulation.
    Basic two-word fraction declaration and manipulation.
-   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),
 #define _FP_FRAC_COPY_1_2(D, S)                (D##_f = S##_f0)
 
 #define _FP_FRAC_COPY_2_1(D, S)                ((D##_f0 = S##_f), (D##_f1 = 0))
+
+#define _FP_FRAC_COPY_2_2(D,S)         _FP_FRAC_COPY_2(D,S)
index 1b90535..70b9faf 100644 (file)
@@ -1,6 +1,6 @@
 /* Software floating-point emulation.
    Basic four-word fraction declaration and manipulation.
-   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),
@@ -684,3 +684,5 @@ do {                                                \
   D##_f[1] = S##_f1;                           \
   D##_f[2] = D##_f[3] = 0;                     \
 } while (0)
+
+#define _FP_FRAC_COPY_4_4(D,S) _FP_FRAC_COPY_4(D,S)
index 1f58b89..ef11b52 100644 (file)
@@ -1153,7 +1153,8 @@ do {                                                                       \
   if (_FP_FRACBITS_##dfs < _FP_FRACBITS_##sfs                           \
       || (_FP_EXPMAX_##dfs - _FP_EXPBIAS_##dfs                          \
          < _FP_EXPMAX_##sfs - _FP_EXPBIAS_##sfs)                        \
-      || _FP_EXPBIAS_##dfs < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1) \
+      || (_FP_EXPBIAS_##dfs < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1 \
+         && _FP_EXPBIAS_##dfs != _FP_EXPBIAS_##sfs))                    \
     abort();                                                            \
   D##_s = S##_s;                                                        \
   _FP_FRAC_COPY_##dwc##_##swc(D, S);                                    \
@@ -1168,6 +1169,14 @@ do {                                                                      \
        {                                                                \
          if (_FP_FRAC_ZEROP_##swc(S))                                   \
            D##_e = 0;                                                   \
+         else if (_FP_EXPBIAS_##dfs                                     \
+                  < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1)         \
+           {                                                            \
+             FP_SET_EXCEPTION(FP_EX_DENORM);                            \
+             _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs                  \
+                                    - _FP_FRACBITS_##sfs));             \
+             D##_e = 0;                                                 \
+           }                                                            \
          else                                                           \
            {                                                            \
              int _lz;                                                   \
@@ -1199,7 +1208,8 @@ do {                                                                       \
 #define FP_TRUNC(dfs,sfs,dwc,swc,D,S)                                       \
 do {                                                                        \
   if (_FP_FRACBITS_##sfs < _FP_FRACBITS_##dfs                               \
-      || _FP_EXPBIAS_##sfs < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1)     \
+      || (_FP_EXPBIAS_##sfs < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1     \
+         && _FP_EXPBIAS_##sfs != _FP_EXPBIAS_##dfs))                        \
     abort();                                                                \
   D##_s = S##_s;                                                            \
   if (_FP_EXP_NORMAL(sfs, swc, S))                                          \
@@ -1237,11 +1247,24 @@ do {                                                                         \
       if (S##_e == 0)                                                       \
        {                                                                    \
          D##_e = 0;                                                         \
-         _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc);                         \
-         if (!_FP_FRAC_ZEROP_##swc(S))                                      \
+         if (_FP_FRAC_ZEROP_##swc(S))                                       \
+           _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc);                       \
+         else                                                               \
            {                                                                \
              FP_SET_EXCEPTION(FP_EX_DENORM);                                \
-             FP_SET_EXCEPTION(FP_EX_INEXACT);                               \
+             if (_FP_EXPBIAS_##sfs                                          \
+                 < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1)              \
+               {                                                            \
+                 _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs                 \
+                                        - _FP_WFRACBITS_##dfs),             \
+                                    _FP_WFRACBITS_##sfs);                   \
+                 _FP_FRAC_COPY_##dwc##_##swc(D, S);                         \
+               }                                                            \
+             else                                                           \
+               {                                                            \
+                 _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc);                 \
+                 _FP_FRAC_LOW_##dwc(D) |= 1;                                \
+               }                                                            \
            }                                                                \
        }                                                                    \
       else                                                                  \