xref: /aosp_15_r20/external/musl/src/internal/libm.h (revision c9945492fdd68bbe62686c5b452b4dc1be3f8453)
1*c9945492SAndroid Build Coastguard Worker #ifndef _LIBM_H
2*c9945492SAndroid Build Coastguard Worker #define _LIBM_H
3*c9945492SAndroid Build Coastguard Worker 
4*c9945492SAndroid Build Coastguard Worker #include <stdint.h>
5*c9945492SAndroid Build Coastguard Worker #include <float.h>
6*c9945492SAndroid Build Coastguard Worker #include <math.h>
7*c9945492SAndroid Build Coastguard Worker #include <endian.h>
8*c9945492SAndroid Build Coastguard Worker #include "fp_arch.h"
9*c9945492SAndroid Build Coastguard Worker 
10*c9945492SAndroid Build Coastguard Worker #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
11*c9945492SAndroid Build Coastguard Worker #elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN
12*c9945492SAndroid Build Coastguard Worker union ldshape {
13*c9945492SAndroid Build Coastguard Worker 	long double f;
14*c9945492SAndroid Build Coastguard Worker 	struct {
15*c9945492SAndroid Build Coastguard Worker 		uint64_t m;
16*c9945492SAndroid Build Coastguard Worker 		uint16_t se;
17*c9945492SAndroid Build Coastguard Worker 	} i;
18*c9945492SAndroid Build Coastguard Worker };
19*c9945492SAndroid Build Coastguard Worker #elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __BIG_ENDIAN
20*c9945492SAndroid Build Coastguard Worker /* This is the m68k variant of 80-bit long double, and this definition only works
21*c9945492SAndroid Build Coastguard Worker  * on archs where the alignment requirement of uint64_t is <= 4. */
22*c9945492SAndroid Build Coastguard Worker union ldshape {
23*c9945492SAndroid Build Coastguard Worker 	long double f;
24*c9945492SAndroid Build Coastguard Worker 	struct {
25*c9945492SAndroid Build Coastguard Worker 		uint16_t se;
26*c9945492SAndroid Build Coastguard Worker 		uint16_t pad;
27*c9945492SAndroid Build Coastguard Worker 		uint64_t m;
28*c9945492SAndroid Build Coastguard Worker 	} i;
29*c9945492SAndroid Build Coastguard Worker };
30*c9945492SAndroid Build Coastguard Worker #elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN
31*c9945492SAndroid Build Coastguard Worker union ldshape {
32*c9945492SAndroid Build Coastguard Worker 	long double f;
33*c9945492SAndroid Build Coastguard Worker 	struct {
34*c9945492SAndroid Build Coastguard Worker 		uint64_t lo;
35*c9945492SAndroid Build Coastguard Worker 		uint32_t mid;
36*c9945492SAndroid Build Coastguard Worker 		uint16_t top;
37*c9945492SAndroid Build Coastguard Worker 		uint16_t se;
38*c9945492SAndroid Build Coastguard Worker 	} i;
39*c9945492SAndroid Build Coastguard Worker 	struct {
40*c9945492SAndroid Build Coastguard Worker 		uint64_t lo;
41*c9945492SAndroid Build Coastguard Worker 		uint64_t hi;
42*c9945492SAndroid Build Coastguard Worker 	} i2;
43*c9945492SAndroid Build Coastguard Worker };
44*c9945492SAndroid Build Coastguard Worker #elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __BIG_ENDIAN
45*c9945492SAndroid Build Coastguard Worker union ldshape {
46*c9945492SAndroid Build Coastguard Worker 	long double f;
47*c9945492SAndroid Build Coastguard Worker 	struct {
48*c9945492SAndroid Build Coastguard Worker 		uint16_t se;
49*c9945492SAndroid Build Coastguard Worker 		uint16_t top;
50*c9945492SAndroid Build Coastguard Worker 		uint32_t mid;
51*c9945492SAndroid Build Coastguard Worker 		uint64_t lo;
52*c9945492SAndroid Build Coastguard Worker 	} i;
53*c9945492SAndroid Build Coastguard Worker 	struct {
54*c9945492SAndroid Build Coastguard Worker 		uint64_t hi;
55*c9945492SAndroid Build Coastguard Worker 		uint64_t lo;
56*c9945492SAndroid Build Coastguard Worker 	} i2;
57*c9945492SAndroid Build Coastguard Worker };
58*c9945492SAndroid Build Coastguard Worker #else
59*c9945492SAndroid Build Coastguard Worker #error Unsupported long double representation
60*c9945492SAndroid Build Coastguard Worker #endif
61*c9945492SAndroid Build Coastguard Worker 
62*c9945492SAndroid Build Coastguard Worker /* Support non-nearest rounding mode.  */
63*c9945492SAndroid Build Coastguard Worker #define WANT_ROUNDING 1
64*c9945492SAndroid Build Coastguard Worker /* Support signaling NaNs.  */
65*c9945492SAndroid Build Coastguard Worker #define WANT_SNAN 0
66*c9945492SAndroid Build Coastguard Worker 
67*c9945492SAndroid Build Coastguard Worker #if WANT_SNAN
68*c9945492SAndroid Build Coastguard Worker #error SNaN is unsupported
69*c9945492SAndroid Build Coastguard Worker #else
70*c9945492SAndroid Build Coastguard Worker #define issignalingf_inline(x) 0
71*c9945492SAndroid Build Coastguard Worker #define issignaling_inline(x) 0
72*c9945492SAndroid Build Coastguard Worker #endif
73*c9945492SAndroid Build Coastguard Worker 
74*c9945492SAndroid Build Coastguard Worker #ifndef TOINT_INTRINSICS
75*c9945492SAndroid Build Coastguard Worker #define TOINT_INTRINSICS 0
76*c9945492SAndroid Build Coastguard Worker #endif
77*c9945492SAndroid Build Coastguard Worker 
78*c9945492SAndroid Build Coastguard Worker #if TOINT_INTRINSICS
79*c9945492SAndroid Build Coastguard Worker /* Round x to nearest int in all rounding modes, ties have to be rounded
80*c9945492SAndroid Build Coastguard Worker    consistently with converttoint so the results match.  If the result
81*c9945492SAndroid Build Coastguard Worker    would be outside of [-2^31, 2^31-1] then the semantics is unspecified.  */
82*c9945492SAndroid Build Coastguard Worker static double_t roundtoint(double_t);
83*c9945492SAndroid Build Coastguard Worker 
84*c9945492SAndroid Build Coastguard Worker /* Convert x to nearest int in all rounding modes, ties have to be rounded
85*c9945492SAndroid Build Coastguard Worker    consistently with roundtoint.  If the result is not representible in an
86*c9945492SAndroid Build Coastguard Worker    int32_t then the semantics is unspecified.  */
87*c9945492SAndroid Build Coastguard Worker static int32_t converttoint(double_t);
88*c9945492SAndroid Build Coastguard Worker #endif
89*c9945492SAndroid Build Coastguard Worker 
90*c9945492SAndroid Build Coastguard Worker /* Helps static branch prediction so hot path can be better optimized.  */
91*c9945492SAndroid Build Coastguard Worker #ifdef __GNUC__
92*c9945492SAndroid Build Coastguard Worker #define predict_true(x) __builtin_expect(!!(x), 1)
93*c9945492SAndroid Build Coastguard Worker #define predict_false(x) __builtin_expect(x, 0)
94*c9945492SAndroid Build Coastguard Worker #else
95*c9945492SAndroid Build Coastguard Worker #define predict_true(x) (x)
96*c9945492SAndroid Build Coastguard Worker #define predict_false(x) (x)
97*c9945492SAndroid Build Coastguard Worker #endif
98*c9945492SAndroid Build Coastguard Worker 
99*c9945492SAndroid Build Coastguard Worker /* Evaluate an expression as the specified type. With standard excess
100*c9945492SAndroid Build Coastguard Worker    precision handling a type cast or assignment is enough (with
101*c9945492SAndroid Build Coastguard Worker    -ffloat-store an assignment is required, in old compilers argument
102*c9945492SAndroid Build Coastguard Worker    passing and return statement may not drop excess precision).  */
103*c9945492SAndroid Build Coastguard Worker 
eval_as_float(float x)104*c9945492SAndroid Build Coastguard Worker static inline float eval_as_float(float x)
105*c9945492SAndroid Build Coastguard Worker {
106*c9945492SAndroid Build Coastguard Worker 	float y = x;
107*c9945492SAndroid Build Coastguard Worker 	return y;
108*c9945492SAndroid Build Coastguard Worker }
109*c9945492SAndroid Build Coastguard Worker 
eval_as_double(double x)110*c9945492SAndroid Build Coastguard Worker static inline double eval_as_double(double x)
111*c9945492SAndroid Build Coastguard Worker {
112*c9945492SAndroid Build Coastguard Worker 	double y = x;
113*c9945492SAndroid Build Coastguard Worker 	return y;
114*c9945492SAndroid Build Coastguard Worker }
115*c9945492SAndroid Build Coastguard Worker 
116*c9945492SAndroid Build Coastguard Worker /* fp_barrier returns its input, but limits code transformations
117*c9945492SAndroid Build Coastguard Worker    as if it had a side-effect (e.g. observable io) and returned
118*c9945492SAndroid Build Coastguard Worker    an arbitrary value.  */
119*c9945492SAndroid Build Coastguard Worker 
120*c9945492SAndroid Build Coastguard Worker #ifndef fp_barrierf
121*c9945492SAndroid Build Coastguard Worker #define fp_barrierf fp_barrierf
fp_barrierf(float x)122*c9945492SAndroid Build Coastguard Worker static inline float fp_barrierf(float x)
123*c9945492SAndroid Build Coastguard Worker {
124*c9945492SAndroid Build Coastguard Worker 	volatile float y = x;
125*c9945492SAndroid Build Coastguard Worker 	return y;
126*c9945492SAndroid Build Coastguard Worker }
127*c9945492SAndroid Build Coastguard Worker #endif
128*c9945492SAndroid Build Coastguard Worker 
129*c9945492SAndroid Build Coastguard Worker #ifndef fp_barrier
130*c9945492SAndroid Build Coastguard Worker #define fp_barrier fp_barrier
fp_barrier(double x)131*c9945492SAndroid Build Coastguard Worker static inline double fp_barrier(double x)
132*c9945492SAndroid Build Coastguard Worker {
133*c9945492SAndroid Build Coastguard Worker 	volatile double y = x;
134*c9945492SAndroid Build Coastguard Worker 	return y;
135*c9945492SAndroid Build Coastguard Worker }
136*c9945492SAndroid Build Coastguard Worker #endif
137*c9945492SAndroid Build Coastguard Worker 
138*c9945492SAndroid Build Coastguard Worker #ifndef fp_barrierl
139*c9945492SAndroid Build Coastguard Worker #define fp_barrierl fp_barrierl
fp_barrierl(long double x)140*c9945492SAndroid Build Coastguard Worker static inline long double fp_barrierl(long double x)
141*c9945492SAndroid Build Coastguard Worker {
142*c9945492SAndroid Build Coastguard Worker 	volatile long double y = x;
143*c9945492SAndroid Build Coastguard Worker 	return y;
144*c9945492SAndroid Build Coastguard Worker }
145*c9945492SAndroid Build Coastguard Worker #endif
146*c9945492SAndroid Build Coastguard Worker 
147*c9945492SAndroid Build Coastguard Worker /* fp_force_eval ensures that the input value is computed when that's
148*c9945492SAndroid Build Coastguard Worker    otherwise unused.  To prevent the constant folding of the input
149*c9945492SAndroid Build Coastguard Worker    expression, an additional fp_barrier may be needed or a compilation
150*c9945492SAndroid Build Coastguard Worker    mode that does so (e.g. -frounding-math in gcc). Then it can be
151*c9945492SAndroid Build Coastguard Worker    used to evaluate an expression for its fenv side-effects only.   */
152*c9945492SAndroid Build Coastguard Worker 
153*c9945492SAndroid Build Coastguard Worker #ifndef fp_force_evalf
154*c9945492SAndroid Build Coastguard Worker #define fp_force_evalf fp_force_evalf
fp_force_evalf(float x)155*c9945492SAndroid Build Coastguard Worker static inline void fp_force_evalf(float x)
156*c9945492SAndroid Build Coastguard Worker {
157*c9945492SAndroid Build Coastguard Worker 	volatile float y;
158*c9945492SAndroid Build Coastguard Worker 	y = x;
159*c9945492SAndroid Build Coastguard Worker }
160*c9945492SAndroid Build Coastguard Worker #endif
161*c9945492SAndroid Build Coastguard Worker 
162*c9945492SAndroid Build Coastguard Worker #ifndef fp_force_eval
163*c9945492SAndroid Build Coastguard Worker #define fp_force_eval fp_force_eval
fp_force_eval(double x)164*c9945492SAndroid Build Coastguard Worker static inline void fp_force_eval(double x)
165*c9945492SAndroid Build Coastguard Worker {
166*c9945492SAndroid Build Coastguard Worker 	volatile double y;
167*c9945492SAndroid Build Coastguard Worker 	y = x;
168*c9945492SAndroid Build Coastguard Worker }
169*c9945492SAndroid Build Coastguard Worker #endif
170*c9945492SAndroid Build Coastguard Worker 
171*c9945492SAndroid Build Coastguard Worker #ifndef fp_force_evall
172*c9945492SAndroid Build Coastguard Worker #define fp_force_evall fp_force_evall
fp_force_evall(long double x)173*c9945492SAndroid Build Coastguard Worker static inline void fp_force_evall(long double x)
174*c9945492SAndroid Build Coastguard Worker {
175*c9945492SAndroid Build Coastguard Worker 	volatile long double y;
176*c9945492SAndroid Build Coastguard Worker 	y = x;
177*c9945492SAndroid Build Coastguard Worker }
178*c9945492SAndroid Build Coastguard Worker #endif
179*c9945492SAndroid Build Coastguard Worker 
180*c9945492SAndroid Build Coastguard Worker #define FORCE_EVAL(x) do {                        \
181*c9945492SAndroid Build Coastguard Worker 	if (sizeof(x) == sizeof(float)) {         \
182*c9945492SAndroid Build Coastguard Worker 		fp_force_evalf(x);                \
183*c9945492SAndroid Build Coastguard Worker 	} else if (sizeof(x) == sizeof(double)) { \
184*c9945492SAndroid Build Coastguard Worker 		fp_force_eval(x);                 \
185*c9945492SAndroid Build Coastguard Worker 	} else {                                  \
186*c9945492SAndroid Build Coastguard Worker 		fp_force_evall(x);                \
187*c9945492SAndroid Build Coastguard Worker 	}                                         \
188*c9945492SAndroid Build Coastguard Worker } while(0)
189*c9945492SAndroid Build Coastguard Worker 
190*c9945492SAndroid Build Coastguard Worker #define asuint(f) ((union{float _f; uint32_t _i;}){f})._i
191*c9945492SAndroid Build Coastguard Worker #define asfloat(i) ((union{uint32_t _i; float _f;}){i})._f
192*c9945492SAndroid Build Coastguard Worker #define asuint64(f) ((union{double _f; uint64_t _i;}){f})._i
193*c9945492SAndroid Build Coastguard Worker #define asdouble(i) ((union{uint64_t _i; double _f;}){i})._f
194*c9945492SAndroid Build Coastguard Worker 
195*c9945492SAndroid Build Coastguard Worker #define EXTRACT_WORDS(hi,lo,d)                    \
196*c9945492SAndroid Build Coastguard Worker do {                                              \
197*c9945492SAndroid Build Coastguard Worker   uint64_t __u = asuint64(d);                     \
198*c9945492SAndroid Build Coastguard Worker   (hi) = __u >> 32;                               \
199*c9945492SAndroid Build Coastguard Worker   (lo) = (uint32_t)__u;                           \
200*c9945492SAndroid Build Coastguard Worker } while (0)
201*c9945492SAndroid Build Coastguard Worker 
202*c9945492SAndroid Build Coastguard Worker #define GET_HIGH_WORD(hi,d)                       \
203*c9945492SAndroid Build Coastguard Worker do {                                              \
204*c9945492SAndroid Build Coastguard Worker   (hi) = asuint64(d) >> 32;                       \
205*c9945492SAndroid Build Coastguard Worker } while (0)
206*c9945492SAndroid Build Coastguard Worker 
207*c9945492SAndroid Build Coastguard Worker #define GET_LOW_WORD(lo,d)                        \
208*c9945492SAndroid Build Coastguard Worker do {                                              \
209*c9945492SAndroid Build Coastguard Worker   (lo) = (uint32_t)asuint64(d);                   \
210*c9945492SAndroid Build Coastguard Worker } while (0)
211*c9945492SAndroid Build Coastguard Worker 
212*c9945492SAndroid Build Coastguard Worker #define INSERT_WORDS(d,hi,lo)                     \
213*c9945492SAndroid Build Coastguard Worker do {                                              \
214*c9945492SAndroid Build Coastguard Worker   (d) = asdouble(((uint64_t)(hi)<<32) | (uint32_t)(lo)); \
215*c9945492SAndroid Build Coastguard Worker } while (0)
216*c9945492SAndroid Build Coastguard Worker 
217*c9945492SAndroid Build Coastguard Worker #define SET_HIGH_WORD(d,hi)                       \
218*c9945492SAndroid Build Coastguard Worker   INSERT_WORDS(d, hi, (uint32_t)asuint64(d))
219*c9945492SAndroid Build Coastguard Worker 
220*c9945492SAndroid Build Coastguard Worker #define SET_LOW_WORD(d,lo)                        \
221*c9945492SAndroid Build Coastguard Worker   INSERT_WORDS(d, asuint64(d)>>32, lo)
222*c9945492SAndroid Build Coastguard Worker 
223*c9945492SAndroid Build Coastguard Worker #define GET_FLOAT_WORD(w,d)                       \
224*c9945492SAndroid Build Coastguard Worker do {                                              \
225*c9945492SAndroid Build Coastguard Worker   (w) = asuint(d);                                \
226*c9945492SAndroid Build Coastguard Worker } while (0)
227*c9945492SAndroid Build Coastguard Worker 
228*c9945492SAndroid Build Coastguard Worker #define SET_FLOAT_WORD(d,w)                       \
229*c9945492SAndroid Build Coastguard Worker do {                                              \
230*c9945492SAndroid Build Coastguard Worker   (d) = asfloat(w);                               \
231*c9945492SAndroid Build Coastguard Worker } while (0)
232*c9945492SAndroid Build Coastguard Worker 
233*c9945492SAndroid Build Coastguard Worker hidden int    __rem_pio2_large(double*,double*,int,int,int);
234*c9945492SAndroid Build Coastguard Worker 
235*c9945492SAndroid Build Coastguard Worker hidden int    __rem_pio2(double,double*);
236*c9945492SAndroid Build Coastguard Worker hidden double __sin(double,double,int);
237*c9945492SAndroid Build Coastguard Worker hidden double __cos(double,double);
238*c9945492SAndroid Build Coastguard Worker hidden double __tan(double,double,int);
239*c9945492SAndroid Build Coastguard Worker hidden double __expo2(double,double);
240*c9945492SAndroid Build Coastguard Worker 
241*c9945492SAndroid Build Coastguard Worker hidden int    __rem_pio2f(float,double*);
242*c9945492SAndroid Build Coastguard Worker hidden float  __sindf(double);
243*c9945492SAndroid Build Coastguard Worker hidden float  __cosdf(double);
244*c9945492SAndroid Build Coastguard Worker hidden float  __tandf(double,int);
245*c9945492SAndroid Build Coastguard Worker hidden float  __expo2f(float,float);
246*c9945492SAndroid Build Coastguard Worker 
247*c9945492SAndroid Build Coastguard Worker hidden int __rem_pio2l(long double, long double *);
248*c9945492SAndroid Build Coastguard Worker hidden long double __sinl(long double, long double, int);
249*c9945492SAndroid Build Coastguard Worker hidden long double __cosl(long double, long double);
250*c9945492SAndroid Build Coastguard Worker hidden long double __tanl(long double, long double, int);
251*c9945492SAndroid Build Coastguard Worker 
252*c9945492SAndroid Build Coastguard Worker hidden long double __polevll(long double, const long double *, int);
253*c9945492SAndroid Build Coastguard Worker hidden long double __p1evll(long double, const long double *, int);
254*c9945492SAndroid Build Coastguard Worker 
255*c9945492SAndroid Build Coastguard Worker extern int __signgam;
256*c9945492SAndroid Build Coastguard Worker hidden double __lgamma_r(double, int *);
257*c9945492SAndroid Build Coastguard Worker hidden float __lgammaf_r(float, int *);
258*c9945492SAndroid Build Coastguard Worker 
259*c9945492SAndroid Build Coastguard Worker /* error handling functions */
260*c9945492SAndroid Build Coastguard Worker hidden float __math_xflowf(uint32_t, float);
261*c9945492SAndroid Build Coastguard Worker hidden float __math_uflowf(uint32_t);
262*c9945492SAndroid Build Coastguard Worker hidden float __math_oflowf(uint32_t);
263*c9945492SAndroid Build Coastguard Worker hidden float __math_divzerof(uint32_t);
264*c9945492SAndroid Build Coastguard Worker hidden float __math_invalidf(float);
265*c9945492SAndroid Build Coastguard Worker hidden double __math_xflow(uint32_t, double);
266*c9945492SAndroid Build Coastguard Worker hidden double __math_uflow(uint32_t);
267*c9945492SAndroid Build Coastguard Worker hidden double __math_oflow(uint32_t);
268*c9945492SAndroid Build Coastguard Worker hidden double __math_divzero(uint32_t);
269*c9945492SAndroid Build Coastguard Worker hidden double __math_invalid(double);
270*c9945492SAndroid Build Coastguard Worker #if LDBL_MANT_DIG != DBL_MANT_DIG
271*c9945492SAndroid Build Coastguard Worker hidden long double __math_invalidl(long double);
272*c9945492SAndroid Build Coastguard Worker #endif
273*c9945492SAndroid Build Coastguard Worker 
274*c9945492SAndroid Build Coastguard Worker #endif
275