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