This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
powerpc64 rldic
- To: Geoff Keating <geoffk at redhat dot com>, David Edelsohn <dje at watson dot ibm dot com>
- Subject: powerpc64 rldic
- From: Alan Modra <amodra at bigpond dot net dot au>
- Date: Tue, 21 Aug 2001 22:28:51 +0930
- Cc: gcc-patches at gcc dot gnu dot org
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)))