OSDN Git Service

* config/i386/i386.md (any_rotate): New code iterator.
authoruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 12 Apr 2010 20:20:54 +0000 (20:20 +0000)
committeruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 12 Apr 2010 20:20:54 +0000 (20:20 +0000)
(rotate_insn): New code attribute.
(rotate): Ditto.
(SWIM124): New mode iterator.
(<rotate_insn>ti3): New expander.
(<rotate_insn>di3): Macroize expander from {rotl,rotr}di3 using
any_rotate code iterator.
(<rotate_insn><mode>3) Macroize expander from {rotl,rotr}{qi,hi,si}3
using any_rotate code iterator and SWIM124 mode iterator.
(ix86_rotlti3): New insn_and_split pattern.
(ix86_rotrti3): Ditto.
(ix86_rotl<dwi>3_doubleword): Macroize insn_and_split pattern from
ix86_rotl{di,ti}3 patterns.
(ix86_rotr<dwi>3_doubleword): Ditto from ix86_rotr{di,ti}3 patterns.
(*<rotate_insn><mode>3_1): Merge with *{rotl,rotr}{qi,hi,si}3_1_one_bit
and *{rotl,rotr}di3_1_one_bit_rex64. Macroize insn from
*{rotl,rotr}{qi,hi,si}3_1 and *{rotl,rotr}di3_1_rex64 using any_rotate
code iterator and SWI mode iterator.
(*<rotate_insn>si3_1_zext): Merge with *{rotl,rotr}si3_1_one_bit_zext.
Macroize insn from {rotl,rotr}si3_1_zext using any_rotate
code iterator.
(*<rotate_insn>qi3_1_slp): Merge with *{rotl,rotr}qi3_1_one_bit_slp.
Macroize insn from {rotl,rotr}qi3_1_slp using any_rotate code iterator.
(bswap rotatert splitter): Add splitter.
(bswap splitter): Macroize splitter using any_rotate code iterator.
Add insn predicate to split only for TARGET_USE_XCHGB or when
optimizing function for size.

testsuite/ChangeLog:

* gcc.target/i386/rotate-2.c: New test.

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

gcc/ChangeLog
gcc/config/i386/i386.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/rotate-2.c [new file with mode: 0644]

index e293d01..7c2a25d 100644 (file)
@@ -1,3 +1,33 @@
+2010-04-12  Uros Bizjak  <ubizjak@gmail.com>
+
+       * config/i386/i386.md (any_rotate): New code iterator.
+       (rotate_insn): New code attribute.
+       (rotate): Ditto.
+       (SWIM124): New mode iterator.
+       (<rotate_insn>ti3): New expander.
+       (<rotate_insn>di3): Macroize expander from {rotl,rotr}di3 using
+       any_rotate code iterator.
+       (<rotate_insn><mode>3) Macroize expander from {rotl,rotr}{qi,hi,si}3
+       using any_rotate code iterator and SWIM124 mode iterator.
+       (ix86_rotlti3): New insn_and_split pattern.
+       (ix86_rotrti3): Ditto.
+       (ix86_rotl<dwi>3_doubleword): Macroize insn_and_split pattern from
+       ix86_rotl{di,ti}3 patterns.
+       (ix86_rotr<dwi>3_doubleword): Ditto from ix86_rotr{di,ti}3 patterns.
+       (*<rotate_insn><mode>3_1): Merge with *{rotl,rotr}{qi,hi,si}3_1_one_bit
+       and *{rotl,rotr}di3_1_one_bit_rex64. Macroize insn from
+       *{rotl,rotr}{qi,hi,si}3_1 and *{rotl,rotr}di3_1_rex64 using any_rotate
+       code iterator and SWI mode iterator.
+       (*<rotate_insn>si3_1_zext): Merge with *{rotl,rotr}si3_1_one_bit_zext.
+       Macroize insn from {rotl,rotr}si3_1_zext using any_rotate
+       code iterator.
+       (*<rotate_insn>qi3_1_slp): Merge with *{rotl,rotr}qi3_1_one_bit_slp.
+       Macroize insn from {rotl,rotr}qi3_1_slp using any_rotate code iterator.
+       (bswap rotatert splitter): Add splitter.
+       (bswap splitter): Macroize splitter using any_rotate code iterator.
+       Add insn predicate to split only for TARGET_USE_XCHGB or when
+       optimizing function for size.
+
 2010-04-12  Steve Ellcey  <sje@cup.hp.com>
 
        * config/pa/pa.c (emit_move_sequence): Remove use of
 2010-04-12  Steve Ellcey  <sje@cup.hp.com>
 
        * config/pa/pa.c (emit_move_sequence): Remove use of
        * ipa.c (cgraph_postorder): Adjust postorder to guarantee
        single-iteration always-inline inlining.
        * ipa-inline.c (cgraph_mark_inline): Do not return anything.
        * ipa.c (cgraph_postorder): Adjust postorder to guarantee
        single-iteration always-inline inlining.
        * ipa-inline.c (cgraph_mark_inline): Do not return anything.
