floatformat.c revision 1.1 1 1.1 christos /* IEEE floating point support routines, for GDB, the GNU Debugger.
2 1.1 christos Copyright 1991, 1994, 1999, 2000, 2003, 2005, 2006, 2010
3 1.1 christos Free Software Foundation, Inc.
4 1.1 christos
5 1.1 christos This file is part of GDB.
6 1.1 christos
7 1.1 christos This program is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 2 of the License, or
10 1.1 christos (at your option) any later version.
11 1.1 christos
12 1.1 christos This program is distributed in the hope that it will be useful,
13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 christos GNU General Public License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with this program; if not, write to the Free Software
19 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
20 1.1 christos
21 1.1 christos /* This is needed to pick up the NAN macro on some systems. */
22 1.1 christos #define _GNU_SOURCE
23 1.1 christos
24 1.1 christos #ifdef HAVE_CONFIG_H
25 1.1 christos #include "config.h"
26 1.1 christos #endif
27 1.1 christos
28 1.1 christos #include <math.h>
29 1.1 christos
30 1.1 christos #ifdef HAVE_STRING_H
31 1.1 christos #include <string.h>
32 1.1 christos #endif
33 1.1 christos
34 1.1 christos /* On some platforms, <float.h> provides DBL_QNAN. */
35 1.1 christos #ifdef STDC_HEADERS
36 1.1 christos #include <float.h>
37 1.1 christos #endif
38 1.1 christos
39 1.1 christos #include "ansidecl.h"
40 1.1 christos #include "libiberty.h"
41 1.1 christos #include "floatformat.h"
42 1.1 christos
43 1.1 christos #ifndef INFINITY
44 1.1 christos #ifdef HUGE_VAL
45 1.1 christos #define INFINITY HUGE_VAL
46 1.1 christos #else
47 1.1 christos #define INFINITY (1.0 / 0.0)
48 1.1 christos #endif
49 1.1 christos #endif
50 1.1 christos
51 1.1 christos #ifndef NAN
52 1.1 christos #ifdef DBL_QNAN
53 1.1 christos #define NAN DBL_QNAN
54 1.1 christos #else
55 1.1 christos #define NAN (0.0 / 0.0)
56 1.1 christos #endif
57 1.1 christos #endif
58 1.1 christos
59 1.1 christos static int mant_bits_set (const struct floatformat *, const unsigned char *);
60 1.1 christos static unsigned long get_field (const unsigned char *,
61 1.1 christos enum floatformat_byteorders,
62 1.1 christos unsigned int,
63 1.1 christos unsigned int,
64 1.1 christos unsigned int);
65 1.1 christos static int floatformat_always_valid (const struct floatformat *fmt,
66 1.1 christos const void *from);
67 1.1 christos
68 1.1 christos static int
69 1.1 christos floatformat_always_valid (const struct floatformat *fmt ATTRIBUTE_UNUSED,
70 1.1 christos const void *from ATTRIBUTE_UNUSED)
71 1.1 christos {
72 1.1 christos return 1;
73 1.1 christos }
74 1.1 christos
75 1.1 christos /* The odds that CHAR_BIT will be anything but 8 are low enough that I'm not
76 1.1 christos going to bother with trying to muck around with whether it is defined in
77 1.1 christos a system header, what we do if not, etc. */
78 1.1 christos #define FLOATFORMAT_CHAR_BIT 8
79 1.1 christos
80 1.1 christos /* floatformats for IEEE half, single and double, big and little endian. */
81 1.1 christos const struct floatformat floatformat_ieee_half_big =
82 1.1 christos {
83 1.1 christos floatformat_big, 16, 0, 1, 5, 15, 31, 6, 10,
84 1.1 christos floatformat_intbit_no,
85 1.1 christos "floatformat_ieee_half_big",
86 1.1 christos floatformat_always_valid,
87 1.1 christos NULL
88 1.1 christos };
89 1.1 christos const struct floatformat floatformat_ieee_half_little =
90 1.1 christos {
91 1.1 christos floatformat_little, 16, 0, 1, 5, 15, 31, 6, 10,
92 1.1 christos floatformat_intbit_no,
93 1.1 christos "floatformat_ieee_half_little",
94 1.1 christos floatformat_always_valid,
95 1.1 christos NULL
96 1.1 christos };
97 1.1 christos const struct floatformat floatformat_ieee_single_big =
98 1.1 christos {
99 1.1 christos floatformat_big, 32, 0, 1, 8, 127, 255, 9, 23,
100 1.1 christos floatformat_intbit_no,
101 1.1 christos "floatformat_ieee_single_big",
102 1.1 christos floatformat_always_valid,
103 1.1 christos NULL
104 1.1 christos };
105 1.1 christos const struct floatformat floatformat_ieee_single_little =
106 1.1 christos {
107 1.1 christos floatformat_little, 32, 0, 1, 8, 127, 255, 9, 23,
108 1.1 christos floatformat_intbit_no,
109 1.1 christos "floatformat_ieee_single_little",
110 1.1 christos floatformat_always_valid,
111 1.1 christos NULL
112 1.1 christos };
113 1.1 christos const struct floatformat floatformat_ieee_double_big =
114 1.1 christos {
115 1.1 christos floatformat_big, 64, 0, 1, 11, 1023, 2047, 12, 52,
116 1.1 christos floatformat_intbit_no,
117 1.1 christos "floatformat_ieee_double_big",
118 1.1 christos floatformat_always_valid,
119 1.1 christos NULL
120 1.1 christos };
121 1.1 christos const struct floatformat floatformat_ieee_double_little =
122 1.1 christos {
123 1.1 christos floatformat_little, 64, 0, 1, 11, 1023, 2047, 12, 52,
124 1.1 christos floatformat_intbit_no,
125 1.1 christos "floatformat_ieee_double_little",
126 1.1 christos floatformat_always_valid,
127 1.1 christos NULL
128 1.1 christos };
129 1.1 christos
130 1.1 christos /* floatformat for IEEE double, little endian byte order, with big endian word
131 1.1 christos ordering, as on the ARM. */
132 1.1 christos
133 1.1 christos const struct floatformat floatformat_ieee_double_littlebyte_bigword =
134 1.1 christos {
135 1.1 christos floatformat_littlebyte_bigword, 64, 0, 1, 11, 1023, 2047, 12, 52,
136 1.1 christos floatformat_intbit_no,
137 1.1 christos "floatformat_ieee_double_littlebyte_bigword",
138 1.1 christos floatformat_always_valid,
139 1.1 christos NULL
140 1.1 christos };
141 1.1 christos
142 1.1 christos /* floatformat for VAX. Not quite IEEE, but close enough. */
143 1.1 christos
144 1.1 christos const struct floatformat floatformat_vax_f =
145 1.1 christos {
146 1.1 christos floatformat_vax, 32, 0, 1, 8, 129, 0, 9, 23,
147 1.1 christos floatformat_intbit_no,
148 1.1 christos "floatformat_vax_f",
149 1.1 christos floatformat_always_valid,
150 1.1 christos NULL
151 1.1 christos };
152 1.1 christos const struct floatformat floatformat_vax_d =
153 1.1 christos {
154 1.1 christos floatformat_vax, 64, 0, 1, 8, 129, 0, 9, 55,
155 1.1 christos floatformat_intbit_no,
156 1.1 christos "floatformat_vax_d",
157 1.1 christos floatformat_always_valid,
158 1.1 christos NULL
159 1.1 christos };
160 1.1 christos const struct floatformat floatformat_vax_g =
161 1.1 christos {
162 1.1 christos floatformat_vax, 64, 0, 1, 11, 1025, 0, 12, 52,
163 1.1 christos floatformat_intbit_no,
164 1.1 christos "floatformat_vax_g",
165 1.1 christos floatformat_always_valid,
166 1.1 christos NULL
167 1.1 christos };
168 1.1 christos
169 1.1 christos static int floatformat_i387_ext_is_valid (const struct floatformat *fmt,
170 1.1 christos const void *from);
171 1.1 christos
172 1.1 christos static int
173 1.1 christos floatformat_i387_ext_is_valid (const struct floatformat *fmt, const void *from)
174 1.1 christos {
175 1.1 christos /* In the i387 double-extended format, if the exponent is all ones,
176 1.1 christos then the integer bit must be set. If the exponent is neither 0
177 1.1 christos nor ~0, the intbit must also be set. Only if the exponent is
178 1.1 christos zero can it be zero, and then it must be zero. */
179 1.1 christos unsigned long exponent, int_bit;
180 1.1 christos const unsigned char *ufrom = (const unsigned char *) from;
181 1.1 christos
182 1.1 christos exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize,
183 1.1 christos fmt->exp_start, fmt->exp_len);
184 1.1 christos int_bit = get_field (ufrom, fmt->byteorder, fmt->totalsize,
185 1.1 christos fmt->man_start, 1);
186 1.1 christos
187 1.1 christos if ((exponent == 0) != (int_bit == 0))
188 1.1 christos return 0;
189 1.1 christos else
190 1.1 christos return 1;
191 1.1 christos }
192 1.1 christos
193 1.1 christos const struct floatformat floatformat_i387_ext =
194 1.1 christos {
195 1.1 christos floatformat_little, 80, 0, 1, 15, 0x3fff, 0x7fff, 16, 64,
196 1.1 christos floatformat_intbit_yes,
197 1.1 christos "floatformat_i387_ext",
198 1.1 christos floatformat_i387_ext_is_valid,
199 1.1 christos NULL
200 1.1 christos };
201 1.1 christos const struct floatformat floatformat_m68881_ext =
202 1.1 christos {
203 1.1 christos /* Note that the bits from 16 to 31 are unused. */
204 1.1 christos floatformat_big, 96, 0, 1, 15, 0x3fff, 0x7fff, 32, 64,
205 1.1 christos floatformat_intbit_yes,
206 1.1 christos "floatformat_m68881_ext",
207 1.1 christos floatformat_always_valid,
208 1.1 christos NULL
209 1.1 christos };
210 1.1 christos const struct floatformat floatformat_i960_ext =
211 1.1 christos {
212 1.1 christos /* Note that the bits from 0 to 15 are unused. */
213 1.1 christos floatformat_little, 96, 16, 17, 15, 0x3fff, 0x7fff, 32, 64,
214 1.1 christos floatformat_intbit_yes,
215 1.1 christos "floatformat_i960_ext",
216 1.1 christos floatformat_always_valid,
217 1.1 christos NULL
218 1.1 christos };
219 1.1 christos const struct floatformat floatformat_m88110_ext =
220 1.1 christos {
221 1.1 christos floatformat_big, 80, 0, 1, 15, 0x3fff, 0x7fff, 16, 64,
222 1.1 christos floatformat_intbit_yes,
223 1.1 christos "floatformat_m88110_ext",
224 1.1 christos floatformat_always_valid,
225 1.1 christos NULL
226 1.1 christos };
227 1.1 christos const struct floatformat floatformat_m88110_harris_ext =
228 1.1 christos {
229 1.1 christos /* Harris uses raw format 128 bytes long, but the number is just an ieee
230 1.1 christos double, and the last 64 bits are wasted. */
231 1.1 christos floatformat_big,128, 0, 1, 11, 0x3ff, 0x7ff, 12, 52,
232 1.1 christos floatformat_intbit_no,
233 1.1 christos "floatformat_m88110_ext_harris",
234 1.1 christos floatformat_always_valid,
235 1.1 christos NULL
236 1.1 christos };
237 1.1 christos const struct floatformat floatformat_arm_ext_big =
238 1.1 christos {
239 1.1 christos /* Bits 1 to 16 are unused. */
240 1.1 christos floatformat_big, 96, 0, 17, 15, 0x3fff, 0x7fff, 32, 64,
241 1.1 christos floatformat_intbit_yes,
242 1.1 christos "floatformat_arm_ext_big",
243 1.1 christos floatformat_always_valid,
244 1.1 christos NULL
245 1.1 christos };
246 1.1 christos const struct floatformat floatformat_arm_ext_littlebyte_bigword =
247 1.1 christos {
248 1.1 christos /* Bits 1 to 16 are unused. */
249 1.1 christos floatformat_littlebyte_bigword, 96, 0, 17, 15, 0x3fff, 0x7fff, 32, 64,
250 1.1 christos floatformat_intbit_yes,
251 1.1 christos "floatformat_arm_ext_littlebyte_bigword",
252 1.1 christos floatformat_always_valid,
253 1.1 christos NULL
254 1.1 christos };
255 1.1 christos const struct floatformat floatformat_ia64_spill_big =
256 1.1 christos {
257 1.1 christos floatformat_big, 128, 0, 1, 17, 65535, 0x1ffff, 18, 64,
258 1.1 christos floatformat_intbit_yes,
259 1.1 christos "floatformat_ia64_spill_big",
260 1.1 christos floatformat_always_valid,
261 1.1 christos NULL
262 1.1 christos };
263 1.1 christos const struct floatformat floatformat_ia64_spill_little =
264 1.1 christos {
265 1.1 christos floatformat_little, 128, 0, 1, 17, 65535, 0x1ffff, 18, 64,
266 1.1 christos floatformat_intbit_yes,
267 1.1 christos "floatformat_ia64_spill_little",
268 1.1 christos floatformat_always_valid,
269 1.1 christos NULL
270 1.1 christos };
271 1.1 christos const struct floatformat floatformat_ia64_quad_big =
272 1.1 christos {
273 1.1 christos floatformat_big, 128, 0, 1, 15, 16383, 0x7fff, 16, 112,
274 1.1 christos floatformat_intbit_no,
275 1.1 christos "floatformat_ia64_quad_big",
276 1.1 christos floatformat_always_valid,
277 1.1 christos NULL
278 1.1 christos };
279 1.1 christos const struct floatformat floatformat_ia64_quad_little =
280 1.1 christos {
281 1.1 christos floatformat_little, 128, 0, 1, 15, 16383, 0x7fff, 16, 112,
282 1.1 christos floatformat_intbit_no,
283 1.1 christos "floatformat_ia64_quad_little",
284 1.1 christos floatformat_always_valid,
285 1.1 christos NULL
286 1.1 christos };
287 1.1 christos
288 1.1 christos static int
289 1.1 christos floatformat_ibm_long_double_is_valid (const struct floatformat *fmt,
290 1.1 christos const void *from)
291 1.1 christos {
292 1.1 christos const unsigned char *ufrom = (const unsigned char *) from;
293 1.1 christos const struct floatformat *hfmt = fmt->split_half;
294 1.1 christos long top_exp, bot_exp;
295 1.1 christos int top_nan = 0;
296 1.1 christos
297 1.1 christos top_exp = get_field (ufrom, hfmt->byteorder, hfmt->totalsize,
298 1.1 christos hfmt->exp_start, hfmt->exp_len);
299 1.1 christos bot_exp = get_field (ufrom + 8, hfmt->byteorder, hfmt->totalsize,
300 1.1 christos hfmt->exp_start, hfmt->exp_len);
301 1.1 christos
302 1.1 christos if ((unsigned long) top_exp == hfmt->exp_nan)
303 1.1 christos top_nan = mant_bits_set (hfmt, ufrom);
304 1.1 christos
305 1.1 christos /* A NaN is valid with any low part. */
306 1.1 christos if (top_nan)
307 1.1 christos return 1;
308 1.1 christos
309 1.1 christos /* An infinity, zero or denormal requires low part 0 (positive or
310 1.1 christos negative). */
311 1.1 christos if ((unsigned long) top_exp == hfmt->exp_nan || top_exp == 0)
312 1.1 christos {
313 1.1 christos if (bot_exp != 0)
314 1.1 christos return 0;
315 1.1 christos
316 1.1 christos return !mant_bits_set (hfmt, ufrom + 8);
317 1.1 christos }
318 1.1 christos
319 1.1 christos /* The top part is now a finite normal value. The long double value
320 1.1 christos is the sum of the two parts, and the top part must equal the
321 1.1 christos result of rounding the long double value to nearest double. Thus
322 1.1 christos the bottom part must be <= 0.5ulp of the top part in absolute
323 1.1 christos value, and if it is < 0.5ulp then the long double is definitely
324 1.1 christos valid. */
325 1.1 christos if (bot_exp < top_exp - 53)
326 1.1 christos return 1;
327 1.1 christos if (bot_exp > top_exp - 53 && bot_exp != 0)
328 1.1 christos return 0;
329 1.1 christos if (bot_exp == 0)
330 1.1 christos {
331 1.1 christos /* The bottom part is 0 or denormal. Determine which, and if
332 1.1 christos denormal the first two set bits. */
333 1.1 christos int first_bit = -1, second_bit = -1, cur_bit;
334 1.1 christos for (cur_bit = 0; (unsigned int) cur_bit < hfmt->man_len; cur_bit++)
335 1.1 christos if (get_field (ufrom + 8, hfmt->byteorder, hfmt->totalsize,
336 1.1 christos hfmt->man_start + cur_bit, 1))
337 1.1 christos {
338 1.1 christos if (first_bit == -1)
339 1.1 christos first_bit = cur_bit;
340 1.1 christos else
341 1.1 christos {
342 1.1 christos second_bit = cur_bit;
343 1.1 christos break;
344 1.1 christos }
345 1.1 christos }
346 1.1 christos /* Bottom part 0 is OK. */
347 1.1 christos if (first_bit == -1)
348 1.1 christos return 1;
349 1.1 christos /* The real exponent of the bottom part is -first_bit. */
350 1.1 christos if (-first_bit < top_exp - 53)
351 1.1 christos return 1;
352 1.1 christos if (-first_bit > top_exp - 53)
353 1.1 christos return 0;
354 1.1 christos /* The bottom part is at least 0.5ulp of the top part. For this
355 1.1 christos to be OK, the bottom part must be exactly 0.5ulp (i.e. no
356 1.1 christos more bits set) and the top part must have last bit 0. */
357 1.1 christos if (second_bit != -1)
358 1.1 christos return 0;
359 1.1 christos return !get_field (ufrom, hfmt->byteorder, hfmt->totalsize,
360 1.1 christos hfmt->man_start + hfmt->man_len - 1, 1);
361 1.1 christos }
362 1.1 christos else
363 1.1 christos {
364 1.1 christos /* The bottom part is at least 0.5ulp of the top part. For this
365 1.1 christos to be OK, it must be exactly 0.5ulp (i.e. no explicit bits
366 1.1 christos set) and the top part must have last bit 0. */
367 1.1 christos if (get_field (ufrom, hfmt->byteorder, hfmt->totalsize,
368 1.1 christos hfmt->man_start + hfmt->man_len - 1, 1))
369 1.1 christos return 0;
370 1.1 christos return !mant_bits_set (hfmt, ufrom + 8);
371 1.1 christos }
372 1.1 christos }
373 1.1 christos
374 1.1 christos const struct floatformat floatformat_ibm_long_double =
375 1.1 christos {
376 1.1 christos floatformat_big, 128, 0, 1, 11, 1023, 2047, 12, 52,
377 1.1 christos floatformat_intbit_no,
378 1.1 christos "floatformat_ibm_long_double",
379 1.1 christos floatformat_ibm_long_double_is_valid,
380 1.1 christos &floatformat_ieee_double_big
381 1.1 christos };
382 1.1 christos
383 1.1 christos
385 1.1 christos #ifndef min
386 1.1 christos #define min(a, b) ((a) < (b) ? (a) : (b))
387 1.1 christos #endif
388 1.1 christos
389 1.1 christos /* Return 1 if any bits are explicitly set in the mantissa of UFROM,
390 1.1 christos format FMT, 0 otherwise. */
391 1.1 christos static int
392 1.1 christos mant_bits_set (const struct floatformat *fmt, const unsigned char *ufrom)
393 1.1 christos {
394 1.1 christos unsigned int mant_bits, mant_off;
395 1.1 christos int mant_bits_left;
396 1.1 christos
397 1.1 christos mant_off = fmt->man_start;
398 1.1 christos mant_bits_left = fmt->man_len;
399 1.1 christos while (mant_bits_left > 0)
400 1.1 christos {
401 1.1 christos mant_bits = min (mant_bits_left, 32);
402 1.1 christos
403 1.1 christos if (get_field (ufrom, fmt->byteorder, fmt->totalsize,
404 1.1 christos mant_off, mant_bits) != 0)
405 1.1 christos return 1;
406 1.1 christos
407 1.1 christos mant_off += mant_bits;
408 1.1 christos mant_bits_left -= mant_bits;
409 1.1 christos }
410 1.1 christos return 0;
411 1.1 christos }
412 1.1 christos
413 1.1 christos /* Extract a field which starts at START and is LEN bits long. DATA and
414 1.1 christos TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */
415 1.1 christos static unsigned long
416 1.1 christos get_field (const unsigned char *data, enum floatformat_byteorders order,
417 1.1 christos unsigned int total_len, unsigned int start, unsigned int len)
418 1.1 christos {
419 1.1 christos unsigned long result = 0;
420 1.1 christos unsigned int cur_byte;
421 1.1 christos int lo_bit, hi_bit, cur_bitshift = 0;
422 1.1 christos int nextbyte = (order == floatformat_little) ? 1 : -1;
423 1.1 christos
424 1.1 christos /* Start is in big-endian bit order! Fix that first. */
425 1.1 christos start = total_len - (start + len);
426 1.1 christos
427 1.1 christos /* Start at the least significant part of the field. */
428 1.1 christos if (order == floatformat_little)
429 1.1 christos cur_byte = start / FLOATFORMAT_CHAR_BIT;
430 1.1 christos else
431 1.1 christos cur_byte = (total_len - start - 1) / FLOATFORMAT_CHAR_BIT;
432 1.1 christos
433 1.1 christos lo_bit = start % FLOATFORMAT_CHAR_BIT;
434 1.1 christos hi_bit = min (lo_bit + len, FLOATFORMAT_CHAR_BIT);
435 1.1 christos
436 1.1 christos do
437 1.1 christos {
438 1.1 christos unsigned int shifted = *(data + cur_byte) >> lo_bit;
439 1.1 christos unsigned int bits = hi_bit - lo_bit;
440 1.1 christos unsigned int mask = (1 << bits) - 1;
441 1.1 christos result |= (shifted & mask) << cur_bitshift;
442 1.1 christos len -= bits;
443 1.1 christos cur_bitshift += bits;
444 1.1 christos cur_byte += nextbyte;
445 1.1 christos lo_bit = 0;
446 1.1 christos hi_bit = min (len, FLOATFORMAT_CHAR_BIT);
447 1.1 christos }
448 1.1 christos while (len != 0);
449 1.1 christos
450 1.1 christos return result;
451 1.1 christos }
452 1.1 christos
453 1.1 christos /* Convert from FMT to a double.
454 1.1 christos FROM is the address of the extended float.
455 1.1 christos Store the double in *TO. */
456 1.1 christos
457 1.1 christos void
458 1.1 christos floatformat_to_double (const struct floatformat *fmt,
459 1.1 christos const void *from, double *to)
460 1.1 christos {
461 1.1 christos const unsigned char *ufrom = (const unsigned char *) from;
462 1.1 christos double dto;
463 1.1 christos long exponent;
464 1.1 christos unsigned long mant;
465 1.1 christos unsigned int mant_bits, mant_off;
466 1.1 christos int mant_bits_left;
467 1.1 christos int special_exponent; /* It's a NaN, denorm or zero */
468 1.1 christos
469 1.1 christos /* Split values are not handled specially, since the top half has
470 1.1 christos the correctly rounded double value (in the only supported case of
471 1.1 christos split values). */
472 1.1 christos
473 1.1 christos exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize,
474 1.1 christos fmt->exp_start, fmt->exp_len);
475 1.1 christos
476 1.1 christos /* If the exponent indicates a NaN, we don't have information to
477 1.1 christos decide what to do. So we handle it like IEEE, except that we
478 1.1 christos don't try to preserve the type of NaN. FIXME. */
479 1.1 christos if ((unsigned long) exponent == fmt->exp_nan)
480 1.1 christos {
481 1.1 christos int nan = mant_bits_set (fmt, ufrom);
482 1.1 christos
483 1.1 christos /* On certain systems (such as GNU/Linux), the use of the
484 1.1 christos INFINITY macro below may generate a warning that can not be
485 1.1 christos silenced due to a bug in GCC (PR preprocessor/11931). The
486 1.1 christos preprocessor fails to recognise the __extension__ keyword in
487 1.1 christos conjunction with the GNU/C99 extension for hexadecimal
488 1.1 christos floating point constants and will issue a warning when
489 1.1 christos compiling with -pedantic. */
490 1.1 christos if (nan)
491 1.1 christos dto = NAN;
492 1.1 christos else
493 1.1 christos dto = INFINITY;
494 1.1 christos
495 1.1 christos if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1))
496 1.1 christos dto = -dto;
497 1.1 christos
498 1.1 christos *to = dto;
499 1.1 christos
500 1.1 christos return;
501 1.1 christos }
502 1.1 christos
503 1.1 christos mant_bits_left = fmt->man_len;
504 1.1 christos mant_off = fmt->man_start;
505 1.1 christos dto = 0.0;
506 1.1 christos
507 1.1 christos special_exponent = exponent == 0 || (unsigned long) exponent == fmt->exp_nan;
508 1.1 christos
509 1.1 christos /* Don't bias zero's, denorms or NaNs. */
510 1.1 christos if (!special_exponent)
511 1.1 christos exponent -= fmt->exp_bias;
512 1.1 christos
513 1.1 christos /* Build the result algebraically. Might go infinite, underflow, etc;
514 1.1 christos who cares. */
515 1.1 christos
516 1.1 christos /* If this format uses a hidden bit, explicitly add it in now. Otherwise,
517 1.1 christos increment the exponent by one to account for the integer bit. */
518 1.1 christos
519 1.1 christos if (!special_exponent)
520 1.1 christos {
521 1.1 christos if (fmt->intbit == floatformat_intbit_no)
522 1.1 christos dto = ldexp (1.0, exponent);
523 1.1 christos else
524 1.1 christos exponent++;
525 1.1 christos }
526 1.1 christos
527 1.1 christos while (mant_bits_left > 0)
528 1.1 christos {
529 1.1 christos mant_bits = min (mant_bits_left, 32);
530 1.1 christos
531 1.1 christos mant = get_field (ufrom, fmt->byteorder, fmt->totalsize,
532 1.1 christos mant_off, mant_bits);
533 1.1 christos
534 1.1 christos /* Handle denormalized numbers. FIXME: What should we do for
535 1.1 christos non-IEEE formats? */
536 1.1 christos if (special_exponent && exponent == 0 && mant != 0)
537 1.1 christos dto += ldexp ((double)mant,
538 1.1 christos (- fmt->exp_bias
539 1.1 christos - mant_bits
540 1.1 christos - (mant_off - fmt->man_start)
541 1.1 christos + 1));
542 1.1 christos else
543 1.1 christos dto += ldexp ((double)mant, exponent - mant_bits);
544 1.1 christos if (exponent != 0)
545 1.1 christos exponent -= mant_bits;
546 1.1 christos mant_off += mant_bits;
547 1.1 christos mant_bits_left -= mant_bits;
548 1.1 christos }
549 1.1 christos
550 1.1 christos /* Negate it if negative. */
551 1.1 christos if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1))
552 1.1 christos dto = -dto;
553 1.1 christos *to = dto;
554 1.1 christos }
555 1.1 christos
556 1.1 christos static void put_field (unsigned char *, enum floatformat_byteorders,
558 1.1 christos unsigned int,
559 1.1 christos unsigned int,
560 1.1 christos unsigned int,
561 1.1 christos unsigned long);
562 1.1 christos
563 1.1 christos /* Set a field which starts at START and is LEN bits long. DATA and
564 1.1 christos TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */
565 1.1 christos static void
566 1.1 christos put_field (unsigned char *data, enum floatformat_byteorders order,
567 1.1 christos unsigned int total_len, unsigned int start, unsigned int len,
568 1.1 christos unsigned long stuff_to_put)
569 1.1 christos {
570 1.1 christos unsigned int cur_byte;
571 1.1 christos int lo_bit, hi_bit;
572 1.1 christos int nextbyte = (order == floatformat_little) ? 1 : -1;
573 1.1 christos
574 1.1 christos /* Start is in big-endian bit order! Fix that first. */
575 1.1 christos start = total_len - (start + len);
576 1.1 christos
577 1.1 christos /* Start at the least significant part of the field. */
578 1.1 christos if (order == floatformat_little)
579 1.1 christos cur_byte = start / FLOATFORMAT_CHAR_BIT;
580 1.1 christos else
581 1.1 christos cur_byte = (total_len - start - 1) / FLOATFORMAT_CHAR_BIT;
582 1.1 christos
583 1.1 christos lo_bit = start % FLOATFORMAT_CHAR_BIT;
584 1.1 christos hi_bit = min (lo_bit + len, FLOATFORMAT_CHAR_BIT);
585 1.1 christos
586 1.1 christos do
587 1.1 christos {
588 1.1 christos unsigned char *byte_ptr = data + cur_byte;
589 1.1 christos unsigned int bits = hi_bit - lo_bit;
590 1.1 christos unsigned int mask = ((1 << bits) - 1) << lo_bit;
591 1.1 christos *byte_ptr = (*byte_ptr & ~mask) | ((stuff_to_put << lo_bit) & mask);
592 1.1 christos stuff_to_put >>= bits;
593 1.1 christos len -= bits;
594 1.1 christos cur_byte += nextbyte;
595 1.1 christos lo_bit = 0;
596 1.1 christos hi_bit = min (len, FLOATFORMAT_CHAR_BIT);
597 1.1 christos }
598 1.1 christos while (len != 0);
599 1.1 christos }
600 1.1 christos
601 1.1 christos /* The converse: convert the double *FROM to an extended float
602 1.1 christos and store where TO points. Neither FROM nor TO have any alignment
603 1.1 christos restrictions. */
604 1.1 christos
605 1.1 christos void
606 1.1 christos floatformat_from_double (const struct floatformat *fmt,
607 1.1 christos const double *from, void *to)
608 1.1 christos {
609 1.1 christos double dfrom;
610 1.1 christos int exponent;
611 1.1 christos double mant;
612 1.1 christos unsigned int mant_bits, mant_off;
613 1.1 christos int mant_bits_left;
614 1.1 christos unsigned char *uto = (unsigned char *) to;
615 1.1 christos
616 1.1 christos dfrom = *from;
617 1.1 christos memset (uto, 0, fmt->totalsize / FLOATFORMAT_CHAR_BIT);
618 1.1 christos
619 1.1 christos /* Split values are not handled specially, since a bottom half of
620 1.1 christos zero is correct for any value representable as double (in the
621 1.1 christos only supported case of split values). */
622 1.1 christos
623 1.1 christos /* If negative, set the sign bit. */
624 1.1 christos if (dfrom < 0)
625 1.1 christos {
626 1.1 christos put_field (uto, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1, 1);
627 1.1 christos dfrom = -dfrom;
628 1.1 christos }
629 1.1 christos
630 1.1 christos if (dfrom == 0)
631 1.1 christos {
632 1.1 christos /* 0.0. */
633 1.1 christos return;
634 1.1 christos }
635 1.1 christos
636 1.1 christos if (dfrom != dfrom)
637 1.1 christos {
638 1.1 christos /* NaN. */
639 1.1 christos put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
640 1.1 christos fmt->exp_len, fmt->exp_nan);
641 1.1 christos /* Be sure it's not infinity, but NaN value is irrelevant. */
642 1.1 christos put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start,
643 1.1 christos 32, 1);
644 1.1 christos return;
645 1.1 christos }
646 1.1 christos
647 1.1 christos if (dfrom + dfrom == dfrom)
648 1.1 christos {
649 1.1 christos /* This can only happen for an infinite value (or zero, which we
650 1.1 christos already handled above). */
651 1.1 christos put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
652 1.1 christos fmt->exp_len, fmt->exp_nan);
653 1.1 christos return;
654 1.1 christos }
655 1.1 christos
656 1.1 christos mant = frexp (dfrom, &exponent);
657 1.1 christos if (exponent + fmt->exp_bias - 1 > 0)
658 1.1 christos put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
659 1.1 christos fmt->exp_len, exponent + fmt->exp_bias - 1);
660 1.1 christos else
661 1.1 christos {
662 1.1 christos /* Handle a denormalized number. FIXME: What should we do for
663 1.1 christos non-IEEE formats? */
664 1.1 christos put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
665 1.1 christos fmt->exp_len, 0);
666 1.1 christos mant = ldexp (mant, exponent + fmt->exp_bias - 1);
667 1.1 christos }
668 1.1 christos
669 1.1 christos mant_bits_left = fmt->man_len;
670 1.1 christos mant_off = fmt->man_start;
671 1.1 christos while (mant_bits_left > 0)
672 1.1 christos {
673 1.1 christos unsigned long mant_long;
674 1.1 christos mant_bits = mant_bits_left < 32 ? mant_bits_left : 32;
675 1.1 christos
676 1.1 christos mant *= 4294967296.0;
677 1.1 christos mant_long = (unsigned long)mant;
678 1.1 christos mant -= mant_long;
679 1.1 christos
680 1.1 christos /* If the integer bit is implicit, and we are not creating a
681 1.1 christos denormalized number, then we need to discard it. */
682 1.1 christos if ((unsigned int) mant_bits_left == fmt->man_len
683 1.1 christos && fmt->intbit == floatformat_intbit_no
684 1.1 christos && exponent + fmt->exp_bias - 1 > 0)
685 1.1 christos {
686 1.1 christos mant_long &= 0x7fffffff;
687 1.1 christos mant_bits -= 1;
688 1.1 christos }
689 1.1 christos else if (mant_bits < 32)
690 1.1 christos {
691 1.1 christos /* The bits we want are in the most significant MANT_BITS bits of
692 1.1 christos mant_long. Move them to the least significant. */
693 1.1 christos mant_long >>= 32 - mant_bits;
694 1.1 christos }
695 1.1 christos
696 1.1 christos put_field (uto, fmt->byteorder, fmt->totalsize,
697 1.1 christos mant_off, mant_bits, mant_long);
698 1.1 christos mant_off += mant_bits;
699 1.1 christos mant_bits_left -= mant_bits;
700 1.1 christos }
701 1.1 christos }
702 1.1 christos
703 1.1 christos /* Return non-zero iff the data at FROM is a valid number in format FMT. */
704 1.1 christos
705 1.1 christos int
706 1.1 christos floatformat_is_valid (const struct floatformat *fmt, const void *from)
707 1.1 christos {
708 1.1 christos return fmt->is_valid (fmt, from);
709 1.1 christos }
710 1.1 christos
711 1.1 christos
712 1.1 christos #ifdef IEEE_DEBUG
713 1.1 christos
714 1.1 christos #include <stdio.h>
715 1.1 christos
716 1.1 christos /* This is to be run on a host which uses IEEE floating point. */
717 1.1 christos
718 1.1 christos void
719 1.1 christos ieee_test (double n)
720 1.1 christos {
721 1.1 christos double result;
722 1.1 christos
723 1.1 christos floatformat_to_double (&floatformat_ieee_double_little, &n, &result);
724 1.1 christos if ((n != result && (! isnan (n) || ! isnan (result)))
725 1.1 christos || (n < 0 && result >= 0)
726 1.1 christos || (n >= 0 && result < 0))
727 1.1 christos printf ("Differ(to): %.20g -> %.20g\n", n, result);
728 1.1 christos
729 1.1 christos floatformat_from_double (&floatformat_ieee_double_little, &n, &result);
730 1.1 christos if ((n != result && (! isnan (n) || ! isnan (result)))
731 1.1 christos || (n < 0 && result >= 0)
732 1.1 christos || (n >= 0 && result < 0))
733 1.1 christos printf ("Differ(from): %.20g -> %.20g\n", n, result);
734 1.1 christos
735 1.1 christos #if 0
736 1.1 christos {
737 1.1 christos char exten[16];
738 1.1 christos
739 1.1 christos floatformat_from_double (&floatformat_m68881_ext, &n, exten);
740 1.1 christos floatformat_to_double (&floatformat_m68881_ext, exten, &result);
741 1.1 christos if (n != result)
742 1.1 christos printf ("Differ(to+from): %.20g -> %.20g\n", n, result);
743 1.1 christos }
744 1.1 christos #endif
745 1.1 christos
746 1.1 christos #if IEEE_DEBUG > 1
747 1.1 christos /* This is to be run on a host which uses 68881 format. */
748 1.1 christos {
749 1.1 christos long double ex = *(long double *)exten;
750 1.1 christos if (ex != n)
751 1.1 christos printf ("Differ(from vs. extended): %.20g\n", n);
752 1.1 christos }
753 1.1 christos #endif
754 1.1 christos }
755 1.1 christos
756 1.1 christos int
757 1.1 christos main (void)
758 1.1 christos {
759 1.1 christos ieee_test (0.0);
760 1.1 christos ieee_test (0.5);
761 1.1 christos ieee_test (256.0);
762 1.1 christos ieee_test (0.12345);
763 1.1 christos ieee_test (234235.78907234);
764 1.1 christos ieee_test (-512.0);
765 1.1 christos ieee_test (-0.004321);
766 1.1 christos ieee_test (1.2E-70);
767 1.1 christos ieee_test (1.2E-316);
768 1.1 christos ieee_test (4.9406564584124654E-324);
769 1.1 christos ieee_test (- 4.9406564584124654E-324);
770 1.1 christos ieee_test (- 0.0);
771 1.1 christos ieee_test (- INFINITY);
772 1.1 christos ieee_test (- NAN);
773 1.1 christos ieee_test (INFINITY);
774 1.1 christos ieee_test (NAN);
775 1.1 christos return 0;
776 }
777 #endif
778