* config/atof-ieee.c (gen_to_words): Correctly round a
authorAndreas Schwab <schwab@linux-m68k.org>
Fri, 14 May 1999 01:53:28 +0000 (01:53 +0000)
committerAndreas Schwab <schwab@linux-m68k.org>
Fri, 14 May 1999 01:53:28 +0000 (01:53 +0000)
denormalized number.  Fix off-by-one in range checking for
exponent in a denormal.

gas/ChangeLog
gas/config/atof-ieee.c

index 7e62bdcfd60d06d3e6c7ee5b4cd8ec32d4a2a09d..0e7b0e889e419e16cedd93c77f64d2969c2d66c0 100644 (file)
@@ -1,3 +1,9 @@
+Fri May 14 10:52:13 1999  Andreas Schwab  <schwab@issan.cs.uni-dortmund.de>
+
+       * config/atof-ieee.c (gen_to_words): Correctly round a
+       denormalized number.  Fix off-by-one in range checking for
+       exponent in a denormal. 
+
 Thu May 13 09:46:59 1999  Joel Sherrill (joel@OARcorp.com)
 
        * configure.in (i386-*-rtemself*, sh-*-rtemself*): New targets.
index d586e3a85e396593dc448d42407191fb7e3bb435..fbf0ffb62c9e02043a6e2c5f2b37b98a3a534b8c 100644 (file)
@@ -460,7 +460,7 @@ gen_to_words (words, precision, exponent_bits)
          /* Bigger than one littlenum */
          num_bits -= (LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits;
          *lp++ = word1;
-         if (num_bits + exponent_bits + 1 >= precision * LITTLENUM_NUMBER_OF_BITS)
+         if (num_bits + exponent_bits + 1 > precision * LITTLENUM_NUMBER_OF_BITS)
            {
              /* Exponent overflow */
              make_invalid_floating_point_number (words);
@@ -501,7 +501,7 @@ gen_to_words (words, precision, exponent_bits)
       if (next_bits (1))
        {
          --lp;
-         if (prec_bits > LITTLENUM_NUMBER_OF_BITS)
+         if (prec_bits >= LITTLENUM_NUMBER_OF_BITS)
            {
              int n = 0;
              int tmp_bits;
@@ -515,7 +515,19 @@ gen_to_words (words, precision, exponent_bits)
                  --n;
                  tmp_bits -= LITTLENUM_NUMBER_OF_BITS;
                }
-             if (tmp_bits > LITTLENUM_NUMBER_OF_BITS || (lp[n] & mask[tmp_bits]) != mask[tmp_bits])
+             if (tmp_bits > LITTLENUM_NUMBER_OF_BITS
+                 || (lp[n] & mask[tmp_bits]) != mask[tmp_bits]
+                 || (prec_bits != (precision * LITTLENUM_NUMBER_OF_BITS
+                                   - exponent_bits - 1)
+#ifdef TC_I386
+                     /* An extended precision float with only the integer
+                        bit set would be invalid.  That must be converted
+                        to the smallest normalized number.  */
+                     && !(precision == X_PRECISION
+                          && prec_bits == (precision * LITTLENUM_NUMBER_OF_BITS
+                                           - exponent_bits - 2))
+#endif
+                     ))
                {
                  unsigned long carry;
 
@@ -539,11 +551,18 @@ gen_to_words (words, precision, exponent_bits)
                            << ((LITTLENUM_NUMBER_OF_BITS - 1)
                                - exponent_bits));
                  *lp++ = word1;
+#ifdef TC_I386
+                 /* Set the integer bit in the extended precision format.
+                    This cannot happen on the m68k where the mantissa
+                    just overflows into the integer bit above.  */
+                 if (precision == X_PRECISION)
+                   *lp++ = 1 << (LITTLENUM_NUMBER_OF_BITS - 1);
+#endif
                  while (lp < words_end)
                    *lp++ = 0;
                }
            }
-         else if ((*lp & mask[prec_bits]) != mask[prec_bits])
+         else
            *lp += 1;
        }