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