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