This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PowerPC] Fix PR23649 gcc.dg/ppc-and-1.c failure


gcc.dg/ppc-and-1.c has been failing on powerpc64-linux since

2005-06-11  Geoffrey Keating  <geoffk@apple.com>
	* config/rs6000/predicates.md
[snip]
	(mask_operand): Handle DImode.
	(mask64_operand): Delete.
[snip]

Most of this patch is a fairly straight-forward reversion of the
2005-06-11 mask_operand changes, and reimplementing Nathan's 2004-11-11
patch in a way that allows mask64_1or2_operand to move from rs6000.c to
predicates.md (as the original mask64_2_operand and a tweak to
mask_operand) (*).  In addition, I added "rlwinm." variants for
anddi3_internal2 and anddi3_internal3 insns.  Besides generating better
code (actually fixing a regression introduced 2004-11-11 for these
insns), this makes usage of the 't' constraint consistent.  't'
shouldn't allow a match for anything that matches any of the other
anddi3 operand[2] constraints, otherwise the insn will be unnecessarily
split (which is why we weren't using the rlwinm variant after Geoff's
patch).  If 't' is so changed, then the other insns that use a 't'
constraint also need a 'T' variant, or reload will force constants that
match 'T' into a register.  Another minor tweak was to make the
anddi3_internal2 and anddi3_internal3 splitters test TARGET_64BIT rather
than TARGET_POWERPC64, since that is what the insns use.  Of course,
these splitters also need their predicates tweaked in line with the 't'
constraint change.  Note that Geoff's merge of and64_operand with
and_operand is still effective, so and_operand in one of the splitters
and in sync.md will still work for both SImode and DImode.

Bootstrap and regression test powerpc-linux and powerpc64-linux in
progress.  OK to apply assuming no regressions?

*) I had to look at mask64_1or2_operand at least twice to verify that
anddi3 was correct prior to Geoff's change.  mask64_1or2_operand
was used in the add64_2_operand predicate to pass all masks that might
be implemented as two rldicl or rldicr insns, and in the 't' constraint
to pass those masks *minus* the set of valid 64-bit mode rlwinm masks.
I think it's a lot clearer to exclude the rlwinm masks by using
"&& !mask_operand (op, DImode)" and tweak mask_operand for DImode.

:ADDPATCH <target(powerpc64)>:

	PR target/23649
	* config/rs6000/predicates.md (mask_operand): Only handle rlwinm masks.
	(mask64_operand): Reinstate code prior to 2005-06-11 change.
	(mask64_2_operand): Reinstate code prior to 2004-11-11 change.
	(and64_2_operand): Tweak to use predicate.
	(and_operand): Adjust for mask_operand changes.
	* config/rs6000/rs6000.c (num_insns_constant): Revert 2005-06-11.
	(print_operand): Likewise.
	(rs6000_rtx_costs): Pass mode to mask_operand and use mask64_operand.
	(mask64_1or2_operand): Delete.
	* rs6000/rs6000-protos.h (mask64_1or2_operand): Delete.
	* config/rs6000/rs6000.h (EXTRA_CONSTRAINT <S>): Revert 2005-06-11.
	(EXTRA_CONSTRAINT <T>): Pass operand mode to predicate.
	(EXTRA_CONSTRAINT <t>): Disallow mask64_operand matches.
	* config/rs6000/rs6000.md (andsi3_internal3 split): Revert 2005-06-11.
	(rotldi3_internal4): Likewise.
	(rotldi3_internal5, rotldi3_internal5 split): Likewise.
	(rotldi3_internal6, rotldi3_internal6 split): Likewise.
	(ashldi3_internal7): Likewise.
	(ashldi3_internal8, ashldi3_internal8 split): Likewise.
	(ashldi3_internal, ashldi3_internal9 split): Likewise.
	(anddi3 split): Don't match mask64_operand.
	(anddi3_internal2): Add rlwinm.  Modify 't' splitter predicate.
	(anddi3_internal3): Add rlwinm.  Use and64_2_operand in non-cr0
	splitter and match TARGET_64BIT not TARGET_POWERPC64.  Modify
	't' splitter predicate.
	(movdi_internal64 + 2): Revert 2005-06-11 change.


