13a8617a8SJordan K. Hubbard /* 23a8617a8SJordan K. Hubbard * ==================================================== 33a8617a8SJordan K. Hubbard * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 43a8617a8SJordan K. Hubbard * 53a8617a8SJordan K. Hubbard * Developed at SunPro, a Sun Microsystems, Inc. business. 63a8617a8SJordan K. Hubbard * Permission to use, copy, modify, and distribute this 73a8617a8SJordan K. Hubbard * software is freely granted, provided that this notice 83a8617a8SJordan K. Hubbard * is preserved. 93a8617a8SJordan K. Hubbard * ==================================================== 103a8617a8SJordan K. Hubbard */ 113a8617a8SJordan K. Hubbard 123a8617a8SJordan K. Hubbard /* 133a8617a8SJordan K. Hubbard * from: @(#)fdlibm.h 5.1 93/09/24 147f3dea24SPeter Wemm * $FreeBSD$ 153a8617a8SJordan K. Hubbard */ 163a8617a8SJordan K. Hubbard 173a8617a8SJordan K. Hubbard #ifndef _MATH_PRIVATE_H_ 183a8617a8SJordan K. Hubbard #define _MATH_PRIVATE_H_ 193a8617a8SJordan K. Hubbard 203a8617a8SJordan K. Hubbard #include <sys/types.h> 21bcfa1759SBrian Somers #include <machine/endian.h> 223a8617a8SJordan K. Hubbard 23ef1ee63eSAlexey Zelkin /* 24ef1ee63eSAlexey Zelkin * The original fdlibm code used statements like: 25ef1ee63eSAlexey Zelkin * n0 = ((*(int*)&one)>>29)^1; * index of high word * 26ef1ee63eSAlexey Zelkin * ix0 = *(n0+(int*)&x); * high word of x * 27ef1ee63eSAlexey Zelkin * ix1 = *((1-n0)+(int*)&x); * low word of x * 28ef1ee63eSAlexey Zelkin * to dig two 32 bit words out of the 64 bit IEEE floating point 29ef1ee63eSAlexey Zelkin * value. That is non-ANSI, and, moreover, the gcc instruction 30ef1ee63eSAlexey Zelkin * scheduler gets it wrong. We instead use the following macros. 31ef1ee63eSAlexey Zelkin * Unlike the original code, we determine the endianness at compile 32ef1ee63eSAlexey Zelkin * time, not at run time; I don't see much benefit to selecting 33ef1ee63eSAlexey Zelkin * endianness at run time. 34ef1ee63eSAlexey Zelkin */ 353a8617a8SJordan K. Hubbard 36ef1ee63eSAlexey Zelkin /* 37ef1ee63eSAlexey Zelkin * A union which permits us to convert between a double and two 32 bit 38ef1ee63eSAlexey Zelkin * ints. 39ef1ee63eSAlexey Zelkin */ 403a8617a8SJordan K. Hubbard 4174aed985SMarcel Moolenaar #ifdef __arm__ 420a10f22aSAndrew Turner #if defined(__VFP_FP__) || defined(__ARM_EABI__) 4374aed985SMarcel Moolenaar #define IEEE_WORD_ORDER BYTE_ORDER 4474aed985SMarcel Moolenaar #else 4574aed985SMarcel Moolenaar #define IEEE_WORD_ORDER BIG_ENDIAN 4674aed985SMarcel Moolenaar #endif 4774aed985SMarcel Moolenaar #else /* __arm__ */ 4874aed985SMarcel Moolenaar #define IEEE_WORD_ORDER BYTE_ORDER 4974aed985SMarcel Moolenaar #endif 5074aed985SMarcel Moolenaar 516813d08fSMatt Macy /* A union which permits us to convert between a long double and 526813d08fSMatt Macy four 32 bit ints. */ 536813d08fSMatt Macy 546813d08fSMatt Macy #if IEEE_WORD_ORDER == BIG_ENDIAN 556813d08fSMatt Macy 566813d08fSMatt Macy typedef union 576813d08fSMatt Macy { 586813d08fSMatt Macy long double value; 596813d08fSMatt Macy struct { 606813d08fSMatt Macy u_int32_t mswhi; 616813d08fSMatt Macy u_int32_t mswlo; 626813d08fSMatt Macy u_int32_t lswhi; 636813d08fSMatt Macy u_int32_t lswlo; 646813d08fSMatt Macy } parts32; 656813d08fSMatt Macy struct { 666813d08fSMatt Macy u_int64_t msw; 676813d08fSMatt Macy u_int64_t lsw; 686813d08fSMatt Macy } parts64; 696813d08fSMatt Macy } ieee_quad_shape_type; 706813d08fSMatt Macy 716813d08fSMatt Macy #endif 726813d08fSMatt Macy 736813d08fSMatt Macy #if IEEE_WORD_ORDER == LITTLE_ENDIAN 746813d08fSMatt Macy 756813d08fSMatt Macy typedef union 766813d08fSMatt Macy { 776813d08fSMatt Macy long double value; 786813d08fSMatt Macy struct { 796813d08fSMatt Macy u_int32_t lswlo; 806813d08fSMatt Macy u_int32_t lswhi; 816813d08fSMatt Macy u_int32_t mswlo; 826813d08fSMatt Macy u_int32_t mswhi; 836813d08fSMatt Macy } parts32; 846813d08fSMatt Macy struct { 856813d08fSMatt Macy u_int64_t lsw; 866813d08fSMatt Macy u_int64_t msw; 876813d08fSMatt Macy } parts64; 886813d08fSMatt Macy } ieee_quad_shape_type; 896813d08fSMatt Macy 906813d08fSMatt Macy #endif 916813d08fSMatt Macy 9274aed985SMarcel Moolenaar #if IEEE_WORD_ORDER == BIG_ENDIAN 933a8617a8SJordan K. Hubbard 943a8617a8SJordan K. Hubbard typedef union 953a8617a8SJordan K. Hubbard { 963a8617a8SJordan K. Hubbard double value; 973a8617a8SJordan K. Hubbard struct 983a8617a8SJordan K. Hubbard { 993a8617a8SJordan K. Hubbard u_int32_t msw; 1003a8617a8SJordan K. Hubbard u_int32_t lsw; 1013a8617a8SJordan K. Hubbard } parts; 1023d4dfde4SDavid Schultz struct 1033d4dfde4SDavid Schultz { 1043d4dfde4SDavid Schultz u_int64_t w; 1053d4dfde4SDavid Schultz } xparts; 1063a8617a8SJordan K. Hubbard } ieee_double_shape_type; 1073a8617a8SJordan K. Hubbard 1083a8617a8SJordan K. Hubbard #endif 1093a8617a8SJordan K. Hubbard 11074aed985SMarcel Moolenaar #if IEEE_WORD_ORDER == LITTLE_ENDIAN 1113a8617a8SJordan K. Hubbard 1123a8617a8SJordan K. Hubbard typedef union 1133a8617a8SJordan K. Hubbard { 1143a8617a8SJordan K. Hubbard double value; 1153a8617a8SJordan K. Hubbard struct 1163a8617a8SJordan K. Hubbard { 1173a8617a8SJordan K. Hubbard u_int32_t lsw; 1183a8617a8SJordan K. Hubbard u_int32_t msw; 1193a8617a8SJordan K. Hubbard } parts; 1203d4dfde4SDavid Schultz struct 1213d4dfde4SDavid Schultz { 1223d4dfde4SDavid Schultz u_int64_t w; 1233d4dfde4SDavid Schultz } xparts; 1243a8617a8SJordan K. Hubbard } ieee_double_shape_type; 1253a8617a8SJordan K. Hubbard 1263a8617a8SJordan K. Hubbard #endif 1273a8617a8SJordan K. Hubbard 1283a8617a8SJordan K. Hubbard /* Get two 32 bit ints from a double. */ 1293a8617a8SJordan K. Hubbard 1303a8617a8SJordan K. Hubbard #define EXTRACT_WORDS(ix0,ix1,d) \ 1313a8617a8SJordan K. Hubbard do { \ 1323a8617a8SJordan K. Hubbard ieee_double_shape_type ew_u; \ 1333a8617a8SJordan K. Hubbard ew_u.value = (d); \ 1343a8617a8SJordan K. Hubbard (ix0) = ew_u.parts.msw; \ 1353a8617a8SJordan K. Hubbard (ix1) = ew_u.parts.lsw; \ 1363a8617a8SJordan K. Hubbard } while (0) 1373a8617a8SJordan K. Hubbard 1383d4dfde4SDavid Schultz /* Get a 64-bit int from a double. */ 1393d4dfde4SDavid Schultz #define EXTRACT_WORD64(ix,d) \ 1403d4dfde4SDavid Schultz do { \ 1413d4dfde4SDavid Schultz ieee_double_shape_type ew_u; \ 1423d4dfde4SDavid Schultz ew_u.value = (d); \ 1433d4dfde4SDavid Schultz (ix) = ew_u.xparts.w; \ 1443d4dfde4SDavid Schultz } while (0) 1453d4dfde4SDavid Schultz 1463a8617a8SJordan K. Hubbard /* Get the more significant 32 bit int from a double. */ 1473a8617a8SJordan K. Hubbard 1483a8617a8SJordan K. Hubbard #define GET_HIGH_WORD(i,d) \ 1493a8617a8SJordan K. Hubbard do { \ 1503a8617a8SJordan K. Hubbard ieee_double_shape_type gh_u; \ 1513a8617a8SJordan K. Hubbard gh_u.value = (d); \ 1523a8617a8SJordan K. Hubbard (i) = gh_u.parts.msw; \ 1533a8617a8SJordan K. Hubbard } while (0) 1543a8617a8SJordan K. Hubbard 1553a8617a8SJordan K. Hubbard /* Get the less significant 32 bit int from a double. */ 1563a8617a8SJordan K. Hubbard 1573a8617a8SJordan K. Hubbard #define GET_LOW_WORD(i,d) \ 1583a8617a8SJordan K. Hubbard do { \ 1593a8617a8SJordan K. Hubbard ieee_double_shape_type gl_u; \ 1603a8617a8SJordan K. Hubbard gl_u.value = (d); \ 1613a8617a8SJordan K. Hubbard (i) = gl_u.parts.lsw; \ 1623a8617a8SJordan K. Hubbard } while (0) 1633a8617a8SJordan K. Hubbard 1643a8617a8SJordan K. Hubbard /* Set a double from two 32 bit ints. */ 1653a8617a8SJordan K. Hubbard 1663a8617a8SJordan K. Hubbard #define INSERT_WORDS(d,ix0,ix1) \ 1673a8617a8SJordan K. Hubbard do { \ 1683a8617a8SJordan K. Hubbard ieee_double_shape_type iw_u; \ 1693a8617a8SJordan K. Hubbard iw_u.parts.msw = (ix0); \ 1703a8617a8SJordan K. Hubbard iw_u.parts.lsw = (ix1); \ 1713a8617a8SJordan K. Hubbard (d) = iw_u.value; \ 1723a8617a8SJordan K. Hubbard } while (0) 1733a8617a8SJordan K. Hubbard 1743d4dfde4SDavid Schultz /* Set a double from a 64-bit int. */ 1753d4dfde4SDavid Schultz #define INSERT_WORD64(d,ix) \ 1763d4dfde4SDavid Schultz do { \ 1773d4dfde4SDavid Schultz ieee_double_shape_type iw_u; \ 1783d4dfde4SDavid Schultz iw_u.xparts.w = (ix); \ 1793d4dfde4SDavid Schultz (d) = iw_u.value; \ 1803d4dfde4SDavid Schultz } while (0) 1813d4dfde4SDavid Schultz 1823a8617a8SJordan K. Hubbard /* Set the more significant 32 bits of a double from an int. */ 1833a8617a8SJordan K. Hubbard 1843a8617a8SJordan K. Hubbard #define SET_HIGH_WORD(d,v) \ 1853a8617a8SJordan K. Hubbard do { \ 1863a8617a8SJordan K. Hubbard ieee_double_shape_type sh_u; \ 1873a8617a8SJordan K. Hubbard sh_u.value = (d); \ 1883a8617a8SJordan K. Hubbard sh_u.parts.msw = (v); \ 1893a8617a8SJordan K. Hubbard (d) = sh_u.value; \ 1903a8617a8SJordan K. Hubbard } while (0) 1913a8617a8SJordan K. Hubbard 1923a8617a8SJordan K. Hubbard /* Set the less significant 32 bits of a double from an int. */ 1933a8617a8SJordan K. Hubbard 1943a8617a8SJordan K. Hubbard #define SET_LOW_WORD(d,v) \ 1953a8617a8SJordan K. Hubbard do { \ 1963a8617a8SJordan K. Hubbard ieee_double_shape_type sl_u; \ 1973a8617a8SJordan K. Hubbard sl_u.value = (d); \ 1983a8617a8SJordan K. Hubbard sl_u.parts.lsw = (v); \ 1993a8617a8SJordan K. Hubbard (d) = sl_u.value; \ 2003a8617a8SJordan K. Hubbard } while (0) 2013a8617a8SJordan K. Hubbard 202ef1ee63eSAlexey Zelkin /* 203ef1ee63eSAlexey Zelkin * A union which permits us to convert between a float and a 32 bit 204ef1ee63eSAlexey Zelkin * int. 205ef1ee63eSAlexey Zelkin */ 2063a8617a8SJordan K. Hubbard 2073a8617a8SJordan K. Hubbard typedef union 2083a8617a8SJordan K. Hubbard { 2093a8617a8SJordan K. Hubbard float value; 2103a8617a8SJordan K. Hubbard /* FIXME: Assumes 32 bit int. */ 2113a8617a8SJordan K. Hubbard unsigned int word; 2123a8617a8SJordan K. Hubbard } ieee_float_shape_type; 2133a8617a8SJordan K. Hubbard 2143a8617a8SJordan K. Hubbard /* Get a 32 bit int from a float. */ 2153a8617a8SJordan K. Hubbard 2163a8617a8SJordan K. Hubbard #define GET_FLOAT_WORD(i,d) \ 2173a8617a8SJordan K. Hubbard do { \ 2183a8617a8SJordan K. Hubbard ieee_float_shape_type gf_u; \ 2193a8617a8SJordan K. Hubbard gf_u.value = (d); \ 2203a8617a8SJordan K. Hubbard (i) = gf_u.word; \ 2213a8617a8SJordan K. Hubbard } while (0) 2223a8617a8SJordan K. Hubbard 2233a8617a8SJordan K. Hubbard /* Set a float from a 32 bit int. */ 2243a8617a8SJordan K. Hubbard 2253a8617a8SJordan K. Hubbard #define SET_FLOAT_WORD(d,i) \ 2263a8617a8SJordan K. Hubbard do { \ 2273a8617a8SJordan K. Hubbard ieee_float_shape_type sf_u; \ 2283a8617a8SJordan K. Hubbard sf_u.word = (i); \ 2293a8617a8SJordan K. Hubbard (d) = sf_u.value; \ 2303a8617a8SJordan K. Hubbard } while (0) 2313a8617a8SJordan K. Hubbard 23225a4d6bfSDavid Schultz /* 23325a4d6bfSDavid Schultz * Get expsign and mantissa as 16 bit and 64 bit ints from an 80 bit long 23425a4d6bfSDavid Schultz * double. 23525a4d6bfSDavid Schultz */ 23625a4d6bfSDavid Schultz 23725a4d6bfSDavid Schultz #define EXTRACT_LDBL80_WORDS(ix0,ix1,d) \ 23825a4d6bfSDavid Schultz do { \ 23925a4d6bfSDavid Schultz union IEEEl2bits ew_u; \ 24025a4d6bfSDavid Schultz ew_u.e = (d); \ 24125a4d6bfSDavid Schultz (ix0) = ew_u.xbits.expsign; \ 24225a4d6bfSDavid Schultz (ix1) = ew_u.xbits.man; \ 24325a4d6bfSDavid Schultz } while (0) 24425a4d6bfSDavid Schultz 24525a4d6bfSDavid Schultz /* 24625a4d6bfSDavid Schultz * Get expsign and mantissa as one 16 bit and two 64 bit ints from a 128 bit 24725a4d6bfSDavid Schultz * long double. 24825a4d6bfSDavid Schultz */ 24925a4d6bfSDavid Schultz 25025a4d6bfSDavid Schultz #define EXTRACT_LDBL128_WORDS(ix0,ix1,ix2,d) \ 25125a4d6bfSDavid Schultz do { \ 25225a4d6bfSDavid Schultz union IEEEl2bits ew_u; \ 25325a4d6bfSDavid Schultz ew_u.e = (d); \ 25425a4d6bfSDavid Schultz (ix0) = ew_u.xbits.expsign; \ 25525a4d6bfSDavid Schultz (ix1) = ew_u.xbits.manh; \ 25625a4d6bfSDavid Schultz (ix2) = ew_u.xbits.manl; \ 25725a4d6bfSDavid Schultz } while (0) 25825a4d6bfSDavid Schultz 259e6239486SDavid Schultz /* Get expsign as a 16 bit int from a long double. */ 260e6239486SDavid Schultz 261e6239486SDavid Schultz #define GET_LDBL_EXPSIGN(i,d) \ 262e6239486SDavid Schultz do { \ 263e6239486SDavid Schultz union IEEEl2bits ge_u; \ 264e6239486SDavid Schultz ge_u.e = (d); \ 265e6239486SDavid Schultz (i) = ge_u.xbits.expsign; \ 266e6239486SDavid Schultz } while (0) 267e6239486SDavid Schultz 26825a4d6bfSDavid Schultz /* 26925a4d6bfSDavid Schultz * Set an 80 bit long double from a 16 bit int expsign and a 64 bit int 27025a4d6bfSDavid Schultz * mantissa. 27125a4d6bfSDavid Schultz */ 27225a4d6bfSDavid Schultz 27325a4d6bfSDavid Schultz #define INSERT_LDBL80_WORDS(d,ix0,ix1) \ 27425a4d6bfSDavid Schultz do { \ 27525a4d6bfSDavid Schultz union IEEEl2bits iw_u; \ 27625a4d6bfSDavid Schultz iw_u.xbits.expsign = (ix0); \ 27725a4d6bfSDavid Schultz iw_u.xbits.man = (ix1); \ 27825a4d6bfSDavid Schultz (d) = iw_u.e; \ 27925a4d6bfSDavid Schultz } while (0) 28025a4d6bfSDavid Schultz 28125a4d6bfSDavid Schultz /* 28225a4d6bfSDavid Schultz * Set a 128 bit long double from a 16 bit int expsign and two 64 bit ints 28325a4d6bfSDavid Schultz * comprising the mantissa. 28425a4d6bfSDavid Schultz */ 28525a4d6bfSDavid Schultz 28625a4d6bfSDavid Schultz #define INSERT_LDBL128_WORDS(d,ix0,ix1,ix2) \ 28725a4d6bfSDavid Schultz do { \ 28825a4d6bfSDavid Schultz union IEEEl2bits iw_u; \ 28925a4d6bfSDavid Schultz iw_u.xbits.expsign = (ix0); \ 29025a4d6bfSDavid Schultz iw_u.xbits.manh = (ix1); \ 29125a4d6bfSDavid Schultz iw_u.xbits.manl = (ix2); \ 29225a4d6bfSDavid Schultz (d) = iw_u.e; \ 29325a4d6bfSDavid Schultz } while (0) 29425a4d6bfSDavid Schultz 295e6239486SDavid Schultz /* Set expsign of a long double from a 16 bit int. */ 296e6239486SDavid Schultz 297e6239486SDavid Schultz #define SET_LDBL_EXPSIGN(d,v) \ 298e6239486SDavid Schultz do { \ 299e6239486SDavid Schultz union IEEEl2bits se_u; \ 300e6239486SDavid Schultz se_u.e = (d); \ 301e6239486SDavid Schultz se_u.xbits.expsign = (v); \ 302e6239486SDavid Schultz (d) = se_u.e; \ 303e6239486SDavid Schultz } while (0) 304e6239486SDavid Schultz 305a077586cSSteve Kargl #ifdef __i386__ 306a077586cSSteve Kargl /* Long double constants are broken on i386. */ 307a077586cSSteve Kargl #define LD80C(m, ex, v) { \ 308b83ccea3SSteve Kargl .xbits.man = __CONCAT(m, ULL), \ 309a077586cSSteve Kargl .xbits.expsign = (0x3fff + (ex)) | ((v) < 0 ? 0x8000 : 0), \ 310b83ccea3SSteve Kargl } 311a077586cSSteve Kargl #else 312a077586cSSteve Kargl /* The above works on non-i386 too, but we use this to check v. */ 313a077586cSSteve Kargl #define LD80C(m, ex, v) { .e = (v), } 314a077586cSSteve Kargl #endif 315b83ccea3SSteve Kargl 3161880ccbdSBruce Evans #ifdef FLT_EVAL_METHOD 3171880ccbdSBruce Evans /* 3181880ccbdSBruce Evans * Attempt to get strict C99 semantics for assignment with non-C99 compilers. 3191880ccbdSBruce Evans */ 3201880ccbdSBruce Evans #if FLT_EVAL_METHOD == 0 || __GNUC__ == 0 3211880ccbdSBruce Evans #define STRICT_ASSIGN(type, lval, rval) ((lval) = (rval)) 3221880ccbdSBruce Evans #else 3231880ccbdSBruce Evans #define STRICT_ASSIGN(type, lval, rval) do { \ 3241880ccbdSBruce Evans volatile type __lval; \ 3251880ccbdSBruce Evans \ 326e6f9129aSSteve Kargl if (sizeof(type) >= sizeof(long double)) \ 3275b62c380SBruce Evans (lval) = (rval); \ 3285b62c380SBruce Evans else { \ 3291880ccbdSBruce Evans __lval = (rval); \ 3301880ccbdSBruce Evans (lval) = __lval; \ 3315b62c380SBruce Evans } \ 3321880ccbdSBruce Evans } while (0) 3331880ccbdSBruce Evans #endif 334b83ccea3SSteve Kargl #endif /* FLT_EVAL_METHOD */ 335b83ccea3SSteve Kargl 336b83ccea3SSteve Kargl /* Support switching the mode to FP_PE if necessary. */ 337b83ccea3SSteve Kargl #if defined(__i386__) && !defined(NO_FPSETPREC) 3380c0288a2SKonstantin Belousov #define ENTERI() ENTERIT(long double) 3390c0288a2SKonstantin Belousov #define ENTERIT(returntype) \ 3400c0288a2SKonstantin Belousov returntype __retval; \ 341b83ccea3SSteve Kargl fp_prec_t __oprec; \ 342b83ccea3SSteve Kargl \ 343b83ccea3SSteve Kargl if ((__oprec = fpgetprec()) != FP_PE) \ 344e6f9129aSSteve Kargl fpsetprec(FP_PE) 345b83ccea3SSteve Kargl #define RETURNI(x) do { \ 346b83ccea3SSteve Kargl __retval = (x); \ 347b83ccea3SSteve Kargl if (__oprec != FP_PE) \ 348b83ccea3SSteve Kargl fpsetprec(__oprec); \ 349b83ccea3SSteve Kargl RETURNF(__retval); \ 350b83ccea3SSteve Kargl } while (0) 351e1b98d07SMichal Meloun #define ENTERV() \ 352e1b98d07SMichal Meloun fp_prec_t __oprec; \ 353e1b98d07SMichal Meloun \ 354e1b98d07SMichal Meloun if ((__oprec = fpgetprec()) != FP_PE) \ 355e1b98d07SMichal Meloun fpsetprec(FP_PE) 356e1b98d07SMichal Meloun #define RETURNV() do { \ 357e1b98d07SMichal Meloun if (__oprec != FP_PE) \ 358e1b98d07SMichal Meloun fpsetprec(__oprec); \ 359e1b98d07SMichal Meloun return; \ 360e1b98d07SMichal Meloun } while (0) 361b83ccea3SSteve Kargl #else 362e1b98d07SMichal Meloun #define ENTERI() 3630c0288a2SKonstantin Belousov #define ENTERIT(x) 364b83ccea3SSteve Kargl #define RETURNI(x) RETURNF(x) 365e1b98d07SMichal Meloun #define ENTERV() 366e1b98d07SMichal Meloun #define RETURNV() return 3671880ccbdSBruce Evans #endif 3681880ccbdSBruce Evans 369b83ccea3SSteve Kargl /* Default return statement if hack*_t() is not used. */ 370b83ccea3SSteve Kargl #define RETURNF(v) return (v) 371b83ccea3SSteve Kargl 3727cd4a832SDavid Schultz /* 37325a4d6bfSDavid Schultz * 2sum gives the same result as 2sumF without requiring |a| >= |b| or 37425a4d6bfSDavid Schultz * a == 0, but is slower. 37525a4d6bfSDavid Schultz */ 37625a4d6bfSDavid Schultz #define _2sum(a, b) do { \ 37725a4d6bfSDavid Schultz __typeof(a) __s, __w; \ 37825a4d6bfSDavid Schultz \ 37925a4d6bfSDavid Schultz __w = (a) + (b); \ 38025a4d6bfSDavid Schultz __s = __w - (a); \ 38125a4d6bfSDavid Schultz (b) = ((a) - (__w - __s)) + ((b) - __s); \ 38225a4d6bfSDavid Schultz (a) = __w; \ 38325a4d6bfSDavid Schultz } while (0) 38425a4d6bfSDavid Schultz 38525a4d6bfSDavid Schultz /* 38625a4d6bfSDavid Schultz * 2sumF algorithm. 38725a4d6bfSDavid Schultz * 38825a4d6bfSDavid Schultz * "Normalize" the terms in the infinite-precision expression a + b for 38925a4d6bfSDavid Schultz * the sum of 2 floating point values so that b is as small as possible 39025a4d6bfSDavid Schultz * relative to 'a'. (The resulting 'a' is the value of the expression in 39125a4d6bfSDavid Schultz * the same precision as 'a' and the resulting b is the rounding error.) 39225a4d6bfSDavid Schultz * |a| must be >= |b| or 0, b's type must be no larger than 'a's type, and 39325a4d6bfSDavid Schultz * exponent overflow or underflow must not occur. This uses a Theorem of 39425a4d6bfSDavid Schultz * Dekker (1971). See Knuth (1981) 4.2.2 Theorem C. The name "TwoSum" 39525a4d6bfSDavid Schultz * is apparently due to Skewchuk (1997). 39625a4d6bfSDavid Schultz * 39725a4d6bfSDavid Schultz * For this to always work, assignment of a + b to 'a' must not retain any 39825a4d6bfSDavid Schultz * extra precision in a + b. This is required by C standards but broken 39925a4d6bfSDavid Schultz * in many compilers. The brokenness cannot be worked around using 40025a4d6bfSDavid Schultz * STRICT_ASSIGN() like we do elsewhere, since the efficiency of this 40125a4d6bfSDavid Schultz * algorithm would be destroyed by non-null strict assignments. (The 40225a4d6bfSDavid Schultz * compilers are correct to be broken -- the efficiency of all floating 40325a4d6bfSDavid Schultz * point code calculations would be destroyed similarly if they forced the 40425a4d6bfSDavid Schultz * conversions.) 40525a4d6bfSDavid Schultz * 40625a4d6bfSDavid Schultz * Fortunately, a case that works well can usually be arranged by building 40725a4d6bfSDavid Schultz * any extra precision into the type of 'a' -- 'a' should have type float_t, 40825a4d6bfSDavid Schultz * double_t or long double. b's type should be no larger than 'a's type. 40925a4d6bfSDavid Schultz * Callers should use these types with scopes as large as possible, to 41025a4d6bfSDavid Schultz * reduce their own extra-precision and efficiciency problems. In 41125a4d6bfSDavid Schultz * particular, they shouldn't convert back and forth just to call here. 41225a4d6bfSDavid Schultz */ 41325a4d6bfSDavid Schultz #ifdef DEBUG 41425a4d6bfSDavid Schultz #define _2sumF(a, b) do { \ 41525a4d6bfSDavid Schultz __typeof(a) __w; \ 41625a4d6bfSDavid Schultz volatile __typeof(a) __ia, __ib, __r, __vw; \ 41725a4d6bfSDavid Schultz \ 41825a4d6bfSDavid Schultz __ia = (a); \ 41925a4d6bfSDavid Schultz __ib = (b); \ 42025a4d6bfSDavid Schultz assert(__ia == 0 || fabsl(__ia) >= fabsl(__ib)); \ 42125a4d6bfSDavid Schultz \ 42225a4d6bfSDavid Schultz __w = (a) + (b); \ 42325a4d6bfSDavid Schultz (b) = ((a) - __w) + (b); \ 42425a4d6bfSDavid Schultz (a) = __w; \ 42525a4d6bfSDavid Schultz \ 42625a4d6bfSDavid Schultz /* The next 2 assertions are weak if (a) is already long double. */ \ 42725a4d6bfSDavid Schultz assert((long double)__ia + __ib == (long double)(a) + (b)); \ 42825a4d6bfSDavid Schultz __vw = __ia + __ib; \ 42925a4d6bfSDavid Schultz __r = __ia - __vw; \ 43025a4d6bfSDavid Schultz __r += __ib; \ 43125a4d6bfSDavid Schultz assert(__vw == (a) && __r == (b)); \ 43225a4d6bfSDavid Schultz } while (0) 43325a4d6bfSDavid Schultz #else /* !DEBUG */ 43425a4d6bfSDavid Schultz #define _2sumF(a, b) do { \ 43525a4d6bfSDavid Schultz __typeof(a) __w; \ 43625a4d6bfSDavid Schultz \ 43725a4d6bfSDavid Schultz __w = (a) + (b); \ 43825a4d6bfSDavid Schultz (b) = ((a) - __w) + (b); \ 43925a4d6bfSDavid Schultz (a) = __w; \ 44025a4d6bfSDavid Schultz } while (0) 44125a4d6bfSDavid Schultz #endif /* DEBUG */ 44225a4d6bfSDavid Schultz 44325a4d6bfSDavid Schultz /* 44425a4d6bfSDavid Schultz * Set x += c, where x is represented in extra precision as a + b. 44525a4d6bfSDavid Schultz * x must be sufficiently normalized and sufficiently larger than c, 44625a4d6bfSDavid Schultz * and the result is then sufficiently normalized. 44725a4d6bfSDavid Schultz * 44825a4d6bfSDavid Schultz * The details of ordering are that |a| must be >= |c| (so that (a, c) 44925a4d6bfSDavid Schultz * can be normalized without extra work to swap 'a' with c). The details of 45025a4d6bfSDavid Schultz * the normalization are that b must be small relative to the normalized 'a'. 45125a4d6bfSDavid Schultz * Normalization of (a, c) makes the normalized c tiny relative to the 45225a4d6bfSDavid Schultz * normalized a, so b remains small relative to 'a' in the result. However, 45325a4d6bfSDavid Schultz * b need not ever be tiny relative to 'a'. For example, b might be about 45425a4d6bfSDavid Schultz * 2**20 times smaller than 'a' to give about 20 extra bits of precision. 45525a4d6bfSDavid Schultz * That is usually enough, and adding c (which by normalization is about 45625a4d6bfSDavid Schultz * 2**53 times smaller than a) cannot change b significantly. However, 45725a4d6bfSDavid Schultz * cancellation of 'a' with c in normalization of (a, c) may reduce 'a' 45825a4d6bfSDavid Schultz * significantly relative to b. The caller must ensure that significant 45925a4d6bfSDavid Schultz * cancellation doesn't occur, either by having c of the same sign as 'a', 46025a4d6bfSDavid Schultz * or by having |c| a few percent smaller than |a|. Pre-normalization of 46125a4d6bfSDavid Schultz * (a, b) may help. 46225a4d6bfSDavid Schultz * 46329fea59eSGordon Bergling * This is a variant of an algorithm of Kahan (see Knuth (1981) 4.2.2 46425a4d6bfSDavid Schultz * exercise 19). We gain considerable efficiency by requiring the terms to 46525a4d6bfSDavid Schultz * be sufficiently normalized and sufficiently increasing. 46625a4d6bfSDavid Schultz */ 46725a4d6bfSDavid Schultz #define _3sumF(a, b, c) do { \ 46825a4d6bfSDavid Schultz __typeof(a) __tmp; \ 46925a4d6bfSDavid Schultz \ 47025a4d6bfSDavid Schultz __tmp = (c); \ 47125a4d6bfSDavid Schultz _2sumF(__tmp, (a)); \ 47225a4d6bfSDavid Schultz (b) += (a); \ 47325a4d6bfSDavid Schultz (a) = __tmp; \ 47425a4d6bfSDavid Schultz } while (0) 47525a4d6bfSDavid Schultz 47625a4d6bfSDavid Schultz /* 4777cd4a832SDavid Schultz * Common routine to process the arguments to nan(), nanf(), and nanl(). 4787cd4a832SDavid Schultz */ 4797cd4a832SDavid Schultz void _scan_nan(uint32_t *__words, int __num_words, const char *__s); 4807cd4a832SDavid Schultz 4816f1b8a07SBruce Evans /* 482daa1e391SBruce Evans * Mix 0, 1 or 2 NaNs. First add 0 to each arg. This normally just turns 4836f1b8a07SBruce Evans * signaling NaNs into quiet NaNs by setting a quiet bit. We do this 4846f1b8a07SBruce Evans * because we want to never return a signaling NaN, and also because we 4856f1b8a07SBruce Evans * don't want the quiet bit to affect the result. Then mix the converted 486daa1e391SBruce Evans * args using the specified operation. 4876f1b8a07SBruce Evans * 488daa1e391SBruce Evans * When one arg is NaN, the result is typically that arg quieted. When both 489daa1e391SBruce Evans * args are NaNs, the result is typically the quietening of the arg whose 490daa1e391SBruce Evans * mantissa is largest after quietening. When neither arg is NaN, the 491daa1e391SBruce Evans * result may be NaN because it is indeterminate, or finite for subsequent 492daa1e391SBruce Evans * construction of a NaN as the indeterminate 0.0L/0.0L. 493daa1e391SBruce Evans * 494daa1e391SBruce Evans * Technical complications: the result in bits after rounding to the final 495daa1e391SBruce Evans * precision might depend on the runtime precision and/or on compiler 496daa1e391SBruce Evans * optimizations, especially when different register sets are used for 497daa1e391SBruce Evans * different precisions. Try to make the result not depend on at least the 498daa1e391SBruce Evans * runtime precision by always doing the main mixing step in long double 4996f1b8a07SBruce Evans * precision. Try to reduce dependencies on optimizations by adding the 5006f1b8a07SBruce Evans * the 0's in different precisions (unless everything is in long double 5016f1b8a07SBruce Evans * precision). 5026f1b8a07SBruce Evans */ 503daa1e391SBruce Evans #define nan_mix(x, y) (nan_mix_op((x), (y), +)) 504daa1e391SBruce Evans #define nan_mix_op(x, y, op) (((x) + 0.0L) op ((y) + 0)) 5056f1b8a07SBruce Evans 50619b114daSBruce Evans #ifdef _COMPLEX_H 50724863729SDavid Schultz 50824863729SDavid Schultz /* 50924863729SDavid Schultz * C99 specifies that complex numbers have the same representation as 51024863729SDavid Schultz * an array of two elements, where the first element is the real part 51124863729SDavid Schultz * and the second element is the imaginary part. 51224863729SDavid Schultz */ 51324863729SDavid Schultz typedef union { 51424863729SDavid Schultz float complex f; 51524863729SDavid Schultz float a[2]; 51624863729SDavid Schultz } float_complex; 51724863729SDavid Schultz typedef union { 51824863729SDavid Schultz double complex f; 51924863729SDavid Schultz double a[2]; 52024863729SDavid Schultz } double_complex; 52124863729SDavid Schultz typedef union { 52224863729SDavid Schultz long double complex f; 52324863729SDavid Schultz long double a[2]; 52424863729SDavid Schultz } long_double_complex; 52524863729SDavid Schultz #define REALPART(z) ((z).a[0]) 52624863729SDavid Schultz #define IMAGPART(z) ((z).a[1]) 52724863729SDavid Schultz 52819b114daSBruce Evans /* 52919b114daSBruce Evans * Inline functions that can be used to construct complex values. 53019b114daSBruce Evans * 53119b114daSBruce Evans * The C99 standard intends x+I*y to be used for this, but x+I*y is 53219b114daSBruce Evans * currently unusable in general since gcc introduces many overflow, 53319b114daSBruce Evans * underflow, sign and efficiency bugs by rewriting I*y as 53419b114daSBruce Evans * (0.0+I)*(y+0.0*I) and laboriously computing the full complex product. 53519b114daSBruce Evans * In particular, I*Inf is corrupted to NaN+I*Inf, and I*-0 is corrupted 53619b114daSBruce Evans * to -0.0+I*0.0. 5372cec876aSEd Schouten * 5382cec876aSEd Schouten * The C11 standard introduced the macros CMPLX(), CMPLXF() and CMPLXL() 539799cf446SEd Schouten * to construct complex values. Compilers that conform to the C99 540799cf446SEd Schouten * standard require the following functions to avoid the above issues. 54119b114daSBruce Evans */ 5422cec876aSEd Schouten 5432cec876aSEd Schouten #ifndef CMPLXF 54419b114daSBruce Evans static __inline float complex 5452cec876aSEd Schouten CMPLXF(float x, float y) 54619b114daSBruce Evans { 54724863729SDavid Schultz float_complex z; 54819b114daSBruce Evans 54924863729SDavid Schultz REALPART(z) = x; 55024863729SDavid Schultz IMAGPART(z) = y; 55124863729SDavid Schultz return (z.f); 55219b114daSBruce Evans } 5532cec876aSEd Schouten #endif 55419b114daSBruce Evans 5552cec876aSEd Schouten #ifndef CMPLX 55619b114daSBruce Evans static __inline double complex 5572cec876aSEd Schouten CMPLX(double x, double y) 55819b114daSBruce Evans { 55924863729SDavid Schultz double_complex z; 56019b114daSBruce Evans 56124863729SDavid Schultz REALPART(z) = x; 56224863729SDavid Schultz IMAGPART(z) = y; 56324863729SDavid Schultz return (z.f); 56419b114daSBruce Evans } 5652cec876aSEd Schouten #endif 56619b114daSBruce Evans 5672cec876aSEd Schouten #ifndef CMPLXL 56819b114daSBruce Evans static __inline long double complex 5692cec876aSEd Schouten CMPLXL(long double x, long double y) 57019b114daSBruce Evans { 57124863729SDavid Schultz long_double_complex z; 57219b114daSBruce Evans 57324863729SDavid Schultz REALPART(z) = x; 57424863729SDavid Schultz IMAGPART(z) = y; 57524863729SDavid Schultz return (z.f); 57619b114daSBruce Evans } 5772cec876aSEd Schouten #endif 5782cec876aSEd Schouten 57919b114daSBruce Evans #endif /* _COMPLEX_H */ 58019b114daSBruce Evans 58127aa8442SBruce Evans /* 58227aa8442SBruce Evans * The rnint() family rounds to the nearest integer for a restricted range 58327aa8442SBruce Evans * range of args (up to about 2**MANT_DIG). We assume that the current 58427aa8442SBruce Evans * rounding mode is FE_TONEAREST so that this can be done efficiently. 58527aa8442SBruce Evans * Extra precision causes more problems in practice, and we only centralize 58627aa8442SBruce Evans * this here to reduce those problems, and have not solved the efficiency 58727aa8442SBruce Evans * problems. The exp2() family uses a more delicate version of this that 58827aa8442SBruce Evans * requires extracting bits from the intermediate value, so it is not 58927aa8442SBruce Evans * centralized here and should copy any solution of the efficiency problems. 59027aa8442SBruce Evans */ 5910ddfa46bSBruce Evans 59227aa8442SBruce Evans static inline double 59327aa8442SBruce Evans rnint(__double_t x) 59427aa8442SBruce Evans { 59527aa8442SBruce Evans /* 59627aa8442SBruce Evans * This casts to double to kill any extra precision. This depends 59727aa8442SBruce Evans * on the cast being applied to a double_t to avoid compiler bugs 59827aa8442SBruce Evans * (this is a cleaner version of STRICT_ASSIGN()). This is 59927aa8442SBruce Evans * inefficient if there actually is extra precision, but is hard 60027aa8442SBruce Evans * to improve on. We use double_t in the API to minimise conversions 60127aa8442SBruce Evans * for just calling here. Note that we cannot easily change the 60227aa8442SBruce Evans * magic number to the one that works directly with double_t, since 60327aa8442SBruce Evans * the rounding precision is variable at runtime on x86 so the 60427aa8442SBruce Evans * magic number would need to be variable. Assuming that the 60527aa8442SBruce Evans * rounding precision is always the default is too fragile. This 60627aa8442SBruce Evans * and many other complications will move when the default is 60727aa8442SBruce Evans * changed to FP_PE. 60827aa8442SBruce Evans */ 60927aa8442SBruce Evans return ((double)(x + 0x1.8p52) - 0x1.8p52); 61027aa8442SBruce Evans } 6110ddfa46bSBruce Evans 61227aa8442SBruce Evans static inline float 61327aa8442SBruce Evans rnintf(__float_t x) 61427aa8442SBruce Evans { 61527aa8442SBruce Evans /* 61627aa8442SBruce Evans * As for rnint(), except we could just call that to handle the 61727aa8442SBruce Evans * extra precision case, usually without losing efficiency. 61827aa8442SBruce Evans */ 61927aa8442SBruce Evans return ((float)(x + 0x1.8p23F) - 0x1.8p23F); 62027aa8442SBruce Evans } 62127aa8442SBruce Evans 62227aa8442SBruce Evans #ifdef LDBL_MANT_DIG 62327aa8442SBruce Evans /* 62427aa8442SBruce Evans * The complications for extra precision are smaller for rnintl() since it 62527aa8442SBruce Evans * can safely assume that the rounding precision has been increased from 62627aa8442SBruce Evans * its default to FP_PE on x86. We don't exploit that here to get small 62727aa8442SBruce Evans * optimizations from limiting the rangle to double. We just need it for 62827aa8442SBruce Evans * the magic number to work with long doubles. ld128 callers should use 62927aa8442SBruce Evans * rnint() instead of this if possible. ld80 callers should prefer 63027aa8442SBruce Evans * rnintl() since for amd64 this avoids swapping the register set, while 63127aa8442SBruce Evans * for i386 it makes no difference (assuming FP_PE), and for other arches 63227aa8442SBruce Evans * it makes little difference. 63327aa8442SBruce Evans */ 63427aa8442SBruce Evans static inline long double 63527aa8442SBruce Evans rnintl(long double x) 63627aa8442SBruce Evans { 63727aa8442SBruce Evans return (x + __CONCAT(0x1.8p, LDBL_MANT_DIG) / 2 - 63827aa8442SBruce Evans __CONCAT(0x1.8p, LDBL_MANT_DIG) / 2); 63927aa8442SBruce Evans } 64027aa8442SBruce Evans #endif /* LDBL_MANT_DIG */ 64127aa8442SBruce Evans 64227aa8442SBruce Evans /* 64327aa8442SBruce Evans * irint() and i64rint() give the same result as casting to their integer 64427aa8442SBruce Evans * return type provided their arg is a floating point integer. They can 64527aa8442SBruce Evans * sometimes be more efficient because no rounding is required. 64627aa8442SBruce Evans */ 647*56f5947aSJohn Baldwin #if defined(amd64) || defined(__i386__) 64827aa8442SBruce Evans #define irint(x) \ 64927aa8442SBruce Evans (sizeof(x) == sizeof(float) && \ 65027aa8442SBruce Evans sizeof(__float_t) == sizeof(long double) ? irintf(x) : \ 65127aa8442SBruce Evans sizeof(x) == sizeof(double) && \ 65227aa8442SBruce Evans sizeof(__double_t) == sizeof(long double) ? irintd(x) : \ 65327aa8442SBruce Evans sizeof(x) == sizeof(long double) ? irintl(x) : (int)(x)) 65427aa8442SBruce Evans #else 65527aa8442SBruce Evans #define irint(x) ((int)(x)) 65627aa8442SBruce Evans #endif 65727aa8442SBruce Evans 65827aa8442SBruce Evans #define i64rint(x) ((int64_t)(x)) /* only needed for ld128 so not opt. */ 65927aa8442SBruce Evans 660*56f5947aSJohn Baldwin #if defined(__i386__) 6610ddfa46bSBruce Evans static __inline int 66227aa8442SBruce Evans irintf(float x) 6630ddfa46bSBruce Evans { 6640ddfa46bSBruce Evans int n; 6650ddfa46bSBruce Evans 66627aa8442SBruce Evans __asm("fistl %0" : "=m" (n) : "t" (x)); 6670ddfa46bSBruce Evans return (n); 6680ddfa46bSBruce Evans } 6690ddfa46bSBruce Evans 6700ddfa46bSBruce Evans static __inline int 67127aa8442SBruce Evans irintd(double x) 6720ddfa46bSBruce Evans { 6730ddfa46bSBruce Evans int n; 6740ddfa46bSBruce Evans 67527aa8442SBruce Evans __asm("fistl %0" : "=m" (n) : "t" (x)); 6760ddfa46bSBruce Evans return (n); 6770ddfa46bSBruce Evans } 6780ddfa46bSBruce Evans #endif 6790ddfa46bSBruce Evans 680*56f5947aSJohn Baldwin #if defined(__amd64__) || defined(__i386__) 681b83ccea3SSteve Kargl static __inline int 682b83ccea3SSteve Kargl irintl(long double x) 683b83ccea3SSteve Kargl { 684b83ccea3SSteve Kargl int n; 685b83ccea3SSteve Kargl 68627aa8442SBruce Evans __asm("fistl %0" : "=m" (n) : "t" (x)); 687b83ccea3SSteve Kargl return (n); 688b83ccea3SSteve Kargl } 689b83ccea3SSteve Kargl #endif 690b83ccea3SSteve Kargl 69125a4d6bfSDavid Schultz #ifdef DEBUG 69225a4d6bfSDavid Schultz #if defined(__amd64__) || defined(__i386__) 69325a4d6bfSDavid Schultz #define breakpoint() asm("int $3") 69425a4d6bfSDavid Schultz #else 69525a4d6bfSDavid Schultz #include <signal.h> 69625a4d6bfSDavid Schultz 69725a4d6bfSDavid Schultz #define breakpoint() raise(SIGTRAP) 69825a4d6bfSDavid Schultz #endif 69925a4d6bfSDavid Schultz #endif 70025a4d6bfSDavid Schultz 70125a4d6bfSDavid Schultz /* Write a pari script to test things externally. */ 70225a4d6bfSDavid Schultz #ifdef DOPRINT 70325a4d6bfSDavid Schultz #include <stdio.h> 70425a4d6bfSDavid Schultz 70525a4d6bfSDavid Schultz #ifndef DOPRINT_SWIZZLE 70625a4d6bfSDavid Schultz #define DOPRINT_SWIZZLE 0 70725a4d6bfSDavid Schultz #endif 70825a4d6bfSDavid Schultz 70925a4d6bfSDavid Schultz #ifdef DOPRINT_LD80 71025a4d6bfSDavid Schultz 71125a4d6bfSDavid Schultz #define DOPRINT_START(xp) do { \ 71225a4d6bfSDavid Schultz uint64_t __lx; \ 71325a4d6bfSDavid Schultz uint16_t __hx; \ 71425a4d6bfSDavid Schultz \ 71525a4d6bfSDavid Schultz /* Hack to give more-problematic args. */ \ 71625a4d6bfSDavid Schultz EXTRACT_LDBL80_WORDS(__hx, __lx, *xp); \ 71725a4d6bfSDavid Schultz __lx ^= DOPRINT_SWIZZLE; \ 71825a4d6bfSDavid Schultz INSERT_LDBL80_WORDS(*xp, __hx, __lx); \ 71925a4d6bfSDavid Schultz printf("x = %.21Lg; ", (long double)*xp); \ 72025a4d6bfSDavid Schultz } while (0) 72125a4d6bfSDavid Schultz #define DOPRINT_END1(v) \ 72225a4d6bfSDavid Schultz printf("y = %.21Lg; z = 0; show(x, y, z);\n", (long double)(v)) 72325a4d6bfSDavid Schultz #define DOPRINT_END2(hi, lo) \ 72425a4d6bfSDavid Schultz printf("y = %.21Lg; z = %.21Lg; show(x, y, z);\n", \ 72525a4d6bfSDavid Schultz (long double)(hi), (long double)(lo)) 72625a4d6bfSDavid Schultz 72725a4d6bfSDavid Schultz #elif defined(DOPRINT_D64) 72825a4d6bfSDavid Schultz 72925a4d6bfSDavid Schultz #define DOPRINT_START(xp) do { \ 73025a4d6bfSDavid Schultz uint32_t __hx, __lx; \ 73125a4d6bfSDavid Schultz \ 73225a4d6bfSDavid Schultz EXTRACT_WORDS(__hx, __lx, *xp); \ 73325a4d6bfSDavid Schultz __lx ^= DOPRINT_SWIZZLE; \ 73425a4d6bfSDavid Schultz INSERT_WORDS(*xp, __hx, __lx); \ 73525a4d6bfSDavid Schultz printf("x = %.21Lg; ", (long double)*xp); \ 73625a4d6bfSDavid Schultz } while (0) 73725a4d6bfSDavid Schultz #define DOPRINT_END1(v) \ 73825a4d6bfSDavid Schultz printf("y = %.21Lg; z = 0; show(x, y, z);\n", (long double)(v)) 73925a4d6bfSDavid Schultz #define DOPRINT_END2(hi, lo) \ 74025a4d6bfSDavid Schultz printf("y = %.21Lg; z = %.21Lg; show(x, y, z);\n", \ 74125a4d6bfSDavid Schultz (long double)(hi), (long double)(lo)) 74225a4d6bfSDavid Schultz 74325a4d6bfSDavid Schultz #elif defined(DOPRINT_F32) 74425a4d6bfSDavid Schultz 74525a4d6bfSDavid Schultz #define DOPRINT_START(xp) do { \ 74625a4d6bfSDavid Schultz uint32_t __hx; \ 74725a4d6bfSDavid Schultz \ 74825a4d6bfSDavid Schultz GET_FLOAT_WORD(__hx, *xp); \ 74925a4d6bfSDavid Schultz __hx ^= DOPRINT_SWIZZLE; \ 75025a4d6bfSDavid Schultz SET_FLOAT_WORD(*xp, __hx); \ 75125a4d6bfSDavid Schultz printf("x = %.21Lg; ", (long double)*xp); \ 75225a4d6bfSDavid Schultz } while (0) 75325a4d6bfSDavid Schultz #define DOPRINT_END1(v) \ 75425a4d6bfSDavid Schultz printf("y = %.21Lg; z = 0; show(x, y, z);\n", (long double)(v)) 75525a4d6bfSDavid Schultz #define DOPRINT_END2(hi, lo) \ 75625a4d6bfSDavid Schultz printf("y = %.21Lg; z = %.21Lg; show(x, y, z);\n", \ 75725a4d6bfSDavid Schultz (long double)(hi), (long double)(lo)) 75825a4d6bfSDavid Schultz 75925a4d6bfSDavid Schultz #else /* !DOPRINT_LD80 && !DOPRINT_D64 (LD128 only) */ 76025a4d6bfSDavid Schultz 76125a4d6bfSDavid Schultz #ifndef DOPRINT_SWIZZLE_HIGH 76225a4d6bfSDavid Schultz #define DOPRINT_SWIZZLE_HIGH 0 76325a4d6bfSDavid Schultz #endif 76425a4d6bfSDavid Schultz 76525a4d6bfSDavid Schultz #define DOPRINT_START(xp) do { \ 76625a4d6bfSDavid Schultz uint64_t __lx, __llx; \ 76725a4d6bfSDavid Schultz uint16_t __hx; \ 76825a4d6bfSDavid Schultz \ 76925a4d6bfSDavid Schultz EXTRACT_LDBL128_WORDS(__hx, __lx, __llx, *xp); \ 77025a4d6bfSDavid Schultz __llx ^= DOPRINT_SWIZZLE; \ 77125a4d6bfSDavid Schultz __lx ^= DOPRINT_SWIZZLE_HIGH; \ 77225a4d6bfSDavid Schultz INSERT_LDBL128_WORDS(*xp, __hx, __lx, __llx); \ 77325a4d6bfSDavid Schultz printf("x = %.36Lg; ", (long double)*xp); \ 77425a4d6bfSDavid Schultz } while (0) 77525a4d6bfSDavid Schultz #define DOPRINT_END1(v) \ 77625a4d6bfSDavid Schultz printf("y = %.36Lg; z = 0; show(x, y, z);\n", (long double)(v)) 77725a4d6bfSDavid Schultz #define DOPRINT_END2(hi, lo) \ 77825a4d6bfSDavid Schultz printf("y = %.36Lg; z = %.36Lg; show(x, y, z);\n", \ 77925a4d6bfSDavid Schultz (long double)(hi), (long double)(lo)) 78025a4d6bfSDavid Schultz 78125a4d6bfSDavid Schultz #endif /* DOPRINT_LD80 */ 78225a4d6bfSDavid Schultz 78325a4d6bfSDavid Schultz #else /* !DOPRINT */ 78425a4d6bfSDavid Schultz #define DOPRINT_START(xp) 78525a4d6bfSDavid Schultz #define DOPRINT_END1(v) 78625a4d6bfSDavid Schultz #define DOPRINT_END2(hi, lo) 78725a4d6bfSDavid Schultz #endif /* DOPRINT */ 78825a4d6bfSDavid Schultz 78925a4d6bfSDavid Schultz #define RETURNP(x) do { \ 79025a4d6bfSDavid Schultz DOPRINT_END1(x); \ 79125a4d6bfSDavid Schultz RETURNF(x); \ 79225a4d6bfSDavid Schultz } while (0) 79325a4d6bfSDavid Schultz #define RETURNPI(x) do { \ 79425a4d6bfSDavid Schultz DOPRINT_END1(x); \ 79525a4d6bfSDavid Schultz RETURNI(x); \ 79625a4d6bfSDavid Schultz } while (0) 79725a4d6bfSDavid Schultz #define RETURN2P(x, y) do { \ 79825a4d6bfSDavid Schultz DOPRINT_END2((x), (y)); \ 79925a4d6bfSDavid Schultz RETURNF((x) + (y)); \ 80025a4d6bfSDavid Schultz } while (0) 80125a4d6bfSDavid Schultz #define RETURN2PI(x, y) do { \ 80225a4d6bfSDavid Schultz DOPRINT_END2((x), (y)); \ 80325a4d6bfSDavid Schultz RETURNI((x) + (y)); \ 80425a4d6bfSDavid Schultz } while (0) 80525a4d6bfSDavid Schultz #ifdef STRUCT_RETURN 80625a4d6bfSDavid Schultz #define RETURNSP(rp) do { \ 80725a4d6bfSDavid Schultz if (!(rp)->lo_set) \ 80825a4d6bfSDavid Schultz RETURNP((rp)->hi); \ 80925a4d6bfSDavid Schultz RETURN2P((rp)->hi, (rp)->lo); \ 81025a4d6bfSDavid Schultz } while (0) 81125a4d6bfSDavid Schultz #define RETURNSPI(rp) do { \ 81225a4d6bfSDavid Schultz if (!(rp)->lo_set) \ 81325a4d6bfSDavid Schultz RETURNPI((rp)->hi); \ 81425a4d6bfSDavid Schultz RETURN2PI((rp)->hi, (rp)->lo); \ 81525a4d6bfSDavid Schultz } while (0) 81625a4d6bfSDavid Schultz #endif 81725a4d6bfSDavid Schultz #define SUM2P(x, y) ({ \ 81825a4d6bfSDavid Schultz const __typeof (x) __x = (x); \ 81925a4d6bfSDavid Schultz const __typeof (y) __y = (y); \ 82025a4d6bfSDavid Schultz \ 82125a4d6bfSDavid Schultz DOPRINT_END2(__x, __y); \ 82225a4d6bfSDavid Schultz __x + __y; \ 82325a4d6bfSDavid Schultz }) 82425a4d6bfSDavid Schultz 825e1b61b5bSDavid Schultz /* 826e1b61b5bSDavid Schultz * ieee style elementary functions 827e1b61b5bSDavid Schultz * 828e1b61b5bSDavid Schultz * We rename functions here to improve other sources' diffability 829e1b61b5bSDavid Schultz * against fdlibm. 830e1b61b5bSDavid Schultz */ 831e1b61b5bSDavid Schultz #define __ieee754_sqrt sqrt 832e1b61b5bSDavid Schultz #define __ieee754_acos acos 833e1b61b5bSDavid Schultz #define __ieee754_acosh acosh 834e1b61b5bSDavid Schultz #define __ieee754_log log 835177668d1SDavid Schultz #define __ieee754_log2 log2 836e1b61b5bSDavid Schultz #define __ieee754_atanh atanh 837e1b61b5bSDavid Schultz #define __ieee754_asin asin 838e1b61b5bSDavid Schultz #define __ieee754_atan2 atan2 839e1b61b5bSDavid Schultz #define __ieee754_exp exp 840e1b61b5bSDavid Schultz #define __ieee754_cosh cosh 841e1b61b5bSDavid Schultz #define __ieee754_fmod fmod 842e1b61b5bSDavid Schultz #define __ieee754_pow pow 843e1b61b5bSDavid Schultz #define __ieee754_lgamma lgamma 844e1b61b5bSDavid Schultz #define __ieee754_gamma gamma 845e1b61b5bSDavid Schultz #define __ieee754_lgamma_r lgamma_r 846e1b61b5bSDavid Schultz #define __ieee754_gamma_r gamma_r 847e1b61b5bSDavid Schultz #define __ieee754_log10 log10 848e1b61b5bSDavid Schultz #define __ieee754_sinh sinh 849e1b61b5bSDavid Schultz #define __ieee754_hypot hypot 850e1b61b5bSDavid Schultz #define __ieee754_j0 j0 851e1b61b5bSDavid Schultz #define __ieee754_j1 j1 852e1b61b5bSDavid Schultz #define __ieee754_y0 y0 853e1b61b5bSDavid Schultz #define __ieee754_y1 y1 854e1b61b5bSDavid Schultz #define __ieee754_jn jn 855e1b61b5bSDavid Schultz #define __ieee754_yn yn 856e1b61b5bSDavid Schultz #define __ieee754_remainder remainder 857e1b61b5bSDavid Schultz #define __ieee754_scalb scalb 858e1b61b5bSDavid Schultz #define __ieee754_sqrtf sqrtf 859e1b61b5bSDavid Schultz #define __ieee754_acosf acosf 860e1b61b5bSDavid Schultz #define __ieee754_acoshf acoshf 861e1b61b5bSDavid Schultz #define __ieee754_logf logf 862e1b61b5bSDavid Schultz #define __ieee754_atanhf atanhf 863e1b61b5bSDavid Schultz #define __ieee754_asinf asinf 864e1b61b5bSDavid Schultz #define __ieee754_atan2f atan2f 865e1b61b5bSDavid Schultz #define __ieee754_expf expf 866e1b61b5bSDavid Schultz #define __ieee754_coshf coshf 867e1b61b5bSDavid Schultz #define __ieee754_fmodf fmodf 868e1b61b5bSDavid Schultz #define __ieee754_powf powf 869e1b61b5bSDavid Schultz #define __ieee754_lgammaf lgammaf 870e1b61b5bSDavid Schultz #define __ieee754_gammaf gammaf 871e1b61b5bSDavid Schultz #define __ieee754_lgammaf_r lgammaf_r 872e1b61b5bSDavid Schultz #define __ieee754_gammaf_r gammaf_r 873e1b61b5bSDavid Schultz #define __ieee754_log10f log10f 874177668d1SDavid Schultz #define __ieee754_log2f log2f 875e1b61b5bSDavid Schultz #define __ieee754_sinhf sinhf 876e1b61b5bSDavid Schultz #define __ieee754_hypotf hypotf 877e1b61b5bSDavid Schultz #define __ieee754_j0f j0f 878e1b61b5bSDavid Schultz #define __ieee754_j1f j1f 879e1b61b5bSDavid Schultz #define __ieee754_y0f y0f 880e1b61b5bSDavid Schultz #define __ieee754_y1f y1f 881e1b61b5bSDavid Schultz #define __ieee754_jnf jnf 882e1b61b5bSDavid Schultz #define __ieee754_ynf ynf 883e1b61b5bSDavid Schultz #define __ieee754_remainderf remainderf 884e1b61b5bSDavid Schultz #define __ieee754_scalbf scalbf 8853a8617a8SJordan K. Hubbard 8863a8617a8SJordan K. Hubbard /* fdlibm kernel function */ 887079299f7SDavid Schultz int __kernel_rem_pio2(double*,double*,int,int,int); 888079299f7SDavid Schultz 889079299f7SDavid Schultz /* double precision kernel functions */ 8902b795b29SDimitry Andric #ifndef INLINE_REM_PIO2 891e02846ceSDavid Schultz int __ieee754_rem_pio2(double,double*); 8922b795b29SDimitry Andric #endif 89369160b1eSDavid E. O'Brien double __kernel_sin(double,double,int); 89469160b1eSDavid E. O'Brien double __kernel_cos(double,double); 89569160b1eSDavid E. O'Brien double __kernel_tan(double,double,int); 89612188b77SDavid Schultz double __ldexp_exp(double,int); 89712188b77SDavid Schultz #ifdef _COMPLEX_H 89812188b77SDavid Schultz double complex __ldexp_cexp(double complex,int); 89912188b77SDavid Schultz #endif 9003a8617a8SJordan K. Hubbard 901079299f7SDavid Schultz /* float precision kernel functions */ 9022b795b29SDimitry Andric #ifndef INLINE_REM_PIO2F 90370d818a2SBruce Evans int __ieee754_rem_pio2f(float,double*); 904b492f289SEd Schouten #endif 9052b795b29SDimitry Andric #ifndef INLINE_KERNEL_SINDF 90659aad933SBruce Evans float __kernel_sindf(double); 907b492f289SEd Schouten #endif 9082b795b29SDimitry Andric #ifndef INLINE_KERNEL_COSDF 90959aad933SBruce Evans float __kernel_cosdf(double); 910b492f289SEd Schouten #endif 9112b795b29SDimitry Andric #ifndef INLINE_KERNEL_TANDF 91294a5f9beSBruce Evans float __kernel_tandf(double,int); 9132b795b29SDimitry Andric #endif 91412188b77SDavid Schultz float __ldexp_expf(float,int); 91512188b77SDavid Schultz #ifdef _COMPLEX_H 91612188b77SDavid Schultz float complex __ldexp_cexpf(float complex,int); 91712188b77SDavid Schultz #endif 918079299f7SDavid Schultz 919079299f7SDavid Schultz /* long double precision kernel functions */ 920079299f7SDavid Schultz long double __kernel_sinl(long double, long double, int); 921079299f7SDavid Schultz long double __kernel_cosl(long double, long double); 922079299f7SDavid Schultz long double __kernel_tanl(long double, long double, int); 9233a8617a8SJordan K. Hubbard 924ef1ee63eSAlexey Zelkin #endif /* !_MATH_PRIVATE_H_ */ 925