-       (cgraph_decide_inlining): Do not handle always-inline
-       specially.
+       (cgraph_decide_inlining): Do not handle always-inline specially.
        (try_inline): Remove always-inline cycle detection special case.
        Do not recurse on always-inlines.
        (cgraph_early_inlining): Do not iterate if not optimizing.
        (try_inline): Remove always-inline cycle detection special case.
        Do not recurse on always-inlines.
        (cgraph_early_inlining): Do not iterate if not optimizing.
        * config/i386/i386.md (any_shiftrt): New code iterator.
        (shiftrt_insn): New code attribute.
        (shiftrt): Ditto.
        * config/i386/i386.md (any_shiftrt): New code iterator.
        (shiftrt_insn): New code attribute.
        (shiftrt): Ditto.
-       (<shiftrt_insn><mode>3): Macroize expander from ashr<mode>3 and
-       lshr<mode>3 using any_shiftrt code iterator.
+       (<shiftrt_insn><mode>3): Macroize expander from {ashr,lshr}<mode>3
+       using any_shiftrt code iterator.
        (*<shiftrt_insn><mode>3_doubleword): Macroize insn_and_split from
        (*<shiftrt_insn><mode>3_doubleword): Macroize insn_and_split from
-       *ashr<mode>3_doubleword and *lshr<mode>3_doubleword using
-       any_shiftrt code iterator.
+       *{ashr,lshr}<mode>3_doubleword using any_shiftrt code iterator.
        (*<shiftrt_insn><mode>3_doubleword peephole2): Macroize peephole2
        pattern from corresponding peephole2 patterns.
        (*<shiftrt_insn><mode>3_doubleword peephole2): Macroize peephole2
        pattern from corresponding peephole2 patterns.
-       (*<shiftrt_insn><mode>3_1): Macroize insn from *ashr<mode>3_1
-       and *lshr<mode>3_1 using any_shiftrt code iterator.
-       (*<shiftrt_insn>si3_1_zext): Ditto from *ashrsi3_1_zext
-       and *lshrsi3_1_zext.
-       (*<shiftrt_insn>qi3_1_slp): Ditto from *ashrqi3_1_slp
-       and *lshrqi3_1_slp.
-       (*<shiftrt_insn><mode>3_cmp): Ditto from *ashr<mode>3_cmp
-       and *lshr<mode>3_cmp.
-       (*<shiftrt_insn><mode>3_cmp_zext): Ditto from *ashr<mode>3_cmp_zext
-       and *lshr<mode>3_cmp_zext.
-       (*<shiftrt_insn><mode>3_cconly): Ditto from *ashr<mode>3_cconly
-       and *lshr<mode>3_cconly.
+       (*<shiftrt_insn><mode>3_1): Macroize insn from *{ashr,lshr}<mode>3_1
+       using any_shiftrt code iterator.
+       (*<shiftrt_insn>si3_1_zext): Ditto from *{ashr,lshr}si3_1_zext.
+       (*<shiftrt_insn>qi3_1_slp): Ditto from *{ashr,lshr}qi3_1_slp.
+       (*<shiftrt_insn><mode>3_cmp): Ditto from *{ashr,lshr}<mode>3_cmp.
+       (*<shiftrt_insn><mode>3_cmp_zext): Ditto from
+       *{ashr,lshr}<mode>3_cmp_zext.
+       (*<shiftrt_insn><mode>3_cconly): Ditto from *{ashr,lshr}<mode>3_cconly.
 
 2010-04-11  Uros Bizjak  <ubizjak@gmail.com>
 
 
 2010-04-11  Uros Bizjak  <ubizjak@gmail.com>
 
        (*lshr<mode>3_doubleword peephole2): Macroize peephole2 pattern
        from corresponding peephole2 patterns.
        (*lshr<mode>3_1): Merge with *lshr{qi,hi,si}3_1_one_bit and
        (*lshr<mode>3_doubleword peephole2): Macroize peephole2 pattern
        from corresponding peephole2 patterns.
        (*lshr<mode>3_1): Merge with *lshr{qi,hi,si}3_1_one_bit and
