Commit 7f251dee by Alexandre Oliva Committed by Alexandre Oliva

final.c (split_double): Right shift of negative values is not portable.

* final.c (split_double): Right shift of negative values is not
portable.

From-SVN: r34061
parent 6b48deee
2000-05-20 Alexandre Oliva <aoliva@cygnus.com> 2000-05-20 Alexandre Oliva <aoliva@cygnus.com>
* final.c (split_double): Right shift of negative values is not
portable.
* ifcvt.c (if_convert): Scan and kill dead code. * ifcvt.c (if_convert): Scan and kill dead code.
* emit-rtl.c (unshare_all_rtl): Store the copied rtx. * emit-rtl.c (unshare_all_rtl): Store the copied rtx.
...@@ -3923,25 +3923,50 @@ split_double (value, first, second) ...@@ -3923,25 +3923,50 @@ split_double (value, first, second)
/* In this case the CONST_INT holds both target words. /* In this case the CONST_INT holds both target words.
Extract the bits from it into two word-sized pieces. Extract the bits from it into two word-sized pieces.
Sign extend each half to HOST_WIDE_INT. */ Sign extend each half to HOST_WIDE_INT. */
rtx low, high; unsigned HOST_WIDE_INT low, high;
/* On machines where HOST_BITS_PER_WIDE_INT == BITS_PER_WORD unsigned HOST_WIDE_INT mask, sign_bit, sign_extend;
the shift below will cause a compiler warning, even though
this code won't be executed. So put the shift amounts in /* Set sign_bit to the most significant bit of a word. */
variables to avoid the warning. */ sign_bit = 1;
int rshift = HOST_BITS_PER_WIDE_INT - BITS_PER_WORD; sign_bit <<= BITS_PER_WORD - 1;
int lshift = HOST_BITS_PER_WIDE_INT - 2 * BITS_PER_WORD;
/* Set mask so that all bits of the word are set. We could
low = GEN_INT ((INTVAL (value) << rshift) >> rshift); have used 1 << BITS_PER_WORD instead of basing the
high = GEN_INT ((INTVAL (value) << lshift) >> rshift); calculation on sign_bit. However, on machines where
HOST_BITS_PER_WIDE_INT == BITS_PER_WORD, it could cause a
compiler warning, even though the code would never be
executed. */
mask = sign_bit << 1;
mask--;
/* Set sign_extend as any remaining bits. */
sign_extend = ~mask;
/* Pick the lower word and sign-extend it. */
low = INTVAL (value);
low &= mask;
if (low & sign_bit)
low |= sign_extend;
/* Pick the higher word, shifted to the least significant
bits, and sign-extend it. */
high = INTVAL (value);
high >>= BITS_PER_WORD - 1;
high >>= 1;
high &= mask;
if (high & sign_bit)
high |= sign_extend;
/* Store the words in the target machine order. */
if (WORDS_BIG_ENDIAN) if (WORDS_BIG_ENDIAN)
{ {
*first = high; *first = GEN_INT (high);
*second = low; *second = GEN_INT (low);
} }
else else
{ {
*first = low; *first = GEN_INT (low);
*second = high; *second = GEN_INT (high);
} }
} }
else else
......
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