diff options
-rw-r--r-- | ChangeLog | 33 | ||||
-rw-r--r-- | soft-fp/op-common.h | 35 | ||||
-rw-r--r-- | soft-fp/soft-fp.h | 3 | ||||
-rw-r--r-- | sysdeps/aarch64/soft-fp/sfp-machine.h | 2 | ||||
-rw-r--r-- | sysdeps/alpha/soft-fp/sfp-machine.h | 2 | ||||
-rw-r--r-- | sysdeps/arm/soft-fp/sfp-machine.h | 2 | ||||
-rw-r--r-- | sysdeps/mips/mips64/soft-fp/sfp-machine.h | 2 | ||||
-rw-r--r-- | sysdeps/mips/soft-fp/sfp-machine.h | 2 | ||||
-rw-r--r-- | sysdeps/powerpc/soft-fp/sfp-machine.h | 2 | ||||
-rw-r--r-- | sysdeps/sh/soft-fp/sfp-machine.h | 2 | ||||
-rw-r--r-- | sysdeps/sparc/sparc32/soft-fp/sfp-machine.h | 2 | ||||
-rw-r--r-- | sysdeps/sparc/sparc64/soft-fp/sfp-machine.h | 2 | ||||
-rw-r--r-- | sysdeps/tile/sfp-machine.h | 2 |
13 files changed, 87 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog index ffdb54696c..a7dc412492 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,36 @@ +2014-02-12 Joseph Myers <joseph@codesourcery.com> + + * soft-fp/op-common.h (_FP_DECL): Mark exponent as possibly + unused. + (_FP_PACK_SEMIRAW): Determine tininess based on rounding shifted + value if _FP_TININESS_AFTER_ROUNDING and unrounded value is in + subnormal range. + (_FP_PACK_CANONICAL): Determine tininess based on rounding to + normal precision if _FP_TININESS_AFTER_ROUNDING and unrounded + value has largest subnormal exponent. + * soft-fp/soft-fp.h [FP_NO_EXCEPTIONS] + (_FP_TININESS_AFTER_ROUNDING): Undefine and redefine to 0. + * sysdeps/aarch64/soft-fp/sfp-machine.h + (_FP_TININESS_AFTER_ROUNDING): New macro. + * sysdeps/alpha/soft-fp/sfp-machine.h + (_FP_TININESS_AFTER_ROUNDING): Likewise. + * sysdeps/arm/soft-fp/sfp-machine.h (_FP_TININESS_AFTER_ROUNDING): + Likewise. + * sysdeps/mips/mips64/soft-fp/sfp-machine.h + (_FP_TININESS_AFTER_ROUNDING): Likewise. + * sysdeps/mips/soft-fp/sfp-machine.h + (_FP_TININESS_AFTER_ROUNDING): Likewise. + * sysdeps/powerpc/soft-fp/sfp-machine.h + (_FP_TININESS_AFTER_ROUNDING): Likewise. + * sysdeps/sh/soft-fp/sfp-machine.h (_FP_TININESS_AFTER_ROUNDING): + Likewise. + * sysdeps/sparc/sparc32/soft-fp/sfp-machine.h + (_FP_TININESS_AFTER_ROUNDING): Likewise. + * sysdeps/sparc/sparc64/soft-fp/sfp-machine.h + (_FP_TININESS_AFTER_ROUNDING): Likewise. + * sysdeps/tile/sfp-machine.h (_FP_TININESS_AFTER_ROUNDING): + Likewise. + 2014-02-12 Dylan Alex Simon <dylan@dylex.net> [BZ #16545] 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) \ diff --git a/sysdeps/aarch64/soft-fp/sfp-machine.h b/sysdeps/aarch64/soft-fp/sfp-machine.h index 9bb94e5ccc..3e969952fa 100644 --- a/sysdeps/aarch64/soft-fp/sfp-machine.h +++ b/sysdeps/aarch64/soft-fp/sfp-machine.h @@ -60,6 +60,8 @@ #define FP_EX_DIVZERO FE_DIVBYZERO #define FP_EX_INEXACT FE_INEXACT +#define _FP_TININESS_AFTER_ROUNDING 0 + #define FP_INIT_ROUNDMODE \ do { \ _FPU_GETCW (_fcw); \ diff --git a/sysdeps/alpha/soft-fp/sfp-machine.h b/sysdeps/alpha/soft-fp/sfp-machine.h index cceccafe26..e11a8dd7ca 100644 --- a/sysdeps/alpha/soft-fp/sfp-machine.h +++ b/sysdeps/alpha/soft-fp/sfp-machine.h @@ -74,6 +74,8 @@ #define FP_EX_DIVZERO FE_DIVBYZERO #define FP_EX_INEXACT FE_INEXACT +#define _FP_TININESS_AFTER_ROUNDING 1 + #define FP_INIT_ROUNDMODE \ do { \ if (__builtin_expect (_round == 4, 0)) \ diff --git a/sysdeps/arm/soft-fp/sfp-machine.h b/sysdeps/arm/soft-fp/sfp-machine.h index eba6e35ced..52a08b5298 100644 --- a/sysdeps/arm/soft-fp/sfp-machine.h +++ b/sysdeps/arm/soft-fp/sfp-machine.h @@ -47,3 +47,5 @@ } \ R##_c = FP_CLS_NAN; \ } while (0) + +#define _FP_TININESS_AFTER_ROUNDING 0 diff --git a/sysdeps/mips/mips64/soft-fp/sfp-machine.h b/sysdeps/mips/mips64/soft-fp/sfp-machine.h index 5be50927d0..708afc783e 100644 --- a/sysdeps/mips/mips64/soft-fp/sfp-machine.h +++ b/sysdeps/mips/mips64/soft-fp/sfp-machine.h @@ -77,6 +77,8 @@ #define FP_EX_DIVZERO FE_DIVBYZERO #define FP_EX_INEXACT FE_INEXACT +#define _FP_TININESS_AFTER_ROUNDING 1 + #ifdef __mips_hard_float #define FP_INIT_ROUNDMODE \ do { \ diff --git a/sysdeps/mips/soft-fp/sfp-machine.h b/sysdeps/mips/soft-fp/sfp-machine.h index fff3b3c613..4e23aa8b26 100644 --- a/sysdeps/mips/soft-fp/sfp-machine.h +++ b/sysdeps/mips/soft-fp/sfp-machine.h @@ -64,3 +64,5 @@ #define FP_EX_OVERFLOW (1 << 2) #define FP_EX_UNDERFLOW (1 << 1) #define FP_EX_INEXACT (1 << 0) + +#define _FP_TININESS_AFTER_ROUNDING 1 diff --git a/sysdeps/powerpc/soft-fp/sfp-machine.h b/sysdeps/powerpc/soft-fp/sfp-machine.h index 35a38b0031..d92a90e3e2 100644 --- a/sysdeps/powerpc/soft-fp/sfp-machine.h +++ b/sysdeps/powerpc/soft-fp/sfp-machine.h @@ -41,6 +41,8 @@ R##_c = FP_CLS_NAN; \ } while (0) +#define _FP_TININESS_AFTER_ROUNDING 0 + #if defined __NO_FPRS__ && !defined _SOFT_FLOAT /* Exception flags. We use the bit positions of the appropriate bits diff --git a/sysdeps/sh/soft-fp/sfp-machine.h b/sysdeps/sh/soft-fp/sfp-machine.h index 9b9074860f..81474e8a7c 100644 --- a/sysdeps/sh/soft-fp/sfp-machine.h +++ b/sysdeps/sh/soft-fp/sfp-machine.h @@ -53,3 +53,5 @@ #define FP_EX_OVERFLOW (1 << 4) #define FP_EX_UNDERFLOW (1 << 3) #define FP_EX_INEXACT (1 << 2) + +#define _FP_TININESS_AFTER_ROUNDING 1 diff --git a/sysdeps/sparc/sparc32/soft-fp/sfp-machine.h b/sysdeps/sparc/sparc32/soft-fp/sfp-machine.h index 025b3ab196..b6baa8185f 100644 --- a/sysdeps/sparc/sparc32/soft-fp/sfp-machine.h +++ b/sysdeps/sparc/sparc32/soft-fp/sfp-machine.h @@ -185,6 +185,8 @@ #define FP_EX_DIVZERO (1 << 1) #define FP_EX_INEXACT (1 << 0) +#define _FP_TININESS_AFTER_ROUNDING 0 + #define _FP_DECL_EX \ fpu_control_t _fcw __attribute__ ((unused)) = (FP_RND_NEAREST << 30) diff --git a/sysdeps/sparc/sparc64/soft-fp/sfp-machine.h b/sysdeps/sparc/sparc64/soft-fp/sfp-machine.h index 9a0384b1d8..80c1ac5d52 100644 --- a/sysdeps/sparc/sparc64/soft-fp/sfp-machine.h +++ b/sysdeps/sparc/sparc64/soft-fp/sfp-machine.h @@ -93,6 +93,8 @@ do { \ #define FP_EX_DIVZERO (1 << 1) #define FP_EX_INEXACT (1 << 0) +#define _FP_TININESS_AFTER_ROUNDING 0 + #define _FP_DECL_EX \ fpu_control_t _fcw __attribute__ ((unused)) = (FP_RND_NEAREST << 30) diff --git a/sysdeps/tile/sfp-machine.h b/sysdeps/tile/sfp-machine.h index ff8beeffa7..7a1993ea61 100644 --- a/sysdeps/tile/sfp-machine.h +++ b/sysdeps/tile/sfp-machine.h @@ -95,3 +95,5 @@ } \ R##_c = FP_CLS_NAN; \ } while (0) + +#define _FP_TININESS_AFTER_ROUNDING 0 |