about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog12
-rw-r--r--soft-fp/op-common.h34
-rw-r--r--soft-fp/soft-fp.h5
3 files changed, 50 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 18d1cbcfb6..29a4113dfe 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
 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.
 
diff --git a/soft-fp/op-common.h b/soft-fp/op-common.h
index e0a108a6ee..3da234ba33 100644
--- a/soft-fp/op-common.h
+++ b/soft-fp/op-common.h
@@ -63,6 +63,12 @@
 	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.  */			\
@@ -99,6 +105,21 @@
    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)			\
@@ -387,6 +408,8 @@
 #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.  */						\
@@ -1222,6 +1245,9 @@
 	  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						\
@@ -1264,6 +1290,9 @@
 	}								\
       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)))); \
@@ -1361,7 +1390,8 @@
 	    {								\
 	      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);			\
 		}							\
 	    }								\
@@ -1540,6 +1570,7 @@
 	{								\
 	  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				\
@@ -1625,6 +1656,7 @@
 	{								\
 	  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);		\
diff --git a/soft-fp/soft-fp.h b/soft-fp/soft-fp.h
index 4018b0ee91..3ac269ecf7 100644
--- a/soft-fp/soft-fp.h
+++ b/soft-fp/soft-fp.h
@@ -123,6 +123,11 @@
 # define FP_HANDLE_EXCEPTIONS do {} while (0)
 #endif
 
+/* Whether to flush subnormal inputs to zero with the same sign.  */
+#ifndef FP_DENORM_ZERO
+# define FP_DENORM_ZERO 0
+#endif
+
 #ifndef FP_INHIBIT_RESULTS
 /* By default we write the results always.
    sfp-machine may override this and e.g.