fix namespace issues for lgamma, etc.
[musl] / src / internal / libm.h
1 /* origin: FreeBSD /usr/src/lib/msun/src/math_private.h */
2 /*
3  * ====================================================
4  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5  *
6  * Developed at SunPro, a Sun Microsystems, Inc. business.
7  * Permission to use, copy, modify, and distribute this
8  * software is freely granted, provided that this notice
9  * is preserved.
10  * ====================================================
11  */
12
13 #ifndef _LIBM_H
14 #define _LIBM_H
15
16 #include <stdint.h>
17 #include <float.h>
18 #include <math.h>
19 #include <complex.h>
20
21 #include "longdbl.h"
22
23 #include "libc.h"
24
25 union fshape {
26         float value;
27         uint32_t bits;
28 };
29
30 union dshape {
31         double value;
32         uint64_t bits;
33 };
34
35 /* Get two 32 bit ints from a double.  */
36 #define EXTRACT_WORDS(hi,lo,d)                                  \
37 do {                                                            \
38   union dshape __u;                                             \
39   __u.value = (d);                                              \
40   (hi) = __u.bits >> 32;                                        \
41   (lo) = (uint32_t)__u.bits;                                    \
42 } while (0)
43
44 /* Get a 64 bit int from a double.  */
45 #define EXTRACT_WORD64(i,d)                                     \
46 do {                                                            \
47   union dshape __u;                                             \
48   __u.value = (d);                                              \
49   (i) = __u.bits;                                               \
50 } while (0)
51
52 /* Get the more significant 32 bit int from a double.  */
53 #define GET_HIGH_WORD(i,d)                                      \
54 do {                                                            \
55   union dshape __u;                                             \
56   __u.value = (d);                                              \
57   (i) = __u.bits >> 32;                                         \
58 } while (0)
59
60 /* Get the less significant 32 bit int from a double.  */
61 #define GET_LOW_WORD(i,d)                                       \
62 do {                                                            \
63   union dshape __u;                                             \
64   __u.value = (d);                                              \
65   (i) = (uint32_t)__u.bits;                                     \
66 } while (0)
67
68 /* Set a double from two 32 bit ints.  */
69 #define INSERT_WORDS(d,hi,lo)                                   \
70 do {                                                            \
71   union dshape __u;                                             \
72   __u.bits = ((uint64_t)(hi) << 32) | (uint32_t)(lo);           \
73   (d) = __u.value;                                              \
74 } while (0)
75
76 /* Set a double from a 64 bit int.  */
77 #define INSERT_WORD64(d,i)                                      \
78 do {                                                            \
79   union dshape __u;                                             \
80   __u.bits = (i);                                               \
81   (d) = __u.value;                                              \
82 } while (0)
83
84 /* Set the more significant 32 bits of a double from an int.  */
85 #define SET_HIGH_WORD(d,hi)                                     \
86 do {                                                            \
87   union dshape __u;                                             \
88   __u.value = (d);                                              \
89   __u.bits &= 0xffffffff;                                       \
90   __u.bits |= (uint64_t)(hi) << 32;                             \
91   (d) = __u.value;                                              \
92 } while (0)
93
94 /* Set the less significant 32 bits of a double from an int.  */
95 #define SET_LOW_WORD(d,lo)                                      \
96 do {                                                            \
97   union dshape __u;                                             \
98   __u.value = (d);                                              \
99   __u.bits &= 0xffffffff00000000ull;                            \
100   __u.bits |= (uint32_t)(lo);                                   \
101   (d) = __u.value;                                              \
102 } while (0)
103
104 /* Get a 32 bit int from a float.  */
105 #define GET_FLOAT_WORD(i,d)                                     \
106 do {                                                            \
107   union fshape __u;                                             \
108   __u.value = (d);                                              \
109   (i) = __u.bits;                                               \
110 } while (0)
111
112 /* Set a float from a 32 bit int.  */
113 #define SET_FLOAT_WORD(d,i)                                     \
114 do {                                                            \
115   union fshape __u;                                             \
116   __u.bits = (i);                                               \
117   (d) = __u.value;                                              \
118 } while (0)
119
120 /* fdlibm kernel functions */
121
122 int    __rem_pio2_large(double*,double*,int,int,int);
123
124 int    __rem_pio2(double,double*);
125 double __sin(double,double,int);
126 double __cos(double,double);
127 double __tan(double,double,int);
128 double __expo2(double);
129 double complex __ldexp_cexp(double complex,int);
130
131 int    __rem_pio2f(float,double*);
132 float  __sindf(double);
133 float  __cosdf(double);
134 float  __tandf(double,int);
135 float  __expo2f(float);
136 float complex __ldexp_cexpf(float complex,int);
137
138 long double __sinl(long double, long double, int);
139 long double __cosl(long double, long double);
140 long double __tanl(long double, long double, int);
141
142 /* polynomial evaluation */
143 long double __polevll(long double, long double *, int);
144 long double __p1evll(long double, long double *, int);
145
146 // FIXME: not needed when -fexcess-precision=standard is supported (>=gcc4.5)
147 /*
148  * Attempt to get strict C99 semantics for assignment with non-C99 compilers.
149  */
150 #if 1
151 #define STRICT_ASSIGN(type, lval, rval) do {    \
152         volatile type __v = (rval);             \
153         (lval) = __v;                           \
154 } while (0)
155 #else
156 #define STRICT_ASSIGN(type, lval, rval) ((lval) = (type)(rval))
157 #endif
158
159
160 /* complex */
161
162 union dcomplex {
163         double complex z;
164         double a[2];
165 };
166 union fcomplex {
167         float complex z;
168         float a[2];
169 };
170 union lcomplex {
171         long double complex z;
172         long double a[2];
173 };
174
175 // FIXME: move to complex.h ?
176 #define creal(z) ((double)(z))
177 #define crealf(z) ((float)(z))
178 #define creall(z) ((long double)(z))
179 #define cimag(z) ((union dcomplex){(z)}.a[1])
180 #define cimagf(z) ((union fcomplex){(z)}.a[1])
181 #define cimagl(z) ((union lcomplex){(z)}.a[1])
182
183 /* x + y*I is not supported properly by gcc */
184 #define cpack(x,y) ((union dcomplex){.a={(x),(y)}}.z)
185 #define cpackf(x,y) ((union fcomplex){.a={(x),(y)}}.z)
186 #define cpackl(x,y) ((union lcomplex){.a={(x),(y)}}.z)
187
188 #endif