2 * ====================================================
3 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
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
9 * ====================================================
13 * from: @(#)fdlibm.h 5.1 93/09/24
14 * $FreeBSD: src/lib/msun/src/math_private.h,v 1.34 2011/10/21 06:27:56 das Exp $
17 #ifndef _MATH_PRIVATE_H_
18 #define _MATH_PRIVATE_H_
22 #include <aros/system.h>
26 #include "bsdsrc/math_private_openbsd.h"
28 //the following define is used to comment out gcc's incorrect section attributes
30 #define SECTIONCOMMENT "\n@"
32 #define SECTIONCOMMENT "\n#"
36 * The original fdlibm code used statements like:
37 * n0 = ((*(int*)&one)>>29)^1; * index of high word *
38 * ix0 = *(n0+(int*)&x); * high word of x *
39 * ix1 = *((1-n0)+(int*)&x); * low word of x *
40 * to dig two 32 bit words out of the 64 bit IEEE floating point
41 * value. That is non-ANSI, and, moreover, the gcc instruction
42 * scheduler gets it wrong. We instead use the following macros.
43 * Unlike the original code, we determine the endianness at compile
44 * time, not at run time; I don't see much benefit to selecting
45 * endianness at run time.
49 * A union which permits us to convert between a double and two 32 bit
67 } ieee_double_shape_type
;
85 } ieee_double_shape_type
;
89 /* Get two 32 bit ints from a double. */
91 #define EXTRACT_WORDS(ix0,ix1,d) \
93 ieee_double_shape_type ew_u; \
95 (ix0) = ew_u.parts.msw; \
96 (ix1) = ew_u.parts.lsw; \
99 /* Get a 64-bit int from a double. */
100 #define EXTRACT_WORD64(ix,d) \
102 ieee_double_shape_type ew_u; \
104 (ix) = ew_u.xparts.w; \
107 /* Get the more significant 32 bit int from a double. */
109 #define GET_HIGH_WORD(i,d) \
111 ieee_double_shape_type gh_u; \
113 (i) = gh_u.parts.msw; \
116 /* Get the less significant 32 bit int from a double. */
118 #define GET_LOW_WORD(i,d) \
120 ieee_double_shape_type gl_u; \
122 (i) = gl_u.parts.lsw; \
125 /* Set a double from two 32 bit ints. */
127 #define INSERT_WORDS(d,ix0,ix1) \
129 ieee_double_shape_type iw_u; \
130 iw_u.parts.msw = (ix0); \
131 iw_u.parts.lsw = (ix1); \
135 /* Set a double from a 64-bit int. */
136 #define INSERT_WORD64(d,ix) \
138 ieee_double_shape_type iw_u; \
139 iw_u.xparts.w = (ix); \
143 /* Set the more significant 32 bits of a double from an int. */
145 #define SET_HIGH_WORD(d,v) \
147 ieee_double_shape_type sh_u; \
149 sh_u.parts.msw = (v); \
153 /* Set the less significant 32 bits of a double from an int. */
155 #define SET_LOW_WORD(d,v) \
157 ieee_double_shape_type sl_u; \
159 sl_u.parts.lsw = (v); \
164 * A union which permits us to convert between a float and a 32 bit
171 /* FIXME: Assumes 32 bit int. */
173 } ieee_float_shape_type
;
175 /* Get a 32 bit int from a float. */
177 #define GET_FLOAT_WORD(i,d) \
179 ieee_float_shape_type gf_u; \
184 /* Set a float from a 32 bit int. */
186 #define SET_FLOAT_WORD(d,i) \
188 ieee_float_shape_type sf_u; \
194 * Get expsign and mantissa as 16 bit and 64 bit ints from an 80 bit long
198 #define EXTRACT_LDBL80_WORDS(ix0,ix1,d) \
200 union IEEEl2bits ew_u; \
202 (ix0) = ew_u.xbits.expsign; \
203 (ix1) = ew_u.xbits.man; \
207 * Get expsign and mantissa as one 16 bit and two 64 bit ints from a 128 bit
211 #define EXTRACT_LDBL128_WORDS(ix0,ix1,ix2,d) \
213 union IEEEl2bits ew_u; \
215 (ix0) = ew_u.xbits.expsign; \
216 (ix1) = ew_u.xbits.manh; \
217 (ix2) = ew_u.xbits.manl; \
220 /* Get expsign as a 16 bit int from a long double. */
222 #define GET_LDBL_EXPSIGN(i,d) \
224 union IEEEl2bits ge_u; \
226 (i) = ge_u.xbits.expsign; \
230 * Set an 80 bit long double from a 16 bit int expsign and a 64 bit int
234 #define INSERT_LDBL80_WORDS(d,ix0,ix1) \
236 union IEEEl2bits iw_u; \
237 iw_u.xbits.expsign = (ix0); \
238 iw_u.xbits.man = (ix1); \
243 * Set a 128 bit long double from a 16 bit int expsign and two 64 bit ints
244 * comprising the mantissa.
247 #define INSERT_LDBL128_WORDS(d,ix0,ix1,ix2) \
249 union IEEEl2bits iw_u; \
250 iw_u.xbits.expsign = (ix0); \
251 iw_u.xbits.manh = (ix1); \
252 iw_u.xbits.manl = (ix2); \
256 /* Set expsign of a long double from a 16 bit int. */
258 #define SET_LDBL_EXPSIGN(d,v) \
260 union IEEEl2bits se_u; \
262 se_u.xbits.expsign = (v); \
267 /* Long double constants are broken on i386. */
268 #define LD80C(m, ex, v) { \
269 .xbits.man = __CONCAT(m, ULL), \
270 .xbits.expsign = (0x3fff + (ex)) | ((v) < 0 ? 0x8000 : 0), \
273 /* The above works on non-i386 too, but we use this to check v. */
274 #define LD80C(m, ex, v) { .e = (v), }
277 #ifdef FLT_EVAL_METHOD
279 * Attempt to get strict C99 semantics for assignment with non-C99 compilers.
281 #if FLT_EVAL_METHOD == 0 || __GNUC__ == 0
282 #define STRICT_ASSIGN(type, lval, rval) (*((volatile type *)&lval) = (rval))
284 #define STRICT_ASSIGN(type, lval, rval) do { \
285 volatile type __lval; \
287 if (sizeof(type) >= sizeof(long double)) \
296 #define STRICT_ASSIGN(type, lval, rval) (*((volatile type *)&lval) = (rval))
297 #endif /* FLT_EVAL_METHOD */
299 /* Support switching the mode to FP_PE if necessary. */
300 #if (defined(__x86_64__) || defined(__i386__)) && !defined(NO_FPSETPREC)
302 long double __retval; \
305 if ((__oprec = fpgetprec()) != FP_PE) \
307 #define RETURNI(x) do { \
309 if (__oprec != FP_PE) \
310 fpsetprec(__oprec); \
316 if ((__oprec = fpgetprec()) != FP_PE) \
318 #define RETURNV() do { \
319 if (__oprec != FP_PE) \
320 fpsetprec(__oprec); \
325 #define RETURNI(x) RETURNF(x)
327 #define RETURNV() return
330 /* Default return statement if hack*_t() is not used. */
331 #define RETURNF(v) return (v)
334 * 2sum gives the same result as 2sumF without requiring |a| >= |b| or
335 * a == 0, but is slower.
337 #define _2sum(a, b) do { \
338 __typeof(a) __s, __w; \
342 (b) = ((a) - (__w - __s)) + ((b) - __s); \
349 * "Normalize" the terms in the infinite-precision expression a + b for
350 * the sum of 2 floating point values so that b is as small as possible
351 * relative to 'a'. (The resulting 'a' is the value of the expression in
352 * the same precision as 'a' and the resulting b is the rounding error.)
353 * |a| must be >= |b| or 0, b's type must be no larger than 'a's type, and
354 * exponent overflow or underflow must not occur. This uses a Theorem of
355 * Dekker (1971). See Knuth (1981) 4.2.2 Theorem C. The name "TwoSum"
356 * is apparently due to Skewchuk (1997).
358 * For this to always work, assignment of a + b to 'a' must not retain any
359 * extra precision in a + b. This is required by C standards but broken
360 * in many compilers. The brokenness cannot be worked around using
361 * STRICT_ASSIGN() like we do elsewhere, since the efficiency of this
362 * algorithm would be destroyed by non-null strict assignments. (The
363 * compilers are correct to be broken -- the efficiency of all floating
364 * point code calculations would be destroyed similarly if they forced the
367 * Fortunately, a case that works well can usually be arranged by building
368 * any extra precision into the type of 'a' -- 'a' should have type float_t,
369 * double_t or long double. b's type should be no larger than 'a's type.
370 * Callers should use these types with scopes as large as possible, to
371 * reduce their own extra-precision and efficiciency problems. In
372 * particular, they shouldn't convert back and forth just to call here.
375 #define _2sumF(a, b) do { \
377 volatile __typeof(a) __ia, __ib, __r, __vw; \
381 assert(__ia == 0 || fabsl(__ia) >= fabsl(__ib)); \
384 (b) = ((a) - __w) + (b); \
387 /* The next 2 assertions are weak if (a) is already long double. */ \
388 assert((long double)__ia + __ib == (long double)(a) + (b)); \
389 __vw = __ia + __ib; \
392 assert(__vw == (a) && __r == (b)); \
395 #define _2sumF(a, b) do { \
399 (b) = ((a) - __w) + (b); \
405 * Set x += c, where x is represented in extra precision as a + b.
406 * x must be sufficiently normalized and sufficiently larger than c,
407 * and the result is then sufficiently normalized.
409 * The details of ordering are that |a| must be >= |c| (so that (a, c)
410 * can be normalized without extra work to swap 'a' with c). The details of
411 * the normalization are that b must be small relative to the normalized 'a'.
412 * Normalization of (a, c) makes the normalized c tiny relative to the
413 * normalized a, so b remains small relative to 'a' in the result. However,
414 * b need not ever be tiny relative to 'a'. For example, b might be about
415 * 2**20 times smaller than 'a' to give about 20 extra bits of precision.
416 * That is usually enough, and adding c (which by normalization is about
417 * 2**53 times smaller than a) cannot change b significantly. However,
418 * cancellation of 'a' with c in normalization of (a, c) may reduce 'a'
419 * significantly relative to b. The caller must ensure that significant
420 * cancellation doesn't occur, either by having c of the same sign as 'a',
421 * or by having |c| a few percent smaller than |a|. Pre-normalization of
424 * This is is a variant of an algorithm of Kahan (see Knuth (1981) 4.2.2
425 * exercise 19). We gain considerable efficiency by requiring the terms to
426 * be sufficiently normalized and sufficiently increasing.
428 #define _3sumF(a, b, c) do { \
432 _2sumF(__tmp, (a)); \
438 * Common routine to process the arguments to nan(), nanf(), and nanl().
440 void _scan_nan(uint32_t *__words
, int __num_words
, const char *__s
);
442 #if defined(_COMPLEX_H) || defined(_STDC_COMPLEX_H_)
445 * C99 specifies that complex numbers have the same representation as
446 * an array of two elements, where the first element is the real part
447 * and the second element is the imaginary part.
458 long double complex f
;
460 } long_double_complex
;
461 #define REALPART(z) ((z).a[0])
462 #define IMAGPART(z) ((z).a[1])
465 * Inline functions that can be used to construct complex values.
467 * The C99 standard intends x+I*y to be used for this, but x+I*y is
468 * currently unusable in general since gcc introduces many overflow,
469 * underflow, sign and efficiency bugs by rewriting I*y as
470 * (0.0+I)*(y+0.0*I) and laboriously computing the full complex product.
471 * In particular, I*Inf is corrupted to NaN+I*Inf, and I*-0 is corrupted
474 * The C11 standard introduced the macros CMPLX(), CMPLXF() and CMPLXL()
475 * to construct complex values. Compilers that conform to the C99
476 * standard require the following functions to avoid the above issues.
479 static __inline
float complex
480 CMPLXF(float x
, float y
)
491 static __inline
double complex
492 CMPLX(double x
, double y
)
503 static __inline
long double complex
504 CMPLXL(long double x
, long double y
)
506 long_double_complex z
;
514 #endif /* _COMPLEX_H || _STDC_COMPLEX_H_ */
516 #ifdef __GNUCLIKE_ASM
518 /* Asm versions of some functions. */
526 asm("cvtsd2si %1,%0" : "=r" (n
) : "x" (x
));
529 #define HAVE_EFFICIENT_IRINT
538 asm("fistl %0" : "=m" (n
) : "t" (x
));
541 #define HAVE_EFFICIENT_IRINT
544 #if defined(__amd64__) || defined(__i386__)
546 irintl(long double x
)
550 asm("fistl %0" : "=m" (n
) : "t" (x
));
553 #define HAVE_EFFICIENT_IRINTL
556 #endif /* __GNUCLIKE_ASM */
559 #if defined(__amd64__) || defined(__i386__)
560 #define breakpoint() asm("int $3")
564 #define breakpoint() raise(SIGTRAP)
568 /* Write a pari script to test things externally. */
572 #ifndef DOPRINT_SWIZZLE
573 #define DOPRINT_SWIZZLE 0
578 #define DOPRINT_START(xp) do { \
582 /* Hack to give more-problematic args. */ \
583 EXTRACT_LDBL80_WORDS(__hx, __lx, *xp); \
584 __lx ^= DOPRINT_SWIZZLE; \
585 INSERT_LDBL80_WORDS(*xp, __hx, __lx); \
586 printf("x = %.21Lg; ", (long double)*xp); \
588 #define DOPRINT_END1(v) \
589 printf("y = %.21Lg; z = 0; show(x, y, z);\n", (long double)(v))
590 #define DOPRINT_END2(hi, lo) \
591 printf("y = %.21Lg; z = %.21Lg; show(x, y, z);\n", \
592 (long double)(hi), (long double)(lo))
594 #elif defined(DOPRINT_D64)
596 #define DOPRINT_START(xp) do { \
597 uint32_t __hx, __lx; \
599 EXTRACT_WORDS(__hx, __lx, *xp); \
600 __lx ^= DOPRINT_SWIZZLE; \
601 INSERT_WORDS(*xp, __hx, __lx); \
602 printf("x = %.21Lg; ", (long double)*xp); \
604 #define DOPRINT_END1(v) \
605 printf("y = %.21Lg; z = 0; show(x, y, z);\n", (long double)(v))
606 #define DOPRINT_END2(hi, lo) \
607 printf("y = %.21Lg; z = %.21Lg; show(x, y, z);\n", \
608 (long double)(hi), (long double)(lo))
610 #elif defined(DOPRINT_F32)
612 #define DOPRINT_START(xp) do { \
615 GET_FLOAT_WORD(__hx, *xp); \
616 __hx ^= DOPRINT_SWIZZLE; \
617 SET_FLOAT_WORD(*xp, __hx); \
618 printf("x = %.21Lg; ", (long double)*xp); \
620 #define DOPRINT_END1(v) \
621 printf("y = %.21Lg; z = 0; show(x, y, z);\n", (long double)(v))
622 #define DOPRINT_END2(hi, lo) \
623 printf("y = %.21Lg; z = %.21Lg; show(x, y, z);\n", \
624 (long double)(hi), (long double)(lo))
626 #else /* !DOPRINT_LD80 && !DOPRINT_D64 (LD128 only) */
628 #ifndef DOPRINT_SWIZZLE_HIGH
629 #define DOPRINT_SWIZZLE_HIGH 0
632 #define DOPRINT_START(xp) do { \
633 uint64_t __lx, __llx; \
636 EXTRACT_LDBL128_WORDS(__hx, __lx, __llx, *xp); \
637 __llx ^= DOPRINT_SWIZZLE; \
638 __lx ^= DOPRINT_SWIZZLE_HIGH; \
639 INSERT_LDBL128_WORDS(*xp, __hx, __lx, __llx); \
640 printf("x = %.36Lg; ", (long double)*xp); \
642 #define DOPRINT_END1(v) \
643 printf("y = %.36Lg; z = 0; show(x, y, z);\n", (long double)(v))
644 #define DOPRINT_END2(hi, lo) \
645 printf("y = %.36Lg; z = %.36Lg; show(x, y, z);\n", \
646 (long double)(hi), (long double)(lo))
648 #endif /* DOPRINT_LD80 */
651 #define DOPRINT_START(xp)
652 #define DOPRINT_END1(v)
653 #define DOPRINT_END2(hi, lo)
656 #define RETURNP(x) do { \
660 #define RETURNPI(x) do { \
664 #define RETURN2P(x, y) do { \
665 DOPRINT_END2((x), (y)); \
666 RETURNF((x) + (y)); \
668 #define RETURN2PI(x, y) do { \
669 DOPRINT_END2((x), (y)); \
670 RETURNI((x) + (y)); \
673 #define RETURNSP(rp) do { \
676 RETURN2P((rp)->hi, (rp)->lo); \
678 #define RETURNSPI(rp) do { \
680 RETURNPI((rp)->hi); \
681 RETURN2PI((rp)->hi, (rp)->lo); \
684 #define SUM2P(x, y) ({ \
685 const __typeof (x) __x = (x); \
686 const __typeof (y) __y = (y); \
688 DOPRINT_END2(__x, __y); \
693 * ieee style elementary functions
695 * We rename functions here to improve other sources' diffability
698 #define __ieee754_sqrt sqrt
699 #define __ieee754_acos acos
700 #define __ieee754_acosh acosh
701 #define __ieee754_log log
702 #define __ieee754_log2 log2
703 #define __ieee754_atanh atanh
704 #define __ieee754_asin asin
705 #define __ieee754_atan2 atan2
706 #define __ieee754_exp exp
707 #define __ieee754_cosh cosh
708 #define __ieee754_fmod fmod
709 #define __ieee754_pow pow
710 #define __ieee754_lgamma lgamma
711 #define __ieee754_lgamma_r lgamma_r
712 #define __ieee754_log10 log10
713 #define __ieee754_sinh sinh
714 #define __ieee754_hypot hypot
715 #define __ieee754_j0 j0
716 #define __ieee754_j1 j1
717 #define __ieee754_y0 y0
718 #define __ieee754_y1 y1
719 #define __ieee754_jn jn
720 #define __ieee754_yn yn
721 #define __ieee754_remainder remainder
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_lgammaf_r lgammaf_r
735 #define __ieee754_log10f log10f
736 #define __ieee754_log2f log2f
737 #define __ieee754_sinhf sinhf
738 #define __ieee754_hypotf hypotf
739 #define __ieee754_j0f j0f
740 #define __ieee754_j1f j1f
741 #define __ieee754_y0f y0f
742 #define __ieee754_y1f y1f
743 #define __ieee754_jnf jnf
744 #define __ieee754_ynf ynf
745 #define __ieee754_remainderf remainderf
748 Deprecated functions: instead, use either the tgamma(3) or
749 the lgamma(3) functions, as appropriate.
751 #define __ieee754_gamma gamma
752 #define __ieee754_gamma_r gamma_r
753 #define __ieee754_gammaf gammaf
754 #define __ieee754_gammaf_r gammaf_r
756 Specified in POSIX.1-2001, but marked obsolescent.
757 removed in POSIX.1-2008, instead the use of scalbln(3),
758 scalblnf(3), or scalblnl(3) are recommended
760 #define __ieee754_scalb scalb
761 #define __ieee754_scalbf scalbf
763 /* Under FreeBSD, int32_t and int are the same thing. On AROS it may not be,
764 * which causes the build to fail. This is a FreeBSD bug (prototypes don't
765 * match the functions proper), so we work around it with defines below. */
767 /* fdlibm kernel function */
768 int __kernel_rem_pio2(double*,double*,int,int,int);
770 int __kernel_rem_pio2f(float*,float*,int,int,int,const int*);
772 int __kernel_rem_pio2f(float*,float*,int,int,int,const int32_t*);
775 /* double precision kernel functions */
776 #ifndef INLINE_REM_PIO2
778 int __ieee754_rem_pio2(double,double*);
780 int32_t __ieee754_rem_pio2(double,double*);
783 double __kernel_sin(double,double,int);
784 double __kernel_cos(double,double);
785 double __kernel_tan(double,double,int);
786 double __ldexp_exp(double,int);
787 #if defined(_COMPLEX_H) || defined(_STDC_COMPLEX_H_)
788 double complex __ldexp_cexp(double complex,int);
791 /* float precision kernel functions */
792 #ifndef INLINE_REM_PIO2F
794 int __ieee754_rem_pio2f(float,double*);
796 int32_t __ieee754_rem_pio2f(float,double*);
799 #ifndef INLINE_KERNEL_SINDF
800 float __kernel_sindf(double);
802 #ifndef INLINE_KERNEL_COSDF
803 float __kernel_cosdf(double);
805 #ifndef INLINE_KERNEL_TANDF
806 float __kernel_tandf(double,int);
808 float __ldexp_expf(float,int);
809 #if defined(_COMPLEX_H) || defined(_STDC_COMPLEX_H_)
810 float complex __ldexp_cexpf(float complex,int);
813 /* long double precision kernel functions */
814 long double __kernel_sinl(long double, long double, int);
815 long double __kernel_cosl(long double, long double);
816 long double __kernel_tanl(long double, long double, int);
818 #endif /* !_MATH_PRIVATE_H_ */