-       *lshrdi3_1_one_bit_rex64. Macroize insn from *lshr{qi,hi,si}3_cmp
-       and *lshrdi3_cmp_rex64 using SWI mode iterator.
+       *lshrdi3_1_one_bit_rex64. Macroize insn from *lshr{qi,hi,si}3_1
+       and *lshrdi3_1_rex64 using SWI mode iterator.
        (*lshrsi3_1_zext): Merge with *lshrsi3_1_one_bit_zext.
        (*lshrqi3_1_slp): Merge with *lshrqi3_1_one_bit_slp.
        (*lshr<mode>3_cmp): Merge with *lshr{qi,hi,si}3_one_bit_cmp and
        (*lshrsi3_1_zext): Merge with *lshrsi3_1_one_bit_zext.
        (*lshrqi3_1_slp): Merge with *lshrqi3_1_one_bit_slp.
        (*lshr<mode>3_cmp): Merge with *lshr{qi,hi,si}3_one_bit_cmp and
        (x86_shift<mode>_adj_3): Macroize expander from x86_shift_adj_3
        and x86_64_shift_adj_3 using SWI48 mode iterator.
        (*ashr<mode>3_1): Merge with *ashr{qi,hi,si}3_1_one_bit and
        (x86_shift<mode>_adj_3): Macroize expander from x86_shift_adj_3
        and x86_64_shift_adj_3 using SWI48 mode iterator.
        (*ashr<mode>3_1): Merge with *ashr{qi,hi,si}3_1_one_bit and
-       *ashrdi3_1_one_bit_rex64. Macroize insn from *ashr{qi,hi,si}3_cmp
-       and *ashrdi3_cmp_rex64 using SWI mode iterator.
+       *ashrdi3_1_one_bit_rex64. Macroize insn from *ashr{qi,hi,si}3_1
+       and *ashrdi3_1_rex64 using SWI mode iterator.
        (*ashrsi3_1_zext): Merge with *ashrsi3_1_one_bit_zext.
        (*ashrqi3_1_slp): Merge with *ashrqi3_1_one_bit_slp.
        (*ashr<mode>3_cmp): Merge with *ashr{qi,hi,si}3_one_bit_cmp and
        (*ashrsi3_1_zext): Merge with *ashrsi3_1_one_bit_zext.
        (*ashrqi3_1_slp): Merge with *ashrqi3_1_one_bit_slp.
        (*ashr<mode>3_cmp): Merge with *ashr{qi,hi,si}3_one_bit_cmp and
index abe09cf..411feaf 100644 (file)
 ;; Base name for insn mnemonic.
 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
 
 ;; Base name for insn mnemonic.
 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
 
+;; Mapping of rotate operators
+(define_code_iterator any_rotate [rotate rotatert])
+
+;; Base name for define_insn
+(define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
+
+;; Base name for insn mnemonic.
+(define_code_attr rotate [(rotate "rol") (rotatert "ror")])
+
 ;; Mapping of abs neg operators
 (define_code_iterator absneg [abs neg])
 
 ;; Mapping of abs neg operators
 (define_code_iterator absneg [abs neg])
 
                            (HI "TARGET_HIMODE_MATH")
                            SI (DI "TARGET_64BIT")])
 
                            (HI "TARGET_HIMODE_MATH")
                            SI (DI "TARGET_64BIT")])
 
+;; Math-dependant single word integer modes without DImode.
+(define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
+                              (HI "TARGET_HIMODE_MATH")
+                              SI])
+
 ;; Math-dependant single word integer modes without QImode.
 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
                               SI (DI "TARGET_64BIT")])
 ;; Math-dependant single word integer modes without QImode.
 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
                               SI (DI "TARGET_64BIT")])
 \f
 ;; Rotate instructions
 
 \f
 ;; Rotate instructions
 
