i386.md: Create new [right,left] rotate and right shift patterns to optimize shift...
authorJeffrey A Law <law@cygnus.com>
Fri, 16 Jun 2000 00:59:02 +0000 (00:59 +0000)
committerJeff Law <law@gcc.gnu.org>
Fri, 16 Jun 2000 00:59:02 +0000 (18:59 -0600)
* i386.md: Create new [right,left] rotate and right shift
patterns to optimize shift by 1 bit for certain ia32 processors.
Update patterns which perform left shifts to optimize shift by
1 bit for certain ia32 processors.
* i386.c (const_int_1_operand): New predicate.
* i386.h (PREDICATE_CODES): Handle const_int_1_operand.
* i386-protos.h (const_int_1_operand): Prototype.

From-SVN: r34569

gcc/ChangeLog
gcc/config/i386/i386-protos.h
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/config/i386/i386.md

index 216e7f4..7d1eec4 100644 (file)
@@ -1,3 +1,13 @@
+Thu Jun 15 18:56:12 2000  Jeffrey A Law  (law@cygnus.com)
+
+       * i386.md: Create new [right,left] rotate and right shift
+       patterns to optimize shift by 1 bit for certain ia32 processors.
+       Update patterns which perform left shifts to optimize shift by
+       1 bit for certain ia32 processors.
+       * i386.c (const_int_1_operand): New predicate.
+       * i386.h (PREDICATE_CODES): Handle const_int_1_operand.
+       * i386-protos.h (const_int_1_operand): Prototype.
+
 Wed Jun 14 23:46:26 2000  J"orn Rennecke <amylaar@cygnus.co.uk>
 
        * mips.c (machine_dependent_reorg): Fix braces for nested if.
index d7a4110..9d062dd 100644 (file)
@@ -41,6 +41,7 @@ extern int ix86_aligned_p PARAMS ((rtx));
 extern int standard_80387_constant_p PARAMS ((rtx));
 extern int symbolic_reference_mentioned_p PARAMS ((rtx));
 
+extern int const_int_1_operand PARAMS ((rtx, enum machine_mode));
 extern int symbolic_operand PARAMS ((rtx, enum machine_mode));
 extern int pic_symbolic_operand PARAMS ((rtx, enum machine_mode));
 extern int call_insn_operand PARAMS ((rtx, enum machine_mode));
index f91692a..722d52e 100644 (file)
@@ -981,6 +981,17 @@ function_arg (cum, mode, type, named)
   return ret;
 }
 \f
+
+/* Return nonzero if OP is (const_int 1), else return zero.  */
+
+int
+const_int_1_operand (op, mode)
+     rtx op;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+  return (GET_CODE (op) == CONST_INT && INTVAL (op) == 1);
+}
+
 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
    reference and a constant.  */
 
