2005-12-08 Andreas Krebbel <krebbel1@de.ibm.com>
authorkrebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 8 Dec 2005 08:56:24 +0000 (08:56 +0000)
committerkrebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 8 Dec 2005 08:56:24 +0000 (08:56 +0000)
            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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@108220 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/s390/predicates.md
gcc/config/s390/s390-protos.h
gcc/config/s390/s390.c
gcc/config/s390/s390.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/20051207-1.c [new file with mode: 0644]

index 0a08ca7..6113f45 100644 (file)
@@ -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>
 
index a921d1f..de6e796 100644 (file)
        (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
index e62493d..710f4e7 100644 (file)
@@ -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 */
index 901b9b5..941e6f2 100644 (file)
@@ -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.  */
index cf484c3..c9ce6fd 100644 (file)
   [(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))])]
 (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))]
   [(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).
 ;
 (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.
 (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")
 (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).
 ;
   [(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))])]
   ""
   "")
 (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)))]
 (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)"
 (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"
 (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)))]
 (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"
 (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"
    (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).
 ;
 (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).
 ;
 (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)))]
 (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)"
 (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.
index 8d9986e..dfe9d4d 100644 (file)
@@ -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 (file)
index 0000000..9baa63b
--- /dev/null
@@ -0,0 +1,7 @@
+/* PR target/25268 */
+
+long long
+foo (long long x, int y)
+{
+  return x << ((y + 1) & 63);
+}