1 /*
2 * Configuration for math routines.
3 *
4 * Copyright (c) 2017-2024, Arm Limited.
5 * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception
6 */
7
8 #ifndef _MATH_CONFIG_H
9 #define _MATH_CONFIG_H
10
11 #include <math.h>
12 #include <stdint.h>
13
14 #ifndef WANT_ROUNDING
15 /* If defined to 1, return correct results for special cases in non-nearest
16 rounding modes (logf (1.0f) returns 0.0f with FE_DOWNWARD rather than
17 -0.0f). This may be set to 0 if there is no fenv support or if math
18 functions only get called in round to nearest mode. */
19 # define WANT_ROUNDING 1
20 #endif
21 #ifndef WANT_ERRNO
22 /* If defined to 1, set errno in math functions according to ISO C. Many math
23 libraries do not set errno, so this is 0 by default. It may need to be
24 set to 1 if math.h has (math_errhandling & MATH_ERRNO) != 0. */
25 # define WANT_ERRNO 0
26 #endif
27 #ifndef WANT_ERRNO_UFLOW
28 /* Set errno to ERANGE if result underflows to 0 (in all rounding modes). */
29 # define WANT_ERRNO_UFLOW (WANT_ROUNDING && WANT_ERRNO)
30 #endif
31
32 /* Compiler can inline round as a single instruction. */
33 #ifndef HAVE_FAST_ROUND
34 # if __aarch64__
35 # define HAVE_FAST_ROUND 1
36 # else
37 # define HAVE_FAST_ROUND 0
38 # endif
39 #endif
40
41 /* Compiler can inline lround, but not (long)round(x). */
42 #ifndef HAVE_FAST_LROUND
43 # if __aarch64__ && (100*__GNUC__ + __GNUC_MINOR__) >= 408 && __NO_MATH_ERRNO__
44 # define HAVE_FAST_LROUND 1
45 # else
46 # define HAVE_FAST_LROUND 0
47 # endif
48 #endif
49
50 /* Compiler can inline fma as a single instruction. */
51 #ifndef HAVE_FAST_FMA
52 # if defined FP_FAST_FMA || __aarch64__
53 # define HAVE_FAST_FMA 1
54 # else
55 # define HAVE_FAST_FMA 0
56 # endif
57 #endif
58
59 /* Provide *_finite symbols and some of the glibc hidden symbols
60 so libmathlib can be used with binaries compiled against glibc
61 to interpose math functions with both static and dynamic linking. */
62 #ifndef USE_GLIBC_ABI
63 # if __GNUC__
64 # define USE_GLIBC_ABI 1
65 # else
66 # define USE_GLIBC_ABI 0
67 # endif
68 #endif
69
70 /* Optionally used extensions. */
71 #ifdef __GNUC__
72 # define HIDDEN __attribute__ ((__visibility__ ("hidden")))
73 # define NOINLINE __attribute__ ((noinline))
74 # define UNUSED __attribute__ ((unused))
75 # define likely(x) __builtin_expect (!!(x), 1)
76 # define unlikely(x) __builtin_expect (x, 0)
77 # if __GNUC__ >= 9
78 # define attribute_copy(f) __attribute__ ((copy (f)))
79 # else
80 # define attribute_copy(f)
81 # endif
82 # define strong_alias(f, a) \
83 extern __typeof (f) a __attribute__ ((alias (#f))) attribute_copy (f);
84 # define hidden_alias(f, a) \
85 extern __typeof (f) a __attribute__ ((alias (#f), visibility ("hidden"))) \
86 attribute_copy (f);
87 #else
88 # define HIDDEN
89 # define NOINLINE
90 # define UNUSED
91 # define likely(x) (x)
92 # define unlikely(x) (x)
93 #endif
94
95 /* Return ptr but hide its value from the compiler so accesses through it
96 cannot be optimized based on the contents. */
97 #define ptr_barrier(ptr) \
98 ({ \
99 __typeof (ptr) __ptr = (ptr); \
100 __asm("" : "+r"(__ptr)); \
101 __ptr; \
102 })
103
104 /* Symbol renames to avoid libc conflicts. */
105 #define __math_oflowf arm_math_oflowf
106 #define __math_uflowf arm_math_uflowf
107 #define __math_may_uflowf arm_math_may_uflowf
108 #define __math_divzerof arm_math_divzerof
109 #define __math_oflow arm_math_oflow
110 #define __math_uflow arm_math_uflow
111 #define __math_may_uflow arm_math_may_uflow
112 #define __math_divzero arm_math_divzero
113 #define __math_invalidf arm_math_invalidf
114 #define __math_invalid arm_math_invalid
115 #define __math_check_oflow arm_math_check_oflow
116 #define __math_check_uflow arm_math_check_uflow
117 #define __math_check_oflowf arm_math_check_oflowf
118 #define __math_check_uflowf arm_math_check_uflowf
119
120 #define __exp_data arm_math_exp_data
121 #define __asin_poly arm_math_asin_poly
122 #define __asinf_poly arm_math_asinf_poly
123 #define __asinh_data arm_math_asinh_data
124 #define __asinhf_data arm_math_asinhf_data
125 #define __atan_poly_data arm_math_atan_poly_data
126 #define __atanf_poly_data arm_math_atanf_poly_data
127 #define __cbrt_data arm_math_cbrt_data
128 #define __cbrtf_data arm_math_cbrtf_data
129 #define __erf_data arm_math_erf_data
130 #define __expf_data arm_math_expf_data
131 #define __expm1_poly arm_math_expm1_poly
132 #define __expm1f_poly arm_math_expm1f_poly
133 #define __log10_data arm_math_log10_data
134 #define __log1p_data arm_math_log1p_data
135 #define __log1pf_data arm_math_log1pf_data
136 #define __log_data arm_math_log_data
137 #define __tanf_poly_data arm_math_tanf_poly_data
138 #define __v_log_data arm_math_v_log_data
139 #define __sincosf_table arm_math_sincosf_table
140 #define __inv_pio4 arm_math_inv_pio4
141 #define __exp2f_data arm_math_exp2f_data
142 #define __logf_data arm_math_logf_data
143 #define __log2f_data arm_math_log2f_data
144 #define __powf_log2_data arm_math_powf_log2_data
145 #define __exp_data arm_math_exp_data
146 #define __log_data arm_math_log_data
147 #define __log2_data arm_math_log2_data
148 #define __pow_log_data arm_math_pow_log_data
149 #define __erff_data arm_math_erff_data
150 #define __erf_data arm_math_erf_data
151 #define __v_exp_data arm_math_v_exp_data
152 #define __v_log_data arm_math_v_log_data
153 #define __v_erf_data arm_math_v_erf_data
154 #define __v_erfc_data arm_math_v_erfc_data
155 #define __v_erfcf_data arm_math_v_erfcf_data
156 #define __v_erff_data arm_math_v_erff_data
157 #define __v_exp_tail_data arm_math_v_exp_tail_data
158 #define __v_log10_data arm_math_v_log10_data
159 #define __v_log2_data arm_math_v_log2_data
160 #define __v_pow_exp_data arm_math_v_pow_exp_data
161 #define __v_pow_log_data arm_math_v_pow_log_data
162 #define __v_powf_data arm_math_v_powf_data
163
164 /* On some platforms (in particular Windows) INFINITY and HUGE_VAL might
165 be defined in such a way that might not produce the expected bit pattern,
166 therefore we enforce the glibc math.h definition using a builtin that is
167 supported in both gcc and clang. */
168 #if defined (_WIN32) && (defined (__GNUC__) || defined (__clang__))
169 # undef INFINITY
170 # define INFINITY __builtin_inff()
171 #endif
172
173 #if HAVE_FAST_ROUND
174 /* When set, the roundtoint and converttoint functions are provided with
175 the semantics documented below. */
176 # define TOINT_INTRINSICS 1
177
178 /* Round x to nearest int in all rounding modes, ties have to be rounded
179 consistently with converttoint so the results match. If the result
180 would be outside of [-2^31, 2^31-1] then the semantics is unspecified. */
181 static inline double_t
roundtoint(double_t x)182 roundtoint (double_t x)
183 {
184 return round (x);
185 }
186
187 /* Convert x to nearest int in all rounding modes, ties have to be rounded
188 consistently with roundtoint. If the result is not representible in an
189 int32_t then the semantics is unspecified. */
190 static inline int32_t
converttoint(double_t x)191 converttoint (double_t x)
192 {
193 # if HAVE_FAST_LROUND
194 return lround (x);
195 # else
196 return (long) round (x);
197 # endif
198 }
199 #endif
200
201 static inline uint32_t
asuint(float f)202 asuint (float f)
203 {
204 union
205 {
206 float f;
207 uint32_t i;
208 } u = {f};
209 return u.i;
210 }
211
212 static inline float
asfloat(uint32_t i)213 asfloat (uint32_t i)
214 {
215 union
216 {
217 uint32_t i;
218 float f;
219 } u = {i};
220 return u.f;
221 }
222
223 static inline uint64_t
asuint64(double f)224 asuint64 (double f)
225 {
226 union
227 {
228 double f;
229 uint64_t i;
230 } u = {f};
231 return u.i;
232 }
233
234 static inline double
asdouble(uint64_t i)235 asdouble (uint64_t i)
236 {
237 union
238 {
239 uint64_t i;
240 double f;
241 } u = {i};
242 return u.f;
243 }
244
245 #ifndef IEEE_754_2008_SNAN
246 # define IEEE_754_2008_SNAN 1
247 #endif
248 static inline int
issignalingf_inline(float x)249 issignalingf_inline (float x)
250 {
251 uint32_t ix = asuint (x);
252 if (!IEEE_754_2008_SNAN)
253 return (ix & 0x7fc00000) == 0x7fc00000;
254 return 2 * (ix ^ 0x00400000) > 2u * 0x7fc00000;
255 }
256
257 static inline int
issignaling_inline(double x)258 issignaling_inline (double x)
259 {
260 uint64_t ix = asuint64 (x);
261 if (!IEEE_754_2008_SNAN)
262 return (ix & 0x7ff8000000000000) == 0x7ff8000000000000;
263 return 2 * (ix ^ 0x0008000000000000) > 2 * 0x7ff8000000000000ULL;
264 }
265
266 #if __aarch64__ && __GNUC__
267 /* Prevent the optimization of a floating-point expression. */
268 static inline float
opt_barrier_float(float x)269 opt_barrier_float (float x)
270 {
271 __asm__ __volatile__ ("" : "+w" (x));
272 return x;
273 }
274 static inline double
opt_barrier_double(double x)275 opt_barrier_double (double x)
276 {
277 __asm__ __volatile__ ("" : "+w" (x));
278 return x;
279 }
280 /* Force the evaluation of a floating-point expression for its side-effect. */
281 static inline void
force_eval_float(float x)282 force_eval_float (float x)
283 {
284 __asm__ __volatile__ ("" : "+w" (x));
285 }
286 static inline void
force_eval_double(double x)287 force_eval_double (double x)
288 {
289 __asm__ __volatile__ ("" : "+w" (x));
290 }
291 #else
292 static inline float
opt_barrier_float(float x)293 opt_barrier_float (float x)
294 {
295 volatile float y = x;
296 return y;
297 }
298 static inline double
opt_barrier_double(double x)299 opt_barrier_double (double x)
300 {
301 volatile double y = x;
302 return y;
303 }
304 static inline void
force_eval_float(float x)305 force_eval_float (float x)
306 {
307 volatile float y UNUSED = x;
308 }
309 static inline void
force_eval_double(double x)310 force_eval_double (double x)
311 {
312 volatile double y UNUSED = x;
313 }
314 #endif
315
316 /* Evaluate an expression as the specified type, normally a type
317 cast should be enough, but compilers implement non-standard
318 excess-precision handling, so when FLT_EVAL_METHOD != 0 then
319 these functions may need to be customized. */
320 static inline float
eval_as_float(float x)321 eval_as_float (float x)
322 {
323 return x;
324 }
325 static inline double
eval_as_double(double x)326 eval_as_double (double x)
327 {
328 return x;
329 }
330
331 /* Error handling tail calls for special cases, with a sign argument.
332 The sign of the return value is set if the argument is non-zero. */
333
334 /* The result overflows. */
335 HIDDEN float __math_oflowf (uint32_t);
336 /* The result underflows to 0 in nearest rounding mode. */
337 HIDDEN float __math_uflowf (uint32_t);
338 /* The result underflows to 0 in some directed rounding mode only. */
339 HIDDEN float __math_may_uflowf (uint32_t);
340 /* Division by zero. */
341 HIDDEN float __math_divzerof (uint32_t);
342 /* The result overflows. */
343 HIDDEN double __math_oflow (uint32_t);
344 /* The result underflows to 0 in nearest rounding mode. */
345 HIDDEN double __math_uflow (uint32_t);
346 /* The result underflows to 0 in some directed rounding mode only. */
347 HIDDEN double __math_may_uflow (uint32_t);
348 /* Division by zero. */
349 HIDDEN double __math_divzero (uint32_t);
350
351 /* Error handling using input checking. */
352
353 /* Invalid input unless it is a quiet NaN. */
354 HIDDEN float __math_invalidf (float);
355 /* Invalid input unless it is a quiet NaN. */
356 HIDDEN double __math_invalid (double);
357
358 /* Error handling using output checking, only for errno setting. */
359
360 /* Check if the result overflowed to infinity. */
361 HIDDEN double __math_check_oflow (double);
362 /* Check if the result underflowed to 0. */
363 HIDDEN double __math_check_uflow (double);
364
365 /* Check if the result overflowed to infinity. */
366 static inline double
check_oflow(double x)367 check_oflow (double x)
368 {
369 return WANT_ERRNO ? __math_check_oflow (x) : x;
370 }
371
372 /* Check if the result underflowed to 0. */
373 static inline double
check_uflow(double x)374 check_uflow (double x)
375 {
376 return WANT_ERRNO ? __math_check_uflow (x) : x;
377 }
378
379 /* Check if the result overflowed to infinity. */
380 HIDDEN float __math_check_oflowf (float);
381 /* Check if the result underflowed to 0. */
382 HIDDEN float __math_check_uflowf (float);
383
384 /* Check if the result overflowed to infinity. */
385 static inline float
check_oflowf(float x)386 check_oflowf (float x)
387 {
388 return WANT_ERRNO ? __math_check_oflowf (x) : x;
389 }
390
391 /* Check if the result underflowed to 0. */
392 static inline float
check_uflowf(float x)393 check_uflowf (float x)
394 {
395 return WANT_ERRNO ? __math_check_uflowf (x) : x;
396 }
397
398 /* Shared between expf, exp2f and powf. */
399 #define EXP2F_TABLE_BITS 5
400 #define EXP2F_POLY_ORDER 3
401 extern const struct exp2f_data
402 {
403 uint64_t tab[1 << EXP2F_TABLE_BITS];
404 double shift_scaled;
405 double poly[EXP2F_POLY_ORDER];
406 double invln2_scaled;
407 double poly_scaled[EXP2F_POLY_ORDER];
408 double shift;
409 } __exp2f_data HIDDEN;
410
411 /* Data for logf and log10f. */
412 #define LOGF_TABLE_BITS 4
413 #define LOGF_POLY_ORDER 4
414 extern const struct logf_data
415 {
416 struct
417 {
418 double invc, logc;
419 } tab[1 << LOGF_TABLE_BITS];
420 double ln2;
421 double invln10;
422 double poly[LOGF_POLY_ORDER - 1]; /* First order coefficient is 1. */
423 } __logf_data HIDDEN;
424
425 #define LOG2F_TABLE_BITS 4
426 #define LOG2F_POLY_ORDER 4
427 extern const struct log2f_data
428 {
429 struct
430 {
431 double invc, logc;
432 } tab[1 << LOG2F_TABLE_BITS];
433 double poly[LOG2F_POLY_ORDER];
434 } __log2f_data HIDDEN;
435
436 #define POWF_LOG2_TABLE_BITS 4
437 #define POWF_LOG2_POLY_ORDER 5
438 #if TOINT_INTRINSICS
439 # define POWF_SCALE_BITS EXP2F_TABLE_BITS
440 #else
441 # define POWF_SCALE_BITS 0
442 #endif
443 #define POWF_SCALE ((double) (1 << POWF_SCALE_BITS))
444 extern const struct powf_log2_data
445 {
446 struct
447 {
448 double invc, logc;
449 } tab[1 << POWF_LOG2_TABLE_BITS];
450 double poly[POWF_LOG2_POLY_ORDER];
451 } __powf_log2_data HIDDEN;
452
453
454 #define EXP_TABLE_BITS 7
455 #define EXP_POLY_ORDER 5
456 /* Use polynomial that is optimized for a wider input range. This may be
457 needed for good precision in non-nearest rounding and !TOINT_INTRINSICS. */
458 #define EXP_POLY_WIDE 0
459 /* Use close to nearest rounding toint when !TOINT_INTRINSICS. This may be
460 needed for good precision in non-nearest rouning and !EXP_POLY_WIDE. */
461 #define EXP_USE_TOINT_NARROW 0
462 #define EXP2_POLY_ORDER 5
463 #define EXP2_POLY_WIDE 0
464 /* Wider exp10 polynomial necessary for good precision in non-nearest rounding
465 and !TOINT_INTRINSICS. */
466 #define EXP10_POLY_WIDE 0
467 extern const struct exp_data
468 {
469 double invln2N;
470 double negln2hiN;
471 double negln2loN;
472 double poly[4]; /* Last four coefficients. */
473 double shift;
474
475 double exp2_shift;
476 double exp2_poly[EXP2_POLY_ORDER];
477
478 double neglog10_2hiN;
479 double neglog10_2loN;
480 double exp10_poly[5];
481 uint64_t tab[2*(1 << EXP_TABLE_BITS)];
482 double invlog10_2N;
483 } __exp_data HIDDEN;
484
485 #define LOG_TABLE_BITS 7
486 #define LOG_POLY_ORDER 6
487 #define LOG_POLY1_ORDER 12
488 extern const struct log_data
489 {
490 double ln2hi;
491 double ln2lo;
492 double poly[LOG_POLY_ORDER - 1]; /* First coefficient is 1. */
493 double poly1[LOG_POLY1_ORDER - 1];
494 struct {double invc, logc;} tab[1 << LOG_TABLE_BITS];
495 #if !HAVE_FAST_FMA
496 struct {double chi, clo;} tab2[1 << LOG_TABLE_BITS];
497 #endif
498 } __log_data HIDDEN;
499
500 #define LOG2_TABLE_BITS 6
501 #define LOG2_POLY_ORDER 7
502 #define LOG2_POLY1_ORDER 11
503 extern const struct log2_data
504 {
505 double invln2hi;
506 double invln2lo;
507 double poly[LOG2_POLY_ORDER - 1];
508 double poly1[LOG2_POLY1_ORDER - 1];
509 struct {double invc, logc;} tab[1 << LOG2_TABLE_BITS];
510 #if !HAVE_FAST_FMA
511 struct {double chi, clo;} tab2[1 << LOG2_TABLE_BITS];
512 #endif
513 } __log2_data HIDDEN;
514
515 #define POW_LOG_TABLE_BITS 7
516 #define POW_LOG_POLY_ORDER 8
517 extern const struct pow_log_data
518 {
519 double ln2hi;
520 double ln2lo;
521 double poly[POW_LOG_POLY_ORDER - 1]; /* First coefficient is 1. */
522 /* Note: the pad field is unused, but allows slightly faster indexing. */
523 struct {double invc, pad, logc, logctail;} tab[1 << POW_LOG_TABLE_BITS];
524 } __pow_log_data HIDDEN;
525
526 extern const struct erff_data
527 {
528 float erff_poly_A[6];
529 float erff_poly_B[7];
530 } __erff_data HIDDEN;
531
532 #define ERF_POLY_A_ORDER 19
533 #define ERF_POLY_A_NCOEFFS 10
534 #define ERFC_POLY_C_NCOEFFS 16
535 #define ERFC_POLY_D_NCOEFFS 18
536 #define ERFC_POLY_E_NCOEFFS 14
537 #define ERFC_POLY_F_NCOEFFS 17
538 extern const struct erf_data
539 {
540 double erf_poly_A[ERF_POLY_A_NCOEFFS];
541 double erf_ratio_N_A[5];
542 double erf_ratio_D_A[5];
543 double erf_ratio_N_B[7];
544 double erf_ratio_D_B[6];
545 double erfc_poly_C[ERFC_POLY_C_NCOEFFS];
546 double erfc_poly_D[ERFC_POLY_D_NCOEFFS];
547 double erfc_poly_E[ERFC_POLY_E_NCOEFFS];
548 double erfc_poly_F[ERFC_POLY_F_NCOEFFS];
549 } __erf_data HIDDEN;
550
551 #define V_EXP_TABLE_BITS 7
552 extern const uint64_t __v_exp_data[1 << V_EXP_TABLE_BITS] HIDDEN;
553
554 #define V_LOG_POLY_ORDER 6
555 #define V_LOG_TABLE_BITS 7
556 extern const struct v_log_data
557 {
558 /* Shared data for vector log and log-derived routines (e.g. asinh). */
559 double poly[V_LOG_POLY_ORDER - 1];
560 double ln2;
561 struct
562 {
563 double invc, logc;
564 } table[1 << V_LOG_TABLE_BITS];
565 } __v_log_data HIDDEN;
566
567 /* Some data for SVE powf's internal exp and log. */
568 #define V_POWF_EXP2_TABLE_BITS 5
569 #define V_POWF_EXP2_N (1 << V_POWF_EXP2_TABLE_BITS)
570 #define V_POWF_LOG2_TABLE_BITS 5
571 #define V_POWF_LOG2_N (1 << V_POWF_LOG2_TABLE_BITS)
572 extern const struct v_powf_data
573 {
574 double invc[V_POWF_LOG2_N];
575 double logc[V_POWF_LOG2_N];
576 uint64_t scale[V_POWF_EXP2_N];
577 } __v_powf_data HIDDEN;
578
579 /* Some data for AdvSIMD and SVE pow's internal exp and log. */
580 #define V_POW_EXP_TABLE_BITS 8
581 extern const struct v_pow_exp_data
582 {
583 double poly[3];
584 double n_over_ln2, ln2_over_n_hi, ln2_over_n_lo, shift;
585 uint64_t sbits[1 << V_POW_EXP_TABLE_BITS];
586 } __v_pow_exp_data HIDDEN;
587
588 #define V_POW_LOG_TABLE_BITS 7
589 extern const struct v_pow_log_data
590 {
591 double poly[7]; /* First coefficient is 1. */
592 double ln2_hi, ln2_lo;
593 double invc[1 << V_POW_LOG_TABLE_BITS];
594 double logc[1 << V_POW_LOG_TABLE_BITS];
595 double logctail[1 << V_POW_LOG_TABLE_BITS];
596 } __v_pow_log_data HIDDEN;
597
598 #define V_LOG2_TABLE_BITS 7
599 extern const struct v_log2_data
600 {
601 double poly[5];
602 double invln2;
603 struct
604 {
605 double invc, log2c;
606 } table[1 << V_LOG2_TABLE_BITS];
607 } __v_log2_data HIDDEN;
608
609 #define V_LOG10_TABLE_BITS 7
610 extern const struct v_log10_data
611 {
612 double poly[5];
613 double invln10, log10_2;
614 struct
615 {
616 double invc, log10c;
617 } table[1 << V_LOG10_TABLE_BITS];
618 } __v_log10_data HIDDEN;
619
620 #define V_EXP_TAIL_TABLE_BITS 8
621 extern const uint64_t __v_exp_tail_data[1 << V_EXP_TAIL_TABLE_BITS] HIDDEN;
622
623 extern const struct v_erff_data
624 {
625 struct
626 {
627 float erf, scale;
628 } tab[513];
629 } __v_erff_data HIDDEN;
630
631 extern const struct v_erfcf_data
632 {
633 struct
634 {
635 float erfc, scale;
636 } tab[645];
637 } __v_erfcf_data HIDDEN;
638
639 extern const struct v_erf_data
640 {
641 struct
642 {
643 double erf, scale;
644 } tab[769];
645 } __v_erf_data HIDDEN;
646
647 extern const struct v_erfc_data
648 {
649 struct
650 {
651 double erfc, scale;
652 } tab[3488];
653 } __v_erfc_data HIDDEN;
654
655 /* Table with 4/PI to 192 bit precision. */
656 extern const uint32_t __inv_pio4[] HIDDEN;
657
658 #if WANT_EXPERIMENTAL_MATH
659
660 # define LOG1P_NCOEFFS 19
661 extern const struct log1p_data
662 {
663 double coeffs[LOG1P_NCOEFFS];
664 } __log1p_data HIDDEN;
665
666 # define LOG1PF_2U5
667 # define LOG1PF_NCOEFFS 9
668 extern const struct log1pf_data
669 {
670 float coeffs[LOG1PF_NCOEFFS];
671 } __log1pf_data HIDDEN;
672
673 # define ASINF_POLY_ORDER 4
674 extern const float __asinf_poly[ASINF_POLY_ORDER + 1] HIDDEN;
675
676 # define ASIN_POLY_ORDER 11
677 extern const double __asin_poly[ASIN_POLY_ORDER + 1] HIDDEN;
678
679 # define ASINHF_NCOEFFS 8
680 extern const struct asinhf_data
681 {
682 float coeffs[ASINHF_NCOEFFS];
683 } __asinhf_data HIDDEN;
684
685 # define ASINH_NCOEFFS 18
686 extern const struct asinh_data
687 {
688 double poly[ASINH_NCOEFFS];
689 } __asinh_data HIDDEN;
690
691 # define ATAN_POLY_NCOEFFS 20
692 extern const struct atan_poly_data
693 {
694 double poly[ATAN_POLY_NCOEFFS];
695 } __atan_poly_data HIDDEN;
696
697 # define ATANF_POLY_NCOEFFS 8
698 extern const struct atanf_poly_data
699 {
700 float poly[ATANF_POLY_NCOEFFS];
701 } __atanf_poly_data HIDDEN;
702
703 extern const struct cbrtf_data
704 {
705 float poly[4];
706 float table[5];
707 } __cbrtf_data HIDDEN;
708
709 extern const struct cbrt_data
710 {
711 double poly[4];
712 double table[5];
713 } __cbrt_data HIDDEN;
714
715 # define EXPF_TABLE_BITS 5
716 # define EXPF_POLY_ORDER 3
717 extern const struct expf_data
718 {
719 uint64_t tab[1 << EXPF_TABLE_BITS];
720 double invln2_scaled;
721 double poly_scaled[EXPF_POLY_ORDER];
722 } __expf_data HIDDEN;
723
724 # define EXPM1F_POLY_ORDER 5
725 extern const float __expm1f_poly[EXPM1F_POLY_ORDER] HIDDEN;
726
727 # define EXPM1_POLY_ORDER 11
728 extern const double __expm1_poly[EXPM1_POLY_ORDER] HIDDEN;
729
730 /* Data for low accuracy log10 (with 1/ln(10) included in coefficients). */
731 # define LOG10_TABLE_BITS 7
732 # define LOG10_POLY_ORDER 6
733 # define LOG10_POLY1_ORDER 12
734 extern const struct log10_data
735 {
736 double ln2hi;
737 double ln2lo;
738 double invln10;
739 double poly[LOG10_POLY_ORDER - 1]; /* First coefficient is 1/log(10). */
740 double poly1[LOG10_POLY1_ORDER - 1];
741 struct
742 {
743 double invc, logc;
744 } tab[1 << LOG10_TABLE_BITS];
745 # if !HAVE_FAST_FMA
746 struct
747 {
748 double chi, clo;
749 } tab2[1 << LOG10_TABLE_BITS];
750 # endif
751 } __log10_data HIDDEN;
752
753 # define TANF_P_POLY_NCOEFFS 6
754 /* cotan approach needs order 3 on [0, pi/4] to reach <3.5ulps. */
755 # define TANF_Q_POLY_NCOEFFS 4
756 extern const struct tanf_poly_data
757 {
758 float poly_tan[TANF_P_POLY_NCOEFFS];
759 float poly_cotan[TANF_Q_POLY_NCOEFFS];
760 } __tanf_poly_data HIDDEN;
761
762 #endif /* WANT_EXPERIMENTAL_MATH. */
763
764 #endif
765