gas: sparc: fix collision of registers and pseudo-ops.
[deliverable/binutils-gdb.git] / libiberty / floatformat.c
index 07af7264df499c932b3d07662513a4a86304cc14..9190e1469d9fdf4587a5ed600197489a684148d9 100644 (file)
@@ -1,5 +1,5 @@
 /* IEEE floating point support routines, for GDB, the GNU Debugger.
 /* IEEE floating point support routines, for GDB, the GNU Debugger.
-   Copyright 1991, 1994, 1999, 2000, 2003, 2005, 2006
+   Copyright 1991, 1994, 1999, 2000, 2003, 2005, 2006, 2010, 2012, 2015
    Free Software Foundation, Inc.
 
 This file is part of GDB.
    Free Software Foundation, Inc.
 
 This file is part of GDB.
@@ -19,7 +19,9 @@ along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
 
 /* This is needed to pick up the NAN macro on some systems.  */
 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
 
 /* This is needed to pick up the NAN macro on some systems.  */
+#ifndef _GNU_SOURCE
 #define _GNU_SOURCE
 #define _GNU_SOURCE
+#endif
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -77,7 +79,23 @@ floatformat_always_valid (const struct floatformat *fmt ATTRIBUTE_UNUSED,
    a system header, what we do if not, etc.  */
 #define FLOATFORMAT_CHAR_BIT 8
 
    a system header, what we do if not, etc.  */
 #define FLOATFORMAT_CHAR_BIT 8
 
-/* floatformats for IEEE single and double, big and little endian.  */
+/* floatformats for IEEE half, single and double, big and little endian.  */
+const struct floatformat floatformat_ieee_half_big =
+{
+  floatformat_big, 16, 0, 1, 5, 15, 31, 6, 10,
+  floatformat_intbit_no,
+  "floatformat_ieee_half_big",
+  floatformat_always_valid,
+  NULL
+};
+const struct floatformat floatformat_ieee_half_little =
+{
+  floatformat_little, 16, 0, 1, 5, 15, 31, 6, 10,
+  floatformat_intbit_no,
+  "floatformat_ieee_half_little",
+  floatformat_always_valid,
+  NULL
+};
 const struct floatformat floatformat_ieee_single_big =
 {
   floatformat_big, 32, 0, 1, 8, 127, 255, 9, 23,
 const struct floatformat floatformat_ieee_single_big =
 {
   floatformat_big, 32, 0, 1, 8, 127, 255, 9, 23,
@@ -283,7 +301,7 @@ floatformat_ibm_long_double_is_valid (const struct floatformat *fmt,
   bot_exp = get_field (ufrom + 8, hfmt->byteorder, hfmt->totalsize,
                       hfmt->exp_start, hfmt->exp_len);
 
   bot_exp = get_field (ufrom + 8, hfmt->byteorder, hfmt->totalsize,
                       hfmt->exp_start, hfmt->exp_len);
 
-  if (top_exp == hfmt->exp_nan)
+  if ((unsigned long) top_exp == hfmt->exp_nan)
     top_nan = mant_bits_set (hfmt, ufrom);
 
   /* A NaN is valid with any low part.  */
     top_nan = mant_bits_set (hfmt, ufrom);
 
   /* A NaN is valid with any low part.  */
@@ -292,11 +310,8 @@ floatformat_ibm_long_double_is_valid (const struct floatformat *fmt,
 
   /* An infinity, zero or denormal requires low part 0 (positive or
      negative).  */
 
   /* An infinity, zero or denormal requires low part 0 (positive or
      negative).  */
-  if (top_exp == hfmt->exp_nan || top_exp == 0)
+  if ((unsigned long) top_exp == hfmt->exp_nan || top_exp == 0)
     {
     {
-      unsigned int mant_bits, mant_off;
-      int mant_bits_left;
-
       if (bot_exp != 0)
        return 0;
 
       if (bot_exp != 0)
        return 0;
 
@@ -318,7 +333,7 @@ floatformat_ibm_long_double_is_valid (const struct floatformat *fmt,
       /* The bottom part is 0 or denormal.  Determine which, and if
         denormal the first two set bits.  */
       int first_bit = -1, second_bit = -1, cur_bit;
       /* The bottom part is 0 or denormal.  Determine which, and if
         denormal the first two set bits.  */
       int first_bit = -1, second_bit = -1, cur_bit;
-      for (cur_bit = 0; cur_bit < hfmt->man_len; cur_bit++)
+      for (cur_bit = 0; (unsigned int) cur_bit < hfmt->man_len; cur_bit++)
        if (get_field (ufrom + 8, hfmt->byteorder, hfmt->totalsize,
                       hfmt->man_start + cur_bit, 1))
          {
        if (get_field (ufrom + 8, hfmt->byteorder, hfmt->totalsize,
                       hfmt->man_start + cur_bit, 1))
          {
@@ -358,14 +373,23 @@ floatformat_ibm_long_double_is_valid (const struct floatformat *fmt,
     }
 }
 
     }
 }
 
-const struct floatformat floatformat_ibm_long_double =
+const struct floatformat floatformat_ibm_long_double_big =
 {
   floatformat_big, 128, 0, 1, 11, 1023, 2047, 12, 52,
   floatformat_intbit_no,
 {
   floatformat_big, 128, 0, 1, 11, 1023, 2047, 12, 52,
   floatformat_intbit_no,
-  "floatformat_ibm_long_double",
-  floatformat_always_valid,
+  "floatformat_ibm_long_double_big",
+  floatformat_ibm_long_double_is_valid,
   &floatformat_ieee_double_big
 };
   &floatformat_ieee_double_big
 };
+
+const struct floatformat floatformat_ibm_long_double_little =
+{
+  floatformat_little, 128, 0, 1, 11, 1023, 2047, 12, 52,
+  floatformat_intbit_no,
+  "floatformat_ibm_long_double_little",
+  floatformat_ibm_long_double_is_valid,
+  &floatformat_ieee_double_little
+};
 \f
 
 #ifndef min
 \f
 
 #ifndef min
@@ -450,7 +474,6 @@ floatformat_to_double (const struct floatformat *fmt,
   unsigned long mant;
   unsigned int mant_bits, mant_off;
   int mant_bits_left;
   unsigned long mant;
   unsigned int mant_bits, mant_off;
   int mant_bits_left;
-  int special_exponent;                /* It's a NaN, denorm or zero */
 
   /* Split values are not handled specially, since the top half has
      the correctly rounded double value (in the only supported case of
 
   /* Split values are not handled specially, since the top half has
      the correctly rounded double value (in the only supported case of
@@ -490,20 +513,20 @@ floatformat_to_double (const struct floatformat *fmt,
   mant_off = fmt->man_start;
   dto = 0.0;
 
   mant_off = fmt->man_start;
   dto = 0.0;
 
-  special_exponent = exponent == 0 || (unsigned long) exponent == fmt->exp_nan;
-
-  /* Don't bias zero's, denorms or NaNs.  */
-  if (!special_exponent)
-    exponent -= fmt->exp_bias;
-
   /* Build the result algebraically.  Might go infinite, underflow, etc;
      who cares. */
 
   /* Build the result algebraically.  Might go infinite, underflow, etc;
      who cares. */
 
-  /* If this format uses a hidden bit, explicitly add it in now.  Otherwise,
-     increment the exponent by one to account for the integer bit.  */
-
-  if (!special_exponent)
+  /* For denorms use minimum exponent.  */
+  if (exponent == 0)
+    exponent = 1 - fmt->exp_bias;
+  else
     {
     {
+      exponent -= fmt->exp_bias;
+
+      /* If this format uses a hidden bit, explicitly add it in now.
+        Otherwise, increment the exponent by one to account for the
+        integer bit.  */
+
       if (fmt->intbit == floatformat_intbit_no)
        dto = ldexp (1.0, exponent);
       else
       if (fmt->intbit == floatformat_intbit_no)
        dto = ldexp (1.0, exponent);
       else
@@ -517,18 +540,8 @@ floatformat_to_double (const struct floatformat *fmt,
       mant = get_field (ufrom, fmt->byteorder, fmt->totalsize,
                         mant_off, mant_bits);
 
       mant = get_field (ufrom, fmt->byteorder, fmt->totalsize,
                         mant_off, mant_bits);
 
-      /* Handle denormalized numbers.  FIXME: What should we do for
-        non-IEEE formats?  */
-      if (special_exponent && exponent == 0 && mant != 0)
-       dto += ldexp ((double)mant,
-                     (- fmt->exp_bias
-                      - mant_bits
-                      - (mant_off - fmt->man_start)
-                      + 1));
-      else
-       dto += ldexp ((double)mant, exponent - mant_bits);
-      if (exponent != 0)
-       exponent -= mant_bits;
+      dto += ldexp ((double) mant, exponent - mant_bits);
+      exponent -= mant_bits;
       mant_off += mant_bits;
       mant_bits_left -= mant_bits;
     }
       mant_off += mant_bits;
       mant_bits_left -= mant_bits;
     }
@@ -743,6 +756,7 @@ main (void)
 {
   ieee_test (0.0);
   ieee_test (0.5);
 {
   ieee_test (0.0);
   ieee_test (0.5);
+  ieee_test (1.1);
   ieee_test (256.0);
   ieee_test (0.12345);
   ieee_test (234235.78907234);
   ieee_test (256.0);
   ieee_test (0.12345);
   ieee_test (234235.78907234);
This page took 0.026223 seconds and 4 git commands to generate.