diff mbox

[RS6000,5/7] Split mask64_2_operand rotates early

Message ID 20150624005356.GZ1723@bubble.grove.modra.org
State New
Headers show

Commit Message

Alan Modra June 24, 2015, 12:53 a.m. UTC
This gets rid of some patterns I added a long time ago for ANDs that
can be performed by two rotate and mask insns.

	* config/rs6000/preficates.md (and64_2_operand): Delete.
	(and_2rld_operand): Delete.
	* config/rs6000/rs6000.md (and<mode>3): Expand two insn
	mask_operand_wrap and mask64_2_operand AND/ROTATE.
	(andsi3_internal6): Delete.
	(anddi3_2rld, anddi3_2rld_dot, anddi3_2rld_dot2): Delete.
	* config/rs6000/rs6000.md (rs6000_rtx_costs): Cost AND constants
	matching mask64_2_operand.
diff mbox

Patch

diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index c408b0f..44eca2a 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -902,14 +902,6 @@ 
        (and (match_test "TARGET_POWERPC64 && mode == DImode")
 	    (match_operand 0 "mask64_operand"))))
 
-;; Like and_operand, but also match constants that can be implemented
-;; with two rldicl or rldicr insns.
-(define_predicate "and64_2_operand"
-  (ior (match_operand 0 "mask64_2_operand")
-       (if_then_else (match_test "fixed_regs[CR0_REGNO]")
-	 (match_operand 0 "gpc_reg_operand")
-	 (match_operand 0 "logical_operand"))))
-
 ;; Return 1 if the operand is either a non-special register or a
 ;; constant that can be used as the operand of a logical AND.
 (define_predicate "and_operand"
@@ -920,13 +912,6 @@ 
 	 (match_operand 0 "gpc_reg_operand")
 	 (match_operand 0 "logical_operand"))))
 
-;; Return 1 if the operand is a constant that can be used as the operand
-;; of a logical AND, implemented with two rld* insns, and it cannot be done
-;; using just one insn.
-(define_predicate "and_2rld_operand"
-  (and (match_operand 0 "and64_2_operand")
-       (not (match_operand 0 "and_operand"))))
-
 ;; Return 1 if the operand is either a logical operand or a short cint operand.
 (define_predicate "scc_eq_operand"
   (ior (match_operand 0 "logical_operand")
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index a4a72f3..941ad02 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -30688,7 +30688,10 @@  rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code,
 		    || outer_code == IOR
 		    || outer_code == XOR)
 		   && (INTVAL (x)
-		       & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
+		       & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0)
+	       || (outer_code == AND
+		   && mode == DImode
+		   && mask64_2_operand (x, mode)))
 	{
 	  *total = COSTS_N_INSNS (1);
 	  return true;
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index dafb04f..420441b 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -2906,9 +2906,53 @@ 
 	operands[2] = force_reg (<MODE>mode, operands[2]);
     }
 
-  if ((<MODE>mode == DImode && !and64_2_operand (operands[2], <MODE>mode))
-      || (<MODE>mode != DImode && !and_operand (operands[2], <MODE>mode)))
-    operands[2] = force_reg (<MODE>mode, operands[2]);
+  if (!and_operand (operands[2], <MODE>mode))
+    {
+      if (TARGET_POWERPC64
+	  && <MODE>mode == SImode && mask_operand_wrap (operands[2], SImode))
+	{
+	  /* Handle the PowerPC64 rlwinm corner case.  */
+	  rtx out[3];
+	  rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
+	  int mb = extract_MB (operands[2]);
+	  int me = extract_ME (operands[2]);
+	  out[0] = GEN_INT (me + 1);
+	  out[1] = GEN_INT (~((unsigned HOST_WIDE_INT) -1 << (33 + me - mb)));
+	  out[2] = GEN_INT (32 - (me + 1));
+	  emit_insn (gen_rtx_SET (tmp,
+				  gen_rtx_AND (SImode,
+					       gen_rtx_ROTATE (SImode,
+							       operands[1],
+							       out[0]),
+					       out[1])));
+	  emit_insn (gen_rtx_SET (operands[0],
+				  gen_rtx_ROTATE (SImode,
+						  tmp,
+						  out[2])));
+	  DONE;
+	}
+      if (TARGET_POWERPC64
+	  && <MODE>mode == DImode && mask64_2_operand (operands[2], DImode))
+	{
+	  rtx out[4];
+	  rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : operands[0];
+	  build_mask64_2_operands (operands[2], out);
+	  emit_insn (gen_rtx_SET (tmp,
+				  gen_rtx_AND (DImode,
+					       gen_rtx_ROTATE (DImode,
+							       operands[1],
+							       out[0]),
+					       out[1])));
+	  emit_insn (gen_rtx_SET (operands[0],
+				  gen_rtx_AND (DImode,
+					       gen_rtx_ROTATE (DImode,
+							       tmp,
+							       out[2]),
+					       out[3])));
+	  DONE;
+	}
+      operands[2] = force_reg (<MODE>mode, operands[2]);
+    }
 })
 
 
