xref: /freebsd/contrib/arm-optimized-routines/math/math_config.h (revision dd21556857e8d40f66bf5ad54754d9d52669ebf7)
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
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
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
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
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
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
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
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
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
269 opt_barrier_float (float x)
270 {
271   __asm__ __volatile__ ("" : "+w" (x));
272   return x;
273 }
274 static inline double
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
282 force_eval_float (float x)
283 {
284   __asm__ __volatile__ ("" : "+w" (x));
285 }
286 static inline void
287 force_eval_double (double x)
288 {
289   __asm__ __volatile__ ("" : "+w" (x));
290 }
291 #else
292 static inline float
293 opt_barrier_float (float x)
294 {
295   volatile float y = x;
296   return y;
297 }
298 static inline double
299 opt_barrier_double (double x)
300 {
301   volatile double y = x;
302   return y;
303 }
304 static inline void
305 force_eval_float (float x)
306 {
307   volatile float y UNUSED = x;
308 }
309 static inline void
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
321 eval_as_float (float x)
322 {
323   return x;
324 }
325 static inline double
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
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
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
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
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