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.h145
1 files changed, 61 insertions, 84 deletions
diff --git a/math/math-narrow.h b/math/math-narrow.h
index dadbe5cfba..93d1b4c52a 100644
--- a/math/math-narrow.h
+++ b/math/math-narrow.h
@@ -27,16 +27,20 @@
 #include <math-barriers.h>
 #include <math_private.h>
 #include <fenv_private.h>
+#include <math-narrow-alias.h>
 
 /* Carry out a computation using round-to-odd.  The computation is
    EXPR; the union type in which to store the result is UNION and the
    subfield of the "ieee" field of that union with the low part of the
-   mantissa is MANTISSA; SUFFIX is the suffix for the libc_fe* macros
-   to ensure that the correct rounding mode is used, for platforms
-   with multiple rounding modes where those macros set only the
-   relevant mode.  This macro does not work correctly if the sign of
-   an exact zero result depends on the rounding mode, so that case
-   must be checked for separately.  */
+   mantissa is MANTISSA; SUFFIX is the suffix for both underlying libm
+   functions for the argument type (for computations where a libm
+   function rather than a C operator is used when argument and result
+   types are the same) and the libc_fe* macros to ensure that the
+   correct rounding mode is used, for platforms with multiple rounding
+   modes where those macros set only the relevant mode.  This macro
+   does not work correctly if the sign of an exact zero result depends
+   on the rounding mode, so that case must be checked for
+   separately.  */
 #define ROUND_TO_ODD(EXPR, UNION, SUFFIX, MANTISSA)			\
   ({									\
     fenv_t env;								\
@@ -273,85 +277,58 @@
     }						\
   while (0)
 
-/* The following macros declare aliases for a narrowing function.  The
-   sole argument is the base name of a family of functions, such as
-   "add".  If any platform changes long double format after the
-   introduction of narrowing functions, in a way requiring symbol
-   versioning compatibility, additional variants of these macros will
-   be needed.  */
-
-#define libm_alias_float_double_main(func)	\
-  weak_alias (__f ## func, f ## func)		\
-  weak_alias (__f ## func, f32 ## func ## f64)	\
-  weak_alias (__f ## func, f32 ## func ## f32x)
-
-#ifdef NO_LONG_DOUBLE
-# define libm_alias_float_double(func)		\
-  libm_alias_float_double_main (func)		\
-  weak_alias (__f ## func, f ## func ## l)
-#else
-# define libm_alias_float_double(func)		\
-  libm_alias_float_double_main (func)
-#endif
-
-#define libm_alias_float32x_float64_main(func)			\
-  weak_alias (__f32x ## func ## f64, f32x ## func ## f64)
-
-#ifdef NO_LONG_DOUBLE
-# define libm_alias_float32x_float64(func)		\
-  libm_alias_float32x_float64_main (func)		\
-  weak_alias (__f32x ## func ## f64, d ## func ## l)
-#elif defined __LONG_DOUBLE_MATH_OPTIONAL
-# define libm_alias_float32x_float64(func)			\
-  libm_alias_float32x_float64_main (func)			\
-  weak_alias (__f32x ## func ## f64, __nldbl_d ## func ## l)
-#else
-# define libm_alias_float32x_float64(func)	\
-  libm_alias_float32x_float64_main (func)
-#endif
-
-#if __HAVE_FLOAT128 && !__HAVE_DISTINCT_FLOAT128
-# define libm_alias_float_ldouble_f128(func)		\
-  weak_alias (__f ## func ## l, f32 ## func ## f128)
-# define libm_alias_double_ldouble_f128(func)		\
-  weak_alias (__d ## func ## l, f32x ## func ## f128)	\
-  weak_alias (__d ## func ## l, f64 ## func ## f128)
-#else
-# define libm_alias_float_ldouble_f128(func)
-# define libm_alias_double_ldouble_f128(func)
-#endif
-
-#if __HAVE_FLOAT64X_LONG_DOUBLE
-# define libm_alias_float_ldouble_f64x(func)		\
-  weak_alias (__f ## func ## l, f32 ## func ## f64x)
-# define libm_alias_double_ldouble_f64x(func)		\
-  weak_alias (__d ## func ## l, f32x ## func ## f64x)	\
-  weak_alias (__d ## func ## l, f64 ## func ## f64x)
-#else
-# define libm_alias_float_ldouble_f64x(func)
-# define libm_alias_double_ldouble_f64x(func)
-#endif
-
-#define libm_alias_float_ldouble(func)		\
-  weak_alias (__f ## func ## l, f ## func ## l) \
-  libm_alias_float_ldouble_f128 (func)		\
-  libm_alias_float_ldouble_f64x (func)
-
-#define libm_alias_double_ldouble(func)		\
-  weak_alias (__d ## func ## l, d ## func ## l) \
-  libm_alias_double_ldouble_f128 (func)		\
-  libm_alias_double_ldouble_f64x (func)
-
-#define libm_alias_float64x_float128(func)			\
-  weak_alias (__f64x ## func ## f128, f64x ## func ## f128)
-
-#define libm_alias_float32_float128_main(func)			\
-  weak_alias (__f32 ## func ## f128, f32 ## func ## f128)
+/* Check for error conditions from a narrowing square root function
+   returning RET with argument X and set errno as needed.  Overflow
+   and underflow can occur for finite positive arguments and a domain
+   error for negative arguments.  */
+#define CHECK_NARROW_SQRT(RET, X)		\
+  do						\
+    {						\
+      if (!isfinite (RET))			\
+	{					\
+	  if (isnan (RET))			\
+	    {					\
+	      if (!isnan (X))			\
+		__set_errno (EDOM);		\
+	    }					\
+	  else if (isfinite (X))		\
+	    __set_errno (ERANGE);		\
+	}					\
+      else if ((RET) == 0 && (X) != 0)		\
+	__set_errno (ERANGE);			\
+    }						\
+  while (0)
 
-#define libm_alias_float64_float128_main(func)			\
-  weak_alias (__f64 ## func ## f128, f64 ## func ## f128)	\
-  weak_alias (__f64 ## func ## f128, f32x ## func ## f128)
+/* Implement narrowing square root using round-to-odd.  The argument
+   is X, the return type is TYPE and UNION, MANTISSA and SUFFIX are as
+   for ROUND_TO_ODD.  */
+#define NARROW_SQRT_ROUND_TO_ODD(X, TYPE, UNION, SUFFIX, MANTISSA)	\
+  do									\
+    {									\
+      TYPE ret;								\
+									\
+      ret = (TYPE) ROUND_TO_ODD (sqrt ## SUFFIX (math_opt_barrier (X)),	\
+				 UNION, SUFFIX, MANTISSA);		\
+									\
+      CHECK_NARROW_SQRT (ret, (X));					\
+      return ret;							\
+    }									\
+  while (0)
 
-#include <math-narrow-alias-float128.h>
+/* Implement a narrowing square root 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 sqrt functions in libm, not using this macro).  The
+   argument is X and the return type is TYPE.  */
+#define NARROW_SQRT_TRIVIAL(X, TYPE, SUFFIX)	\
+  do						\
+    {						\
+      TYPE ret;					\
+						\
+      ret = (TYPE) (sqrt ## SUFFIX (X));	\
+      CHECK_NARROW_SQRT (ret, (X));		\
+      return ret;				\
+    }						\
+  while (0)
 
 #endif /* math-narrow.h.  */