diff -urp -xCVS -x'*~' -x'.#*' -xTAGS -xautom4te.cache -x'*.info' gcc-virgin/gcc/config/rs6000/predicates.md gcc-current/gcc/config/rs6000/predicates.md
--- gcc-virgin/gcc/config/rs6000/predicates.md	2005-08-24 09:59:52.000000000 +0930
+++ gcc-current/gcc/config/rs6000/predicates.md	2005-08-31 22:16:28.000000000 +0930
@@ -452,14 +452,10 @@
        (and (not (match_operand 0 "logical_operand"))
 	    (match_operand 0 "reg_or_logical_cint_operand"))))
 
-;; For SImode, return 1 if op is a constant that can be encoded in a
-;; 32-bit mask (no more than two 1->0 or 0->1 transitions).  Reject
-;; all ones and all zeros, since these should have been optimized away
-;; and confuse the making of MB and ME.
-;; For DImode, return 1 if the operand is a constant that is a
-;; PowerPC64 mask (no more than one 1->0 or 0->1 transitions).  Reject
-;; all zeros, since zero should have been optimized away and confuses
-;; the making of MB and ME.
+;; Return 1 if op is a constant that can be encoded in a 32-bit mask,
+;; suitable for use with rlwinm (no more than two 1->0 or 0->1
+;; transitions).  Reject all ones and all zeros, since these should have
+;; been optimized away and confuse the making of MB and ME.
 (define_predicate "mask_operand"
   (match_code "const_int")
 {
@@ -467,34 +463,38 @@
 
   c = INTVAL (op);
 
-  /* Fail in 64-bit mode if the mask wraps around because the upper
-     32-bits of the mask will all be 1s, contrary to GCC's internal view.  */
-  if (mode == SImode && TARGET_POWERPC64 && (c & 0x80000001) == 0x80000001)
-    return 0;
+  if (TARGET_POWERPC64)
+    {
+      /* Fail if the mask is not 32-bit.  */
+      if (mode == DImode && (c & ~(unsigned HOST_WIDE_INT) 0xffffffff) != 0)
+	return 0;
 
-  /* Reject all zeros or all ones in 32-bit mode.  */
-  if (c == 0 || (mode == SImode && c == -1))
-    return 0;
+      /* Fail if the mask wraps around because the upper 32-bits of the
+	 mask will all be 1s, contrary to GCC's internal view.  */
+      if ((c & 0x80000001) == 0x80000001)
+	return 0;
+    }
 
   /* We don't change the number of transitions by inverting,
      so make sure we start with the LS bit zero.  */
   if (c & 1)
     c = ~c;
 
+  /* Reject all zeros or all ones.  */
+  if (c == 0)
+    return 0;
+
   /* Find the first transition.  */
   lsb = c & -c;
 
-  if (mode == SImode)
-    {
-      /* Invert to look for a second transition.  */
-      c = ~c;
+  /* Invert to look for a second transition.  */
+  c = ~c;
 
-      /* Erase first transition.  */
-      c &= -lsb;
+  /* Erase first transition.  */
+  c &= -lsb;
 
-      /* Find the second transition (if any).  */
-      lsb = c & -c;
-    }
+  /* Find the second transition (if any).  */
+  lsb = c & -c;
 
   /* Match if all the bits above are 1's (or c is zero).  */
   return c == -lsb;
@@ -522,20 +522,81 @@
   return c == -lsb;
 })
 
