10928368fSKristof Beyls /*
20928368fSKristof Beyls * Configuration for math routines.
30928368fSKristof Beyls *
40928368fSKristof Beyls * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
50928368fSKristof Beyls * See https://llvm.org/LICENSE.txt for license information.
60928368fSKristof Beyls * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
70928368fSKristof Beyls */
80928368fSKristof Beyls
90928368fSKristof Beyls #ifndef _MATH_CONFIG_H
100928368fSKristof Beyls #define _MATH_CONFIG_H
110928368fSKristof Beyls
120928368fSKristof Beyls #include <math.h>
130928368fSKristof Beyls #include <stdint.h>
140928368fSKristof Beyls
150928368fSKristof Beyls #ifndef WANT_ROUNDING
160928368fSKristof Beyls /* If defined to 1, return correct results for special cases in non-nearest
170928368fSKristof Beyls rounding modes (logf (1.0f) returns 0.0f with FE_DOWNWARD rather than -0.0f).
180928368fSKristof Beyls This may be set to 0 if there is no fenv support or if math functions only
190928368fSKristof Beyls get called in round to nearest mode. */
200928368fSKristof Beyls # define WANT_ROUNDING 1
210928368fSKristof Beyls #endif
220928368fSKristof Beyls #ifndef WANT_ERRNO
230928368fSKristof Beyls /* If defined to 1, set errno in math functions according to ISO C. Many math
240928368fSKristof Beyls libraries do not set errno, so this is 0 by default. It may need to be
250928368fSKristof Beyls set to 1 if math.h has (math_errhandling & MATH_ERRNO) != 0. */
260928368fSKristof Beyls # define WANT_ERRNO 0
270928368fSKristof Beyls #endif
280928368fSKristof Beyls #ifndef WANT_ERRNO_UFLOW
290928368fSKristof Beyls /* Set errno to ERANGE if result underflows to 0 (in all rounding modes). */
300928368fSKristof Beyls # define WANT_ERRNO_UFLOW (WANT_ROUNDING && WANT_ERRNO)
310928368fSKristof Beyls #endif
320928368fSKristof Beyls
330928368fSKristof Beyls /* Compiler can inline round as a single instruction. */
340928368fSKristof Beyls #ifndef HAVE_FAST_ROUND
350928368fSKristof Beyls # if __aarch64__
360928368fSKristof Beyls # define HAVE_FAST_ROUND 1
370928368fSKristof Beyls # else
380928368fSKristof Beyls # define HAVE_FAST_ROUND 0
390928368fSKristof Beyls # endif
400928368fSKristof Beyls #endif
410928368fSKristof Beyls
420928368fSKristof Beyls /* Compiler can inline lround, but not (long)round(x). */
430928368fSKristof Beyls #ifndef HAVE_FAST_LROUND
440928368fSKristof Beyls # if __aarch64__ && (100*__GNUC__ + __GNUC_MINOR__) >= 408 && __NO_MATH_ERRNO__
450928368fSKristof Beyls # define HAVE_FAST_LROUND 1
460928368fSKristof Beyls # else
470928368fSKristof Beyls # define HAVE_FAST_LROUND 0
480928368fSKristof Beyls # endif
490928368fSKristof Beyls #endif
500928368fSKristof Beyls
510928368fSKristof Beyls /* Compiler can inline fma as a single instruction. */
520928368fSKristof Beyls #ifndef HAVE_FAST_FMA
530928368fSKristof Beyls # if defined FP_FAST_FMA || __aarch64__
540928368fSKristof Beyls # define HAVE_FAST_FMA 1
550928368fSKristof Beyls # else
560928368fSKristof Beyls # define HAVE_FAST_FMA 0
570928368fSKristof Beyls # endif
580928368fSKristof Beyls #endif
590928368fSKristof Beyls
600928368fSKristof Beyls /* Provide *_finite symbols and some of the glibc hidden symbols
610928368fSKristof Beyls so libmathlib can be used with binaries compiled against glibc
620928368fSKristof Beyls to interpose math functions with both static and dynamic linking. */
630928368fSKristof Beyls #ifndef USE_GLIBC_ABI
640928368fSKristof Beyls # if __GNUC__
650928368fSKristof Beyls # define USE_GLIBC_ABI 1
660928368fSKristof Beyls # else
670928368fSKristof Beyls # define USE_GLIBC_ABI 0
680928368fSKristof Beyls # endif
690928368fSKristof Beyls #endif
700928368fSKristof Beyls
710928368fSKristof Beyls /* Optionally used extensions. */
720928368fSKristof Beyls #ifdef __GNUC__
730928368fSKristof Beyls # define HIDDEN __attribute__ ((__visibility__ ("hidden")))
740928368fSKristof Beyls # define NOINLINE __attribute__ ((noinline))
750928368fSKristof Beyls # define UNUSED __attribute__ ((unused))
760928368fSKristof Beyls # define likely(x) __builtin_expect (!!(x), 1)
770928368fSKristof Beyls # define unlikely(x) __builtin_expect (x, 0)
780928368fSKristof Beyls # if __GNUC__ >= 9
790928368fSKristof Beyls # define attribute_copy(f) __attribute__ ((copy (f)))
800928368fSKristof Beyls # else
810928368fSKristof Beyls # define attribute_copy(f)
820928368fSKristof Beyls # endif
830928368fSKristof Beyls # define strong_alias(f, a) \
840928368fSKristof Beyls extern __typeof (f) a __attribute__ ((alias (#f))) attribute_copy (f);
850928368fSKristof Beyls # define hidden_alias(f, a) \
860928368fSKristof Beyls extern __typeof (f) a __attribute__ ((alias (#f), visibility ("hidden"))) \
870928368fSKristof Beyls attribute_copy (f);
880928368fSKristof Beyls #else
890928368fSKristof Beyls # define HIDDEN
900928368fSKristof Beyls # define NOINLINE
910928368fSKristof Beyls # define UNUSED
920928368fSKristof Beyls # define likely(x) (x)
930928368fSKristof Beyls # define unlikely(x) (x)
940928368fSKristof Beyls #endif
950928368fSKristof Beyls
960928368fSKristof Beyls #if HAVE_FAST_ROUND
970928368fSKristof Beyls /* When set, the roundtoint and converttoint functions are provided with
980928368fSKristof Beyls the semantics documented below. */
990928368fSKristof Beyls # define TOINT_INTRINSICS 1
1000928368fSKristof Beyls
1010928368fSKristof Beyls /* Round x to nearest int in all rounding modes, ties have to be rounded
1020928368fSKristof Beyls consistently with converttoint so the results match. If the result
1030928368fSKristof Beyls would be outside of [-2^31, 2^31-1] then the semantics is unspecified. */
1040928368fSKristof Beyls static inline double_t
roundtoint(double_t x)1050928368fSKristof Beyls roundtoint (double_t x)
1060928368fSKristof Beyls {
1070928368fSKristof Beyls return round (x);
1080928368fSKristof Beyls }
1090928368fSKristof Beyls
1100928368fSKristof Beyls /* Convert x to nearest int in all rounding modes, ties have to be rounded
111*0570de73SKazuaki Ishizaki consistently with roundtoint. If the result is not representable in an
1120928368fSKristof Beyls int32_t then the semantics is unspecified. */
1130928368fSKristof Beyls static inline int32_t
converttoint(double_t x)1140928368fSKristof Beyls converttoint (double_t x)
1150928368fSKristof Beyls {
1160928368fSKristof Beyls # if HAVE_FAST_LROUND
1170928368fSKristof Beyls return lround (x);
1180928368fSKristof Beyls # else
1190928368fSKristof Beyls return (long) round (x);
1200928368fSKristof Beyls # endif
1210928368fSKristof Beyls }
1220928368fSKristof Beyls #endif
1230928368fSKristof Beyls
1240928368fSKristof Beyls static inline uint32_t
asuint(float f)1250928368fSKristof Beyls asuint (float f)
1260928368fSKristof Beyls {
1270928368fSKristof Beyls union
1280928368fSKristof Beyls {
1290928368fSKristof Beyls float f;
1300928368fSKristof Beyls uint32_t i;
1310928368fSKristof Beyls } u = {f};
1320928368fSKristof Beyls return u.i;
1330928368fSKristof Beyls }
1340928368fSKristof Beyls
1350928368fSKristof Beyls static inline float
asfloat(uint32_t i)1360928368fSKristof Beyls asfloat (uint32_t i)
1370928368fSKristof Beyls {
1380928368fSKristof Beyls union
1390928368fSKristof Beyls {
1400928368fSKristof Beyls uint32_t i;
1410928368fSKristof Beyls float f;
1420928368fSKristof Beyls } u = {i};
1430928368fSKristof Beyls return u.f;
1440928368fSKristof Beyls }
1450928368fSKristof Beyls
1460928368fSKristof Beyls static inline uint64_t
asuint64(double f)1470928368fSKristof Beyls asuint64 (double f)
1480928368fSKristof Beyls {
1490928368fSKristof Beyls union
1500928368fSKristof Beyls {
1510928368fSKristof Beyls double f;
1520928368fSKristof Beyls uint64_t i;
1530928368fSKristof Beyls } u = {f};
1540928368fSKristof Beyls return u.i;
1550928368fSKristof Beyls }
1560928368fSKristof Beyls
1570928368fSKristof Beyls static inline double
asdouble(uint64_t i)1580928368fSKristof Beyls asdouble (uint64_t i)
1590928368fSKristof Beyls {
1600928368fSKristof Beyls union
1610928368fSKristof Beyls {
1620928368fSKristof Beyls uint64_t i;
1630928368fSKristof Beyls double f;
1640928368fSKristof Beyls } u = {i};
1650928368fSKristof Beyls return u.f;
1660928368fSKristof Beyls }
1670928368fSKristof Beyls
1680928368fSKristof Beyls #ifndef IEEE_754_2008_SNAN
1690928368fSKristof Beyls # define IEEE_754_2008_SNAN 1
1700928368fSKristof Beyls #endif
1710928368fSKristof Beyls static inline int
issignalingf_inline(float x)1720928368fSKristof Beyls issignalingf_inline (float x)
1730928368fSKristof Beyls {
1740928368fSKristof Beyls uint32_t ix = asuint (x);
1750928368fSKristof Beyls if (!IEEE_754_2008_SNAN)
1760928368fSKristof Beyls return (ix & 0x7fc00000) == 0x7fc00000;
1770928368fSKristof Beyls return 2 * (ix ^ 0x00400000) > 2u * 0x7fc00000;
1780928368fSKristof Beyls }
1790928368fSKristof Beyls
1800928368fSKristof Beyls static inline int
issignaling_inline(double x)1810928368fSKristof Beyls issignaling_inline (double x)
1820928368fSKristof Beyls {
1830928368fSKristof Beyls uint64_t ix = asuint64 (x);
1840928368fSKristof Beyls if (!IEEE_754_2008_SNAN)
1850928368fSKristof Beyls return (ix & 0x7ff8000000000000) == 0x7ff8000000000000;
1860928368fSKristof Beyls return 2 * (ix ^ 0x0008000000000000) > 2 * 0x7ff8000000000000ULL;
1870928368fSKristof Beyls }
1880928368fSKristof Beyls
1890928368fSKristof Beyls #if __aarch64__ && __GNUC__
1900928368fSKristof Beyls /* Prevent the optimization of a floating-point expression. */
1910928368fSKristof Beyls static inline float
opt_barrier_float(float x)1920928368fSKristof Beyls opt_barrier_float (float x)
1930928368fSKristof Beyls {
1940928368fSKristof Beyls __asm__ __volatile__ ("" : "+w" (x));
1950928368fSKristof Beyls return x;
1960928368fSKristof Beyls }
1970928368fSKristof Beyls static inline double
opt_barrier_double(double x)1980928368fSKristof Beyls opt_barrier_double (double x)
1990928368fSKristof Beyls {
2000928368fSKristof Beyls __asm__ __volatile__ ("" : "+w" (x));
2010928368fSKristof Beyls return x;
2020928368fSKristof Beyls }
2030928368fSKristof Beyls /* Force the evaluation of a floating-point expression for its side-effect. */
2040928368fSKristof Beyls static inline void
force_eval_float(float x)2050928368fSKristof Beyls force_eval_float (float x)
2060928368fSKristof Beyls {
2070928368fSKristof Beyls __asm__ __volatile__ ("" : "+w" (x));
2080928368fSKristof Beyls }
2090928368fSKristof Beyls static inline void
force_eval_double(double x)2100928368fSKristof Beyls force_eval_double (double x)
2110928368fSKristof Beyls {
2120928368fSKristof Beyls __asm__ __volatile__ ("" : "+w" (x));
2130928368fSKristof Beyls }
2140928368fSKristof Beyls #else
2150928368fSKristof Beyls static inline float
opt_barrier_float(float x)2160928368fSKristof Beyls opt_barrier_float (float x)
2170928368fSKristof Beyls {
2180928368fSKristof Beyls volatile float y = x;
2190928368fSKristof Beyls return y;
2200928368fSKristof Beyls }
2210928368fSKristof Beyls static inline double
opt_barrier_double(double x)2220928368fSKristof Beyls opt_barrier_double (double x)
2230928368fSKristof Beyls {
2240928368fSKristof Beyls volatile double y = x;
2250928368fSKristof Beyls return y;
2260928368fSKristof Beyls }
2270928368fSKristof Beyls static inline void
force_eval_float(float x)2280928368fSKristof Beyls force_eval_float (float x)
2290928368fSKristof Beyls {
2300928368fSKristof Beyls volatile float y UNUSED = x;
2310928368fSKristof Beyls }
2320928368fSKristof Beyls static inline void
force_eval_double(double x)2330928368fSKristof Beyls force_eval_double (double x)
2340928368fSKristof Beyls {
2350928368fSKristof Beyls volatile double y UNUSED = x;
2360928368fSKristof Beyls }
2370928368fSKristof Beyls #endif
2380928368fSKristof Beyls
2390928368fSKristof Beyls /* Evaluate an expression as the specified type, normally a type
2400928368fSKristof Beyls cast should be enough, but compilers implement non-standard
2410928368fSKristof Beyls excess-precision handling, so when FLT_EVAL_METHOD != 0 then
2420928368fSKristof Beyls these functions may need to be customized. */
2430928368fSKristof Beyls static inline float
eval_as_float(float x)2440928368fSKristof Beyls eval_as_float (float x)
2450928368fSKristof Beyls {
2460928368fSKristof Beyls return x;
2470928368fSKristof Beyls }
2480928368fSKristof Beyls static inline double
eval_as_double(double x)2490928368fSKristof Beyls eval_as_double (double x)
2500928368fSKristof Beyls {
2510928368fSKristof Beyls return x;
2520928368fSKristof Beyls }
2530928368fSKristof Beyls
2540928368fSKristof Beyls /* Error handling tail calls for special cases, with a sign argument.
2550928368fSKristof Beyls The sign of the return value is set if the argument is non-zero. */
2560928368fSKristof Beyls
2570928368fSKristof Beyls /* The result overflows. */
2580928368fSKristof Beyls HIDDEN float __math_oflowf (uint32_t);
2590928368fSKristof Beyls /* The result underflows to 0 in nearest rounding mode. */
2600928368fSKristof Beyls HIDDEN float __math_uflowf (uint32_t);
2610928368fSKristof Beyls /* The result underflows to 0 in some directed rounding mode only. */
2620928368fSKristof Beyls HIDDEN float __math_may_uflowf (uint32_t);
2630928368fSKristof Beyls /* Division by zero. */
2640928368fSKristof Beyls HIDDEN float __math_divzerof (uint32_t);
2650928368fSKristof Beyls /* The result overflows. */
2660928368fSKristof Beyls HIDDEN double __math_oflow (uint32_t);
2670928368fSKristof Beyls /* The result underflows to 0 in nearest rounding mode. */
2680928368fSKristof Beyls HIDDEN double __math_uflow (uint32_t);
2690928368fSKristof Beyls /* The result underflows to 0 in some directed rounding mode only. */
2700928368fSKristof Beyls HIDDEN double __math_may_uflow (uint32_t);
2710928368fSKristof Beyls /* Division by zero. */
2720928368fSKristof Beyls HIDDEN double __math_divzero (uint32_t);
2730928368fSKristof Beyls
2740928368fSKristof Beyls /* Error handling using input checking. */
2750928368fSKristof Beyls
2760928368fSKristof Beyls /* Invalid input unless it is a quiet NaN. */
2770928368fSKristof Beyls HIDDEN float __math_invalidf (float);
2780928368fSKristof Beyls /* Invalid input unless it is a quiet NaN. */
2790928368fSKristof Beyls HIDDEN double __math_invalid (double);
2800928368fSKristof Beyls
2810928368fSKristof Beyls /* Error handling using output checking, only for errno setting. */
2820928368fSKristof Beyls
2830928368fSKristof Beyls /* Check if the result overflowed to infinity. */
2840928368fSKristof Beyls HIDDEN double __math_check_oflow (double);
2850928368fSKristof Beyls /* Check if the result underflowed to 0. */
2860928368fSKristof Beyls HIDDEN double __math_check_uflow (double);
2870928368fSKristof Beyls
2880928368fSKristof Beyls /* Check if the result overflowed to infinity. */
2890928368fSKristof Beyls static inline double
check_oflow(double x)2900928368fSKristof Beyls check_oflow (double x)
2910928368fSKristof Beyls {
2920928368fSKristof Beyls return WANT_ERRNO ? __math_check_oflow (x) : x;
2930928368fSKristof Beyls }
2940928368fSKristof Beyls
2950928368fSKristof Beyls /* Check if the result underflowed to 0. */
2960928368fSKristof Beyls static inline double
check_uflow(double x)2970928368fSKristof Beyls check_uflow (double x)
2980928368fSKristof Beyls {
2990928368fSKristof Beyls return WANT_ERRNO ? __math_check_uflow (x) : x;
3000928368fSKristof Beyls }
3010928368fSKristof Beyls
3020928368fSKristof Beyls
3030928368fSKristof Beyls /* Shared between expf, exp2f and powf. */
3040928368fSKristof Beyls #define EXP2F_TABLE_BITS 5
3050928368fSKristof Beyls #define EXP2F_POLY_ORDER 3
3060928368fSKristof Beyls extern const struct exp2f_data
3070928368fSKristof Beyls {
3080928368fSKristof Beyls uint64_t tab[1 << EXP2F_TABLE_BITS];
3090928368fSKristof Beyls double shift_scaled;
3100928368fSKristof Beyls double poly[EXP2F_POLY_ORDER];
3110928368fSKristof Beyls double shift;
3120928368fSKristof Beyls double invln2_scaled;
3130928368fSKristof Beyls double poly_scaled[EXP2F_POLY_ORDER];
3140928368fSKristof Beyls } __exp2f_data HIDDEN;
3150928368fSKristof Beyls
3160928368fSKristof Beyls #define LOGF_TABLE_BITS 4
3170928368fSKristof Beyls #define LOGF_POLY_ORDER 4
3180928368fSKristof Beyls extern const struct logf_data
3190928368fSKristof Beyls {
3200928368fSKristof Beyls struct
3210928368fSKristof Beyls {
3220928368fSKristof Beyls double invc, logc;
3230928368fSKristof Beyls } tab[1 << LOGF_TABLE_BITS];
3240928368fSKristof Beyls double ln2;
3250928368fSKristof Beyls double poly[LOGF_POLY_ORDER - 1]; /* First order coefficient is 1. */
3260928368fSKristof Beyls } __logf_data HIDDEN;
3270928368fSKristof Beyls
3280928368fSKristof Beyls #define LOG2F_TABLE_BITS 4
3290928368fSKristof Beyls #define LOG2F_POLY_ORDER 4
3300928368fSKristof Beyls extern const struct log2f_data
3310928368fSKristof Beyls {
3320928368fSKristof Beyls struct
3330928368fSKristof Beyls {
3340928368fSKristof Beyls double invc, logc;
3350928368fSKristof Beyls } tab[1 << LOG2F_TABLE_BITS];
3360928368fSKristof Beyls double poly[LOG2F_POLY_ORDER];
3370928368fSKristof Beyls } __log2f_data HIDDEN;
3380928368fSKristof Beyls
3390928368fSKristof Beyls #define POWF_LOG2_TABLE_BITS 4
3400928368fSKristof Beyls #define POWF_LOG2_POLY_ORDER 5
3410928368fSKristof Beyls #if TOINT_INTRINSICS
3420928368fSKristof Beyls # define POWF_SCALE_BITS EXP2F_TABLE_BITS
3430928368fSKristof Beyls #else
3440928368fSKristof Beyls # define POWF_SCALE_BITS 0
3450928368fSKristof Beyls #endif
3460928368fSKristof Beyls #define POWF_SCALE ((double) (1 << POWF_SCALE_BITS))
3470928368fSKristof Beyls extern const struct powf_log2_data
3480928368fSKristof Beyls {
3490928368fSKristof Beyls struct
3500928368fSKristof Beyls {
3510928368fSKristof Beyls double invc, logc;
3520928368fSKristof Beyls } tab[1 << POWF_LOG2_TABLE_BITS];
3530928368fSKristof Beyls double poly[POWF_LOG2_POLY_ORDER];
3540928368fSKristof Beyls } __powf_log2_data HIDDEN;
3550928368fSKristof Beyls
3560928368fSKristof Beyls
3570928368fSKristof Beyls #define EXP_TABLE_BITS 7
3580928368fSKristof Beyls #define EXP_POLY_ORDER 5
3590928368fSKristof Beyls /* Use polynomial that is optimized for a wider input range. This may be
3600928368fSKristof Beyls needed for good precision in non-nearest rounding and !TOINT_INTRINSICS. */
3610928368fSKristof Beyls #define EXP_POLY_WIDE 0
3620928368fSKristof Beyls /* Use close to nearest rounding toint when !TOINT_INTRINSICS. This may be
363*0570de73SKazuaki Ishizaki needed for good precision in non-nearest rounding and !EXP_POLY_WIDE. */
3640928368fSKristof Beyls #define EXP_USE_TOINT_NARROW 0
3650928368fSKristof Beyls #define EXP2_POLY_ORDER 5
3660928368fSKristof Beyls #define EXP2_POLY_WIDE 0
3670928368fSKristof Beyls extern const struct exp_data
3680928368fSKristof Beyls {
3690928368fSKristof Beyls double invln2N;
3700928368fSKristof Beyls double shift;
3710928368fSKristof Beyls double negln2hiN;
3720928368fSKristof Beyls double negln2loN;
3730928368fSKristof Beyls double poly[4]; /* Last four coefficients. */
3740928368fSKristof Beyls double exp2_shift;
3750928368fSKristof Beyls double exp2_poly[EXP2_POLY_ORDER];
3760928368fSKristof Beyls uint64_t tab[2*(1 << EXP_TABLE_BITS)];
3770928368fSKristof Beyls } __exp_data HIDDEN;
3780928368fSKristof Beyls
3790928368fSKristof Beyls #define LOG_TABLE_BITS 7
3800928368fSKristof Beyls #define LOG_POLY_ORDER 6
3810928368fSKristof Beyls #define LOG_POLY1_ORDER 12
3820928368fSKristof Beyls extern const struct log_data
3830928368fSKristof Beyls {
3840928368fSKristof Beyls double ln2hi;
3850928368fSKristof Beyls double ln2lo;
3860928368fSKristof Beyls double poly[LOG_POLY_ORDER - 1]; /* First coefficient is 1. */
3870928368fSKristof Beyls double poly1[LOG_POLY1_ORDER - 1];
3880928368fSKristof Beyls struct {double invc, logc;} tab[1 << LOG_TABLE_BITS];
3890928368fSKristof Beyls #if !HAVE_FAST_FMA
3900928368fSKristof Beyls struct {double chi, clo;} tab2[1 << LOG_TABLE_BITS];
3910928368fSKristof Beyls #endif
3920928368fSKristof Beyls } __log_data HIDDEN;
3930928368fSKristof Beyls
3940928368fSKristof Beyls #define LOG2_TABLE_BITS 6
3950928368fSKristof Beyls #define LOG2_POLY_ORDER 7
3960928368fSKristof Beyls #define LOG2_POLY1_ORDER 11
3970928368fSKristof Beyls extern const struct log2_data
3980928368fSKristof Beyls {
3990928368fSKristof Beyls double invln2hi;
4000928368fSKristof Beyls double invln2lo;
4010928368fSKristof Beyls double poly[LOG2_POLY_ORDER - 1];
4020928368fSKristof Beyls double poly1[LOG2_POLY1_ORDER - 1];
4030928368fSKristof Beyls struct {double invc, logc;} tab[1 << LOG2_TABLE_BITS];
4040928368fSKristof Beyls #if !HAVE_FAST_FMA
4050928368fSKristof Beyls struct {double chi, clo;} tab2[1 << LOG2_TABLE_BITS];
4060928368fSKristof Beyls #endif
4070928368fSKristof Beyls } __log2_data HIDDEN;
4080928368fSKristof Beyls
4090928368fSKristof Beyls #define POW_LOG_TABLE_BITS 7
4100928368fSKristof Beyls #define POW_LOG_POLY_ORDER 8
4110928368fSKristof Beyls extern const struct pow_log_data
4120928368fSKristof Beyls {
4130928368fSKristof Beyls double ln2hi;
4140928368fSKristof Beyls double ln2lo;
4150928368fSKristof Beyls double poly[POW_LOG_POLY_ORDER - 1]; /* First coefficient is 1. */
4160928368fSKristof Beyls /* Note: the pad field is unused, but allows slightly faster indexing. */
4170928368fSKristof Beyls struct {double invc, pad, logc, logctail;} tab[1 << POW_LOG_TABLE_BITS];
4180928368fSKristof Beyls } __pow_log_data HIDDEN;
4190928368fSKristof Beyls
4200928368fSKristof Beyls #endif
421