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