aboutsummaryrefslogtreecommitdiff
path: root/gcc/combine.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@bigpond.net.au>2005-12-02 06:25:13 +0000
committerAlan Modra <amodra@gcc.gnu.org>2005-12-02 16:55:13 +1030
commitc54293c6e8b6e06d1f6eb7501402edbdda93786c (patch)
tree2af83ee1343bba5a8ecee7a849655428c1e1b576 /gcc/combine.c
parent815eb8f0ca3d0b677b5694781ac9b2809e39cd08 (diff)
downloadgcc-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.c33
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