1 #ifndef	_MATH_H
2 
3 #ifdef _ISOMAC
4 # undef NO_LONG_DOUBLE
5 #endif
6 
7 #include <math/math.h>
8 
9 #ifndef _ISOMAC
10 /* Now define the internal interfaces.  */
11 extern int __signgam;
12 
13 # if IS_IN (libc) || IS_IN (libm)
14 hidden_proto (__finite)
15 hidden_proto (__isinf)
16 hidden_proto (__isnan)
17 hidden_proto (__finitef)
18 hidden_proto (__isinff)
19 hidden_proto (__isnanf)
20 
21 #  if !defined __NO_LONG_DOUBLE_MATH \
22       && __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 0
23 hidden_proto (__finitel)
24 hidden_proto (__isinfl)
25 hidden_proto (__isnanl)
26 #  endif
27 
28 #  if __HAVE_DISTINCT_FLOAT128
29 hidden_proto (__finitef128)
30 hidden_proto (__isinff128)
31 hidden_proto (__isnanf128)
32 #  endif
33 # endif
34 
35 libm_hidden_proto (__fpclassify)
36 libm_hidden_proto (__fpclassifyf)
37 libm_hidden_proto (__issignaling)
38 libm_hidden_proto (__issignalingf)
39 libm_hidden_proto (__exp)
40 libm_hidden_proto (__expf)
41 
42 #  if !defined __NO_LONG_DOUBLE_MATH \
43       && __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 0
44 libm_hidden_proto (__fpclassifyl)
45 libm_hidden_proto (__issignalingl)
46 libm_hidden_proto (__expl)
47 libm_hidden_proto (__expm1l)
48 # endif
49 
50 # if __HAVE_DISTINCT_FLOAT128
51 libm_hidden_proto (__fpclassifyf128)
52 libm_hidden_proto (__issignalingf128)
53 libm_hidden_proto (__expf128)
54 libm_hidden_proto (__expm1f128)
55 # endif
56 
57 #include <stdint.h>
58 #include <nan-high-order-bit.h>
59 
60 /* A union which permits us to convert between a float and a 32 bit
61    int.  */
62 
63 typedef union
64 {
65   float value;
66   uint32_t word;
67 } ieee_float_shape_type;
68 
69 /* Get a 32 bit int from a float.  */
70 #ifndef GET_FLOAT_WORD
71 # define GET_FLOAT_WORD(i,d)					\
72 do {								\
73   ieee_float_shape_type gf_u;					\
74   gf_u.value = (d);						\
75   (i) = gf_u.word;						\
76 } while (0)
77 #endif
78 
79 /* Set a float from a 32 bit int.  */
80 #ifndef SET_FLOAT_WORD
81 # define SET_FLOAT_WORD(d,i)					\
82 do {								\
83   ieee_float_shape_type sf_u;					\
84   sf_u.word = (i);						\
85   (d) = sf_u.value;						\
86 } while (0)
87 #endif
88 
89 extern inline int
__issignalingf(float x)90 __issignalingf (float x)
91 {
92   uint32_t xi;
93   GET_FLOAT_WORD (xi, x);
94 #if HIGH_ORDER_BIT_IS_SET_FOR_SNAN
95   /* We only have to care about the high-order bit of x's significand, because
96      having it set (sNaN) already makes the significand different from that
97      used to designate infinity.  */
98   return (xi & 0x7fc00000) == 0x7fc00000;
99 #else
100   /* To keep the following comparison simple, toggle the quiet/signaling bit,
101      so that it is set for sNaNs.  This is inverse to IEEE 754-2008 (as well as
102      common practice for IEEE 754-1985).  */
103   xi ^= 0x00400000;
104   /* We have to compare for greater (instead of greater or equal), because x's
105      significand being all-zero designates infinity not NaN.  */
106   return (xi & 0x7fffffff) > 0x7fc00000;
107 #endif
108 }
109 
110 # if __HAVE_DISTINCT_FLOAT128
111 
112 /* __builtin_isinf_sign is broken in GCC < 7 for float128.  */
113 #  if ! __GNUC_PREREQ (7, 0)
114 #   include <ieee754_float128.h>
115 extern inline int
__isinff128(_Float128 x)116 __isinff128 (_Float128 x)
117 {
118   int64_t hx, lx;
119   GET_FLOAT128_WORDS64 (hx, lx, x);
120   lx |= (hx & 0x7fffffffffffffffLL) ^ 0x7fff000000000000LL;
121   lx |= -lx;
122   return ~(lx >> 63) & (hx >> 62);
123 }
124 #  endif
125 
126 extern inline _Float128
fabsf128(_Float128 x)127 fabsf128 (_Float128 x)
128 {
129   return __builtin_fabsf128 (x);
130 }
131 # endif
132 
133 # if !(defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0)
134 #  ifndef NO_MATH_REDIRECT
135 /* Declare some functions for use within GLIBC.  Compilers typically
136    inline those functions as a single instruction.  Use an asm to
137    avoid use of PLTs if it doesn't.  */
138 #   define MATH_REDIRECT(FUNC, PREFIX, ARGS)			\
139   float (FUNC ## f) (ARGS (float)) asm (PREFIX #FUNC "f");	\
140   double (FUNC) (ARGS (double)) asm (PREFIX #FUNC );		\
141   MATH_REDIRECT_LDBL (FUNC, PREFIX, ARGS)			\
142   MATH_REDIRECT_F128 (FUNC, PREFIX, ARGS)
143 #   if defined __NO_LONG_DOUBLE_MATH 				\
144        || __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1
145 #    define MATH_REDIRECT_LDBL(FUNC, PREFIX, ARGS)
146 #   else
147 #    define MATH_REDIRECT_LDBL(FUNC, PREFIX, ARGS)			\
148   long double (FUNC ## l) (ARGS (long double)) asm (PREFIX #FUNC "l");
149 #   endif
150 #   if __HAVE_DISTINCT_FLOAT128
151 #    define MATH_REDIRECT_F128(FUNC, PREFIX, ARGS)			\
152   _Float128 (FUNC ## f128) (ARGS (_Float128)) asm (PREFIX #FUNC "f128");
153 #   else
154 #    define MATH_REDIRECT_F128(FUNC, PREFIX, ARGS)
155 #   endif
156 #   define MATH_REDIRECT_UNARY_ARGS(TYPE) TYPE
157 #   define MATH_REDIRECT_BINARY_ARGS(TYPE) TYPE, TYPE
158 #   define MATH_REDIRECT_TERNARY_ARGS(TYPE) TYPE, TYPE, TYPE
159 MATH_REDIRECT (sqrt, "__ieee754_", MATH_REDIRECT_UNARY_ARGS)
160 MATH_REDIRECT (ceil, "__", MATH_REDIRECT_UNARY_ARGS)
161 MATH_REDIRECT (floor, "__", MATH_REDIRECT_UNARY_ARGS)
162 MATH_REDIRECT (roundeven, "__", MATH_REDIRECT_UNARY_ARGS)
163 MATH_REDIRECT (rint, "__", MATH_REDIRECT_UNARY_ARGS)
164 MATH_REDIRECT (trunc, "__", MATH_REDIRECT_UNARY_ARGS)
165 MATH_REDIRECT (round, "__", MATH_REDIRECT_UNARY_ARGS)
166 MATH_REDIRECT (copysign, "__", MATH_REDIRECT_BINARY_ARGS)
167 MATH_REDIRECT (fma, "__", MATH_REDIRECT_TERNARY_ARGS)
168 #  endif
169 # endif
170 
171 #endif
172 #endif
173