OSDN Git Service

* i386.md (addqi_1_slp, subqi_1_slp
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 11 Jun 2002 23:57:10 +0000 (23:57 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 11 Jun 2002 23:57:10 +0000 (23:57 +0000)
(andqi_ext0, testqi_ext0): Remove unnecesary check.
(addhi*, addqi*): Simplify "dec" condition.
(testsi to testqi splitters): Remove TARGET_PROMOTE_QImode check.
(and, or, xor to QImode splitters): New.
(iorqi_ext*): New.
(xorqi_ext_0): New.
(xorqi_ext_1): Rename to xorqi_ext_2; bring to sync with and versions.
(andqi_ext_1_rex64): New.
(ashrqi*_slp): New.
(ashlqi*_slp): New.
(lshlqi*_slp): New.
(rotrqi3*_slp): New.
(rotlqi3*_slp): New.

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

gcc/ChangeLog
gcc/config/i386/i386.md

index 1e1174d..d5f7f83 100644 (file)
@@ -1,3 +1,20 @@
+Wed Jun 12 01:50:28 CEST 2002  Jan Hubicka  <jh@suse.cz>
+
+       * i386.md (addqi_1_slp, subqi_1_slp
+       (andqi_ext0, testqi_ext0): Remove unnecesary check.
+       (addhi*, addqi*): Simplify "dec" condition.
+       (testsi to testqi splitters): Remove TARGET_PROMOTE_QImode check.
+       (and, or, xor to QImode splitters): New.
+       (iorqi_ext*): New.
+       (xorqi_ext_0): New.
+       (xorqi_ext_1): Rename to xorqi_ext_2; bring to sync with and versions.
+       (andqi_ext_1_rex64): New.
+       (ashrqi*_slp): New.
+       (ashlqi*_slp): New.
+       (lshlqi*_slp): New.
+       (rotrqi3*_slp): New.
+       (rotlqi3*_slp): New.
+
 2002-06-11  Geoffrey Keating  <geoffk@redhat.com>
 
        * config.gcc (powerpc*-*-*, rs6000-*-*-*): Don't bother including
index fd2cb47..df0f117 100644 (file)
     case TYPE_INCDEC:
       if (operands[2] == const1_rtx)
        return "inc{w}\t%0";
-      else if (operands[2] == constm1_rtx
-              || (GET_CODE (operands[2]) == CONST_INT
-                  && INTVAL (operands[2]) == 65535))
+      else if (operands[2] == constm1_rtx)
        return "dec{w}\t%0";
       abort();
 
     case TYPE_INCDEC:
       if (operands[2] == const1_rtx)
        return "inc{w}\t%0";
-      else if (operands[2] == constm1_rtx
-              || (GET_CODE (operands[2]) == CONST_INT
-                  && INTVAL (operands[2]) == 65535))
+      else if (operands[2] == constm1_rtx)
        return "dec{w}\t%0";
       abort();
 
     case TYPE_INCDEC:
       if (operands[2] == const1_rtx)
        return "inc{w}\t%0";
-      else if (operands[2] == constm1_rtx
-              || (GET_CODE (operands[2]) == CONST_INT
-                  && INTVAL (operands[2]) == 65535))
+      else if (operands[2] == constm1_rtx)
        return "dec{w}\t%0";
       abort();
 
     case TYPE_INCDEC:
       if (operands[2] == const1_rtx)
        return "inc{w}\t%0";
-      else if (operands[2] == constm1_rtx
-              || (GET_CODE (operands[2]) == CONST_INT
-                  && INTVAL (operands[2]) == 65535))
+      else if (operands[2] == constm1_rtx)
        return "dec{w}\t%0";
       abort();
 
   switch (get_attr_type (insn))
     {
     case TYPE_INCDEC:
-      if (operands[2] == constm1_rtx
-         || (GET_CODE (operands[2]) == CONST_INT
-             && INTVAL (operands[2]) == 65535))
+      if (operands[2] == constm1_rtx)
         return "inc{w}\t%0";
       else if (operands[2] == const1_rtx)
         return "dec{w}\t%0";
     case TYPE_INCDEC:
       if (operands[2] == const1_rtx)
        return "inc{w}\t%0";
-      else if (operands[2] == constm1_rtx
-              || (GET_CODE (operands[2]) == CONST_INT
-                  && INTVAL (operands[2]) == 65535))
+      else if (operands[2] == constm1_rtx)
        return "dec{w}\t%0";
       abort();
 
     case TYPE_INCDEC:
       if (operands[2] == const1_rtx)
        return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
-      else if (operands[2] == constm1_rtx
-              || (GET_CODE (operands[2]) == CONST_INT
-                  && INTVAL (operands[2]) == 255))
+      else if (operands[2] == constm1_rtx)
        return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
       abort();
 
     case TYPE_INCDEC:
       if (operands[2] == const1_rtx)
        return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
-      else if (operands[2] == constm1_rtx
-              || (GET_CODE (operands[2]) == CONST_INT
-                  && INTVAL (operands[2]) == 255))
+      else if (operands[2] == constm1_rtx)
        return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
       abort();
 
        (const_string "alu")))
    (set_attr "mode" "QI,QI,SI")])
 
