diff options
author | Alan Modra <amodra@bigpond.net.au> | 2005-12-02 06:25:13 +0000 |
---|---|---|
committer | Alan Modra <amodra@gcc.gnu.org> | 2005-12-02 16:55:13 +1030 |
commit | c54293c6e8b6e06d1f6eb7501402edbdda93786c (patch) | |
tree | 2af83ee1343bba5a8ecee7a849655428c1e1b576 /gcc/combine.c | |
parent | 815eb8f0ca3d0b677b5694781ac9b2809e39cd08 (diff) | |
download | gcc-c54293c6e8b6e06d1f6eb7501402edbdda93786c.zip gcc-c54293c6e8b6e06d1f6eb7501402edbdda93786c.tar.gz gcc-c54293c6e8b6e06d1f6eb7501402edbdda93786c.tar.bz2 |
re PR target/21017 (ppc 64bit target not using rlwinm)
PR target/21017
* combine.c (simplify_logical <IOR>): Simplify more patterns to
rotates.
From-SVN: r107873
Diffstat (limited to 'gcc/combine.c')
-rw-r--r-- | gcc/combine.c | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/gcc/combine.c b/gcc/combine.c index 08cacab..b13ea86 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -5597,7 +5597,7 @@ simplify_logical (rtx x) enum machine_mode mode = GET_MODE (x); rtx op0 = XEXP (x, 0); rtx op1 = XEXP (x, 1); - rtx reversed; + rtx tmp, reversed; switch (GET_CODE (x)) { @@ -5724,16 +5724,37 @@ simplify_logical (rtx x) /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the mode size to (rotate A CX). */ - if (((GET_CODE (op0) == ASHIFT && GET_CODE (op1) == LSHIFTRT) - || (GET_CODE (op1) == ASHIFT && GET_CODE (op0) == LSHIFTRT)) + if (GET_CODE (op1) == ASHIFT + || GET_CODE (op1) == SUBREG) + tmp = op1, op1 = op0, op0 = tmp; + + if (GET_CODE (op0) == ASHIFT && GET_CODE (op1) == LSHIFTRT && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0)) && GET_CODE (XEXP (op0, 1)) == CONST_INT && GET_CODE (XEXP (op1, 1)) == CONST_INT && (INTVAL (XEXP (op0, 1)) + INTVAL (XEXP (op1, 1)) == GET_MODE_BITSIZE (mode))) - return gen_rtx_ROTATE (mode, XEXP (op0, 0), - (GET_CODE (op0) == ASHIFT - ? XEXP (op0, 1) : XEXP (op1, 1))); + return gen_rtx_ROTATE (mode, XEXP (op1, 0), XEXP (op0, 1)); + + /* Same, but for ashift that has been "simplified" to a wider mode + by simplify_shift_const. */ + + if (GET_CODE (op0) == SUBREG + && GET_CODE (SUBREG_REG (op0)) == ASHIFT + && GET_CODE (op1) == LSHIFTRT + && GET_CODE (XEXP (op1, 0)) == SUBREG + && GET_MODE (op0) == GET_MODE (XEXP (op1, 0)) + && SUBREG_BYTE (op0) == SUBREG_BYTE (XEXP (op1, 0)) + && (GET_MODE_SIZE (GET_MODE (op0)) + < GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0)))) + && rtx_equal_p (XEXP (SUBREG_REG (op0), 0), + SUBREG_REG (XEXP (op1, 0))) + && GET_CODE (XEXP (SUBREG_REG (op0), 1)) == CONST_INT + && GET_CODE (XEXP (op1, 1)) == CONST_INT + && (INTVAL (XEXP (SUBREG_REG (op0), 1)) + INTVAL (XEXP (op1, 1)) + == GET_MODE_BITSIZE (mode))) + return gen_rtx_ROTATE (mode, XEXP (op1, 0), + XEXP (SUBREG_REG (op0), 1)); /* If OP0 is (ashiftrt (plus ...) C), it might actually be a (sign_extend (plus ...)). If so, OP1 is a CONST_INT, and the PLUS |