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