index 7bf706c..881f4ea 100644 (file)
@@ -2496,6 +2496,7 @@ do { long l;                                              \
 /* Define the codes that are matched by predicates in i386.c.  */
 
 #define PREDICATE_CODES                                                        \
+  {"const_int_1_operand", {CONST_INT}},                                        \
   {"symbolic_operand", {SYMBOL_REF, LABEL_REF, CONST}},                        \
   {"aligned_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,     \
                       LABEL_REF, SUBREG, REG, MEM}},                   \
index 36c9d1f..21cc145 100644 (file)
     default:
       if (REG_P (operands[2]))
        return \"sal{l}\\t{%b2, %0|%0, %b2}\";
+      else if (GET_CODE (operands[2]) == CONST_INT
+              && INTVAL (operands[2]) == 1
+              && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
+       return \"sal{l}\\t%0\";
       else
        return \"sal{l}\\t{%2, %0|%0, %2}\";
     }
     default:
       if (REG_P (operands[2]))
        return \"sal{l}\\t{%b2, %0|%0, %b2}\";
+      else if (GET_CODE (operands[2]) == CONST_INT
+              && INTVAL (operands[2]) == 1
+              && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
+       return \"sal{l}\\t%0\";
       else
        return \"sal{l}\\t{%2, %0|%0, %2}\";
     }
     default:
       if (REG_P (operands[2]))
        return \"sal{w}\\t{%b2, %0|%0, %b2}\";
+      else if (GET_CODE (operands[2]) == CONST_INT
+              && INTVAL (operands[2]) == 1
+              && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
+       return \"sal{w}\\t%0\";
       else
        return \"sal{w}\\t{%2, %0|%0, %2}\";
     }
     default:
       if (REG_P (operands[2]))
        return \"sal{w}\\t{%b2, %0|%0, %b2}\";
+      else if (GET_CODE (operands[2]) == CONST_INT
+              && INTVAL (operands[2]) == 1
+              && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
+       return \"sal{w}\\t%0\";
       else
        return \"sal{w}\\t{%2, %0|%0, %2}\";
     }
          else
            return \"sal{b}\\t{%b2, %0|%0, %b2}\";
        }
+      else if (GET_CODE (operands[2]) == CONST_INT
+              && INTVAL (operands[2]) == 1
+              && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
+       {
+          if (NON_QI_REG_P (operands[1]))
+           return \"sal{l}\\t%0\";
+         else
+           return \"sal{b}\\t%0\";
+       }
       else
        {
           if (NON_QI_REG_P (operands[1]))
     default:
       if (REG_P (operands[2]))
        return \"sal{b}\\t{%b2, %0|%0, %b2}\";
+      else if (GET_CODE (operands[2]) == CONST_INT
+              && INTVAL (operands[2]) == 1
+              && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
+       return \"sal{b}\\t%0\";
       else
        return \"sal{b}\\t{%2, %0|%0, %2}\";
     }
   ""
   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
 
+(define_insn "*ashrsi3_1_one_bit"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
+       (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
+                    (match_operand:QI 2 "const_int_1_operand" "")))
+   (clobber (reg:CC 17))]
+  "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
+   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
+  "sar{l}\\t%0"
+  [(set_attr "type" "ishift")
+   (set (attr "length") 
+     (if_then_else (match_operand:SI 0 "register_operand" "") 
+       (const_string "2")
+       (const_string "*")))])
+
 (define_insn "*ashrsi3_1"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
        (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
 ;; 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.
+(define_insn "*ashrsi3_one_bit_cmpno"
+  [(set (reg 17)
+       (compare
+         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
+                      (match_operand:QI 2 "const_int_1_operand" ""))
+         (const_int 0)))
+   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
+       (ashiftrt:SI (match_dup 1) (match_dup 2)))]
+  "ix86_match_ccmode (insn, CCNOmode)
+   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
+   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
+  "sar{l}\\t%0"
+  [(set_attr "type" "ishift")
+   (set (attr "length") 
+     (if_then_else (match_operand:SI 0 "register_operand" "") 
+       (const_string "2")
+       (const_string "*")))])
+
+;; 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.
 (define_insn "*ashrsi3_cmpno"
   [(set (reg 17)
        (compare
   "TARGET_HIMODE_MATH"
   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
 
+(define_insn "*ashrhi3_1_one_bit"
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
+       (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
+                    (match_operand:QI 2 "const_int_1_operand" "")))
+   (clobber (reg:CC 17))]
+  "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
+   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
+  "sar{w}\\t%0"
+  [(set_attr "type" "ishift")
+   (set (attr "length") 
+     (if_then_else (match_operand:SI 0 "register_operand" "") 
+       (const_string "2")
+       (const_string "*")))])
+
 (define_insn "*ashrhi3_1"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
        (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
 ;; 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.
+(define_insn "*ashrhi3_one_bit_cmpno"
+  [(set (reg 17)
+       (compare
+         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
+                      (match_operand:QI 2 "const_int_1_operand" ""))
+         (const_int 0)))
+   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
+       (ashiftrt:HI (match_dup 1) (match_dup 2)))]
+  "ix86_match_ccmode (insn, CCNOmode)
+   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
+   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
+  "sar{w}\\t%0"
+  [(set_attr "type" "ishift")
+   (set (attr "length") 
+     (if_then_else (match_operand:SI 0 "register_operand" "") 
+       (const_string "2")
+       (const_string "*")))])
+
+;; 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.
 (define_insn "*ashrhi3_cmpno"
   [(set (reg 17)
        (compare
   "TARGET_QIMODE_MATH"
   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
 
+(define_insn "*ashrqi3_1_one_bit"
+  [(set (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_PENTIUM || TARGET_PENTIUMPRO)"
+  "sar{b}\\t%0"
+  [(set_attr "type" "ishift")
+   (set (attr "length") 
+     (if_then_else (match_operand:SI 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")
 ;; 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.
+(define_insn "*ashrqi3_cmpno_one_bit"
+  [(set (reg 17)
+       (compare
+         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
+                      (match_operand:QI 2 "const_int_1_operand" "I"))
+         (const_int 0)))
+   (set (match_operand:QI 0 "nonimmediate_operand" "=rm")
+       (ashiftrt:QI (match_dup 1) (match_dup 2)))]
+  "ix86_match_ccmode (insn, CCNOmode)
+   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
+   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
+  "sar{b}\\t%0"
+  [(set_attr "type" "ishift")
+   (set (attr "length") 
+     (if_then_else (match_operand:SI 0 "register_operand" "") 
+       (const_string "2")
+       (const_string "*")))])
+
+;; 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.
 (define_insn "*ashrqi3_cmpno"
   [(set (reg 17)
        (compare
   ""
   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
 
+(define_insn "*lshrsi3_1_one_bit"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
+       (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
+                    (match_operand:QI 2 "const_int_1_operand" "")))
+   (clobber (reg:CC 17))]
+  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
+   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
+  "shr{l}\\t%0"
+  [(set_attr "type" "ishift")
+   (set (attr "length") 
+     (if_then_else (match_operand:SI 0 "register_operand" "") 
+       (const_string "2")
+       (const_string "*")))])
+
 (define_insn "*lshrsi3_1"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
        (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
 ;; 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.
+(define_insn "*lshrsi3_cmpno_one_bit"
+  [(set (reg 17)
+       (compare
+         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
+                      (match_operand:QI 2 "const_int_1_operand" ""))
+         (const_int 0)))
+   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
+       (lshiftrt:SI (match_dup 1) (match_dup 2)))]
+  "ix86_match_ccmode (insn, CCNOmode)
+   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
+   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
+  "shr{l}\\t%0"
+  [(set_attr "type" "ishift")
+   (set (attr "length") 
+     (if_then_else (match_operand:SI 0 "register_operand" "") 
+       (const_string "2")
+       (const_string "*")))])
+
+;; 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.
 (define_insn "*lshrsi3_cmpno"
   [(set (reg 17)
        (compare
   "TARGET_HIMODE_MATH"
   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
 
+(define_insn "*lshrhi3_1_one_bit"
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
+       (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
+                    (match_operand:QI 2 "const_int_1_operand" "")))
+   (clobber (reg:CC 17))]
+  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
+   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
+  "shr{w}\\t%0"
+  [(set_attr "type" "ishift")
+   (set (attr "length") 
+     (if_then_else (match_operand:SI 0 "register_operand" "") 
+       (const_string "2")
+       (const_string "*")))])
+
 (define_insn "*lshrhi3_1"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
        (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
 ;; 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.
+(define_insn "*lshrhi3_cmpno_one_bit"
+  [(set (reg 17)
+       (compare
+         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
+                      (match_operand:QI 2 "const_int_1_operand" ""))
+         (const_int 0)))
+   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
+       (lshiftrt:HI (match_dup 1) (match_dup 2)))]
+  "ix86_match_ccmode (insn, CCNOmode)
+   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
+   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
+  "shr{w}\\t%0"
+  [(set_attr "type" "ishift")
+   (set (attr "length") 
+     (if_then_else (match_operand:SI 0 "register_operand" "") 
+       (const_string "2")
+       (const_string "*")))])
+
+;; 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.
 (define_insn "*lshrhi3_cmpno"
   [(set (reg 17)
        (compare
   "TARGET_QIMODE_MATH"
   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
 
+(define_insn "*lshrqi3_1_one_bit"
+  [(set (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))]
+  "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:SI 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")
 ;; 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.
+(define_insn "*lshrqi2_cmpno_one_bit"
+  [(set (reg 17)
+       (compare
+         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
+                      (match_operand:QI 2 "const_int_1_operand" ""))
+         (const_int 0)))
+   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
+       (lshiftrt:QI (match_dup 1) (match_dup 2)))]
+  "ix86_match_ccmode (insn, CCNOmode)
+   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
+   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
+  "shr{b}\\t%0"
+  [(set_attr "type" "ishift")
+   (set (attr "length") 
+     (if_then_else (match_operand:SI 0 "register_operand" "") 
+       (const_string "2")
+       (const_string "*")))])
+
+;; 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.
 (define_insn "*lshrqi2_cmpno"
   [(set (reg 17)
        (compare
   ""
   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
 
+(define_insn "*rotlsi3_1_one_bit"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
+       (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
+                  (match_operand:QI 2 "const_int_1_operand" "")))
+   (clobber (reg:CC 17))]
+  "ix86_binary_operator_ok (ROTATE, SImode, operands)
+   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
+  "rol{l}\\t%0"
+  [(set_attr "type" "ishift")
+   (set (attr "length") 
+     (if_then_else (match_operand:SI 0 "register_operand" "") 
+       (const_string "2")
+       (const_string "*")))])
+
 (define_insn "*rotlsi3_1"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
        (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
   "TARGET_HIMODE_MATH"
   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
 
+(define_insn "*rotlhi3_1_one_bit"
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
+       (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
+                  (match_operand:QI 2 "const_int_1_operand" "")))
+   (clobber (reg:CC 17))]
+  "ix86_binary_operator_ok (ROTATE, HImode, operands)
+   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
+  "rol{w}\\t%0"
+  [(set_attr "type" "ishift")
+   (set (attr "length") 
+     (if_then_else (match_operand:SI 0 "register_operand" "") 
+       (const_string "2")
+       (const_string "*")))])
+
 (define_insn "*rotlhi3_1"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
        (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
   "TARGET_QIMODE_MATH"
   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
 
+(define_insn "*rotlqi3_1_one_bit"
+  [(set (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))]
+  "ix86_binary_operator_ok (ROTATE, QImode, operands)
+   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
+  "rol{b}\\t%0"
+  [(set_attr "type" "ishift")
+   (set (attr "length") 
+     (if_then_else (match_operand:SI 0 "register_operand" "") 
+       (const_string "2")
+       (const_string "*")))])
+
 (define_insn "*rotlqi3_1"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
        (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
   ""
   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
 
+(define_insn "*rotrsi3_1_one_bit"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
+       (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
+                    (match_operand:QI 2 "const_int_1_operand" "")))
+   (clobber (reg:CC 17))]
+  "ix86_binary_operator_ok (ROTATERT, SImode, operands)
+   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
+  "ror{l}\\t%0"
+  [(set_attr "type" "ishift")
+   (set (attr "length") 
+     (if_then_else (match_operand:SI 0 "register_operand" "") 
+       (const_string "2")
+       (const_string "*")))])
+
 (define_insn "*rotrsi3_1"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
        (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
   "TARGET_HIMODE_MATH"
   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
 
+(define_insn "*rotrhi3_one_bit"
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
+       (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
+                    (match_operand:QI 2 "const_int_1_operand" "")))
+   (clobber (reg:CC 17))]
+  "ix86_binary_operator_ok (ROTATERT, HImode, operands)
+   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
+  "ror{w}\\t%0"
+  [(set_attr "type" "ishift")
+   (set (attr "length") 
+     (if_then_else (match_operand:SI 0 "register_operand" "") 
+       (const_string "2")
+       (const_string "*")))])
+
 (define_insn "*rotrhi3"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
        (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
   "TARGET_QIMODE_MATH"
   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
 
+(define_insn "*rotrqi3_1_one_bit"
+  [(set (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))]
+  "ix86_binary_operator_ok (ROTATERT, QImode, operands)
+   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
+  "ror{b}\\t%0"
+  [(set_attr "type" "ishift")
+   (set (attr "length") 
+     (if_then_else (match_operand:SI 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")