-;; Like mask_operand, but allow up to three transitions.  This
+;; Return 1 if the operand is a constant that is a PowerPC64 mask
+;; suitable for use with rldicl or rldicr (no more than one 1->0 or 0->1
+;; transition).  Reject all zeros, since zero should have been
+;; optimized away and confuses the making of MB and ME.
+(define_predicate "mask64_operand"
+  (match_code "const_int")
+{
+  HOST_WIDE_INT c, lsb;
+
+  c = INTVAL (op);
+
+  /* Reject all zeros.  */
+  if (c == 0)
+    return 0;
+
+  /* We don't change the number of transitions by inverting,
+     so make sure we start with the LS bit zero.  */
+  if (c & 1)
+    c = ~c;
+
+  /* Find the first transition.  */
+  lsb = c & -c;
+
+  /* Match if all the bits above are 1's (or c is zero).  */
+  return c == -lsb;
+})
+
+;; Like mask64_operand, but allow up to three transitions.  This
 ;; predicate is used by insn patterns that generate two rldicl or
 ;; rldicr machine insns.
 (define_predicate "mask64_2_operand"
   (match_code "const_int")
 {
-  return mask64_1or2_operand (op, mode, false);
+  HOST_WIDE_INT c, lsb;
+
+  c = INTVAL (op);
+
+  /* Disallow all zeros.  */
+  if (c == 0)
+    return 0;
+
+  /* We don't change the number of transitions by inverting,
+     so make sure we start with the LS bit zero.  */
+  if (c & 1)
+    c = ~c;
+
+  /* Find the first transition.  */
+  lsb = c & -c;
+
+  /* Invert to look for a second transition.  */
+  c = ~c;
+
+  /* Erase first transition.  */
+  c &= -lsb;
+
+  /* Find the second transition.  */
+  lsb = c & -c;
+
+  /* Invert to look for a third transition.  */
+  c = ~c;
+
+  /* Erase second transition.  */
+  c &= -lsb;
+
+  /* Find the third transition (if any).  */
+  lsb = c & -c;
+
+  /* Match if all the bits above are 1's (or c is zero).  */
+  return c == -lsb;
 })
 
 ;; Like and_operand, but also match constants that can be implemented
 ;; with two rldicl or rldicr insns.
 (define_predicate "and64_2_operand"
-  (ior (and (match_code "const_int")
-	    (match_test "mask64_1or2_operand (op, mode, true)"))
+  (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"))))
@@ -544,9 +605,11 @@
 ;; constant that can be used as the operand of a logical AND.
 (define_predicate "and_operand"
   (ior (match_operand 0 "mask_operand")
-       (if_then_else (match_test "fixed_regs[CR0_REGNO]")
-	 (match_operand 0 "gpc_reg_operand")
-	 (match_operand 0 "logical_operand"))))
+       (ior (and (match_test "TARGET_POWERPC64 && mode == DImode")
+		 (match_operand 0 "mask64_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 logical operand or a short cint operand.
 (define_predicate "scc_eq_operand"
diff -urp -xCVS -x'*~' -x'.#*' -xTAGS -xautom4te.cache -x'*.info' gcc-virgin/gcc/config/rs6000/rs6000-protos.h gcc-current/gcc/config/rs6000/rs6000-protos.h
--- gcc-virgin/gcc/config/rs6000/rs6000-protos.h	2005-08-23 12:07:46.000000000 +0930
+++ gcc-current/gcc/config/rs6000/rs6000-protos.h	2005-08-31 23:16:55.000000000 +0930
@@ -34,7 +34,6 @@ extern void rs6000_va_start (tree, rtx);
 
 extern int easy_vector_same (rtx, enum machine_mode);
 extern int easy_vector_splat_const (int, enum machine_mode);
-extern int mask64_1or2_operand (rtx, enum machine_mode, bool);
 extern bool macho_lo_sum_memory_operand (rtx, enum machine_mode);
 extern int num_insns_constant (rtx, enum machine_mode);
 extern int num_insns_constant_wide (HOST_WIDE_INT);
diff -urp -xCVS -x'*~' -x'.#*' -xTAGS -xautom4te.cache -x'*.info' gcc-virgin/gcc/config/rs6000/rs6000.c gcc-current/gcc/config/rs6000/rs6000.c
--- gcc-virgin/gcc/config/rs6000/rs6000.c	2005-08-28 08:57:10.000000000 +0930
+++ gcc-current/gcc/config/rs6000/rs6000.c	2005-08-30 19:44:45.000000000 +0930
@@ -1980,7 +1980,7 @@ num_insns_constant (rtx op, enum machine
     case CONST_INT:
 #if HOST_BITS_PER_WIDE_INT == 64
       if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
-	  && mask_operand (op, mode))
+	  && mask64_operand (op, mode))
 	return 2;
       else
 #endif
@@ -2022,7 +2022,7 @@ num_insns_constant (rtx op, enum machine
 		|| (high == -1 && low < 0))
 	      return num_insns_constant_wide (low);
 
-	    else if (mask_operand (op, mode))
+	    else if (mask64_operand (op, mode))
 	      return 2;
 
 	    else if (low == 0)
@@ -2346,61 +2346,6 @@ rs6000_expand_vector_extract (rtx target
   emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
 }
 
-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)
-	c = ~c;
-
-      /* Find the first transition.  */
-      lsb = c & -c;
-
-      /* Invert to look for a second transition.  */
-      c = ~c;
-
-      /* Erase first transition.  */
-      c &= -lsb;
-
-      /* Find the second transition.  */
-      lsb = c & -c;
-
-      /* Invert to look for a third transition.  */
-      c = ~c;
-
-      /* Erase second transition.  */
-      c &= -lsb;
-
-      if (one_ok && !(allow_one || c))
-	return 0;
-
-      /* Find the third transition (if any).  */
-      lsb = c & -c;
-
-      /* Match if all the bits above are 1's (or c is zero).  */
-      return c == -lsb;
-    }
-  return 0;
-}
-
 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
    implement ANDing by the mask IN.  */
 void
@@ -10379,7 +10338,7 @@ print_operand (FILE *file, rtx x, int co
       /* PowerPC64 mask position.  All 0's is excluded.
 	 CONST_INT 32-bit mask is considered sign-extended so any
 	 transition must occur within the CONST_INT, not on the boundary.  */
-      if (! mask_operand (x, DImode))
+      if (! mask64_operand (x, DImode))
 	output_operand_lossage ("invalid %%S value");
 
       uval = INT_LOWPART (x);
@@ -18235,7 +18194,9 @@ rs6000_rtx_costs (rtx x, int code, int o
 	      && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'K')
 		  || (CONST_OK_FOR_LETTER_P (INTVAL (x),
 					     mode == SImode ? 'L' : 'J'))
-		  || mask_operand (x, VOIDmode)))
+		  || mask_operand (x, mode)
+		  || (mode == DImode
+		      && mask64_operand (x, DImode))))
 	  || ((outer_code == IOR || outer_code == XOR)
 	      && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'K')
 		  || (CONST_OK_FOR_LETTER_P (INTVAL (x),
@@ -18287,7 +18248,8 @@ rs6000_rtx_costs (rtx x, int code, int o
 	  && ((outer_code == AND
 	       && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'K')
 		   || CONST_OK_FOR_LETTER_P (INTVAL (x), 'L')
-		   || mask_operand (x, DImode)))
+		   || mask_operand (x, DImode)
+		   || mask64_operand (x, DImode)))
 	      || ((outer_code == IOR || outer_code == XOR)
 		  && CONST_DOUBLE_HIGH (x) == 0
 		  && (CONST_DOUBLE_LOW (x)
diff -urp -xCVS -x'*~' -x'.#*' -xTAGS -xautom4te.cache -x'*.info' gcc-virgin/gcc/config/rs6000/rs6000.h gcc-current/gcc/config/rs6000/rs6000.h
--- gcc-virgin/gcc/config/rs6000/rs6000.h	2005-08-16 23:26:52.000000000 +0930
+++ gcc-current/gcc/config/rs6000/rs6000.h	2005-08-31 22:17:38.000000000 +0930
@@ -1105,26 +1133,28 @@ enum reg_class
 
    'Q' means that is a memory operand that is just an offset from a reg.
    'R' is for AIX TOC entries.
-   'S' is a constant that can be placed into a 64-bit mask operand
-   'T' is a constant that can be placed into a 32-bit mask operand
+   'S' is a constant that can be placed into a 64-bit mask operand.
+   'T' is a constant that can be placed into a 32-bit mask operand.
    'U' is for V.4 small data references.
    'W' is a vector constant that can be easily generated (no mem refs).
    'Y' is an indexed or word-aligned displacement memory operand.
    'Z' is an indexed or indirect memory operand.
    'a'  is an indexed or indirect address operand.
-   't' is for AND masks that can be performed by two rldic{l,r} insns.  */
+   't' is for AND masks that can be performed by two rldic{l,r} insns
+       (but excluding those that could match other constraints of anddi3.)  */
 
 #define EXTRA_CONSTRAINT(OP, C)						\
   ((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG	\
    : (C) == 'R' ? legitimate_constant_pool_address_p (OP)		\
-   : (C) == 'S' ? mask_operand (OP, DImode)				\
-   : (C) == 'T' ? mask_operand (OP, SImode)				\
+   : (C) == 'S' ? mask64_operand (OP, DImode)				\
+   : (C) == 'T' ? mask_operand (OP, GET_MODE (OP))			\
    : (C) == 'U' ? (DEFAULT_ABI == ABI_V4				\
 		   && small_data_operand (OP, GET_MODE (OP)))		\
    : (C) == 't' ? (mask64_2_operand (OP, DImode)			\
 		   && (fixed_regs[CR0_REGNO]				\
 		       || !logical_operand (OP, DImode))		\
-		   && !mask_operand (OP, DImode))			\
+		   && !mask_operand (OP, DImode)			\
+		   && !mask64_operand (OP, DImode))			\
    : (C) == 'W' ? (easy_vector_constant (OP, GET_MODE (OP)))		\
    : (C) == 'Y' ? (word_offset_memref_operand (OP, GET_MODE (OP)))      \
    : (C) == 'Z' ? (indexed_or_indirect_operand (OP, GET_MODE (OP)))	\
diff -urp -xCVS -x'*~' -x'.#*' -xTAGS -xautom4te.cache -x'*.info' gcc-virgin/gcc/config/rs6000/rs6000.md gcc-current/gcc/config/rs6000/rs6000.md
--- gcc-virgin/gcc/config/rs6000/rs6000.md	2005-08-27 09:02:36.000000000 +0930
+++ gcc-current/gcc/config/rs6000/rs6000.md	2005-08-31 22:16:31.000000000 +0930
@@ -5979,7 +5979,7 @@
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
 	(and:DI (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
 			   (match_operand:DI 2 "reg_or_cint_operand" "ri"))
-		(match_operand:DI 3 "mask_operand" "n")))]
+		(match_operand:DI 3 "mask64_operand" "n")))]
   "TARGET_POWERPC64"
   "rld%I2c%B3 %0,%1,%H2,%S3")
 