@@ -3097,31 +3141,6 @@ 
    (set_attr "length" "4,4,8,8")])
 
 
-;; Handle the PowerPC64 rlwinm corner case
-
-(define_insn_and_split "*andsi3_internal6"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-	(and:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-		(match_operand:SI 2 "mask_operand_wrap" "i")))]
-  "TARGET_POWERPC64"
-  "#"
-  "TARGET_POWERPC64"
-  [(set (match_dup 0)
-	(and:SI (rotate:SI (match_dup 1) (match_dup 3))
-		(match_dup 4)))
-   (set (match_dup 0)
-	(rotate:SI (match_dup 0) (match_dup 5)))]
-  "
-{
-  int mb = extract_MB (operands[2]);
-  int me = extract_ME (operands[2]);
-  operands[3] = GEN_INT (me + 1);
-  operands[5] = GEN_INT (32 - (me + 1));
-  operands[4] = GEN_INT (~((HOST_WIDE_INT) -1 << (33 + me - mb)));
-}"
-  [(set_attr "length" "8")])
-
-
 (define_expand "<code><mode>3"
   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
 	(iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
@@ -6017,87 +6036,6 @@ 
 		    (const_int 0)))]
   "")
 
-
-(define_insn_and_split "*anddi3_2rld"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
-	(and:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
-		(match_operand:DI 2 "and_2rld_operand" "n")))]
-  "TARGET_POWERPC64"
-  "#"
-  ""
-  [(set (match_dup 0)
-	(and:DI (rotate:DI (match_dup 1)
-			   (match_dup 4))
-		(match_dup 5)))
-   (set (match_dup 0)
-	(and:DI (rotate:DI (match_dup 0)
-			   (match_dup 6))
-		(match_dup 7)))]
-{
-  build_mask64_2_operands (operands[2], &operands[4]);
-}
-  [(set_attr "length" "8")])
-
-(define_insn_and_split "*anddi3_2rld_dot"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
-	(compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
-			    (match_operand:DI 2 "and_2rld_operand" "n,n"))
-		    (const_int 0)))
-   (clobber (match_scratch:DI 0 "=r,r"))]
-  "TARGET_64BIT && rs6000_gen_cell_microcode"
-  "@
-   #
-   #"
-  "&& reload_completed"
-  [(set (match_dup 0)
-	(and:DI (rotate:DI (match_dup 1)
-			   (match_dup 4))
-		(match_dup 5)))
-   (parallel [(set (match_dup 3)
-		   (compare:CC (and:DI (rotate:DI (match_dup 0)
-						  (match_dup 6))
-				       (match_dup 7))
-			       (const_int 0)))
-	      (clobber (match_dup 0))])]
-{
-  build_mask64_2_operands (operands[2], &operands[4]);
-}
-  [(set_attr "type" "two")
-   (set_attr "dot" "yes")
-   (set_attr "length" "8,12")])
-
-(define_insn_and_split "*anddi3_2rld_dot2"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
-	(compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
-			    (match_operand:DI 2 "and_2rld_operand" "n,n"))
-		    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
-	(and:DI (match_dup 1)
-		(match_dup 2)))]
-  "TARGET_64BIT && rs6000_gen_cell_microcode"
-  "@
-   #
-   #"
-  "&& reload_completed"
-  [(set (match_dup 0)
-	(and:DI (rotate:DI (match_dup 1)
-			   (match_dup 4))
-		(match_dup 5)))
-   (parallel [(set (match_dup 3)
-		   (compare:CC (and:DI (rotate:DI (match_dup 0)
-						  (match_dup 6))
-				       (match_dup 7))
-			       (const_int 0)))
-	      (set (match_dup 0)
-		   (and:DI (rotate:DI (match_dup 0)
-				      (match_dup 6))
-			   (match_dup 7)))])]
-{
-  build_mask64_2_operands (operands[2], &operands[4]);
-}
-  [(set_attr "type" "two")
-   (set_attr "dot" "yes")
-   (set_attr "length" "8,12")])
 
 ;; 128-bit logical operations expanders