-(define_expand "rotldi3"
+(define_expand "<rotate_insn>ti3"
+  [(set (match_operand:TI 0 "register_operand" "")
+       (any_rotate:TI (match_operand:TI 1 "register_operand" "")
+                      (match_operand:QI 2 "nonmemory_operand" "")))]
+  "TARGET_64BIT"
+{
+  if (const_1_to_63_operand (operands[2], VOIDmode))
+    emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
+               (operands[0], operands[1], operands[2]));
+  else
+    FAIL;
+
+  DONE;
+})
+
+(define_expand "<rotate_insn>di3"
   [(set (match_operand:DI 0 "shiftdi_operand" "")
   [(set (match_operand:DI 0 "shiftdi_operand" "")
-       (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
-                  (match_operand:QI 2 "nonmemory_operand" "")))]
+       (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
+                      (match_operand:QI 2 "nonmemory_operand" "")))]
  ""
 {
   if (TARGET_64BIT)
  ""
 {
   if (TARGET_64BIT)
-    {
-      ix86_expand_binary_operator (ROTATE, DImode, operands);
-      DONE;
-    }
-  if (!const_1_to_31_operand (operands[2], VOIDmode))
+    ix86_expand_binary_operator (<CODE>, DImode, operands);
+  else if (const_1_to_31_operand (operands[2], VOIDmode))
+    emit_insn (gen_ix86_<rotate_insn>di3_doubleword
+               (operands[0], operands[1], operands[2]));
+  else
     FAIL;
     FAIL;
-  emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
+
   DONE;
 })
 
   DONE;
 })
 
