1 /* $OpenBSD: math_private.h,v 1.17 2014/06/02 19:31:17 kettenis 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_OPENBSD_H_
18 #define _MATH_PRIVATE_OPENBSD_H_
19
20 #ifdef _IEEE128_FLOAT
21
22 #if __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__
23
24 typedef union
25 {
26 long double value;
27 struct {
28 u_int32_t mswhi;
29 u_int32_t mswlo;
30 u_int32_t lswhi;
31 u_int32_t lswlo;
32 } parts32;
33 struct {
34 u_int64_t msw;
35 u_int64_t lsw;
36 } parts64;
37 } ieee_quad_shape_type;
38
39 #endif
40
41 #if __FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__
42
43 typedef union
44 {
45 long double value;
46 struct {
47 u_int32_t lswlo;
48 u_int32_t lswhi;
49 u_int32_t mswlo;
50 u_int32_t mswhi;
51 } parts32;
52 struct {
53 u_int64_t lsw;
54 u_int64_t msw;
55 } parts64;
56 } ieee_quad_shape_type;
57
58 #endif
59
60 /* Get two 64 bit ints from a long double. */
61
62 #define GET_LDOUBLE_WORDS64(ix0,ix1,d) \
63 do { \
64 ieee_quad_shape_type qw_u; \
65 qw_u.value = (d); \
66 (ix0) = qw_u.parts64.msw; \
67 (ix1) = qw_u.parts64.lsw; \
68 } while (0)
69
70 /* Set a long double from two 64 bit ints. */
71
72 #define SET_LDOUBLE_WORDS64(d,ix0,ix1) \
73 do { \
74 ieee_quad_shape_type qw_u; \
75 qw_u.parts64.msw = (ix0); \
76 qw_u.parts64.lsw = (ix1); \
77 (d) = qw_u.value; \
78 } while (0)
79
80 /* Get the more significant 64 bits of a long double mantissa. */
81
82 #define GET_LDOUBLE_MSW64(v,d) \
83 do { \
84 ieee_quad_shape_type sh_u; \
85 sh_u.value = (d); \
86 (v) = sh_u.parts64.msw; \
87 } while (0)
88
89 /* Set the more significant 64 bits of a long double mantissa from an int. */
90
91 #define SET_LDOUBLE_MSW64(d,v) \
92 do { \
93 ieee_quad_shape_type sh_u; \
94 sh_u.value = (d); \
95 sh_u.parts64.msw = (v); \
96 (d) = sh_u.value; \
97 } while (0)
98
99 /* Get the least significant 64 bits of a long double mantissa. */
100
101 #define GET_LDOUBLE_LSW64(v,d) \
102 do { \
103 ieee_quad_shape_type sh_u; \
104 sh_u.value = (d); \
105 (v) = sh_u.parts64.lsw; \
106 } while (0)
107
108 static ALWAYS_INLINE int
issignalingl(long double x)109 issignalingl(long double x)
110 {
111 u_int64_t high;
112 if (!isnanl(x))
113 return 0;
114 GET_LDOUBLE_MSW64(high, x);
115 if (!IEEE_754_2008_SNAN)
116 return (high & 0x0000800000000000ULL) != 0;
117 else
118 return (high & 0x0000800000000000ULL) == 0;
119 }
120
121 static ALWAYS_INLINE int
__signbitl(long double x)122 __signbitl(long double x)
123 {
124 int64_t high;
125 GET_LDOUBLE_MSW64(high, x);
126 return high < 0;
127 }
128
129 /* 128-bit long double */
130
131 union IEEEl2bits {
132 long double e;
133 struct {
134 #if __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__
135 uint64_t sign :1;
136 uint64_t exp :15;
137 uint64_t manh :48;
138 uint64_t manl :64;
139 #endif
140 #if __FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__
141 uint64_t manl :64;
142 uint64_t manh :48;
143 uint64_t exp :15;
144 uint64_t sign :1;
145 #endif
146 } bits;
147 /* TODO andrew: Check the packing here */
148 struct {
149 #if __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__
150 uint64_t expsign :16;
151 uint64_t manh :48;
152 uint64_t manl :64;
153 #endif
154 #if __FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__
155 uint64_t manl :64;
156 uint64_t manh :48;
157 uint64_t expsign :16;
158 #endif
159 } xbits;
160 };
161
162 #define LDBL_NBIT 0
163 #define LDBL_IMPLICIT_NBIT
164 #define mask_nbit_l(u) ((void)0)
165 #define LDBL_INF_NAN_EXP 32767
166 #define LDBL_EXP_MASK 0x7fff
167 #define LDBL_EXP_SIGN 0x8000
168
169 #define LDBL_MANH_SIZE 48
170 #define LDBL_MANL_SIZE 64
171
172 #define LDBL_TO_ARRAY32(u, a) do { \
173 (a)[0] = (uint32_t)(u).bits.manl; \
174 (a)[1] = (uint32_t)((u).bits.manl >> 32); \
175 (a)[2] = (uint32_t)(u).bits.manh; \
176 (a)[3] = (uint32_t)((u).bits.manh >> 32); \
177 } while(0)
178
179 #endif /* _IEEE128_FLOAT */
180
181 #ifdef _INTEL80_FLOAT
182
183 /* A union which permits us to convert between a long double and
184 three 32 bit ints. */
185
186 #if __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__
187
188 typedef union
189 {
190 long double value;
191 struct {
192 #ifdef __LP64__
193 int padh:32;
194 #endif
195 int exp:16;
196 int padl:16;
197 u_int32_t msw;
198 u_int32_t lsw;
199 } parts;
200 } ieee_extended_shape_type;
201
202 #endif
203
204 #if __FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__
205
206 typedef union
207 {
208 long double value;
209 struct {
210 u_int32_t lsw;
211 u_int32_t msw;
212 int exp:16;
213 int padl:16;
214 #ifdef __LP64__
215 int padh:32;
216 #endif
217 } parts;
218 } ieee_extended_shape_type;
219
220 #endif
221
222 /* Get three 32 bit ints from a double. */
223
224 #define GET_LDOUBLE_WORDS(se,ix0,ix1,d) \
225 do { \
226 ieee_extended_shape_type ew_u; \
227 ew_u.value = (d); \
228 (se) = ew_u.parts.exp; \
229 (ix0) = ew_u.parts.msw; \
230 (ix1) = ew_u.parts.lsw; \
231 } while (0)
232
233 /* Set a double from two 32 bit ints. */
234
235 #define SET_LDOUBLE_WORDS(d,se,ix0,ix1) \
236 do { \
237 ieee_extended_shape_type iw_u; \
238 iw_u.parts.exp = (se); \
239 iw_u.parts.msw = (ix0); \
240 iw_u.parts.lsw = (ix1); \
241 (d) = iw_u.value; \
242 } while (0)
243
244 /* Get the more significant 32 bits of a long double mantissa. */
245
246 #define GET_LDOUBLE_MSW(v,d) \
247 do { \
248 ieee_extended_shape_type sh_u; \
249 sh_u.value = (d); \
250 (v) = sh_u.parts.msw; \
251 } while (0)
252
253 /* Set the more significant 32 bits of a long double mantissa from an int. */
254
255 #define SET_LDOUBLE_MSW(d,v) \
256 do { \
257 ieee_extended_shape_type sh_u; \
258 sh_u.value = (d); \
259 sh_u.parts.msw = (v); \
260 (d) = sh_u.value; \
261 } while (0)
262
263 /* Get int from the exponent of a long double. */
264
265 #define GET_LDOUBLE_EXP(se,d) \
266 do { \
267 ieee_extended_shape_type ge_u; \
268 ge_u.value = (d); \
269 (se) = ge_u.parts.exp; \
270 } while (0)
271
272 /* Set exponent of a long double from an int. */
273
274 #define SET_LDOUBLE_EXP(d,se) \
275 do { \
276 ieee_extended_shape_type se_u; \
277 se_u.value = (d); \
278 se_u.parts.exp = (se); \
279 (d) = se_u.value; \
280 } while (0)
281
282 static ALWAYS_INLINE int
issignalingl(long double x)283 issignalingl(long double x)
284 {
285 u_int32_t high;
286 if (!isnanl(x))
287 return 0;
288 GET_LDOUBLE_MSW(high, x);
289 return (high & 0x40000000U) == 0;
290 }
291
292 static ALWAYS_INLINE int
__signbitl(long double x)293 __signbitl(long double x)
294 {
295 int exp;
296 GET_LDOUBLE_EXP(exp, x);
297 return (exp & 0x8000) != 0;
298 }
299
300 union IEEEl2bits {
301 long double e;
302 struct {
303 #if __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__
304 uint64_t sign :1;
305 uint64_t exp :15;
306 uint64_t manh :32;
307 uint64_t manl :32;
308 uint64_t junk :16;
309 #endif
310 #if __FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__
311 uint64_t manl :32;
312 uint64_t manh :32;
313 uint64_t exp :15;
314 uint64_t sign :1;
315 uint64_t junk :16;
316 #endif
317 } bits;
318 struct {
319 #if __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__
320 uint64_t expsign :16;
321 uint64_t man :64;
322 uint64_t junk :16;
323 #endif
324 #if __FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__
325 uint64_t man :64;
326 uint64_t expsign :16;
327 uint64_t junk :16;
328 #endif
329 } xbits;
330 };
331
332 #define LDBL_NBIT 0x80000000
333 #define mask_nbit_l(u) ((u).bits.manh &= ~LDBL_NBIT)
334 #define LDBL_INF_NAN_EXP 32767
335 #define LDBL_EXP_MASK 0x7fff
336 #define LDBL_EXP_SIGN 0x8000
337
338 #define LDBL_MANH_SIZE 32
339 #define LDBL_MANL_SIZE 32
340
341 #define LDBL_TO_ARRAY32(u, a) do { \
342 (a)[0] = (uint32_t)(u).bits.manl; \
343 (a)[1] = (uint32_t)(u).bits.manh; \
344 } while (0)
345
346 #endif /* _INTEL80_FLOAT */
347
348 #ifdef _DOUBLE_DOUBLE_FLOAT
349
350 #if __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__
351
352 typedef union
353 {
354 long double value;
355 struct {
356 double msd;
357 double lsd;
358 } doubles;
359 struct {
360 u_int32_t mswhi;
361 u_int32_t mswlo;
362 u_int32_t lswhi;
363 u_int32_t lswlo;
364 } parts32;
365 struct {
366 u_int64_t msw;
367 u_int64_t lsw;
368 } parts64;
369 struct {
370 int exp:12;
371 u_int64_t msw :52;
372 int expl:12;
373 u_int64_t lsw :52;
374 } parts;
375 } double_double_shape_type;
376
377 #endif /* __ORDER_BIG_ENDIAN__ */
378
379 #if __FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__
380
381 typedef union
382 {
383 long double value;
384 struct {
385 double msd;
386 double lsd;
387 } doubles;
388 struct {
389 u_int32_t mswlo;
390 u_int32_t mswhi;
391 u_int32_t lswlo;
392 u_int32_t lswhi;
393 } parts32;
394 struct {
395 u_int64_t msw;
396 u_int64_t lsw;
397 } parts64;
398 struct {
399 u_int64_t msw :52;
400 int exp:12;
401 u_int64_t lsw :52;
402 int expl:12;
403 } parts;
404 } double_double_shape_type;
405
406 #endif /* __ORDER_LITTLE_ENDIAN__ */
407
408 /* Get two 64 bit ints from a long double. */
409
410 #define GET_LDOUBLE_WORDS64(ix0,ix1,d) \
411 do { \
412 double_double_shape_type qw_u; \
413 qw_u.value = (d); \
414 (ix0) = qw_u.parts64.msw; \
415 (ix1) = qw_u.parts64.lsw; \
416 } while (0)
417
418 /* Set a long double from two 64 bit ints. */
419
420 #define SET_LDOUBLE_WORDS64(d,ix0,ix1) \
421 do { \
422 double_double_shape_type qw_u; \
423 qw_u.parts64.msw = (ix0); \
424 qw_u.parts64.lsw = (ix1); \
425 (d) = qw_u.value; \
426 } while (0)
427
428 /* Get the more significant 64 bits of a long double mantissa. */
429
430 #define GET_LDOUBLE_MSW64(v,d) \
431 do { \
432 double_double_shape_type sh_u; \
433 sh_u.value = (d); \
434 (v) = sh_u.parts64.msw; \
435 } while (0)
436
437 /* Set the more significant 64 bits of a long double mantissa from an int. */
438
439 #define SET_LDOUBLE_MSW64(d,v) \
440 do { \
441 double_double_shape_type sh_u; \
442 sh_u.value = (d); \
443 sh_u.parts64.msw = (v); \
444 (d) = sh_u.value; \
445 } while (0)
446
447 /* Get the least significant 64 bits of a long double mantissa. */
448
449 #define GET_LDOUBLE_LSW64(v,d) \
450 do { \
451 double_double_shape_type sh_u; \
452 sh_u.value = (d); \
453 (v) = sh_u.parts64.lsw; \
454 } while (0)
455
456 /* Get int from the exponent of a long double. */
457
458 #define GET_LDOUBLE_EXP(se,d) \
459 do { \
460 double_double_shape_type ge_u; \
461 ge_u.value = (d); \
462 (se) = ge_u.parts.exp; \
463 } while (0)
464
465 /* Set exponent of a long double from an int. */
466
467 #define SET_LDOUBLE_EXP(d,se) \
468 do { \
469 double_double_shape_type se_u; \
470 se_u.value = (d); \
471 se_u.parts.exp = (se); \
472 (d) = se_u.value; \
473 } while (0)
474
475 static ALWAYS_INLINE int
issignalingl(long double x)476 issignalingl(long double x)
477 {
478 u_int64_t high;
479 if (!isnanl(x))
480 return 0;
481 GET_LDOUBLE_MSW64(high, x);
482 if (!IEEE_754_2008_SNAN)
483 return (high & 0x0008000000000000ULL) != 0;
484 else
485 return (high & 0x0008000000000000ULL) == 0;
486 }
487
488 static ALWAYS_INLINE int
__signbitl(long double x)489 __signbitl(long double x)
490 {
491 int exp;
492 GET_LDOUBLE_EXP(exp, x);
493 return exp < 0;
494 }
495
496 union IEEEl2bits {
497 long double e;
498 struct {
499 #if __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__
500 u_int64_t sign :1;
501 u_int64_t exp :11;
502 u_int64_t manh :52;
503 u_int64_t signl :1;
504 u_int64_t expl :11;
505 u_int64_t manl :52;
506 #endif
507 #if __FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__
508 u_int64_t manh :52;
509 u_int64_t exp :11;
510 u_int64_t sign :1;
511 u_int64_t manl :52;
512 u_int64_t expl :11;
513 u_int64_t signl :1;
514 #endif
515 } bits;
516 struct {
517 #if __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__
518 u_int64_t expsign :12;
519 u_int64_t manh :52;
520 u_int64_t expsignl:12;
521 u_int64_t manl :52;
522 #endif
523 #if __FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__
524 u_int64_t manh :52;
525 u_int64_t expsign :12;
526 u_int64_t manl :52;
527 u_int64_t expsignl:12;
528 #endif
529 } xbits;
530 struct {
531 double dh;
532 double dl;
533 } dbits;
534 };
535
536 #define LDBL_NBIT 0
537 #define LDBL_IMPLICIT_NBIT
538 #define mask_nbit_l(u) ((void)0)
539 #define LDBL_INF_NAN_EXP 2047
540 #define LDBL_EXP_MASK 0x7ff
541 #define LDBL_EXP_SIGN 0x800
542
543 #define LDBL_MANH_SIZE 52
544
545 #define LDBL_TO_ARRAY32(u, a) do { \
546 (a)[0] = (uint32_t)(u).bits.manl; \
547 (a)[1] = (uint32_t)((u).bits.manl >> 32); \
548 (a)[2] = (uint32_t)(u).bits.manh; \
549 (a)[3] = (uint32_t)((u).bits.manh >> 32); \
550 } while(0)
551
552 #endif /* _DOUBLE_DOUBLE_FLOAT */
553
554 /*
555 * Common routine to process the arguments to nan(), nanf(), and nanl().
556 */
557 void __scan_nan(uint32_t *__words, int __num_words, const char *__s);
558
559 /*
560 * Functions internal to the math package, yet not static.
561 */
562 double __exp__D(double, double);
563 struct Double __log__D(double);
564 long double __p1evll(long double, const long double *, int);
565 long double __polevll(long double, const long double *, int);
566
567 #endif /* _MATH_PRIVATE_OPENBSD_H_ */
568