+(define_insn "*addqi_1_slp"
+  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
+       (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
+                (match_operand:QI 2 "general_operand" "qn,qnm")))
+   (clobber (reg:CC 17))]
+  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
+   && ix86_binary_operator_ok (PLUS, QImode, operands)"
+{
+  switch (get_attr_type (insn))
+    {
+    case TYPE_INCDEC:
+      if (operands[2] == const1_rtx)
+       return "inc{b}\t%0";
+      else if (operands[2] == constm1_rtx)
+       return "dec{b}\t%0";
+      abort();
+
+    default:
+      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
+      if (GET_CODE (operands[2]) == CONST_INT
+         && INTVAL (operands[2]) < 0)
+       {
+         operands[2] = GEN_INT (-INTVAL (operands[2]));
+         return "sub{b}\t{%2, %0|%0, %2}";
+       }
+      return "add{b}\t{%2, %0|%0, %2}";
+    }
+}
+  [(set (attr "type")
+     (if_then_else (match_operand:QI 2 "incdec_operand" "")
+       (const_string "incdec")
+       (const_string "alu")))
+   (set_attr "mode" "QI")])
+
 (define_insn "*addqi_2"
   [(set (reg 17)
        (compare
   [(set_attr "type" "alu")
    (set_attr "mode" "QI")])
 
+(define_insn "*subqi_1_slp"
+  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
+       (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
+                 (match_operand:QI 2 "general_operand" "qn,qmn")))
+   (clobber (reg:CC 17))]
+  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
+   && ix86_binary_operator_ok (MINUS, QImode, operands)"
+  "sub{b}\t{%2, %0|%0, %2}"
+  [(set_attr "type" "alu")
+   (set_attr "mode" "QI")])
+
 (define_insn "*subqi_2"
   [(set (reg 17)
        (compare
              (const_int 8))
            (match_operand 1 "const_int_operand" "n"))
          (const_int 0)))]
-  "(unsigned HOST_WIDE_INT) INTVAL (operands[1]) <= 0xff
-   && ix86_match_ccmode (insn, CCNOmode)"
+  "ix86_match_ccmode (insn, CCNOmode)"
   "test{b}\t{%1, %h0|%h0, %1}"
   [(set_attr "type" "test")
    (set_attr "mode" "QI")
          (and (match_operand 0 "register_operand" "")
               (match_operand 1 "const_int_operand" ""))
          (const_int 0)))]
-   "(!TARGET_PROMOTE_QImode || optimize_size)
-    && reload_completed
+   "reload_completed
     && QI_REG_P (operands[0])
     && ((ix86_match_ccmode (insn, CCZmode)
         && !(INTVAL (operands[1]) & ~(255 << 8)))
          (and (match_operand 0 "nonimmediate_operand" "")
               (match_operand 1 "const_int_operand" ""))
          (const_int 0)))]
-   "(!TARGET_PROMOTE_QImode || optimize_size)
-    && reload_completed
+   "reload_completed
     && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
     && ((ix86_match_ccmode (insn, CCZmode)
         && !(INTVAL (operands[1]) & ~255))
        (and:QI (match_dup 0)
                (match_operand:QI 1 "general_operand" "qi,qmi")))
    (clobber (reg:CC 17))]
-  ""
+  "! TARGET_PARTIAL_REG_STALL || optimize_size"
   "and{b}\t{%1, %0|%0, %1}"
   [(set_attr "type" "alu1")
    (set_attr "mode" "QI")])
                 (const_int 0)))
    (set (strict_low_part (match_dup 0))
        (and:QI (match_dup 0) (match_dup 1)))]
