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