OSDN Git Service

* include/bits/basic_string.tcc (_Rep::_S_create): Call
[pf3gnuchains/gcc-fork.git] / libiberty / floatformat.c
index a0f6535..0bbb8ed 100644 (file)
@@ -1,5 +1,6 @@
 /* IEEE floating point support routines, for GDB, the GNU Debugger.
-   Copyright (C) 1991, 1994, 1999, 2000, 2003 Free Software Foundation, Inc.
+   Copyright 1991, 1994, 1999, 2000, 2003, 2005, 2006
+   Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -15,7 +16,7 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
 
 /* This is needed to pick up the NAN macro on some systems.  */
 #define _GNU_SOURCE
@@ -30,6 +31,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include <string.h>
 #endif
 
+/* On some platforms, <float.h> provides DBL_QNAN.  */
+#ifdef STDC_HEADERS
+#include <float.h>
+#endif
+
 #include "ansidecl.h"
 #include "libiberty.h"
 #include "floatformat.h"
@@ -43,21 +49,24 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #endif
 
 #ifndef NAN
+#ifdef DBL_QNAN
+#define NAN DBL_QNAN
+#else
 #define NAN (0.0 / 0.0)
 #endif
+#endif
 
-static unsigned long get_field PARAMS ((const unsigned char *,
-                                       enum floatformat_byteorders,
-                                       unsigned int,
-                                       unsigned int,
-                                       unsigned int));
-static int floatformat_always_valid PARAMS ((const struct floatformat *fmt,
-                                            const char *from));
+static unsigned long get_field (const unsigned char *,
+                                enum floatformat_byteorders,
+                                unsigned int,
+                                unsigned int,
+                                unsigned int);
+static int floatformat_always_valid (const struct floatformat *fmt,
+                                     const void *from);
 
 static int
-floatformat_always_valid (fmt, from)
-     const struct floatformat *fmt ATTRIBUTE_UNUSED;
-     const char *from ATTRIBUTE_UNUSED;
+floatformat_always_valid (const struct floatformat *fmt ATTRIBUTE_UNUSED,
+                          const void *from ATTRIBUTE_UNUSED)
 {
   return 1;
 }
@@ -108,12 +117,35 @@ const struct floatformat floatformat_ieee_double_littlebyte_bigword =
   floatformat_always_valid
 };
 
-static int floatformat_i387_ext_is_valid PARAMS ((const struct floatformat *fmt, const char *from));
+/* floatformat for VAX.  Not quite IEEE, but close enough.  */
+
+const struct floatformat floatformat_vax_f =
+{
+  floatformat_vax, 32, 0, 1, 8, 129, 0, 9, 23,
+  floatformat_intbit_no,
+  "floatformat_vax_f",
+  floatformat_always_valid
+};
+const struct floatformat floatformat_vax_d =
+{
+  floatformat_vax, 64, 0, 1, 8, 129, 0, 9, 55,
+  floatformat_intbit_no,
+  "floatformat_vax_d",
+  floatformat_always_valid
+};
+const struct floatformat floatformat_vax_g =
+{
+  floatformat_vax, 64, 0, 1, 11, 1025, 0, 12, 52,
+  floatformat_intbit_no,
+  "floatformat_vax_g",
+  floatformat_always_valid
+};
+
+static int floatformat_i387_ext_is_valid (const struct floatformat *fmt,
+                                         const void *from);
 
 static int
-floatformat_i387_ext_is_valid (fmt, from)
-     const struct floatformat *fmt;
-     const char *from;
+floatformat_i387_ext_is_valid (const struct floatformat *fmt, const void *from)
 {
   /* In the i387 double-extended format, if the exponent is all ones,
      then the integer bit must be set.  If the exponent is neither 0
@@ -121,12 +153,12 @@ floatformat_i387_ext_is_valid (fmt, from)
      zero can it be zero, and then it must be zero.  */
   unsigned long exponent, int_bit;
   const unsigned char *ufrom = (const unsigned char *) from;
-  
+
   exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize,
                        fmt->exp_start, fmt->exp_len);
   int_bit = get_field (ufrom, fmt->byteorder, fmt->totalsize,
                       fmt->man_start, 1);
-  
+
   if ((exponent == 0) != (int_bit == 0))
     return 0;
   else
@@ -220,12 +252,8 @@ const struct floatformat floatformat_ia64_quad_little =
 /* Extract a field which starts at START and is LEN bits long.  DATA and
    TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER.  */
 static unsigned long
