2014-10-09 Joseph Myers <joseph@codesourcery.com>
+ * soft-fp/soft-fp.h (FP_DENORM_ZERO): New macro.
+ * soft-fp/op-common.h (_FP_UNPACK_CANONICAL): Check
+ FP_DENORM_ZERO.
+ (_FP_CHECK_FLUSH_ZERO): New macro.
+ (_FP_ADD_INTERNAL): Call _FP_CHECK_FLUSH_ZERO.
+ (_FP_CMP): Likewise.
+ (_FP_CMP_EQ): Likewise.
+ (_FP_TO_INT): Do not set inexact for subnormal arguments if
+ FP_DENORM_ZERO.
+ (FP_EXTEND): Call _FP_CHECK_FLUSH_ZERO.
+ (FP_TRUNC): Likewise.
+
* soft-fp/op-common.h (_FP_TO_INT): Ensure maximum exponent is
treated as invalid conversion, not as normal exponent.
case 0: \
if (_FP_FRAC_ZEROP_##wc (X)) \
X##_c = FP_CLS_ZERO; \
+ else if (FP_DENORM_ZERO) \
+ { \
+ X##_c = FP_CLS_ZERO; \
+ _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc); \
+ FP_SET_EXCEPTION (FP_EX_DENORM); \
+ } \
else \
{ \
/* A denormalized number. */ \
other classification is not done. */
#define _FP_UNPACK_SEMIRAW(fs, wc, X) _FP_FRAC_SLL_##wc (X, _FP_WORKBITS)
+/* Check whether a raw or semi-raw input value should be flushed to
+ zero, and flush it to zero if so. */
+#define _FP_CHECK_FLUSH_ZERO(fs, wc, X) \
+ do \
+ { \
+ if (FP_DENORM_ZERO \
+ && X##_e == 0 \
+ && !_FP_FRAC_ZEROP_##wc (X)) \
+ { \
+ _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc); \
+ FP_SET_EXCEPTION (FP_EX_DENORM); \
+ } \
+ } \
+ while (0)
+
/* A semi-raw value has overflowed to infinity. Adjust the mantissa
and exponent appropriately. */
#define _FP_OVERFLOW_SEMIRAW(fs, wc, X) \
#define _FP_ADD_INTERNAL(fs, wc, R, X, Y, OP) \
do \
{ \
+ _FP_CHECK_FLUSH_ZERO (fs, wc, X); \
+ _FP_CHECK_FLUSH_ZERO (fs, wc, Y); \
if (X##_s == Y##_s) \
{ \
/* Addition. */ \
int _FP_CMP_is_zero_x; \
int _FP_CMP_is_zero_y; \
\
+ _FP_CHECK_FLUSH_ZERO (fs, wc, X); \
+ _FP_CHECK_FLUSH_ZERO (fs, wc, Y); \
+ \
_FP_CMP_is_zero_x \
= (!X##_e && _FP_FRAC_ZEROP_##wc (X)) ? 1 : 0; \
_FP_CMP_is_zero_y \
} \
else \
{ \
+ _FP_CHECK_FLUSH_ZERO (fs, wc, X); \
+ _FP_CHECK_FLUSH_ZERO (fs, wc, Y); \
+ \
ret = !(X##_e == Y##_e \
&& _FP_FRAC_EQ_##wc (X, Y) \
&& (X##_s == Y##_s || (!X##_e && _FP_FRAC_ZEROP_##wc (X)))); \
{ \
if (!_FP_FRAC_ZEROP_##wc (X)) \
{ \
- FP_SET_EXCEPTION (FP_EX_INEXACT); \
+ if (!FP_DENORM_ZERO) \
+ FP_SET_EXCEPTION (FP_EX_INEXACT); \
FP_SET_EXCEPTION (FP_EX_DENORM); \
} \
} \
{ \
if (S##_e == 0) \
{ \
+ _FP_CHECK_FLUSH_ZERO (sfs, swc, S); \
if (_FP_FRAC_ZEROP_##swc (S)) \
D##_e = 0; \
else if (_FP_EXPBIAS_##dfs \
{ \
if (S##_e == 0) \
{ \
+ _FP_CHECK_FLUSH_ZERO (sfs, swc, S); \
D##_e = 0; \
if (_FP_FRAC_ZEROP_##swc (S)) \
_FP_FRAC_SET_##dwc (D, _FP_ZEROFRAC_##dwc); \