1 |
|
|
/* $OpenBSD: math_private.h,v 1.18 2016/09/12 19:47:02 guenther Exp $ */ |
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 |
|
|
/* |
14 |
|
|
* from: @(#)fdlibm.h 5.1 93/09/24 |
15 |
|
|
*/ |
16 |
|
|
|
17 |
|
|
#ifndef _MATH_PRIVATE_H_ |
18 |
|
|
#define _MATH_PRIVATE_H_ |
19 |
|
|
|
20 |
|
|
#include <sys/types.h> |
21 |
|
|
|
22 |
|
|
/* The original fdlibm code used statements like: |
23 |
|
|
n0 = ((*(int*)&one)>>29)^1; * index of high word * |
24 |
|
|
ix0 = *(n0+(int*)&x); * high word of x * |
25 |
|
|
ix1 = *((1-n0)+(int*)&x); * low word of x * |
26 |
|
|
to dig two 32 bit words out of the 64 bit IEEE floating point |
27 |
|
|
value. That is non-ANSI, and, moreover, the gcc instruction |
28 |
|
|
scheduler gets it wrong. We instead use the following macros. |
29 |
|
|
Unlike the original code, we determine the endianness at compile |
30 |
|
|
time, not at run time; I don't see much benefit to selecting |
31 |
|
|
endianness at run time. */ |
32 |
|
|
|
33 |
|
|
/* A union which permits us to convert between a long double and |
34 |
|
|
four 32 bit ints. */ |
35 |
|
|
|
36 |
|
|
#if BYTE_ORDER == BIG_ENDIAN |
37 |
|
|
|
38 |
|
|
typedef union |
39 |
|
|
{ |
40 |
|
|
long double value; |
41 |
|
|
struct { |
42 |
|
|
u_int32_t mswhi; |
43 |
|
|
u_int32_t mswlo; |
44 |
|
|
u_int32_t lswhi; |
45 |
|
|
u_int32_t lswlo; |
46 |
|
|
} parts32; |
47 |
|
|
struct { |
48 |
|
|
u_int64_t msw; |
49 |
|
|
u_int64_t lsw; |
50 |
|
|
} parts64; |
51 |
|
|
} ieee_quad_shape_type; |
52 |
|
|
|
53 |
|
|
#endif |
54 |
|
|
|
55 |
|
|
#if BYTE_ORDER == LITTLE_ENDIAN |
56 |
|
|
|
57 |
|
|
typedef union |
58 |
|
|
{ |
59 |
|
|
long double value; |
60 |
|
|
struct { |
61 |
|
|
u_int32_t lswlo; |
62 |
|
|
u_int32_t lswhi; |
63 |
|
|
u_int32_t mswlo; |
64 |
|
|
u_int32_t mswhi; |
65 |
|
|
} parts32; |
66 |
|
|
struct { |
67 |
|
|
u_int64_t lsw; |
68 |
|
|
u_int64_t msw; |
69 |
|
|
} parts64; |
70 |
|
|
} ieee_quad_shape_type; |
71 |
|
|
|
72 |
|
|
#endif |
73 |
|
|
|
74 |
|
|
/* Get two 64 bit ints from a long double. */ |
75 |
|
|
|
76 |
|
|
#define GET_LDOUBLE_WORDS64(ix0,ix1,d) \ |
77 |
|
|
do { \ |
78 |
|
|
ieee_quad_shape_type qw_u; \ |
79 |
|
|
qw_u.value = (d); \ |
80 |
|
|
(ix0) = qw_u.parts64.msw; \ |
81 |
|
|
(ix1) = qw_u.parts64.lsw; \ |
82 |
|
|
} while (0) |
83 |
|
|
|
84 |
|
|
/* Set a long double from two 64 bit ints. */ |
85 |
|
|
|
86 |
|
|
#define SET_LDOUBLE_WORDS64(d,ix0,ix1) \ |
87 |
|
|
do { \ |
88 |
|
|
ieee_quad_shape_type qw_u; \ |
89 |
|
|
qw_u.parts64.msw = (ix0); \ |
90 |
|
|
qw_u.parts64.lsw = (ix1); \ |
91 |
|
|
(d) = qw_u.value; \ |
92 |
|
|
} while (0) |
93 |
|
|
|
94 |
|
|
/* Get the more significant 64 bits of a long double mantissa. */ |
95 |
|
|
|
96 |
|
|
#define GET_LDOUBLE_MSW64(v,d) \ |
97 |
|
|
do { \ |
98 |
|
|
ieee_quad_shape_type sh_u; \ |
99 |
|
|
sh_u.value = (d); \ |
100 |
|
|
(v) = sh_u.parts64.msw; \ |
101 |
|
|
} while (0) |
102 |
|
|
|
103 |
|
|
/* Set the more significant 64 bits of a long double mantissa from an int. */ |
104 |
|
|
|
105 |
|
|
#define SET_LDOUBLE_MSW64(d,v) \ |
106 |
|
|
do { \ |
107 |
|
|
ieee_quad_shape_type sh_u; \ |
108 |
|
|
sh_u.value = (d); \ |
109 |
|
|
sh_u.parts64.msw = (v); \ |
110 |
|
|
(d) = sh_u.value; \ |
111 |
|
|
} while (0) |
112 |
|
|
|
113 |
|
|
/* Get the least significant 64 bits of a long double mantissa. */ |
114 |
|
|
|
115 |
|
|
#define GET_LDOUBLE_LSW64(v,d) \ |
116 |
|
|
do { \ |
117 |
|
|
ieee_quad_shape_type sh_u; \ |
118 |
|
|
sh_u.value = (d); \ |
119 |
|
|
(v) = sh_u.parts64.lsw; \ |
120 |
|
|
} while (0) |
121 |
|
|
|
122 |
|
|
/* A union which permits us to convert between a long double and |
123 |
|
|
three 32 bit ints. */ |
124 |
|
|
|
125 |
|
|
#if BYTE_ORDER == BIG_ENDIAN |
126 |
|
|
|
127 |
|
|
typedef union |
128 |
|
|
{ |
129 |
|
|
long double value; |
130 |
|
|
struct { |
131 |
|
|
#ifdef __LP64__ |
132 |
|
|
int padh:32; |
133 |
|
|
#endif |
134 |
|
|
int exp:16; |
135 |
|
|
int padl:16; |
136 |
|
|
u_int32_t msw; |
137 |
|
|
u_int32_t lsw; |
138 |
|
|
} parts; |
139 |
|
|
} ieee_extended_shape_type; |
140 |
|
|
|
141 |
|
|
#endif |
142 |
|
|
|
143 |
|
|
#if BYTE_ORDER == LITTLE_ENDIAN |
144 |
|
|
|
145 |
|
|
typedef union |
146 |
|
|
{ |
147 |
|
|
long double value; |
148 |
|
|
struct { |
149 |
|
|
u_int32_t lsw; |
150 |
|
|
u_int32_t msw; |
151 |
|
|
int exp:16; |
152 |
|
|
int padl:16; |
153 |
|
|
#ifdef __LP64__ |
154 |
|
|
int padh:32; |
155 |
|
|
#endif |
156 |
|
|
} parts; |
157 |
|
|
} ieee_extended_shape_type; |
158 |
|
|
|
159 |
|
|
#endif |
160 |
|
|
|
161 |
|
|
/* Get three 32 bit ints from a double. */ |
162 |
|
|
|
163 |
|
|
#define GET_LDOUBLE_WORDS(se,ix0,ix1,d) \ |
164 |
|
|
do { \ |
165 |
|
|
ieee_extended_shape_type ew_u; \ |
166 |
|
|
ew_u.value = (d); \ |
167 |
|
|
(se) = ew_u.parts.exp; \ |
168 |
|
|
(ix0) = ew_u.parts.msw; \ |
169 |
|
|
(ix1) = ew_u.parts.lsw; \ |
170 |
|
|
} while (0) |
171 |
|
|
|
172 |
|
|
/* Set a double from two 32 bit ints. */ |
173 |
|
|
|
174 |
|
|
#define SET_LDOUBLE_WORDS(d,se,ix0,ix1) \ |
175 |
|
|
do { \ |
176 |
|
|
ieee_extended_shape_type iw_u; \ |
177 |
|
|
iw_u.parts.exp = (se); \ |
178 |
|
|
iw_u.parts.msw = (ix0); \ |
179 |
|
|
iw_u.parts.lsw = (ix1); \ |
180 |
|
|
(d) = iw_u.value; \ |
181 |
|
|
} while (0) |
182 |
|
|
|
183 |
|
|
/* Get the more significant 32 bits of a long double mantissa. */ |
184 |
|
|
|
185 |
|
|
#define GET_LDOUBLE_MSW(v,d) \ |
186 |
|
|
do { \ |
187 |
|
|
ieee_extended_shape_type sh_u; \ |
188 |
|
|
sh_u.value = (d); \ |
189 |
|
|
(v) = sh_u.parts.msw; \ |
190 |
|
|
} while (0) |
191 |
|
|
|
192 |
|
|
/* Set the more significant 32 bits of a long double mantissa from an int. */ |
193 |
|
|
|
194 |
|
|
#define SET_LDOUBLE_MSW(d,v) \ |
195 |
|
|
do { \ |
196 |
|
|
ieee_extended_shape_type sh_u; \ |
197 |
|
|
sh_u.value = (d); \ |
198 |
|
|
sh_u.parts.msw = (v); \ |
199 |
|
|
(d) = sh_u.value; \ |
200 |
|
|
} while (0) |
201 |
|
|
|
202 |
|
|
/* Get int from the exponent of a long double. */ |
203 |
|
|
|
204 |
|
|
#define GET_LDOUBLE_EXP(se,d) \ |
205 |
|
|
do { \ |
206 |
|
|
ieee_extended_shape_type ge_u; \ |
207 |
|
|
ge_u.value = (d); \ |
208 |
|
|
(se) = ge_u.parts.exp; \ |
209 |
|
|
} while (0) |
210 |
|
|
|
211 |
|
|
/* Set exponent of a long double from an int. */ |
212 |
|
|
|
213 |
|
|
#define SET_LDOUBLE_EXP(d,se) \ |
214 |
|
|
do { \ |
215 |
|
|
ieee_extended_shape_type se_u; \ |
216 |
|
|
se_u.value = (d); \ |
217 |
|
|
se_u.parts.exp = (se); \ |
218 |
|
|
(d) = se_u.value; \ |
219 |
|
|
} while (0) |
220 |
|
|
|
221 |
|
|
/* A union which permits us to convert between a double and two 32 bit |
222 |
|
|
ints. */ |
223 |
|
|
|
224 |
|
|
/* |
225 |
|
|
* The arm port is little endian except for the FP word order which is |
226 |
|
|
* big endian. |
227 |
|
|
*/ |
228 |
|
|
|
229 |
|
|
#if (BYTE_ORDER == BIG_ENDIAN) || (defined(__arm__) && !defined(__VFP_FP__)) |
230 |
|
|
|
231 |
|
|
typedef union |
232 |
|
|
{ |
233 |
|
|
double value; |
234 |
|
|
struct |
235 |
|
|
{ |
236 |
|
|
u_int32_t msw; |
237 |
|
|
u_int32_t lsw; |
238 |
|
|
} parts; |
239 |
|
|
} ieee_double_shape_type; |
240 |
|
|
|
241 |
|
|
#endif |
242 |
|
|
|
243 |
|
|
#if (BYTE_ORDER == LITTLE_ENDIAN) && !(defined(__arm__) && !defined(__VFP_FP__)) |
244 |
|
|
|
245 |
|
|
typedef union |
246 |
|
|
{ |
247 |
|
|
double value; |
248 |
|
|
struct |
249 |
|
|
{ |
250 |
|
|
u_int32_t lsw; |
251 |
|
|
u_int32_t msw; |
252 |
|
|
} parts; |
253 |
|
|
} ieee_double_shape_type; |
254 |
|
|
|
255 |
|
|
#endif |
256 |
|
|
|
257 |
|
|
/* Get two 32 bit ints from a double. */ |
258 |
|
|
|
259 |
|
|
#define EXTRACT_WORDS(ix0,ix1,d) \ |
260 |
|
|
do { \ |
261 |
|
|
ieee_double_shape_type ew_u; \ |
262 |
|
|
ew_u.value = (d); \ |
263 |
|
|
(ix0) = ew_u.parts.msw; \ |
264 |
|
|
(ix1) = ew_u.parts.lsw; \ |
265 |
|
|
} while (0) |
266 |
|
|
|
267 |
|
|
/* Get the more significant 32 bit int from a double. */ |
268 |
|
|
|
269 |
|
|
#define GET_HIGH_WORD(i,d) \ |
270 |
|
|
do { \ |
271 |
|
|
ieee_double_shape_type gh_u; \ |
272 |
|
|
gh_u.value = (d); \ |
273 |
|
|
(i) = gh_u.parts.msw; \ |
274 |
|
|
} while (0) |
275 |
|
|
|
276 |
|
|
/* Get the less significant 32 bit int from a double. */ |
277 |
|
|
|
278 |
|
|
#define GET_LOW_WORD(i,d) \ |
279 |
|
|
do { \ |
280 |
|
|
ieee_double_shape_type gl_u; \ |
281 |
|
|
gl_u.value = (d); \ |
282 |
|
|
(i) = gl_u.parts.lsw; \ |
283 |
|
|
} while (0) |
284 |
|
|
|
285 |
|
|
/* Set a double from two 32 bit ints. */ |
286 |
|
|
|
287 |
|
|
#define INSERT_WORDS(d,ix0,ix1) \ |
288 |
|
|
do { \ |
289 |
|
|
ieee_double_shape_type iw_u; \ |
290 |
|
|
iw_u.parts.msw = (ix0); \ |
291 |
|
|
iw_u.parts.lsw = (ix1); \ |
292 |
|
|
(d) = iw_u.value; \ |
293 |
|
|
} while (0) |
294 |
|
|
|
295 |
|
|
/* Set the more significant 32 bits of a double from an int. */ |
296 |
|
|
|
297 |
|
|
#define SET_HIGH_WORD(d,v) \ |
298 |
|
|
do { \ |
299 |
|
|
ieee_double_shape_type sh_u; \ |
300 |
|
|
sh_u.value = (d); \ |
301 |
|
|
sh_u.parts.msw = (v); \ |
302 |
|
|
(d) = sh_u.value; \ |
303 |
|
|
} while (0) |
304 |
|
|
|
305 |
|
|
/* Set the less significant 32 bits of a double from an int. */ |
306 |
|
|
|
307 |
|
|
#define SET_LOW_WORD(d,v) \ |
308 |
|
|
do { \ |
309 |
|
|
ieee_double_shape_type sl_u; \ |
310 |
|
|
sl_u.value = (d); \ |
311 |
|
|
sl_u.parts.lsw = (v); \ |
312 |
|
|
(d) = sl_u.value; \ |
313 |
|
|
} while (0) |
314 |
|
|
|
315 |
|
|
/* A union which permits us to convert between a float and a 32 bit |
316 |
|
|
int. */ |
317 |
|
|
|
318 |
|
|
typedef union |
319 |
|
|
{ |
320 |
|
|
float value; |
321 |
|
|
u_int32_t word; |
322 |
|
|
} ieee_float_shape_type; |
323 |
|
|
|
324 |
|
|
/* Get a 32 bit int from a float. */ |
325 |
|
|
|
326 |
|
|
#define GET_FLOAT_WORD(i,d) \ |
327 |
|
|
do { \ |
328 |
|
|
ieee_float_shape_type gf_u; \ |
329 |
|
|
gf_u.value = (d); \ |
330 |
|
|
(i) = gf_u.word; \ |
331 |
|
|
} while (0) |
332 |
|
|
|
333 |
|
|
/* Set a float from a 32 bit int. */ |
334 |
|
|
|
335 |
|
|
#define SET_FLOAT_WORD(d,i) \ |
336 |
|
|
do { \ |
337 |
|
|
ieee_float_shape_type sf_u; \ |
338 |
|
|
sf_u.word = (i); \ |
339 |
|
|
(d) = sf_u.value; \ |
340 |
|
|
} while (0) |
341 |
|
|
|
342 |
|
|
#ifdef FLT_EVAL_METHOD |
343 |
|
|
/* |
344 |
|
|
* Attempt to get strict C99 semantics for assignment with non-C99 compilers. |
345 |
|
|
*/ |
346 |
|
|
#if FLT_EVAL_METHOD == 0 || __GNUC__ == 0 |
347 |
|
|
#define STRICT_ASSIGN(type, lval, rval) ((lval) = (rval)) |
348 |
|
|
#else /* FLT_EVAL_METHOD == 0 || __GNUC__ == 0 */ |
349 |
|
|
#define STRICT_ASSIGN(type, lval, rval) do { \ |
350 |
|
|
volatile type __lval; \ |
351 |
|
|
\ |
352 |
|
|
if (sizeof(type) >= sizeof(long double)) \ |
353 |
|
|
(lval) = (rval); \ |
354 |
|
|
else { \ |
355 |
|
|
__lval = (rval); \ |
356 |
|
|
(lval) = __lval; \ |
357 |
|
|
} \ |
358 |
|
|
} while (0) |
359 |
|
|
#endif /* FLT_EVAL_METHOD == 0 || __GNUC__ == 0 */ |
360 |
|
|
#endif /* FLT_EVAL_METHOD */ |
361 |
|
|
|
362 |
|
|
__BEGIN_HIDDEN_DECLS |
363 |
|
|
/* fdlibm kernel function */ |
364 |
|
|
extern int __ieee754_rem_pio2(double,double*); |
365 |
|
|
extern double __kernel_sin(double,double,int); |
366 |
|
|
extern double __kernel_cos(double,double); |
367 |
|
|
extern double __kernel_tan(double,double,int); |
368 |
|
|
extern int __kernel_rem_pio2(double*,double*,int,int,int); |
369 |
|
|
|
370 |
|
|
/* float versions of fdlibm kernel functions */ |
371 |
|
|
extern int __ieee754_rem_pio2f(float,float*); |
372 |
|
|
extern float __kernel_sinf(float,float,int); |
373 |
|
|
extern float __kernel_cosf(float,float); |
374 |
|
|
extern float __kernel_tanf(float,float,int); |
375 |
|
|
extern int __kernel_rem_pio2f(float*,float*,int,int,int,const int*); |
376 |
|
|
|
377 |
|
|
/* long double precision kernel functions */ |
378 |
|
|
long double __kernel_sinl(long double, long double, int); |
379 |
|
|
long double __kernel_cosl(long double, long double); |
380 |
|
|
long double __kernel_tanl(long double, long double, int); |
381 |
|
|
|
382 |
|
|
/* |
383 |
|
|
* Common routine to process the arguments to nan(), nanf(), and nanl(). |
384 |
|
|
*/ |
385 |
|
|
void _scan_nan(uint32_t *__words, int __num_words, const char *__s); |
386 |
|
|
__END_HIDDEN_DECLS |
387 |
|
|
|
388 |
|
|
/* |
389 |
|
|
* TRUNC() is a macro that sets the trailing 27 bits in the mantissa |
390 |
|
|
* of an IEEE double variable to zero. It must be expression-like |
391 |
|
|
* for syntactic reasons, and we implement this expression using |
392 |
|
|
* an inline function instead of a pure macro to avoid depending |
393 |
|
|
* on the gcc feature of statement-expressions. |
394 |
|
|
*/ |
395 |
|
|
#define TRUNC(d) (_b_trunc(&(d))) |
396 |
|
|
|
397 |
|
|
static __inline void |
398 |
|
|
_b_trunc(volatile double *_dp) |
399 |
|
|
{ |
400 |
|
|
uint32_t _lw; |
401 |
|
|
|
402 |
|
150 |
GET_LOW_WORD(_lw, *_dp); |
403 |
|
75 |
SET_LOW_WORD(*_dp, _lw & 0xf8000000); |
404 |
|
75 |
} |
405 |
|
|
|
406 |
|
|
struct Double { |
407 |
|
|
double a; |
408 |
|
|
double b; |
409 |
|
|
}; |
410 |
|
|
|
411 |
|
|
/* |
412 |
|
|
* Functions internal to the math package, yet not static. |
413 |
|
|
*/ |
414 |
|
|
__BEGIN_HIDDEN_DECLS |
415 |
|
|
double __exp__D(double, double); |
416 |
|
|
struct Double __log__D(double); |
417 |
|
|
long double __p1evll(long double, void *, int); |
418 |
|
|
long double __polevll(long double, void *, int); |
419 |
|
|
__END_HIDDEN_DECLS |
420 |
|
|
|
421 |
|
|
#endif /* _MATH_PRIVATE_H_ */ |