-get_field (data, order, total_len, start, len)
-     const unsigned char *data;
-     enum floatformat_byteorders order;
-     unsigned int total_len;
-     unsigned int start;
-     unsigned int len;
+get_field (const unsigned char *data, enum floatformat_byteorders order,
+           unsigned int total_len, unsigned int start, unsigned int len)
 {
   unsigned long result;
   unsigned int cur_byte;
@@ -273,12 +301,10 @@ get_field (data, order, total_len, start, len)
    Store the double in *TO.  */
 
 void
-floatformat_to_double (fmt, from, to)
-     const struct floatformat *fmt;
-     const char *from;
-     double *to;
+floatformat_to_double (const struct floatformat *fmt,
+                       const void *from, double *to)
 {
-  const unsigned char *ufrom = (const unsigned char *)from;
+  const unsigned char *ufrom = (const unsigned char *) from;
   double dto;
   long exponent;
   unsigned long mant;
@@ -315,6 +341,13 @@ floatformat_to_double (fmt, from, to)
          mant_bits_left -= mant_bits;
        }
 
+      /* On certain systems (such as GNU/Linux), the use of the
+        INFINITY macro below may generate a warning that can not be
+        silenced due to a bug in GCC (PR preprocessor/11931).  The
+        preprocessor fails to recognise the __extension__ keyword in
+        conjunction with the GNU/C99 extension for hexadecimal
+        floating point constants and will issue a warning when
+        compiling with -pedantic.  */
       if (nan)
        dto = NAN;
       else
@@ -361,7 +394,7 @@ floatformat_to_double (fmt, from, to)
 
       /* Handle denormalized numbers.  FIXME: What should we do for
         non-IEEE formats?  */
-      if (exponent == 0 && mant != 0)
+      if (special_exponent && exponent == 0 && mant != 0)
        dto += ldexp ((double)mant,
                      (- fmt->exp_bias
                       - mant_bits
@@ -381,22 +414,18 @@ floatformat_to_double (fmt, from, to)
   *to = dto;
 }
 \f
-static void put_field PARAMS ((unsigned char *, enum floatformat_byteorders,
-                              unsigned int,
-                              unsigned int,
-                              unsigned int,
-                              unsigned long));
+static void put_field (unsigned char *, enum floatformat_byteorders,
+                       unsigned int,
+                       unsigned int,
+                       unsigned int,
+                       unsigned long);
 
 /* Set a field which starts at START and is LEN bits long.  DATA and
    TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER.  */
 static void
-put_field (data, order, total_len, start, len, stuff_to_put)
-     unsigned char *data;
-     enum floatformat_byteorders order;
-     unsigned int total_len;
-     unsigned int start;
-     unsigned int len;
-     unsigned long stuff_to_put;
+put_field (unsigned char *data, enum floatformat_byteorders order,
+           unsigned int total_len, unsigned int start, unsigned int len,
+           unsigned long stuff_to_put)
 {
   unsigned int cur_byte;
   int cur_bitshift;
@@ -443,17 +472,15 @@ put_field (data, order, total_len, start, len, stuff_to_put)
    restrictions.  */
 
 void
-floatformat_from_double (fmt, from, to)
-     const struct floatformat *fmt;
-     const double *from;
-     char *to;
+floatformat_from_double (const struct floatformat *fmt,
+                         const double *from, void *to)
 {
   double dfrom;
   int exponent;
   double mant;
   unsigned int mant_bits, mant_off;
   int mant_bits_left;
-  unsigned char *uto = (unsigned char *)to;
+  unsigned char *uto = (unsigned char *) to;
 
   dfrom = *from;
   memset (uto, 0, fmt->totalsize / FLOATFORMAT_CHAR_BIT);
@@ -541,9 +568,7 @@ floatformat_from_double (fmt, from, to)
 /* Return non-zero iff the data at FROM is a valid number in format FMT.  */
 
 int
-floatformat_is_valid (fmt, from)
-     const struct floatformat *fmt;
-     const char *from;
+floatformat_is_valid (const struct floatformat *fmt, const void *from)
 {
   return fmt->is_valid (fmt, from);
 }
@@ -556,20 +581,17 @@ floatformat_is_valid (fmt, from)
 /* This is to be run on a host which uses IEEE floating point.  */
 
 void
-ieee_test (n)
-     double n;
+ieee_test (double n)
 {
   double result;
 
-  floatformat_to_double (&floatformat_ieee_double_little, (char *) &n,
-                        &result);
+  floatformat_to_double (&floatformat_ieee_double_little, &n, &result);
   if ((n != result && (! isnan (n) || ! isnan (result)))
       || (n < 0 && result >= 0)
       || (n >= 0 && result < 0))
     printf ("Differ(to): %.20g -> %.20g\n", n, result);
 
-  floatformat_from_double (&floatformat_ieee_double_little, &n,
-                          (char *) &result);
+  floatformat_from_double (&floatformat_ieee_double_little, &n, &result);
   if ((n != result && (! isnan (n) || ! isnan (result)))
       || (n < 0 && result >= 0)
       || (n >= 0 && result < 0))
@@ -597,7 +619,7 @@ ieee_test (n)
 }
 
 int
-main ()
+main (void)
 {
   ieee_test (0.0);
   ieee_test (0.5);