about summary refs log tree commit diff
path: root/math/math-narrow.h
diff options
context:
space:
mode:
Diffstat (limited to 'math/math-narrow.h')
-rw-r--r--math/math-narrow.h53
1 files changed, 53 insertions, 0 deletions
diff --git a/math/math-narrow.h b/math/math-narrow.h
index 0194f8c97e..fee00f12df 100644
--- a/math/math-narrow.h
+++ b/math/math-narrow.h
@@ -342,4 +342,57 @@
     }						\
   while (0)
 
+/* Check for error conditions from a narrowing fused multiply-add
+   function returning RET with arguments X, Y and Z and set errno as
+   needed.  Checking for error conditions for fma (either narrowing or
+   not) and setting errno is not currently implemented.  See bug
+   6801.  */
+#define CHECK_NARROW_FMA(RET, X, Y, Z)		\
+  do						\
+    {						\
+    }						\
+  while (0)
+
+/* Implement narrowing fused multiply-add using round-to-odd.  The
+   arguments are X, Y and Z, the return type is TYPE and UNION,
+   MANTISSA, SUFFIX and CLEAR_UNDERFLOW are as for ROUND_TO_ODD.  */
+#define NARROW_FMA_ROUND_TO_ODD(X, Y, Z, TYPE, UNION, SUFFIX, MANTISSA, \
+				CLEAR_UNDERFLOW)			\
+  do									\
+    {									\
+      typeof (X) tmp;							\
+      TYPE ret;								\
+									\
+      tmp = ROUND_TO_ODD (fma ## SUFFIX (math_opt_barrier (X), (Y),	\
+					 (Z)),				\
+			  UNION, SUFFIX, MANTISSA, CLEAR_UNDERFLOW);	\
+      /* If the round-to-odd result is zero, the result is an exact	\
+	 zero and must be recomputed in the original rounding mode.  */ \
+      if (tmp == 0)							\
+	ret = (TYPE) (math_opt_barrier (X) * (Y) + (Z));		\
+      else								\
+	ret = (TYPE) tmp;						\
+									\
+      CHECK_NARROW_FMA (ret, (X), (Y), (Z));				\
+      return ret;							\
+    }									\
+  while (0)
+
+/* Implement a narrowing fused multiply-add function where no attempt
+   is made to be correctly rounding (this only applies to IBM long
+   double; the case where the function is not actually narrowing is
+   handled by aliasing other fma functions in libm, not using this
+   macro).  The arguments are X, Y and Z and the return type is
+   TYPE.  */
+#define NARROW_FMA_TRIVIAL(X, Y, Z, TYPE, SUFFIX)	\
+  do							\
+    {							\
+      TYPE ret;						\
+							\
+      ret = (TYPE) (fma ## SUFFIX ((X), (Y), (Z)));	\
+      CHECK_NARROW_FMA (ret, (X), (Y), (Z));		\
+      return ret;					\
+    }							\
+  while (0)
+
 #endif /* math-narrow.h.  */