aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAlan Modra <amodra@bigpond.net.au>2001-08-27 15:52:35 +0000
committerAlan Modra <amodra@gcc.gnu.org>2001-08-28 01:22:35 +0930
commitc50594233b1cf896e3383fd4f2988819d2bba440 (patch)
tree50af4f9077687a22c24751668bbbe8a3bd6ee6bd /gcc
parentc34cce440404a66643a1cf32388fa5c40f7d92d1 (diff)
downloadgcc-c50594233b1cf896e3383fd4f2988819d2bba440.zip
gcc-c50594233b1cf896e3383fd4f2988819d2bba440.tar.gz
gcc-c50594233b1cf896e3383fd4f2988819d2bba440.tar.bz2
rs6000.c (mask_operand): Rewrite without bit-shifting loop.
* config/rs6000/rs6000.c (mask_operand): Rewrite without bit-shifting loop. (mask64_operand): Likewise. (rldic_operand): Delete. (includes_lshift64_p): Delete. (includes_rldic_lshift_p): New function. (includes_rldicr_lshift_p): New function. (print_operand): Don't call rldic_operand in case 'W'. * config/rs6000/rs6000-protos.h (rldic_operand): Remove. (includes_lshift64_p): Remove. (includes_rldic_lshift_p): Declare. (includes_rldicr_lshift_p): Declare. * 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 includes_rldic_lshift_p. <ashldi3_internal 64 bit rldicr patterns>: New. From-SVN: r45192
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog21
-rw-r--r--gcc/config/rs6000/rs6000-protos.h4
-rw-r--r--gcc/config/rs6000/rs6000.c351
-rw-r--r--gcc/config/rs6000/rs6000.h1
-rw-r--r--gcc/config/rs6000/rs6000.md98
5 files changed, 317 insertions, 158 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ebcf81d..bf70736 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,24 @@
+2001-08-27 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.c (mask_operand): Rewrite without
+ bit-shifting loop.
+ (mask64_operand): Likewise.
+ (rldic_operand): Delete.
+ (includes_lshift64_p): Delete.
+ (includes_rldic_lshift_p): New function.
+ (includes_rldicr_lshift_p): New function.
+ (print_operand): Don't call rldic_operand in case 'W'.
+ * config/rs6000/rs6000-protos.h (rldic_operand): Remove.
+ (includes_lshift64_p): Remove.
+ (includes_rldic_lshift_p): Declare.
+ (includes_rldicr_lshift_p): Declare.
+ * 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
+ includes_rldic_lshift_p.
+ <ashldi3_internal 64 bit rldicr patterns>: New.
+
2001-08-27 Andreas Jaeger <aj@suse.de>
* emit-rtl.c: Use VA_OPEN/VA_CLOSE/VA_FIXEDARG throughout.
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index 13a2f3d..3a205e2 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -60,7 +60,6 @@ extern int non_logical_cint_operand PARAMS ((rtx, enum machine_mode));
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));
@@ -86,7 +85,8 @@ extern int boolean_or_operator PARAMS ((rtx, enum machine_mode));
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 includes_rldic_lshift_p PARAMS ((rtx, rtx));
+extern int includes_rldicr_lshift_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,
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 705eaa1..c902564 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -1158,26 +1158,36 @@ mask_operand (op, mode)
register rtx op;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
- HOST_WIDE_INT c;
- int i;
- int last_bit_value;
- int transitions = 0;
+ unsigned HOST_WIDE_INT c, lsb;
if (GET_CODE (op) != CONST_INT)
return 0;
c = INTVAL (op);
- if (c == 0 || c == ~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;
- last_bit_value = c & 1;
+ /* Find the first transition. */
+ lsb = c & -c;
+
+ /* Invert to look for a second transition. */
+ c = ~c;
- for (i = 1; i < 32; i++)
- if (((c >>= 1) & 1) != last_bit_value)
- last_bit_value ^= 1, transitions++;
+ /* Erase first transition. */
+ c &= -lsb;
- return transitions <= 2;
+ /* 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.
@@ -1192,133 +1202,49 @@ mask64_operand (op, 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++;
+ unsigned HOST_WIDE_INT c, lsb;
- 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;
+ /* 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;
- 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
- ))
+ /* Reject all zeros or all ones. */
+ if (c == 0)
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;
+ /* 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))
{
- 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;
+ unsigned HOST_WIDE_INT low, high, lsb;
- last_bit_value = low & 1;
+ if (HOST_BITS_PER_WIDE_INT < 64)
+ high = CONST_DOUBLE_HIGH (op);
- for (i = 1; i < HOST_BITS_PER_WIDE_INT; i++)
- if (((low >>= 1) & 1) != last_bit_value)
- last_bit_value ^= 1, transitions++;
+ low = CONST_DOUBLE_LOW (op);
+ if (low & 1)
+ {
+ if (HOST_BITS_PER_WIDE_INT < 64)
+ high = ~high;
+ low = ~low;
+ }
-#if HOST_BITS_PER_WIDE_INT == 32
- if ((high & 1) != last_bit_value)
- last_bit_value ^= 1, transitions++;
+ if (low == 0)
+ {
+ if (HOST_BITS_PER_WIDE_INT >= 64 || high == 0)
+ return 0;
- for (i = 1; i < HOST_BITS_PER_WIDE_INT; i++)
- if (((high >>= 1) & 1) != last_bit_value)
- last_bit_value ^= 1, transitions++;
-#endif
+ lsb = high & -high;
+ return high == -lsb;
+ }
- return transitions <= 2;
+ lsb = low & -low;
+ return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
}
else
return 0;
@@ -3705,36 +3631,174 @@ includes_rshift_p (shiftop, andop)
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. */
+/* Return 1 if ANDOP is a mask suitable for use with an rldic insn
+ to perform a left shift. It must have exactly SHIFTOP least
+ signifigant 0's, then one or more 1's, then zero or more 0's. */
int
-includes_lshift64_p (shiftop, andop)
+includes_rldic_lshift_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;
+ if (GET_CODE (andop) == CONST_INT)
+ {
+ unsigned HOST_WIDE_INT c, lsb, shift_mask;
- shift_mask <<= INTVAL (shiftop);
+ c = INTVAL (andop);
+ if (c == 0 || c == ~(unsigned HOST_WIDE_INT) 0)
+ return 0;
- 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 = ~(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 == ~(unsigned HOST_WIDE_INT) 0
+ && (HOST_BITS_PER_WIDE_INT >= 64
+ || high == ~(unsigned HOST_WIDE_INT) 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;
- shift_mask_low <<= INTVAL (shiftop);
+ 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;
+}
- if (INTVAL (shiftop) > 32)
- shift_mask_high <<= (INTVAL (shiftop) - 32);
+/* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
+ to perform a left shift. It must have SHIFTOP or more least
+ signifigant 0's, with the remainder of the word 1's. */
+int
+includes_rldicr_lshift_p (shiftop, andop)
+ register rtx shiftop;
+ register rtx andop;
+{
if (GET_CODE (andop) == CONST_INT)
- return (INTVAL (andop) & ~shift_mask_low) == 0;
+ {
+ 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 ((CONST_DOUBLE_HIGH (andop) & ~shift_mask_high) == 0
- && (CONST_DOUBLE_LOW (andop) & ~shift_mask_low) == 0);
-#endif
+ return 0;
}
/* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
@@ -4537,9 +4601,6 @@ print_operand (file, x, code)
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));
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 27d1d4b..b602dfb 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -2585,7 +2585,6 @@ do { \
{"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}}, \
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 03690ab..d116a63 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -6559,8 +6559,8 @@
[(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])"
+ (match_operand:DI 3 "const_int_operand" "n")))]
+ "TARGET_POWERPC64 && includes_rldic_lshift_p (operands[2], operands[3])"
"rldic %0,%1,%H2,%W3")
(define_insn "ashldi3_internal5"
@@ -6568,10 +6568,10 @@
(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"))
+ (match_operand:DI 3 "const_int_operand" "n,n"))
(const_int 0)))
(clobber (match_scratch:DI 4 "=r,r"))]
- "TARGET_POWERPC64 && includes_lshift64_p (operands[2], operands[3])"
+ "TARGET_POWERPC64 && includes_rldic_lshift_p (operands[2], operands[3])"
"@
rldic. %4,%1,%H2,%W3
#"
@@ -6583,10 +6583,11 @@
(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" ""))
+ (match_operand:DI 3 "const_int_operand" ""))
(const_int 0)))
(clobber (match_scratch:DI 4 ""))]
- "TARGET_POWERPC64 && includes_lshift64_p (operands[2], operands[3]) && reload_completed"
+ "TARGET_POWERPC64 && reload_completed
+ && includes_rldic_lshift_p (operands[2], operands[3])"
[(set (match_dup 4)
(and:DI (ashift:DI (match_dup 1) (match_dup 2))
(match_dup 3)))
@@ -6600,11 +6601,11 @@
(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"))
+ (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 && includes_lshift64_p (operands[2], operands[3])"
+ "TARGET_POWERPC64 && includes_rldic_lshift_p (operands[2], operands[3])"
"@
rldic. %0,%1,%H2,%W3
#"
@@ -6616,11 +6617,88 @@
(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" ""))
+ (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 && includes_lshift64_p (operands[2], operands[3]) && reload_completed"
+ "TARGET_POWERPC64 && reload_completed
+ && includes_rldic_lshift_p (operands[2], operands[3])"
+ [(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 "mask64_operand" "S")))]
+ "TARGET_POWERPC64 && includes_rldicr_lshift_p (operands[2], operands[3])"
+ "rldicr %0,%1,%H2,%S3")
+
+(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 "mask64_operand" "S,S"))
+ (const_int 0)))
+ (clobber (match_scratch:DI 4 "=r,r"))]
+ "TARGET_POWERPC64 && includes_rldicr_lshift_p (operands[2], operands[3])"
+ "@
+ rldicr. %4,%1,%H2,%S3
+ #"
+ [(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 "mask64_operand" ""))
+ (const_int 0)))
+ (clobber (match_scratch:DI 4 ""))]
+ "TARGET_POWERPC64 && reload_completed
+ && includes_rldicr_lshift_p (operands[2], operands[3])"
+ [(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 "mask64_operand" "S,S"))
+ (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_rldicr_lshift_p (operands[2], operands[3])"
+ "@
+ rldicr. %0,%1,%H2,%S3
+ #"
+ [(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 "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)))]
+ "TARGET_POWERPC64 && reload_completed
+ && includes_rldicr_lshift_p (operands[2], operands[3])"
[(set (match_dup 0)
(and:DI (ashift:DI (match_dup 1) (match_dup 2))
(match_dup 3)))