aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2004-11-11 17:03:36 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2004-11-11 17:03:36 +0000
commite1e2e653d7fdcf6c9f1cafb76fbb016c1879029d (patch)
treeefdb48c0d188106687c9363a2b7beb368a971779 /gcc
parent00803cd56f7d96060766249a23f3e89f778ad8f3 (diff)
downloadgcc-e1e2e653d7fdcf6c9f1cafb76fbb016c1879029d.zip
gcc-e1e2e653d7fdcf6c9f1cafb76fbb016c1879029d.tar.gz
gcc-e1e2e653d7fdcf6c9f1cafb76fbb016c1879029d.tar.bz2
re PR target/16457 (PowerPC - Combine two rldicr instructions into a single rlwinm.)
.: PR target/16457 * config/rs6000/rs6000.c (mask64_2_operand): Stub to call mask64_1or2_operand. (mask64_1or_2_operand): Broken out of mask64_2_operand, add flag to spot rlwinm opportunities. (and64_2_operand): Use mask_1or2_operand. * config/rs6000/rs6000.md (anddi3): Use rlwinm when possible. testsuite: PR target/16457 * gcc.dg/ppc-and-1: New From-SVN: r90481
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/config/rs6000/rs6000.c32
-rw-r--r--gcc/config/rs6000/rs6000.md16
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/gcc.dg/ppc-and-1.c20
5 files changed, 64 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index accb4de..21599f4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2004-11-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR target/16457
+ * config/rs6000/rs6000.c (mask64_2_operand): Stub to call
+ mask64_1or2_operand.
+ (mask64_1or2_operand): Broken out of mask64_2_operand, add flag
+ to spot rlwinm opportunities.
+ (and64_2_operand): Use mask_1or2_operand.
+ * config/rs6000/rs6000.md (anddi3): Use rlwinm when possible.
+
2004-11-11 Dorit Naishlos <dorit@il.ibm.com>
* tree-vectorizer.c (update_phi_nodes_for_guard): Call reverse_phis.
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 02b37fe..ada49ce 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -2708,23 +2708,26 @@ mask64_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
return 0;
}
-/* Like mask64_operand, but allow up to three transitions. This
- predicate is used by insn patterns that generate two rldicl or
- rldicr machine insns. */
-
-int
-mask64_2_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+static int
+mask64_1or2_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED,
+ bool allow_one)
{
if (GET_CODE (op) == CONST_INT)
{
HOST_WIDE_INT c, lsb;
-
+ bool one_ok;
+
c = INTVAL (op);
/* Disallow all zeros. */
if (c == 0)
return 0;
+ /* We can use a single rlwinm insn if no upper bits of C are set
+ AND there are zero, one or two transitions in the _whole_ of
+ C. */
+ one_ok = !(c & ~(HOST_WIDE_INT)0xffffffff);
+
/* We don't change the number of transitions by inverting,
so make sure we start with the LS bit zero. */
if (c & 1)
@@ -2748,6 +2751,9 @@ mask64_2_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
/* Erase second transition. */
c &= -lsb;
+ if (one_ok && !(allow_one || c))
+ return 0;
+
/* Find the third transition (if any). */
lsb = c & -c;
@@ -2757,6 +2763,14 @@ mask64_2_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
return 0;
}
+/* Like mask64_operand, but allow up to three transitions. This
+ predicate is used by insn patterns that generate two rldicl or
+ rldicr machine insns. */
+int mask64_2_operand (rtx op, enum machine_mode mode)
+{
+ return mask64_1or2_operand (op, mode, false);
+}
+
/* Generates shifts and masks for a pair of rldicl or rldicr insns to
implement ANDing by the mask IN. */
void
@@ -2846,9 +2860,9 @@ int
and64_2_operand (rtx op, enum machine_mode mode)
{
if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
- return gpc_reg_operand (op, mode) || mask64_2_operand (op, mode);
+ return gpc_reg_operand (op, mode) || mask64_1or2_operand (op, mode, true);
- return logical_operand (op, mode) || mask64_2_operand (op, mode);
+ return logical_operand (op, mode) || mask64_1or2_operand (op, mode, true);
}
/* Return 1 if the operand is either a non-special register or a
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 6b1c0b6..1902f5d 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -7197,19 +7197,20 @@
"")
(define_insn "anddi3"
- [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r")
- (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r")
- (match_operand:DI 2 "and64_2_operand" "?r,S,K,J,t")))
- (clobber (match_scratch:CC 3 "=X,X,x,x,X"))]
+ [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r")
+ (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r")
+ (match_operand:DI 2 "and64_2_operand" "?r,S,T,K,J,t")))
+ (clobber (match_scratch:CC 3 "=X,X,X,x,x,X"))]
"TARGET_POWERPC64"
"@
and %0,%1,%2
rldic%B2 %0,%1,0,%S2
+ rlwinm %0,%1,0,%m2,%M2
andi. %0,%1,%b2
andis. %0,%1,%u2
#"
- [(set_attr "type" "*,*,compare,compare,*")
- (set_attr "length" "4,4,4,4,8")])
+ [(set_attr "type" "*,*,*,compare,compare,*")
+ (set_attr "length" "4,4,4,4,4,8")])
(define_split
[(set (match_operand:DI 0 "gpc_reg_operand" "")
@@ -7227,10 +7228,9 @@
(and:DI (rotate:DI (match_dup 0)
(match_dup 6))
(match_dup 7)))]
- "
{
build_mask64_2_operands (operands[2], &operands[4]);
-}")
+})
(define_insn "*anddi3_internal2"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x,?y,?y,??y,??y,?y")
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 64da733..776f8e4 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2004-11-11 Nathan Sidwell <nathan@codesourcery.com>
+ PR target/16457
+ * gcc.dg/ppc-and-1: New
+
PR target/16796
* gcc.dg/ppc-mov-1.c: New.
diff --git a/gcc/testsuite/gcc.dg/ppc-and-1.c b/gcc/testsuite/gcc.dg/ppc-and-1.c
new file mode 100644
index 0000000..88a4b7a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ppc-and-1.c
@@ -0,0 +1,20 @@
+/* { dg-do compile { target powerpc64-*-* } } */
+/* { dg-options "-m64 -O2" } */
+
+/* { dg-final { scan-assembler "rlwinm \[0-9\]+,\[0-9\]+,0,0,30" } } */
+/* { dg-final { scan-assembler "rlwinm \[0-9\]+,\[0-9\]+,0,29,30" } } */
+/* { dg-final { scan-assembler-not "rldicr" } } */
+
+/* Origin:Pete Steinmetz <steinmtz@us.ibm.com> */
+
+/* PR 16457 - use rlwinm insn. */
+
+char *foo1 (char *p, unsigned int x)
+{
+ return p - (x & ~1);
+}
+
+char *foo2 (char *p, unsigned int x)
+{
+ return p - (x & 6);
+}