aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Earnshaw <rearnsha@gcc.gnu.org>2010-12-08 16:38:10 +0000
committerRichard Earnshaw <rearnsha@gcc.gnu.org>2010-12-08 16:38:10 +0000
commitc994a0ce087dba0ca4563130ba8840bf87c0d07c (patch)
tree2ee917e10b5c68f9fa9b353878f75bb3e19ba27d
parentb0ce92b4038fa29a390186c9eb03f1f1cfa8dd56 (diff)
downloadgcc-c994a0ce087dba0ca4563130ba8840bf87c0d07c.zip
gcc-c994a0ce087dba0ca4563130ba8840bf87c0d07c.tar.gz
gcc-c994a0ce087dba0ca4563130ba8840bf87c0d07c.tar.bz2
[multiple changes]
2010-12-08 Richard Earnshaw <rearnsha@arm.com> PR target/46631 * arm.c (thumb2_reorg): Also try to reduce <commutative_op> Rd, Rn, Rd into a 16-bit instruction. 2010-12-08 Wei Guozhi <carrot@google.com> PR target/46631 * gcc.target/arm/pr46631: New testcase. From-SVN: r167595
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/arm/arm.c23
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/arm/pr46631.c16
4 files changed, 50 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6428570..7f039b1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2010-12-08 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/46631
+ * arm.c (thumb2_reorg): Also try to reduce <commutative_op> Rd, Rn, Rd
+ into a 16-bit instruction.
+
2010-12-08 Michael Meissner <meissner@linux.vnet.ibm.com>
PR middle-end/42694
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 88c43e3..9d2c6dd 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -12183,6 +12183,7 @@ thumb2_reorg (void)
FOR_EACH_BB (bb)
{
rtx insn;
+
COPY_REG_SET (&live, DF_LR_OUT (bb));
df_simulate_initialize_backwards (bb, &live);
FOR_BB_INSNS_REVERSE (bb, insn)
@@ -12200,21 +12201,43 @@ thumb2_reorg (void)
rtx dst = XEXP (pat, 0);
rtx src = XEXP (pat, 1);
rtx op0 = XEXP (src, 0);
+ rtx op1 = (GET_RTX_CLASS (GET_CODE (src)) == RTX_COMM_ARITH
+ ? XEXP (src, 1) : NULL);
+
if (rtx_equal_p (dst, op0)
|| GET_CODE (src) == PLUS || GET_CODE (src) == MINUS)
{
rtx ccreg = gen_rtx_REG (CCmode, CC_REGNUM);
rtx clobber = gen_rtx_CLOBBER (VOIDmode, ccreg);
rtvec vec = gen_rtvec (2, pat, clobber);
+
+ PATTERN (insn) = gen_rtx_PARALLEL (VOIDmode, vec);
+ INSN_CODE (insn) = -1;
+ }
+ /* We can also handle a commutative operation where the
+ second operand matches the destination. */
+ else if (op1 && rtx_equal_p (dst, op1))
+ {
+ rtx ccreg = gen_rtx_REG (CCmode, CC_REGNUM);
+ rtx clobber = gen_rtx_CLOBBER (VOIDmode, ccreg);
+ rtvec vec;
+
+ src = copy_rtx (src);
+ XEXP (src, 0) = op1;
+ XEXP (src, 1) = op0;
+ pat = gen_rtx_SET (VOIDmode, dst, src);
+ vec = gen_rtvec (2, pat, clobber);
PATTERN (insn) = gen_rtx_PARALLEL (VOIDmode, vec);
INSN_CODE (insn) = -1;
}
}
}
+
if (NONDEBUG_INSN_P (insn))
df_simulate_one_insn_backwards (bb, insn, &live);
}
}
+
CLEAR_REG_SET (&live);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7a7f3be..313af80 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2010-12-08 Wei Guozhi <carrot@google.com>
+
+ PR target/46631
+ * gcc.target/arm/pr46631: New testcase.
+
2010-12-08 Michael Meissner <meissner@linux.vnet.ibm.com>
PR middle-end/42694
diff --git a/gcc/testsuite/gcc.target/arm/pr46631.c b/gcc/testsuite/gcc.target/arm/pr46631.c
new file mode 100644
index 0000000..6f6dc4e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr46631.c
@@ -0,0 +1,16 @@
+/* { dg-options "-mthumb -Os" } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-final { scan-assembler "ands" } } */
+
+struct S {
+ int bi_buf;
+ int bi_valid;
+};
+
+int tz (struct S* p, int bits, int value)
+{
+ if (p == 0) return 1;
+ p->bi_valid = bits;
+ p->bi_buf = value & ((1 << bits) - 1);
+ return 0;
+}