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