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
floatformat_always_valid(const struct floatformat * fmt ATTRIBUTE_UNUSED,const void * from ATTRIBUTE_UNUSED)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
floatformat_i387_ext_is_valid(const struct floatformat * fmt,const void * from)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
floatformat_ibm_long_double_is_valid(const struct floatformat * fmt,const void * from)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
399 #ifndef min
400 #define min(a, b) ((a) < (b) ? (a) : (b))
401 #endif
402
403 /* Return 1 if any bits are explicitly set in the mantissa of UFROM,
404 format FMT, 0 otherwise. */
405 static int
mant_bits_set(const struct floatformat * fmt,const unsigned char * ufrom)406 mant_bits_set (const struct floatformat *fmt, const unsigned char *ufrom)
407 {
408 unsigned int mant_bits, mant_off;
409 int mant_bits_left;
410
411 mant_off = fmt->man_start;
412 mant_bits_left = fmt->man_len;
413 while (mant_bits_left > 0)
414 {
415 mant_bits = min (mant_bits_left, 32);
416
417 if (get_field (ufrom, fmt->byteorder, fmt->totalsize,
418 mant_off, mant_bits) != 0)
419 return 1;
420
421 mant_off += mant_bits;
422 mant_bits_left -= mant_bits;
423 }
424 return 0;
425 }
426
427 /* Extract a field which starts at START and is LEN bits long. DATA and
428 TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */
429 static unsigned long
get_field(const unsigned char * data,enum floatformat_byteorders order,unsigned int total_len,unsigned int start,unsigned int len)430 get_field (const unsigned char *data, enum floatformat_byteorders order,
431 unsigned int total_len, unsigned int start, unsigned int len)
432 {
433 unsigned long result = 0;
434 unsigned int cur_byte;
435 int lo_bit, hi_bit, cur_bitshift = 0;
436 int nextbyte = (order == floatformat_little) ? 1 : -1;
437
438 /* Start is in big-endian bit order! Fix that first. */
439 start = total_len - (start + len);
440
441 /* Start at the least significant part of the field. */
442 if (order == floatformat_little)
443 cur_byte = start / FLOATFORMAT_CHAR_BIT;
444 else
445 cur_byte = (total_len - start - 1) / FLOATFORMAT_CHAR_BIT;
446
447 lo_bit = start % FLOATFORMAT_CHAR_BIT;
448 hi_bit = min (lo_bit + len, FLOATFORMAT_CHAR_BIT);
449
450 do
451 {
452 unsigned int shifted = *(data + cur_byte) >> lo_bit;
453 unsigned int bits = hi_bit - lo_bit;
454 unsigned int mask = (1 << bits) - 1;
455 result |= (shifted & mask) << cur_bitshift;
456 len -= bits;
457 cur_bitshift += bits;
458 cur_byte += nextbyte;
459 lo_bit = 0;
460 hi_bit = min (len, FLOATFORMAT_CHAR_BIT);
461 }
462 while (len != 0);
463
464 return result;
465 }
466
467 /* Convert from FMT to a double.
468 FROM is the address of the extended float.
469 Store the double in *TO. */
470
471 void
floatformat_to_double(const struct floatformat * fmt,const void * from,double * to)472 floatformat_to_double (const struct floatformat *fmt,
473 const void *from, double *to)
474 {
475 const unsigned char *ufrom = (const unsigned char *) from;
476 double dto;
477 long exponent;
478 unsigned long mant;
479 unsigned int mant_bits, mant_off;
480 int mant_bits_left;
481
482 /* Split values are not handled specially, since the top half has
483 the correctly rounded double value (in the only supported case of
484 split values). */
485
486 exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize,
487 fmt->exp_start, fmt->exp_len);
488
489 /* If the exponent indicates a NaN, we don't have information to
490 decide what to do. So we handle it like IEEE, except that we
491 don't try to preserve the type of NaN. FIXME. */
492 if ((unsigned long) exponent == fmt->exp_nan)
493 {
494 int nan = mant_bits_set (fmt, ufrom);
495
496 /* On certain systems (such as GNU/Linux), the use of the
497 INFINITY macro below may generate a warning that cannot be
498 silenced due to a bug in GCC (PR preprocessor/11931). The
499 preprocessor fails to recognise the __extension__ keyword in
500 conjunction with the GNU/C99 extension for hexadecimal
501 floating point constants and will issue a warning when
502 compiling with -pedantic. */
503 if (nan)
504 dto = NAN;
505 else
506 #ifdef __vax__
507 dto = HUGE_VAL;
508 #else
509 dto = INFINITY;
510 #endif
511
512 if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1))
513 dto = -dto;
514
515 *to = dto;
516
517 return;
518 }
519
520 mant_bits_left = fmt->man_len;
521 mant_off = fmt->man_start;
522 dto = 0.0;
523
524 /* Build the result algebraically. Might go infinite, underflow, etc;
525 who cares. */
526
527 /* For denorms use minimum exponent. */
528 if (exponent == 0)
529 exponent = 1 - fmt->exp_bias;
530 else
531 {
532 exponent -= fmt->exp_bias;
533
534 /* If this format uses a hidden bit, explicitly add it in now.
535 Otherwise, increment the exponent by one to account for the
536 integer bit. */
537
538 if (fmt->intbit == floatformat_intbit_no)
539 dto = ldexp (1.0, exponent);
540 else
541 exponent++;
542 }
543
544 while (mant_bits_left > 0)
545 {
546 mant_bits = min (mant_bits_left, 32);
547
548 mant = get_field (ufrom, fmt->byteorder, fmt->totalsize,
549 mant_off, mant_bits);
550
551 dto += ldexp ((double) mant, exponent - mant_bits);
552 exponent -= mant_bits;
553 mant_off += mant_bits;
554 mant_bits_left -= mant_bits;
555 }
556
557 /* Negate it if negative. */
558 if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1))
559 dto = -dto;
560 *to = dto;
561 }
562
563 static void put_field (unsigned char *, enum floatformat_byteorders,
564 unsigned int,
565 unsigned int,
566 unsigned int,
567 unsigned long);
568
569 /* Set a field which starts at START and is LEN bits long. DATA and
570 TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */
571 static void
put_field(unsigned char * data,enum floatformat_byteorders order,unsigned int total_len,unsigned int start,unsigned int len,unsigned long stuff_to_put)572 put_field (unsigned char *data, enum floatformat_byteorders order,
573 unsigned int total_len, unsigned int start, unsigned int len,
574 unsigned long stuff_to_put)
575 {
576 unsigned int cur_byte;
577 int lo_bit, hi_bit;
578 int nextbyte = (order == floatformat_little) ? 1 : -1;
579
580 /* Start is in big-endian bit order! Fix that first. */
581 start = total_len - (start + len);
582
583 /* Start at the least significant part of the field. */
584 if (order == floatformat_little)
585 cur_byte = start / FLOATFORMAT_CHAR_BIT;
586 else
587 cur_byte = (total_len - start - 1) / FLOATFORMAT_CHAR_BIT;
588
589 lo_bit = start % FLOATFORMAT_CHAR_BIT;
590 hi_bit = min (lo_bit + len, FLOATFORMAT_CHAR_BIT);
591
592 do
593 {
594 unsigned char *byte_ptr = data + cur_byte;
595 unsigned int bits = hi_bit - lo_bit;
596 unsigned int mask = ((1 << bits) - 1) << lo_bit;
597 *byte_ptr = (*byte_ptr & ~mask) | ((stuff_to_put << lo_bit) & mask);
598 stuff_to_put >>= bits;
599 len -= bits;
600 cur_byte += nextbyte;
601 lo_bit = 0;
602 hi_bit = min (len, FLOATFORMAT_CHAR_BIT);
603 }
604 while (len != 0);
605 }
606
607 /* The converse: convert the double *FROM to an extended float
608 and store where TO points. Neither FROM nor TO have any alignment
609 restrictions. */
610
611 void
floatformat_from_double(const struct floatformat * fmt,const double * from,void * to)612 floatformat_from_double (const struct floatformat *fmt,
613 const double *from, void *to)
614 {
615 double dfrom;
616 int exponent;
617 double mant;
618 unsigned int mant_bits, mant_off;
619 int mant_bits_left;
620 unsigned char *uto = (unsigned char *) to;
621
622 dfrom = *from;
623 memset (uto, 0, fmt->totalsize / FLOATFORMAT_CHAR_BIT);
624
625 /* Split values are not handled specially, since a bottom half of
626 zero is correct for any value representable as double (in the
627 only supported case of split values). */
628
629 /* If negative, set the sign bit. */
630 if (dfrom < 0)
631 {
632 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1, 1);
633 dfrom = -dfrom;
634 }
635
636 if (dfrom == 0)
637 {
638 /* 0.0. */
639 return;
640 }
641
642 if (dfrom != dfrom)
643 {
644 /* NaN. */
645 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
646 fmt->exp_len, fmt->exp_nan);
647 /* Be sure it's not infinity, but NaN value is irrelevant. */
648 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start,
649 32, 1);
650 return;
651 }
652
653 if (dfrom + dfrom == dfrom)
654 {
655 /* This can only happen for an infinite value (or zero, which we
656 already handled above). */
657 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
658 fmt->exp_len, fmt->exp_nan);
659 return;
660 }
661
662 mant = frexp (dfrom, &exponent);
663 if (exponent + fmt->exp_bias - 1 > 0)
664 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
665 fmt->exp_len, exponent + fmt->exp_bias - 1);
666 else
667 {
668 /* Handle a denormalized number. FIXME: What should we do for
669 non-IEEE formats? */
670 put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
671 fmt->exp_len, 0);
672 mant = ldexp (mant, exponent + fmt->exp_bias - 1);
673 }
674
675 mant_bits_left = fmt->man_len;
676 mant_off = fmt->man_start;
677 while (mant_bits_left > 0)
678 {
679 unsigned long mant_long;
680 mant_bits = mant_bits_left < 32 ? mant_bits_left : 32;
681
682 mant *= 4294967296.0;
683 mant_long = (unsigned long)mant;
684 mant -= mant_long;
685
686 /* If the integer bit is implicit, and we are not creating a
687 denormalized number, then we need to discard it. */
688 if ((unsigned int) mant_bits_left == fmt->man_len
689 && fmt->intbit == floatformat_intbit_no
690 && exponent + fmt->exp_bias - 1 > 0)
691 {
692 mant_long &= 0x7fffffff;
693 mant_bits -= 1;
694 }
695 else if (mant_bits < 32)
696 {
697 /* The bits we want are in the most significant MANT_BITS bits of
698 mant_long. Move them to the least significant. */
699 mant_long >>= 32 - mant_bits;
700 }
701
702 put_field (uto, fmt->byteorder, fmt->totalsize,
703 mant_off, mant_bits, mant_long);
704 mant_off += mant_bits;
705 mant_bits_left -= mant_bits;
706 }
707 }
708
709 /* Return non-zero iff the data at FROM is a valid number in format FMT. */
710
711 int
floatformat_is_valid(const struct floatformat * fmt,const void * from)712 floatformat_is_valid (const struct floatformat *fmt, const void *from)
713 {
714 return fmt->is_valid (fmt, from);
715 }
716
717
718 #ifdef IEEE_DEBUG
719
720 #include <stdio.h>
721
722 /* This is to be run on a host which uses IEEE floating point. */
723
724 void
ieee_test(double n)725 ieee_test (double n)
726 {
727 double result;
728
729 floatformat_to_double (&floatformat_ieee_double_little, &n, &result);
730 if ((n != result && (! isnan (n) || ! isnan (result)))
731 || (n < 0 && result >= 0)
732 || (n >= 0 && result < 0))
733 printf ("Differ(to): %.20g -> %.20g\n", n, result);
734
735 floatformat_from_double (&floatformat_ieee_double_little, &n, &result);
736 if ((n != result && (! isnan (n) || ! isnan (result)))
737 || (n < 0 && result >= 0)
738 || (n >= 0 && result < 0))
739 printf ("Differ(from): %.20g -> %.20g\n", n, result);
740
741 #if 0
742 {
743 char exten[16];
744
745 floatformat_from_double (&floatformat_m68881_ext, &n, exten);
746 floatformat_to_double (&floatformat_m68881_ext, exten, &result);
747 if (n != result)
748 printf ("Differ(to+from): %.20g -> %.20g\n", n, result);
749 }
750 #endif
751
752 #if IEEE_DEBUG > 1
753 /* This is to be run on a host which uses 68881 format. */
754 {
755 long double ex = *(long double *)exten;
756 if (ex != n)
757 printf ("Differ(from vs. extended): %.20g\n", n);
758 }
759 #endif
760 }
761
762 int
main(void)763 main (void)
764 {
765 ieee_test (0.0);
766 ieee_test (0.5);
767 ieee_test (1.1);
768 ieee_test (256.0);
769 ieee_test (0.12345);
770 ieee_test (234235.78907234);
771 ieee_test (-512.0);
772 ieee_test (-0.004321);
773 ieee_test (1.2E-70);
774 ieee_test (1.2E-316);
775 ieee_test (4.9406564584124654E-324);
776 ieee_test (- 4.9406564584124654E-324);
777 ieee_test (- 0.0);
778 ieee_test (- INFINITY);
779 ieee_test (- NAN);
780 ieee_test (INFINITY);
781 ieee_test (NAN);
782 return 0;
783 }
784 #endif
785