@@ -5988,7 +5988,7 @@
 	(compare:CC (and:DI
 		     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
 				(match_operand:DI 2 "reg_or_cint_operand" "ri,ri"))
-		     (match_operand:DI 3 "mask_operand" "n,n"))
+		     (match_operand:DI 3 "mask64_operand" "n,n"))
 		    (const_int 0)))
    (clobber (match_scratch:DI 4 "=r,r"))]
   "TARGET_64BIT"
@@ -6003,7 +6003,7 @@
 	(compare:CC (and:DI
 		     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
 				(match_operand:DI 2 "reg_or_cint_operand" ""))
-		     (match_operand:DI 3 "mask_operand" ""))
+		     (match_operand:DI 3 "mask64_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:DI 4 ""))]
   "TARGET_POWERPC64 && reload_completed"
@@ -6021,7 +6021,7 @@
 	(compare:CC (and:DI
 		     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
 				(match_operand:DI 2 "reg_or_cint_operand" "ri,ri"))
-		     (match_operand:DI 3 "mask_operand" "n,n"))
+		     (match_operand:DI 3 "mask64_operand" "n,n"))
 		    (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
 	(and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
@@ -6037,7 +6037,7 @@
 	(compare:CC (and:DI
 		     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
 				(match_operand:DI 2 "reg_or_cint_operand" ""))
-		     (match_operand:DI 3 "mask_operand" ""))
+		     (match_operand:DI 3 "mask64_operand" ""))
 		    (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "")
 	(and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
@@ -6435,7 +6435,7 @@
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
 	(and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
 			   (match_operand:SI 2 "const_int_operand" "i"))
-		(match_operand:DI 3 "mask_operand" "n")))]
+		(match_operand:DI 3 "mask64_operand" "n")))]
   "TARGET_POWERPC64 && includes_rldicr_lshift_p (operands[2], operands[3])"
   "rldicr %0,%1,%H2,%S3")
 
