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