-  "ix86_match_ccmode (insn, CCNOmode)"
+  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
+   && ix86_match_ccmode (insn, CCNOmode)"
   "and{b}\t{%1, %0|%0, %1}"
   [(set_attr "type" "alu1")
    (set_attr "mode" "QI")])
            (const_int 8))
          (match_operand 2 "const_int_operand" "n")))
    (clobber (reg:CC 17))]
-  "(unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
+  ""
   "and{b}\t{%2, %h0|%h0, %2}"
   [(set_attr "type" "alu")
    (set_attr "length_immediate" "1")
            (const_int 8)
            (const_int 8))
          (match_dup 2)))]
-  "ix86_match_ccmode (insn, CCNOmode)
-   && (unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
+  "ix86_match_ccmode (insn, CCNOmode)"
   "and{b}\t{%2, %h0|%h0, %2}"
   [(set_attr "type" "alu")
    (set_attr "length_immediate" "1")
   [(set_attr "type" "alu")
    (set_attr "length_immediate" "0")
    (set_attr "mode" "QI")])
+
+;; Convert wide AND instructions with immediate operand to shorter QImode
+;; equivalents when possible.
+;; Don't do the splitting with memory operands, since it intoduces risc
+;; of memory mismatch stalls.  We may want to do the splitting for optimizing
+;; for size, but that can (should?) be handled by generic code instead.
+(define_split
+  [(set (match_operand 0 "register_operand" "")
+       (and (match_operand 1 "register_operand" "")
+            (match_operand 2 "const_int_operand" "")))
+   (clobber (reg:CC 17))]
+   "reload_completed
+    && QI_REG_P (operands[0])
+    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
+    && !(~INTVAL (operands[2]) & ~(255 << 8))
+    && GET_MODE (operands[0]) != QImode"
+  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
+                  (and:SI (zero_extract:SI (match_dup 1)
+                                           (const_int 8) (const_int 8))
+                          (match_dup 2)))
+             (clobber (reg:CC 17))])]
+  "operands[0] = gen_lowpart (SImode, operands[0]);
+   operands[1] = gen_lowpart (SImode, operands[1]);
+   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
+
+;; Since AND can be encoded with sign extended immediate, this is only
+;; profitable when 7th bit is not set.
+(define_split
+  [(set (match_operand 0 "register_operand" "")
+       (and (match_operand 1 "general_operand" "")
+            (match_operand 2 "const_int_operand" "")))
+   (clobber (reg:CC 17))]
+   "reload_completed
+    && ANY_QI_REG_P (operands[0])
+    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
+    && !(~INTVAL (operands[2]) & ~255)
+    && !(INTVAL (operands[2]) & 128)
+    && GET_MODE (operands[0]) != QImode"
+  [(parallel [(set (strict_low_part (match_dup 0))
+                  (and:QI (match_dup 1)
+                          (match_dup 2)))
+             (clobber (reg:CC 17))])]
+  "operands[0] = gen_lowpart (QImode, operands[0]);
+   operands[1] = gen_lowpart (QImode, operands[1]);
+   operands[2] = gen_lowpart (QImode, operands[2]);")
 \f
 ;; Logical inclusive OR instructions
 
        (ior:QI (match_dup 0)
                (match_operand:QI 1 "general_operand" "qmi,qi")))
    (clobber (reg:CC 17))]
-  ""
+  "! TARGET_PARTIAL_REG_STALL || optimize_size"
   "or{b}\t{%1, %0|%0, %1}"
   [(set_attr "type" "alu1")
    (set_attr "mode" "QI")])
                 (const_int 0)))
    (set (strict_low_part (match_dup 0))
        (ior:QI (match_dup 0) (match_dup 1)))]
-  "ix86_match_ccmode (insn, CCNOmode)"
+  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
+   && ix86_match_ccmode (insn, CCNOmode)"
   "or{b}\t{%1, %0|%0, %1}"
   [(set_attr "type" "alu1")
    (set_attr "mode" "QI")])
   [(set_attr "type" "alu")
    (set_attr "mode" "QI")])
 
