Hello,
I am tracking a bug and find the lshift_value function in
expmed.c questionable (both head and gcc 4.4).
Suppose HOST_BITS_PER_WIDE_INT = 32, bitpos = 0
and bitsize = 33, the following expression is wrong
high = (v >> (HOST_BITS_PER_WIDE_INT - bitpos))
& ((1 << (bitpos + bitsize - HOST_BITS_PER_WIDE_INT)) - 1);
v >> 32 bits on a 32-bit machine is undefined. On i386,
v >> 32 results in v, which is not intention of the function.
Cheers,
Bingfeng Mei
static rtx
lshift_value (enum machine_mode mode, rtx value, int bitpos, int bitsize)
{
unsigned HOST_WIDE_INT v = INTVAL (value);
HOST_WIDE_INT low, high;
if (bitsize < HOST_BITS_PER_WIDE_INT)
v &= ~((HOST_WIDE_INT) -1 << bitsize);
if (bitpos < HOST_BITS_PER_WIDE_INT)
{
low = v << bitpos;
/* Obtain value by shifting and set zeros for remaining part*/
if((bitpos + bitsize) > HOST_BITS_PER_WIDE_INT)
high = (v >> (HOST_BITS_PER_WIDE_INT - bitpos))
& ((1 << (bitpos + bitsize - HOST_BITS_PER_WIDE_INT)) - 1);
else
high = 0;
}
else
{
low = 0;
high = v << (bitpos - HOST_BITS_PER_WIDE_INT);
}
return immed_double_const (low, high, mode);
}