@@ -6444,7 +6444,7 @@
 	(compare:CC
 	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
 			    (match_operand:SI 2 "const_int_operand" "i,i"))
-		 (match_operand:DI 3 "mask_operand" "n,n"))
+		 (match_operand:DI 3 "mask64_operand" "n,n"))
 	 (const_int 0)))
    (clobber (match_scratch:DI 4 "=r,r"))]
   "TARGET_64BIT && includes_rldicr_lshift_p (operands[2], operands[3])"
@@ -6459,7 +6459,7 @@
 	(compare:CC
 	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
 			    (match_operand:SI 2 "const_int_operand" ""))
-		 (match_operand:DI 3 "mask_operand" ""))
+		 (match_operand:DI 3 "mask64_operand" ""))
 	 (const_int 0)))
    (clobber (match_scratch:DI 4 ""))]
   "TARGET_POWERPC64 && reload_completed
@@ -6477,7 +6477,7 @@
 	(compare:CC
 	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
 			    (match_operand:SI 2 "const_int_operand" "i,i"))
-		    (match_operand:DI 3 "mask_operand" "n,n"))
+		    (match_operand:DI 3 "mask64_operand" "n,n"))
 	 (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
 	(and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
@@ -6493,7 +6493,7 @@
 	(compare:CC
 	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
 			    (match_operand:SI 2 "const_int_operand" ""))
-		 (match_operand:DI 3 "mask_operand" ""))
+		 (match_operand:DI 3 "mask64_operand" ""))
 	 (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "")
 	(and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
@@ -6698,7 +6698,8 @@
    (clobber (match_scratch:CC 3 ""))]
   "TARGET_POWERPC64
     && (fixed_regs[CR0_REGNO] || !logical_operand (operands[2], DImode))
