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