+(define_insn "iorqi_ext_0"
+  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
+                        (const_int 8)
+                        (const_int 8))
+       (ior:SI 
+         (zero_extract:SI
+           (match_operand 1 "ext_register_operand" "0")
+           (const_int 8)
+           (const_int 8))
+         (match_operand 2 "const_int_operand" "n")))
+   (clobber (reg:CC 17))]
+  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
+  "or{b}\t{%2, %h0|%h0, %2}"
+  [(set_attr "type" "alu")
+   (set_attr "length_immediate" "1")
+   (set_attr "mode" "QI")])
+
+(define_insn "*iorqi_ext_1"
+  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
+                        (const_int 8)
+                        (const_int 8))
+       (ior:SI 
+         (zero_extract:SI
+           (match_operand 1 "ext_register_operand" "0")
+           (const_int 8)
+           (const_int 8))
+         (zero_extend:SI
+           (match_operand:QI 2 "general_operand" "Qm"))))
+   (clobber (reg:CC 17))]
+  "!TARGET_64BIT
+   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
+  "or{b}\t{%2, %h0|%h0, %2}"
+  [(set_attr "type" "alu")
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "QI")])
+
+(define_insn "*iorqi_ext_1_rex64"
+  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
+                        (const_int 8)
+                        (const_int 8))
+       (ior:SI 
+         (zero_extract:SI
+           (match_operand 1 "ext_register_operand" "0")
+           (const_int 8)
+           (const_int 8))
+         (zero_extend:SI
+           (match_operand 2 "ext_register_operand" "Q"))))
+   (clobber (reg:CC 17))]
+  "TARGET_64BIT
+   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
+  "or{b}\t{%2, %h0|%h0, %2}"
+  [(set_attr "type" "alu")
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "QI")])
+
+(define_insn "*iorqi_ext_2"
+  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
+                        (const_int 8)
+                        (const_int 8))
+       (ior:SI 
+         (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
+                          (const_int 8)
+                          (const_int 8))
+         (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
+                          (const_int 8)
+                          (const_int 8))))
+   (clobber (reg:CC 17))]
+  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
+  "ior{b}\t{%h2, %h0|%h0, %h2}"
+  [(set_attr "type" "alu")
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "QI")])
+
+(define_split
+  [(set (match_operand 0 "register_operand" "")
+       (ior (match_operand 1 "register_operand" "")
+            (match_operand 2 "const_int_operand" "")))
+   (clobber (reg:CC 17))]
+   "reload_completed
+    && QI_REG_P (operands[0])
+    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
+    && !(INTVAL (operands[2]) & ~(255 << 8))
+    && GET_MODE (operands[0]) != QImode"
+  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
+                  (ior:SI (zero_extract:SI (match_dup 1)
+                                           (const_int 8) (const_int 8))
+                          (match_dup 2)))
+             (clobber (reg:CC 17))])]
+  "operands[0] = gen_lowpart (SImode, operands[0]);
+   operands[1] = gen_lowpart (SImode, operands[1]);
+   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
+
+;; Since OR can be encoded with sign extended immediate, this is only
+;; profitable when 7th bit is set.
+(define_split
+  [(set (match_operand 0 "register_operand" "")
+       (ior (match_operand 1 "general_operand" "")
+            (match_operand 2 "const_int_operand" "")))
+   (clobber (reg:CC 17))]
+   "reload_completed
+    && ANY_QI_REG_P (operands[0])
+    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
+    && !(INTVAL (operands[2]) & ~255)
+    && (INTVAL (operands[2]) & 128)
+    && GET_MODE (operands[0]) != QImode"
+  [(parallel [(set (strict_low_part (match_dup 0))
+                  (ior:QI (match_dup 1)
+                          (match_dup 2)))
+             (clobber (reg:CC 17))])]
+  "operands[0] = gen_lowpart (QImode, operands[0]);
+   operands[1] = gen_lowpart (QImode, operands[1]);
+   operands[2] = gen_lowpart (QImode, operands[2]);")
 \f
 ;; Logical XOR instructions
 
   [(set_attr "type" "alu")
    (set_attr "mode" "QI,QI,SI")])
 
