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