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