+(define_insn "xorqi_ext_0"
+  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
+                        (const_int 8)
+                        (const_int 8))
+       (xor:SI 
+         (zero_extract:SI
+           (match_operand 1 "ext_register_operand" "0")
+           (const_int 8)
+           (const_int 8))
+         (match_operand 2 "const_int_operand" "n")))
+   (clobber (reg:CC 17))]
+  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
+  "xor{b}\t{%2, %h0|%h0, %2}"
+  [(set_attr "type" "alu")
+   (set_attr "length_immediate" "1")
+   (set_attr "mode" "QI")])
+
 (define_insn "*xorqi_ext_1"
   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
                         (const_int 8)
                         (const_int 8))
        (xor:SI 
+         (zero_extract:SI
+           (match_operand 1 "ext_register_operand" "0")
+           (const_int 8)
+           (const_int 8))
+         (zero_extend:SI
+           (match_operand:QI 2 "general_operand" "Qm"))))
+   (clobber (reg:CC 17))]
+  "!TARGET_64BIT
+   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
+  "xor{b}\t{%2, %h0|%h0, %2}"
+  [(set_attr "type" "alu")
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "QI")])
+
+(define_insn "*xorqi_ext_1_rex64"
+  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
+                        (const_int 8)
+                        (const_int 8))
+       (xor:SI 
+         (zero_extract:SI
+           (match_operand 1 "ext_register_operand" "0")
+           (const_int 8)
+           (const_int 8))
+         (zero_extend:SI
+           (match_operand 2 "ext_register_operand" "Q"))))
+   (clobber (reg:CC 17))]
+  "TARGET_64BIT
+   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
+  "xor{b}\t{%2, %h0|%h0, %2}"
+  [(set_attr "type" "alu")
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "QI")])
+
+(define_insn "*xorqi_ext_2"
+  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
+                        (const_int 8)
+                        (const_int 8))
+       (xor:SI 
          (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
                           (const_int 8)
                           (const_int 8))
                           (const_int 8)
                           (const_int 8))))
    (clobber (reg:CC 17))]
-  ""
+  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
   "xor{b}\t{%h2, %h0|%h0, %h2}"
   [(set_attr "type" "alu")
    (set_attr "length_immediate" "0")
            (match_dup 2)))])]
   ""
   "")
+
+(define_split
+  [(set (match_operand 0 "register_operand" "")
+       (xor (match_operand 1 "register_operand" "")
+            (match_operand 2 "const_int_operand" "")))
+   (clobber (reg:CC 17))]
+   "reload_completed
+    && QI_REG_P (operands[0])
+    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
+    && !(INTVAL (operands[2]) & ~(255 << 8))
+    && GET_MODE (operands[0]) != QImode"
+  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
+                  (xor:SI (zero_extract:SI (match_dup 1)
+                                           (const_int 8) (const_int 8))
+                          (match_dup 2)))
+             (clobber (reg:CC 17))])]
+  "operands[0] = gen_lowpart (SImode, operands[0]);
+   operands[1] = gen_lowpart (SImode, operands[1]);
+   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
+
+;; Since XOR can be encoded with sign extended immediate, this is only
+;; profitable when 7th bit is set.
+(define_split
+  [(set (match_operand 0 "register_operand" "")
+       (xor (match_operand 1 "general_operand" "")
+            (match_operand 2 "const_int_operand" "")))
+   (clobber (reg:CC 17))]
+   "reload_completed
+    && ANY_QI_REG_P (operands[0])
+    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
+    && !(INTVAL (operands[2]) & ~255)
+    && (INTVAL (operands[2]) & 128)
+    && GET_MODE (operands[0]) != QImode"
+  [(parallel [(set (strict_low_part (match_dup 0))
+                  (xor:QI (match_dup 1)
+                          (match_dup 2)))
+             (clobber (reg:CC 17))])]
+  "operands[0] = gen_lowpart (QImode, operands[0]);
+   operands[1] = gen_lowpart (QImode, operands[1]);
+   operands[2] = gen_lowpart (QImode, operands[2]);")
 \f
 ;; Negation instructions
 
        (const_string "2")
        (const_string "*")))])
 
