diff options
author | bernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-08-03 23:48:52 +0000 |
---|---|---|
committer | bernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-08-03 23:48:52 +0000 |
commit | 422101e83a6c5901d04e9f438a51fb8c3afabb5f (patch) | |
tree | ecb6814d4696c9ee687838148c96dfdb407da3ab /gcc/combine.c | |
parent | 1c0efcbaa0b9ba8727cc9f3f1c45eff5e3276549 (diff) | |
download | gcc-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.c | 73 |
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) |