diff options
Diffstat (limited to 'math/math_config.h')
-rw-r--r-- | math/math_config.h | 261 |
1 files changed, 252 insertions, 9 deletions
diff --git a/math/math_config.h b/math/math_config.h index faf77b31fc99..0fc653f93761 100644 --- a/math/math_config.h +++ b/math/math_config.h @@ -1,7 +1,7 @@ /* * Configuration for math routines. * - * Copyright (c) 2017-2023, Arm Limited. + * Copyright (c) 2017-2024, Arm Limited. * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception */ @@ -13,9 +13,9 @@ #ifndef WANT_ROUNDING /* If defined to 1, return correct results for special cases in non-nearest - rounding modes (logf (1.0f) returns 0.0f with FE_DOWNWARD rather than -0.0f). - This may be set to 0 if there is no fenv support or if math functions only - get called in round to nearest mode. */ + rounding modes (logf (1.0f) returns 0.0f with FE_DOWNWARD rather than + -0.0f). This may be set to 0 if there is no fenv support or if math + functions only get called in round to nearest mode. */ # define WANT_ROUNDING 1 #endif #ifndef WANT_ERRNO @@ -117,6 +117,25 @@ #define __math_check_oflowf arm_math_check_oflowf #define __math_check_uflowf arm_math_check_uflowf +#define __exp_data arm_math_exp_data +#define __asin_poly arm_math_asin_poly +#define __asinf_poly arm_math_asinf_poly +#define __asinh_data arm_math_asinh_data +#define __asinhf_data arm_math_asinhf_data +#define __atan_poly_data arm_math_atan_poly_data +#define __atanf_poly_data arm_math_atanf_poly_data +#define __cbrt_data arm_math_cbrt_data +#define __cbrtf_data arm_math_cbrtf_data +#define __erf_data arm_math_erf_data +#define __expf_data arm_math_expf_data +#define __expm1_poly arm_math_expm1_poly +#define __expm1f_poly arm_math_expm1f_poly +#define __log10_data arm_math_log10_data +#define __log1p_data arm_math_log1p_data +#define __log1pf_data arm_math_log1pf_data +#define __log_data arm_math_log_data +#define __tanf_poly_data arm_math_tanf_poly_data +#define __v_log_data arm_math_v_log_data #define __sincosf_table arm_math_sincosf_table #define __inv_pio4 arm_math_inv_pio4 #define __exp2f_data arm_math_exp2f_data @@ -131,6 +150,25 @@ #define __erf_data arm_math_erf_data #define __v_exp_data arm_math_v_exp_data #define __v_log_data arm_math_v_log_data +#define __v_erf_data arm_math_v_erf_data +#define __v_erfc_data arm_math_v_erfc_data +#define __v_erfcf_data arm_math_v_erfcf_data +#define __v_erff_data arm_math_v_erff_data +#define __v_exp_tail_data arm_math_v_exp_tail_data +#define __v_log10_data arm_math_v_log10_data +#define __v_log2_data arm_math_v_log2_data +#define __v_pow_exp_data arm_math_v_pow_exp_data +#define __v_pow_log_data arm_math_v_pow_log_data +#define __v_powf_data arm_math_v_powf_data + +/* On some platforms (in particular Windows) INFINITY and HUGE_VAL might + be defined in such a way that might not produce the expected bit pattern, + therefore we enforce the glibc math.h definition using a builtin that is + supported in both gcc and clang. */ +#if defined (_WIN32) && (defined (__GNUC__) || defined (__clang__)) +# undef INFINITY +# define INFINITY __builtin_inff() +#endif #if HAVE_FAST_ROUND /* When set, the roundtoint and converttoint functions are provided with @@ -365,11 +403,12 @@ extern const struct exp2f_data uint64_t tab[1 << EXP2F_TABLE_BITS]; double shift_scaled; double poly[EXP2F_POLY_ORDER]; - double shift; double invln2_scaled; double poly_scaled[EXP2F_POLY_ORDER]; + double shift; } __exp2f_data HIDDEN; +/* Data for logf and log10f. */ #define LOGF_TABLE_BITS 4 #define LOGF_POLY_ORDER 4 extern const struct logf_data @@ -379,6 +418,7 @@ extern const struct logf_data double invc, logc; } tab[1 << LOGF_TABLE_BITS]; double ln2; + double invln10; double poly[LOGF_POLY_ORDER - 1]; /* First order coefficient is 1. */ } __logf_data HIDDEN; @@ -427,17 +467,19 @@ extern const struct powf_log2_data extern const struct exp_data { double invln2N; - double invlog10_2N; - double shift; double negln2hiN; double negln2loN; - double neglog10_2hiN; - double neglog10_2loN; double poly[4]; /* Last four coefficients. */ + double shift; + double exp2_shift; double exp2_poly[EXP2_POLY_ORDER]; + + double neglog10_2hiN; + double neglog10_2loN; double exp10_poly[5]; uint64_t tab[2*(1 << EXP_TABLE_BITS)]; + double invlog10_2N; } __exp_data HIDDEN; #define LOG_TABLE_BITS 7 @@ -509,13 +551,214 @@ extern const struct erf_data #define V_EXP_TABLE_BITS 7 extern const uint64_t __v_exp_data[1 << V_EXP_TABLE_BITS] HIDDEN; +#define V_LOG_POLY_ORDER 6 #define V_LOG_TABLE_BITS 7 extern const struct v_log_data { + /* Shared data for vector log and log-derived routines (e.g. asinh). */ + double poly[V_LOG_POLY_ORDER - 1]; + double ln2; struct { double invc, logc; } table[1 << V_LOG_TABLE_BITS]; } __v_log_data HIDDEN; +/* Some data for SVE powf's internal exp and log. */ +#define V_POWF_EXP2_TABLE_BITS 5 +#define V_POWF_EXP2_N (1 << V_POWF_EXP2_TABLE_BITS) +#define V_POWF_LOG2_TABLE_BITS 5 +#define V_POWF_LOG2_N (1 << V_POWF_LOG2_TABLE_BITS) +extern const struct v_powf_data +{ + double invc[V_POWF_LOG2_N]; + double logc[V_POWF_LOG2_N]; + uint64_t scale[V_POWF_EXP2_N]; +} __v_powf_data HIDDEN; + +/* Some data for AdvSIMD and SVE pow's internal exp and log. */ +#define V_POW_EXP_TABLE_BITS 8 +extern const struct v_pow_exp_data +{ + double poly[3]; + double n_over_ln2, ln2_over_n_hi, ln2_over_n_lo, shift; + uint64_t sbits[1 << V_POW_EXP_TABLE_BITS]; +} __v_pow_exp_data HIDDEN; + +#define V_POW_LOG_TABLE_BITS 7 +extern const struct v_pow_log_data +{ + double poly[7]; /* First coefficient is 1. */ + double ln2_hi, ln2_lo; + double invc[1 << V_POW_LOG_TABLE_BITS]; + double logc[1 << V_POW_LOG_TABLE_BITS]; + double logctail[1 << V_POW_LOG_TABLE_BITS]; +} __v_pow_log_data HIDDEN; + +#define V_LOG2_TABLE_BITS 7 +extern const struct v_log2_data +{ + double poly[5]; + double invln2; + struct + { + double invc, log2c; + } table[1 << V_LOG2_TABLE_BITS]; +} __v_log2_data HIDDEN; + +#define V_LOG10_TABLE_BITS 7 +extern const struct v_log10_data +{ + double poly[5]; + double invln10, log10_2; + struct + { + double invc, log10c; + } table[1 << V_LOG10_TABLE_BITS]; +} __v_log10_data HIDDEN; + +#define V_EXP_TAIL_TABLE_BITS 8 +extern const uint64_t __v_exp_tail_data[1 << V_EXP_TAIL_TABLE_BITS] HIDDEN; + +extern const struct v_erff_data +{ + struct + { + float erf, scale; + } tab[513]; +} __v_erff_data HIDDEN; + +extern const struct v_erfcf_data +{ + struct + { + float erfc, scale; + } tab[645]; +} __v_erfcf_data HIDDEN; + +extern const struct v_erf_data +{ + struct + { + double erf, scale; + } tab[769]; +} __v_erf_data HIDDEN; + +extern const struct v_erfc_data +{ + struct + { + double erfc, scale; + } tab[3488]; +} __v_erfc_data HIDDEN; + +/* Table with 4/PI to 192 bit precision. */ +extern const uint32_t __inv_pio4[] HIDDEN; + +#if WANT_EXPERIMENTAL_MATH + +# define LOG1P_NCOEFFS 19 +extern const struct log1p_data +{ + double coeffs[LOG1P_NCOEFFS]; +} __log1p_data HIDDEN; + +# define LOG1PF_2U5 +# define LOG1PF_NCOEFFS 9 +extern const struct log1pf_data +{ + float coeffs[LOG1PF_NCOEFFS]; +} __log1pf_data HIDDEN; + +# define ASINF_POLY_ORDER 4 +extern const float __asinf_poly[ASINF_POLY_ORDER + 1] HIDDEN; + +# define ASIN_POLY_ORDER 11 +extern const double __asin_poly[ASIN_POLY_ORDER + 1] HIDDEN; + +# define ASINHF_NCOEFFS 8 +extern const struct asinhf_data +{ + float coeffs[ASINHF_NCOEFFS]; +} __asinhf_data HIDDEN; + +# define ASINH_NCOEFFS 18 +extern const struct asinh_data +{ + double poly[ASINH_NCOEFFS]; +} __asinh_data HIDDEN; + +# define ATAN_POLY_NCOEFFS 20 +extern const struct atan_poly_data +{ + double poly[ATAN_POLY_NCOEFFS]; +} __atan_poly_data HIDDEN; + +# define ATANF_POLY_NCOEFFS 8 +extern const struct atanf_poly_data +{ + float poly[ATANF_POLY_NCOEFFS]; +} __atanf_poly_data HIDDEN; + +extern const struct cbrtf_data +{ + float poly[4]; + float table[5]; +} __cbrtf_data HIDDEN; + +extern const struct cbrt_data +{ + double poly[4]; + double table[5]; +} __cbrt_data HIDDEN; + +# define EXPF_TABLE_BITS 5 +# define EXPF_POLY_ORDER 3 +extern const struct expf_data +{ + uint64_t tab[1 << EXPF_TABLE_BITS]; + double invln2_scaled; + double poly_scaled[EXPF_POLY_ORDER]; +} __expf_data HIDDEN; + +# define EXPM1F_POLY_ORDER 5 +extern const float __expm1f_poly[EXPM1F_POLY_ORDER] HIDDEN; + +# define EXPM1_POLY_ORDER 11 +extern const double __expm1_poly[EXPM1_POLY_ORDER] HIDDEN; + +/* Data for low accuracy log10 (with 1/ln(10) included in coefficients). */ +# define LOG10_TABLE_BITS 7 +# define LOG10_POLY_ORDER 6 +# define LOG10_POLY1_ORDER 12 +extern const struct log10_data +{ + double ln2hi; + double ln2lo; + double invln10; + double poly[LOG10_POLY_ORDER - 1]; /* First coefficient is 1/log(10). */ + double poly1[LOG10_POLY1_ORDER - 1]; + struct + { + double invc, logc; + } tab[1 << LOG10_TABLE_BITS]; +# if !HAVE_FAST_FMA + struct + { + double chi, clo; + } tab2[1 << LOG10_TABLE_BITS]; +# endif +} __log10_data HIDDEN; + +# define TANF_P_POLY_NCOEFFS 6 +/* cotan approach needs order 3 on [0, pi/4] to reach <3.5ulps. */ +# define TANF_Q_POLY_NCOEFFS 4 +extern const struct tanf_poly_data +{ + float poly_tan[TANF_P_POLY_NCOEFFS]; + float poly_cotan[TANF_Q_POLY_NCOEFFS]; +} __tanf_poly_data HIDDEN; + +#endif /* WANT_EXPERIMENTAL_MATH. */ + #endif |