Home | History | Annotate | Line # | Download | only in libiberty
floatformat.c revision 1.1.1.9
      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,
    582                        unsigned int,
    583                        unsigned int,
    584                        unsigned int,
    585                        unsigned long);
    586 
    587 /* Set a field which starts at START and is LEN bits long.  DATA and
    588    TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER.  */
    589 static void
    590 put_field (unsigned char *data, enum floatformat_byteorders order,
    591            unsigned int total_len, unsigned int start, unsigned int len,
    592            unsigned long stuff_to_put)
    593 {
    594   unsigned int cur_byte;
    595   int lo_bit, hi_bit;
    596   int nextbyte = (order == floatformat_little) ? 1 : -1;
    597 
    598   /* Start is in big-endian bit order!  Fix that first.  */
    599   start = total_len - (start + len);
    600 
    601   /* Start at the least significant part of the field.  */
    602   if (order == floatformat_little)
    603     cur_byte = start / FLOATFORMAT_CHAR_BIT;
    604   else
    605     cur_byte = (total_len - start - 1) / FLOATFORMAT_CHAR_BIT;
    606 
    607   lo_bit = start % FLOATFORMAT_CHAR_BIT;
    608   hi_bit = min (lo_bit + len, FLOATFORMAT_CHAR_BIT);
    609 
    610   do
    611     {
    612       unsigned char *byte_ptr = data + cur_byte;
    613       unsigned int bits = hi_bit - lo_bit;
    614       unsigned int mask = ((1 << bits) - 1) << lo_bit;
    615       *byte_ptr = (*byte_ptr & ~mask) | ((stuff_to_put << lo_bit) & mask);
    616       stuff_to_put >>= bits;
    617       len -= bits;
    618       cur_byte += nextbyte;
    619       lo_bit = 0;
    620       hi_bit = min (len, FLOATFORMAT_CHAR_BIT);
    621     }
    622   while (len != 0);
    623 }
    624 
    625 /* The converse: convert the double *FROM to an extended float
    626    and store where TO points.  Neither FROM nor TO have any alignment
    627    restrictions.  */
    628 
    629 void
    630 floatformat_from_double (const struct floatformat *fmt,
    631                          const double *from, void *to)
    632 {
    633   double dfrom;
    634   int exponent;
    635   double mant;
    636   unsigned int mant_bits, mant_off;
    637   int mant_bits_left;
    638   unsigned char *uto = (unsigned char *) to;
    639 
    640   dfrom = *from;
    641   memset (uto, 0, fmt->totalsize / FLOATFORMAT_CHAR_BIT);
    642 
    643   /* Split values are not handled specially, since a bottom half of
    644      zero is correct for any value representable as double (in the
    645      only supported case of split values).  */
    646 
    647   /* If negative, set the sign bit.  */
    648   if (dfrom < 0)
    649     {
    650       put_field (uto, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1, 1);
    651       dfrom = -dfrom;
    652     }
    653 
    654   if (dfrom == 0)
    655     {
    656       /* 0.0.  */
    657       return;
    658     }
    659 
    660   if (dfrom != dfrom)
    661     {
    662       /* NaN.  */
    663       put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
    664 		 fmt->exp_len, fmt->exp_nan);
    665       /* Be sure it's not infinity, but NaN value is irrelevant.  */
    666       put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start,
    667 		 32, 1);
    668       return;
    669     }
    670 
    671   if (dfrom + dfrom == dfrom)
    672     {
    673       /* This can only happen for an infinite value (or zero, which we
    674 	 already handled above).  */
    675       put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
    676 		 fmt->exp_len, fmt->exp_nan);
    677       return;
    678     }
    679 
    680   mant = frexp (dfrom, &exponent);
    681   if (exponent + fmt->exp_bias - 1 > 0)
    682     put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
    683 	       fmt->exp_len, exponent + fmt->exp_bias - 1);
    684   else
    685     {
    686       /* Handle a denormalized number.  FIXME: What should we do for
    687 	 non-IEEE formats?  */
    688       put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
    689 		 fmt->exp_len, 0);
    690       mant = ldexp (mant, exponent + fmt->exp_bias - 1);
    691     }
    692 
    693   mant_bits_left = fmt->man_len;
    694   mant_off = fmt->man_start;
    695   while (mant_bits_left > 0)
    696     {
    697       unsigned long mant_long;
    698       mant_bits = mant_bits_left < 32 ? mant_bits_left : 32;
    699 
    700       mant *= 4294967296.0;
    701       mant_long = (unsigned long)mant;
    702       mant -= mant_long;
    703 
    704       /* If the integer bit is implicit, and we are not creating a
    705 	 denormalized number, then we need to discard it.  */
    706       if ((unsigned int) mant_bits_left == fmt->man_len
    707 	  && fmt->intbit == floatformat_intbit_no
    708 	  && exponent + fmt->exp_bias - 1 > 0)
    709 	{
    710 	  mant_long &= 0x7fffffff;
    711 	  mant_bits -= 1;
    712 	}
    713       else if (mant_bits < 32)
    714 	{
    715 	  /* The bits we want are in the most significant MANT_BITS bits of
    716 	     mant_long.  Move them to the least significant.  */
    717 	  mant_long >>= 32 - mant_bits;
    718 	}
    719 
    720       put_field (uto, fmt->byteorder, fmt->totalsize,
    721 		 mant_off, mant_bits, mant_long);
    722       mant_off += mant_bits;
    723       mant_bits_left -= mant_bits;
    724     }
    725 }
    726 
    727 /* Return non-zero iff the data at FROM is a valid number in format FMT.  */
    728 
    729 int
    730 floatformat_is_valid (const struct floatformat *fmt, const void *from)
    731 {
    732   return fmt->is_valid (fmt, from);
    733 }
    734 
    735 
    736 #ifdef IEEE_DEBUG
    737 
    738 #include <stdio.h>
    739 
    740 /* This is to be run on a host which uses IEEE floating point.  */
    741 
    742 void
    743 ieee_test (double n)
    744 {
    745   double result;
    746 
    747   floatformat_to_double (&floatformat_ieee_double_little, &n, &result);
    748   if ((n != result && (! isnan (n) || ! isnan (result)))
    749       || (n < 0 && result >= 0)
    750       || (n >= 0 && result < 0))
    751     printf ("Differ(to): %.20g -> %.20g\n", n, result);
    752 
    753   floatformat_from_double (&floatformat_ieee_double_little, &n, &result);
    754   if ((n != result && (! isnan (n) || ! isnan (result)))
    755       || (n < 0 && result >= 0)
    756       || (n >= 0 && result < 0))
    757     printf ("Differ(from): %.20g -> %.20g\n", n, result);
    758 
    759 #if 0
    760   {
    761     char exten[16];
    762 
    763     floatformat_from_double (&floatformat_m68881_ext, &n, exten);
    764     floatformat_to_double (&floatformat_m68881_ext, exten, &result);
    765     if (n != result)
    766       printf ("Differ(to+from): %.20g -> %.20g\n", n, result);
    767   }
    768 #endif
    769 
    770 #if IEEE_DEBUG > 1
    771   /* This is to be run on a host which uses 68881 format.  */
    772   {
    773     long double ex = *(long double *)exten;
    774     if (ex != n)
    775       printf ("Differ(from vs. extended): %.20g\n", n);
    776   }
    777 #endif
    778 }
    779 
    780 int
    781 main (void)
    782 {
    783   ieee_test (0.0);
    784   ieee_test (0.5);
    785   ieee_test (1.1);
    786   ieee_test (256.0);
    787   ieee_test (0.12345);
    788   ieee_test (234235.78907234);
    789   ieee_test (-512.0);
    790   ieee_test (-0.004321);
    791   ieee_test (1.2E-70);
    792   ieee_test (1.2E-316);
    793   ieee_test (4.9406564584124654E-324);
    794   ieee_test (- 4.9406564584124654E-324);
    795   ieee_test (- 0.0);
    796   ieee_test (- INFINITY);
    797   ieee_test (- NAN);
    798   ieee_test (INFINITY);
    799   ieee_test (NAN);
    800   return 0;
    801 }
    802 #endif
    803