-;; Implement rotation using two double-precision shift instructions
-;; and a scratch register.
-(define_insn_and_split "ix86_rotldi3"
- [(set (match_operand:DI 0 "register_operand" "=r")
-       (rotate:DI (match_operand:DI 1 "register_operand" "0")
-                  (match_operand:QI 2 "const_1_to_31_operand" "I")))
+(define_expand "<rotate_insn><mode>3"
+  [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
+       (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
+                           (match_operand:QI 2 "nonmemory_operand" "")))]
+  ""
+  "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
+
+;; Implement rotation using two double-precision
+;; shift instructions and a scratch register.
+
+(define_insn_and_split "ix86_rotl<dwi>3_doubleword"
+ [(set (match_operand:<DWI> 0 "register_operand" "=r")
+       (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
+                    (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
   (clobber (reg:CC FLAGS_REG))
   (clobber (reg:CC FLAGS_REG))
-  (clobber (match_scratch:SI 3 "=&r"))]
- "!TARGET_64BIT"
+  (clobber (match_scratch:DWIH 3 "=&r"))]
  ""
  ""
- "&& reload_completed"
+ "#"
+ "reload_completed"
  [(set (match_dup 3) (match_dup 4))
   (parallel
    [(set (match_dup 4)
  [(set (match_dup 3) (match_dup 4))
   (parallel
    [(set (match_dup 4)
-         (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
-                 (lshiftrt:SI (match_dup 5)
-                              (minus:QI (const_int 32) (match_dup 2)))))
+        (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
+                  (lshiftrt:DWIH (match_dup 5)
+                                 (minus:QI (match_dup 6) (match_dup 2)))))
     (clobber (reg:CC FLAGS_REG))])
   (parallel
    [(set (match_dup 5)
     (clobber (reg:CC FLAGS_REG))])
   (parallel
    [(set (match_dup 5)
-         (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
-                 (lshiftrt:SI (match_dup 3)
-                              (minus:QI (const_int 32) (match_dup 2)))))
+        (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
+                  (lshiftrt:DWIH (match_dup 3)
+                                 (minus:QI (match_dup 6) (match_dup 2)))))
     (clobber (reg:CC FLAGS_REG))])]
     (clobber (reg:CC FLAGS_REG))])]
- "split_di (&operands[0], 1, &operands[4], &operands[5]);")
-
-(define_insn "*rotlsi3_1_one_bit_rex64"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
-       (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
-                  (match_operand:QI 2 "const1_operand" "")))
-   (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT
-   && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
-   && ix86_binary_operator_ok (ROTATE, DImode, operands)"
-  "rol{q}\t%0"
-  [(set_attr "type" "rotate")
-   (set_attr "length_immediate" "0")
-   (set_attr "mode" "DI")])
-
-(define_insn "*rotldi3_1_rex64"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
-       (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
-                  (match_operand:QI 2 "nonmemory_operand" "e,c")))
-   (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
-  "@
-   rol{q}\t{%2, %0|%0, %2}
-   rol{q}\t{%b2, %0|%0, %b2}"
-  [(set_attr "type" "rotate")
-   (set_attr "mode" "DI")])
-
-(define_expand "rotlsi3"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "")
-       (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
-                  (match_operand:QI 2 "nonmemory_operand" "")))]
-  ""
-  "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 "const1_operand" "")))
-   (clobber (reg:CC FLAGS_REG))]
-  "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
-   && ix86_binary_operator_ok (ROTATE, SImode, operands)"
-  "rol{l}\t%0"
-  [(set_attr "type" "rotate")
-   (set_attr "length_immediate" "0")
-   (set_attr "mode" "SI")])
-
-(define_insn "*rotlsi3_1_one_bit_zext"
-  [(set (match_operand:DI 0 "register_operand" "=r")
-       (zero_extend:DI
-         (rotate:SI (match_operand:SI 1 "register_operand" "0")
-                    (match_operand:QI 2 "const1_operand" ""))))
-   (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT
-   && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
-   && ix86_binary_operator_ok (ROTATE, SImode, operands)"
-  "rol{l}\t%k0"
-  [(set_attr "type" "rotate")
-   (set_attr "length_immediate" "0")
-   (set_attr "mode" "SI")])
-
-(define_insn "*rotlsi3_1"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-       (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
-                  (match_operand:QI 2 "nonmemory_operand" "I,c")))
-   (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (ROTATE, SImode, operands)"
-  "@
-   rol{l}\t{%2, %0|%0, %2}
-   rol{l}\t{%b2, %0|%0, %b2}"
-  [(set_attr "type" "rotate")
-   (set_attr "mode" "SI")])
-
-(define_insn "*rotlsi3_1_zext"
-  [(set (match_operand:DI 0 "register_operand" "=r,r")
-       (zero_extend:DI
-         (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
-                    (match_operand:QI 2 "nonmemory_operand" "I,c"))))
-   (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
-  "@
-   rol{l}\t{%2, %k0|%k0, %2}
-   rol{l}\t{%b2, %k0|%k0, %b2}"
-  [(set_attr "type" "rotate")
-   (set_attr "mode" "SI")])
-
-(define_expand "rotlhi3"
-  [(set (match_operand:HI 0 "nonimmediate_operand" "")
-       (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
-                  (match_operand:QI 2 "nonmemory_operand" "")))]
-  "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 "const1_operand" "")))
-   (clobber (reg:CC FLAGS_REG))]
-  "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
-   && ix86_binary_operator_ok (ROTATE, HImode, operands)"
-  "rol{w}\t%0"
-  [(set_attr "type" "rotate")
-   (set_attr "length_immediate" "0")
-   (set_attr "mode" "HI")])
-
-(define_insn "*rotlhi3_1"
-  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
-       (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
-                  (match_operand:QI 2 "nonmemory_operand" "I,c")))
-   (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (ROTATE, HImode, operands)"
-  "@
-   rol{w}\t{%2, %0|%0, %2}
-   rol{w}\t{%b2, %0|%0, %b2}"
-  [(set_attr "type" "rotate")
-   (set_attr "mode" "HI")])
-
-(define_split
- [(set (match_operand:HI 0 "register_operand" "")
-       (rotate:HI (match_dup 0) (const_int 8)))
-  (clobber (reg:CC FLAGS_REG))]
- "reload_completed"
- [(parallel [(set (strict_low_part (match_dup 0))
-                 (bswap:HI (match_dup 0)))
-            (clobber (reg:CC FLAGS_REG))])]
- "")
-
-(define_expand "rotlqi3"
-  [(set (match_operand:QI 0 "nonimmediate_operand" "")
-       (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
-                  (match_operand:QI 2 "nonmemory_operand" "")))]
-  "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_dup 0)
-                  (match_operand:QI 1 "const1_operand" "")))
-   (clobber (reg:CC FLAGS_REG))]
-  "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
-   && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
-  "rol{b}\t%0"
-  [(set_attr "type" "rotate1")
-   (set_attr "length_immediate" "0")
-   (set_attr "mode" "QI")])
-
-(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 "const1_operand" "")))
-   (clobber (reg:CC FLAGS_REG))]
-  "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
-   && ix86_binary_operator_ok (ROTATE, QImode, operands)"
-  "rol{b}\t%0"
-  [(set_attr "type" "rotate")
-   (set_attr "length_immediate" "0")
-   (set_attr "mode" "QI")])
-
-(define_insn "*rotlqi3_1_slp"
-  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
-       (rotate:QI (match_dup 0)
-                  (match_operand:QI 1 "nonmemory_operand" "I,c")))
-   (clobber (reg:CC FLAGS_REG))]
-  "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
-   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
-  "@
-   rol{b}\t{%1, %0|%0, %1}
-   rol{b}\t{%b1, %0|%0, %b1}"
-  [(set_attr "type" "rotate1")
-   (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")
-                  (match_operand:QI 2 "nonmemory_operand" "I,c")))
-   (clobber (reg:CC FLAGS_REG))]
-  "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_expand "rotrdi3"
-  [(set (match_operand:DI 0 "shiftdi_operand" "")
-       (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
-                  (match_operand:QI 2 "nonmemory_operand" "")))]
- ""
 {
 {
-  if (TARGET_64BIT)
-    {
-      ix86_expand_binary_operator (ROTATERT, DImode, operands);
-      DONE;
-    }
-  if (!const_1_to_31_operand (operands[2], VOIDmode))
-    FAIL;
-  emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
-  DONE;
+  operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
+
+  split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
 })
 
 })
 
