diff options
Diffstat (limited to 'soft-fp')
-rw-r--r-- | soft-fp/op-common.h | 35 | ||||
-rw-r--r-- | soft-fp/soft-fp.h | 3 |
2 files changed, 34 insertions, 4 deletions
diff --git a/soft-fp/op-common.h b/soft-fp/op-common.h index e901981b95..6f8c1f3cb0 100644 --- a/soft-fp/op-common.h +++ b/soft-fp/op-common.h @@ -32,7 +32,7 @@ #define _FP_DECL(wc, X) \ _FP_I_TYPE X##_c __attribute__ ((unused)); \ _FP_I_TYPE X##_s __attribute__ ((unused)); \ - _FP_I_TYPE X##_e; \ + _FP_I_TYPE X##_e __attribute__ ((unused)); \ _FP_FRAC_DECL_##wc (X) /* Test whether the qNaN bit denotes a signaling NaN. */ @@ -191,8 +191,22 @@ #define _FP_PACK_SEMIRAW(fs, wc, X) \ do \ { \ + int _FP_PACK_SEMIRAW_is_tiny \ + = X##_e == 0 && !_FP_FRAC_ZEROP_##wc (X); \ + if (_FP_TININESS_AFTER_ROUNDING \ + && _FP_PACK_SEMIRAW_is_tiny) \ + { \ + FP_DECL_##fs (_FP_PACK_SEMIRAW_T); \ + _FP_FRAC_COPY_##wc (_FP_PACK_SEMIRAW_T, X); \ + _FP_PACK_SEMIRAW_T##_s = X##_s; \ + _FP_PACK_SEMIRAW_T##_e = X##_e; \ + _FP_FRAC_SLL_##wc (_FP_PACK_SEMIRAW_T, 1); \ + _FP_ROUND (wc, _FP_PACK_SEMIRAW_T); \ + if (_FP_FRAC_OVERP_##wc (fs, _FP_PACK_SEMIRAW_T)) \ + _FP_PACK_SEMIRAW_is_tiny = 0; \ + } \ _FP_ROUND (wc, X); \ - if (X##_e == 0 && !_FP_FRAC_ZEROP_##wc (X)) \ + if (_FP_PACK_SEMIRAW_is_tiny) \ { \ if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) \ || (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \ @@ -279,6 +293,17 @@ else \ { \ /* we've got a denormalized number */ \ + int _FP_PACK_CANONICAL_is_tiny = 1; \ + if (_FP_TININESS_AFTER_ROUNDING && X##_e == 0) \ + { \ + FP_DECL_##fs (_FP_PACK_CANONICAL_T); \ + _FP_FRAC_COPY_##wc (_FP_PACK_CANONICAL_T, X); \ + _FP_PACK_CANONICAL_T##_s = X##_s; \ + _FP_PACK_CANONICAL_T##_e = X##_e; \ + _FP_ROUND (wc, _FP_PACK_CANONICAL_T); \ + if (_FP_FRAC_OVERP_##wc (fs, _FP_PACK_CANONICAL_T)) \ + _FP_PACK_CANONICAL_is_tiny = 0; \ + } \ X##_e = -X##_e + 1; \ if (X##_e <= _FP_WFRACBITS_##fs) \ { \ @@ -296,8 +321,10 @@ X##_e = 0; \ _FP_FRAC_SRL_##wc (X, _FP_WORKBITS); \ } \ - if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) \ - || (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \ + if (_FP_PACK_CANONICAL_is_tiny \ + && ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) \ + || (FP_TRAPPING_EXCEPTIONS \ + & FP_EX_UNDERFLOW))) \ FP_SET_EXCEPTION (FP_EX_UNDERFLOW); \ } \ else \ diff --git a/soft-fp/soft-fp.h b/soft-fp/soft-fp.h index c8a98948f8..8d0efa58e7 100644 --- a/soft-fp/soft-fp.h +++ b/soft-fp/soft-fp.h @@ -161,6 +161,9 @@ # undef FP_ROUNDMODE # define FP_ROUNDMODE FP_RND_ZERO +# undef _FP_TININESS_AFTER_ROUNDING +# define _FP_TININESS_AFTER_ROUNDING 0 + #endif #define _FP_ROUND_NEAREST(wc, X) \ |