floatformat.c revision 218822
118334Speter/* IEEE floating point support routines, for GDB, the GNU Debugger.
2169689Skan   Copyright 1991, 1994, 1999, 2000, 2003, 2005, 2006
3132718Skan   Free Software Foundation, Inc.
418334Speter
590075SobrienThis file is part of GDB.
618334Speter
790075SobrienThis program is free software; you can redistribute it and/or modify
890075Sobrienit under the terms of the GNU General Public License as published by
990075Sobrienthe Free Software Foundation; either version 2 of the License, or
1090075Sobrien(at your option) any later version.
1118334Speter
1290075SobrienThis program is distributed in the hope that it will be useful,
1390075Sobrienbut WITHOUT ANY WARRANTY; without even the implied warranty of
1490075SobrienMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1590075SobrienGNU General Public License for more details.
1618334Speter
1718334SpeterYou should have received a copy of the GNU General Public License
1890075Sobrienalong with this program; if not, write to the Free Software
19169689SkanFoundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
20169689Skan
2118334Speter/* This is needed to pick up the NAN macro on some systems.  */
2218334Speter#define _GNU_SOURCE
2318334Speter
2418334Speter#ifdef HAVE_CONFIG_H
2518334Speter#include "config.h"
2618334Speter#endif
2718334Speter
2818334Speter#include <math.h>
2990075Sobrien
30132718Skan#ifdef HAVE_STRING_H
31132718Skan#include <string.h>
3218334Speter#endif
3318334Speter
3418334Speter/* On some platforms, <float.h> provides DBL_QNAN.  */
35117395Skan#ifdef STDC_HEADERS
36169689Skan#include <float.h>
37169689Skan#endif
3850397Sobrien
39169689Skan#include "ansidecl.h"
4018334Speter#include "libiberty.h"
4118334Speter#include "floatformat.h"
4218334Speter
4318334Speter#ifndef INFINITY
4418334Speter#ifdef HUGE_VAL
4518334Speter#define INFINITY HUGE_VAL
4618334Speter#else
4718334Speter#define INFINITY (1.0 / 0.0)
4818334Speter#endif
4918334Speter#endif
5018334Speter
5118334Speter#ifndef NAN
52117395Skan#ifdef DBL_QNAN
53117395Skan#define NAN DBL_QNAN
5418334Speter#else
5518334Speter#define NAN (0.0 / 0.0)
5618334Speter#endif
5718334Speter#endif
5818334Speter
5918334Speterstatic unsigned long get_field (const unsigned char *,
6018334Speter                                enum floatformat_byteorders,
6118334Speter                                unsigned int,
6218334Speter                                unsigned int,
6318334Speter                                unsigned int);
6418334Speterstatic int floatformat_always_valid (const struct floatformat *fmt,
6518334Speter                                     const void *from);
6618334Speter
6718334Speterstatic int
6818334Speterfloatformat_always_valid (const struct floatformat *fmt ATTRIBUTE_UNUSED,
69132718Skan                          const void *from ATTRIBUTE_UNUSED)
7018334Speter{
7190075Sobrien  return 1;
7290075Sobrien}
73169689Skan
7418334Speter/* The odds that CHAR_BIT will be anything but 8 are low enough that I'm not
75169689Skan   going to bother with trying to muck around with whether it is defined in
76169689Skan   a system header, what we do if not, etc.  */
77169689Skan#define FLOATFORMAT_CHAR_BIT 8
78169689Skan
79169689Skan/* floatformats for IEEE single and double, big and little endian.  */
80169689Skanconst struct floatformat floatformat_ieee_single_big =
81169689Skan{
82169689Skan  floatformat_big, 32, 0, 1, 8, 127, 255, 9, 23,
83260011Spfg  floatformat_intbit_no,
84169689Skan  "floatformat_ieee_single_big",
85169689Skan  floatformat_always_valid
86169689Skan};
87169689Skanconst struct floatformat floatformat_ieee_single_little =
8818334Speter{
8990075Sobrien  floatformat_little, 32, 0, 1, 8, 127, 255, 9, 23,
9018334Speter  floatformat_intbit_no,
91169689Skan  "floatformat_ieee_single_little",
9218334Speter  floatformat_always_valid
9318334Speter};
9418334Speterconst struct floatformat floatformat_ieee_double_big =
9518334Speter{
9618334Speter  floatformat_big, 64, 0, 1, 11, 1023, 2047, 12, 52,
9718334Speter  floatformat_intbit_no,
9818334Speter  "floatformat_ieee_double_big",
9918334Speter  floatformat_always_valid
100169689Skan};
10118334Speterconst struct floatformat floatformat_ieee_double_little =
10218334Speter{
10390075Sobrien  floatformat_little, 64, 0, 1, 11, 1023, 2047, 12, 52,
104169689Skan  floatformat_intbit_no,
10590075Sobrien  "floatformat_ieee_double_little",
10618334Speter  floatformat_always_valid
10718334Speter};
10818334Speter
10918334Speter/* floatformat for IEEE double, little endian byte order, with big endian word
11018334Speter   ordering, as on the ARM.  */
11190075Sobrien
11290075Sobrienconst struct floatformat floatformat_ieee_double_littlebyte_bigword =
113169689Skan{
114169689Skan  floatformat_littlebyte_bigword, 64, 0, 1, 11, 1023, 2047, 12, 52,
115169689Skan  floatformat_intbit_no,
11618334Speter  "floatformat_ieee_double_littlebyte_bigword",
11718334Speter  floatformat_always_valid
11818334Speter};
11918334Speter
120/* floatformat for VAX.  Not quite IEEE, but close enough.  */
121
122const struct floatformat floatformat_vax_f =
123{
124  floatformat_vax, 32, 0, 1, 8, 129, 0, 9, 23,
125  floatformat_intbit_no,
126  "floatformat_vax_f",
127  floatformat_always_valid
128};
129const struct floatformat floatformat_vax_d =
130{
131  floatformat_vax, 64, 0, 1, 8, 129, 0, 9, 55,
132  floatformat_intbit_no,
133  "floatformat_vax_d",
134  floatformat_always_valid
135};
136const struct floatformat floatformat_vax_g =
137{
138  floatformat_vax, 64, 0, 1, 11, 1025, 0, 12, 52,
139  floatformat_intbit_no,
140  "floatformat_vax_g",
141  floatformat_always_valid
142};
143
144static int floatformat_i387_ext_is_valid (const struct floatformat *fmt,
145					  const void *from);
146
147static int
148floatformat_i387_ext_is_valid (const struct floatformat *fmt, const void *from)
149{
150  /* In the i387 double-extended format, if the exponent is all ones,
151     then the integer bit must be set.  If the exponent is neither 0
152     nor ~0, the intbit must also be set.  Only if the exponent is
153     zero can it be zero, and then it must be zero.  */
154  unsigned long exponent, int_bit;
155  const unsigned char *ufrom = (const unsigned char *) from;
156
157  exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize,
158			fmt->exp_start, fmt->exp_len);
159  int_bit = get_field (ufrom, fmt->byteorder, fmt->totalsize,
160		       fmt->man_start, 1);
161
162  if ((exponent == 0) != (int_bit == 0))
163    return 0;
164  else
165    return 1;
166}
167
168const struct floatformat floatformat_i387_ext =
169{
170  floatformat_little, 80, 0, 1, 15, 0x3fff, 0x7fff, 16, 64,
171  floatformat_intbit_yes,
172  "floatformat_i387_ext",
173  floatformat_i387_ext_is_valid
174};
175const struct floatformat floatformat_m68881_ext =
176{
177  /* Note that the bits from 16 to 31 are unused.  */
178  floatformat_big, 96, 0, 1, 15, 0x3fff, 0x7fff, 32, 64,
179  floatformat_intbit_yes,
180  "floatformat_m68881_ext",
181  floatformat_always_valid
182};
183const struct floatformat floatformat_i960_ext =
184{
185  /* Note that the bits from 0 to 15 are unused.  */
186  floatformat_little, 96, 16, 17, 15, 0x3fff, 0x7fff, 32, 64,
187  floatformat_intbit_yes,
188  "floatformat_i960_ext",
189  floatformat_always_valid
190};
191const struct floatformat floatformat_m88110_ext =
192{
193  floatformat_big, 80, 0, 1, 15, 0x3fff, 0x7fff, 16, 64,
194  floatformat_intbit_yes,
195  "floatformat_m88110_ext",
196  floatformat_always_valid
197};
198const struct floatformat floatformat_m88110_harris_ext =
199{
200  /* Harris uses raw format 128 bytes long, but the number is just an ieee
201     double, and the last 64 bits are wasted. */
202  floatformat_big,128, 0, 1, 11,  0x3ff,  0x7ff, 12, 52,
203  floatformat_intbit_no,
204  "floatformat_m88110_ext_harris",
205  floatformat_always_valid
206};
207const struct floatformat floatformat_arm_ext_big =
208{
209  /* Bits 1 to 16 are unused.  */
210  floatformat_big, 96, 0, 17, 15, 0x3fff, 0x7fff, 32, 64,
211  floatformat_intbit_yes,
212  "floatformat_arm_ext_big",
213  floatformat_always_valid
214};
215const struct floatformat floatformat_arm_ext_littlebyte_bigword =
216{
217  /* Bits 1 to 16 are unused.  */
218  floatformat_littlebyte_bigword, 96, 0, 17, 15, 0x3fff, 0x7fff, 32, 64,
219  floatformat_intbit_yes,
220  "floatformat_arm_ext_littlebyte_bigword",
221  floatformat_always_valid
222};
223const struct floatformat floatformat_ia64_spill_big =
224{
225  floatformat_big, 128, 0, 1, 17, 65535, 0x1ffff, 18, 64,
226  floatformat_intbit_yes,
227  "floatformat_ia64_spill_big",
228  floatformat_always_valid
229};
230const struct floatformat floatformat_ia64_spill_little =
231{
232  floatformat_little, 128, 0, 1, 17, 65535, 0x1ffff, 18, 64,
233  floatformat_intbit_yes,
234  "floatformat_ia64_spill_little",
235  floatformat_always_valid
236};
237const struct floatformat floatformat_ia64_quad_big =
238{
239  floatformat_big, 128, 0, 1, 15, 16383, 0x7fff, 16, 112,
240  floatformat_intbit_no,
241  "floatformat_ia64_quad_big",
242  floatformat_always_valid
243};
244const struct floatformat floatformat_ia64_quad_little =
245{
246  floatformat_little, 128, 0, 1, 15, 16383, 0x7fff, 16, 112,
247  floatformat_intbit_no,
248  "floatformat_ia64_quad_little",
249  floatformat_always_valid
250};
251
252
253#ifndef min
254#define min(a, b) ((a) < (b) ? (a) : (b))
255#endif
256
257/* Extract a field which starts at START and is LEN bits long.  DATA and
258   TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER.  */
259static unsigned long
260get_field (const unsigned char *data, enum floatformat_byteorders order,
261           unsigned int total_len, unsigned int start, unsigned int len)
262{
263  unsigned long result = 0;
264  unsigned int cur_byte;
265  int lo_bit, hi_bit, cur_bitshift = 0;
266  int nextbyte = (order == floatformat_little) ? 1 : -1;
267
268  /* Start is in big-endian bit order!  Fix that first.  */
269  start = total_len - (start + len);
270
271  /* Start at the least significant part of the field.  */
272  if (order == floatformat_little)
273    cur_byte = start / FLOATFORMAT_CHAR_BIT;
274  else
275    cur_byte = (total_len - start - 1) / FLOATFORMAT_CHAR_BIT;
276
277  lo_bit = start % FLOATFORMAT_CHAR_BIT;
278  hi_bit = min (lo_bit + len, FLOATFORMAT_CHAR_BIT);
279
280  do
281    {
282      unsigned int shifted = *(data + cur_byte) >> lo_bit;
283      unsigned int bits = hi_bit - lo_bit;
284      unsigned int mask = (1 << bits) - 1;
285      result |= (shifted & mask) << cur_bitshift;
286      len -= bits;
287      cur_bitshift += bits;
288      cur_byte += nextbyte;
289      lo_bit = 0;
290      hi_bit = min (len, FLOATFORMAT_CHAR_BIT);
291    }
292  while (len != 0);
293
294  return result;
295}
296
297/* Convert from FMT to a double.
298   FROM is the address of the extended float.
299   Store the double in *TO.  */
300
301void
302floatformat_to_double (const struct floatformat *fmt,
303                       const void *from, double *to)
304{
305  const unsigned char *ufrom = (const unsigned char *) from;
306  double dto;
307  long exponent;
308  unsigned long mant;
309  unsigned int mant_bits, mant_off;
310  int mant_bits_left;
311  int special_exponent;		/* It's a NaN, denorm or zero */
312
313  exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize,
314			fmt->exp_start, fmt->exp_len);
315
316  /* If the exponent indicates a NaN, we don't have information to
317     decide what to do.  So we handle it like IEEE, except that we
318     don't try to preserve the type of NaN.  FIXME.  */
319  if ((unsigned long) exponent == fmt->exp_nan)
320    {
321      int nan;
322
323      mant_off = fmt->man_start;
324      mant_bits_left = fmt->man_len;
325      nan = 0;
326      while (mant_bits_left > 0)
327	{
328	  mant_bits = min (mant_bits_left, 32);
329
330	  if (get_field (ufrom, fmt->byteorder, fmt->totalsize,
331			 mant_off, mant_bits) != 0)
332	    {
333	      /* This is a NaN.  */
334	      nan = 1;
335	      break;
336	    }
337
338	  mant_off += mant_bits;
339	  mant_bits_left -= mant_bits;
340	}
341
342      /* On certain systems (such as GNU/Linux), the use of the
343	 INFINITY macro below may generate a warning that can not be
344	 silenced due to a bug in GCC (PR preprocessor/11931).  The
345	 preprocessor fails to recognise the __extension__ keyword in
346	 conjunction with the GNU/C99 extension for hexadecimal
347	 floating point constants and will issue a warning when
348	 compiling with -pedantic.  */
349      if (nan)
350	dto = NAN;
351      else
352	dto = INFINITY;
353
354      if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1))
355	dto = -dto;
356
357      *to = dto;
358
359      return;
360    }
361
362  mant_bits_left = fmt->man_len;
363  mant_off = fmt->man_start;
364  dto = 0.0;
365
366  special_exponent = exponent == 0 || (unsigned long) exponent == fmt->exp_nan;
367
368  /* Don't bias zero's, denorms or NaNs.  */
369  if (!special_exponent)
370    exponent -= fmt->exp_bias;
371
372  /* Build the result algebraically.  Might go infinite, underflow, etc;
373     who cares. */
374
375  /* If this format uses a hidden bit, explicitly add it in now.  Otherwise,
376     increment the exponent by one to account for the integer bit.  */
377
378  if (!special_exponent)
379    {
380      if (fmt->intbit == floatformat_intbit_no)
381	dto = ldexp (1.0, exponent);
382      else
383	exponent++;
384    }
385
386  while (mant_bits_left > 0)
387    {
388      mant_bits = min (mant_bits_left, 32);
389
390      mant = get_field (ufrom, fmt->byteorder, fmt->totalsize,
391			 mant_off, mant_bits);
392
393      /* Handle denormalized numbers.  FIXME: What should we do for
394	 non-IEEE formats?  */
395      if (special_exponent && exponent == 0 && mant != 0)
396	dto += ldexp ((double)mant,
397		      (- fmt->exp_bias
398		       - mant_bits
399		       - (mant_off - fmt->man_start)
400		       + 1));
401      else
402	dto += ldexp ((double)mant, exponent - mant_bits);
403      if (exponent != 0)
404	exponent -= mant_bits;
405      mant_off += mant_bits;
406      mant_bits_left -= mant_bits;
407    }
408
409  /* Negate it if negative.  */
410  if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1))
411    dto = -dto;
412  *to = dto;
413}
414
415static void put_field (unsigned char *, enum floatformat_byteorders,
416                       unsigned int,
417                       unsigned int,
418                       unsigned int,
419                       unsigned long);
420
421/* Set a field which starts at START and is LEN bits long.  DATA and
422   TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER.  */
423static void
424put_field (unsigned char *data, enum floatformat_byteorders order,
425           unsigned int total_len, unsigned int start, unsigned int len,
426           unsigned long stuff_to_put)
427{
428  unsigned int cur_byte;
429  int lo_bit, hi_bit;
430  int nextbyte = (order == floatformat_little) ? 1 : -1;
431
432  /* Start is in big-endian bit order!  Fix that first.  */
433  start = total_len - (start + len);
434
435  /* Start at the least significant part of the field.  */
436  if (order == floatformat_little)
437    cur_byte = start / FLOATFORMAT_CHAR_BIT;
438  else
439    cur_byte = (total_len - start - 1) / FLOATFORMAT_CHAR_BIT;
440
441  lo_bit = start % FLOATFORMAT_CHAR_BIT;
442  hi_bit = min (lo_bit + len, FLOATFORMAT_CHAR_BIT);
443
444  do
445    {
446      unsigned char *byte_ptr = data + cur_byte;
447      unsigned int bits = hi_bit - lo_bit;
448      unsigned int mask = ((1 << bits) - 1) << lo_bit;
449      *byte_ptr = (*byte_ptr & ~mask) | ((stuff_to_put << lo_bit) & mask);
450      stuff_to_put >>= bits;
451      len -= bits;
452      cur_byte += nextbyte;
453      lo_bit = 0;
454      hi_bit = min (len, FLOATFORMAT_CHAR_BIT);
455    }
456  while (len != 0);
457}
458
459/* The converse: convert the double *FROM to an extended float
460   and store where TO points.  Neither FROM nor TO have any alignment
461   restrictions.  */
462
463void
464floatformat_from_double (const struct floatformat *fmt,
465                         const double *from, void *to)
466{
467  double dfrom;
468  int exponent;
469  double mant;
470  unsigned int mant_bits, mant_off;
471  int mant_bits_left;
472  unsigned char *uto = (unsigned char *) to;
473
474  dfrom = *from;
475  memset (uto, 0, fmt->totalsize / FLOATFORMAT_CHAR_BIT);
476
477  /* If negative, set the sign bit.  */
478  if (dfrom < 0)
479    {
480      put_field (uto, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1, 1);
481      dfrom = -dfrom;
482    }
483
484  if (dfrom == 0)
485    {
486      /* 0.0.  */
487      return;
488    }
489
490  if (dfrom != dfrom)
491    {
492      /* NaN.  */
493      put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
494		 fmt->exp_len, fmt->exp_nan);
495      /* Be sure it's not infinity, but NaN value is irrelevant.  */
496      put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start,
497		 32, 1);
498      return;
499    }
500
501  if (dfrom + dfrom == dfrom)
502    {
503      /* This can only happen for an infinite value (or zero, which we
504	 already handled above).  */
505      put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
506		 fmt->exp_len, fmt->exp_nan);
507      return;
508    }
509
510  mant = frexp (dfrom, &exponent);
511  if (exponent + fmt->exp_bias - 1 > 0)
512    put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
513	       fmt->exp_len, exponent + fmt->exp_bias - 1);
514  else
515    {
516      /* Handle a denormalized number.  FIXME: What should we do for
517	 non-IEEE formats?  */
518      put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
519		 fmt->exp_len, 0);
520      mant = ldexp (mant, exponent + fmt->exp_bias - 1);
521    }
522
523  mant_bits_left = fmt->man_len;
524  mant_off = fmt->man_start;
525  while (mant_bits_left > 0)
526    {
527      unsigned long mant_long;
528      mant_bits = mant_bits_left < 32 ? mant_bits_left : 32;
529
530      mant *= 4294967296.0;
531      mant_long = (unsigned long)mant;
532      mant -= mant_long;
533
534      /* If the integer bit is implicit, and we are not creating a
535	 denormalized number, then we need to discard it.  */
536      if ((unsigned int) mant_bits_left == fmt->man_len
537	  && fmt->intbit == floatformat_intbit_no
538	  && exponent + fmt->exp_bias - 1 > 0)
539	{
540	  mant_long &= 0x7fffffff;
541	  mant_bits -= 1;
542	}
543      else if (mant_bits < 32)
544	{
545	  /* The bits we want are in the most significant MANT_BITS bits of
546	     mant_long.  Move them to the least significant.  */
547	  mant_long >>= 32 - mant_bits;
548	}
549
550      put_field (uto, fmt->byteorder, fmt->totalsize,
551		 mant_off, mant_bits, mant_long);
552      mant_off += mant_bits;
553      mant_bits_left -= mant_bits;
554    }
555}
556
557/* Return non-zero iff the data at FROM is a valid number in format FMT.  */
558
559int
560floatformat_is_valid (const struct floatformat *fmt, const void *from)
561{
562  return fmt->is_valid (fmt, from);
563}
564
565
566#ifdef IEEE_DEBUG
567
568#include <stdio.h>
569
570/* This is to be run on a host which uses IEEE floating point.  */
571
572void
573ieee_test (double n)
574{
575  double result;
576
577  floatformat_to_double (&floatformat_ieee_double_little, &n, &result);
578  if ((n != result && (! isnan (n) || ! isnan (result)))
579      || (n < 0 && result >= 0)
580      || (n >= 0 && result < 0))
581    printf ("Differ(to): %.20g -> %.20g\n", n, result);
582
583  floatformat_from_double (&floatformat_ieee_double_little, &n, &result);
584  if ((n != result && (! isnan (n) || ! isnan (result)))
585      || (n < 0 && result >= 0)
586      || (n >= 0 && result < 0))
587    printf ("Differ(from): %.20g -> %.20g\n", n, result);
588
589#if 0
590  {
591    char exten[16];
592
593    floatformat_from_double (&floatformat_m68881_ext, &n, exten);
594    floatformat_to_double (&floatformat_m68881_ext, exten, &result);
595    if (n != result)
596      printf ("Differ(to+from): %.20g -> %.20g\n", n, result);
597  }
598#endif
599
600#if IEEE_DEBUG > 1
601  /* This is to be run on a host which uses 68881 format.  */
602  {
603    long double ex = *(long double *)exten;
604    if (ex != n)
605      printf ("Differ(from vs. extended): %.20g\n", n);
606  }
607#endif
608}
609
610int
611main (void)
612{
613  ieee_test (0.0);
614  ieee_test (0.5);
615  ieee_test (256.0);
616  ieee_test (0.12345);
617  ieee_test (234235.78907234);
618  ieee_test (-512.0);
619  ieee_test (-0.004321);
620  ieee_test (1.2E-70);
621  ieee_test (1.2E-316);
622  ieee_test (4.9406564584124654E-324);
623  ieee_test (- 4.9406564584124654E-324);
624  ieee_test (- 0.0);
625  ieee_test (- INFINITY);
626  ieee_test (- NAN);
627  ieee_test (INFINITY);
628  ieee_test (NAN);
629  return 0;
630}
631#endif
632