+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]
#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. */
#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)) \
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) \
{ \
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 \
# 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) \
#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); \
#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)) \
} \
R##_c = FP_CLS_NAN; \
} while (0)
+
+#define _FP_TININESS_AFTER_ROUNDING 0
#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 { \
#define FP_EX_OVERFLOW (1 << 2)
#define FP_EX_UNDERFLOW (1 << 1)
#define FP_EX_INEXACT (1 << 0)
+
+#define _FP_TININESS_AFTER_ROUNDING 1
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
#define FP_EX_OVERFLOW (1 << 4)
#define FP_EX_UNDERFLOW (1 << 3)
#define FP_EX_INEXACT (1 << 2)
+
+#define _FP_TININESS_AFTER_ROUNDING 1
#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)
#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)
} \
R##_c = FP_CLS_NAN; \
} while (0)
+
+#define _FP_TININESS_AFTER_ROUNDING 0