backport: [multiple changes]

2012-07-06  Richard Guenther  <rguenther@suse.de>

	Backport from mainline
        2012-03-30  Richard Guenther  <rguenther@suse.de>

        PR middle-end/52786
        * double-int.c (rshift_double): Remove not
        needed cast.

	2012-03-28  Richard Guenther  <rguenther@suse.de>

	PR middle-end/50708
	* double-int.h (rshift_double): Remove.
	* double-int.c (lshift_double): Use absu_hwi to make count
	positive.
	(rshift_double): Make static, take unsigned count argument,
	remove handling of negative count argument.
	(double_int_rshift): Dispatch to lshift_double.

From-SVN: r189314
This commit is contained in:
Richard Guenther 2012-07-06 09:25:46 +00:00 committed by Richard Biener
parent 1ffb6a9714
commit 064f886a4b
3 changed files with 83 additions and 73 deletions

View File

@ -1,3 +1,22 @@
2012-07-06 Richard Guenther <rguenther@suse.de>
Backport from mainline
2012-03-30 Richard Guenther <rguenther@suse.de>
PR middle-end/52786
* double-int.c (rshift_double): Remove not needed
cast.
2012-03-28 Richard Guenther <rguenther@suse.de>
PR middle-end/50708
* double-int.h (rshift_double): Remove.
* double-int.c (lshift_double): Use absu_hwi to make count
positive.
(rshift_double): Make static, take unsigned count argument,
remove handling of negative count argument.
(double_int_rshift): Dispatch to lshift_double.
2012-07-06 Richard Guenther <rguenther@suse.de>
Backport from mainline

View File

@ -186,6 +186,68 @@ mul_double_with_sign (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
return (*hv < 0 ? ~(toplow & tophigh) : toplow | tophigh) != 0;
}
/* Shift the doubleword integer in L1, H1 right by COUNT places
keeping only PREC bits of result. ARITH nonzero specifies
arithmetic shifting; otherwise use logical shift.
Store the value as two `HOST_WIDE_INT' pieces in *LV and *HV. */
static void
rshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
unsigned HOST_WIDE_INT count, unsigned int prec,
unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv,
bool arith)
{
unsigned HOST_WIDE_INT signmask;
signmask = (arith
? -((unsigned HOST_WIDE_INT) h1 >> (HOST_BITS_PER_WIDE_INT - 1))
: 0);
if (SHIFT_COUNT_TRUNCATED)
count %= prec;
if (count >= 2 * HOST_BITS_PER_WIDE_INT)
{
/* Shifting by the host word size is undefined according to the
ANSI standard, so we must handle this as a special case. */
*hv = 0;
*lv = 0;
}
else if (count >= HOST_BITS_PER_WIDE_INT)
{
*hv = 0;
*lv = (unsigned HOST_WIDE_INT) h1 >> (count - HOST_BITS_PER_WIDE_INT);
}
else
{
*hv = (unsigned HOST_WIDE_INT) h1 >> count;
*lv = ((l1 >> count)
| ((unsigned HOST_WIDE_INT) h1
<< (HOST_BITS_PER_WIDE_INT - count - 1) << 1));
}
/* Zero / sign extend all bits that are beyond the precision. */
if (count >= 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);
}
}
/* Shift the doubleword integer in L1, H1 left by COUNT places
keeping only PREC bits of result.
Shift right if COUNT is negative.
@ -201,7 +263,7 @@ lshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
if (count < 0)
{
rshift_double (l1, h1, -count, prec, lv, hv, arith);
rshift_double (l1, h1, absu_hwi (count), prec, lv, hv, arith);
return;
}
@ -249,74 +311,6 @@ lshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
}
}
/* Shift the doubleword integer in L1, H1 right by COUNT places
keeping only PREC bits of result. Shift left if COUNT is negative.
ARITH nonzero specifies arithmetic shifting; otherwise use logical shift.
Store the value as two `HOST_WIDE_INT' pieces in *LV and *HV. */
void
rshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
HOST_WIDE_INT count, unsigned int prec,
unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv,
bool arith)
{
unsigned HOST_WIDE_INT signmask;
if (count < 0)
{
lshift_double (l1, h1, -count, prec, lv, hv, arith);
return;
}
signmask = (arith
? -((unsigned HOST_WIDE_INT) h1 >> (HOST_BITS_PER_WIDE_INT - 1))
: 0);
if (SHIFT_COUNT_TRUNCATED)
count %= prec;
if (count >= 2 * HOST_BITS_PER_WIDE_INT)
{
/* Shifting by the host word size is undefined according to the
ANSI standard, so we must handle this as a special case. */
*hv = 0;
*lv = 0;
}
else if (count >= HOST_BITS_PER_WIDE_INT)
{
*hv = 0;
*lv = (unsigned HOST_WIDE_INT) h1 >> (count - HOST_BITS_PER_WIDE_INT);
}
else
{
*hv = (unsigned HOST_WIDE_INT) h1 >> count;
*lv = ((l1 >> count)
| ((unsigned HOST_WIDE_INT) h1
<< (HOST_BITS_PER_WIDE_INT - count - 1) << 1));
}
/* 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);
}
}
/* Divide doubleword integer LNUM, HNUM by doubleword integer LDEN, HDEN
for a quotient (stored in *LQUO, *HQUO) and remainder (in *LREM, *HREM).
CODE is a tree code for a kind of division, one of
@ -895,7 +889,7 @@ double_int
double_int_rshift (double_int a, HOST_WIDE_INT count, unsigned int prec, bool arith)
{
double_int ret;
rshift_double (a.low, a.high, count, prec, &ret.low, &ret.high, arith);
lshift_double (a.low, a.high, -count, prec, &ret.low, &ret.high, arith);
return ret;
}

View File

@ -300,9 +300,6 @@ extern int mul_double_with_sign (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
extern void lshift_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
HOST_WIDE_INT, unsigned int,
unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, bool);
extern void rshift_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
HOST_WIDE_INT, unsigned int,
unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, bool);
extern int div_and_round_double (unsigned, int, unsigned HOST_WIDE_INT,
HOST_WIDE_INT, unsigned HOST_WIDE_INT,
HOST_WIDE_INT, unsigned HOST_WIDE_INT *,