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