add .gitignore file
[musl] / src / math / math_private.h
1 /*
2  * ====================================================
3  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
4  *
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  * ====================================================
10  */
11
12 #ifndef _MATH_PRIVATE_H_
13 #define _MATH_PRIVATE_H_
14
15 #include <inttypes.h>
16
17 /*
18  * The original fdlibm code used statements like:
19  *      n0 = ((*(int*)&one)>>29)^1;             * index of high word *
20  *      ix0 = *(n0+(int*)&x);                   * high word of x *
21  *      ix1 = *((1-n0)+(int*)&x);               * low word of x *
22  * to dig two 32 bit words out of the 64 bit IEEE floating point
23  * value.  That is non-ANSI, and, moreover, the gcc instruction
24  * scheduler gets it wrong.  We instead use the following macros.
25  * Unlike the original code, we determine the endianness at compile
26  * time, not at run time; I don't see much benefit to selecting
27  * endianness at run time.
28  */
29
30 /*
31  * A union which permits us to convert between a double and two 32 bit
32  * ints.
33  */
34
35 typedef union
36 {
37   double value;
38   uint64_t words;
39 } ieee_double_shape_type;
40
41 /* Get two 32 bit ints from a double.  */
42
43 #define EXTRACT_WORDS(ix0,ix1,d)                                \
44 do {                                                            \
45   ieee_double_shape_type ew_u;                                  \
46   ew_u.value = (d);                                             \
47   (ix0) = ew_u.words >> 32;                                     \
48   (ix1) = (uint32_t)ew_u.words;                                 \
49 } while (0)
50
51 /* Get the more significant 32 bit int from a double.  */
52
53 #define GET_HIGH_WORD(i,d)                                      \
54 do {                                                            \
55   ieee_double_shape_type gh_u;                                  \
56   gh_u.value = (d);                                             \
57   (i) = gh_u.words >> 32;                                       \
58 } while (0)
59
60 /* Get the less significant 32 bit int from a double.  */
61
62 #define GET_LOW_WORD(i,d)                                       \
63 do {                                                            \
64   ieee_double_shape_type gl_u;                                  \
65   gl_u.value = (d);                                             \
66   (i) = (uint32_t)gl_u.words;                                   \
67 } while (0)
68
69 /* Set a double from two 32 bit ints.  */
70
71 #define INSERT_WORDS(d,ix0,ix1)                                 \
72 do {                                                            \
73   ieee_double_shape_type iw_u;                                  \
74   iw_u.words = ((uint64_t)(ix0) << 32) | (ix1);                 \
75   (d) = iw_u.value;                                             \
76 } while (0)
77
78 /* Set the more significant 32 bits of a double from an int.  */
79
80 #define SET_HIGH_WORD(d,v)                                      \
81 do {                                                            \
82   ieee_double_shape_type sh_u;                                  \
83   sh_u.value = (d);                                             \
84   sh_u.words &= 0xffffffff;                                     \
85   sh_u.words |= ((uint64_t)(v) << 32);                          \
86   (d) = sh_u.value;                                             \
87 } while (0)
88
89 /* Set the less significant 32 bits of a double from an int.  */
90
91 #define SET_LOW_WORD(d,v)                                       \
92 do {                                                            \
93   ieee_double_shape_type sl_u;                                  \
94   sl_u.value = (d);                                             \
95   sl_u.words &= 0xffffffff00000000ull;                          \
96   sl_u.words |= (uint32_t)(v);                                  \
97   (d) = sl_u.value;                                             \
98 } while (0)
99
100 /*
101  * A union which permits us to convert between a float and a 32 bit
102  * int.
103  */
104
105 typedef union
106 {
107   float value;
108   uint32_t word;
109 } ieee_float_shape_type;
110
111 /* Get a 32 bit int from a float.  */
112
113 #define GET_FLOAT_WORD(i,d)                                     \
114 do {                                                            \
115   ieee_float_shape_type gf_u;                                   \
116   gf_u.value = (d);                                             \
117   (i) = gf_u.word;                                              \
118 } while (0)
119
120 /* Set a float from a 32 bit int.  */
121
122 #define SET_FLOAT_WORD(d,i)                                     \
123 do {                                                            \
124   ieee_float_shape_type sf_u;                                   \
125   sf_u.word = (i);                                              \
126   (d) = sf_u.value;                                             \
127 } while (0)
128
129 /* fdlibm kernel function */
130 int     __ieee754_rem_pio2(double,double*);
131 double  __kernel_sin(double,double,int);
132 double  __kernel_cos(double,double);
133 double  __kernel_tan(double,double,int);
134 int     __kernel_rem_pio2(double*,double*,int,int,int,const int*);
135
136 /* float versions of fdlibm kernel functions */
137 int     __ieee754_rem_pio2f(float,float*);
138 float   __kernel_sinf(float,float,int);
139 float   __kernel_cosf(float,float);
140 float   __kernel_tanf(float,float,int);
141 int     __kernel_rem_pio2f(float*,float*,int,int,int,const int*);
142
143 #endif /* !_MATH_PRIVATE_H_ */