-    && !mask_operand (operands[2], DImode)"
+    && !mask_operand (operands[2], DImode)
+    && !mask64_operand (operands[2], DImode)"
   [(set (match_dup 0)
 	(and:DI (rotate:DI (match_dup 1)
 			   (match_dup 4))
@@ -6712,16 +6713,17 @@
 })
 
 (define_insn "*anddi3_internal2"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x,?y,?y,??y,??y,?y")
-	(compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r")
-			    (match_operand:DI 2 "and64_2_operand" "r,S,K,J,t,r,S,K,J,t"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x,x,?y,?y,?y,??y,??y,?y")
+	(compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r,r,r")
+			    (match_operand:DI 2 "and64_2_operand" "r,S,T,K,J,t,r,S,T,K,J,t"))
 		    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r,r,r,r,r,r,r,r,r,r"))
-   (clobber (match_scratch:CC 4 "=X,X,X,X,X,X,X,x,x,X"))]
+   (clobber (match_scratch:DI 3 "=r,r,r,r,r,r,r,r,r,r,r,r"))
+   (clobber (match_scratch:CC 4 "=X,X,X,X,X,X,X,X,X,x,x,X"))]
   "TARGET_64BIT"
   "@
    and. %3,%1,%2
    rldic%B2. %3,%1,0,%S2
+   rlwinm. %3,%1,0,%m2,%M2
    andi. %3,%1,%b2
    andis. %3,%1,%u2
    #
@@ -6729,9 +6731,10 @@
    #
    #
    #
+   #
    #"
-  [(set_attr "type" "compare,delayed_compare,compare,compare,delayed_compare,compare,compare,compare,compare,compare")
-   (set_attr "length" "4,4,4,4,8,8,8,8,8,12")])
+  [(set_attr "type" "compare,delayed_compare,delayed_compare,compare,compare,delayed_compare,delayed_compare,compare,compare,compare,compare,compare")
+   (set_attr "length" "4,4,4,4,4,8,8,8,8,8,8,12")])
 
 (define_split
   [(set (match_operand:CC 0 "cc_reg_operand" "")
@@ -6740,9 +6743,10 @@
                     (const_int 0)))
    (clobber (match_scratch:DI 3 ""))
    (clobber (match_scratch:CC 4 ""))]
-  "TARGET_POWERPC64 && reload_completed
+  "TARGET_64BIT && reload_completed
     && (fixed_regs[CR0_REGNO] || !logical_operand (operands[2], DImode))
-    && !mask_operand (operands[2], DImode)"
+    && !mask_operand (operands[2], DImode)
+    && !mask64_operand (operands[2], DImode)"
   [(set (match_dup 3)
 	(and:DI (rotate:DI (match_dup 1)
 			   (match_dup 5))
@@ -6759,17 +6763,18 @@
 }")
 
 (define_insn "*anddi3_internal3"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x,x,?y,?y,??y,??y,?y")
-	(compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r")
-			    (match_operand:DI 2 "and64_2_operand" "r,S,K,J,t,r,S,K,J,t"))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x,x,x,?y,?y,?y,??y,??y,?y")
+	(compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r,r,r")
+			    (match_operand:DI 2 "and64_2_operand" "r,S,T,K,J,t,r,S,T,K,J,t"))
 		    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r,r,r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r,r,r,r,r")
 	(and:DI (match_dup 1) (match_dup 2)))
-   (clobber (match_scratch:CC 4 "=X,X,X,X,X,X,X,x,x,X"))]
+   (clobber (match_scratch:CC 4 "=X,X,X,X,X,X,X,X,X,x,x,X"))]
   "TARGET_64BIT"
   "@
    and. %0,%1,%2
    rldic%B2. %0,%1,0,%S2
+   rlwinm. %0,%1,0,%m2,%M2
    andi. %0,%1,%b2
    andis. %0,%1,%u2
    #
@@ -6777,19 +6782,20 @@
    #
    #
    #
+   #
    #"
-  [(set_attr "type" "compare,delayed_compare,compare,compare,delayed_compare,compare,compare,compare,compare,compare")
-   (set_attr "length" "4,4,4,4,8,8,8,8,8,12")])
+  [(set_attr "type" "compare,delayed_compare,delayed_compare,compare,compare,delayed_compare,delayed_compare,compare,compare,compare,compare,compare")
+   (set_attr "length" "4,4,4,4,4,8,8,8,8,8,8,12")])
 
 (define_split
   [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
 	(compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "")
-			    (match_operand:DI 2 "and_operand" ""))
+			    (match_operand:DI 2 "and64_2_operand" ""))
 		    (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "")
 	(and:DI (match_dup 1) (match_dup 2)))
    (clobber (match_scratch:CC 4 ""))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_64BIT && reload_completed"
   [(parallel [(set (match_dup 0)
 		    (and:DI (match_dup 1) (match_dup 2)))
 	       (clobber (match_dup 4))])
@@ -6806,9 +6812,10 @@
    (set (match_operand:DI 0 "gpc_reg_operand" "")
 	(and:DI (match_dup 1) (match_dup 2)))
    (clobber (match_scratch:CC 4 ""))]
-  "TARGET_POWERPC64 && reload_completed
+  "TARGET_64BIT && reload_completed
     && (fixed_regs[CR0_REGNO] || !logical_operand (operands[2], DImode))
-    && !mask_operand (operands[2], DImode)"
+    && !mask_operand (operands[2], DImode)
+    && !mask64_operand (operands[2], DImode)"
   [(set (match_dup 0)
 	(and:DI (rotate:DI (match_dup 1)
 			   (match_dup 5))
@@ -8024,7 +8029,7 @@
 ;; Use (and:DI (rotate:DI ...)) to avoid anddi3 unnecessary clobber.
 (define_split
   [(set (match_operand:DI 0 "gpc_reg_operand" "")
-	(match_operand:DI 1 "mask_operand" ""))]
+	(match_operand:DI 1 "mask64_operand" ""))]
   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
   [(set (match_dup 0) (const_int -1))
    (set (match_dup 0)

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]