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