-;; Implement rotation using two double-precision shift instructions
-;; and a scratch register.
-(define_insn_and_split "ix86_rotrdi3"
- [(set (match_operand:DI 0 "register_operand" "=r")
-       (rotatert:DI (match_operand:DI 1 "register_operand" "0")
-                    (match_operand:QI 2 "const_1_to_31_operand" "I")))
+(define_insn_and_split "ix86_rotr<dwi>3_doubleword"
+ [(set (match_operand:<DWI> 0 "register_operand" "=r")
+       (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
+                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
   (clobber (reg:CC FLAGS_REG))
   (clobber (reg:CC FLAGS_REG))
-  (clobber (match_scratch:SI 3 "=&r"))]
- "!TARGET_64BIT"
+  (clobber (match_scratch:DWIH 3 "=&r"))]
  ""
  ""
- "&& reload_completed"
+ "#"
+ "reload_completed"
  [(set (match_dup 3) (match_dup 4))
   (parallel
    [(set (match_dup 4)
  [(set (match_dup 3) (match_dup 4))
   (parallel
    [(set (match_dup 4)
-         (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
-                 (ashift:SI (match_dup 5)
-                            (minus:QI (const_int 32) (match_dup 2)))))
+        (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
+                  (ashift:DWIH (match_dup 5)
+                               (minus:QI (match_dup 6) (match_dup 2)))))
     (clobber (reg:CC FLAGS_REG))])
   (parallel
    [(set (match_dup 5)
     (clobber (reg:CC FLAGS_REG))])
   (parallel
    [(set (match_dup 5)
-         (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
-                 (ashift:SI (match_dup 3)
-                            (minus:QI (const_int 32) (match_dup 2)))))
+        (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
+                  (ashift:DWIH (match_dup 3)
+                               (minus:QI (match_dup 6) (match_dup 2)))))
     (clobber (reg:CC FLAGS_REG))])]
     (clobber (reg:CC FLAGS_REG))])]
- "split_di (&operands[0], 1, &operands[4], &operands[5]);")
-
-(define_insn "*rotrdi3_1_one_bit_rex64"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
-       (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
-                    (match_operand:QI 2 "const1_operand" "")))
-   (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT
-   && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
-   && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
-  "ror{q}\t%0"
-  [(set_attr "type" "rotate")
-   (set_attr "length_immediate" "0")
-   (set_attr "mode" "DI")])
-
-(define_insn "*rotrdi3_1_rex64"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
-       (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
-                    (match_operand:QI 2 "nonmemory_operand" "J,c")))
-   (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
-  "@
-   ror{q}\t{%2, %0|%0, %2}
-   ror{q}\t{%b2, %0|%0, %b2}"
-  [(set_attr "type" "rotate")
-   (set_attr "mode" "DI")])
+{
+  operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
 
 
-(define_expand "rotrsi3"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "")
-       (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
-                    (match_operand:QI 2 "nonmemory_operand" "")))]
-  ""
-  "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
+  split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
+})
 
 
-(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 "const1_operand" "")))
+(define_insn "*<rotate_insn><mode>3_1"
+  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
+       (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
+                       (match_operand:QI 2 "nonmemory_operand" "c<S>")))
    (clobber (reg:CC FLAGS_REG))]
    (clobber (reg:CC FLAGS_REG))]
