summaryrefslogtreecommitdiff
path: root/gcc/combine.c
diff options
context:
space:
mode:
authorbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>2010-08-03 23:48:52 +0000
committerbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>2010-08-03 23:48:52 +0000
commit422101e83a6c5901d04e9f438a51fb8c3afabb5f (patch)
treeecb6814d4696c9ee687838148c96dfdb407da3ab /gcc/combine.c
parent1c0efcbaa0b9ba8727cc9f3f1c45eff5e3276549 (diff)
downloadgcc-422101e83a6c5901d04e9f438a51fb8c3afabb5f.tar.gz
* simplify-rtx.c (simplify_binary_operation_1): Try to simplify away
NEG as operand of a MULT by merging it with the other operand. * combine.c (make_compound_operation): Use trunc_int_for_mode when generating a MULT with constant. Canonicalize PLUS and MINUS involving MULT. * config/arm/constraints.md (M): Examine only 32 bits of a HOST_WIDE_INT. * config/arm/predicates.md (power_of_two_operand): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@162849 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/combine.c')
-rw-r--r--gcc/combine.c73
1 files changed, 70 insertions, 3 deletions
diff --git a/gcc/combine.c b/gcc/combine.c
index 1991f347f7d..0725c862cf1 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -7110,13 +7110,79 @@ make_compound_operation (rtx x, enum rtx_code in_code)
&& INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT
&& INTVAL (XEXP (x, 1)) >= 0)
{
+ HOST_WIDE_INT count = INTVAL (XEXP (x, 1));
+ HOST_WIDE_INT multval = (HOST_WIDE_INT) 1 << count;
+
new_rtx = make_compound_operation (XEXP (x, 0), next_code);
- new_rtx = gen_rtx_MULT (mode, new_rtx,
- GEN_INT ((HOST_WIDE_INT) 1
- << INTVAL (XEXP (x, 1))));
+ if (GET_CODE (new_rtx) == NEG)
+ {
+ new_rtx = XEXP (new_rtx, 0);
+ multval = -multval;
+ }
+ multval = trunc_int_for_mode (multval, mode);
+ new_rtx = gen_rtx_MULT (mode, new_rtx, GEN_INT (multval));
}
break;
+ case PLUS:
+ lhs = XEXP (x, 0);
+ rhs = XEXP (x, 1);
+ lhs = make_compound_operation (lhs, MEM);
+ rhs = make_compound_operation (rhs, MEM);
+ if (GET_CODE (lhs) == MULT && GET_CODE (XEXP (lhs, 0)) == NEG
+ && SCALAR_INT_MODE_P (mode))
+ {
+ tem = simplify_gen_binary (MULT, mode, XEXP (XEXP (lhs, 0), 0),
+ XEXP (lhs, 1));
+ new_rtx = simplify_gen_binary (MINUS, mode, rhs, tem);
+ }
+ else if (GET_CODE (lhs) == MULT
+ && (CONST_INT_P (XEXP (lhs, 1)) && INTVAL (XEXP (lhs, 1)) < 0))
+ {
+ tem = simplify_gen_binary (MULT, mode, XEXP (lhs, 0),
+ simplify_gen_unary (NEG, mode,
+ XEXP (lhs, 1),
+ mode));
+ new_rtx = simplify_gen_binary (MINUS, mode, rhs, tem);
+ }
+ else
+ {
+ SUBST (XEXP (x, 0), lhs);
+ SUBST (XEXP (x, 1), rhs);
+ goto maybe_swap;
+ }
+ x = gen_lowpart (mode, new_rtx);
+ goto maybe_swap;
+
+ case MINUS:
+ lhs = XEXP (x, 0);
+ rhs = XEXP (x, 1);
+ lhs = make_compound_operation (lhs, MEM);
+ rhs = make_compound_operation (rhs, MEM);
+ if (GET_CODE (rhs) == MULT && GET_CODE (XEXP (rhs, 0)) == NEG
+ && SCALAR_INT_MODE_P (mode))
+ {
+ tem = simplify_gen_binary (MULT, mode, XEXP (XEXP (rhs, 0), 0),
+ XEXP (rhs, 1));
+ new_rtx = simplify_gen_binary (PLUS, mode, tem, lhs);
+ }
+ else if (GET_CODE (rhs) == MULT
+ && (CONST_INT_P (XEXP (rhs, 1)) && INTVAL (XEXP (rhs, 1)) < 0))
+ {
+ tem = simplify_gen_binary (MULT, mode, XEXP (rhs, 0),
+ simplify_gen_unary (NEG, mode,
+ XEXP (rhs, 1),
+ mode));
+ new_rtx = simplify_gen_binary (PLUS, mode, tem, lhs);
+ }
+ else
+ {
+ SUBST (XEXP (x, 0), lhs);
+ SUBST (XEXP (x, 1), rhs);
+ return x;
+ }
+ return gen_lowpart (mode, new_rtx);
+
case AND:
/* If the second operand is not a constant, we can't do anything
with it. */
@@ -7345,6 +7411,7 @@ make_compound_operation (rtx x, enum rtx_code in_code)
SUBST (XVECEXP (x, i, j), new_rtx);
}
+ maybe_swap:
/* If this is a commutative operation, the changes to the operands
may have made it noncanonical. */
if (COMMUTATIVE_ARITH_P (x)