+(define_insn "*ashrqi3_1_one_bit_slp"
+  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
+       (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
+                    (match_operand:QI 2 "const_int_1_operand" "")))
+   (clobber (reg:CC 17))]
+  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
+   && (! TARGET_PARTIAL_REG_STALL || optimize_size)
+   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
+  "sar{b}\t%0"
+  [(set_attr "type" "ishift")
+   (set (attr "length") 
+     (if_then_else (match_operand 0 "register_operand" "") 
+       (const_string "2")
+       (const_string "*")))])
+
 (define_insn "*ashrqi3_1"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
        (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
   [(set_attr "type" "ishift")
    (set_attr "mode" "QI")])
 
+(define_insn "*ashrqi3_1_slp"
+  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
+       (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
+                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
+   (clobber (reg:CC 17))]
+  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
+   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
+  "@
+   sar{b}\t{%2, %0|%0, %2}
+   sar{b}\t{%b2, %0|%0, %b2}"
+  [(set_attr "type" "ishift")
+   (set_attr "mode" "QI")])
+
 ;; This pattern can't accept a variable shift count, since shifts by
 ;; zero don't affect the flags.  We assume that shifts by constant
 ;; zero are optimized away.
        (const_string "2")
        (const_string "*")))])
 
+(define_insn "*lshrqi3_1_one_bit_slp"
+  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
+       (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
+                    (match_operand:QI 2 "const_int_1_operand" "")))
+   (clobber (reg:CC 17))]
+  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
+   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
+   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
+  "shr{b}\t%0"
+  [(set_attr "type" "ishift")
+   (set (attr "length") 
+     (if_then_else (match_operand 0 "register_operand" "") 
+       (const_string "2")
+       (const_string "*")))])
+
 (define_insn "*lshrqi3_1"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
        (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
   [(set_attr "type" "ishift")
    (set_attr "mode" "QI")])
 
+(define_insn "*lshrqi3_1_slp"
+  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
+       (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
+                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
+   (clobber (reg:CC 17))]
+  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
+   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
+  "@
+   shr{b}\t{%2, %0|%0, %2}
+   shr{b}\t{%b2, %0|%0, %b2}"
+  [(set_attr "type" "ishift")
+   (set_attr "mode" "QI")])
+
 ;; This pattern can't accept a variable shift count, since shifts by
 ;; zero don't affect the flags.  We assume that shifts by constant
 ;; zero are optimized away.
   "TARGET_QIMODE_MATH"
   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
 
+(define_insn "*rotlqi3_1_one_bit_slp"
+  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
+       (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
+                  (match_operand:QI 2 "const_int_1_operand" "")))
+   (clobber (reg:CC 17))]
+  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
+   && ix86_binary_operator_ok (ROTATE, QImode, operands)
+   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
+  "rol{b}\t%0"
+  [(set_attr "type" "rotate")
+   (set (attr "length") 
+     (if_then_else (match_operand 0 "register_operand" "") 
+       (const_string "2")
+       (const_string "*")))])
+
 (define_insn "*rotlqi3_1_one_bit"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
        (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
        (const_string "2")
        (const_string "*")))])
 
+(define_insn "*rotlqi3_1_slp"
+  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
+       (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
+                  (match_operand:QI 2 "nonmemory_operand" "I,c")))
+   (clobber (reg:CC 17))]
+  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
+   && ix86_binary_operator_ok (ROTATE, QImode, operands)"
+  "@
+   rol{b}\t{%2, %0|%0, %2}
+   rol{b}\t{%b2, %0|%0, %b2}"
+  [(set_attr "type" "rotate")
+   (set_attr "mode" "QI")])
+
 (define_insn "*rotlqi3_1"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
        (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
        (const_string "2")
        (const_string "*")))])
 
+(define_insn "*rotrqi3_1_one_bit_slp"
+  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
+       (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
+                    (match_operand:QI 2 "const_int_1_operand" "")))
+   (clobber (reg:CC 17))]
+  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
+   && ix86_binary_operator_ok (ROTATERT, QImode, operands)
+   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
+  "ror{b}\t%0"
+  [(set_attr "type" "rotate")
+   (set (attr "length") 
+     (if_then_else (match_operand 0 "register_operand" "") 
+       (const_string "2")
+       (const_string "*")))])
+
 (define_insn "*rotrqi3_1"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
        (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
    ror{b}\t{%b2, %0|%0, %b2}"
   [(set_attr "type" "rotate")
    (set_attr "mode" "QI")])
+
+(define_insn "*rotrqi3_1_slp"
+  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
+       (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
+                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
+   (clobber (reg:CC 17))]
+  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
+   && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
+  "@
+   ror{b}\t{%2, %0|%0, %2}
+   ror{b}\t{%b2, %0|%0, %b2}"
+  [(set_attr "type" "rotate")
+   (set_attr "mode" "QI")])
 \f
 ;; Bit set / bit test instructions