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