1 /**	$MirOS: src/lib/libm/src/math_private.h,v 1.5 2014/02/09 23:20:00 tg Exp $ */
2 /*	$OpenBSD: math_private.h,v 1.6 2002/02/16 21:27:27 millert Exp $	*/
3 /*
4  * ====================================================
5  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
6  *
7  * Developed at SunPro, a Sun Microsystems, Inc. business.
8  * Permission to use, copy, modify, and distribute this
9  * software is freely granted, provided that this notice
10  * is preserved.
11  * ====================================================
12  */
13 
14 /*
15  * from: @(#)fdlibm.h 5.1 93/09/24
16  * $NetBSD: math_private.h,v 1.16 2010/09/16 20:39:50 drochner Exp $
17  */
18 
19 #ifndef _MATH_PRIVATE_H_
20 #define _MATH_PRIVATE_H_ "$MirOS: src/lib/libm/src/math_private.h,v 1.5 2014/02/09 23:20:00 tg Exp $"
21 
22 #include <sys/types.h>
23 
24 /* The original fdlibm code used statements like:
25 	n0 = ((*(int*)&one)>>29)^1;		* index of high word *
26 	ix0 = *(n0+(int*)&x);			* high word of x *
27 	ix1 = *((1-n0)+(int*)&x);		* low word of x *
28    to dig two 32 bit words out of the 64 bit IEEE floating point
29    value.  That is non-ANSI, and, moreover, the gcc instruction
30    scheduler gets it wrong.  We instead use the following macros.
31    Unlike the original code, we determine the endianness at compile
32    time, not at run time; I don't see much benefit to selecting
33    endianness at run time.  */
34 
35 /* A union which permits us to convert between a double and two 32 bit
36    ints.  */
37 
38 /*
39  * The arm32 port is little endian except for the FP word order which is
40  * big endian.
41  */
42 
43 #if (BYTE_ORDER == BIG_ENDIAN) || defined(arm32)
44 
45 typedef union
46 {
47   double value;
48   struct
49   {
50     u_int32_t msw;
51     u_int32_t lsw;
52   } parts;
53 } ieee_double_shape_type;
54 
55 #endif
56 
57 #if (BYTE_ORDER == LITTLE_ENDIAN) && !defined(arm32)
58 
59 typedef union
60 {
61   double value;
62   struct
63   {
64     u_int32_t lsw;
65     u_int32_t msw;
66   } parts;
67 } ieee_double_shape_type;
68 
69 #endif
70 
71 /* Get two 32 bit ints from a double.  */
72 
73 #define EXTRACT_WORDS(ix0,ix1,d)				\
74 do {								\
75   ieee_double_shape_type ew_u;					\
76   ew_u.value = (d);						\
77   (ix0) = ew_u.parts.msw;					\
78   (ix1) = ew_u.parts.lsw;					\
79 } while (/*CONSTCOND*/0)
80 
81 /* Get the more significant 32 bit int from a double.  */
82 
83 #define GET_HIGH_WORD(i,d)					\
84 do {								\
85   ieee_double_shape_type gh_u;					\
86   gh_u.value = (d);						\
87   (i) = gh_u.parts.msw;						\
88 } while (/*CONSTCOND*/0)
89 
90 /* Get the less significant 32 bit int from a double.  */
91 
92 #define GET_LOW_WORD(i,d)					\
93 do {								\
94   ieee_double_shape_type gl_u;					\
95   gl_u.value = (d);						\
96   (i) = gl_u.parts.lsw;						\
97 } while (/*CONSTCOND*/0)
98 
99 /* Set a double from two 32 bit ints.  */
100 
101 #define INSERT_WORDS(d,ix0,ix1)					\
102 do {								\
103   ieee_double_shape_type iw_u;					\
104   iw_u.parts.msw = (ix0);					\
105   iw_u.parts.lsw = (ix1);					\
106   (d) = iw_u.value;						\
107 } while (/*CONSTCOND*/0)
108 
109 /* Set the more significant 32 bits of a double from an int.  */
110 
111 #define SET_HIGH_WORD(d,v)					\
112 do {								\
113   ieee_double_shape_type sh_u;					\
114   sh_u.value = (d);						\
115   sh_u.parts.msw = (v);						\
116   (d) = sh_u.value;						\
117 } while (/*CONSTCOND*/0)
118 
119 /* Set the less significant 32 bits of a double from an int.  */
120 
121 #define SET_LOW_WORD(d,v)					\
122 do {								\
123   ieee_double_shape_type sl_u;					\
124   sl_u.value = (d);						\
125   sl_u.parts.lsw = (v);						\
126   (d) = sl_u.value;						\
127 } while (/*CONSTCOND*/0)
128 
129 /* A union which permits us to convert between a float and a 32 bit
130    int.  */
131 
132 typedef union
133 {
134   float value;
135   u_int32_t word;
136 } ieee_float_shape_type;
137 
138 /* Get a 32 bit int from a float.  */
139 
140 #define GET_FLOAT_WORD(i,d)					\
141 do {								\
142   ieee_float_shape_type gf_u;					\
143   gf_u.value = (d);						\
144   (i) = gf_u.word;						\
145 } while (/*CONSTCOND*/0)
146 
147 /* Set a float from a 32 bit int.  */
148 
149 #define SET_FLOAT_WORD(d,i)					\
150 do {								\
151   ieee_float_shape_type sf_u;					\
152   sf_u.word = (i);						\
153   (d) = sf_u.value;						\
154 } while (/*CONSTCOND*/0)
155 
156 /*
157  * Attempt to get strict C99 semantics for assignment with non-C99 compilers.
158  */
159 #if FLT_EVAL_METHOD == 0 || __GNUC__ == 0
160 #define	STRICT_ASSIGN(type, lval, rval)	((lval) = (rval))
161 #else
162 #define	STRICT_ASSIGN(type, lval, rval) do {	\
163 	volatile type __lval;			\
164 						\
165 	if (sizeof(type) >= sizeof(double))	\
166 		(lval) = (rval);		\
167 	else {					\
168 		__lval = (rval);		\
169 		(lval) = __lval;		\
170 	}					\
171 } while (/*CONSTCOND*/0)
172 #endif
173 
174 #ifdef	_COMPLEX_H
175 
176 /*
177  * Quoting from ISO/IEC 9899:TC2:
178  *
179  * 6.2.5.13 Types
180  * Each complex type has the same representation and alignment requirements as
181  * an array type containing exactly two elements of the corresponding real type;
182  * the first element is equal to the real part, and the second element to the
183  * imaginary part, of the complex number.
184  */
185 typedef union {
186 	float complex z;
187 	float parts[2];
188 } float_complex;
189 
190 typedef union {
191 	double complex z;
192 	double parts[2];
193 } double_complex;
194 
195 #define	REAL_PART(z)	((z).parts[0])
196 #define	IMAG_PART(z)	((z).parts[1])
197 
198 #endif	/* _COMPLEX_H */
199 
200 /* ieee style elementary functions */
201 extern double __ieee754_sqrt(double);
202 extern double __ieee754_acos(double);
203 extern double __ieee754_acosh(double);
204 extern double __ieee754_log(double);
205 extern double __ieee754_atanh(double);
206 extern double __ieee754_asin(double);
207 extern double __ieee754_atan2(double,double);
208 extern double __ieee754_exp(double);
209 extern double __ieee754_cosh(double);
210 extern double __ieee754_fmod(double,double);
211 extern double __ieee754_pow(double,double);
212 extern double __ieee754_lgamma_r(double,int *);
213 extern double __ieee754_gamma_r(double,int *);
214 extern double __ieee754_lgamma(double);
215 extern double __ieee754_gamma(double);
216 extern double __ieee754_log10(double);
217 extern double __ieee754_log2(double);
218 extern double __ieee754_sinh(double);
219 extern double __ieee754_hypot(double,double);
220 extern double __ieee754_j0(double);
221 extern double __ieee754_j1(double);
222 extern double __ieee754_y0(double);
223 extern double __ieee754_y1(double);
224 extern double __ieee754_jn(int,double);
225 extern double __ieee754_yn(int,double);
226 extern double __ieee754_remainder(double,double);
227 extern int    __ieee754_rem_pio2(double,double*);
228 extern double __ieee754_scalb(double,double);
229 
230 /* fdlibm kernel function */
231 extern double __kernel_standard(double,double,int);
232 extern double __kernel_sin(double,double,int);
233 extern double __kernel_cos(double,double);
234 extern double __kernel_tan(double,double,int);
235 extern int    __kernel_rem_pio2(double*,double*,int,int,int,const int*);
236 
237 
238 /* ieee style elementary float functions */
239 extern float __ieee754_sqrtf(float);
240 extern float __ieee754_acosf(float);
241 extern float __ieee754_acoshf(float);
242 extern float __ieee754_logf(float);
243 extern float __ieee754_atanhf(float);
244 extern float __ieee754_asinf(float);
245 extern float __ieee754_atan2f(float,float);
246 extern float __ieee754_expf(float);
247 extern float __ieee754_coshf(float);
248 extern float __ieee754_fmodf(float,float);
249 extern float __ieee754_powf(float,float);
250 extern float __ieee754_lgammaf_r(float,int *);
251 extern float __ieee754_gammaf_r(float,int *);
252 extern float __ieee754_lgammaf(float);
253 extern float __ieee754_gammaf(float);
254 extern float __ieee754_log10f(float);
255 extern float __ieee754_log2f(float);
256 extern float __ieee754_sinhf(float);
257 extern float __ieee754_hypotf(float,float);
258 extern float __ieee754_j0f(float);
259 extern float __ieee754_j1f(float);
260 extern float __ieee754_y0f(float);
261 extern float __ieee754_y1f(float);
262 extern float __ieee754_jnf(int,float);
263 extern float __ieee754_ynf(int,float);
264 extern float __ieee754_remainderf(float,float);
265 extern int   __ieee754_rem_pio2f(float,float*);
266 extern float __ieee754_scalbf(float,float);
267 
268 /* float versions of fdlibm kernel functions */
269 extern float __kernel_sinf(float,float,int);
270 extern float __kernel_cosf(float,float);
271 extern float __kernel_tanf(float,float,int);
272 extern int   __kernel_rem_pio2f(float*,float*,int,int,int,const int*);
273 
274 #endif /* _MATH_PRIVATE_H_ */
275