xref: /relibc/openlibm/src/math_private_openbsd.h (revision 830dc991f3bc055717fe0c46bd24746f8177f455)
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 #if _IEEE_WORD_ORDER == _BIG_ENDIAN
21 
22 typedef union
23 {
24   long double value;
25   struct {
26     u_int32_t mswhi;
27     u_int32_t mswlo;
28     u_int32_t lswhi;
29     u_int32_t lswlo;
30   } parts32;
31   struct {
32     u_int64_t msw;
33     u_int64_t lsw;
34   } parts64;
35 } ieee_quad_shape_type;
36 
37 #endif
38 
39 #if _IEEE_WORD_ORDER == _LITTLE_ENDIAN
40 
41 typedef union
42 {
43   long double value;
44   struct {
45     u_int32_t lswlo;
46     u_int32_t lswhi;
47     u_int32_t mswlo;
48     u_int32_t mswhi;
49   } parts32;
50   struct {
51     u_int64_t lsw;
52     u_int64_t msw;
53   } parts64;
54 } ieee_quad_shape_type;
55 
56 #endif
57 
58 /* Get two 64 bit ints from a long double.  */
59 
60 #define GET_LDOUBLE_WORDS64(ix0,ix1,d)				\
61 do {								\
62   ieee_quad_shape_type qw_u;					\
63   qw_u.value = (d);						\
64   (ix0) = qw_u.parts64.msw;					\
65   (ix1) = qw_u.parts64.lsw;					\
66 } while (0)
67 
68 /* Set a long double from two 64 bit ints.  */
69 
70 #define SET_LDOUBLE_WORDS64(d,ix0,ix1)				\
71 do {								\
72   ieee_quad_shape_type qw_u;					\
73   qw_u.parts64.msw = (ix0);					\
74   qw_u.parts64.lsw = (ix1);					\
75   (d) = qw_u.value;						\
76 } while (0)
77 
78 /* Get the more significant 64 bits of a long double mantissa.  */
79 
80 #define GET_LDOUBLE_MSW64(v,d)					\
81 do {								\
82   ieee_quad_shape_type sh_u;					\
83   sh_u.value = (d);						\
84   (v) = sh_u.parts64.msw;					\
85 } while (0)
86 
87 /* Set the more significant 64 bits of a long double mantissa from an int.  */
88 
89 #define SET_LDOUBLE_MSW64(d,v)					\
90 do {								\
91   ieee_quad_shape_type sh_u;					\
92   sh_u.value = (d);						\
93   sh_u.parts64.msw = (v);					\
94   (d) = sh_u.value;						\
95 } while (0)
96 
97 /* Get the least significant 64 bits of a long double mantissa.  */
98 
99 #define GET_LDOUBLE_LSW64(v,d)					\
100 do {								\
101   ieee_quad_shape_type sh_u;					\
102   sh_u.value = (d);						\
103   (v) = sh_u.parts64.lsw;					\
104 } while (0)
105 
106 /* A union which permits us to convert between a long double and
107    three 32 bit ints.  */
108 
109 #if _IEEE_WORD_ORDER == _BIG_ENDIAN
110 
111 typedef union
112 {
113   long double value;
114   struct {
115 #ifdef __LP64__
116     int padh:32;
117 #endif
118     int exp:16;
119     int padl:16;
120     u_int32_t msw;
121     u_int32_t lsw;
122   } parts;
123 } ieee_extended_shape_type;
124 
125 #endif
126 
127 #if _IEEE_WORD_ORDER == _LITTLE_ENDIAN
128 
129 typedef union
130 {
131   long double value;
132   struct {
133     u_int32_t lsw;
134     u_int32_t msw;
135     int exp:16;
136     int padl:16;
137 #ifdef __LP64__
138     int padh:32;
139 #endif
140   } parts;
141 } ieee_extended_shape_type;
142 
143 #endif
144 
145 /* Get three 32 bit ints from a double.  */
146 
147 #define GET_LDOUBLE_WORDS(se,ix0,ix1,d)				\
148 do {								\
149   ieee_extended_shape_type ew_u;				\
150   ew_u.value = (d);						\
151   (se) = ew_u.parts.exp;					\
152   (ix0) = ew_u.parts.msw;					\
153   (ix1) = ew_u.parts.lsw;					\
154 } while (0)
155 
156 /* Set a double from two 32 bit ints.  */
157 
158 #define SET_LDOUBLE_WORDS(d,se,ix0,ix1)				\
159 do {								\
160   ieee_extended_shape_type iw_u;				\
161   iw_u.parts.exp = (se);					\
162   iw_u.parts.msw = (ix0);					\
163   iw_u.parts.lsw = (ix1);					\
164   (d) = iw_u.value;						\
165 } while (0)
166 
167 /* Get the more significant 32 bits of a long double mantissa.  */
168 
169 #define GET_LDOUBLE_MSW(v,d)					\
170 do {								\
171   ieee_extended_shape_type sh_u;				\
172   sh_u.value = (d);						\
173   (v) = sh_u.parts.msw;						\
174 } while (0)
175 
176 /* Set the more significant 32 bits of a long double mantissa from an int.  */
177 
178 #define SET_LDOUBLE_MSW(d,v)					\
179 do {								\
180   ieee_extended_shape_type sh_u;				\
181   sh_u.value = (d);						\
182   sh_u.parts.msw = (v);						\
183   (d) = sh_u.value;						\
184 } while (0)
185 
186 /* Get int from the exponent of a long double.  */
187 
188 #define GET_LDOUBLE_EXP(se,d)					\
189 do {								\
190   ieee_extended_shape_type ge_u;				\
191   ge_u.value = (d);						\
192   (se) = ge_u.parts.exp;					\
193 } while (0)
194 
195 /* Set exponent of a long double from an int.  */
196 
197 #define SET_LDOUBLE_EXP(d,se)					\
198 do {								\
199   ieee_extended_shape_type se_u;				\
200   se_u.value = (d);						\
201   se_u.parts.exp = (se);					\
202   (d) = se_u.value;						\
203 } while (0)
204 
205 /*
206  * Common routine to process the arguments to nan(), nanf(), and nanl().
207  */
208 void _scan_nan(uint32_t *__words, int __num_words, const char *__s);
209 
210 /*
211  * Functions internal to the math package, yet not static.
212  */
213 double __exp__D(double, double);
214 struct Double __log__D(double);
215 long double __p1evll(long double, void *, int);
216 long double __polevll(long double, void *, int);
217 
218 #endif /* _MATH_PRIVATE_OPENBSD_H_ */
219