aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Krebbel <krebbel1@de.ibm.com>2005-12-08 08:56:24 +0000
committerAndreas Krebbel <krebbel@gcc.gnu.org>2005-12-08 08:56:24 +0000
commit4989e88a3f50d66dc805d984f1c5b2e9a5f6cf31 (patch)
tree9a825017d201445a54a621d6af003c271f921dcd
parent820715b8d29fcb3dd4b3a45815c96091bd3613da (diff)
downloadgcc-4989e88a3f50d66dc805d984f1c5b2e9a5f6cf31.zip
gcc-4989e88a3f50d66dc805d984f1c5b2e9a5f6cf31.tar.gz
gcc-4989e88a3f50d66dc805d984f1c5b2e9a5f6cf31.tar.bz2
re PR target/25268 (ICE on lshrdi3_31 pattern)
2005-12-08 Andreas Krebbel <krebbel1@de.ibm.com> Jakub Jelinek <jakub@redhat.com> PR target/25268 * config/s390/s390.c (s390_decompose_shift_count): Remove BITS argument. Don't drop outer ANDs. (s390_extra_constraint_str, print_shift_count_operand): Adjust callers. * config/s390/s390-protos.h (s390_decompose_shift_count): Adjust prototype. * config/s390/predicates.md (setmem_operand): Remove. (shift_count_operand): Rename to... (shift_count_or_setmem_operand): ... this. Adjust s390_decompose_shift_count caller. * config/s390/s390.md (<shift>di3_31_and, <shift>di3_64_and, ashrdi3_cc_31_and, ashrdi3_cconly_31_and, ashrdi3_31_and, ashrdi3_cc_64_and, ashrdi3_cconly_64_and, ashrdi3_64_and, <shift>si3_and, ashrsi3_cc_and, ashrsi3_cconly_and, ashrsi3_and, rotl<mode>3_and, setmem_long_and): New insns. (<shift>di3_31, <shift>di3_64, ashrdi3_cc_31, ashrdi3_cconly_31, ashrdi3_31, ashrdi3_cc_64, ashrdi3_cconly_64, ashrdi3_64, <shift>si3, ashrsi3_cc, ashrsi3_cconly, ashrsi3, rotl<mode>3, <shift>di3, ashrdi3): Use shift_count_or_setmem_operand instead of shift_count_operand. (setmem_long): Use shift_count_or_setmem_operand instead of setmem_operand. 2005-12-08 Andreas Krebbel <krebbel1@de.ibm.com> Jakub Jelinek <jakub@redhat.com> PR target/25268 * gcc.c-torture/compile/20051207-1.c: New test. Co-Authored-By: Jakub Jelinek <jakub@redhat.com> From-SVN: r108220
-rw-r--r--gcc/ChangeLog26
-rw-r--r--gcc/config/s390/predicates.md34
-rw-r--r--gcc/config/s390/s390-protos.h2
-rw-r--r--gcc/config/s390/s390.c21
-rw-r--r--gcc/config/s390/s390.md203
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20051207-1.c7
7 files changed, 233 insertions, 66 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0a08ca7..6113f45 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,29 @@
+2005-12-08 Andreas Krebbel <krebbel1@de.ibm.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ PR target/25268
+ * config/s390/s390.c (s390_decompose_shift_count): Remove BITS
+ argument. Don't drop outer ANDs.
+ (s390_extra_constraint_str, print_shift_count_operand): Adjust callers.
+ * config/s390/s390-protos.h (s390_decompose_shift_count): Adjust
+ prototype.
+ * config/s390/predicates.md (setmem_operand): Remove.
+ (shift_count_operand): Rename to...
+ (shift_count_or_setmem_operand): ... this. Adjust
+ s390_decompose_shift_count caller.
+ * config/s390/s390.md (<shift>di3_31_and, <shift>di3_64_and,
+ ashrdi3_cc_31_and, ashrdi3_cconly_31_and, ashrdi3_31_and,
+ ashrdi3_cc_64_and, ashrdi3_cconly_64_and, ashrdi3_64_and,
+ <shift>si3_and, ashrsi3_cc_and, ashrsi3_cconly_and, ashrsi3_and,
+ rotl<mode>3_and, setmem_long_and): New insns.
+ (<shift>di3_31, <shift>di3_64, ashrdi3_cc_31, ashrdi3_cconly_31,
+ ashrdi3_31, ashrdi3_cc_64, ashrdi3_cconly_64, ashrdi3_64,
+ <shift>si3, ashrsi3_cc, ashrsi3_cconly, ashrsi3, rotl<mode>3,
+ <shift>di3, ashrdi3): Use shift_count_or_setmem_operand instead
+ of shift_count_operand.
+ (setmem_long): Use shift_count_or_setmem_operand instead of
+ setmem_operand.
+
2005-12-08 Daniel Jacobowitz <dan@codesourcery.com>
Andreas Tobler <a.tobler@schweiz.ch>
diff --git a/gcc/config/s390/predicates.md b/gcc/config/s390/predicates.md
index a921d1f..de6e796 100644
--- a/gcc/config/s390/predicates.md
+++ b/gcc/config/s390/predicates.md
@@ -75,42 +75,16 @@
(and (match_test "mode == Pmode")
(match_test "!legitimate_la_operand_p (op)"))))
-;; Return true if OP is a valid operand for setmem.
+;; Return true if OP is a valid operand as shift count or setmem.
-(define_predicate "setmem_operand"
+(define_predicate "shift_count_or_setmem_operand"
(match_code "reg, subreg, plus, const_int")
{
HOST_WIDE_INT offset;
rtx base;
- /* Extract base register and offset. Use 8 significant bits. */
- if (!s390_decompose_shift_count (op, &base, &offset, 8))
- return false;
-
- /* Don't allow any non-base hard registers. Doing so without
- confusing reload and/or regrename would be tricky, and doesn't
- buy us much anyway. */
- if (base && REGNO (base) < FIRST_PSEUDO_REGISTER && !ADDR_REG_P (base))
- return false;
-
- /* Unfortunately we have to reject constants that are invalid
- for an address, or else reload will get confused. */
- if (!DISP_IN_RANGE (offset))
- return false;
-
- return true;
-})
-
-;; Return true if OP is a valid shift count operand.
-
-(define_predicate "shift_count_operand"
- (match_code "reg, subreg, plus, const_int, and")
-{
- HOST_WIDE_INT offset;
- rtx base;
-
- /* Extract base register and offset. Use 6 significant bits. */
- if (!s390_decompose_shift_count (op, &base, &offset, 6))
+ /* Extract base register and offset. */
+ if (!s390_decompose_shift_count (op, &base, &offset))
return false;
/* Don't allow any non-base hard registers. Doing so without
diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h
index e62493d..710f4e7 100644
--- a/gcc/config/s390/s390-protos.h
+++ b/gcc/config/s390/s390-protos.h
@@ -100,7 +100,7 @@ extern rtx s390_load_got (void);
extern rtx s390_get_thread_pointer (void);
extern void s390_emit_tpf_eh_return (rtx);
extern bool s390_legitimate_address_without_index_p (rtx);
-extern bool s390_decompose_shift_count (rtx, rtx *, HOST_WIDE_INT *, int);
+extern bool s390_decompose_shift_count (rtx, rtx *, HOST_WIDE_INT *);
extern int s390_branch_condition_mask (rtx);
#endif /* RTX_CODE */
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 901b9b5..941e6f2 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -1729,28 +1729,13 @@ s390_decompose_address (rtx addr, struct s390_address *out)
/* Decompose a RTL expression OP for a shift count into its components,
and return the base register in BASE and the offset in OFFSET.
- If BITS is non-zero, the expression is used in a context where only
- that number to low-order bits is significant. We then allow OP to
- contain and outer AND that does not affect significant bits. If BITS
- is zero, we allow OP to contain any outer AND with a constant.
-
Return true if OP is a valid shift count, false if not. */
bool
-s390_decompose_shift_count (rtx op, rtx *base, HOST_WIDE_INT *offset, int bits)
+s390_decompose_shift_count (rtx op, rtx *base, HOST_WIDE_INT *offset)
{
HOST_WIDE_INT off = 0;
- /* Drop outer ANDs. */
- if (GET_CODE (op) == AND && GET_CODE (XEXP (op, 1)) == CONST_INT)
- {
- HOST_WIDE_INT mask = ((HOST_WIDE_INT)1 << bits) - 1;
- if ((INTVAL (XEXP (op, 1)) & mask) != mask)
- return false;
-
- op = XEXP (op, 0);
- }
-
/* We can have an integer constant, an address register,
or a sum of the two. */
if (GET_CODE (op) == CONST_INT)
@@ -1910,7 +1895,7 @@ s390_extra_constraint_str (rtx op, int c, const char * str)
case 'Y':
/* Simply check for the basic form of a shift count. Reload will
take care of making sure we have a proper base register. */
- if (!s390_decompose_shift_count (op, NULL, NULL, 0))
+ if (!s390_decompose_shift_count (op, NULL, NULL))
return 0;
break;
@@ -4284,7 +4269,7 @@ print_shift_count_operand (FILE *file, rtx op)
rtx base;
/* Extract base register and offset. */
- if (!s390_decompose_shift_count (op, &base, &offset, 0))
+ if (!s390_decompose_shift_count (op, &base, &offset))
gcc_unreachable ();
/* Sanity check. */
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index cf484c3..c9ce6fd 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -2222,7 +2222,7 @@
[(parallel
[(clobber (match_dup 1))
(set (match_operand:BLK 0 "memory_operand" "")
- (match_operand 2 "setmem_operand" ""))
+ (match_operand 2 "shift_count_or_setmem_operand" ""))
(use (match_operand 1 "general_operand" ""))
(use (match_dup 3))
(clobber (reg:CC CC_REGNUM))])]
@@ -2248,7 +2248,7 @@
(define_insn "*setmem_long"
[(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
(set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
- (match_operand 2 "setmem_operand" "Y"))
+ (match_operand 2 "shift_count_or_setmem_operand" "Y"))
(use (match_dup 3))
(use (match_operand:<DBL> 1 "register_operand" "d"))
(clobber (reg:CC CC_REGNUM))]
@@ -2257,6 +2257,18 @@
[(set_attr "length" "8")
(set_attr "type" "vs")])
+(define_insn "*setmem_long_and"
+ [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
+ (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
+ (and (match_operand 2 "shift_count_or_setmem_operand" "Y")
+ (match_operand 4 "const_int_operand" "n")))
+ (use (match_dup 3))
+ (use (match_operand:<DBL> 1 "register_operand" "d"))
+ (clobber (reg:CC CC_REGNUM))]
+ "(INTVAL (operands[4]) & 255) == 255"
+ "mvcle\t%0,%1,%Y2\;jo\t.-4"
+ [(set_attr "length" "8")
+ (set_attr "type" "vs")])
;
; cmpmemM instruction pattern(s).
;
@@ -6263,12 +6275,22 @@
(define_insn "rotl<mode>3"
[(set (match_operand:GPR 0 "register_operand" "=d")
(rotate:GPR (match_operand:GPR 1 "register_operand" "d")
- (match_operand:SI 2 "shift_count_operand" "Y")))]
+ (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
"TARGET_CPU_ZARCH"
"rll<g>\t%0,%1,%Y2"
[(set_attr "op_type" "RSE")
(set_attr "atype" "reg")])
+(define_insn "*rotl<mode>3_and"
+ [(set (match_operand:GPR 0 "register_operand" "=d")
+ (rotate:GPR (match_operand:GPR 1 "register_operand" "d")
+ (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
+ (match_operand:SI 3 "const_int_operand" "n"))))]
+ "TARGET_CPU_ZARCH && (INTVAL (operands[3]) & 63) == 63"
+ "rll<g>\t%0,%1,%Y2"
+ [(set_attr "op_type" "RSE")
+ (set_attr "atype" "reg")])
+
;;
;;- Shift instructions.
@@ -6281,14 +6303,14 @@
(define_expand "<shift>di3"
[(set (match_operand:DI 0 "register_operand" "")
(SHIFT:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:SI 2 "shift_count_operand" "")))]
+ (match_operand:SI 2 "shift_count_or_setmem_operand" "")))]
""
"")
(define_insn "*<shift>di3_31"
[(set (match_operand:DI 0 "register_operand" "=d")
(SHIFT:DI (match_operand:DI 1 "register_operand" "0")
- (match_operand:SI 2 "shift_count_operand" "Y")))]
+ (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
"!TARGET_64BIT"
"s<lr>dl\t%0,%Y2"
[(set_attr "op_type" "RS")
@@ -6297,12 +6319,32 @@
(define_insn "*<shift>di3_64"
[(set (match_operand:DI 0 "register_operand" "=d")
(SHIFT:DI (match_operand:DI 1 "register_operand" "d")
- (match_operand:SI 2 "shift_count_operand" "Y")))]
+ (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
"TARGET_64BIT"
"s<lr>lg\t%0,%1,%Y2"
[(set_attr "op_type" "RSE")
(set_attr "atype" "reg")])
+(define_insn "*<shift>di3_31_and"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (SHIFT:DI (match_operand:DI 1 "register_operand" "0")
+ (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
+ (match_operand:SI 3 "const_int_operand" "n"))))]
+ "!TARGET_64BIT && (INTVAL (operands[3]) & 63) == 63"
+ "s<lr>dl\t%0,%Y2"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "reg")])
+
+(define_insn "*<shift>di3_64_and"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (SHIFT:DI (match_operand:DI 1 "register_operand" "d")
+ (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
+ (match_operand:SI 3 "const_int_operand" "n"))))]
+ "TARGET_64BIT && (INTVAL (operands[3]) & 63) == 63"
+ "s<lr>lg\t%0,%1,%Y2"
+ [(set_attr "op_type" "RSE")
+ (set_attr "atype" "reg")])
+
;
; ashrdi3 instruction pattern(s).
;
@@ -6311,7 +6353,7 @@
[(parallel
[(set (match_operand:DI 0 "register_operand" "")
(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:SI 2 "shift_count_operand" "")))
+ (match_operand:SI 2 "shift_count_or_setmem_operand" "")))
(clobber (reg:CC CC_REGNUM))])]
""
"")
@@ -6319,7 +6361,7 @@
(define_insn "*ashrdi3_cc_31"
[(set (reg CC_REGNUM)
(compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
- (match_operand:SI 2 "shift_count_operand" "Y"))
+ (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
(const_int 0)))
(set (match_operand:DI 0 "register_operand" "=d")
(ashiftrt:DI (match_dup 1) (match_dup 2)))]
@@ -6331,7 +6373,7 @@
(define_insn "*ashrdi3_cconly_31"
[(set (reg CC_REGNUM)
(compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
- (match_operand:SI 2 "shift_count_operand" "Y"))
+ (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
(const_int 0)))
(clobber (match_scratch:DI 0 "=d"))]
"!TARGET_64BIT && s390_match_ccmode(insn, CCSmode)"
@@ -6342,7 +6384,7 @@
(define_insn "*ashrdi3_31"
[(set (match_operand:DI 0 "register_operand" "=d")
(ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
- (match_operand:SI 2 "shift_count_operand" "Y")))
+ (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))
(clobber (reg:CC CC_REGNUM))]
"!TARGET_64BIT"
"srda\t%0,%Y2"
@@ -6352,7 +6394,7 @@
(define_insn "*ashrdi3_cc_64"
[(set (reg CC_REGNUM)
(compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
- (match_operand:SI 2 "shift_count_operand" "Y"))
+ (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
(const_int 0)))
(set (match_operand:DI 0 "register_operand" "=d")
(ashiftrt:DI (match_dup 1) (match_dup 2)))]
@@ -6364,7 +6406,7 @@
(define_insn "*ashrdi3_cconly_64"
[(set (reg CC_REGNUM)
(compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
- (match_operand:SI 2 "shift_count_operand" "Y"))
+ (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
(const_int 0)))
(clobber (match_scratch:DI 0 "=d"))]
"s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
@@ -6375,7 +6417,7 @@
(define_insn "*ashrdi3_64"
[(set (match_operand:DI 0 "register_operand" "=d")
(ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
- (match_operand:SI 2 "shift_count_operand" "Y")))
+ (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))
(clobber (reg:CC CC_REGNUM))]
"TARGET_64BIT"
"srag\t%0,%1,%Y2"
@@ -6383,6 +6425,84 @@
(set_attr "atype" "reg")])
+; shift pattern with implicit ANDs
+
+(define_insn "*ashrdi3_cc_31_and"
+ [(set (reg CC_REGNUM)
+ (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
+ (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
+ (match_operand:SI 3 "const_int_operand" "n")))
+ (const_int 0)))
+ (set (match_operand:DI 0 "register_operand" "=d")
+ (ashiftrt:DI (match_dup 1) (and:SI (match_dup 2) (match_dup 3))))]
+ "!TARGET_64BIT && s390_match_ccmode(insn, CCSmode)
+ && (INTVAL (operands[3]) & 63) == 63"
+ "srda\t%0,%Y2"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "reg")])
+
+(define_insn "*ashrdi3_cconly_31_and"
+ [(set (reg CC_REGNUM)
+ (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
+ (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
+ (match_operand:SI 3 "const_int_operand" "n")))
+ (const_int 0)))
+ (clobber (match_scratch:DI 0 "=d"))]
+ "!TARGET_64BIT && s390_match_ccmode(insn, CCSmode)
+ && (INTVAL (operands[3]) & 63) == 63"
+ "srda\t%0,%Y2"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "reg")])
+
+(define_insn "*ashrdi3_31_and"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
+ (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
+ (match_operand:SI 3 "const_int_operand" "n"))))
+ (clobber (reg:CC CC_REGNUM))]
+ "!TARGET_64BIT && (INTVAL (operands[3]) & 63) == 63"
+ "srda\t%0,%Y2"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "reg")])
+
+(define_insn "*ashrdi3_cc_64_and"
+ [(set (reg CC_REGNUM)
+ (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
+ (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
+ (match_operand:SI 3 "const_int_operand" "n")))
+ (const_int 0)))
+ (set (match_operand:DI 0 "register_operand" "=d")
+ (ashiftrt:DI (match_dup 1) (and:SI (match_dup 2) (match_dup 3))))]
+ "TARGET_64BIT && s390_match_ccmode(insn, CCSmode)
+ && (INTVAL (operands[3]) & 63) == 63"
+ "srag\t%0,%1,%Y2"
+ [(set_attr "op_type" "RSE")
+ (set_attr "atype" "reg")])
+
+(define_insn "*ashrdi3_cconly_64_and"
+ [(set (reg CC_REGNUM)
+ (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
+ (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
+ (match_operand:SI 3 "const_int_operand" "n")))
+ (const_int 0)))
+ (clobber (match_scratch:DI 0 "=d"))]
+ "TARGET_64BIT && s390_match_ccmode(insn, CCSmode)
+ && (INTVAL (operands[3]) & 63) == 63"
+ "srag\t%0,%1,%Y2"
+ [(set_attr "op_type" "RSE")
+ (set_attr "atype" "reg")])
+
+(define_insn "*ashrdi3_64_and"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
+ (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
+ (match_operand:SI 3 "const_int_operand" "n"))))
+ (clobber (reg:CC CC_REGNUM))]
+ "TARGET_64BIT && (INTVAL (operands[3]) & 63) == 63"
+ "srag\t%0,%1,%Y2"
+ [(set_attr "op_type" "RSE")
+ (set_attr "atype" "reg")])
+
;
; (ashl|lshr)si3 instruction pattern(s).
;
@@ -6390,12 +6510,22 @@
(define_insn "<shift>si3"
[(set (match_operand:SI 0 "register_operand" "=d")
(SHIFT:SI (match_operand:SI 1 "register_operand" "0")
- (match_operand:SI 2 "shift_count_operand" "Y")))]
+ (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
""
"s<lr>l\t%0,%Y2"
[(set_attr "op_type" "RS")
(set_attr "atype" "reg")])
+(define_insn "*<shift>si3_and"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (SHIFT:SI (match_operand:SI 1 "register_operand" "0")
+ (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
+ (match_operand:SI 3 "const_int_operand" "n"))))]
+ "(INTVAL (operands[3]) & 63) == 63"
+ "s<lr>l\t%0,%Y2"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "reg")])
+
;
; ashrsi3 instruction pattern(s).
;
@@ -6403,7 +6533,7 @@
(define_insn "*ashrsi3_cc"
[(set (reg CC_REGNUM)
(compare (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
- (match_operand:SI 2 "shift_count_operand" "Y"))
+ (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
(const_int 0)))
(set (match_operand:SI 0 "register_operand" "=d")
(ashiftrt:SI (match_dup 1) (match_dup 2)))]
@@ -6416,7 +6546,7 @@
(define_insn "*ashrsi3_cconly"
[(set (reg CC_REGNUM)
(compare (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
- (match_operand:SI 2 "shift_count_operand" "Y"))
+ (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
(const_int 0)))
(clobber (match_scratch:SI 0 "=d"))]
"s390_match_ccmode(insn, CCSmode)"
@@ -6427,13 +6557,52 @@
(define_insn "ashrsi3"
[(set (match_operand:SI 0 "register_operand" "=d")
(ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
- (match_operand:SI 2 "shift_count_operand" "Y")))
+ (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))
(clobber (reg:CC CC_REGNUM))]
""
"sra\t%0,%Y2"
[(set_attr "op_type" "RS")
(set_attr "atype" "reg")])
+; with implicit ANDs
+
+(define_insn "*ashrsi3_cc_and"
+ [(set (reg CC_REGNUM)
+ (compare (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
+ (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
+ (match_operand:SI 3 "const_int_operand" "n")))
+ (const_int 0)))
+ (set (match_operand:SI 0 "register_operand" "=d")
+ (ashiftrt:SI (match_dup 1) (and:SI (match_dup 2) (match_dup 3))))]
+ "s390_match_ccmode(insn, CCSmode) && (INTVAL (operands[3]) & 63) == 63"
+ "sra\t%0,%Y2"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "reg")])
+
+
+(define_insn "*ashrsi3_cconly_and"
+ [(set (reg CC_REGNUM)
+ (compare (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
+ (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
+ (match_operand:SI 3 "const_int_operand" "n")))
+ (const_int 0)))
+ (clobber (match_scratch:SI 0 "=d"))]
+ "s390_match_ccmode(insn, CCSmode) && (INTVAL (operands[3]) & 63) == 63"
+ "sra\t%0,%Y2"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "reg")])
+
+(define_insn "*ashrsi3_and"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
+ (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
+ (match_operand:SI 3 "const_int_operand" "n"))))
+ (clobber (reg:CC CC_REGNUM))]
+ "(INTVAL (operands[3]) & 63) == 63"
+ "sra\t%0,%Y2"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "reg")])
+
;;
;; Branch instruction patterns.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8d9986e..dfe9d4d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2005-12-08 Andreas Krebbel <krebbel1@de.ibm.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ PR target/25268
+ * gcc.c-torture/compile/20051207-1.c: New test.
+
2005-12-07 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* g++.dg/other/i386-1.C, gcc.c-torture/execute/990413-2.x,
diff --git a/gcc/testsuite/gcc.c-torture/compile/20051207-1.c b/gcc/testsuite/gcc.c-torture/compile/20051207-1.c
new file mode 100644
index 0000000..9baa63b
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20051207-1.c
@@ -0,0 +1,7 @@
+/* PR target/25268 */
+
+long long
+foo (long long x, int y)
+{
+ return x << ((y + 1) & 63);
+}