xref: /netbsd-src/external/gpl3/gcc/dist/libiberty/floatformat.c (revision 32d1c65c71fbdb65a012e8392a62a757dd6853e9)
1 /* IEEE floating point support routines, for GDB, the GNU Debugger.
2    Copyright (C) 1991-2022 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, double and quad, 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 const struct floatformat floatformat_ieee_quad_big =
136 {
137   floatformat_big, 128, 0, 1, 15, 16383, 0x7fff, 16, 112,
138   floatformat_intbit_no,
139   "floatformat_ieee_quad_big",
140   floatformat_always_valid,
141   NULL
142 };
143 const struct floatformat floatformat_ieee_quad_little =
144 {
145   floatformat_little, 128, 0, 1, 15, 16383, 0x7fff, 16, 112,
146   floatformat_intbit_no,
147   "floatformat_ieee_quad_little",
148   floatformat_always_valid,
149   NULL
150 };
151 
152 /* floatformat for IEEE double, little endian byte order, with big endian word
153    ordering, as on the ARM.  */
154 
155 const struct floatformat floatformat_ieee_double_littlebyte_bigword =
156 {
157   floatformat_littlebyte_bigword, 64, 0, 1, 11, 1023, 2047, 12, 52,
158   floatformat_intbit_no,
159   "floatformat_ieee_double_littlebyte_bigword",
160   floatformat_always_valid,
161   NULL
162 };
163 
164 /* floatformat for VAX.  Not quite IEEE, but close enough.  */
165 
166 const struct floatformat floatformat_vax_f =
167 {
168   floatformat_vax, 32, 0, 1, 8, 129, 0, 9, 23,
169   floatformat_intbit_no,
170   "floatformat_vax_f",
171   floatformat_always_valid,
172   NULL
173 };
174 const struct floatformat floatformat_vax_d =
175 {
176   floatformat_vax, 64, 0, 1, 8, 129, 0, 9, 55,
177   floatformat_intbit_no,
178   "floatformat_vax_d",
179   floatformat_always_valid,
180   NULL
181 };
182 const struct floatformat floatformat_vax_g =
183 {
184   floatformat_vax, 64, 0, 1, 11, 1025, 0, 12, 52,
185   floatformat_intbit_no,
186   "floatformat_vax_g",
187   floatformat_always_valid,
188   NULL
189 };
190 
191 static int floatformat_i387_ext_is_valid (const struct floatformat *fmt,
192 					  const void *from);
193 
194 static int
195 floatformat_i387_ext_is_valid (const struct floatformat *fmt, const void *from)
196 {
197   /* In the i387 double-extended format, if the exponent is all ones,
198      then the integer bit must be set.  If the exponent is neither 0
199      nor ~0, the intbit must also be set.  Only if the exponent is
200      zero can it be zero, and then it must be zero.  */
201   unsigned long exponent, int_bit;
202   const unsigned char *ufrom = (const unsigned char *) from;
203 
204   exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize,
205 			fmt->exp_start, fmt->exp_len);
206   int_bit = get_field (ufrom, fmt->byteorder, fmt->totalsize,
207 		       fmt->man_start, 1);
208 
209   if ((exponent == 0) != (int_bit == 0))
210     return 0;
211   else
212     return 1;
213 }
214 
215 const struct floatformat floatformat_i387_ext =
216 {
217   floatformat_little, 80, 0, 1, 15, 0x3fff, 0x7fff, 16, 64,
218   floatformat_intbit_yes,
219   "floatformat_i387_ext",
220   floatformat_i387_ext_is_valid,
221   NULL
222 };
223 const struct floatformat floatformat_m68881_ext =
224 {
225   /* Note that the bits from 16 to 31 are unused.  */
226   floatformat_big, 96, 0, 1, 15, 0x3fff, 0x7fff, 32, 64,
227   floatformat_intbit_yes,
228   "floatformat_m68881_ext",
229   floatformat_always_valid,
230   NULL
231 };
232 const struct floatformat floatformat_i960_ext =
233 {
234   /* Note that the bits from 0 to 15 are unused.  */
235   floatformat_little, 96, 16, 17, 15, 0x3fff, 0x7fff, 32, 64,
236   floatformat_intbit_yes,
237   "floatformat_i960_ext",
238   floatformat_always_valid,
239   NULL
240 };
241 const struct floatformat floatformat_m88110_ext =
242 {
243   floatformat_big, 80, 0, 1, 15, 0x3fff, 0x7fff, 16, 64,
244   floatformat_intbit_yes,
245   "floatformat_m88110_ext",
246   floatformat_always_valid,
247   NULL
248 };
249 const struct floatformat floatformat_m88110_harris_ext =
250 {
251   /* Harris uses raw format 128 bytes long, but the number is just an ieee
252      double, and the last 64 bits are wasted. */
253   floatformat_big,128, 0, 1, 11,  0x3ff,  0x7ff, 12, 52,
254   floatformat_intbit_no,
255   "floatformat_m88110_ext_harris",
256   floatformat_always_valid,
257   NULL
258 };
259 const struct floatformat floatformat_arm_ext_big =
260 {
261   /* Bits 1 to 16 are unused.  */
262   floatformat_big, 96, 0, 17, 15, 0x3fff, 0x7fff, 32, 64,
263   floatformat_intbit_yes,
264   "floatformat_arm_ext_big",
265   floatformat_always_valid,
266   NULL
267 };
268 const struct floatformat floatformat_arm_ext_littlebyte_bigword =
269 {
270   /* Bits 1 to 16 are unused.  */
271   floatformat_littlebyte_bigword, 96, 0, 17, 15, 0x3fff, 0x7fff, 32, 64,
272   floatformat_intbit_yes,
273   "floatformat_arm_ext_littlebyte_bigword",
274   floatformat_always_valid,
275   NULL
276 };
277 const struct floatformat floatformat_ia64_spill_big =
278 {
279   floatformat_big, 128, 0, 1, 17, 65535, 0x1ffff, 18, 64,
280   floatformat_intbit_yes,
281   "floatformat_ia64_spill_big",
282   floatformat_always_valid,
283   NULL
284 };
285 const struct floatformat floatformat_ia64_spill_little =
286 {
287   floatformat_little, 128, 0, 1, 17, 65535, 0x1ffff, 18, 64,
288   floatformat_intbit_yes,
289   "floatformat_ia64_spill_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 const struct floatformat floatformat_bfloat16_big =
399 {
400   floatformat_big, 16, 0, 1, 8, 127, 255, 9, 7,
401   floatformat_intbit_no,
402   "floatformat_bfloat16_big",
403   floatformat_always_valid,
404   NULL
405 };
406 
407 const struct floatformat floatformat_bfloat16_little =
408 {
409   floatformat_little, 16, 0, 1, 8, 127, 255, 9, 7,
410   floatformat_intbit_no,
411   "floatformat_bfloat16_little",
412   floatformat_always_valid,
413   NULL
414 };
415 
416 #ifndef min
417 #define min(a, b) ((a) < (b) ? (a) : (b))
418 #endif
419 
420 /* Return 1 if any bits are explicitly set in the mantissa of UFROM,
421    format FMT, 0 otherwise.  */
422 static int
423 mant_bits_set (const struct floatformat *fmt, const unsigned char *ufrom)
424 {
425   unsigned int mant_bits, mant_off;
426   int mant_bits_left;
427 
428   mant_off = fmt->man_start;
429   mant_bits_left = fmt->man_len;
430   while (mant_bits_left > 0)
431     {
432       mant_bits = min (mant_bits_left, 32);
433 
434       if (get_field (ufrom, fmt->byteorder, fmt->totalsize,
435 		     mant_off, mant_bits) != 0)
436 	return 1;
437 
438       mant_off += mant_bits;
439       mant_bits_left -= mant_bits;
440     }
441   return 0;
442 }
443 
444 /* Extract a field which starts at START and is LEN bits long.  DATA and
445    TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER.  */
446 static unsigned long
447 get_field (const unsigned char *data, enum floatformat_byteorders order,
448            unsigned int total_len, unsigned int start, unsigned int len)
449 {
450   unsigned long result = 0;
451   unsigned int cur_byte;
452   int lo_bit, hi_bit, cur_bitshift = 0;
453   int nextbyte = (order == floatformat_little) ? 1 : -1;
454 
455   /* Start is in big-endian bit order!  Fix that first.  */
456   start = total_len - (start + len);
457 
458   /* Start at the least significant part of the field.  */
459   if (order == floatformat_little)
460     cur_byte = start / FLOATFORMAT_CHAR_BIT;
461   else
462     cur_byte = (total_len - start - 1) / FLOATFORMAT_CHAR_BIT;
463 
464   lo_bit = start % FLOATFORMAT_CHAR_BIT;
465   hi_bit = min (lo_bit + len, FLOATFORMAT_CHAR_BIT);
466 
467   do
468     {
469       unsigned int shifted = *(data + cur_byte) >> lo_bit;
470       unsigned int bits = hi_bit - lo_bit;
471       unsigned int mask = (1 << bits) - 1;
472       result |= (shifted & mask) << cur_bitshift;
473       len -= bits;
474       cur_bitshift += bits;
475       cur_byte += nextbyte;
476       lo_bit = 0;
477       hi_bit = min (len, FLOATFORMAT_CHAR_BIT);
478     }
479   while (len != 0);
480 
481   return result;
482 }
483 
484 /* Convert from FMT to a double.
485    FROM is the address of the extended float.
486    Store the double in *TO.  */
487 
488 void
489 floatformat_to_double (const struct floatformat *fmt,
490                        const void *from, double *to)
491 {
492   const unsigned char *ufrom = (const unsigned char *) from;
493   double dto;
494   long exponent;
495   unsigned long mant;
496   unsigned int mant_bits, mant_off;
497   int mant_bits_left;
498 
499   /* Split values are not handled specially, since the top half has
500      the correctly rounded double value (in the only supported case of
501      split values).  */
502 
503   exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize,
504 			fmt->exp_start, fmt->exp_len);
505 
506   /* If the exponent indicates a NaN, we don't have information to
507      decide what to do.  So we handle it like IEEE, except that we
508      don't try to preserve the type of NaN.  FIXME.  */
509   if ((unsigned long) exponent == fmt->exp_nan)
510     {
511       int nan = mant_bits_set (fmt, ufrom);
512 
513       /* On certain systems (such as GNU/Linux), the use of the
514 	 INFINITY macro below may generate a warning that cannot be
515 	 silenced due to a bug in GCC (PR preprocessor/11931).  The
516 	 preprocessor fails to recognise the __extension__ keyword in
517 	 conjunction with the GNU/C99 extension for hexadecimal
518 	 floating point constants and will issue a warning when
519 	 compiling with -pedantic.  */
520       if (nan)
521 	dto = NAN;
522       else
523 #ifdef __vax__
524 	dto = HUGE_VAL;
525 #else
526 	dto = INFINITY;
527 #endif
528 
529       if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1))
530 	dto = -dto;
531 
532       *to = dto;
533 
534       return;
535     }
536 
537   mant_bits_left = fmt->man_len;
538   mant_off = fmt->man_start;
539   dto = 0.0;
540 
541   /* Build the result algebraically.  Might go infinite, underflow, etc;
542      who cares. */
543 
544   /* For denorms use minimum exponent.  */
545   if (exponent == 0)
546     exponent = 1 - fmt->exp_bias;
547   else
548     {
549       exponent -= fmt->exp_bias;
550 
551       /* If this format uses a hidden bit, explicitly add it in now.
552 	 Otherwise, increment the exponent by one to account for the
553 	 integer bit.  */
554 
555       if (fmt->intbit == floatformat_intbit_no)
556 	dto = ldexp (1.0, exponent);
557       else
558 	exponent++;
559     }
560 
561   while (mant_bits_left > 0)
562     {
563       mant_bits = min (mant_bits_left, 32);
564 
565       mant = get_field (ufrom, fmt->byteorder, fmt->totalsize,
566 			 mant_off, mant_bits);
567 
568       dto += ldexp ((double) mant, exponent - mant_bits);
569       exponent -= mant_bits;
570       mant_off += mant_bits;
571       mant_bits_left -= mant_bits;
572     }
573 
574   /* Negate it if negative.  */
575   if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1))
576     dto = -dto;
577   *to = dto;
578 }
579 
580 static void put_field (unsigned char *, enum floatformat_byteorders,
581                        unsigned int,
582                        unsigned int,
583                        unsigned int,
584                        unsigned long);
585 
586 /* Set a field which starts at START and is LEN bits long.  DATA and
587    TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER.  */
588 static void
589 put_field (unsigned char *data, enum floatformat_byteorders order,
590            unsigned int total_len, unsigned int start, unsigned int len,
591            unsigned long stuff_to_put)
592 {
593   unsigned int cur_byte;
594   int lo_bit, hi_bit;
595   int nextbyte = (order == floatformat_little) ? 1 : -1;
596 
597   /* Start is in big-endian bit order!  Fix that first.  */
598   start = total_len - (start + len);
599 
600   /* Start at the least significant part of the field.  */
601   if (order == floatformat_little)
602     cur_byte = start / FLOATFORMAT_CHAR_BIT;
603   else
604     cur_byte = (total_len - start - 1) / FLOATFORMAT_CHAR_BIT;
605 
606   lo_bit = start % FLOATFORMAT_CHAR_BIT;
607   hi_bit = min (lo_bit + len, FLOATFORMAT_CHAR_BIT);
608 
609   do
610     {
611       unsigned char *byte_ptr = data + cur_byte;
612       unsigned int bits = hi_bit - lo_bit;
613       unsigned int mask = ((1 << bits) - 1) << lo_bit;
614       *byte_ptr = (*byte_ptr & ~mask) | ((stuff_to_put << lo_bit) & mask);
615       stuff_to_put >>= bits;
616       len -= bits;
617       cur_byte += nextbyte;
618       lo_bit = 0;
619       hi_bit = min (len, FLOATFORMAT_CHAR_BIT);
620     }
621   while (len != 0);
622 }
623 
624 /* The converse: convert the double *FROM to an extended float
625    and store where TO points.  Neither FROM nor TO have any alignment
626    restrictions.  */
627 
628 void
629 floatformat_from_double (const struct floatformat *fmt,
630                          const double *from, void *to)
631 {
632   double dfrom;
633   int exponent;
634   double mant;
635   unsigned int mant_bits, mant_off;
636   int mant_bits_left;
637   unsigned char *uto = (unsigned char *) to;
638 
639   dfrom = *from;
640   memset (uto, 0, fmt->totalsize / FLOATFORMAT_CHAR_BIT);
641 
642   /* Split values are not handled specially, since a bottom half of
643      zero is correct for any value representable as double (in the
644      only supported case of split values).  */
645 
646   /* If negative, set the sign bit.  */
647   if (dfrom < 0)
648     {
649       put_field (uto, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1, 1);
650       dfrom = -dfrom;
651     }
652 
653   if (dfrom == 0)
654     {
655       /* 0.0.  */
656       return;
657     }
658 
659   if (dfrom != dfrom)
660     {
661       /* NaN.  */
662       put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
663 		 fmt->exp_len, fmt->exp_nan);
664       /* Be sure it's not infinity, but NaN value is irrelevant.  */
665       put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start,
666 		 32, 1);
667       return;
668     }
669 
670   if (dfrom + dfrom == dfrom)
671     {
672       /* This can only happen for an infinite value (or zero, which we
673 	 already handled above).  */
674       put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
675 		 fmt->exp_len, fmt->exp_nan);
676       return;
677     }
678 
679   mant = frexp (dfrom, &exponent);
680   if (exponent + fmt->exp_bias - 1 > 0)
681     put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
682 	       fmt->exp_len, exponent + fmt->exp_bias - 1);
683   else
684     {
685       /* Handle a denormalized number.  FIXME: What should we do for
686 	 non-IEEE formats?  */
687       put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
688 		 fmt->exp_len, 0);
689       mant = ldexp (mant, exponent + fmt->exp_bias - 1);
690     }
691 
692   mant_bits_left = fmt->man_len;
693   mant_off = fmt->man_start;
694   while (mant_bits_left > 0)
695     {
696       unsigned long mant_long;
697       mant_bits = mant_bits_left < 32 ? mant_bits_left : 32;
698 
699       mant *= 4294967296.0;
700       mant_long = (unsigned long)mant;
701       mant -= mant_long;
702 
703       /* If the integer bit is implicit, and we are not creating a
704 	 denormalized number, then we need to discard it.  */
705       if ((unsigned int) mant_bits_left == fmt->man_len
706 	  && fmt->intbit == floatformat_intbit_no
707 	  && exponent + fmt->exp_bias - 1 > 0)
708 	{
709 	  mant_long &= 0x7fffffff;
710 	  mant_bits -= 1;
711 	}
712       else if (mant_bits < 32)
713 	{
714 	  /* The bits we want are in the most significant MANT_BITS bits of
715 	     mant_long.  Move them to the least significant.  */
716 	  mant_long >>= 32 - mant_bits;
717 	}
718 
719       put_field (uto, fmt->byteorder, fmt->totalsize,
720 		 mant_off, mant_bits, mant_long);
721       mant_off += mant_bits;
722       mant_bits_left -= mant_bits;
723     }
724 }
725 
726 /* Return non-zero iff the data at FROM is a valid number in format FMT.  */
727 
728 int
729 floatformat_is_valid (const struct floatformat *fmt, const void *from)
730 {
731   return fmt->is_valid (fmt, from);
732 }
733 
734 
735 #ifdef IEEE_DEBUG
736 
737 #include <stdio.h>
738 
739 /* This is to be run on a host which uses IEEE floating point.  */
740 
741 void
742 ieee_test (double n)
743 {
744   double result;
745 
746   floatformat_to_double (&floatformat_ieee_double_little, &n, &result);
747   if ((n != result && (! isnan (n) || ! isnan (result)))
748       || (n < 0 && result >= 0)
749       || (n >= 0 && result < 0))
750     printf ("Differ(to): %.20g -> %.20g\n", n, result);
751 
752   floatformat_from_double (&floatformat_ieee_double_little, &n, &result);
753   if ((n != result && (! isnan (n) || ! isnan (result)))
754       || (n < 0 && result >= 0)
755       || (n >= 0 && result < 0))
756     printf ("Differ(from): %.20g -> %.20g\n", n, result);
757 
758 #if 0
759   {
760     char exten[16];
761 
762     floatformat_from_double (&floatformat_m68881_ext, &n, exten);
763     floatformat_to_double (&floatformat_m68881_ext, exten, &result);
764     if (n != result)
765       printf ("Differ(to+from): %.20g -> %.20g\n", n, result);
766   }
767 #endif
768 
769 #if IEEE_DEBUG > 1
770   /* This is to be run on a host which uses 68881 format.  */
771   {
772     long double ex = *(long double *)exten;
773     if (ex != n)
774       printf ("Differ(from vs. extended): %.20g\n", n);
775   }
776 #endif
777 }
778 
779 int
780 main (void)
781 {
782   ieee_test (0.0);
783   ieee_test (0.5);
784   ieee_test (1.1);
785   ieee_test (256.0);
786   ieee_test (0.12345);
787   ieee_test (234235.78907234);
788   ieee_test (-512.0);
789   ieee_test (-0.004321);
790   ieee_test (1.2E-70);
791   ieee_test (1.2E-316);
792   ieee_test (4.9406564584124654E-324);
793   ieee_test (- 4.9406564584124654E-324);
794   ieee_test (- 0.0);
795   ieee_test (- INFINITY);
796   ieee_test (- NAN);
797   ieee_test (INFINITY);
798   ieee_test (NAN);
799   return 0;
800 }
801 #endif
802