Commit 9fa6d012 by Torbjorn Granlund

(force_to_mode, case PLUS): Sign extend masks that are negative in OP_MODE.

(simplify_and_const_int): Sign-extend constants when they have the
most significant bit set for the target.
(merge_outer_ops): Likewise.
(simplify_shift_const): Likewise.

From-SVN: r9310
parent ad89d6f6
...@@ -5795,13 +5795,26 @@ force_to_mode (x, mode, mask, reg, just_select) ...@@ -5795,13 +5795,26 @@ force_to_mode (x, mode, mask, reg, just_select)
low-order bits (as in an alignment operation) and FOO is already low-order bits (as in an alignment operation) and FOO is already
aligned to that boundary, mask C1 to that boundary as well. aligned to that boundary, mask C1 to that boundary as well.
This may eliminate that PLUS and, later, the AND. */ This may eliminate that PLUS and, later, the AND. */
if (GET_CODE (XEXP (x, 1)) == CONST_INT
&& exact_log2 (- mask) >= 0 {
&& (nonzero_bits (XEXP (x, 0), mode) & ~ mask) == 0 int width = GET_MODE_BITSIZE (mode);
&& (INTVAL (XEXP (x, 1)) & ~ mask) != 0) unsigned HOST_WIDE_INT smask = mask;
return force_to_mode (plus_constant (XEXP (x, 0),
INTVAL (XEXP (x, 1)) & mask), /* If MODE is narrower than HOST_WIDE_INT and mask is a negative
mode, mask, reg, next_select); number, sign extend it. */
if (width < HOST_BITS_PER_WIDE_INT
&& (smask & ((HOST_WIDE_INT) 1 << (width - 1))) != 0)
smask |= (HOST_WIDE_INT) -1 << width;
if (GET_CODE (XEXP (x, 1)) == CONST_INT
&& exact_log2 (- smask) >= 0
&& (nonzero_bits (XEXP (x, 0), mode) & ~ mask) == 0
&& (INTVAL (XEXP (x, 1)) & ~ mask) != 0)
return force_to_mode (plus_constant (XEXP (x, 0),
INTVAL (XEXP (x, 1)) & mask),
mode, mask, reg, next_select);
}
/* ... fall through ... */ /* ... fall through ... */
...@@ -6598,6 +6611,7 @@ simplify_and_const_int (x, mode, varop, constop) ...@@ -6598,6 +6611,7 @@ simplify_and_const_int (x, mode, varop, constop)
unsigned HOST_WIDE_INT constop; unsigned HOST_WIDE_INT constop;
{ {
unsigned HOST_WIDE_INT nonzero; unsigned HOST_WIDE_INT nonzero;
int width = GET_MODE_BITSIZE (mode);
int i; int i;
/* Simplify VAROP knowing that we will be only looking at some of the /* Simplify VAROP knowing that we will be only looking at some of the
...@@ -6615,6 +6629,19 @@ simplify_and_const_int (x, mode, varop, constop) ...@@ -6615,6 +6629,19 @@ simplify_and_const_int (x, mode, varop, constop)
nonzero = nonzero_bits (varop, mode) & GET_MODE_MASK (mode); nonzero = nonzero_bits (varop, mode) & GET_MODE_MASK (mode);
/* If this would be an entire word for the target, but is not for
the host, then sign-extend on the host so that the number will look
the same way on the host that it would on the target.
For example, when building a 64 bit alpha hosted 32 bit sparc
targeted compiler, then we want the 32 bit unsigned value -1 to be
represented as a 64 bit value -1, and not as 0x00000000ffffffff.
The later confuses the sparc backend. */
if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT && BITS_PER_WORD == width
&& (nonzero & ((HOST_WIDE_INT) 1 << (width - 1))))
nonzero |= ((HOST_WIDE_INT) (-1) << width);
/* Turn off all bits in the constant that are known to already be zero. /* Turn off all bits in the constant that are known to already be zero.
Thus, if the AND isn't needed at all, we will have CONSTOP == NONZERO_BITS Thus, if the AND isn't needed at all, we will have CONSTOP == NONZERO_BITS
which is tested below. */ which is tested below. */
...@@ -7408,6 +7435,7 @@ merge_outer_ops (pop0, pconst0, op1, const1, mode, pcomp_p) ...@@ -7408,6 +7435,7 @@ merge_outer_ops (pop0, pconst0, op1, const1, mode, pcomp_p)
{ {
enum rtx_code op0 = *pop0; enum rtx_code op0 = *pop0;
HOST_WIDE_INT const0 = *pconst0; HOST_WIDE_INT const0 = *pconst0;
int width = GET_MODE_BITSIZE (mode);
const0 &= GET_MODE_MASK (mode); const0 &= GET_MODE_MASK (mode);
const1 &= GET_MODE_MASK (mode); const1 &= GET_MODE_MASK (mode);
...@@ -7497,6 +7525,19 @@ merge_outer_ops (pop0, pconst0, op1, const1, mode, pcomp_p) ...@@ -7497,6 +7525,19 @@ merge_outer_ops (pop0, pconst0, op1, const1, mode, pcomp_p)
else if (const0 == GET_MODE_MASK (mode) && op0 == AND) else if (const0 == GET_MODE_MASK (mode) && op0 == AND)
op0 = NIL; op0 = NIL;
/* If this would be an entire word for the target, but is not for
the host, then sign-extend on the host so that the number will look
the same way on the host that it would on the target.
For example, when building a 64 bit alpha hosted 32 bit sparc
targeted compiler, then we want the 32 bit unsigned value -1 to be
represented as a 64 bit value -1, and not as 0x00000000ffffffff.
The later confuses the sparc backend. */
if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT && BITS_PER_WORD == width
&& (const0 & ((HOST_WIDE_INT) 1 << (width - 1))))
const0 |= ((HOST_WIDE_INT) (-1) << width);
*pop0 = op0; *pop0 = op0;
*pconst0 = const0; *pconst0 = const0;
...@@ -8179,7 +8220,24 @@ simplify_shift_const (x, code, result_mode, varop, count) ...@@ -8179,7 +8220,24 @@ simplify_shift_const (x, code, result_mode, varop, count)
if (outer_op != NIL) if (outer_op != NIL)
{ {
if (GET_MODE_BITSIZE (result_mode) < HOST_BITS_PER_WIDE_INT) if (GET_MODE_BITSIZE (result_mode) < HOST_BITS_PER_WIDE_INT)
outer_const &= GET_MODE_MASK (result_mode); {
int width = GET_MODE_BITSIZE (result_mode);
outer_const &= GET_MODE_MASK (result_mode);
/* If this would be an entire word for the target, but is not for
the host, then sign-extend on the host so that the number will
look the same way on the host that it would on the target.
For example, when building a 64 bit alpha hosted 32 bit sparc
targeted compiler, then we want the 32 bit unsigned value -1 to be
represented as a 64 bit value -1, and not as 0x00000000ffffffff.
The later confuses the sparc backend. */
if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT && BITS_PER_WORD == width
&& (outer_const & ((HOST_WIDE_INT) 1 << (width - 1))))
outer_const |= ((HOST_WIDE_INT) (-1) << width);
}
if (outer_op == AND) if (outer_op == AND)
x = simplify_and_const_int (NULL_RTX, result_mode, x, outer_const); x = simplify_and_const_int (NULL_RTX, result_mode, x, outer_const);
......
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