1 /* Configuration for math routines.
2 Copyright (c) 2017-2018 Arm Ltd. All rights reserved.
3
4 SPDX-License-Identifier: BSD-3-Clause
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
9 1. Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 2. Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14 3. The name of the company may not be used to endorse or promote
15 products derived from this software without specific prior written
16 permission.
17
18 THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
19 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
23 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
28
29 #ifndef _MATH_CONFIG_H
30 #define _MATH_CONFIG_H
31
32 #include <math.h>
33 #include <stdint.h>
34 #include <errno.h>
35 #include <fenv.h>
36
37 #ifndef WANT_ROUNDING
38 /* Correct special case results in non-nearest rounding modes. */
39 # define WANT_ROUNDING 1
40 #endif
41 #ifdef _IEEE_LIBM
42 # define WANT_ERRNO 0
43 # define _LIB_VERSION _IEEE_
44 #else
45 /* Set errno according to ISO C with (math_errhandling & MATH_ERRNO) != 0. */
46 # define WANT_ERRNO 1
47 # define _LIB_VERSION _POSIX_
48 #endif
49 #ifndef WANT_ERRNO_UFLOW
50 /* Set errno to ERANGE if result underflows to 0 (in all rounding modes). */
51 # define WANT_ERRNO_UFLOW (WANT_ROUNDING && WANT_ERRNO)
52 #endif
53
54 #define _IEEE_ -1
55 #define _POSIX_ 0
56
57 #ifdef _HAVE_ATTRIBUTE_ALWAYS_INLINE
58 #define ALWAYS_INLINE __inline__ __attribute__((__always_inline__))
59 #else
60 #define ALWAYS_INLINE __inline__
61 #endif
62
63 #ifdef _HAVE_ATTRIBUTE_NOINLINE
64 # define NOINLINE __attribute__ ((__noinline__))
65 #else
66 # define NOINLINE
67 #endif
68
69 #ifdef _HAVE_BUILTIN_EXPECT
70 # define likely(x) __builtin_expect (!!(x), 1)
71 # define unlikely(x) __builtin_expect (x, 0)
72 #else
73 # define likely(x) (x)
74 # define unlikely(x) (x)
75 #endif
76
77 /* Compiler can inline round as a single instruction. */
78 #ifndef HAVE_FAST_ROUND
79 # if __aarch64__
80 # define HAVE_FAST_ROUND 1
81 # else
82 # define HAVE_FAST_ROUND 0
83 # endif
84 #endif
85
86 /* Compiler can inline lround, but not (long)round(x). */
87 #ifndef HAVE_FAST_LROUND
88 # if __aarch64__ && (100*__GNUC__ + __GNUC_MINOR__) >= 408 && __NO_MATH_ERRNO__
89 # define HAVE_FAST_LROUND 1
90 # else
91 # define HAVE_FAST_LROUND 0
92 # endif
93 #endif
94
95 #if HAVE_FAST_ROUND
96 /* When set, the roundtoint and converttoint functions are provided with
97 the semantics documented below. */
98 # define TOINT_INTRINSICS 1
99
100 /* Round x to nearest int in all rounding modes, ties have to be rounded
101 consistently with converttoint so the results match. If the result
102 would be outside of [-2^31, 2^31-1] then the semantics is unspecified. */
103 static ALWAYS_INLINE double_t
roundtoint(double_t x)104 roundtoint (double_t x)
105 {
106 return round (x);
107 }
108
109 /* Convert x to nearest int in all rounding modes, ties have to be rounded
110 consistently with roundtoint. If the result is not representible in an
111 int32_t then the semantics is unspecified. */
112 static ALWAYS_INLINE int32_t
converttoint(double_t x)113 converttoint (double_t x)
114 {
115 # if HAVE_FAST_LROUND
116 return lround (x);
117 # else
118 return (long) round (x);
119 # endif
120 }
121 #endif
122
123 #ifndef TOINT_INTRINSICS
124 # define TOINT_INTRINSICS 0
125 #endif
126
127 static ALWAYS_INLINE uint32_t
asuint(float f)128 asuint (float f)
129 {
130 #if defined(__riscv_flen) && __riscv_flen >= 32
131 uint32_t result;
132 __asm__("fmv.x.w\t%0, %1" : "=r" (result) : "f" (f));
133 return result;
134 #else
135 union
136 {
137 float f;
138 uint32_t i;
139 } u = {f};
140 return u.i;
141 #endif
142 }
143
144 static ALWAYS_INLINE float
asfloat(uint32_t i)145 asfloat (uint32_t i)
146 {
147 #if defined(__riscv_flen) && __riscv_flen >= 32
148 float result;
149 __asm__("fmv.w.x\t%0, %1" : "=f" (result) : "r" (i));
150 return result;
151 #else
152 union
153 {
154 uint32_t i;
155 float f;
156 } u = {i};
157 return u.f;
158 #endif
159 }
160
161 static ALWAYS_INLINE int32_t
_asint32(float f)162 _asint32 (float f)
163 {
164 return (int32_t) asuint(f);
165 }
166
167 static ALWAYS_INLINE int
_sign32(int32_t ix)168 _sign32(int32_t ix)
169 {
170 return ((uint32_t) ix) >> 31;
171 }
172
173 static ALWAYS_INLINE int
_exponent32(int32_t ix)174 _exponent32(int32_t ix)
175 {
176 return (ix >> 23) & 0xff;
177 }
178
179 static ALWAYS_INLINE int32_t
_significand32(int32_t ix)180 _significand32(int32_t ix)
181 {
182 return ix & 0x7fffff;
183 }
184
185 static ALWAYS_INLINE float
_asfloat(int32_t i)186 _asfloat(int32_t i)
187 {
188 return asfloat((uint32_t) i);
189 }
190
191 static ALWAYS_INLINE uint64_t
asuint64(double f)192 asuint64 (double f)
193 {
194 #if defined(__riscv_flen) && __riscv_flen >= 64 && __riscv_xlen >= 64
195 uint64_t result;
196 __asm__("fmv.x.d\t%0, %1" : "=r" (result) : "f" (f));
197 return result;
198 #else
199 union
200 {
201 double f;
202 uint64_t i;
203 } u = {f};
204 return u.i;
205 #endif
206 }
207
208 static ALWAYS_INLINE double
asdouble(uint64_t i)209 asdouble (uint64_t i)
210 {
211 #if defined(__riscv_flen) && __riscv_flen >= 64 && __riscv_xlen >= 64
212 double result;
213 __asm__("fmv.d.x\t%0, %1" : "=f" (result) : "r" (i));
214 return result;
215 #else
216 union
217 {
218 uint64_t i;
219 double f;
220 } u = {i};
221 return u.f;
222 #endif
223 }
224
225 static ALWAYS_INLINE int64_t
_asint64(double f)226 _asint64(double f)
227 {
228 return (int64_t) asuint64(f);
229 }
230
231 static ALWAYS_INLINE int
_sign64(int64_t ix)232 _sign64(int64_t ix)
233 {
234 return ((uint64_t) ix) >> 63;
235 }
236
237 static ALWAYS_INLINE int
_exponent64(int64_t ix)238 _exponent64(int64_t ix)
239 {
240 return (ix >> 52) & 0x7ff;
241 }
242
243 static ALWAYS_INLINE int64_t
_significand64(int64_t ix)244 _significand64(int64_t ix)
245 {
246 return ix & 0xfffffffffffffLL;
247 }
248
249 static ALWAYS_INLINE double
_asdouble(int64_t i)250 _asdouble(int64_t i)
251 {
252 return asdouble((uint64_t) i);
253 }
254
255 #ifndef IEEE_754_2008_SNAN
256 # define IEEE_754_2008_SNAN 1
257 #endif
258 static ALWAYS_INLINE int
issignalingf_inline(float x)259 issignalingf_inline (float x)
260 {
261 uint32_t ix = asuint (x);
262 if (!IEEE_754_2008_SNAN)
263 return (ix & 0x7fc00000) == 0x7fc00000;
264 return 2 * (ix ^ 0x00400000) > 0xFF800000u;
265 }
266
267 static ALWAYS_INLINE int
issignaling_inline(double x)268 issignaling_inline (double x)
269 {
270 uint64_t ix = asuint64 (x);
271 if (!IEEE_754_2008_SNAN)
272 return (ix & 0x7ff8000000000000) == 0x7ff8000000000000;
273 return 2 * (ix ^ 0x0008000000000000) > 2 * 0x7ff8000000000000ULL;
274 }
275
276 #ifdef PICOLIBC_FLOAT_NOEXCEPT
277 #define FORCE_FLOAT float
278 #define pick_float_except(expr,val) (val)
279 #else
280 #define FORCE_FLOAT volatile float
281 #define pick_float_except(expr,val) (expr)
282 #endif
283
284 #ifdef PICOLIBC_DOUBLE_NOEXCEPT
285 #define FORCE_DOUBLE double
286 #define pick_double_except(expr,val) (val)
287 #else
288 #define FORCE_DOUBLE volatile double
289 #define pick_double_except(expr,val) (expr)
290 #endif
291
292 #ifdef PICOLIBC_LONG_DOUBLE_NOEXCEPT
293 #define FORCE_LONG_DOUBLE long double
294 #define pick_long_double_except(expr,val) (val)
295 #else
296 #define FORCE_LONG_DOUBLE volatile long double
297 #define pick_long_double_except(expr,val) (expr)
298 #endif
299
300 static ALWAYS_INLINE float
opt_barrier_float(float x)301 opt_barrier_float (float x)
302 {
303 FORCE_FLOAT y = x;
304 return y;
305 }
306
307 static ALWAYS_INLINE double
opt_barrier_double(double x)308 opt_barrier_double (double x)
309 {
310 FORCE_DOUBLE y = x;
311 return y;
312 }
313
314 static ALWAYS_INLINE void
force_eval_float(float x)315 force_eval_float (float x)
316 {
317 FORCE_FLOAT y = x;
318 (void) y;
319 }
320
321 static ALWAYS_INLINE void
force_eval_double(double x)322 force_eval_double (double x)
323 {
324 FORCE_DOUBLE y = x;
325 (void) y;
326 }
327
328 #ifdef _HAVE_LONG_DOUBLE
329 static ALWAYS_INLINE void
force_eval_long_double(long double x)330 force_eval_long_double (long double x)
331 {
332 FORCE_LONG_DOUBLE y = x;
333 (void) y;
334 }
335 #endif
336
337 /* Clang doesn't appear to suppor precise exceptions on
338 * many targets. We introduce barriers for that compiler
339 * to force evaluation order where needed
340 */
341 #ifdef __clang__
342 #define clang_barrier_double(x) opt_barrier_double(x)
343 #define clang_barrier_float(x) opt_barrier_float(x)
344 #define clang_force_double(x) force_eval_double(x)
345 #define clang_force_float(x) force_eval_float(x)
346 #else
347 #define clang_barrier_double(x) (x)
348 #define clang_barrier_float(x) (x)
349 #define clang_force_double(x) (x)
350 #define clang_force_float(x) (x)
351 #endif
352
353 #ifdef _ADD_UNDER_R_TO_FUNCS
354
355 #define __FLOAT_NAME(x) x ## f_r
356 #define _FLOAT_NAME(x) __FLOAT_NAME(x)
357 #define _FLOAT_ALIAS(x) # x "f_r"
358
359 #define __LD_NAME(x) x ## l_r
360 #define _LD_NAME(x) __LD_NAME(x)
361 #define _LD_ALIAS(x) # x "l_r"
362
363 #else
364
365 #define __FLOAT_NAME(x) x ## f
366 #define _FLOAT_NAME(x) __FLOAT_NAME(x)
367 #define _FLOAT_ALIAS(x) # x "f"
368
369 #define __LD_NAME(x) x ## l
370 #define _LD_NAME(x) __LD_NAME(x)
371 #define _LD_ALIAS(x) # x "l"
372
373 #endif
374
375 #define __FLOAT_NAME_REG(x) x ## f
376 #define _FLOAT_NAME_REG(x) __FLOAT_NAME_REG(x)
377
378 #define __LD_NAME_REG(x) x ## l
379 #define _LD_NAME_REG(x) __LD_NAME_REG(x)
380
381 #ifdef _ADD_D_TO_DOUBLE_FUNCS
382
383 #define __D_NAME(x) x ## d
384 #define _D_NAME(x) __D_NAME(x)
385 #define _D_ALIAS(x) # x "d"
386
387 #elif defined(_ADD_UNDER_R_TO_FUNCS)
388
389 #define __D_NAME(x) x ## _r
390 #define _D_NAME(x) __D_NAME(x)
391 #define _D_ALIAS(x) # x "_r"
392
393 #else
394
395 #define __D_NAME(x) x
396 #define _D_NAME(x) __D_NAME(x)
397 #define _D_ALIAS(x) # x
398
399 #endif
400
401 #define __D_NAME_REG(x) x
402 #define _D_NAME_REG(x) __D_NAME_REG(x)
403
404 /*
405 * Figure out how to map the 32- and 64- bit functions to
406 * the three C float types (float, double, long double).
407 *
408 * 'float' is assumed to be a 32-bit IEEE value.
409 *
410 * Internal names for 64-bit funcs are unqualified,
411 * Internal names for 32-bit funcs have a trailing 'f'
412 * Internal names for longer funcs have a trailing 'l'
413 *
414 * When types are the same size, they are assumed to have the same
415 * representation. Aliases are generated in this case to eliminate
416 * overhead.
417 *
418 * 32-bit functions are always 'float'
419 * 64-bit functions may either be 'double' or 'long double',
420 * if at least one of those is 64 bits in size
421 *
422 * There is limited support for long double greater than 64 bits
423 */
424
425 #ifdef __GNUC__
426 #pragma GCC diagnostic ignored "-Wpragmas"
427 #pragma GCC diagnostic ignored "-Wunknown-warning-option"
428 #pragma GCC diagnostic ignored "-Wattribute-alias="
429 #pragma GCC diagnostic ignored "-Wmissing-attributes"
430 #endif
431
432 #ifdef _DOUBLE_IS_32BITS
433 # ifdef _HAVE_ALIAS_ATTRIBUTE
434 # define _MATH_ALIAS_d_to_f(name) extern double _D_NAME(name)(void) __attribute__((__alias__(_FLOAT_ALIAS(name))));
435 # define _MATH_ALIAS_d_d_to_f(name) extern double _D_NAME(name)(double x) __attribute__((__alias__(_FLOAT_ALIAS(name))));
436 # define _MATH_ALIAS_d_D_to_f(name) extern double _D_NAME(name)(const double *x) __attribute__((__alias__(_FLOAT_ALIAS(name))));
437 # define _MATH_ALIAS_d_s_to_f(name) extern double _D_NAME(name)(const char *x) __attribute__((__alias__(_FLOAT_ALIAS(name))));
438 # define _MATH_ALIAS_d_dd_to_f(name) extern double _D_NAME(name)(double x, double y) __attribute__((__alias__(_FLOAT_ALIAS(name))));
439 # define _MATH_ALIAS_d_dl_to_f(name) extern double _D_NAME(name)(double x, long double y) __attribute__((__alias__(_FLOAT_ALIAS(name))));
440 # define _MATH_ALIAS_d_dD_to_f(name) extern double _D_NAME(name)(double x, double *y) __attribute__((__alias__(_FLOAT_ALIAS(name))));
441 # define _MATH_ALIAS_d_ddd_to_f(name) extern double _D_NAME(name)(double x, double y, double z) __attribute__((__alias__(_FLOAT_ALIAS(name))));
442 # define _MATH_ALIAS_d_dI_to_f(name) extern double _D_NAME(name)(double x, int *y) __attribute__((__alias__(_FLOAT_ALIAS(name))));
443 # define _MATH_ALIAS_d_ddI_to_f(name) extern double _D_NAME(name)(double x, double y, int *z) __attribute__((__alias__(_FLOAT_ALIAS(name))));
444 # define _MATH_ALIAS_d_id_to_f(name) extern double _D_NAME(name)(int n, double x) __attribute__((__alias__(_FLOAT_ALIAS(name))));
445 # define _MATH_ALIAS_d_di_to_f(name) extern double _D_NAME(name)(double x, int n) __attribute__((__alias__(_FLOAT_ALIAS(name))));
446 # define _MATH_ALIAS_d_dj_to_f(name) extern double _D_NAME(name)(double x, long n) __attribute__((__alias__(_FLOAT_ALIAS(name))));
447 # define _MATH_ALIAS_i_d_to_f(name) extern int name(double x) __attribute__((__alias__(_FLOAT_ALIAS(name))));
448 # define _MATH_ALIAS_j_d_to_f(name) extern long name(double x) __attribute__((__alias__(_FLOAT_ALIAS(name))));
449 # define _MATH_ALIAS_k_d_to_f(name) extern long long name(double x) __attribute__((__alias__(_FLOAT_ALIAS(name))));
450 # define _MATH_ALIAS_i_dd_to_f(name) extern int name(double x, double y) __attribute__((__alias__(_FLOAT_ALIAS(name))));
451 # define _MATH_ALIAS_v_dDD_to_f(name) extern void name(double x, double *y, double *z) __attribute__((__alias__(_FLOAT_ALIAS(name))));
452 # else
453 # define _MATH_ALIAS_d_to_f(name) double _D_NAME(name)(void) { return (double) __FLOAT_NAME(name)(); }
454 # define _MATH_ALIAS_d_d_to_f(name) double _D_NAME(name)(double x) { return (double) __FLOAT_NAME(name)((float) x); }
455 # define _MATH_ALIAS_d_D_to_f(name) double _D_NAME(name)(const double *x) { return (double) __FLOAT_NAME(name)((float *) x); }
456 # define _MATH_ALIAS_d_s_to_f(name) double _D_NAME(name)(const char *x) { return (double) __FLOAT_NAME(name)(x); }
457 # define _MATH_ALIAS_d_dd_to_f(name) double _D_NAME(name)(double x, double y) { return (double) __FLOAT_NAME(name)((float) x, (float) y); }
458 # define _MATH_ALIAS_d_dl_to_f(name) double _D_NAME(name)(double x, long double y) { return (double) __FLOAT_NAME(name)((float) x, y); }
459 # define _MATH_ALIAS_d_dD_to_f(name) double _D_NAME(name)(double x, double *y) { return (double) __FLOAT_NAME(name)((float) x, (float *) y); }
460 # define _MATH_ALIAS_d_ddd_to_f(name) double _D_NAME(name)(double x, double y, double z) { return (double) __FLOAT_NAME(name)((float) x, (float) y, (float) z); }
461 # define _MATH_ALIAS_d_dI_to_f(name) double _D_NAME(name)(double x, int *y) { return (double) __FLOAT_NAME(name)((float) x, y); }
462 # define _MATH_ALIAS_d_ddI_to_f(name) double _D_NAME(name)(double x, double y, int *z) { return (double) __FLOAT_NAME(name)((float) x, (float) y, z); }
463 # define _MATH_ALIAS_d_id_to_f(name) double _D_NAME(name)(int n, double x) { return (double) __FLOAT_NAME(name)(n, (float) x); }
464 # define _MATH_ALIAS_d_di_to_f(name) double _D_NAME(name)(double x, int n) { return (double) __FLOAT_NAME(name)((float) x, n); }
465 # define _MATH_ALIAS_d_dj_to_f(name) double _D_NAME(name)(double x, long n) { return (double) __FLOAT_NAME(name)((float) x, n); }
466 # define _MATH_ALIAS_i_d_to_f(name) int _D_NAME(name)(double x) { return __FLOAT_NAME(name)((float) x); }
467 # define _MATH_ALIAS_j_d_to_f(name) long _D_NAME(name)(double x) { return __FLOAT_NAME(name)((float) x); }
468 # define _MATH_ALIAS_k_d_to_f(name) long long _D_NAME(name)(double x) { return __FLOAT_NAME(name)((float) x); }
469 # define _MATH_ALIAS_i_dd_to_f(name) int _D_NAME(name)(double x, double y) { return __FLOAT_NAME(name)((float) x, (float) y); }
470 # define _MATH_ALIAS_v_dDD_to_f(name) void _D_NAME(name)(double x, double *y, double *z) { return __FLOAT_NAME(name)((float) x, (float *) y, (float *) z); }
471 # endif
472 #else
473 # define _MATH_ALIAS_d_to_f(name)
474 # define _MATH_ALIAS_d_d_to_f(name)
475 # define _MATH_ALIAS_d_D_to_f(name)
476 # define _MATH_ALIAS_d_s_to_f(name)
477 # define _MATH_ALIAS_d_dd_to_f(name)
478 # define _MATH_ALIAS_d_dl_to_f(name)
479 # define _MATH_ALIAS_d_dD_to_f(name)
480 # define _MATH_ALIAS_d_ddd_to_f(name)
481 # define _MATH_ALIAS_d_dI_to_f(name)
482 # define _MATH_ALIAS_d_ddI_to_f(name)
483 # define _MATH_ALIAS_d_id_to_f(name)
484 # define _MATH_ALIAS_d_di_to_f(name)
485 # define _MATH_ALIAS_d_dj_to_f(name)
486 # define _MATH_ALIAS_i_d_to_f(name)
487 # define _MATH_ALIAS_j_d_to_f(name)
488 # define _MATH_ALIAS_k_d_to_f(name)
489 # define _MATH_ALIAS_i_dd_to_f(name)
490 # define _MATH_ALIAS_v_dDD_to_f(name)
491 # define _NEED_FLOAT64
492 #endif
493
494 #ifdef _LDBL_EQ_DBL
495 # ifdef _DOUBLE_IS_32BITS
496 # ifdef _HAVE_ALIAS_ATTRIBUTE
497 # define _MATH_ALIAS_l_to_f(name) extern long double _LD_NAME(name)(void) __attribute__((__alias__(_FLOAT_ALIAS(name))));
498 # define _MATH_ALIAS_l_l_to_f(name) extern long double _LD_NAME(name)(long double x) __attribute__((__alias__(_FLOAT_ALIAS(name))));
499 # define _MATH_ALIAS_l_L_to_f(name) extern long double _LD_NAME(name)(const long double *x) __attribute__((__alias__(_FLOAT_ALIAS(name))));
500 # define _MATH_ALIAS_l_s_to_f(name) extern long double _LD_NAME(name)(const char *x) __attribute__((__alias__(_FLOAT_ALIAS(name))));
501 # define _MATH_ALIAS_l_ll_to_f(name) extern long double _LD_NAME(name)(long double x, long double y) __attribute__((__alias__(_FLOAT_ALIAS(name))));
502 # define _MATH_ALIAS_l_lL_to_f(name) extern long double _LD_NAME(name)(long double x, long double *y) __attribute__((__alias__(_FLOAT_ALIAS(name))));
503 # define _MATH_ALIAS_l_lll_to_f(name) extern long double _LD_NAME(name)(long double x, long double y, long double z) __attribute__((__alias__(_FLOAT_ALIAS(name))));
504 # define _MATH_ALIAS_l_lI_to_f(name) extern long double _LD_NAME(name)(long double x, int *y) __attribute__((__alias__(_FLOAT_ALIAS(name))));
505 # define _MATH_ALIAS_l_llI_to_f(name) extern long double _LD_NAME(name)(long double x, long double y, int *z) __attribute__((__alias__(_FLOAT_ALIAS(name))));
506 # define _MATH_ALIAS_l_il_to_f(name) extern long double _LD_NAME(name)(int n, long double x) __attribute__((__alias__(_FLOAT_ALIAS(name))));
507 # define _MATH_ALIAS_l_li_to_f(name) extern long double _LD_NAME(name)(long double x, int n) __attribute__((__alias__(_FLOAT_ALIAS(name))));
508 # define _MATH_ALIAS_l_lj_to_f(name) extern long double _LD_NAME(name)(long double x, long n) __attribute__((__alias__(_FLOAT_ALIAS(name))));
509 # define _MATH_ALIAS_i_l_to_f(name) extern int _LD_NAME(name)(long double x) __attribute__((__alias__(_FLOAT_ALIAS(name))));
510 # define _MATH_ALIAS_j_l_to_f(name) extern long _LD_NAME(name)(long double x) __attribute__((__alias__(_FLOAT_ALIAS(name))));
511 # define _MATH_ALIAS_k_l_to_f(name) extern long long _LD_NAME(name)(long double x) __attribute__((__alias__(_FLOAT_ALIAS(name))));
512 # define _MATH_ALIAS_i_ll_to_f(name) extern int _LD_NAME(name)(long double x, long double y) __attribute__((__alias__(_FLOAT_ALIAS(name))));
513 # define _MATH_ALIAS_v_lLL_to_f(name) extern void _LD_NAME(name)(long double x, long double *y, long double *z) __attribute__((__alias__(_FLOAT_ALIAS(name))));
514 # else
515 # define _MATH_ALIAS_l_to_f(name) long double _LD_NAME(name)(void) { return (long double) _FLOAT_NAME(name)(); }
516 # define _MATH_ALIAS_l_l_to_f(name) long double _LD_NAME(name)(long double x) { return (long double) _FLOAT_NAME(name)((float) x); }
517 # define _MATH_ALIAS_l_L_to_f(name) long double _LD_NAME(name)(const long double *x) { return (long double) _FLOAT_NAME(name)((float *) x); }
518 # define _MATH_ALIAS_l_s_to_f(name) long double _LD_NAME(name)(const char *x) { return (long double) _FLOAT_NAME(name)(x); }
519 # define _MATH_ALIAS_l_ll_to_f(name) long double _LD_NAME(name)(long double x, long double y) { return (long double) _FLOAT_NAME(name)((float) x, (float) y); }
520 # define _MATH_ALIAS_l_lL_to_f(name) long double _LD_NAME(name)(long double x, long double *y) { return (long double) _FLOAT_NAME(name)((float) x, (float *) y); }
521 # define _MATH_ALIAS_l_lll_to_f(name) long double _LD_NAME(name)(long double x, long double y, long double z) { return (long double) _FLOAT_NAME(name)((float) x, (float) y, (float) z); }
522 # define _MATH_ALIAS_l_lI_to_f(name) long double _LD_NAME(name)(long double x, int *y) { return (long double) _FLOAT_NAME(name)((float) x, y); }
523 # define _MATH_ALIAS_l_llI_to_f(name) long double _LD_NAME(name)(long double x, long double y, int *z) { return (long double) _FLOAT_NAME(name)((float) x, (float) y, z); }
524 # define _MATH_ALIAS_l_il_to_f(name) long double _LD_NAME(name)(int n, long double x) { return (long double) _FLOAT_NAME(name)(n, (float) x); }
525 # define _MATH_ALIAS_l_li_to_f(name) long double _LD_NAME(name)(long double x, int n) { return (long double) _FLOAT_NAME(name)((float) x, n); }
526 # define _MATH_ALIAS_l_lj_to_f(name) long double _LD_NAME(name)(long double x, long n) { return (long double) _FLOAT_NAME(name)((float) x, n); }
527 # define _MATH_ALIAS_i_l_to_f(name) int _LD_NAME(name)(long double x) { return _FLOAT_NAME(name)((float) x); }
528 # define _MATH_ALIAS_j_l_to_f(name) long _LD_NAME(name)(long double x) { return _FLOAT_NAME(name)((float) x); }
529 # define _MATH_ALIAS_k_l_to_f(name) long long _LD_NAME(name)(long double x) { return _FLOAT_NAME(name)((float) x); }
530 # define _MATH_ALIAS_i_ll_to_f(name) int _LD_NAME(name)(long double x, long double y) { return _FLOAT_NAME(name)((float) x, (float) y); }
531 # define _MATH_ALIAS_v_lLL_to_f(name) void _LD_NAME(name)(long double x, long double *y, long double *z) { return _FLOAT_NAME(name)((float) x, (float *) y, (float *) z); }
532 # endif
533 # define _MATH_ALIAS_l_to_d(name)
534 # define _MATH_ALIAS_l_l_to_d(name)
535 # define _MATH_ALIAS_l_L_to_d(name)
536 # define _MATH_ALIAS_l_s_to_d(name)
537 # define _MATH_ALIAS_l_ll_to_d(name)
538 # define _MATH_ALIAS_l_lL_to_d(name)
539 # define _MATH_ALIAS_l_lll_to_d(name)
540 # define _MATH_ALIAS_l_lI_to_d(name)
541 # define _MATH_ALIAS_l_llI_to_d(name)
542 # define _MATH_ALIAS_l_il_to_d(name)
543 # define _MATH_ALIAS_l_li_to_d(name)
544 # define _MATH_ALIAS_l_lj_to_d(name)
545 # define _MATH_ALIAS_i_l_to_d(name)
546 # define _MATH_ALIAS_j_l_to_d(name)
547 # define _MATH_ALIAS_k_l_to_d(name)
548 # define _MATH_ALIAS_i_ll_to_d(name)
549 # else
550 # define _MATH_ALIAS_l_to_f(name)
551 # define _MATH_ALIAS_l_l_to_f(name)
552 # define _MATH_ALIAS_l_L_to_f(name)
553 # define _MATH_ALIAS_l_s_to_f(name)
554 # define _MATH_ALIAS_l_ll_to_f(name)
555 # define _MATH_ALIAS_l_lL_to_f(name)
556 # define _MATH_ALIAS_l_lll_to_f(name)
557 # define _MATH_ALIAS_l_lI_to_f(name)
558 # define _MATH_ALIAS_l_llI_to_f(name)
559 # define _MATH_ALIAS_l_il_to_f(name)
560 # define _MATH_ALIAS_l_li_to_f(name)
561 # define _MATH_ALIAS_l_lj_to_f(name)
562 # define _MATH_ALIAS_i_l_to_f(name)
563 # define _MATH_ALIAS_j_l_to_f(name)
564 # define _MATH_ALIAS_k_l_to_f(name)
565 # define _MATH_ALIAS_i_ll_to_f(name)
566 # define _MATH_ALIAS_v_lLL_to_f(name)
567 # ifdef _HAVE_ALIAS_ATTRIBUTE
568 # define _MATH_ALIAS_l_to_d(name) extern long double _LD_NAME(name)(void) __attribute__((__alias__(_D_ALIAS(name))));
569 # define _MATH_ALIAS_l_l_to_d(name) extern long double _LD_NAME(name)(long double x) __attribute__((__alias__(_D_ALIAS(name))));
570 # define _MATH_ALIAS_l_L_to_d(name) extern long double _LD_NAME(name)(const long double *x) __attribute__((__alias__(_D_ALIAS(name))));
571 # define _MATH_ALIAS_l_s_to_d(name) extern long double _LD_NAME(name)(const char *x) __attribute__((__alias__(_D_ALIAS(name))));
572 # define _MATH_ALIAS_l_ll_to_d(name) extern long double _LD_NAME(name)(long double x, long double y) __attribute__((__alias__(_D_ALIAS(name))));
573 # define _MATH_ALIAS_l_lL_to_d(name) extern long double _LD_NAME(name)(long double x, long double *y) __attribute__((__alias__(_D_ALIAS(name))));
574 # define _MATH_ALIAS_l_lll_to_d(name) extern long double _LD_NAME(name)(long double x, long double y, long double z) __attribute__((__alias__(_D_ALIAS(name))));
575 # define _MATH_ALIAS_l_lI_to_d(name) extern long double _LD_NAME(name)(long double x, int *y) __attribute__((__alias__(_D_ALIAS(name))));
576 # define _MATH_ALIAS_l_llI_to_d(name) extern long double _LD_NAME(name)(long double x, long double y, int *z) __attribute__((__alias__(_D_ALIAS(name))));
577 # define _MATH_ALIAS_l_il_to_d(name) extern long double _LD_NAME(name)(int n, long double x) __attribute__((__alias__(_D_ALIAS(name))));
578 # define _MATH_ALIAS_l_li_to_d(name) extern long double _LD_NAME(name)(long double x, int n) __attribute__((__alias__(_D_ALIAS(name))));
579 # define _MATH_ALIAS_l_lj_to_d(name) extern long double _LD_NAME(name)(long double x, long n) __attribute__((__alias__(_D_ALIAS(name))));
580 # define _MATH_ALIAS_i_l_to_d(name) extern int _LD_NAME(name)(long double x) __attribute__((__alias__(_D_ALIAS(name))));
581 # define _MATH_ALIAS_j_l_to_d(name) extern long _LD_NAME(name)(long double x) __attribute__((__alias__(_D_ALIAS(name))));
582 # define _MATH_ALIAS_k_l_to_d(name) extern long long _LD_NAME(name)(long double x) __attribute__((__alias__(_D_ALIAS(name))));
583 # define _MATH_ALIAS_i_ll_to_d(name) extern int _LD_NAME(name)(long double x, long double y) __attribute__((__alias__(_D_ALIAS(name))));
584 # define _MATH_ALIAS_v_lLL_to_d(name) extern void _LD_NAME(name)(long double x, long double *y, long double *z) __attribute__((__alias__(_D_ALIAS(name))));
585 # else
586 # define _MATH_ALIAS_l_to_d(name) long double _LD_NAME(name)(void) { return (long double) _D_NAME(name)(); }
587 # define _MATH_ALIAS_l_l_to_d(name) long double _LD_NAME(name)(long double x) { return (long double) _D_NAME(name)((double) x); }
588 # define _MATH_ALIAS_l_L_to_d(name) long double _LD_NAME(name)(const long double *x) { return (long double) _D_NAME(name)((double *) x); }
589 # define _MATH_ALIAS_l_s_to_d(name) long double _LD_NAME(name)(const char *x) { return (long double) _D_NAME(name)(x); }
590 # define _MATH_ALIAS_l_ll_to_d(name) long double _LD_NAME(name)(long double x, long double y) { return (long double) _D_NAME(name)((double) x, (double) y); }
591 # define _MATH_ALIAS_l_lL_to_d(name) long double _LD_NAME(name)(long double x, long double *y) { return (long double) _D_NAME(name)((double) x, (double *) y); }
592 # define _MATH_ALIAS_l_lll_to_d(name) long double _LD_NAME(name)(long double x, long double y, long double z) { return (long double) _D_NAME(name)((double) x, (double) y, (double) z); }
593 # define _MATH_ALIAS_l_lI_to_d(name) long double _LD_NAME(name)(long double x, int *y) { return (long double) _D_NAME(name)((double) x, y); }
594 # define _MATH_ALIAS_l_llI_to_d(name) long double _LD_NAME(name)(long double x, long double y, int *z) { return (long double) _D_NAME(name)((double) x, (double) y, z); }
595 # define _MATH_ALIAS_l_il_to_d(name) long double _LD_NAME(name)(int n, long double x) { return (long double) _D_NAME(name)(n, (double) x); }
596 # define _MATH_ALIAS_l_li_to_d(name) long double _LD_NAME(name)(long double x, int n) { return (long double) _D_NAME(name)((double) x, n); }
597 # define _MATH_ALIAS_l_lj_to_d(name) long double _LD_NAME(name)(long double x, long j) { return (long double) _D_NAME(name)((double) x, j); }
598 # define _MATH_ALIAS_i_l_to_d(name) int _LD_NAME(name)(long double x) { return _D_NAME(name)((double) x); }
599 # define _MATH_ALIAS_j_l_to_d(name) long _LD_NAME(name)(long double x) { return _D_NAME(name)((double) x); }
600 # define _MATH_ALIAS_k_l_to_d(name) long long _LD_NAME(name)(long double x) { return _D_NAME(name)((double) x); }
601 # define _MATH_ALIAS_i_ll_to_d(name) int _LD_NAME(name)(long double x, long double y) { return _D_NAME(name)((double) x, (double) y); }
602 # define _MATH_ALIAS_v_lLL_to_d(name) void _LD_NAME(name)(long double x, long double *y, long double *z) { return _D_NAME(name)((double) x, (double *) y, (double *) z); }
603 # endif
604 # endif
605 #else
606 # if __SIZEOF_LONG_DOUBLE__ == 8
607 # define _NAME_64(x) _LD_NAME_REG(x)
608 # define _NAME_64_SPECIAL(d,l) l
609 typedef long double __float64;
610 # define FORCE_FLOAT64 FORCE_LONG_DOUBLE
611 # define pick_float64_except(a,b) pick_long_double_except(a,b)
612 # define _NEED_FLOAT64
613 # define __F_64(x) x ## L
614 # define _F_64(x) __F_64(x)
615 # define _FLOAT64_MIN LDBL_MIN
616 # define _FLOAT64_MAX LDBL_MAX
617 # define force_eval_float64 force_eval_long_double
618 # endif
619 # define _MATH_ALIAS_l_to_f(name)
620 # define _MATH_ALIAS_l_l_to_f(name)
621 # define _MATH_ALIAS_l_L_to_f(name)
622 # define _MATH_ALIAS_l_s_to_f(name)
623 # define _MATH_ALIAS_l_ll_to_f(name)
624 # define _MATH_ALIAS_l_lL_to_f(name)
625 # define _MATH_ALIAS_l_lll_to_f(name)
626 # define _MATH_ALIAS_l_lI_to_f(name)
627 # define _MATH_ALIAS_l_llI_to_f(name)
628 # define _MATH_ALIAS_l_il_to_f(name)
629 # define _MATH_ALIAS_l_li_to_f(name)
630 # define _MATH_ALIAS_l_lj_to_f(name)
631 # define _MATH_ALIAS_i_l_to_f(name)
632 # define _MATH_ALIAS_j_l_to_f(name)
633 # define _MATH_ALIAS_k_l_to_f(name)
634 # define _MATH_ALIAS_i_ll_to_f(name)
635 # define _MATH_ALIAS_v_lLL_to_f(name)
636 # define _MATH_ALIAS_l_to_d(name)
637 # define _MATH_ALIAS_l_l_to_d(name)
638 # define _MATH_ALIAS_l_L_to_d(name)
639 # define _MATH_ALIAS_l_s_to_d(name)
640 # define _MATH_ALIAS_l_ll_to_d(name)
641 # define _MATH_ALIAS_l_lL_to_d(name)
642 # define _MATH_ALIAS_l_lll_to_d(name)
643 # define _MATH_ALIAS_l_lI_to_d(name)
644 # define _MATH_ALIAS_l_llI_to_d(name)
645 # define _MATH_ALIAS_l_il_to_d(name)
646 # define _MATH_ALIAS_l_li_to_d(name)
647 # define _MATH_ALIAS_l_lj_to_d(name)
648 # define _MATH_ALIAS_i_l_to_d(name)
649 # define _MATH_ALIAS_j_l_to_d(name)
650 # define _MATH_ALIAS_k_l_to_d(name)
651 # define _MATH_ALIAS_i_ll_to_d(name)
652 # define _MATH_ALIAS_v_lLL_to_d(name)
653 #endif
654
655 #ifndef _NAME_64
656 # define _NAME_64(x) _D_NAME_REG(x)
657 # define _NAME_64_SPECIAL(d,l) d
658 # define _F_64(x) x
659 # define _FLOAT64_MIN DBL_MIN
660 # define _FLOAT64_MAX DBL_MAX
661 typedef double __float64;
662 # define FORCE_FLOAT64 FORCE_DOUBLE
663 # define pick_float64_except(a,b) pick_double_except(a,b)
664 # define force_eval_float64 force_eval_double
665 #endif
666
667 #if __SIZEOF_LONG_DOUBLE__ > 8
668 # define _NEED_FLOAT_HUGE
669 /* Guess long double layout based on compiler defines */
670
671 #if __LDBL_MANT_DIG__ == 64 && 16383 <= __LDBL_MAX_EXP__ && __LDBL_MAX_EXP__ <= 16384
672 #define _INTEL80_FLOAT
673 #ifdef __LP64__
674 #define _INTEL80_FLOAT_PAD
675 #endif
676 #endif
677
678 #if __LDBL_MANT_DIG__ == 113 && 16383 <= __LDBL_MAX_EXP__ && __LDBL_MAX_EXP__ <= 16384
679 #define _IEEE128_FLOAT
680 #endif
681
682 #if __LDBL_MANT_DIG__ == 106 && __LDBL_MAX_EXP__ == 1024
683 #define _DOUBLE_DOUBLE_FLOAT
684 #endif
685
686 #ifndef __FLOAT_WORD_ORDER__
687 #define __FLOAT_WORD_ORDER__ __BYTE_ORDER__
688 #endif
689
690 #endif
691
692 #define _MATH_ALIAS_f(name) \
693 _MATH_ALIAS_d_to_f(name) \
694 _MATH_ALIAS_l_to_f(name)
695
696 #define _MATH_ALIAS_f_f(name) \
697 _MATH_ALIAS_d_d_to_f(name) \
698 _MATH_ALIAS_l_l_to_f(name)
699
700 #define _MATH_ALIAS_f_F(name) \
701 _MATH_ALIAS_d_D_to_f(name) \
702 _MATH_ALIAS_l_L_to_f(name)
703
704 #define _MATH_ALIAS_f_s(name) \
705 _MATH_ALIAS_d_s_to_f(name) \
706 _MATH_ALIAS_l_s_to_f(name)
707
708 #define _MATH_ALIAS_f_ff(name) \
709 _MATH_ALIAS_d_dd_to_f(name) \
710 _MATH_ALIAS_l_ll_to_f(name)
711
712 #define _MATH_ALIAS_f_fl(name) \
713 _MATH_ALIAS_d_dl_to_f(name) \
714 _MATH_ALIAS_l_ll_to_f(name)
715
716 #define _MATH_ALIAS_f_fF(name) \
717 _MATH_ALIAS_d_dD_to_f(name) \
718 _MATH_ALIAS_l_lL_to_f(name)
719
720 #define _MATH_ALIAS_f_fff(name) \
721 _MATH_ALIAS_d_ddd_to_f(name) \
722 _MATH_ALIAS_l_lll_to_f(name)
723
724 #define _MATH_ALIAS_f_fI(name) \
725 _MATH_ALIAS_d_dI_to_f(name) \
726 _MATH_ALIAS_l_lI_to_f(name)
727
728 #define _MATH_ALIAS_f_ffI(name) \
729 _MATH_ALIAS_d_ddI_to_f(name) \
730 _MATH_ALIAS_l_llI_to_f(name)
731
732 #define _MATH_ALIAS_f_if(name) \
733 _MATH_ALIAS_d_id_to_f(name) \
734 _MATH_ALIAS_l_il_to_f(name)
735
736 #define _MATH_ALIAS_f_fi(name) \
737 _MATH_ALIAS_d_di_to_f(name) \
738 _MATH_ALIAS_l_li_to_f(name)
739
740 #define _MATH_ALIAS_f_fj(name) \
741 _MATH_ALIAS_d_dj_to_f(name) \
742 _MATH_ALIAS_l_lj_to_f(name)
743
744 #define _MATH_ALIAS_i_f(name) \
745 _MATH_ALIAS_i_d_to_f(name) \
746 _MATH_ALIAS_i_l_to_f(name)
747
748 #define _MATH_ALIAS_j_f(name) \
749 _MATH_ALIAS_j_d_to_f(name) \
750 _MATH_ALIAS_j_l_to_f(name)
751
752 #define _MATH_ALIAS_k_f(name) \
753 _MATH_ALIAS_k_d_to_f(name) \
754 _MATH_ALIAS_k_l_to_f(name)
755
756 #define _MATH_ALIAS_i_ff(name) \
757 _MATH_ALIAS_i_dd_to_f(name) \
758 _MATH_ALIAS_i_ll_to_f(name)
759
760 #define _MATH_ALIAS_v_fFF(name) \
761 _MATH_ALIAS_v_dDD_to_f(name) \
762 _MATH_ALIAS_v_lLL_to_f(name)
763
764 #define _MATH_ALIAS_d(name) \
765 _MATH_ALIAS_l_to_d(name)
766
767 #define _MATH_ALIAS_d_d(name) \
768 _MATH_ALIAS_l_l_to_d(name)
769
770 #define _MATH_ALIAS_d_D(name) \
771 _MATH_ALIAS_l_L_to_d(name)
772
773 #define _MATH_ALIAS_d_s(name) \
774 _MATH_ALIAS_l_s_to_d(name)
775
776 #define _MATH_ALIAS_d_dd(name) \
777 _MATH_ALIAS_l_ll_to_d(name)
778
779 #define _MATH_ALIAS_d_dl(name) \
780 _MATH_ALIAS_l_ll_to_d(name)
781
782 #define _MATH_ALIAS_d_dD(name) \
783 _MATH_ALIAS_l_lL_to_d(name)
784
785 #define _MATH_ALIAS_d_ddd(name) \
786 _MATH_ALIAS_l_lll_to_d(name)
787
788 #define _MATH_ALIAS_d_dI(name) \
789 _MATH_ALIAS_l_lI_to_d(name)
790
791 #define _MATH_ALIAS_d_ddI(name) \
792 _MATH_ALIAS_l_llI_to_d(name)
793
794 #define _MATH_ALIAS_d_id(name) \
795 _MATH_ALIAS_l_il_to_d(name)
796
797 #define _MATH_ALIAS_d_di(name) \
798 _MATH_ALIAS_l_li_to_d(name)
799
800 #define _MATH_ALIAS_d_dj(name) \
801 _MATH_ALIAS_l_lj_to_d(name)
802
803 #define _MATH_ALIAS_i_d(name) \
804 _MATH_ALIAS_i_l_to_d(name)
805
806 #define _MATH_ALIAS_j_d(name) \
807 _MATH_ALIAS_j_l_to_d(name)
808
809 #define _MATH_ALIAS_k_d(name) \
810 _MATH_ALIAS_k_l_to_d(name)
811
812 #define _MATH_ALIAS_i_dd(name) \
813 _MATH_ALIAS_i_ll_to_d(name)
814
815 #define _MATH_ALIAS_v_dDD(name) \
816 _MATH_ALIAS_v_lLL_to_d(name)
817
818 /* Evaluate an expression as the specified type, normally a type
819 cast should be enough, but compilers implement non-standard
820 excess-precision handling, so when FLT_EVAL_METHOD != 0 then
821 these functions may need to be customized. */
822 static ALWAYS_INLINE float
eval_as_float(float x)823 eval_as_float (float x)
824 {
825 return x;
826 }
827 static ALWAYS_INLINE double
eval_as_double(double x)828 eval_as_double (double x)
829 {
830 return x;
831 }
832
833 /* gcc emitting PE/COFF doesn't support visibility */
834 #if defined (__GNUC__) && !defined (__CYGWIN__)
835 # define HIDDEN __attribute__ ((__visibility__ ("hidden")))
836 #else
837 # define HIDDEN
838 #endif
839
840 /* Error handling tail calls for special cases, with a sign argument.
841 The sign of the return value is set if the argument is non-zero. */
842
843 /* The result overflows. */
844 HIDDEN float __math_oflowf (uint32_t);
845 /* The result underflows to 0 in nearest rounding mode. */
846 HIDDEN float __math_uflowf (uint32_t);
847 /* The result underflows to 0 in some directed rounding mode only. */
848 HIDDEN float __math_may_uflowf (uint32_t);
849 /* Division by zero. */
850 HIDDEN float __math_divzerof (uint32_t);
851 /* The result overflows. */
852 HIDDEN __float64 __math_oflow (uint32_t);
853 /* The result underflows to 0 in nearest rounding mode. */
854 HIDDEN __float64 __math_uflow (uint32_t);
855 /* The result underflows to 0 in some directed rounding mode only. */
856 HIDDEN __float64 __math_may_uflow (uint32_t);
857 /* Division by zero. */
858 HIDDEN __float64 __math_divzero (uint32_t);
859
860 /* Error handling using input checking. */
861
862 /* Invalid input unless it is a quiet NaN. */
863 HIDDEN float __math_invalidf (float);
864 /* set invalid exception */
865 #if defined(FE_INVALID) && !defined(PICOLIBC_FLOAT_NOEXECPT)
866 HIDDEN void __math_set_invalidf(void);
867 #else
868 #define __math_set_invalidf() ((void) 0)
869 #endif
870 /* Invalid input unless it is a quiet NaN. */
871 HIDDEN __float64 __math_invalid (__float64);
872 /* set invalid exception */
873 #if defined(FE_INVALID) && !defined(PICOLIBC_DOUBLE_NOEXECPT)
874 HIDDEN void __math_set_invalid(void);
875 #else
876 #define __math_set_invalid() ((void) 0)
877 #endif
878
879 #ifdef _HAVE_LONG_DOUBLE
880 HIDDEN long double __math_oflowl (uint32_t);
881 /* The result underflows to 0 in nearest rounding mode. */
882 HIDDEN long double __math_uflowl (uint32_t);
883 /* The result underflows to 0 in some directed rounding mode only. */
884 HIDDEN long double __math_may_uflowl (uint32_t);
885 /* Division by zero. */
886 HIDDEN long double __math_divzerol (uint32_t);
887 /* Invalid input unless it is a quiet NaN. */
888 HIDDEN long double __math_invalidl (long double);
889 /* set invalid exception */
890 #if defined(FE_INVALID) && !defined(PICOLIBC_LONG_DOUBLE_NOEXECPT)
891 HIDDEN void __math_set_invalidl(void);
892 #else
893 #define __math_set_invalidl() ((void) 0)
894 #endif
895 #endif
896
897 /* Error handling using output checking, only for errno setting. */
898
899 /* Check if the result overflowed to infinity. */
900 HIDDEN float __math_check_oflowf (float);
901 /* Check if the result overflowed to infinity. */
902 HIDDEN __float64 __math_check_oflow (__float64);
903 #ifdef _NEED_FLOAT_HUGE
904 HIDDEN long double __math_check_oflowl(long double);
905 #endif
906
907 /* Check if the result underflowed to 0. */
908 HIDDEN float __math_check_uflowf (float);
909 HIDDEN __float64 __math_check_uflow (__float64);
910 #ifdef _NEED_FLOAT_HUGE
911 HIDDEN long double __math_check_uflowl(long double);
912 #endif
913
914 /* Check if the result overflowed to infinity. */
915 static inline __float64
check_oflow(__float64 x)916 check_oflow (__float64 x)
917 {
918 return WANT_ERRNO ? __math_check_oflow (x) : x;
919 }
920
921 /* Check if the result overflowed to infinity. */
922 static inline float
check_oflowf(float x)923 check_oflowf (float x)
924 {
925 return WANT_ERRNO ? __math_check_oflowf (x) : x;
926 }
927
928 #ifdef _NEED_FLOAT_HUGE
929 static inline long double
check_oflowl(long double x)930 check_oflowl (long double x)
931 {
932 return WANT_ERRNO ? __math_check_oflowl (x) : x;
933 }
934 #endif
935
936 /* Check if the result underflowed to 0. */
937 static inline __float64
check_uflow(__float64 x)938 check_uflow (__float64 x)
939 {
940 return WANT_ERRNO ? __math_check_uflow (x) : x;
941 }
942
943 /* Check if the result underflowed to 0. */
944 static inline float
check_uflowf(float x)945 check_uflowf (float x)
946 {
947 return WANT_ERRNO ? __math_check_uflowf (x) : x;
948 }
949
950 #ifdef _NEED_FLOAT_HUGE
951 static inline long double
check_uflowl(long double x)952 check_uflowl (long double x)
953 {
954 return WANT_ERRNO ? __math_check_uflowl (x) : x;
955 }
956 #endif
957
958 /* Set inexact exception */
959 #if defined(FE_INEXACT) && !defined(PICOLIBC_DOUBLE_NOEXECPT)
960 __float64 __math_inexact(__float64);
961 void __math_set_inexact(void);
962 #else
963 #define __math_inexact(val) (val)
964 #define __math_set_inexact() ((void) 0)
965 #endif
966
967 #if defined(FE_INEXACT) && !defined(PICOLIBC_FLOAT_NOEXECPT)
968 float __math_inexactf(float val);
969 void __math_set_inexactf(void);
970 #else
971 #define __math_inexactf(val) (val)
972 #define __math_set_inexactf() ((void) 0)
973 #endif
974
975 #if defined(FE_INEXACT) && !defined(PICOLIBC_LONG_DOUBLE_NOEXECPT) && defined(_NEED_FLOAT_HUGE)
976 long double __math_inexactl(long double val);
977 void __math_set_inexactl(void);
978 #else
979 #define __math_inexactl(val) (val)
980 #define __math_set_inexactl() ((void) 0)
981 #endif
982
983 /* Shared between expf, exp2f and powf. */
984 #define EXP2F_TABLE_BITS 5
985 #define EXP2F_POLY_ORDER 3
986 extern const struct exp2f_data
987 {
988 uint64_t tab[1 << EXP2F_TABLE_BITS];
989 double shift_scaled;
990 double poly[EXP2F_POLY_ORDER];
991 double shift;
992 double invln2_scaled;
993 double poly_scaled[EXP2F_POLY_ORDER];
994 } __exp2f_data HIDDEN;
995
996 #define LOGF_TABLE_BITS 4
997 #define LOGF_POLY_ORDER 4
998 extern const struct logf_data
999 {
1000 struct
1001 {
1002 double invc, logc;
1003 } tab[1 << LOGF_TABLE_BITS];
1004 double ln2;
1005 double poly[LOGF_POLY_ORDER - 1]; /* First order coefficient is 1. */
1006 } __logf_data HIDDEN;
1007
1008 #define LOG2F_TABLE_BITS 4
1009 #define LOG2F_POLY_ORDER 4
1010 extern const struct log2f_data
1011 {
1012 struct
1013 {
1014 double invc, logc;
1015 } tab[1 << LOG2F_TABLE_BITS];
1016 double poly[LOG2F_POLY_ORDER];
1017 } __log2f_data HIDDEN;
1018
1019 #define POWF_LOG2_TABLE_BITS 4
1020 #define POWF_LOG2_POLY_ORDER 5
1021 #if TOINT_INTRINSICS
1022 # define POWF_SCALE_BITS EXP2F_TABLE_BITS
1023 #else
1024 # define POWF_SCALE_BITS 0
1025 #endif
1026 #define POWF_SCALE ((double) (1 << POWF_SCALE_BITS))
1027 extern const struct powf_log2_data
1028 {
1029 struct
1030 {
1031 double invc, logc;
1032 } tab[1 << POWF_LOG2_TABLE_BITS];
1033 double poly[POWF_LOG2_POLY_ORDER];
1034 } __powf_log2_data HIDDEN;
1035
1036 #define EXP_TABLE_BITS 7
1037 #define EXP_POLY_ORDER 5
1038 /* Use polynomial that is optimized for a wider input range. This may be
1039 needed for good precision in non-nearest rounding and !TOINT_INTRINSICS. */
1040 #define EXP_POLY_WIDE 0
1041 /* Use close to nearest rounding toint when !TOINT_INTRINSICS. This may be
1042 needed for good precision in non-nearest rouning and !EXP_POLY_WIDE. */
1043 #define EXP_USE_TOINT_NARROW 0
1044 #define EXP2_POLY_ORDER 5
1045 #define EXP2_POLY_WIDE 0
1046 extern const struct exp_data
1047 {
1048 double invln2N;
1049 double shift;
1050 double negln2hiN;
1051 double negln2loN;
1052 double poly[4]; /* Last four coefficients. */
1053 double exp2_shift;
1054 double exp2_poly[EXP2_POLY_ORDER];
1055 uint64_t tab[2*(1 << EXP_TABLE_BITS)];
1056 } __exp_data HIDDEN;
1057
1058 #define LOG_TABLE_BITS 7
1059 #define LOG_POLY_ORDER 6
1060 #define LOG_POLY1_ORDER 12
1061 extern const struct log_data
1062 {
1063 double ln2hi;
1064 double ln2lo;
1065 double poly[LOG_POLY_ORDER - 1]; /* First coefficient is 1. */
1066 double poly1[LOG_POLY1_ORDER - 1];
1067 struct {double invc, logc;} tab[1 << LOG_TABLE_BITS];
1068 #if !_HAVE_FAST_FMA
1069 struct {double chi, clo;} tab2[1 << LOG_TABLE_BITS];
1070 #endif
1071 } __log_data HIDDEN;
1072
1073 #define LOG2_TABLE_BITS 6
1074 #define LOG2_POLY_ORDER 7
1075 #define LOG2_POLY1_ORDER 11
1076 extern const struct log2_data
1077 {
1078 double invln2hi;
1079 double invln2lo;
1080 double poly[LOG2_POLY_ORDER - 1];
1081 double poly1[LOG2_POLY1_ORDER - 1];
1082 struct {double invc, logc;} tab[1 << LOG2_TABLE_BITS];
1083 #if !_HAVE_FAST_FMA
1084 struct {double chi, clo;} tab2[1 << LOG2_TABLE_BITS];
1085 #endif
1086 } __log2_data HIDDEN;
1087
1088 #define POW_LOG_TABLE_BITS 7
1089 #define POW_LOG_POLY_ORDER 8
1090 extern const struct pow_log_data
1091 {
1092 double ln2hi;
1093 double ln2lo;
1094 double poly[POW_LOG_POLY_ORDER - 1]; /* First coefficient is 1. */
1095 /* Note: the pad field is unused, but allows slightly faster indexing. */
1096 struct {double invc, pad, logc, logctail;} tab[1 << POW_LOG_TABLE_BITS];
1097 } __pow_log_data HIDDEN;
1098
1099 #if WANT_ERRNO
1100 HIDDEN double
1101 __math_with_errno (double y, int e);
1102
1103 HIDDEN float
1104 __math_with_errnof (float y, int e);
1105
1106 #ifdef _HAVE_LONG_DOUBLE
1107 HIDDEN long double
1108 __math_with_errnol (long double y, int e);
1109 #endif
1110 #else
1111 #define __math_with_errno(x, e) (x)
1112 #define __math_with_errnof(x, e) (x)
1113 #define __math_with_errnol(x, e) (x)
1114 #endif
1115
1116 /* Check if the result is a denorm. */
1117 #if (defined(FE_UNDERFLOW) && !defined(PICOLIBC_FLOAT_NOEXCEPT)) || WANT_ERRNO
1118 float __math_denormf (float x);
1119 #else
1120 #define __math_denormf(x) (x)
1121 #endif
1122
1123 #if (defined(FE_UNDERFLOW) && !defined(PICOLIBC_DOUBLE_NOEXCEPT)) || WANT_ERRNO
1124 __float64 __math_denorm (__float64 x);
1125 #else
1126 #define __math_denorm(x) (x)
1127 #endif
1128
1129 #if defined(_NEED_FLOAT_HUGE) && ((defined(FE_UNDERFLOW) && !defined(PICOLIBC_LONG_DOUBLE_NOEXCEPT)) || WANT_ERRNO)
1130 long double __math_denorml(long double x);
1131 #else
1132 #define __math_denorml(x) (x)
1133 #endif
1134
1135 HIDDEN double
1136 __math_xflow (uint32_t sign, double y);
1137
1138 HIDDEN float
1139 __math_xflowf (uint32_t sign, float y);
1140
1141 HIDDEN __float64
1142 __math_lgamma_r (__float64 y, int *signgamp, int *divzero);
1143
1144 HIDDEN float
1145 __math_lgammaf_r (float y, int *signgamp, int *divzero);
1146
1147 #ifdef __weak_reference
1148 extern int __signgam;
1149 #else
1150 #define __signgam signgam
1151 #endif
1152
1153 /* Make aliases for 64-bit functions to the correct name */
1154 #define acos64 _NAME_64(acos)
1155 #define acosh64 _NAME_64(acosh)
1156 #define asin64 _NAME_64(asin)
1157 #define asinh64 _NAME_64(asinh)
1158 #define atan64 _NAME_64(atan)
1159 #define atanh64 _NAME_64(atanh)
1160 #define atan264 _NAME_64(atan2)
1161 #define cbrt64 _NAME_64(cbrt)
1162 #define ceil64 _NAME_64(ceil)
1163 #define copysign64 _NAME_64(copysign)
1164 #define cos64 _NAME_64(cos)
1165 #define _cos64 _NAME_64(_cos)
1166 #define cosh64 _NAME_64(cosh)
1167 #define drem64 _NAME_64(drem)
1168 #define erf64 _NAME_64(erf)
1169 #define erfc64 _NAME_64(erfc)
1170 #define exp64 _NAME_64(exp)
1171 #define exp264 _NAME_64(exp2)
1172 #define exp1064 _NAME_64(exp10)
1173 #define expm164 _NAME_64(expm1)
1174 #define fabs64 _NAME_64(fabs)
1175 #define fdim64 _NAME_64(fdim)
1176 #define finite64 _NAME_64(finite)
1177 #define __finite64 _NAME_64(__finite)
1178 #define floor64 _NAME_64(floor)
1179 #define fma64 _NAME_64(fma)
1180 #define fmax64 _NAME_64(fmax)
1181 #define fmin64 _NAME_64(fmin)
1182 #define fmod64 _NAME_64(fmod)
1183 #define __fpclassify64 _NAME_64_SPECIAL(__fpclassifyd, __fpclassifyl)
1184 #define frexp64 _NAME_64(frexp)
1185 #define gamma64 _NAME_64(gamma)
1186 #define getpayload64 _NAME_64(getpayload)
1187 #define hypot64 _NAME_64(hypot)
1188 #define ilogb64 _NAME_64(ilogb)
1189 #define infinity64 _NAME_64(infinity)
1190 #define __iseqsig64 _NAME_64_SPECIAL(__iseqsigd, __iseqsigl)
1191 #define isfinite64 _NAME_64(isfinite)
1192 #define isinf64 _NAME_64(isinf)
1193 #define __isinf64 _NAME_64_SPECIAL(__isinfd, __isinfl)
1194 #define isnan64 _NAME_64(isnan)
1195 #define __isnan64 _NAME_64_SPECIAL(__isnand, __isnanl)
1196 #define ldexp64 _NAME_64(ldexp)
1197 #define j064 _NAME_64(j0)
1198 #define y064 _NAME_64(y0)
1199 #define j164 _NAME_64(j1)
1200 #define y164 _NAME_64(y1)
1201 #define jn64 _NAME_64(jn)
1202 #define yn64 _NAME_64(yn)
1203 #define lgamma64 _NAME_64(lgamma)
1204 #define lgamma64_r _NAME_64_SPECIAL(lgamma_r, lgammal_r)
1205 #define llrint64 _NAME_64(llrint)
1206 #define llround64 _NAME_64(llround)
1207 #define log64 _NAME_64(log)
1208 #define log1064 _NAME_64(log10)
1209 #define log1p64 _NAME_64(log1p)
1210 #define log264 _NAME_64(log2)
1211 #define logb64 _NAME_64(logb)
1212 #define lrint64 _NAME_64(lrint)
1213 #define lround64 _NAME_64(lround)
1214 #define modf64 _NAME_64(modf)
1215 #define nan64 _NAME_64(nan)
1216 #define nearbyint64 _NAME_64(nearbyint)
1217 #define nextafter64 _NAME_64(nextafter)
1218 #define nexttoward64 _NAME_64(nexttoward)
1219 #define pow64 _NAME_64(pow)
1220 #define _pow64 _NAME_64(_pow)
1221 #define pow1064 _NAME_64(pow10)
1222 #define remainder64 _NAME_64(remainder)
1223 #define remquo64 _NAME_64(remquo)
1224 #define rint64 _NAME_64(rint)
1225 #define round64 _NAME_64(round)
1226 #define scalb64 _NAME_64(scalb)
1227 #define scalbn64 _NAME_64(scalbn)
1228 #define scalbln64 _NAME_64(scalbln)
1229 #define significand64 _NAME_64(significand)
1230 #define sin64 _NAME_64(sin)
1231 #define _sin64 _NAME_64(_sin)
1232 #define sincos64 _NAME_64(sincos)
1233 #define sinh64 _NAME_64(sinh)
1234 #define sqrt64 _NAME_64(sqrt)
1235 #define tan64 _NAME_64(tan)
1236 #define tanh64 _NAME_64(tanh)
1237 #define tgamma64 _NAME_64(tgamma)
1238 #define trunc64 _NAME_64(trunc)
1239
1240 #ifdef _HAVE_ALIAS_ATTRIBUTE
1241 float _powf(float, float);
1242 float _sinf(float);
1243 float _cosf(float);
1244
1245 __float64 _pow64(__float64, __float64);
1246 __float64 _sin64(__float64);
1247 __float64 _cos64(__float64);
1248
1249 #ifdef _HAVE_LONG_DOUBLE_MATH
1250 long double _powl(long double, long double);
1251 long double _sinl(long double);
1252 long double _cosl(long double);
1253 #endif
1254
1255 #else
1256
1257 #define _powf(x,y) powf(x,y)
1258 #define _sinf(x) sinf(x)
1259 #define _cosf(x) cosf(x)
1260
1261 #undef _pow64
1262 #undef _sin64
1263 #undef _cos64
1264 #define _pow64(x,y) pow64(x,y)
1265 #define _sin64(x) sin64(x)
1266 #define _cos64(x) cos64(x)
1267
1268 #ifdef _HAVE_LONG_DOUBLE_MATH
1269 #define _powl(x,y) powl(x,y)
1270 #define _sinl(x) sinl(x)
1271 #define _cosl(x) cosl(x)
1272 #endif /* _HAVE_LONG_DOUBLE_MATH */
1273
1274 #endif /* _HAVE_ALIAS_ATTRIBUTE */
1275
1276 #endif
1277