Paranoia fails for sh-elf -m4-single-only with current newlib mainline.
Paranoia wnts to print the smallest representable floating point number,
which is a denormal with only the least significant bit set.
dtoa.c calculates correctly that there is only one bit, but it assumes
it has
to pick it out of a 64 bit double, i.e. it shifts word1, which is always 0,
left by 31. Hence converting to floating point yields 0.0, and subtracting
31 from the exponent causes an underflow. Hence we end up with a ds
that is larger than INT_MAX, and a k of INT_MAX.
Hence we run out of memory when while calculating
pow5mult (ptr, S, s5), and the memory gets corrupted when Balloc fails.
The attached patch fixes this by getting the fraction buts from the
right place.
I've also fixed the rounding of the constant used to compute ds for
_DOUBLE_IS_32BITS so that we keep the error strictly positive as the
comment above requires.
I've sucessfully run a check-gcc check-target-libstdc++-v3 regresion test
with this patch.
check-target-newlib already failed for the baseline, see
http://sourceware.org/ml/newlib/2006/msg00635.html . I can't investigate
this now because I have some GCC problems to look into.
------------------------------------------------------------------------
2006-08-01 J"orn Rennecke <joern.rennecke@st.com>
* dtoa.c (dtoa_r): Handle the denormalized _DOUBLE_IS_32BITS case
properly.
--- dtoa.c 2002-02-05 17:14:35.000000000 +0000
+++ /home/afra/users/renneckej/dtoa.c 2006-08-01 18:49:31.000000000 +0100
@@ -338,15 +338,23 @@ _DEFUN (_dtoa_r,
/* d is denormalized */
i = bbits + be + (Bias + (P - 1) - 1);
+#if defined (_DOUBLE_IS_32BITS)
+ x = word0 (d) << (32 - i);
+#else
x = (i > 32) ? (word0 (d) << (64 - i)) | (word1 (d) >> (i - 32))
: (word1 (d) << (32 - i));
+#endif
d2.d = x;
word0 (d2) -= 31 * Exp_msk1; /* adjust exponent */
i -= (Bias + (P - 1) - 1) + 1;
denorm = 1;
}
#endif
+#if defined (_DOUBLE_IS_32BITS)
+ ds = (d2.d - 1.5) * 0.289529651 + 0.176091269 + i * 0.30103001;
+#else
ds = (d2.d - 1.5) * 0.289529654602168 + 0.1760912590558 + i * 0.301029995663981;
+#endif
k = (int) ds;
if (ds < 0. && ds != k)
k--; /* want k = floor(ds) */