]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - include/math.h
Correct range checking in mallopt/mxfast/tcache [BZ #25194]
[thirdparty/glibc.git] / include / math.h
index b28c4412e20dd5d9c321e9e7b73be78038334275..a274f2bdfd2c93eb97fd4050da01847fdddcc8c7 100644 (file)
@@ -1,10 +1,14 @@
 #ifndef        _MATH_H
 
+#ifdef _ISOMAC
+# undef NO_LONG_DOUBLE
+#endif
+
 #include <math/math.h>
 
 #ifndef _ISOMAC
 /* Now define the internal interfaces.  */
-extern int __matherr (struct exception *__exc);
+extern int __signgam;
 
 # if IS_IN (libc) || IS_IN (libm)
 hidden_proto (__finite)
@@ -19,6 +23,13 @@ hidden_proto (__finitel)
 hidden_proto (__isinfl)
 hidden_proto (__isnanl)
 #  endif
+
+#  if __HAVE_DISTINCT_FLOAT128
+hidden_proto (__finitef128)
+hidden_proto (__isinff128)
+hidden_proto (__isnanf128)
+hidden_proto (__signbitf128)
+#  endif
 # endif
 
 libm_hidden_proto (__fpclassify)
@@ -27,6 +38,7 @@ libm_hidden_proto (__issignaling)
 libm_hidden_proto (__issignalingf)
 libm_hidden_proto (__exp)
 libm_hidden_proto (__expf)
+libm_hidden_proto (__roundeven)
 
 # ifndef __NO_LONG_DOUBLE_MATH
 libm_hidden_proto (__fpclassifyl)
@@ -35,5 +47,122 @@ libm_hidden_proto (__expl)
 libm_hidden_proto (__expm1l)
 # endif
 
+# if __HAVE_DISTINCT_FLOAT128
+libm_hidden_proto (__fpclassifyf128)
+libm_hidden_proto (__issignalingf128)
+libm_hidden_proto (__expf128)
+libm_hidden_proto (__expm1f128)
+# endif
+
+#include <stdint.h>
+#include <nan-high-order-bit.h>
+
+/* A union which permits us to convert between a float and a 32 bit
+   int.  */
+
+typedef union
+{
+  float value;
+  uint32_t word;
+} ieee_float_shape_type;
+
+/* Get a 32 bit int from a float.  */
+#ifndef GET_FLOAT_WORD
+# define GET_FLOAT_WORD(i,d)                                   \
+do {                                                           \
+  ieee_float_shape_type gf_u;                                  \
+  gf_u.value = (d);                                            \
+  (i) = gf_u.word;                                             \
+} while (0)
+#endif
+
+/* Set a float from a 32 bit int.  */
+#ifndef SET_FLOAT_WORD
+# define SET_FLOAT_WORD(d,i)                                   \
+do {                                                           \
+  ieee_float_shape_type sf_u;                                  \
+  sf_u.word = (i);                                             \
+  (d) = sf_u.value;                                            \
+} while (0)
+#endif
+
+extern inline int
+__issignalingf (float x)
+{
+  uint32_t xi;
+  GET_FLOAT_WORD (xi, x);
+#if HIGH_ORDER_BIT_IS_SET_FOR_SNAN
+  /* We only have to care about the high-order bit of x's significand, because
+     having it set (sNaN) already makes the significand different from that
+     used to designate infinity.  */
+  return (xi & 0x7fc00000) == 0x7fc00000;
+#else
+  /* To keep the following comparison simple, toggle the quiet/signaling bit,
+     so that it is set for sNaNs.  This is inverse to IEEE 754-2008 (as well as
+     common practice for IEEE 754-1985).  */
+  xi ^= 0x00400000;
+  /* We have to compare for greater (instead of greater or equal), because x's
+     significand being all-zero designates infinity not NaN.  */
+  return (xi & 0x7fffffff) > 0x7fc00000;
+#endif
+}
+
+# if __HAVE_DISTINCT_FLOAT128
+
+/* __builtin_isinf_sign is broken in GCC < 7 for float128.  */
+#  if ! __GNUC_PREREQ (7, 0)
+#   include <ieee754_float128.h>
+extern inline int
+__isinff128 (_Float128 x)
+{
+  int64_t hx, lx;
+  GET_FLOAT128_WORDS64 (hx, lx, x);
+  lx |= (hx & 0x7fffffffffffffffLL) ^ 0x7fff000000000000LL;
+  lx |= -lx;
+  return ~(lx >> 63) & (hx >> 62);
+}
+#  endif
+
+extern inline _Float128
+fabsf128 (_Float128 x)
+{
+  return __builtin_fabsf128 (x);
+}
+# endif
+
+# if !(defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0)
+#  ifndef NO_MATH_REDIRECT
+/* Declare some functions for use within GLIBC.  Compilers typically
+   inline those functions as a single instruction.  Use an asm to
+   avoid use of PLTs if it doesn't.  */
+#   define MATH_REDIRECT(FUNC, PREFIX, ARGS)                   \
+  float (FUNC ## f) (ARGS (float)) asm (PREFIX #FUNC "f");     \
+  double (FUNC) (ARGS (double)) asm (PREFIX #FUNC );           \
+  MATH_REDIRECT_LDBL (FUNC, PREFIX, ARGS)                      \
+  MATH_REDIRECT_F128 (FUNC, PREFIX, ARGS)
+#   ifdef __NO_LONG_DOUBLE_MATH
+#    define MATH_REDIRECT_LDBL(FUNC, PREFIX, ARGS)
+#   else
+#    define MATH_REDIRECT_LDBL(FUNC, PREFIX, ARGS)                     \
+  long double (FUNC ## l) (ARGS (long double)) asm (PREFIX #FUNC "l");
+#   endif
+#   if __HAVE_DISTINCT_FLOAT128
+#    define MATH_REDIRECT_F128(FUNC, PREFIX, ARGS)                     \
+  _Float128 (FUNC ## f128) (ARGS (_Float128)) asm (PREFIX #FUNC "f128");
+#   else
+#    define MATH_REDIRECT_F128(FUNC, PREFIX, ARGS)
+#   endif
+#   define MATH_REDIRECT_UNARY_ARGS(TYPE) TYPE
+#   define MATH_REDIRECT_BINARY_ARGS(TYPE) TYPE, TYPE
+MATH_REDIRECT (sqrt, "__ieee754_", MATH_REDIRECT_UNARY_ARGS)
+MATH_REDIRECT (ceil, "__", MATH_REDIRECT_UNARY_ARGS)
+MATH_REDIRECT (floor, "__", MATH_REDIRECT_UNARY_ARGS)
+MATH_REDIRECT (rint, "__", MATH_REDIRECT_UNARY_ARGS)
+MATH_REDIRECT (trunc, "__", MATH_REDIRECT_UNARY_ARGS)
+MATH_REDIRECT (round, "__", MATH_REDIRECT_UNARY_ARGS)
+MATH_REDIRECT (copysign, "__", MATH_REDIRECT_BINARY_ARGS)
+#  endif
+# endif
+
 #endif
 #endif