aboutsummaryrefslogtreecommitdiff
path: root/gcc/real.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/real.cc')
-rw-r--r--gcc/real.cc27
1 files changed, 15 insertions, 12 deletions
diff --git a/gcc/real.cc b/gcc/real.cc
index b64bad0..95a9332 100644
--- a/gcc/real.cc
+++ b/gcc/real.cc
@@ -2230,7 +2230,6 @@ real_from_integer (REAL_VALUE_TYPE *r, format_helper fmt,
{
unsigned int len = val_in.get_precision ();
int i, j, e = 0;
- int maxbitlen = MAX_BITSIZE_MODE_ANY_INT + HOST_BITS_PER_WIDE_INT;
const unsigned int realmax = (SIGNIFICAND_BITS / HOST_BITS_PER_WIDE_INT
* HOST_BITS_PER_WIDE_INT);
@@ -2238,12 +2237,6 @@ real_from_integer (REAL_VALUE_TYPE *r, format_helper fmt,
r->cl = rvc_normal;
r->sign = wi::neg_p (val_in, sgn);
- /* We have to ensure we can negate the largest negative number. */
- wide_int val = wide_int::from (val_in, maxbitlen, sgn);
-
- if (r->sign)
- val = -val;
-
/* Ensure a multiple of HOST_BITS_PER_WIDE_INT, ceiling, as elt
won't work with precisions that are not a multiple of
HOST_BITS_PER_WIDE_INT. */
@@ -2252,7 +2245,13 @@ real_from_integer (REAL_VALUE_TYPE *r, format_helper fmt,
/* Ensure we can represent the largest negative number. */
len += 1;
- len = len/HOST_BITS_PER_WIDE_INT * HOST_BITS_PER_WIDE_INT;
+ len = len / HOST_BITS_PER_WIDE_INT * HOST_BITS_PER_WIDE_INT;
+
+ /* We have to ensure we can negate the largest negative number. */
+ wide_int val = wide_int::from (val_in, len, sgn);
+
+ if (r->sign)
+ val = -val;
/* Cap the size to the size allowed by real.h. */
if (len > realmax)
@@ -2260,14 +2259,18 @@ real_from_integer (REAL_VALUE_TYPE *r, format_helper fmt,
HOST_WIDE_INT cnt_l_z;
cnt_l_z = wi::clz (val);
- if (maxbitlen - cnt_l_z > realmax)
+ if (len - cnt_l_z > realmax)
{
- e = maxbitlen - cnt_l_z - realmax;
+ e = len - cnt_l_z - realmax;
/* This value is too large, we must shift it right to
preserve all the bits we can, and then bump the
- exponent up by that amount. */
- val = wi::lrshift (val, e);
+ exponent up by that amount, but or in 1 if any of
+ the shifted out bits are non-zero. */
+ if (wide_int::from (val, e, UNSIGNED) != 0)
+ val = wi::set_bit (wi::lrshift (val, e), 0);
+ else
+ val = wi::lrshift (val, e);
}
len = realmax;
}