revert between 56095 -> 55830 in arch
[AROS.git] / compiler / stdc / math / math_private.h
blobd32cc13433ccf02f2bf801388fd173ab8cf78150
1 /*
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
8 * is preserved.
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_
20 #include <complex.h>
22 #include <aros/system.h>
23 #include <stdint.h>
25 #include "fpmath.h"
26 #include "bsdsrc/math_private_openbsd.h"
28 //the following define is used to comment out gcc's incorrect section attributes
29 #if defined(__arm__)
30 #define SECTIONCOMMENT "\n@"
31 #else
32 #define SECTIONCOMMENT "\n#"
33 #endif
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
50 * ints.
53 #if AROS_BIG_ENDIAN
55 typedef union
57 double value;
58 struct
60 uint32_t msw;
61 uint32_t lsw;
62 } parts;
63 struct
65 uint64_t w;
66 } xparts;
67 } ieee_double_shape_type;
69 #endif
71 #if !AROS_BIG_ENDIAN
73 typedef union
75 double value;
76 struct
78 uint32_t lsw;
79 uint32_t msw;
80 } parts;
81 struct
83 uint64_t w;
84 } xparts;
85 } ieee_double_shape_type;
87 #endif
89 /* Get two 32 bit ints from a double. */
91 #define EXTRACT_WORDS(ix0,ix1,d) \
92 do { \
93 ieee_double_shape_type ew_u; \
94 ew_u.value = (d); \
95 (ix0) = ew_u.parts.msw; \
96 (ix1) = ew_u.parts.lsw; \
97 } while (0)
99 /* Get a 64-bit int from a double. */
100 #define EXTRACT_WORD64(ix,d) \
101 do { \
102 ieee_double_shape_type ew_u; \
103 ew_u.value = (d); \
104 (ix) = ew_u.xparts.w; \
105 } while (0)
107 /* Get the more significant 32 bit int from a double. */
109 #define GET_HIGH_WORD(i,d) \
110 do { \
111 ieee_double_shape_type gh_u; \
112 gh_u.value = (d); \
113 (i) = gh_u.parts.msw; \
114 } while (0)
116 /* Get the less significant 32 bit int from a double. */
118 #define GET_LOW_WORD(i,d) \
119 do { \
120 ieee_double_shape_type gl_u; \
121 gl_u.value = (d); \
122 (i) = gl_u.parts.lsw; \
123 } while (0)
125 /* Set a double from two 32 bit ints. */
127 #define INSERT_WORDS(d,ix0,ix1) \
128 do { \
129 ieee_double_shape_type iw_u; \
130 iw_u.parts.msw = (ix0); \
131 iw_u.parts.lsw = (ix1); \
132 (d) = iw_u.value; \
133 } while (0)
135 /* Set a double from a 64-bit int. */
136 #define INSERT_WORD64(d,ix) \
137 do { \
138 ieee_double_shape_type iw_u; \
139 iw_u.xparts.w = (ix); \
140 (d) = iw_u.value; \
141 } while (0)
143 /* Set the more significant 32 bits of a double from an int. */
145 #define SET_HIGH_WORD(d,v) \
146 do { \
147 ieee_double_shape_type sh_u; \
148 sh_u.value = (d); \
149 sh_u.parts.msw = (v); \
150 (d) = sh_u.value; \
151 } while (0)
153 /* Set the less significant 32 bits of a double from an int. */
155 #define SET_LOW_WORD(d,v) \
156 do { \
157 ieee_double_shape_type sl_u; \
158 sl_u.value = (d); \
159 sl_u.parts.lsw = (v); \
160 (d) = sl_u.value; \
161 } while (0)
164 * A union which permits us to convert between a float and a 32 bit
165 * int.
168 typedef union
170 float value;
171 /* FIXME: Assumes 32 bit int. */
172 unsigned int word;
173 } ieee_float_shape_type;
175 /* Get a 32 bit int from a float. */
177 #define GET_FLOAT_WORD(i,d) \
178 do { \
179 ieee_float_shape_type gf_u; \
180 gf_u.value = (d); \
181 (i) = gf_u.word; \
182 } while (0)
184 /* Set a float from a 32 bit int. */
186 #define SET_FLOAT_WORD(d,i) \
187 do { \
188 ieee_float_shape_type sf_u; \
189 sf_u.word = (i); \
190 (d) = sf_u.value; \
191 } while (0)
194 * Get expsign and mantissa as 16 bit and 64 bit ints from an 80 bit long
195 * double.
198 #define EXTRACT_LDBL80_WORDS(ix0,ix1,d) \
199 do { \
200 union IEEEl2bits ew_u; \
201 ew_u.e = (d); \
202 (ix0) = ew_u.xbits.expsign; \
203 (ix1) = ew_u.xbits.man; \
204 } while (0)
207 * Get expsign and mantissa as one 16 bit and two 64 bit ints from a 128 bit
208 * long double.
211 #define EXTRACT_LDBL128_WORDS(ix0,ix1,ix2,d) \
212 do { \
213 union IEEEl2bits ew_u; \
214 ew_u.e = (d); \
215 (ix0) = ew_u.xbits.expsign; \
216 (ix1) = ew_u.xbits.manh; \
217 (ix2) = ew_u.xbits.manl; \
218 } while (0)
220 /* Get expsign as a 16 bit int from a long double. */
222 #define GET_LDBL_EXPSIGN(i,d) \
223 do { \
224 union IEEEl2bits ge_u; \
225 ge_u.e = (d); \
226 (i) = ge_u.xbits.expsign; \
227 } while (0)
230 * Set an 80 bit long double from a 16 bit int expsign and a 64 bit int
231 * mantissa.
234 #define INSERT_LDBL80_WORDS(d,ix0,ix1) \
235 do { \
236 union IEEEl2bits iw_u; \
237 iw_u.xbits.expsign = (ix0); \
238 iw_u.xbits.man = (ix1); \
239 (d) = iw_u.e; \
240 } while (0)
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) \
248 do { \
249 union IEEEl2bits iw_u; \
250 iw_u.xbits.expsign = (ix0); \
251 iw_u.xbits.manh = (ix1); \
252 iw_u.xbits.manl = (ix2); \
253 (d) = iw_u.e; \
254 } while (0)
256 /* Set expsign of a long double from a 16 bit int. */
258 #define SET_LDBL_EXPSIGN(d,v) \
259 do { \
260 union IEEEl2bits se_u; \
261 se_u.e = (d); \
262 se_u.xbits.expsign = (v); \
263 (d) = se_u.e; \
264 } while (0)
266 #ifdef __i386__
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), \
272 #else
273 /* The above works on non-i386 too, but we use this to check v. */
274 #define LD80C(m, ex, v) { .e = (v), }
275 #endif
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))
283 #else
284 #define STRICT_ASSIGN(type, lval, rval) do { \
285 volatile type __lval; \
287 if (sizeof(type) >= sizeof(long double)) \
288 (lval) = (rval); \
289 else { \
290 __lval = (rval); \
291 (lval) = __lval; \
293 } while (0)
294 #endif
295 #else
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)
301 #define ENTERI() \
302 long double __retval; \
303 fp_prec_t __oprec; \
305 if ((__oprec = fpgetprec()) != FP_PE) \
306 fpsetprec(FP_PE)
307 #define RETURNI(x) do { \
308 __retval = (x); \
309 if (__oprec != FP_PE) \
310 fpsetprec(__oprec); \
311 RETURNF(__retval); \
312 } while (0)
313 #define ENTERV() \
314 fp_prec_t __oprec; \
316 if ((__oprec = fpgetprec()) != FP_PE) \
317 fpsetprec(FP_PE)
318 #define RETURNV() do { \
319 if (__oprec != FP_PE) \
320 fpsetprec(__oprec); \
321 return; \
322 } while (0)
323 #else
324 #define ENTERI()
325 #define RETURNI(x) RETURNF(x)
326 #define ENTERV()
327 #define RETURNV() return
328 #endif
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; \
340 __w = (a) + (b); \
341 __s = __w - (a); \
342 (b) = ((a) - (__w - __s)) + ((b) - __s); \
343 (a) = __w; \
344 } while (0)
347 * 2sumF algorithm.
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
365 * conversions.)
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.
374 #ifdef DEBUG
375 #define _2sumF(a, b) do { \
376 __typeof(a) __w; \
377 volatile __typeof(a) __ia, __ib, __r, __vw; \
379 __ia = (a); \
380 __ib = (b); \
381 assert(__ia == 0 || fabsl(__ia) >= fabsl(__ib)); \
383 __w = (a) + (b); \
384 (b) = ((a) - __w) + (b); \
385 (a) = __w; \
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; \
390 __r = __ia - __vw; \
391 __r += __ib; \
392 assert(__vw == (a) && __r == (b)); \
393 } while (0)
394 #else /* !DEBUG */
395 #define _2sumF(a, b) do { \
396 __typeof(a) __w; \
398 __w = (a) + (b); \
399 (b) = ((a) - __w) + (b); \
400 (a) = __w; \
401 } while (0)
402 #endif /* DEBUG */
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
422 * (a, b) may help.
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 { \
429 __typeof(a) __tmp; \
431 __tmp = (c); \
432 _2sumF(__tmp, (a)); \
433 (b) += (a); \
434 (a) = __tmp; \
435 } while (0)
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.
449 typedef union {
450 float complex f;
451 float a[2];
452 } float_complex;
453 typedef union {
454 double complex f;
455 double a[2];
456 } double_complex;
457 typedef union {
458 long double complex f;
459 long double a[2];
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
472 * to -0.0+I*0.0.
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.
478 #ifndef CMPLXF
479 static __inline float complex
480 CMPLXF(float x, float y)
482 float_complex z;
484 REALPART(z) = x;
485 IMAGPART(z) = y;
486 return (z.f);
488 #endif
490 #ifndef CMPLX
491 static __inline double complex
492 CMPLX(double x, double y)
494 double_complex z;
496 REALPART(z) = x;
497 IMAGPART(z) = y;
498 return (z.f);
500 #endif
502 #ifndef CMPLXL
503 static __inline long double complex
504 CMPLXL(long double x, long double y)
506 long_double_complex z;
508 REALPART(z) = x;
509 IMAGPART(z) = y;
510 return (z.f);
512 #endif
514 #endif /* _COMPLEX_H || _STDC_COMPLEX_H_ */
516 #ifdef __GNUCLIKE_ASM
518 /* Asm versions of some functions. */
520 #ifdef __amd64__
521 static __inline int
522 irint(double x)
524 int n;
526 asm("cvtsd2si %1,%0" : "=r" (n) : "x" (x));
527 return (n);
529 #define HAVE_EFFICIENT_IRINT
530 #endif
532 #ifdef __i386__
533 static __inline int
534 irint(double x)
536 int n;
538 asm("fistl %0" : "=m" (n) : "t" (x));
539 return (n);
541 #define HAVE_EFFICIENT_IRINT
542 #endif
544 #if defined(__amd64__) || defined(__i386__)
545 static __inline int
546 irintl(long double x)
548 int n;
550 asm("fistl %0" : "=m" (n) : "t" (x));
551 return (n);
553 #define HAVE_EFFICIENT_IRINTL
554 #endif
556 #endif /* __GNUCLIKE_ASM */
558 #ifdef DEBUG
559 #if defined(__amd64__) || defined(__i386__)
560 #define breakpoint() asm("int $3")
561 #else
562 #include <signal.h>
564 #define breakpoint() raise(SIGTRAP)
565 #endif
566 #endif
568 /* Write a pari script to test things externally. */
569 #ifdef DOPRINT
570 #include <stdio.h>
572 #ifndef DOPRINT_SWIZZLE
573 #define DOPRINT_SWIZZLE 0
574 #endif
576 #ifdef DOPRINT_LD80
578 #define DOPRINT_START(xp) do { \
579 uint64_t __lx; \
580 uint16_t __hx; \
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); \
587 } while (0)
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); \
603 } while (0)
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 { \
613 uint32_t __hx; \
615 GET_FLOAT_WORD(__hx, *xp); \
616 __hx ^= DOPRINT_SWIZZLE; \
617 SET_FLOAT_WORD(*xp, __hx); \
618 printf("x = %.21Lg; ", (long double)*xp); \
619 } while (0)
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
630 #endif
632 #define DOPRINT_START(xp) do { \
633 uint64_t __lx, __llx; \
634 uint16_t __hx; \
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); \
641 } while (0)
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 */
650 #else /* !DOPRINT */
651 #define DOPRINT_START(xp)
652 #define DOPRINT_END1(v)
653 #define DOPRINT_END2(hi, lo)
654 #endif /* DOPRINT */
656 #define RETURNP(x) do { \
657 DOPRINT_END1(x); \
658 RETURNF(x); \
659 } while (0)
660 #define RETURNPI(x) do { \
661 DOPRINT_END1(x); \
662 RETURNI(x); \
663 } while (0)
664 #define RETURN2P(x, y) do { \
665 DOPRINT_END2((x), (y)); \
666 RETURNF((x) + (y)); \
667 } while (0)
668 #define RETURN2PI(x, y) do { \
669 DOPRINT_END2((x), (y)); \
670 RETURNI((x) + (y)); \
671 } while (0)
672 #ifdef STRUCT_RETURN
673 #define RETURNSP(rp) do { \
674 if (!(rp)->lo_set) \
675 RETURNP((rp)->hi); \
676 RETURN2P((rp)->hi, (rp)->lo); \
677 } while (0)
678 #define RETURNSPI(rp) do { \
679 if (!(rp)->lo_set) \
680 RETURNPI((rp)->hi); \
681 RETURN2PI((rp)->hi, (rp)->lo); \
682 } while (0)
683 #endif
684 #define SUM2P(x, y) ({ \
685 const __typeof (x) __x = (x); \
686 const __typeof (y) __y = (y); \
688 DOPRINT_END2(__x, __y); \
689 __x + __y; \
693 * ieee style elementary functions
695 * We rename functions here to improve other sources' diffability
696 * against fdlibm.
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);
769 #ifndef __AROS__
770 int __kernel_rem_pio2f(float*,float*,int,int,int,const int*);
771 #else
772 int __kernel_rem_pio2f(float*,float*,int,int,int,const int32_t*);
773 #endif
775 /* double precision kernel functions */
776 #ifndef INLINE_REM_PIO2
777 #ifndef __AROS__
778 int __ieee754_rem_pio2(double,double*);
779 #else
780 int32_t __ieee754_rem_pio2(double,double*);
781 #endif
782 #endif
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);
789 #endif
791 /* float precision kernel functions */
792 #ifndef INLINE_REM_PIO2F
793 #ifndef __AROS__
794 int __ieee754_rem_pio2f(float,double*);
795 #else
796 int32_t __ieee754_rem_pio2f(float,double*);
797 #endif
798 #endif
799 #ifndef INLINE_KERNEL_SINDF
800 float __kernel_sindf(double);
801 #endif
802 #ifndef INLINE_KERNEL_COSDF
803 float __kernel_cosdf(double);
804 #endif
805 #ifndef INLINE_KERNEL_TANDF
806 float __kernel_tandf(double,int);
807 #endif
808 float __ldexp_expf(float,int);
809 #if defined(_COMPLEX_H) || defined(_STDC_COMPLEX_H_)
810 float complex __ldexp_cexpf(float complex,int);
811 #endif
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_ */