1/* IEEE floating point support routines, for GDB, the GNU Debugger.
2   Copyright (C) 1991-2022 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#ifdef __lint__
57static 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
65static int mant_bits_set (const struct floatformat *, const unsigned char *);
66static unsigned long get_field (const unsigned char *,
67                                enum floatformat_byteorders,
68                                unsigned int,
69                                unsigned int,
70                                unsigned int);
71static int floatformat_always_valid (const struct floatformat *fmt,
72                                     const void *from);
73
74static int
75floatformat_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.  */
87const 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};
95const 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};
103const 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};
111const 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};
119const 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};
127const 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};
135const 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};
143const 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
155const 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
166const 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};
174const 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};
182const 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
191static int floatformat_i387_ext_is_valid (const struct floatformat *fmt,
192					  const void *from);
193
194static int
195floatformat_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
215const 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};
223const 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};
232const 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};
241const 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};
249const 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};
259const 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};
268const 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};
277const 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};
285const 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
294static int
295floatformat_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
380const 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
389const 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
398const 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
407const 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.  */
422static int
423mant_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.  */
446static unsigned long
447get_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
488void
489floatformat_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
580static 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.  */
588static void
589put_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
628void
629floatformat_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
728int
729floatformat_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
741void
742ieee_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
779int
780main (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