1 | /**************************************************************** |
---|
2 | * |
---|
3 | * The author of this software is David M. Gay. |
---|
4 | * |
---|
5 | * Copyright (c) 1991 by AT&T. |
---|
6 | * |
---|
7 | * Permission to use, copy, modify, and distribute this software for any |
---|
8 | * purpose without fee is hereby granted, provided that this entire notice |
---|
9 | * is included in all copies of any software which is or includes a copy |
---|
10 | * or modification of this software and in all copies of the supporting |
---|
11 | * documentation for such software. |
---|
12 | * |
---|
13 | * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED |
---|
14 | * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY |
---|
15 | * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY |
---|
16 | * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. |
---|
17 | * |
---|
18 | ***************************************************************/ |
---|
19 | |
---|
20 | /* Please send bug reports to |
---|
21 | David M. Gay |
---|
22 | AT&T Bell Laboratories, Room 2C-463 |
---|
23 | 600 Mountain Avenue |
---|
24 | Murray Hill, NJ 07974-2070 |
---|
25 | U.S.A. |
---|
26 | dmg@research.att.com or research!dmg |
---|
27 | */ |
---|
28 | |
---|
29 | /* This header file is a modification of mprec.h that only contains floating |
---|
30 | point union code. */ |
---|
31 | |
---|
32 | #include <newlib.h> |
---|
33 | #include <ieeefp.h> |
---|
34 | #include <math.h> |
---|
35 | #include <float.h> |
---|
36 | #include <errno.h> |
---|
37 | #include <sys/config.h> |
---|
38 | #include <sys/cdefs.h> |
---|
39 | |
---|
40 | #ifdef __IEEE_LITTLE_ENDIAN |
---|
41 | #define IEEE_8087 |
---|
42 | #endif |
---|
43 | |
---|
44 | #ifdef __IEEE_BIG_ENDIAN |
---|
45 | #define IEEE_MC68k |
---|
46 | #endif |
---|
47 | |
---|
48 | #ifdef __Z8000__ |
---|
49 | #define Just_16 |
---|
50 | #endif |
---|
51 | |
---|
52 | #ifdef Unsigned_Shifts |
---|
53 | #define Sign_Extend(a,b) if (b < 0) a |= (__uint32_t)0xffff0000; |
---|
54 | #else |
---|
55 | #define Sign_Extend(a,b) /*no-op*/ |
---|
56 | #endif |
---|
57 | |
---|
58 | #if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1 |
---|
59 | Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined. |
---|
60 | #endif |
---|
61 | |
---|
62 | #ifdef _WANT_IO_LONG_DOUBLE |
---|
63 | /* If we are going to examine or modify specific bits in a long double using |
---|
64 | the lword0 or lwordx macros, then we must wrap the long double inside |
---|
65 | a union. This is necessary to avoid undefined behavior according to |
---|
66 | the ANSI C spec. */ |
---|
67 | |
---|
68 | #ifdef IEEE_8087 |
---|
69 | #if LDBL_MANT_DIG == 24 |
---|
70 | struct ldieee |
---|
71 | { |
---|
72 | unsigned manh:23; |
---|
73 | unsigned exp:8; |
---|
74 | unsigned sign:1; |
---|
75 | } __packed; |
---|
76 | #elif LDBL_MANT_DIG == 53 |
---|
77 | struct ldieee |
---|
78 | { |
---|
79 | unsigned manl:20; |
---|
80 | unsigned manh:32; |
---|
81 | unsigned exp:11; |
---|
82 | unsigned sign:1; |
---|
83 | } __packed; |
---|
84 | #elif LDBL_MANT_DIG == 64 |
---|
85 | struct ldieee |
---|
86 | { |
---|
87 | unsigned manl:32; |
---|
88 | unsigned manh:32; |
---|
89 | unsigned exp:15; |
---|
90 | unsigned sign:1; |
---|
91 | } __packed; |
---|
92 | #elif LDBL_MANT_DIG > 64 |
---|
93 | struct ldieee |
---|
94 | { |
---|
95 | unsigned manl3:16; |
---|
96 | unsigned manl2:32; |
---|
97 | unsigned manl:32; |
---|
98 | unsigned manh:32; |
---|
99 | unsigned exp:15; |
---|
100 | unsigned sign:1; |
---|
101 | } __packed; |
---|
102 | #endif /* LDBL_MANT_DIG */ |
---|
103 | #else /* !IEEE_8087 */ |
---|
104 | #if LDBL_MANT_DIG == 24 |
---|
105 | struct ldieee |
---|
106 | { |
---|
107 | unsigned sign:1; |
---|
108 | unsigned exp:8; |
---|
109 | unsigned manh:23; |
---|
110 | } __packed; |
---|
111 | #elif LDBL_MANT_DIG == 53 |
---|
112 | struct ldieee |
---|
113 | { |
---|
114 | unsigned sign:1; |
---|
115 | unsigned exp:11; |
---|
116 | unsigned manh:32; |
---|
117 | unsigned manl:20; |
---|
118 | } __packed; |
---|
119 | #elif LDBL_MANT_DIG == 64 |
---|
120 | struct ldieee |
---|
121 | { |
---|
122 | unsigned sign:1; |
---|
123 | unsigned exp:15; |
---|
124 | unsigned manh:32; |
---|
125 | unsigned manl:32; |
---|
126 | } __packed; |
---|
127 | #elif LDBL_MANT_DIG > 64 |
---|
128 | struct ldieee |
---|
129 | { |
---|
130 | unsigned sign:1; |
---|
131 | unsigned exp:15; |
---|
132 | unsigned manh:32; |
---|
133 | unsigned manl:32; |
---|
134 | unsigned manl2:32; |
---|
135 | unsigned manl3:16; |
---|
136 | } __packed; |
---|
137 | #endif /* LDBL_MANT_DIG */ |
---|
138 | #endif /* !IEEE_8087 */ |
---|
139 | #endif /* _WANT_IO_LONG_DOUBLE */ |
---|
140 | |
---|
141 | /* If we are going to examine or modify specific bits in a double using |
---|
142 | the word0 and/or word1 macros, then we must wrap the double inside |
---|
143 | a union. This is necessary to avoid undefined behavior according to |
---|
144 | the ANSI C spec. */ |
---|
145 | union double_union |
---|
146 | { |
---|
147 | double d; |
---|
148 | __uint32_t i[2]; |
---|
149 | }; |
---|
150 | |
---|
151 | #ifdef IEEE_8087 |
---|
152 | #define word0(x) (x.i[1]) |
---|
153 | #define word1(x) (x.i[0]) |
---|
154 | #else |
---|
155 | #define word0(x) (x.i[0]) |
---|
156 | #define word1(x) (x.i[1]) |
---|
157 | #endif |
---|
158 | |
---|
159 | /* #define P DBL_MANT_DIG */ |
---|
160 | /* Ten_pmax = floor(P*log(2)/log(5)) */ |
---|
161 | /* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ |
---|
162 | /* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ |
---|
163 | /* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ |
---|
164 | |
---|
165 | #if defined(IEEE_8087) + defined(IEEE_MC68k) |
---|
166 | #if defined (_DOUBLE_IS_32BITS) |
---|
167 | #define Exp_shift 23 |
---|
168 | #define Exp_shift1 23 |
---|
169 | #define Exp_msk1 ((__uint32_t)0x00800000L) |
---|
170 | #define Exp_msk11 ((__uint32_t)0x00800000L) |
---|
171 | #define Exp_mask ((__uint32_t)0x7f800000L) |
---|
172 | #define P 24 |
---|
173 | #define Bias 127 |
---|
174 | #define IEEE_Arith |
---|
175 | #define Emin (-126) |
---|
176 | #define Exp_1 ((__uint32_t)0x3f800000L) |
---|
177 | #define Exp_11 ((__uint32_t)0x3f800000L) |
---|
178 | #define Ebits 8 |
---|
179 | #define Frac_mask ((__uint32_t)0x007fffffL) |
---|
180 | #define Frac_mask1 ((__uint32_t)0x007fffffL) |
---|
181 | #define Ten_pmax 10 |
---|
182 | #define Sign_bit ((__uint32_t)0x80000000L) |
---|
183 | #define Ten_pmax 10 |
---|
184 | #define Bletch 2 |
---|
185 | #define Bndry_mask ((__uint32_t)0x007fffffL) |
---|
186 | #define Bndry_mask1 ((__uint32_t)0x007fffffL) |
---|
187 | #define LSB 1 |
---|
188 | #define Sign_bit ((__uint32_t)0x80000000L) |
---|
189 | #define Log2P 1 |
---|
190 | #define Tiny0 0 |
---|
191 | #define Tiny1 1 |
---|
192 | #define Quick_max 5 |
---|
193 | #define Int_max 6 |
---|
194 | #define Infinite(x) (word0(x) == ((__uint32_t)0x7f800000L)) |
---|
195 | #undef word0 |
---|
196 | #undef word1 |
---|
197 | |
---|
198 | #define word0(x) (x.i[0]) |
---|
199 | #define word1(x) 0 |
---|
200 | #else |
---|
201 | |
---|
202 | #define Exp_shift 20 |
---|
203 | #define Exp_shift1 20 |
---|
204 | #define Exp_msk1 ((__uint32_t)0x100000L) |
---|
205 | #define Exp_msk11 ((__uint32_t)0x100000L) |
---|
206 | #define Exp_mask ((__uint32_t)0x7ff00000L) |
---|
207 | #define P 53 |
---|
208 | #define Bias 1023 |
---|
209 | #define IEEE_Arith |
---|
210 | #define Emin (-1022) |
---|
211 | #define Exp_1 ((__uint32_t)0x3ff00000L) |
---|
212 | #define Exp_11 ((__uint32_t)0x3ff00000L) |
---|
213 | #define Ebits 11 |
---|
214 | #define Frac_mask ((__uint32_t)0xfffffL) |
---|
215 | #define Frac_mask1 ((__uint32_t)0xfffffL) |
---|
216 | #define Ten_pmax 22 |
---|
217 | #define Bletch 0x10 |
---|
218 | #define Bndry_mask ((__uint32_t)0xfffffL) |
---|
219 | #define Bndry_mask1 ((__uint32_t)0xfffffL) |
---|
220 | #define LSB 1 |
---|
221 | #define Sign_bit ((__uint32_t)0x80000000L) |
---|
222 | #define Log2P 1 |
---|
223 | #define Tiny0 0 |
---|
224 | #define Tiny1 1 |
---|
225 | #define Quick_max 14 |
---|
226 | #define Int_max 14 |
---|
227 | #define Infinite(x) (word0(x) == ((__uint32_t)0x7ff00000L)) /* sufficient test for here */ |
---|
228 | #endif |
---|
229 | |
---|
230 | #else |
---|
231 | #undef Sudden_Underflow |
---|
232 | #define Sudden_Underflow |
---|
233 | #ifdef IBM |
---|
234 | #define Exp_shift 24 |
---|
235 | #define Exp_shift1 24 |
---|
236 | #define Exp_msk1 ((__uint32_t)0x1000000L) |
---|
237 | #define Exp_msk11 ((__uint32_t)0x1000000L) |
---|
238 | #define Exp_mask ((__uint32_t)0x7f000000L) |
---|
239 | #define P 14 |
---|
240 | #define Bias 65 |
---|
241 | #define Exp_1 ((__uint32_t)0x41000000L) |
---|
242 | #define Exp_11 ((__uint32_t)0x41000000L) |
---|
243 | #define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ |
---|
244 | #define Frac_mask ((__uint32_t)0xffffffL) |
---|
245 | #define Frac_mask1 ((__uint32_t)0xffffffL) |
---|
246 | #define Bletch 4 |
---|
247 | #define Ten_pmax 22 |
---|
248 | #define Bndry_mask ((__uint32_t)0xefffffL) |
---|
249 | #define Bndry_mask1 ((__uint32_t)0xffffffL) |
---|
250 | #define LSB 1 |
---|
251 | #define Sign_bit ((__uint32_t)0x80000000L) |
---|
252 | #define Log2P 4 |
---|
253 | #define Tiny0 ((__uint32_t)0x100000L) |
---|
254 | #define Tiny1 0 |
---|
255 | #define Quick_max 14 |
---|
256 | #define Int_max 15 |
---|
257 | #else /* VAX */ |
---|
258 | #define Exp_shift 23 |
---|
259 | #define Exp_shift1 7 |
---|
260 | #define Exp_msk1 0x80 |
---|
261 | #define Exp_msk11 ((__uint32_t)0x800000L) |
---|
262 | #define Exp_mask ((__uint32_t)0x7f80L) |
---|
263 | #define P 56 |
---|
264 | #define Bias 129 |
---|
265 | #define Exp_1 ((__uint32_t)0x40800000L) |
---|
266 | #define Exp_11 ((__uint32_t)0x4080L) |
---|
267 | #define Ebits 8 |
---|
268 | #define Frac_mask ((__uint32_t)0x7fffffL) |
---|
269 | #define Frac_mask1 ((__uint32_t)0xffff007fL) |
---|
270 | #define Ten_pmax 24 |
---|
271 | #define Bletch 2 |
---|
272 | #define Bndry_mask ((__uint32_t)0xffff007fL) |
---|
273 | #define Bndry_mask1 ((__uint32_t)0xffff007fL) |
---|
274 | #define LSB ((__uint32_t)0x10000L) |
---|
275 | #define Sign_bit ((__uint32_t)0x8000L) |
---|
276 | #define Log2P 1 |
---|
277 | #define Tiny0 0x80 |
---|
278 | #define Tiny1 0 |
---|
279 | #define Quick_max 15 |
---|
280 | #define Int_max 15 |
---|
281 | #endif |
---|
282 | #endif |
---|
283 | |
---|
284 | |
---|