aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog40
-rw-r--r--math/test-misc.c85
-rw-r--r--soft-fp/extended.h38
-rw-r--r--soft-fp/floatundidf.c5
-rw-r--r--soft-fp/floatundisf.c5
-rw-r--r--soft-fp/floatunsidf.c5
-rw-r--r--soft-fp/floatunsisf.c5
-rw-r--r--soft-fp/op-2.h4
-rw-r--r--soft-fp/op-4.h4
-rw-r--r--soft-fp/op-common.h33
10 files changed, 164 insertions, 60 deletions
diff --git a/ChangeLog b/ChangeLog
index d77d7842b4..e89e7a7407 100644
--- 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.
diff --git a/math/test-misc.c b/math/test-misc.c
index 1dc4d909bb..a1ad6885db 100644
--- a/math/test-misc.c
+++ b/math/test-misc.c
@@ -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;
diff --git a/soft-fp/extended.h b/soft-fp/extended.h
index 0e2a90c084..e5f16debec 100644
--- a/soft-fp/extended.h
+++ b/soft-fp/extended.h
@@ -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)
diff --git a/soft-fp/floatundidf.c b/soft-fp/floatundidf.c
index 2169a3f198..af8e4a5aef 100644
--- a/soft-fp/floatundidf.c
+++ b/soft-fp/floatundidf.c
@@ -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);
diff --git a/soft-fp/floatundisf.c b/soft-fp/floatundisf.c
index 5f08764dc5..977f7dfc79 100644
--- a/soft-fp/floatundisf.c
+++ b/soft-fp/floatundisf.c
@@ -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);
diff --git a/soft-fp/floatunsidf.c b/soft-fp/floatunsidf.c
index 97b488ab68..12d0f25bf0 100644
--- a/soft-fp/floatunsidf.c
+++ b/soft-fp/floatunsidf.c
@@ -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);
diff --git a/soft-fp/floatunsisf.c b/soft-fp/floatunsisf.c
index 2ec16ba7b7..80c5d3d359 100644
--- a/soft-fp/floatunsisf.c
+++ b/soft-fp/floatunsisf.c
@@ -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);
diff --git a/soft-fp/op-2.h b/soft-fp/op-2.h
index 5c9bce4c17..3a3b3aa069 100644
--- a/soft-fp/op-2.h
+++ b/soft-fp/op-2.h
@@ -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),
@@ -613,3 +613,5 @@
#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)
diff --git a/soft-fp/op-4.h b/soft-fp/op-4.h
index 1b90535c56..70b9fafbe5 100644
--- a/soft-fp/op-4.h
+++ b/soft-fp/op-4.h
@@ -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)
diff --git a/soft-fp/op-common.h b/soft-fp/op-common.h
index 1f58b89478..ef11b527b7 100644
--- a/soft-fp/op-common.h
+++ b/soft-fp/op-common.h
@@ -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 \