-  "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
-   && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
-  "ror{l}\t%0"
+  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
+{
+  if (REG_P (operands[2]))
+    return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
+  else if (operands[2] == const1_rtx
+          && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
+    return "<rotate>{<imodesuffix>}\t%0";
+  else
+    return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
+}
   [(set_attr "type" "rotate")
   [(set_attr "type" "rotate")
-   (set_attr "length_immediate" "0")
-   (set_attr "mode" "SI")])
+   (set (attr "length_immediate")
+     (if_then_else
+       (and (match_operand 2 "const1_operand" "")
+           (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+               (const_int 0)))
+       (const_string "0")
+       (const_string "*")))
+   (set_attr "mode" "<MODE>")])
 
 
-(define_insn "*rotrsi3_1_one_bit_zext"
+(define_insn "*<rotate_insn>si3_1_zext"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (zero_extend:DI
   [(set (match_operand:DI 0 "register_operand" "=r")
        (zero_extend:DI
-         (rotatert:SI (match_operand:SI 1 "register_operand" "0")
-                      (match_operand:QI 2 "const1_operand" ""))))
-   (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT
-   && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
-   && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
-  "ror{l}\t%k0"
-  [(set_attr "type" "rotate")
-   (set_attr "length_immediate" "0")
-   (set_attr "mode" "SI")])
-
-(define_insn "*rotrsi3_1"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
-       (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
-                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
-   (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
-  "@
-   ror{l}\t{%2, %0|%0, %2}
-   ror{l}\t{%b2, %0|%0, %b2}"
-  [(set_attr "type" "rotate")
-   (set_attr "mode" "SI")])
-
-(define_insn "*rotrsi3_1_zext"
-  [(set (match_operand:DI 0 "register_operand" "=r,r")
-       (zero_extend:DI
-         (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
-                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
+         (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
+                        (match_operand:QI 2 "nonmemory_operand" "cI"))))
    (clobber (reg:CC FLAGS_REG))]
    (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
-  "@
-   ror{l}\t{%2, %k0|%k0, %2}
-   ror{l}\t{%b2, %k0|%k0, %b2}"
+  "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
+{
+  if (REG_P (operands[2]))
+    return "<rotate>{l}\t{%b2, %k0|%k0, %b2}";
+  else if (operands[2] == const1_rtx
+          && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
+    return "<rotate>{l}\t%k0";
+  else
+    return "<rotate>{l}\t{%2, %k0|%k0, %2}";
+}
   [(set_attr "type" "rotate")
   [(set_attr "type" "rotate")
+   (set (attr "length_immediate")
+     (if_then_else
+       (and (match_operand 2 "const1_operand" "")
+           (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+               (const_int 0)))
+       (const_string "0")
+       (const_string "*")))
    (set_attr "mode" "SI")])
 
    (set_attr "mode" "SI")])
 
-(define_expand "rotrhi3"
-  [(set (match_operand:HI 0 "nonimmediate_operand" "")
-       (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
-                    (match_operand:QI 2 "nonmemory_operand" "")))]
-  "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 "const1_operand" "")))
-   (clobber (reg:CC FLAGS_REG))]
-  "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
-   && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
-  "ror{w}\t%0"
-  [(set_attr "type" "rotate")
-   (set_attr "length_immediate" "0")
-   (set_attr "mode" "HI")])
-
-(define_insn "*rotrhi3_1"
-  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
-       (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
-                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
+(define_insn "*<rotate_insn>qi3_1_slp"
+  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
+       (any_rotate:QI (match_dup 0)
+                      (match_operand:QI 1 "nonmemory_operand" "cI")))
    (clobber (reg:CC FLAGS_REG))]
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
-  "@
-   ror{w}\t{%2, %0|%0, %2}
-   ror{w}\t{%b2, %0|%0, %b2}"
-  [(set_attr "type" "rotate")
-   (set_attr "mode" "HI")])
+  "(optimize_function_for_size_p (cfun)
+    || !TARGET_PARTIAL_REG_STALL
+    || (operands[1] == const1_rtx
+       && TARGET_SHIFT1))"
+{
+  if (REG_P (operands[1]))
+    return "<rotate>{b}\t{%b1, %0|%0, %b1}";
+  else if (operands[1] == const1_rtx
+          && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
+    return "<rotate>{b}\t%0";
+  else
+    return "<rotate>{b}\t{%1, %0|%0, %1}";
+}
+  [(set_attr "type" "rotate1")
+   (set (attr "length_immediate")
+     (if_then_else
+       (and (match_operand 1 "const1_operand" "")
+           (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+               (const_int 0)))
+       (const_string "0")
+       (const_string "*")))
+   (set_attr "mode" "QI")])
 
 (define_split
  [(set (match_operand:HI 0 "register_operand" "")
 
 (define_split
  [(set (match_operand:HI 0 "register_operand" "")
-       (rotatert:HI (match_dup 0) (const_int 8)))
+       (any_rotate:HI (match_dup 0) (const_int 8)))
   (clobber (reg:CC FLAGS_REG))]
   (clobber (reg:CC FLAGS_REG))]
- "reload_completed"
+ "reload_completed
+  && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
  [(parallel [(set (strict_low_part (match_dup 0))
                  (bswap:HI (match_dup 0)))
             (clobber (reg:CC FLAGS_REG))])]
  "")
  [(parallel [(set (strict_low_part (match_dup 0))
                  (bswap:HI (match_dup 0)))
             (clobber (reg:CC FLAGS_REG))])]
  "")
-
-(define_expand "rotrqi3"
-  [(set (match_operand:QI 0 "nonimmediate_operand" "")
-       (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
-                    (match_operand:QI 2 "nonmemory_operand" "")))]
-  "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 "const1_operand" "")))
-   (clobber (reg:CC FLAGS_REG))]
-  "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
-   && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
-  "ror{b}\t%0"
-  [(set_attr "type" "rotate")
-   (set_attr "length_immediate" "0")
-   (set_attr "mode" "QI")])
-
-(define_insn "*rotrqi3_1_one_bit_slp"
-  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
-       (rotatert:QI (match_dup 0)
-                    (match_operand:QI 1 "const1_operand" "")))
-   (clobber (reg:CC FLAGS_REG))]
-  "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
-   && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
-  "ror{b}\t%0"
-  [(set_attr "type" "rotate1")
-   (set_attr "length_immediate" "0")
-   (set_attr "mode" "QI")])
-
-(define_insn "*rotrqi3_1"
-  [(set (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 FLAGS_REG))]
-  "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")])
-
-(define_insn "*rotrqi3_1_slp"
-  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
-       (rotatert:QI (match_dup 0)
-                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
-   (clobber (reg:CC FLAGS_REG))]
-  "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
-   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
-  "@
-   ror{b}\t{%1, %0|%0, %1}
-   ror{b}\t{%b1, %0|%0, %b1}"
-  [(set_attr "type" "rotate1")
-   (set_attr "mode" "QI")])
 \f
 ;; Bit set / bit test instructions
 
 \f
 ;; Bit set / bit test instructions
 
index 03bfcc0..68e4aa9 100644 (file)
@@ -1,8 +1,11 @@
+2010-04-12  Uros Bizjak  <ubizjak@gmail.com>
+
+       * gcc.target/i386/rotate-2.c: New test.
+
 2010-04-12  Jason Merrill  <jason@redhat.com>
 
        PR c++/43641
        * g++.dg/cpp0x/lambda/lambda-conv4.C: New.
 2010-04-12  Jason Merrill  <jason@redhat.com>
 
        PR c++/43641
        * g++.dg/cpp0x/lambda/lambda-conv4.C: New.
-
        * g++.dg/cpp0x/lambda/lambda-deduce2.C: New.
 
 2010-04-12  Fabien Chene  <fabien.chene@gmail.com>
        * g++.dg/cpp0x/lambda/lambda-deduce2.C: New.
 
 2010-04-12  Fabien Chene  <fabien.chene@gmail.com>
diff --git a/gcc/testsuite/gcc.target/i386/rotate-2.c b/gcc/testsuite/gcc.target/i386/rotate-2.c
new file mode 100644 (file)
index 0000000..69a0625
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-O2" } */
+
+typedef unsigned int UTItype __attribute__ ((mode (TI)));
+
+void foo (UTItype *);
+
+UTItype
+test (void)
+{
+  UTItype c = 0;
+  foo (&c);
+  c = c >> 5 | c << 123;
+  return c;
+}
+/* { dg-final { scan-assembler-times "shrdq" 2 } } */