Merge from vendor branch OPENSSL:
[dragonfly.git] / contrib / binutils-2.17 / libiberty / floatformat.c
1 /* IEEE floating point support routines, for GDB, the GNU Debugger.
2    Copyright 1991, 1994, 1999, 2000, 2003, 2005, 2006
3    Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
20
21 /* This is needed to pick up the NAN macro on some systems.  */
22 #define _GNU_SOURCE
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include <math.h>
29
30 #ifdef HAVE_STRING_H
31 #include <string.h>
32 #endif
33
34 /* On some platforms, <float.h> provides DBL_QNAN.  */
35 #ifdef STDC_HEADERS
36 #include <float.h>
37 #endif
38
39 #include "ansidecl.h"
40 #include "libiberty.h"
41 #include "floatformat.h"
42
43 #ifndef INFINITY
44 #ifdef HUGE_VAL
45 #define INFINITY HUGE_VAL
46 #else
47 #define INFINITY (1.0 / 0.0)
48 #endif
49 #endif
50
51 #ifndef NAN
52 #ifdef DBL_QNAN
53 #define NAN DBL_QNAN
54 #else
55 #define NAN (0.0 / 0.0)
56 #endif
57 #endif
58
59 static unsigned long get_field (const unsigned char *,
60                                 enum floatformat_byteorders,
61                                 unsigned int,
62                                 unsigned int,
63                                 unsigned int);
64 static int floatformat_always_valid (const struct floatformat *fmt,
65                                      const void *from);
66
67 static int
68 floatformat_always_valid (const struct floatformat *fmt ATTRIBUTE_UNUSED,
69                           const void *from ATTRIBUTE_UNUSED)
70 {
71   return 1;
72 }
73
74 /* The odds that CHAR_BIT will be anything but 8 are low enough that I'm not
75    going to bother with trying to muck around with whether it is defined in
76    a system header, what we do if not, etc.  */
77 #define FLOATFORMAT_CHAR_BIT 8
78
79 /* floatformats for IEEE single and double, big and little endian.  */
80 const struct floatformat floatformat_ieee_single_big =
81 {
82   floatformat_big, 32, 0, 1, 8, 127, 255, 9, 23,
83   floatformat_intbit_no,
84   "floatformat_ieee_single_big",
85   floatformat_always_valid
86 };
87 const struct floatformat floatformat_ieee_single_little =
88 {
89   floatformat_little, 32, 0, 1, 8, 127, 255, 9, 23,
90   floatformat_intbit_no,
91   "floatformat_ieee_single_little",
92   floatformat_always_valid
93 };
94 const struct floatformat floatformat_ieee_double_big =
95 {
96   floatformat_big, 64, 0, 1, 11, 1023, 2047, 12, 52,
97   floatformat_intbit_no,
98   "floatformat_ieee_double_big",
99   floatformat_always_valid
100 };
101 const struct floatformat floatformat_ieee_double_little =
102 {
103   floatformat_little, 64, 0, 1, 11, 1023, 2047, 12, 52,
104   floatformat_intbit_no,
105   "floatformat_ieee_double_little",
106   floatformat_always_valid
107 };
108
109 /* floatformat for IEEE double, little endian byte order, with big endian word
110    ordering, as on the ARM.  */
111
112 const struct floatformat floatformat_ieee_double_littlebyte_bigword =
113 {
114   floatformat_littlebyte_bigword, 64, 0, 1, 11, 1023, 2047, 12, 52,
115   floatformat_intbit_no,
116   "floatformat_ieee_double_littlebyte_bigword",
117   floatformat_always_valid
118 };
119
120 /* floatformat for VAX.  Not quite IEEE, but close enough.  */
121
122 const 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 };
129 const 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 };
136 const 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
144 static int floatformat_i387_ext_is_valid (const struct floatformat *fmt,
145                                           const void *from);
146
147 static int
148 floatformat_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
168 const 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 };
175 const 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 };
183 const 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 };
191 const 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 };
198 const 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 };
207 const 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 };
215 const 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 };
223 const 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 };
230 const 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 };
237 const 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 };
244 const 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 \f
252 /* Extract a field which starts at START and is LEN bits long.  DATA and
253    TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER.  */
254 static unsigned long
255 get_field (const unsigned char *data, enum floatformat_byteorders order,
256            unsigned int total_len, unsigned int start, unsigned int len)
257 {
258   unsigned long result;
259   unsigned int cur_byte;
260   int cur_bitshift;
261
262   /* Start at the least significant part of the field.  */
263   cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT;
264   if (order == floatformat_little)
265     cur_byte = (total_len / FLOATFORMAT_CHAR_BIT) - cur_byte - 1;
266   cur_bitshift =
267     ((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT;
268   result = *(data + cur_byte) >> (-cur_bitshift);
269   cur_bitshift += FLOATFORMAT_CHAR_BIT;
270   if (order == floatformat_little)
271     ++cur_byte;
272   else
273     --cur_byte;
274
275   /* Move towards the most significant part of the field.  */
276   while ((unsigned int) cur_bitshift < len)
277     {
278       if (len - cur_bitshift < FLOATFORMAT_CHAR_BIT)
279         /* This is the last byte; zero out the bits which are not part of
280            this field.  */
281         result |=
282           (*(data + cur_byte) & ((1 << (len - cur_bitshift)) - 1))
283             << cur_bitshift;
284       else
285         result |= *(data + cur_byte) << cur_bitshift;
286       cur_bitshift += FLOATFORMAT_CHAR_BIT;
287       if (order == floatformat_little)
288         ++cur_byte;
289       else
290         --cur_byte;
291     }
292   return result;
293 }
294   
295 #ifndef min
296 #define min(a, b) ((a) < (b) ? (a) : (b))
297 #endif
298
299 /* Convert from FMT to a double.
300    FROM is the address of the extended float.
301    Store the double in *TO.  */
302
303 void
304 floatformat_to_double (const struct floatformat *fmt,
305                        const void *from, double *to)
306 {
307   const unsigned char *ufrom = (const unsigned char *) from;
308   double dto;
309   long exponent;
310   unsigned long mant;
311   unsigned int mant_bits, mant_off;
312   int mant_bits_left;
313   int special_exponent;         /* It's a NaN, denorm or zero */
314
315   exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize,
316                         fmt->exp_start, fmt->exp_len);
317
318   /* If the exponent indicates a NaN, we don't have information to
319      decide what to do.  So we handle it like IEEE, except that we
320      don't try to preserve the type of NaN.  FIXME.  */
321   if ((unsigned long) exponent == fmt->exp_nan)
322     {
323       int nan;
324
325       mant_off = fmt->man_start;
326       mant_bits_left = fmt->man_len;
327       nan = 0;
328       while (mant_bits_left > 0)
329         {
330           mant_bits = min (mant_bits_left, 32);
331
332           if (get_field (ufrom, fmt->byteorder, fmt->totalsize,
333                          mant_off, mant_bits) != 0)
334             {
335               /* This is a NaN.  */
336               nan = 1;
337               break;
338             }
339
340           mant_off += mant_bits;
341           mant_bits_left -= mant_bits;
342         }
343
344       /* On certain systems (such as GNU/Linux), the use of the
345          INFINITY macro below may generate a warning that can not be
346          silenced due to a bug in GCC (PR preprocessor/11931).  The
347          preprocessor fails to recognise the __extension__ keyword in
348          conjunction with the GNU/C99 extension for hexadecimal
349          floating point constants and will issue a warning when
350          compiling with -pedantic.  */
351       if (nan)
352         dto = NAN;
353       else
354         dto = INFINITY;
355
356       if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1))
357         dto = -dto;
358
359       *to = dto;
360
361       return;
362     }
363
364   mant_bits_left = fmt->man_len;
365   mant_off = fmt->man_start;
366   dto = 0.0;
367
368   special_exponent = exponent == 0 || (unsigned long) exponent == fmt->exp_nan;
369
370   /* Don't bias zero's, denorms or NaNs.  */
371   if (!special_exponent)
372     exponent -= fmt->exp_bias;
373
374   /* Build the result algebraically.  Might go infinite, underflow, etc;
375      who cares. */
376
377   /* If this format uses a hidden bit, explicitly add it in now.  Otherwise,
378      increment the exponent by one to account for the integer bit.  */
379
380   if (!special_exponent)
381     {
382       if (fmt->intbit == floatformat_intbit_no)
383         dto = ldexp (1.0, exponent);
384       else
385         exponent++;
386     }
387
388   while (mant_bits_left > 0)
389     {
390       mant_bits = min (mant_bits_left, 32);
391
392       mant = get_field (ufrom, fmt->byteorder, fmt->totalsize,
393                          mant_off, mant_bits);
394
395       /* Handle denormalized numbers.  FIXME: What should we do for
396          non-IEEE formats?  */
397       if (exponent == 0 && mant != 0)
398         dto += ldexp ((double)mant,
399                       (- fmt->exp_bias
400                        - mant_bits
401                        - (mant_off - fmt->man_start)
402                        + 1));
403       else
404         dto += ldexp ((double)mant, exponent - mant_bits);
405       if (exponent != 0)
406         exponent -= mant_bits;
407       mant_off += mant_bits;
408       mant_bits_left -= mant_bits;
409     }
410
411   /* Negate it if negative.  */
412   if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1))
413     dto = -dto;
414   *to = dto;
415 }
416 \f
417 static void put_field (unsigned char *, enum floatformat_byteorders,
418                        unsigned int,
419                        unsigned int,
420                        unsigned int,
421                        unsigned long);
422
423 /* Set a field which starts at START and is LEN bits long.  DATA and
424    TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER.  */
425 static void
426 put_field (unsigned char *data, enum floatformat_byteorders order,
427            unsigned int total_len, unsigned int start, unsigned int len,
428            unsigned long stuff_to_put)
429 {
430   unsigned int cur_byte;
431   int cur_bitshift;
432
433   /* Start at the least significant part of the field.  */
434   cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT;
435   if (order == floatformat_little)
436     cur_byte = (total_len / FLOATFORMAT_CHAR_BIT) - cur_byte - 1;
437   cur_bitshift =
438     ((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT;
439   *(data + cur_byte) &=
440     ~(((1 << ((start + len) % FLOATFORMAT_CHAR_BIT)) - 1) << (-cur_bitshift));
441   *(data + cur_byte) |=
442     (stuff_to_put & ((1 << FLOATFORMAT_CHAR_BIT) - 1)) << (-cur_bitshift);
443   cur_bitshift += FLOATFORMAT_CHAR_BIT;
444   if (order == floatformat_little)
445     ++cur_byte;
446   else
447     --cur_byte;
448
449   /* Move towards the most significant part of the field.  */
450   while ((unsigned int) cur_bitshift < len)
451     {
452       if (len - cur_bitshift < FLOATFORMAT_CHAR_BIT)
453         {
454           /* This is the last byte.  */
455           *(data + cur_byte) &=
456             ~((1 << (len - cur_bitshift)) - 1);
457           *(data + cur_byte) |= (stuff_to_put >> cur_bitshift);
458         }
459       else
460         *(data + cur_byte) = ((stuff_to_put >> cur_bitshift)
461                               & ((1 << FLOATFORMAT_CHAR_BIT) - 1));
462       cur_bitshift += FLOATFORMAT_CHAR_BIT;
463       if (order == floatformat_little)
464         ++cur_byte;
465       else
466         --cur_byte;
467     }
468 }
469
470 /* The converse: convert the double *FROM to an extended float
471    and store where TO points.  Neither FROM nor TO have any alignment
472    restrictions.  */
473
474 void
475 floatformat_from_double (const struct floatformat *fmt,
476                          const double *from, void *to)
477 {
478   double dfrom;
479   int exponent;
480   double mant;
481   unsigned int mant_bits, mant_off;
482   int mant_bits_left;
483   unsigned char *uto = (unsigned char *) to;
484
485   dfrom = *from;
486   memset (uto, 0, fmt->totalsize / FLOATFORMAT_CHAR_BIT);
487
488   /* If negative, set the sign bit.  */
489   if (dfrom < 0)
490     {
491       put_field (uto, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1, 1);
492       dfrom = -dfrom;
493     }
494
495   if (dfrom == 0)
496     {
497       /* 0.0.  */
498       return;
499     }
500
501   if (dfrom != dfrom)
502     {
503       /* NaN.  */
504       put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
505                  fmt->exp_len, fmt->exp_nan);
506       /* Be sure it's not infinity, but NaN value is irrelevant.  */
507       put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start,
508                  32, 1);
509       return;
510     }
511
512   if (dfrom + dfrom == dfrom)
513     {
514       /* This can only happen for an infinite value (or zero, which we
515          already handled above).  */
516       put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
517                  fmt->exp_len, fmt->exp_nan);
518       return;
519     }
520
521   mant = frexp (dfrom, &exponent);
522   if (exponent + fmt->exp_bias - 1 > 0)
523     put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
524                fmt->exp_len, exponent + fmt->exp_bias - 1);
525   else
526     {
527       /* Handle a denormalized number.  FIXME: What should we do for
528          non-IEEE formats?  */
529       put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
530                  fmt->exp_len, 0);
531       mant = ldexp (mant, exponent + fmt->exp_bias - 1);
532     }
533
534   mant_bits_left = fmt->man_len;
535   mant_off = fmt->man_start;
536   while (mant_bits_left > 0)
537     {
538       unsigned long mant_long;
539       mant_bits = mant_bits_left < 32 ? mant_bits_left : 32;
540
541       mant *= 4294967296.0;
542       mant_long = (unsigned long)mant;
543       mant -= mant_long;
544
545       /* If the integer bit is implicit, and we are not creating a
546          denormalized number, then we need to discard it.  */
547       if ((unsigned int) mant_bits_left == fmt->man_len
548           && fmt->intbit == floatformat_intbit_no
549           && exponent + fmt->exp_bias - 1 > 0)
550         {
551           mant_long &= 0x7fffffff;
552           mant_bits -= 1;
553         }
554       else if (mant_bits < 32)
555         {
556           /* The bits we want are in the most significant MANT_BITS bits of
557              mant_long.  Move them to the least significant.  */
558           mant_long >>= 32 - mant_bits;
559         }
560
561       put_field (uto, fmt->byteorder, fmt->totalsize,
562                  mant_off, mant_bits, mant_long);
563       mant_off += mant_bits;
564       mant_bits_left -= mant_bits;
565     }
566 }
567
568 /* Return non-zero iff the data at FROM is a valid number in format FMT.  */
569
570 int
571 floatformat_is_valid (const struct floatformat *fmt, const void *from)
572 {
573   return fmt->is_valid (fmt, from);
574 }
575
576
577 #ifdef IEEE_DEBUG
578
579 #include <stdio.h>
580
581 /* This is to be run on a host which uses IEEE floating point.  */
582
583 void
584 ieee_test (double n)
585 {
586   double result;
587
588   floatformat_to_double (&floatformat_ieee_double_little, &n, &result);
589   if ((n != result && (! isnan (n) || ! isnan (result)))
590       || (n < 0 && result >= 0)
591       || (n >= 0 && result < 0))
592     printf ("Differ(to): %.20g -> %.20g\n", n, result);
593
594   floatformat_from_double (&floatformat_ieee_double_little, &n, &result);
595   if ((n != result && (! isnan (n) || ! isnan (result)))
596       || (n < 0 && result >= 0)
597       || (n >= 0 && result < 0))
598     printf ("Differ(from): %.20g -> %.20g\n", n, result);
599
600 #if 0
601   {
602     char exten[16];
603
604     floatformat_from_double (&floatformat_m68881_ext, &n, exten);
605     floatformat_to_double (&floatformat_m68881_ext, exten, &result);
606     if (n != result)
607       printf ("Differ(to+from): %.20g -> %.20g\n", n, result);
608   }
609 #endif
610
611 #if IEEE_DEBUG > 1
612   /* This is to be run on a host which uses 68881 format.  */
613   {
614     long double ex = *(long double *)exten;
615     if (ex != n)
616       printf ("Differ(from vs. extended): %.20g\n", n);
617   }
618 #endif
619 }
620
621 int
622 main (void)
623 {
624   ieee_test (0.0);
625   ieee_test (0.5);
626   ieee_test (256.0);
627   ieee_test (0.12345);
628   ieee_test (234235.78907234);
629   ieee_test (-512.0);
630   ieee_test (-0.004321);
631   ieee_test (1.2E-70);
632   ieee_test (1.2E-316);
633   ieee_test (4.9406564584124654E-324);
634   ieee_test (- 4.9406564584124654E-324);
635   ieee_test (- 0.0);
636   ieee_test (- INFINITY);
637   ieee_test (- NAN);
638   ieee_test (INFINITY);
639   ieee_test (NAN);
640   return 0;
641 }
642 #endif