1 /* 2 * ==================================================== 3 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 4 * 5 * Developed at SunPro, a Sun Microsystems, Inc. business. 6 * Permission to use, copy, modify, and distribute this 7 * software is freely granted, provided that this notice 8 * is preserved. 9 * ==================================================== 10 */ 11 12 /* 13 * from: @(#)fdlibm.h 5.1 93/09/24 14 * $FreeBSD$ 15 */ 16 17 #ifndef _MATH_PRIVATE_H_ 18 #define _MATH_PRIVATE_H_ 19 20 #include <sys/types.h> 21 #include <machine/endian.h> 22 23 /* 24 * The original fdlibm code used statements like: 25 * n0 = ((*(int*)&one)>>29)^1; * index of high word * 26 * ix0 = *(n0+(int*)&x); * high word of x * 27 * ix1 = *((1-n0)+(int*)&x); * low word of x * 28 * to dig two 32 bit words out of the 64 bit IEEE floating point 29 * value. That is non-ANSI, and, moreover, the gcc instruction 30 * scheduler gets it wrong. We instead use the following macros. 31 * Unlike the original code, we determine the endianness at compile 32 * time, not at run time; I don't see much benefit to selecting 33 * endianness at run time. 34 */ 35 36 /* 37 * A union which permits us to convert between a double and two 32 bit 38 * ints. 39 */ 40 41 #ifdef __arm__ 42 #if defined(__VFP_FP__) || defined(__ARM_EABI__) 43 #define IEEE_WORD_ORDER BYTE_ORDER 44 #else 45 #define IEEE_WORD_ORDER BIG_ENDIAN 46 #endif 47 #else /* __arm__ */ 48 #define IEEE_WORD_ORDER BYTE_ORDER 49 #endif 50 51 #if IEEE_WORD_ORDER == BIG_ENDIAN 52 53 typedef union 54 { 55 double value; 56 struct 57 { 58 u_int32_t msw; 59 u_int32_t lsw; 60 } parts; 61 struct 62 { 63 u_int64_t w; 64 } xparts; 65 } ieee_double_shape_type; 66 67 #endif 68 69 #if IEEE_WORD_ORDER == LITTLE_ENDIAN 70 71 typedef union 72 { 73 double value; 74 struct 75 { 76 u_int32_t lsw; 77 u_int32_t msw; 78 } parts; 79 struct 80 { 81 u_int64_t w; 82 } xparts; 83 } ieee_double_shape_type; 84 85 #endif 86 87 /* Get two 32 bit ints from a double. */ 88 89 #define EXTRACT_WORDS(ix0,ix1,d) \ 90 do { \ 91 ieee_double_shape_type ew_u; \ 92 ew_u.value = (d); \ 93 (ix0) = ew_u.parts.msw; \ 94 (ix1) = ew_u.parts.lsw; \ 95 } while (0) 96 97 /* Get a 64-bit int from a double. */ 98 #define EXTRACT_WORD64(ix,d) \ 99 do { \ 100 ieee_double_shape_type ew_u; \ 101 ew_u.value = (d); \ 102 (ix) = ew_u.xparts.w; \ 103 } while (0) 104 105 /* Get the more significant 32 bit int from a double. */ 106 107 #define GET_HIGH_WORD(i,d) \ 108 do { \ 109 ieee_double_shape_type gh_u; \ 110 gh_u.value = (d); \ 111 (i) = gh_u.parts.msw; \ 112 } while (0) 113 114 /* Get the less significant 32 bit int from a double. */ 115 116 #define GET_LOW_WORD(i,d) \ 117 do { \ 118 ieee_double_shape_type gl_u; \ 119 gl_u.value = (d); \ 120 (i) = gl_u.parts.lsw; \ 121 } while (0) 122 123 /* Set a double from two 32 bit ints. */ 124 125 #define INSERT_WORDS(d,ix0,ix1) \ 126 do { \ 127 ieee_double_shape_type iw_u; \ 128 iw_u.parts.msw = (ix0); \ 129 iw_u.parts.lsw = (ix1); \ 130 (d) = iw_u.value; \ 131 } while (0) 132 133 /* Set a double from a 64-bit int. */ 134 #define INSERT_WORD64(d,ix) \ 135 do { \ 136 ieee_double_shape_type iw_u; \ 137 iw_u.xparts.w = (ix); \ 138 (d) = iw_u.value; \ 139 } while (0) 140 141 /* Set the more significant 32 bits of a double from an int. */ 142 143 #define SET_HIGH_WORD(d,v) \ 144 do { \ 145 ieee_double_shape_type sh_u; \ 146 sh_u.value = (d); \ 147 sh_u.parts.msw = (v); \ 148 (d) = sh_u.value; \ 149 } while (0) 150 151 /* Set the less significant 32 bits of a double from an int. */ 152 153 #define SET_LOW_WORD(d,v) \ 154 do { \ 155 ieee_double_shape_type sl_u; \ 156 sl_u.value = (d); \ 157 sl_u.parts.lsw = (v); \ 158 (d) = sl_u.value; \ 159 } while (0) 160 161 /* 162 * A union which permits us to convert between a float and a 32 bit 163 * int. 164 */ 165 166 typedef union 167 { 168 float value; 169 /* FIXME: Assumes 32 bit int. */ 170 unsigned int word; 171 } ieee_float_shape_type; 172 173 /* Get a 32 bit int from a float. */ 174 175 #define GET_FLOAT_WORD(i,d) \ 176 do { \ 177 ieee_float_shape_type gf_u; \ 178 gf_u.value = (d); \ 179 (i) = gf_u.word; \ 180 } while (0) 181 182 /* Set a float from a 32 bit int. */ 183 184 #define SET_FLOAT_WORD(d,i) \ 185 do { \ 186 ieee_float_shape_type sf_u; \ 187 sf_u.word = (i); \ 188 (d) = sf_u.value; \ 189 } while (0) 190 191 /* 192 * Get expsign and mantissa as 16 bit and 64 bit ints from an 80 bit long 193 * double. 194 */ 195 196 #define EXTRACT_LDBL80_WORDS(ix0,ix1,d) \ 197 do { \ 198 union IEEEl2bits ew_u; \ 199 ew_u.e = (d); \ 200 (ix0) = ew_u.xbits.expsign; \ 201 (ix1) = ew_u.xbits.man; \ 202 } while (0) 203 204 /* 205 * Get expsign and mantissa as one 16 bit and two 64 bit ints from a 128 bit 206 * long double. 207 */ 208 209 #define EXTRACT_LDBL128_WORDS(ix0,ix1,ix2,d) \ 210 do { \ 211 union IEEEl2bits ew_u; \ 212 ew_u.e = (d); \ 213 (ix0) = ew_u.xbits.expsign; \ 214 (ix1) = ew_u.xbits.manh; \ 215 (ix2) = ew_u.xbits.manl; \ 216 } while (0) 217 218 /* Get expsign as a 16 bit int from a long double. */ 219 220 #define GET_LDBL_EXPSIGN(i,d) \ 221 do { \ 222 union IEEEl2bits ge_u; \ 223 ge_u.e = (d); \ 224 (i) = ge_u.xbits.expsign; \ 225 } while (0) 226 227 /* 228 * Set an 80 bit long double from a 16 bit int expsign and a 64 bit int 229 * mantissa. 230 */ 231 232 #define INSERT_LDBL80_WORDS(d,ix0,ix1) \ 233 do { \ 234 union IEEEl2bits iw_u; \ 235 iw_u.xbits.expsign = (ix0); \ 236 iw_u.xbits.man = (ix1); \ 237 (d) = iw_u.e; \ 238 } while (0) 239 240 /* 241 * Set a 128 bit long double from a 16 bit int expsign and two 64 bit ints 242 * comprising the mantissa. 243 */ 244 245 #define INSERT_LDBL128_WORDS(d,ix0,ix1,ix2) \ 246 do { \ 247 union IEEEl2bits iw_u; \ 248 iw_u.xbits.expsign = (ix0); \ 249 iw_u.xbits.manh = (ix1); \ 250 iw_u.xbits.manl = (ix2); \ 251 (d) = iw_u.e; \ 252 } while (0) 253 254 /* Set expsign of a long double from a 16 bit int. */ 255 256 #define SET_LDBL_EXPSIGN(d,v) \ 257 do { \ 258 union IEEEl2bits se_u; \ 259 se_u.e = (d); \ 260 se_u.xbits.expsign = (v); \ 261 (d) = se_u.e; \ 262 } while (0) 263 264 #ifdef __i386__ 265 /* Long double constants are broken on i386. */ 266 #define LD80C(m, ex, v) { \ 267 .xbits.man = __CONCAT(m, ULL), \ 268 .xbits.expsign = (0x3fff + (ex)) | ((v) < 0 ? 0x8000 : 0), \ 269 } 270 #else 271 /* The above works on non-i386 too, but we use this to check v. */ 272 #define LD80C(m, ex, v) { .e = (v), } 273 #endif 274 275 #ifdef FLT_EVAL_METHOD 276 /* 277 * Attempt to get strict C99 semantics for assignment with non-C99 compilers. 278 */ 279 #if FLT_EVAL_METHOD == 0 || __GNUC__ == 0 280 #define STRICT_ASSIGN(type, lval, rval) ((lval) = (rval)) 281 #else 282 #define STRICT_ASSIGN(type, lval, rval) do { \ 283 volatile type __lval; \ 284 \ 285 if (sizeof(type) >= sizeof(long double)) \ 286 (lval) = (rval); \ 287 else { \ 288 __lval = (rval); \ 289 (lval) = __lval; \ 290 } \ 291 } while (0) 292 #endif 293 #endif /* FLT_EVAL_METHOD */ 294 295 /* Support switching the mode to FP_PE if necessary. */ 296 #if defined(__i386__) && !defined(NO_FPSETPREC) 297 #define ENTERI() \ 298 long double __retval; \ 299 fp_prec_t __oprec; \ 300 \ 301 if ((__oprec = fpgetprec()) != FP_PE) \ 302 fpsetprec(FP_PE) 303 #define RETURNI(x) do { \ 304 __retval = (x); \ 305 if (__oprec != FP_PE) \ 306 fpsetprec(__oprec); \ 307 RETURNF(__retval); \ 308 } while (0) 309 #define ENTERV() \ 310 fp_prec_t __oprec; \ 311 \ 312 if ((__oprec = fpgetprec()) != FP_PE) \ 313 fpsetprec(FP_PE) 314 #define RETURNV() do { \ 315 if (__oprec != FP_PE) \ 316 fpsetprec(__oprec); \ 317 return; \ 318 } while (0) 319 #else 320 #define ENTERI() 321 #define RETURNI(x) RETURNF(x) 322 #define ENTERV() 323 #define RETURNV() return 324 #endif 325 326 /* Default return statement if hack*_t() is not used. */ 327 #define RETURNF(v) return (v) 328 329 /* 330 * 2sum gives the same result as 2sumF without requiring |a| >= |b| or 331 * a == 0, but is slower. 332 */ 333 #define _2sum(a, b) do { \ 334 __typeof(a) __s, __w; \ 335 \ 336 __w = (a) + (b); \ 337 __s = __w - (a); \ 338 (b) = ((a) - (__w - __s)) + ((b) - __s); \ 339 (a) = __w; \ 340 } while (0) 341 342 /* 343 * 2sumF algorithm. 344 * 345 * "Normalize" the terms in the infinite-precision expression a + b for 346 * the sum of 2 floating point values so that b is as small as possible 347 * relative to 'a'. (The resulting 'a' is the value of the expression in 348 * the same precision as 'a' and the resulting b is the rounding error.) 349 * |a| must be >= |b| or 0, b's type must be no larger than 'a's type, and 350 * exponent overflow or underflow must not occur. This uses a Theorem of 351 * Dekker (1971). See Knuth (1981) 4.2.2 Theorem C. The name "TwoSum" 352 * is apparently due to Skewchuk (1997). 353 * 354 * For this to always work, assignment of a + b to 'a' must not retain any 355 * extra precision in a + b. This is required by C standards but broken 356 * in many compilers. The brokenness cannot be worked around using 357 * STRICT_ASSIGN() like we do elsewhere, since the efficiency of this 358 * algorithm would be destroyed by non-null strict assignments. (The 359 * compilers are correct to be broken -- the efficiency of all floating 360 * point code calculations would be destroyed similarly if they forced the 361 * conversions.) 362 * 363 * Fortunately, a case that works well can usually be arranged by building 364 * any extra precision into the type of 'a' -- 'a' should have type float_t, 365 * double_t or long double. b's type should be no larger than 'a's type. 366 * Callers should use these types with scopes as large as possible, to 367 * reduce their own extra-precision and efficiciency problems. In 368 * particular, they shouldn't convert back and forth just to call here. 369 */ 370 #ifdef DEBUG 371 #define _2sumF(a, b) do { \ 372 __typeof(a) __w; \ 373 volatile __typeof(a) __ia, __ib, __r, __vw; \ 374 \ 375 __ia = (a); \ 376 __ib = (b); \ 377 assert(__ia == 0 || fabsl(__ia) >= fabsl(__ib)); \ 378 \ 379 __w = (a) + (b); \ 380 (b) = ((a) - __w) + (b); \ 381 (a) = __w; \ 382 \ 383 /* The next 2 assertions are weak if (a) is already long double. */ \ 384 assert((long double)__ia + __ib == (long double)(a) + (b)); \ 385 __vw = __ia + __ib; \ 386 __r = __ia - __vw; \ 387 __r += __ib; \ 388 assert(__vw == (a) && __r == (b)); \ 389 } while (0) 390 #else /* !DEBUG */ 391 #define _2sumF(a, b) do { \ 392 __typeof(a) __w; \ 393 \ 394 __w = (a) + (b); \ 395 (b) = ((a) - __w) + (b); \ 396 (a) = __w; \ 397 } while (0) 398 #endif /* DEBUG */ 399 400 /* 401 * Set x += c, where x is represented in extra precision as a + b. 402 * x must be sufficiently normalized and sufficiently larger than c, 403 * and the result is then sufficiently normalized. 404 * 405 * The details of ordering are that |a| must be >= |c| (so that (a, c) 406 * can be normalized without extra work to swap 'a' with c). The details of 407 * the normalization are that b must be small relative to the normalized 'a'. 408 * Normalization of (a, c) makes the normalized c tiny relative to the 409 * normalized a, so b remains small relative to 'a' in the result. However, 410 * b need not ever be tiny relative to 'a'. For example, b might be about 411 * 2**20 times smaller than 'a' to give about 20 extra bits of precision. 412 * That is usually enough, and adding c (which by normalization is about 413 * 2**53 times smaller than a) cannot change b significantly. However, 414 * cancellation of 'a' with c in normalization of (a, c) may reduce 'a' 415 * significantly relative to b. The caller must ensure that significant 416 * cancellation doesn't occur, either by having c of the same sign as 'a', 417 * or by having |c| a few percent smaller than |a|. Pre-normalization of 418 * (a, b) may help. 419 * 420 * This is is a variant of an algorithm of Kahan (see Knuth (1981) 4.2.2 421 * exercise 19). We gain considerable efficiency by requiring the terms to 422 * be sufficiently normalized and sufficiently increasing. 423 */ 424 #define _3sumF(a, b, c) do { \ 425 __typeof(a) __tmp; \ 426 \ 427 __tmp = (c); \ 428 _2sumF(__tmp, (a)); \ 429 (b) += (a); \ 430 (a) = __tmp; \ 431 } while (0) 432 433 /* 434 * Common routine to process the arguments to nan(), nanf(), and nanl(). 435 */ 436 void _scan_nan(uint32_t *__words, int __num_words, const char *__s); 437 438 #ifdef _COMPLEX_H 439 440 /* 441 * C99 specifies that complex numbers have the same representation as 442 * an array of two elements, where the first element is the real part 443 * and the second element is the imaginary part. 444 */ 445 typedef union { 446 float complex f; 447 float a[2]; 448 } float_complex; 449 typedef union { 450 double complex f; 451 double a[2]; 452 } double_complex; 453 typedef union { 454 long double complex f; 455 long double a[2]; 456 } long_double_complex; 457 #define REALPART(z) ((z).a[0]) 458 #define IMAGPART(z) ((z).a[1]) 459 460 /* 461 * Inline functions that can be used to construct complex values. 462 * 463 * The C99 standard intends x+I*y to be used for this, but x+I*y is 464 * currently unusable in general since gcc introduces many overflow, 465 * underflow, sign and efficiency bugs by rewriting I*y as 466 * (0.0+I)*(y+0.0*I) and laboriously computing the full complex product. 467 * In particular, I*Inf is corrupted to NaN+I*Inf, and I*-0 is corrupted 468 * to -0.0+I*0.0. 469 * 470 * The C11 standard introduced the macros CMPLX(), CMPLXF() and CMPLXL() 471 * to construct complex values. Compilers that conform to the C99 472 * standard require the following functions to avoid the above issues. 473 */ 474 475 #ifndef CMPLXF 476 static __inline float complex 477 CMPLXF(float x, float y) 478 { 479 float_complex z; 480 481 REALPART(z) = x; 482 IMAGPART(z) = y; 483 return (z.f); 484 } 485 #endif 486 487 #ifndef CMPLX 488 static __inline double complex 489 CMPLX(double x, double y) 490 { 491 double_complex z; 492 493 REALPART(z) = x; 494 IMAGPART(z) = y; 495 return (z.f); 496 } 497 #endif 498 499 #ifndef CMPLXL 500 static __inline long double complex 501 CMPLXL(long double x, long double y) 502 { 503 long_double_complex z; 504 505 REALPART(z) = x; 506 IMAGPART(z) = y; 507 return (z.f); 508 } 509 #endif 510 511 #endif /* _COMPLEX_H */ 512 513 #ifdef __GNUCLIKE_ASM 514 515 /* Asm versions of some functions. */ 516 517 #ifdef __amd64__ 518 static __inline int 519 irint(double x) 520 { 521 int n; 522 523 asm("cvtsd2si %1,%0" : "=r" (n) : "x" (x)); 524 return (n); 525 } 526 #define HAVE_EFFICIENT_IRINT 527 #endif 528 529 #ifdef __i386__ 530 static __inline int 531 irint(double x) 532 { 533 int n; 534 535 asm("fistl %0" : "=m" (n) : "t" (x)); 536 return (n); 537 } 538 #define HAVE_EFFICIENT_IRINT 539 #endif 540 541 #if defined(__amd64__) || defined(__i386__) 542 static __inline int 543 irintl(long double x) 544 { 545 int n; 546 547 asm("fistl %0" : "=m" (n) : "t" (x)); 548 return (n); 549 } 550 #define HAVE_EFFICIENT_IRINTL 551 #endif 552 553 #endif /* __GNUCLIKE_ASM */ 554 555 #ifdef DEBUG 556 #if defined(__amd64__) || defined(__i386__) 557 #define breakpoint() asm("int $3") 558 #else 559 #include <signal.h> 560 561 #define breakpoint() raise(SIGTRAP) 562 #endif 563 #endif 564 565 /* Write a pari script to test things externally. */ 566 #ifdef DOPRINT 567 #include <stdio.h> 568 569 #ifndef DOPRINT_SWIZZLE 570 #define DOPRINT_SWIZZLE 0 571 #endif 572 573 #ifdef DOPRINT_LD80 574 575 #define DOPRINT_START(xp) do { \ 576 uint64_t __lx; \ 577 uint16_t __hx; \ 578 \ 579 /* Hack to give more-problematic args. */ \ 580 EXTRACT_LDBL80_WORDS(__hx, __lx, *xp); \ 581 __lx ^= DOPRINT_SWIZZLE; \ 582 INSERT_LDBL80_WORDS(*xp, __hx, __lx); \ 583 printf("x = %.21Lg; ", (long double)*xp); \ 584 } while (0) 585 #define DOPRINT_END1(v) \ 586 printf("y = %.21Lg; z = 0; show(x, y, z);\n", (long double)(v)) 587 #define DOPRINT_END2(hi, lo) \ 588 printf("y = %.21Lg; z = %.21Lg; show(x, y, z);\n", \ 589 (long double)(hi), (long double)(lo)) 590 591 #elif defined(DOPRINT_D64) 592 593 #define DOPRINT_START(xp) do { \ 594 uint32_t __hx, __lx; \ 595 \ 596 EXTRACT_WORDS(__hx, __lx, *xp); \ 597 __lx ^= DOPRINT_SWIZZLE; \ 598 INSERT_WORDS(*xp, __hx, __lx); \ 599 printf("x = %.21Lg; ", (long double)*xp); \ 600 } while (0) 601 #define DOPRINT_END1(v) \ 602 printf("y = %.21Lg; z = 0; show(x, y, z);\n", (long double)(v)) 603 #define DOPRINT_END2(hi, lo) \ 604 printf("y = %.21Lg; z = %.21Lg; show(x, y, z);\n", \ 605 (long double)(hi), (long double)(lo)) 606 607 #elif defined(DOPRINT_F32) 608 609 #define DOPRINT_START(xp) do { \ 610 uint32_t __hx; \ 611 \ 612 GET_FLOAT_WORD(__hx, *xp); \ 613 __hx ^= DOPRINT_SWIZZLE; \ 614 SET_FLOAT_WORD(*xp, __hx); \ 615 printf("x = %.21Lg; ", (long double)*xp); \ 616 } while (0) 617 #define DOPRINT_END1(v) \ 618 printf("y = %.21Lg; z = 0; show(x, y, z);\n", (long double)(v)) 619 #define DOPRINT_END2(hi, lo) \ 620 printf("y = %.21Lg; z = %.21Lg; show(x, y, z);\n", \ 621 (long double)(hi), (long double)(lo)) 622 623 #else /* !DOPRINT_LD80 && !DOPRINT_D64 (LD128 only) */ 624 625 #ifndef DOPRINT_SWIZZLE_HIGH 626 #define DOPRINT_SWIZZLE_HIGH 0 627 #endif 628 629 #define DOPRINT_START(xp) do { \ 630 uint64_t __lx, __llx; \ 631 uint16_t __hx; \ 632 \ 633 EXTRACT_LDBL128_WORDS(__hx, __lx, __llx, *xp); \ 634 __llx ^= DOPRINT_SWIZZLE; \ 635 __lx ^= DOPRINT_SWIZZLE_HIGH; \ 636 INSERT_LDBL128_WORDS(*xp, __hx, __lx, __llx); \ 637 printf("x = %.36Lg; ", (long double)*xp); \ 638 } while (0) 639 #define DOPRINT_END1(v) \ 640 printf("y = %.36Lg; z = 0; show(x, y, z);\n", (long double)(v)) 641 #define DOPRINT_END2(hi, lo) \ 642 printf("y = %.36Lg; z = %.36Lg; show(x, y, z);\n", \ 643 (long double)(hi), (long double)(lo)) 644 645 #endif /* DOPRINT_LD80 */ 646 647 #else /* !DOPRINT */ 648 #define DOPRINT_START(xp) 649 #define DOPRINT_END1(v) 650 #define DOPRINT_END2(hi, lo) 651 #endif /* DOPRINT */ 652 653 #define RETURNP(x) do { \ 654 DOPRINT_END1(x); \ 655 RETURNF(x); \ 656 } while (0) 657 #define RETURNPI(x) do { \ 658 DOPRINT_END1(x); \ 659 RETURNI(x); \ 660 } while (0) 661 #define RETURN2P(x, y) do { \ 662 DOPRINT_END2((x), (y)); \ 663 RETURNF((x) + (y)); \ 664 } while (0) 665 #define RETURN2PI(x, y) do { \ 666 DOPRINT_END2((x), (y)); \ 667 RETURNI((x) + (y)); \ 668 } while (0) 669 #ifdef STRUCT_RETURN 670 #define RETURNSP(rp) do { \ 671 if (!(rp)->lo_set) \ 672 RETURNP((rp)->hi); \ 673 RETURN2P((rp)->hi, (rp)->lo); \ 674 } while (0) 675 #define RETURNSPI(rp) do { \ 676 if (!(rp)->lo_set) \ 677 RETURNPI((rp)->hi); \ 678 RETURN2PI((rp)->hi, (rp)->lo); \ 679 } while (0) 680 #endif 681 #define SUM2P(x, y) ({ \ 682 const __typeof (x) __x = (x); \ 683 const __typeof (y) __y = (y); \ 684 \ 685 DOPRINT_END2(__x, __y); \ 686 __x + __y; \ 687 }) 688 689 /* 690 * ieee style elementary functions 691 * 692 * We rename functions here to improve other sources' diffability 693 * against fdlibm. 694 */ 695 #define __ieee754_sqrt sqrt 696 #define __ieee754_acos acos 697 #define __ieee754_acosh acosh 698 #define __ieee754_log log 699 #define __ieee754_log2 log2 700 #define __ieee754_atanh atanh 701 #define __ieee754_asin asin 702 #define __ieee754_atan2 atan2 703 #define __ieee754_exp exp 704 #define __ieee754_cosh cosh 705 #define __ieee754_fmod fmod 706 #define __ieee754_pow pow 707 #define __ieee754_lgamma lgamma 708 #define __ieee754_gamma gamma 709 #define __ieee754_lgamma_r lgamma_r 710 #define __ieee754_gamma_r gamma_r 711 #define __ieee754_log10 log10 712 #define __ieee754_sinh sinh 713 #define __ieee754_hypot hypot 714 #define __ieee754_j0 j0 715 #define __ieee754_j1 j1 716 #define __ieee754_y0 y0 717 #define __ieee754_y1 y1 718 #define __ieee754_jn jn 719 #define __ieee754_yn yn 720 #define __ieee754_remainder remainder 721 #define __ieee754_scalb scalb 722 #define __ieee754_sqrtf sqrtf 723 #define __ieee754_acosf acosf 724 #define __ieee754_acoshf acoshf 725 #define __ieee754_logf logf 726 #define __ieee754_atanhf atanhf 727 #define __ieee754_asinf asinf 728 #define __ieee754_atan2f atan2f 729 #define __ieee754_expf expf 730 #define __ieee754_coshf coshf 731 #define __ieee754_fmodf fmodf 732 #define __ieee754_powf powf 733 #define __ieee754_lgammaf lgammaf 734 #define __ieee754_gammaf gammaf 735 #define __ieee754_lgammaf_r lgammaf_r 736 #define __ieee754_gammaf_r gammaf_r 737 #define __ieee754_log10f log10f 738 #define __ieee754_log2f log2f 739 #define __ieee754_sinhf sinhf 740 #define __ieee754_hypotf hypotf 741 #define __ieee754_j0f j0f 742 #define __ieee754_j1f j1f 743 #define __ieee754_y0f y0f 744 #define __ieee754_y1f y1f 745 #define __ieee754_jnf jnf 746 #define __ieee754_ynf ynf 747 #define __ieee754_remainderf remainderf 748 #define __ieee754_scalbf scalbf 749 750 /* fdlibm kernel function */ 751 int __kernel_rem_pio2(double*,double*,int,int,int); 752 753 /* double precision kernel functions */ 754 #ifndef INLINE_REM_PIO2 755 int __ieee754_rem_pio2(double,double*); 756 #endif 757 double __kernel_sin(double,double,int); 758 double __kernel_cos(double,double); 759 double __kernel_tan(double,double,int); 760 double __ldexp_exp(double,int); 761 #ifdef _COMPLEX_H 762 double complex __ldexp_cexp(double complex,int); 763 #endif 764 765 /* float precision kernel functions */ 766 #ifndef INLINE_REM_PIO2F 767 int __ieee754_rem_pio2f(float,double*); 768 #endif 769 #ifndef INLINE_KERNEL_SINDF 770 float __kernel_sindf(double); 771 #endif 772 #ifndef INLINE_KERNEL_COSDF 773 float __kernel_cosdf(double); 774 #endif 775 #ifndef INLINE_KERNEL_TANDF 776 float __kernel_tandf(double,int); 777 #endif 778 float __ldexp_expf(float,int); 779 #ifdef _COMPLEX_H 780 float complex __ldexp_cexpf(float complex,int); 781 #endif 782 783 /* long double precision kernel functions */ 784 long double __kernel_sinl(long double, long double, int); 785 long double __kernel_cosl(long double, long double); 786 long double __kernel_tanl(long double, long double, int); 787 788 #endif /* !_MATH_PRIVATE_H_ */ 789