Commit 11b161d0 by John Wehle Committed by John Wehle

fold-const.c (lshift_double): Honor PREC.

	* fold-const.c (lshift_double): Honor PREC.
	(rshift_double): Likewise.

From-SVN: r46872
parent 702020d6
Fri Nov 9 00:25:18 EST 2001 John Wehle (john@feith.com)
* fold-const.c (lshift_double): Honor PREC.
(rshift_double): Likewise.
2001-11-08 Kazu Hirata <kazu@hxi.com> 2001-11-08 Kazu Hirata <kazu@hxi.com>
* config/1750a/1750a.c: Fix comment formatting. * config/1750a/1750a.c: Fix comment formatting.
......
...@@ -383,6 +383,8 @@ lshift_double (l1, h1, count, prec, lv, hv, arith) ...@@ -383,6 +383,8 @@ lshift_double (l1, h1, count, prec, lv, hv, arith)
HOST_WIDE_INT *hv; HOST_WIDE_INT *hv;
int arith; int arith;
{ {
unsigned HOST_WIDE_INT signmask;
if (count < 0) if (count < 0)
{ {
rshift_double (l1, h1, -count, prec, lv, hv, arith); rshift_double (l1, h1, -count, prec, lv, hv, arith);
...@@ -412,6 +414,26 @@ lshift_double (l1, h1, count, prec, lv, hv, arith) ...@@ -412,6 +414,26 @@ lshift_double (l1, h1, count, prec, lv, hv, arith)
| (l1 >> (HOST_BITS_PER_WIDE_INT - count - 1) >> 1)); | (l1 >> (HOST_BITS_PER_WIDE_INT - count - 1) >> 1));
*lv = l1 << count; *lv = l1 << count;
} }
/* Sign extend all bits that are beyond the precision. */
signmask = -((prec > HOST_BITS_PER_WIDE_INT
? (*hv >> (prec - HOST_BITS_PER_WIDE_INT - 1))
: (*lv >> (prec - 1))) & 1);
if (prec >= 2 * HOST_BITS_PER_WIDE_INT)
;
else if (prec >= HOST_BITS_PER_WIDE_INT)
{
*hv &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT));
*hv |= signmask << (prec - HOST_BITS_PER_WIDE_INT);
}
else
{
*hv = signmask;
*lv &= ~((unsigned HOST_WIDE_INT) (-1) << prec);
*lv |= signmask << prec;
}
} }
/* Shift the doubleword integer in L1, H1 right by COUNT places /* Shift the doubleword integer in L1, H1 right by COUNT places
...@@ -423,7 +445,7 @@ void ...@@ -423,7 +445,7 @@ void
rshift_double (l1, h1, count, prec, lv, hv, arith) rshift_double (l1, h1, count, prec, lv, hv, arith)
unsigned HOST_WIDE_INT l1; unsigned HOST_WIDE_INT l1;
HOST_WIDE_INT h1, count; HOST_WIDE_INT h1, count;
unsigned int prec ATTRIBUTE_UNUSED; unsigned int prec;
unsigned HOST_WIDE_INT *lv; unsigned HOST_WIDE_INT *lv;
HOST_WIDE_INT *hv; HOST_WIDE_INT *hv;
int arith; int arith;
...@@ -443,21 +465,40 @@ rshift_double (l1, h1, count, prec, lv, hv, arith) ...@@ -443,21 +465,40 @@ rshift_double (l1, h1, count, prec, lv, hv, arith)
{ {
/* Shifting by the host word size is undefined according to the /* Shifting by the host word size is undefined according to the
ANSI standard, so we must handle this as a special case. */ ANSI standard, so we must handle this as a special case. */
*hv = signmask; *hv = 0;
*lv = signmask; *lv = 0;
} }
else if (count >= HOST_BITS_PER_WIDE_INT) else if (count >= HOST_BITS_PER_WIDE_INT)
{ {
*hv = signmask; *hv = 0;
*lv = ((signmask << (2 * HOST_BITS_PER_WIDE_INT - count - 1) << 1) *lv = (unsigned HOST_WIDE_INT) h1 >> (count - HOST_BITS_PER_WIDE_INT);
| ((unsigned HOST_WIDE_INT) h1 >> (count - HOST_BITS_PER_WIDE_INT)));
} }
else else
{ {
*hv = (unsigned HOST_WIDE_INT) h1 >> count;
*lv = ((l1 >> count) *lv = ((l1 >> count)
| ((unsigned HOST_WIDE_INT) h1 << (HOST_BITS_PER_WIDE_INT - count - 1) << 1)); | ((unsigned HOST_WIDE_INT) h1 << (HOST_BITS_PER_WIDE_INT - count - 1) << 1));
*hv = ((signmask << (HOST_BITS_PER_WIDE_INT - count)) }
| ((unsigned HOST_WIDE_INT) h1 >> count));
/* Zero / sign extend all bits that are beyond the precision. */
if (count >= (HOST_WIDE_INT)prec)
{
*hv = signmask;
*lv = signmask;
}
else if ((prec - count) >= 2 * HOST_BITS_PER_WIDE_INT)
;
else if ((prec - count) >= HOST_BITS_PER_WIDE_INT)
{
*hv &= ~((HOST_WIDE_INT) (-1) << (prec - count - HOST_BITS_PER_WIDE_INT));
*hv |= signmask << (prec - count - HOST_BITS_PER_WIDE_INT);
}
else
{
*hv = signmask;
*lv &= ~((unsigned HOST_WIDE_INT) (-1) << (prec - count));
*lv |= signmask << (prec - count);
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment