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]

powerpc64 rldic


Hi Geoff, David,
  rldic_operand and includes_lshift64_p together don't sufficiently
restrict allowable mask values.  A simple testcase from code in the linux
kernel:

long foo (long i)
{
  return (i & -4096) << 4;
}

compiles to

.foo:
        rldic 3,3,4,0
        blr

This patch goes a little further than just fixing the breakage.  I've
rewritten various bit-mask validation predicates without the bit shift
loop, and added insns and splitters to use rldicr when possible.

gcc/ChangeLog
	* config/rs6000/rs6000.c (mask_operand): Rewrite without
	bit-shifting loop.
	(mask64_operand): Likewise.
	(rldic_operand): Likewise.  Pass in shift operand as well, and
	restrict allowed mask properly.
	(rldicr_operand): New.
	(includes_lshift64_p): Delete.
	(print_operand): Handle 't'.  Don't call rldic_operand in case 'W'.
	* config/rs6000/rs6000-protos.h (rldic_operand): Update
	(rldicr_operand): Add.
	(includes_lshift64_p): Remove.
	* config/rs6000/rs6000.h (PREDICATE_CODES): Remove rldic_operand.
	* config/rs6000/rs6000.md <ashldi3_internal 64 bit patterns>:
	Replace match_operand rldic_operand predicate with
	const_int_operand.  Replace includes_lshift64_p condition with
	rldic_operand.
	<ashldi3_internal 64 bit rldicr patterns>: New.

Currently bootstrapping.

-- 
Alan Modra

diff -crp gcc-current/gcc/config/rs6000/rs6000-protos.h gcc-ppc64/gcc/config/rs6000/rs6000-protos.h
*** gcc-current/gcc/config/rs6000/rs6000-protos.h	Wed Aug  1 18:33:26 2001
--- gcc-ppc64/gcc/config/rs6000/rs6000-protos.h	Tue Aug 21 14:08:01 2001
*************** extern int non_logical_cint_operand PARA
*** 60,66 ****
  extern int logical_operand PARAMS ((rtx, enum machine_mode));
  extern int mask_operand PARAMS ((rtx, enum machine_mode));
  extern int mask64_operand PARAMS ((rtx, enum machine_mode));
! extern int rldic_operand PARAMS ((rtx, enum machine_mode));
  extern int and64_operand PARAMS ((rtx, enum machine_mode));
  extern int and_operand PARAMS ((rtx, enum machine_mode));
  extern int count_register_operand PARAMS ((rtx, enum machine_mode));
--- 60,67 ----
  extern int logical_operand PARAMS ((rtx, enum machine_mode));
  extern int mask_operand PARAMS ((rtx, enum machine_mode));
  extern int mask64_operand PARAMS ((rtx, enum machine_mode));
! extern int rldic_operand PARAMS ((rtx, rtx));
! extern int rldicr_operand PARAMS ((rtx, rtx));
  extern int and64_operand PARAMS ((rtx, enum machine_mode));
  extern int and_operand PARAMS ((rtx, enum machine_mode));
  extern int count_register_operand PARAMS ((rtx, enum machine_mode));
*************** extern int boolean_or_operator PARAMS ((
*** 86,92 ****
  extern int min_max_operator PARAMS ((rtx, enum machine_mode));
  extern int includes_lshift_p PARAMS ((rtx, rtx));
  extern int includes_rshift_p PARAMS ((rtx, rtx));
- extern int includes_lshift64_p PARAMS ((rtx, rtx));
  extern int registers_ok_for_quad_peep PARAMS ((rtx, rtx));
  extern int addrs_ok_for_quad_peep PARAMS ((rtx, rtx));
  extern enum reg_class secondary_reload_class PARAMS ((enum reg_class,
--- 87,92 ----
diff -crp gcc-current/gcc/config/rs6000/rs6000.c gcc-ppc64/gcc/config/rs6000/rs6000.c
*** gcc-current/gcc/config/rs6000/rs6000.c	Wed Aug 15 14:52:57 2001
--- gcc-ppc64/gcc/config/rs6000/rs6000.c	Tue Aug 21 14:08:01 2001
*************** mask_operand (op, mode)
*** 1148,1173 ****
       register rtx op;
       enum machine_mode mode ATTRIBUTE_UNUSED;
  {
!   HOST_WIDE_INT c;
!   int i;
!   int last_bit_value;
!   int transitions = 0;
  
    if (GET_CODE (op) != CONST_INT)
      return 0;
  
    c = INTVAL (op);
  
!   if (c == 0 || c == ~0)
      return 0;
  
!   last_bit_value = c & 1;
  
!   for (i = 1; i < 32; i++)
!     if (((c >>= 1) & 1) != last_bit_value)
!       last_bit_value ^= 1, transitions++;
  
!   return transitions <= 2;
  }
  
  /* Return 1 if the operand is a constant that is a PowerPC64 mask.
--- 1148,1183 ----
       register rtx op;
       enum machine_mode mode ATTRIBUTE_UNUSED;
  {
!   unsigned HOST_WIDE_INT c, lsb;
  
    if (GET_CODE (op) != CONST_INT)
      return 0;
  
    c = INTVAL (op);
  
!   /* 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;
! 
!   /* Invert to look for a second transition.  */
!   c = ~c;
! 
!   /* Erase first transition.  */
!   c &= -lsb;
  
!   /* 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;
  }
  
  /* Return 1 if the operand is a constant that is a PowerPC64 mask.
*************** mask64_operand (op, mode)
*** 1182,1314 ****
  {
    if (GET_CODE (op) == CONST_INT)
      {
!       HOST_WIDE_INT c = INTVAL (op);
!       int i;
!       int last_bit_value;
!       int transitions = 0;
  
!       if (c == 0 || c == ~0)
! 	return 0;
  
!       last_bit_value = c & 1;
! 
!       for (i = 1; i < HOST_BITS_PER_WIDE_INT; i++)
! 	if (((c >>= 1) & 1) != last_bit_value)
! 	  last_bit_value ^= 1, transitions++;
  
!       return transitions <= 1;
      }
    else if (GET_CODE (op) == CONST_DOUBLE
  	   && (mode == VOIDmode || mode == DImode))
      {
!       HOST_WIDE_INT low = CONST_DOUBLE_LOW (op);
! #if HOST_BITS_PER_WIDE_INT == 32
!       HOST_WIDE_INT high = CONST_DOUBLE_HIGH (op);
! #endif
!       int i;
!       int last_bit_value;
!       int transitions = 0;
! 
!       if ((low == 0
! #if HOST_BITS_PER_WIDE_INT == 32
! 	  && high == 0
! #endif
! 	   )
! 	  || (low == ~0
! #if HOST_BITS_PER_WIDE_INT == 32
! 	      && high == ~0
! #endif
! 	      ))
! 	return 0;
  
!       last_bit_value = low & 1;
  
!       for (i = 1; i < HOST_BITS_PER_WIDE_INT; i++)
! 	if (((low >>= 1) & 1) != last_bit_value)
! 	  last_bit_value ^= 1, transitions++;
  
! #if HOST_BITS_PER_WIDE_INT == 32
!       if ((high & 1) != last_bit_value)
! 	last_bit_value ^= 1, transitions++;
  
!       for (i = 1; i < HOST_BITS_PER_WIDE_INT; i++)
! 	if (((high >>= 1) & 1) != last_bit_value)
! 	  last_bit_value ^= 1, transitions++;
! #endif
  
!       return transitions <= 1;
      }
    else
      return 0;
  }
  
! /* Return 1 if the operand is a constant that is a PowerPC64 mask.
!    It is if there are 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.  */
  
  int
! rldic_operand (op, mode)
!      register rtx op;
!      enum machine_mode mode;
  {
!   if (GET_CODE (op) == CONST_INT)
      {
!       HOST_WIDE_INT c = INTVAL (op);
!       int i;
!       int last_bit_value;
!       int transitions = 0;
  
        if (c == 0 || c == ~0)
  	return 0;
  
!       last_bit_value = c & 1;
  
!       for (i = 1; i < HOST_BITS_PER_WIDE_INT; i++)
! 	if (((c >>= 1) & 1) != last_bit_value)
! 	  last_bit_value ^= 1, transitions++;
  
!       return transitions <= 2;
      }
!   else if (GET_CODE (op) == CONST_DOUBLE
! 	   && (mode == VOIDmode || mode == DImode))
      {
!       HOST_WIDE_INT low = CONST_DOUBLE_LOW (op);
! #if HOST_BITS_PER_WIDE_INT == 32
!       HOST_WIDE_INT high = CONST_DOUBLE_HIGH (op);
! #endif
!       int i;
!       int last_bit_value;
!       int transitions = 0;
  
!       if ((low == 0
! #if HOST_BITS_PER_WIDE_INT == 32
! 	  && high == 0
! #endif
! 	   )
! 	  || (low == ~0
! #if HOST_BITS_PER_WIDE_INT == 32
! 	      && high == ~0
! #endif
! 	      ))
  	return 0;
  
!       last_bit_value = low & 1;
  
!       for (i = 1; i < HOST_BITS_PER_WIDE_INT; i++)
! 	if (((low >>= 1) & 1) != last_bit_value)
! 	  last_bit_value ^= 1, transitions++;
  
! #if HOST_BITS_PER_WIDE_INT == 32
!       if ((high & 1) != last_bit_value)
! 	last_bit_value ^= 1, transitions++;
  
!       for (i = 1; i < HOST_BITS_PER_WIDE_INT; i++)
! 	if (((high >>= 1) & 1) != last_bit_value)
! 	  last_bit_value ^= 1, transitions++;
! #endif
  
!       return transitions <= 2;
      }
    else
      return 0;
--- 1192,1408 ----
  {
    if (GET_CODE (op) == CONST_INT)
      {
!       unsigned HOST_WIDE_INT c, lsb;
  
!       /* We don't change the number of transitions by inverting,
! 	 so make sure we start with the LS bit zero.  */
!       c = INTVAL (op);
!       if (c & 1)
! 	c = ~c;
  
!       /* Reject all zeros or all ones.  */
!       if (c == 0)
! 	return 0;
  
!       /* Find the transition, and check that all bits above are 1's.  */
!       lsb = c & -c;
!       return c == -lsb;
      }
    else if (GET_CODE (op) == CONST_DOUBLE
  	   && (mode == VOIDmode || mode == DImode))
      {
!       unsigned HOST_WIDE_INT low, high, lsb;
  
!       if (HOST_BITS_PER_WIDE_INT < 64)
! 	high = CONST_DOUBLE_HIGH (op);
  
!       low = CONST_DOUBLE_LOW (op);
!       if (low & 1)
! 	{
! 	  if (HOST_BITS_PER_WIDE_INT < 64)
! 	    high = ~high;
! 	  low = ~low;
! 	}
  
!       if (low == 0)
! 	{
! 	  if (HOST_BITS_PER_WIDE_INT >= 64 || high == 0)
! 	    return 0;
  
! 	  lsb = high & -high;
! 	  return high == -lsb;
! 	}
  
!       lsb = low & -low;
!       return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
      }
    else
      return 0;
  }
  
! /* Return 1 if ANDOP is a mask suitable for use with an rldic
!    instruction.  It must have SHIFTOP least signifigant 0's, then one
!    or more 1's, then zero or more 0's.  */
  
  int
! rldic_operand (shiftop, andop)
!      register rtx shiftop;
!      register rtx andop;
  {
!   if (GET_CODE (andop) == CONST_INT)
      {
!       unsigned HOST_WIDE_INT c, lsb, shift_mask;
  
+       c = INTVAL (andop);
        if (c == 0 || c == ~0)
  	return 0;
  
!       shift_mask = ~(unsigned HOST_WIDE_INT) 0;
!       shift_mask <<= INTVAL (shiftop);
  
!       /* Find the least signifigant one bit.  */
!       lsb = c & -c;
  
!       /* It must coincide with the LSB of the shift mask.  */
!       if (-lsb != shift_mask)
! 	return 0;
! 
!       /* Invert to look for the next transition (if any).  */
!       c = ~c;
! 
!       /* Remove the low group of ones (originally low group of zeros).  */
!       c &= -lsb;
! 
!       /* Again find the lsb, and check we have all 1's above.  */
!       lsb = c & -c;
!       return c == -lsb;
      }
!   else if (GET_CODE (andop) == CONST_DOUBLE
! 	   && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
      {
!       unsigned HOST_WIDE_INT low, high, lsb;
!       unsigned HOST_WIDE_INT shift_mask_low, shift_mask_high;
  
!       low = CONST_DOUBLE_LOW (andop);
!       if (HOST_BITS_PER_WIDE_INT < 64)
! 	high = CONST_DOUBLE_HIGH (andop);
! 
!       if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
! 	  || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
  	return 0;
  
!       if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
! 	{
! 	  shift_mask_high = ~(unsigned HOST_WIDE_INT) 0;
! 	  if (INTVAL (shiftop) > 32)
! 	    shift_mask_high <<= INTVAL (shiftop) - 32;
  
! 	  lsb = high & -high;
  
! 	  if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
! 	    return 0;
  
! 	  high = ~high;
! 	  high &= -lsb;
! 
! 	  lsb = high & -high;
! 	  return high == -lsb;
! 	}
! 
!       shift_mask_low = ~(unsigned HOST_WIDE_INT) 0;
!       shift_mask_low <<= INTVAL (shiftop);
! 
!       lsb = low & -low;
! 
!       if (-lsb != shift_mask_low)
! 	return 0;
! 
!       if (HOST_BITS_PER_WIDE_INT < 64)
! 	high = ~high;
!       low = ~low;
!       low &= -lsb;
  
!       if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
! 	{
! 	  lsb = high & -high;
! 	  return high == -lsb;
! 	}
! 
!       lsb = low & -low;
!       return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
!     }
!   else
!     return 0;
! }
! 
! /* Return 1 if ANDOP is a mask suitable for use with an rldicr
!    instruction.  It must have SHIFTOP or more least signifigant 0's,
!    with the remainder of the word 1's.  */
! 
! int
! rldicr_operand (shiftop, andop)
!      register rtx shiftop;
!      register rtx andop;
! {
!   if (GET_CODE (andop) == CONST_INT)
!     {
!       unsigned HOST_WIDE_INT c, lsb;
!       unsigned HOST_WIDE_INT shift_mask;
! 
!       shift_mask = ~(unsigned HOST_WIDE_INT) 0;
!       shift_mask <<= INTVAL (shiftop);
!       c = INTVAL (andop);
! 
!       /* Find the least signifigant one bit.  */
!       lsb = c & -c;
! 
!       /* It must be covered by the shift mask.
! 	 This test also rejects c == 0. */
!       if ((lsb & shift_mask) == 0)
! 	return 0;
! 
!       /* Check we have all 1's above the transition, and reject all 1's.  */
!       return c == -lsb && lsb != 1;
!     }
!   else if (GET_CODE (andop) == CONST_DOUBLE
! 	   && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
!     {
!       unsigned HOST_WIDE_INT low, lsb, shift_mask_low;
! 
!       low = CONST_DOUBLE_LOW (andop);
! 
!       if (HOST_BITS_PER_WIDE_INT < 64)
! 	{
! 	  unsigned HOST_WIDE_INT high, shift_mask_high;
! 
! 	  high = CONST_DOUBLE_HIGH (andop);
! 
! 	  if (low == 0)
! 	    {
! 	      shift_mask_high = ~(unsigned HOST_WIDE_INT) 0;
! 	      if (INTVAL (shiftop) > 32)
! 		shift_mask_high <<= INTVAL (shiftop) - 32;
! 
! 	      lsb = high & -high;
! 
! 	      if ((lsb & shift_mask_high) == 0)
! 		return 0;
! 
! 	      return high == -lsb;
! 	    }
! 	  if (high != ~0)
! 	    return 0;
! 	}
! 
!       shift_mask_low = ~(unsigned HOST_WIDE_INT) 0;
!       shift_mask_low <<= INTVAL (shiftop);
! 
!       lsb = low & -low;
! 
!       if ((lsb & shift_mask_low) == 0)
! 	return 0;
! 
!       return low == -lsb && lsb != 1;
      }
    else
      return 0;
*************** includes_rshift_p (shiftop, andop)
*** 3695,3732 ****
    return (INTVAL (andop) & ~shift_mask) == 0;
  }
  
- /* Return 1 if ANDOP is a mask that has no bits on that are not in the
-    mask required to convert the result of a rotate insn into a shift
-    left insn of SHIFTOP bits.  */
- 
- int
- includes_lshift64_p (shiftop, andop)
-      register rtx shiftop;
-      register rtx andop;
- {
- #if HOST_BITS_PER_WIDE_INT == 64
-   unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
- 
-   shift_mask <<= INTVAL (shiftop);
- 
-   return (INTVAL (andop) & ~shift_mask) == 0;
- #else
-   unsigned HOST_WIDE_INT shift_mask_low = ~(unsigned HOST_WIDE_INT) 0;
-   unsigned HOST_WIDE_INT shift_mask_high = ~(unsigned HOST_WIDE_INT) 0;
- 
-   shift_mask_low <<= INTVAL (shiftop);
- 
-   if (INTVAL (shiftop) > 32)
-     shift_mask_high <<= (INTVAL (shiftop) - 32);
- 
-   if (GET_CODE (andop) == CONST_INT)
-     return (INTVAL (andop) & ~shift_mask_low) == 0;
-   else
-     return ((CONST_DOUBLE_HIGH (andop) & ~shift_mask_high) == 0
- 	    && (CONST_DOUBLE_LOW (andop) & ~shift_mask_low) == 0);
- #endif
- }
- 
  /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
     for lfq and stfq insns.
  
--- 3789,3794 ----
*************** print_operand (file, x, code)
*** 4432,4437 ****
--- 4494,4525 ----
  	  return;
  	}
  
+     case 't':
+       /* ME value for a PowerPC64 rldicr operand.  */
+       val = INT_LOWPART (x);
+ 
+       /* Look for the first 1 bit on the right.  We know we have at
+ 	 least one 0, and one 1.  */
+ 
+       i = 63;
+       if (val == 0)
+ 	{
+ 	  if (HOST_BITS_PER_WIDE_INT >= 64
+ 	      || GET_CODE (x) != CONST_DOUBLE
+ 	      || (val = CONST_DOUBLE_HIGH (x)) == 0)
+ 	    abort ();
+ 	  i = 31;
+ 	}
+ 
+       while ((val & 1) == 0)
+ 	{
+ 	  val >>= 1;
+ 	  i -= 1;
+ 	}
+ 
+       fprintf (file, "%d", i);
+       return;
+ 
      case 'T':
        /* Print the symbolic name of a branch target register.  */
        if (GET_CODE (x) != REG || (REGNO (x) != LINK_REGISTER_REGNUM
*************** print_operand (file, x, code)
*** 4527,4535 ****
  
      case 'W':
        /* MB value for a PowerPC64 rldic operand.  */
-       if (! rldic_operand (x, VOIDmode))
- 	output_operand_lossage ("invalid %%W value");
- 
        val = (GET_CODE (x) == CONST_INT
  	     ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
  
--- 4615,4620 ----
diff -crp gcc-current/gcc/config/rs6000/rs6000.h gcc-ppc64/gcc/config/rs6000/rs6000.h
*** gcc-current/gcc/config/rs6000/rs6000.h	Tue Aug  7 13:58:59 2001
--- gcc-ppc64/gcc/config/rs6000/rs6000.h	Tue Aug 21 14:08:01 2001
*************** do {									\
*** 2602,2608 ****
    {"non_logical_cint_operand", {CONST_INT, CONST_DOUBLE}},		   \
    {"mask_operand", {CONST_INT}},					   \
    {"mask64_operand", {CONST_INT, CONST_DOUBLE}},			   \
-   {"rldic_operand", {CONST_INT, CONST_DOUBLE}},				   \
    {"count_register_operand", {REG}},					   \
    {"xer_operand", {REG}},						   \
    {"call_operand", {SYMBOL_REF, REG}},					   \
--- 2602,2607 ----
diff -crp gcc-current/gcc/config/rs6000/rs6000.md gcc-ppc64/gcc/config/rs6000/rs6000.md
*** gcc-current/gcc/config/rs6000/rs6000.md	Fri Aug  3 11:16:59 2001
--- gcc-ppc64/gcc/config/rs6000/rs6000.md	Tue Aug 21 14:08:01 2001
***************
*** 6559,6566 ****
    [(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 "rldic_operand" "n")))]
!   "TARGET_POWERPC64 && includes_lshift64_p (operands[2], operands[3])"
    "rldic %0,%1,%H2,%W3")
  
  (define_insn "ashldi3_internal5"
--- 6559,6566 ----
    [(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 "const_int_operand" "n")))]
!   "TARGET_POWERPC64 && rldic_operand (operands[2], operands[3])"
    "rldic %0,%1,%H2,%W3")
  
  (define_insn "ashldi3_internal5"
***************
*** 6568,6577 ****
  	(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 "rldic_operand" "n,n"))
  	 (const_int 0)))
     (clobber (match_scratch:DI 4 "=r,r"))]
!   "TARGET_POWERPC64 && includes_lshift64_p (operands[2], operands[3])"
    "@
     rldic. %4,%1,%H2,%W3
     #"
--- 6568,6577 ----
  	(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 "const_int_operand" "n,n"))
  	 (const_int 0)))
     (clobber (match_scratch:DI 4 "=r,r"))]
!   "TARGET_POWERPC64 && rldic_operand (operands[2], operands[3])"
    "@
     rldic. %4,%1,%H2,%W3
     #"
***************
*** 6583,6592 ****
  	(compare:CC
  	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
  			    (match_operand:SI 2 "const_int_operand" ""))
! 		 (match_operand:DI 3 "rldic_operand" ""))
  	 (const_int 0)))
     (clobber (match_scratch:DI 4 ""))]
!   "TARGET_POWERPC64 && includes_lshift64_p (operands[2], operands[3]) && reload_completed"
    [(set (match_dup 4)
  	(and:DI (ashift:DI (match_dup 1) (match_dup 2))
  		(match_dup 3)))
--- 6583,6592 ----
  	(compare:CC
  	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
  			    (match_operand:SI 2 "const_int_operand" ""))
! 		 (match_operand:DI 3 "const_int_operand" ""))
  	 (const_int 0)))
     (clobber (match_scratch:DI 4 ""))]
!   "TARGET_POWERPC64 && rldic_operand (operands[2], operands[3]) && reload_completed"
    [(set (match_dup 4)
  	(and:DI (ashift:DI (match_dup 1) (match_dup 2))
  		(match_dup 3)))
***************
*** 6600,6610 ****
  	(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 "rldic_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)))]
!   "TARGET_POWERPC64 && includes_lshift64_p (operands[2], operands[3])"
    "@
     rldic. %0,%1,%H2,%W3
     #"
--- 6600,6610 ----
  	(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 "const_int_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)))]
!   "TARGET_POWERPC64 && rldic_operand (operands[2], operands[3])"
    "@
     rldic. %0,%1,%H2,%W3
     #"
***************
*** 6616,6626 ****
  	(compare:CC
  	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
  			    (match_operand:SI 2 "const_int_operand" ""))
! 		 (match_operand:DI 3 "rldic_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)))]
!   "TARGET_POWERPC64 && includes_lshift64_p (operands[2], operands[3]) && reload_completed"
    [(set (match_dup 0)
  	(and:DI (ashift:DI (match_dup 1) (match_dup 2))
  		(match_dup 3)))
--- 6616,6700 ----
  	(compare:CC
  	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
  			    (match_operand:SI 2 "const_int_operand" ""))
! 		 (match_operand:DI 3 "const_int_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)))]
!   "TARGET_POWERPC64 && rldic_operand (operands[2], operands[3]) && reload_completed"
!   [(set (match_dup 0)
! 	(and:DI (ashift:DI (match_dup 1) (match_dup 2))
! 		(match_dup 3)))
!    (set (match_dup 4)
! 	(compare:CC (match_dup 0)
! 		    (const_int 0)))]
!   "")
! 
! (define_insn "*ashldi3_internal7"
!   [(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 "const_int_operand" "n")))]
!   "TARGET_POWERPC64 && rldicr_operand (operands[2], operands[3])"
!   "rldicr %0,%1,%H2,%t3")
! 
! (define_insn "ashldi3_internal8"
!   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
! 	(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 "const_int_operand" "n,n"))
! 	 (const_int 0)))
!    (clobber (match_scratch:DI 4 "=r,r"))]
!   "TARGET_POWERPC64 && rldicr_operand (operands[2], operands[3])"
!   "@
!    rldicr. %4,%1,%H2,%t3
!    #"
!   [(set_attr "type" "delayed_compare")
!    (set_attr "length" "4,8")])
! 
! (define_split
!   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
! 	(compare:CC
! 	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
! 			    (match_operand:SI 2 "const_int_operand" ""))
! 		 (match_operand:DI 3 "const_int_operand" ""))
! 	 (const_int 0)))
!    (clobber (match_scratch:DI 4 ""))]
!   "TARGET_POWERPC64 && rldicr_operand (operands[2], operands[3]) && reload_completed"
!   [(set (match_dup 4)
! 	(and:DI (ashift:DI (match_dup 1) (match_dup 2))
! 		(match_dup 3)))
!    (set (match_dup 0)
! 	(compare:CC (match_dup 4)
! 		    (const_int 0)))]
!   "")
! 
! (define_insn "*ashldi3_internal9"
!   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
! 	(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 "const_int_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)))]
!   "TARGET_POWERPC64 && rldicr_operand (operands[2], operands[3])"
!   "@
!    rldicr. %0,%1,%H2,%t3
!    #"
!   [(set_attr "type" "delayed_compare")
!    (set_attr "length" "4,8")])
! 
! (define_split
!   [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
! 	(compare:CC
! 	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
! 			    (match_operand:SI 2 "const_int_operand" ""))
! 		 (match_operand:DI 3 "const_int_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)))]
!   "TARGET_POWERPC64 && rldicr_operand (operands[2], operands[3]) && reload_completed"
    [(set (match_dup 0)
  	(and:DI (ashift:DI (match_dup 1) (match_dup 2))
  		(match_dup 3)))


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