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// ANDROID
20//#include <complex.h>
21#include <endian.h>
22
23#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
24#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN
25union ldshape {
26	long double f;
27	struct {
28		uint64_t m;
29		uint16_t se;
30	} i;
31};
32#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN
33union ldshape {
34	long double f;
35	struct {
36		uint64_t lo;
37		uint32_t mid;
38		uint16_t top;
39		uint16_t se;
40	} i;
41	struct {
42		uint64_t lo;
43		uint64_t hi;
44	} i2;
45};
46#else
47#error Unsupported long double representation
48#endif
49
50#define FORCE_EVAL(x) do {                        \
51	if (sizeof(x) == sizeof(float)) {         \
52		volatile float __x;               \
53		__x = (x);                        \
54	} else if (sizeof(x) == sizeof(double)) { \
55		volatile double __x;              \
56		__x = (x);                        \
57	} else {                                  \
58		volatile long double __x;         \
59		__x = (x);                        \
60	}                                         \
61} while(0)
62
63/* Get two 32 bit ints from a double.  */
64#define EXTRACT_WORDS(hi,lo,d)                    \
65do {                                              \
66  union {double f; uint64_t i;} __u;              \
67  __u.f = (d);                                    \
68  (hi) = __u.i >> 32;                             \
69  (lo) = (uint32_t)__u.i;                         \
70} while (0)
71
72/* Get the more significant 32 bit int from a double.  */
73#define GET_HIGH_WORD(hi,d)                       \
74do {                                              \
75  union {double f; uint64_t i;} __u;              \
76  __u.f = (d);                                    \
77  (hi) = __u.i >> 32;                             \
78} while (0)
79
80/* Get the less significant 32 bit int from a double.  */
81#define GET_LOW_WORD(lo,d)                        \
82do {                                              \
83  union {double f; uint64_t i;} __u;              \
84  __u.f = (d);                                    \
85  (lo) = (uint32_t)__u.i;                         \
86} while (0)
87
88/* Set a double from two 32 bit ints.  */
89#define INSERT_WORDS(d,hi,lo)                     \
90do {                                              \
91  union {double f; uint64_t i;} __u;              \
92  __u.i = ((uint64_t)(hi)<<32) | (uint32_t)(lo);  \
93  (d) = __u.f;                                    \
94} while (0)
95
96/* Set the more significant 32 bits of a double from an int.  */
97#define SET_HIGH_WORD(d,hi)                       \
98do {                                              \
99  union {double f; uint64_t i;} __u;              \
100  __u.f = (d);                                    \
101  __u.i &= 0xffffffff;                            \
102  __u.i |= (uint64_t)(hi) << 32;                  \
103  (d) = __u.f;                                    \
104} while (0)
105
106/* Set the less significant 32 bits of a double from an int.  */
107#define SET_LOW_WORD(d,lo)                        \
108do {                                              \
109  union {double f; uint64_t i;} __u;              \
110  __u.f = (d);                                    \
111  __u.i &= 0xffffffff00000000ull;                 \
112  __u.i |= (uint32_t)(lo);                        \
113  (d) = __u.f;                                    \
114} while (0)
115
116/* Get a 32 bit int from a float.  */
117#define GET_FLOAT_WORD(w,d)                       \
118do {                                              \
119  union {float f; uint32_t i;} __u;               \
120  __u.f = (d);                                    \
121  (w) = __u.i;                                    \
122} while (0)
123
124/* Set a float from a 32 bit int.  */
125#define SET_FLOAT_WORD(d,w)                       \
126do {                                              \
127  union {float f; uint32_t i;} __u;               \
128  __u.i = (w);                                    \
129  (d) = __u.f;                                    \
130} while (0)
131
132/* fdlibm kernel functions */
133
134int    __rem_pio2_large(double*,double*,int,int,int);
135
136int    __rem_pio2(double,double*);
137double __sin(double,double,int);
138double __cos(double,double);
139double __tan(double,double,int);
140double __expo2(double);
141// ANDROID
142//double complex __ldexp_cexp(double complex,int);
143
144int    __rem_pio2f(float,double*);
145float  __sindf(double);
146float  __cosdf(double);
147float  __tandf(double,int);
148float  __expo2f(float);
149// ANDROID
150//float complex __ldexp_cexpf(float complex,int);
151
152int __rem_pio2l(long double, long double *);
153long double __sinl(long double, long double, int);
154long double __cosl(long double, long double);
155long double __tanl(long double, long double, int);
156
157/* polynomial evaluation */
158long double __polevll(long double, const long double *, int);
159long double __p1evll(long double, const long double *, int);
160
161#endif
162