From 371bc54b8fb7548c53164af04550915105d7a63d Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Sun, 25 Mar 2001 15:03:31 +0200 Subject: [PATCH] i386.md (ashldi3, [...]): Change predicates to shiftdi_operand; use ix86_expand_binary_operator * i386.md (ashldi3, ashrdi3, lshrdi3): Change predicates to shiftdi_operand; use ix86_expand_binary_operator (?sh??i_?): Disable for 64bit. * i386.h (PREDICATE_CODES): Add shiftdi_operand. * i386.c (shiftdi_operand): New predicate. * (ashldi3_1_rex64, ashldi3_cmp_rex64, ashlsi3_1_zext, ashlsi3_cmp_zext, ashrdi3_63_rex64, ashrdi3_1_one_bit_rex64, ashrdi3_1_rex64, ashrdi3_one_bit_cmp_rex64, ashrdi3_cmp_rex64, ashrsi3_31_zext, ashrsi3_1_one_bit_zext, ashrsi3_1_zext, ashrsi3_one_bit_cmp_zext, ashrsi3_cmp_zext, lshrdi3_1_one_bit_rex64, lshrdi3_1_rex64, lshrdi3_cmp_one_bit_rex64, lshrdi3_cmp_rex64, lshrsi3_1_one_bit_zext, lshrsi3_1_zext, lshrsi3_cmp_one_bit_zext, lshrsi3_cmp_zext, rotlsi3_1_one_bit_rex64, rotldi3_1_rex64, rotlsi3_1_one_bit_zext, rotlsi3_1_zext, rotrdi3_1_one_bit_rex64, rotrdi3_1_rex64, rotrsi3_1_one_bit_zext, rotrsi3_1_zext): New patterns. (rotldi3, rotrdi3): New expanders. From-SVN: r40827 --- gcc/ChangeLog | 21 ++ gcc/config/i386/i386.c | 14 + gcc/config/i386/i386.h | 1 + gcc/config/i386/i386.md | 633 ++++++++++++++++++++++++++++++++++++++-- 4 files changed, 648 insertions(+), 21 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e681730c832..bd87ea7531d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +Sun Mar 25 15:01:40 CEST 2001 Jan Hubicka + + * i386.md (ashldi3, ashrdi3, lshrdi3): Change predicates to + shiftdi_operand; + use ix86_expand_binary_operator + (?sh??i_?): Disable for 64bit. + * i386.h (PREDICATE_CODES): Add shiftdi_operand. + * i386.c (shiftdi_operand): New predicate. + + * (ashldi3_1_rex64, ashldi3_cmp_rex64, ashlsi3_1_zext, ashlsi3_cmp_zext, + ashrdi3_63_rex64, ashrdi3_1_one_bit_rex64, ashrdi3_1_rex64, + ashrdi3_one_bit_cmp_rex64, ashrdi3_cmp_rex64, ashrsi3_31_zext, + ashrsi3_1_one_bit_zext, ashrsi3_1_zext, ashrsi3_one_bit_cmp_zext, + ashrsi3_cmp_zext, lshrdi3_1_one_bit_rex64, lshrdi3_1_rex64, + lshrdi3_cmp_one_bit_rex64, lshrdi3_cmp_rex64, lshrsi3_1_one_bit_zext, + lshrsi3_1_zext, lshrsi3_cmp_one_bit_zext, lshrsi3_cmp_zext, + rotlsi3_1_one_bit_rex64, rotldi3_1_rex64, + rotlsi3_1_one_bit_zext, rotlsi3_1_zext, rotrdi3_1_one_bit_rex64, + rotrdi3_1_rex64, rotrsi3_1_one_bit_zext, rotrsi3_1_zext): New patterns. + (rotldi3, rotrdi3): New expanders. + Sun Mar 25 14:25:33 CEST 2001 Jan Hubicka * i386.md (movstrsi): Move offline. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 962d0539949..fa6633d2260 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -1411,6 +1411,20 @@ incdec_operand (op, mode) return 0; } +/* Return nonzero if OP is acceptable as operand of DImode shift + expander. */ + +int +shiftdi_operand (op, mode) + rtx op; + enum machine_mode mode ATTRIBUTE_UNUSED; +{ + if (TARGET_64BIT) + return nonimmediate_operand (op, mode); + else + return register_operand (op, mode); +} + /* Return false if this is the stack pointer, or any other fake register eliminable to the stack pointer. Otherwise, this is a register operand. diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index efc1e651368..7312108dfcb 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -3036,6 +3036,7 @@ do { long l; \ SYMBOL_REF, LABEL_REF, CONST}}, \ {"x86_64_zext_immediate_operand", {CONST_INT, CONST_DOUBLE, CONST, \ SYMBOL_REF, LABEL_REF}}, \ + {"shiftdi_operand", {SUBREG, REG, MEM}}, \ {"const_int_1_operand", {CONST_INT}}, \ {"symbolic_operand", {SYMBOL_REF, LABEL_REF, CONST}}, \ {"aligned_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, \ diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 7a4e0fc4e54..4850ca491b1 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -9963,8 +9963,8 @@ ;; than 31. (define_expand "ashldi3" - [(parallel [(set (match_operand:DI 0 "register_operand" "") - (ashift:DI (match_operand:DI 1 "register_operand" "") + [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "") + (ashift:DI (match_operand:DI 1 "shiftdi_operand" "") (match_operand:QI 2 "nonmemory_operand" ""))) (clobber (reg:CC 17))])] "" @@ -9975,16 +9975,122 @@ emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2])); DONE; } - ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE; + ix86_expand_binary_operator (ASHIFT, DImode, operands); + DONE; }") +(define_insn "*ashldi3_1_rex64" + [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") + (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r") + (match_operand:QI 2 "nonmemory_operand" "c,M"))) + (clobber (reg:CC 17))] + "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)" + "* +{ + switch (get_attr_type (insn)) + { + case TYPE_ALU: + if (operands[2] != const1_rtx) + abort (); + if (!rtx_equal_p (operands[0], operands[1])) + abort (); + return \"add{q}\\t{%0, %0|%0, %0}\"; + + case TYPE_LEA: + if (GET_CODE (operands[2]) != CONST_INT + || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3) + abort (); + operands[1] = gen_rtx_MULT (DImode, operands[1], + GEN_INT (1 << INTVAL (operands[2]))); + return \"lea{q}\\t{%a1, %0|%0, %a1}\"; + + default: + if (REG_P (operands[2])) + return \"sal{q}\\t{%b2, %0|%0, %b2}\"; + else if (GET_CODE (operands[2]) == CONST_INT + && INTVAL (operands[2]) == 1 + && (TARGET_PENTIUM || TARGET_PENTIUMPRO)) + return \"sal{q}\\t%0\"; + else + return \"sal{q}\\t{%2, %0|%0, %2}\"; + } +}" + [(set (attr "type") + (cond [(eq_attr "alternative" "1") + (const_string "lea") + (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") + (const_int 0)) + (match_operand 0 "register_operand" "")) + (match_operand 2 "const1_operand" "")) + (const_string "alu") + ] + (const_string "ishift"))) + (set_attr "mode" "DI")]) + +;; Convert lea to the lea pattern to avoid flags dependency. +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (ashift:DI (match_operand:DI 1 "register_operand" "") + (match_operand:QI 2 "immediate_operand" ""))) + (clobber (reg:CC 17))] + "reload_completed + && TARGET_64BIT + && true_regnum (operands[0]) != true_regnum (operands[1])" + [(set (match_dup 0) + (mult:DI (match_dup 1) + (match_dup 2)))] + "operands[2] = GEN_INT (1 << INTVAL (operands[2]));") + +;; 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 "*ashldi3_cmp_rex64" + [(set (reg 17) + (compare + (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0") + (match_operand:QI 2 "immediate_operand" "e")) + (const_int 0))) + (set (match_operand:DI 0 "nonimmediate_operand" "=rm") + (ashift:DI (match_dup 1) (match_dup 2)))] + "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) + && ix86_binary_operator_ok (ASHIFT, DImode, operands)" + "* +{ + switch (get_attr_type (insn)) + { + case TYPE_ALU: + if (operands[2] != const1_rtx) + abort (); + return \"add{q}\\t{%0, %0|%0, %0}\"; + + default: + if (REG_P (operands[2])) + return \"sal{q}\\t{%b2, %0|%0, %b2}\"; + else if (GET_CODE (operands[2]) == CONST_INT + && INTVAL (operands[2]) == 1 + && (TARGET_PENTIUM || TARGET_PENTIUMPRO)) + return \"sal{q}\\t%0\"; + else + return \"sal{q}\\t{%2, %0|%0, %2}\"; + } +}" + [(set (attr "type") + (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") + (const_int 0)) + (match_operand 0 "register_operand" "")) + (match_operand 2 "const1_operand" "")) + (const_string "alu") + ] + (const_string "ishift"))) + (set_attr "mode" "DI")]) + (define_insn "ashldi3_1" [(set (match_operand:DI 0 "register_operand" "=r") (ashift:DI (match_operand:DI 1 "register_operand" "0") (match_operand:QI 2 "nonmemory_operand" "Jc"))) (clobber (match_scratch:SI 3 "=&r")) (clobber (reg:CC 17))] - "TARGET_CMOVE" + "!TARGET_64BIT && TARGET_CMOVE" "#" [(set_attr "type" "multi")]) @@ -9993,7 +10099,7 @@ (ashift:DI (match_operand:DI 1 "register_operand" "0") (match_operand:QI 2 "nonmemory_operand" "Jc"))) (clobber (reg:CC 17))] - "" + "!TARGET_64BIT" "#" [(set_attr "type" "multi")]) @@ -10003,7 +10109,7 @@ (match_operand:QI 2 "nonmemory_operand" ""))) (clobber (match_scratch:SI 3 "")) (clobber (reg:CC 17))] - "TARGET_CMOVE && reload_completed" + "!TARGET_64BIT && TARGET_CMOVE && reload_completed" [(const_int 0)] "ix86_split_ashldi (operands, operands[3]); DONE;") @@ -10012,7 +10118,7 @@ (ashift:DI (match_operand:DI 1 "register_operand" "") (match_operand:QI 2 "nonmemory_operand" ""))) (clobber (reg:CC 17))] - "reload_completed" + "!TARGET_64BIT && reload_completed" [(const_int 0)] "ix86_split_ashldi (operands, NULL_RTX); DONE;") @@ -10152,6 +10258,61 @@ DONE; }") +(define_insn "*ashlsi3_1_zext" + [(set (match_operand:DI 0 "register_operand" "=r,r") + (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r") + (match_operand:QI 2 "nonmemory_operand" "cI,M")))) + (clobber (reg:CC 17))] + "ix86_binary_operator_ok (ASHIFT, SImode, operands) && TARGET_64BIT" + "* +{ + switch (get_attr_type (insn)) + { + case TYPE_ALU: + if (operands[2] != const1_rtx) + abort (); + return \"add{l}\\t{%k0, %k0|%k0, %k0}\"; + + case TYPE_LEA: + return \"#\"; + + default: + if (REG_P (operands[2])) + return \"sal{l}\\t{%b2, %k0|%k0, %b2}\"; + else if (GET_CODE (operands[2]) == CONST_INT + && INTVAL (operands[2]) == 1 + && (TARGET_PENTIUM || TARGET_PENTIUMPRO)) + return \"sal{l}\\t%k0\"; + else + return \"sal{l}\\t{%2, %k0|%k0, %2}\"; + } +}" + [(set (attr "type") + (cond [(eq_attr "alternative" "1") + (const_string "lea") + (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") + (const_int 0)) + (match_operand 2 "const1_operand" "")) + (const_string "alu") + ] + (const_string "ishift"))) + (set_attr "mode" "SI")]) + +;; Convert lea to the lea pattern to avoid flags dependency. +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (zero_extend:DI (ashift (match_operand 1 "register_operand" "") + (match_operand:QI 2 "const_int_operand" "")))) + (clobber (reg:CC 17))] + "reload_completed + && true_regnum (operands[0]) != true_regnum (operands[1])" + [(set (match_dup 0) (zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))] + " +{ + operands[1] = gen_lowpart (Pmode, operands[1]); + operands[2] = GEN_INT (1 << INTVAL (operands[2])); +}") + ;; 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. @@ -10195,6 +10356,45 @@ (const_string "ishift"))) (set_attr "mode" "SI")]) +(define_insn "*ashlsi3_cmp_zext" + [(set (reg 17) + (compare + (ashift:SI (match_operand:SI 1 "register_operand" "0") + (match_operand:QI 2 "immediate_operand" "I")) + (const_int 0))) + (set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))] + "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) + && ix86_binary_operator_ok (ASHIFT, SImode, operands)" + "* +{ + switch (get_attr_type (insn)) + { + case TYPE_ALU: + if (operands[2] != const1_rtx) + abort (); + return \"add{l}\\t{%k0, %k0|%k0, %k0}\"; + + default: + if (REG_P (operands[2])) + return \"sal{l}\\t{%b2, %k0|%k0, %b2}\"; + else if (GET_CODE (operands[2]) == CONST_INT + && INTVAL (operands[2]) == 1 + && (TARGET_PENTIUM || TARGET_PENTIUMPRO)) + return \"sal{l}\\t%k0\"; + else + return \"sal{l}\\t{%2, %k0|%k0, %2}\"; + } +}" + [(set (attr "type") + (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") + (const_int 0)) + (match_operand 2 "const1_operand" "")) + (const_string "alu") + ] + (const_string "ishift"))) + (set_attr "mode" "SI")]) + (define_expand "ashlhi3" [(set (match_operand:HI 0 "nonimmediate_operand" "") (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "") @@ -10494,27 +10694,110 @@ ;; See comment above `ashldi3' about how this works. (define_expand "ashrdi3" - [(parallel [(set (match_operand:DI 0 "register_operand" "=r") - (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") - (match_operand:QI 2 "nonmemory_operand" "Jc"))) + [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "") + (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "") + (match_operand:QI 2 "nonmemory_operand" ""))) (clobber (reg:CC 17))])] "" " { - if (TARGET_CMOVE && ! immediate_operand (operands[2], QImode)) + if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode)) { emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2])); DONE; } + ix86_expand_binary_operator (ASHIFTRT, DImode, operands); + DONE; }") +(define_insn "ashrdi3_63_rex64" + [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm") + (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0") + (match_operand:DI 2 "const_int_operand" "i,i"))) + (clobber (reg:CC 17))] + "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size) + && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" + "@ + {cqto|cqo} + sar{q}\\t{%2, %0|%0, %2}" + [(set_attr "type" "imovx,ishift") + (set_attr "prefix_0f" "0,*") + (set_attr "length_immediate" "0,*") + (set_attr "modrm" "0,1") + (set_attr "mode" "DI")]) + +(define_insn "*ashrdi3_1_one_bit_rex64" + [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") + (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") + (match_operand:QI 2 "const_int_1_operand" ""))) + (clobber (reg:CC 17))] + "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands) + && (TARGET_PENTIUM || TARGET_PENTIUMPRO)" + "sar{q}\\t%0" + [(set_attr "type" "ishift") + (set (attr "length") + (if_then_else (match_operand:DI 0 "register_operand" "") + (const_string "2") + (const_string "*")))]) + +(define_insn "*ashrdi3_1_rex64" + [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm") + (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") + (match_operand:QI 2 "nonmemory_operand" "n,c"))) + (clobber (reg:CC 17))] + "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" + "@ + sar{q}\\t{%2, %0|%0, %2} + sar{q}\\t{%b2, %0|%0, %b2}" + [(set_attr "type" "ishift") + (set_attr "mode" "DI")]) + +;; 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 "*ashrdi3_one_bit_cmp_rex64" + [(set (reg 17) + (compare + (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") + (match_operand:QI 2 "const_int_1_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "nonimmediate_operand" "=rm") + (ashiftrt:DI (match_dup 1) (match_dup 2)))] + "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) + && (TARGET_PENTIUM || TARGET_PENTIUMPRO) + && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" + "sar{q}\\t%0" + [(set_attr "type" "ishift") + (set (attr "length") + (if_then_else (match_operand:DI 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 "*ashrdi3_cmp_rex64" + [(set (reg 17) + (compare + (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") + (match_operand:QI 2 "const_int_operand" "n")) + (const_int 0))) + (set (match_operand:DI 0 "nonimmediate_operand" "=rm") + (ashiftrt:DI (match_dup 1) (match_dup 2)))] + "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) + && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" + "sar{q}\\t{%2, %0|%0, %2}" + [(set_attr "type" "ishift") + (set_attr "mode" "DI")]) + + (define_insn "ashrdi3_1" [(set (match_operand:DI 0 "register_operand" "=r") (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") (match_operand:QI 2 "nonmemory_operand" "Jc"))) (clobber (match_scratch:SI 3 "=&r")) (clobber (reg:CC 17))] - "TARGET_CMOVE" + "!TARGET_64BIT && TARGET_CMOVE" "#" [(set_attr "type" "multi")]) @@ -10523,7 +10806,7 @@ (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") (match_operand:QI 2 "nonmemory_operand" "Jc"))) (clobber (reg:CC 17))] - "" + "!TARGET_64BIT" "#" [(set_attr "type" "multi")]) @@ -10533,7 +10816,7 @@ (match_operand:QI 2 "nonmemory_operand" ""))) (clobber (match_scratch:SI 3 "")) (clobber (reg:CC 17))] - "TARGET_CMOVE && reload_completed" + "!TARGET_64BIT && TARGET_CMOVE && reload_completed" [(const_int 0)] "ix86_split_ashrdi (operands, operands[3]); DONE;") @@ -10542,7 +10825,7 @@ (ashiftrt:DI (match_operand:DI 1 "register_operand" "") (match_operand:QI 2 "nonmemory_operand" ""))) (clobber (reg:CC 17))] - "reload_completed" + "!TARGET_64BIT && reload_completed" [(const_int 0)] "ix86_split_ashrdi (operands, NULL_RTX); DONE;") @@ -10608,6 +10891,22 @@ (set_attr "modrm" "0,1") (set_attr "mode" "SI")]) +(define_insn "*ashrsi3_31_zext" + [(set (match_operand:DI 0 "register_operand" "=*d,r") + (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0") + (match_operand:SI 2 "const_int_operand" "i,i")))) + (clobber (reg:CC 17))] + "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size) + && TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" + "@ + {cltd|cdq} + sar{l}\\t{%2, %k0|%k0, %2}" + [(set_attr "type" "imovx,ishift") + (set_attr "prefix_0f" "0,*") + (set_attr "length_immediate" "0,*") + (set_attr "modrm" "0,1") + (set_attr "mode" "SI")]) + (define_expand "ashrsi3" [(set (match_operand:SI 0 "nonimmediate_operand" "") (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "") @@ -10630,6 +10929,17 @@ (const_string "2") (const_string "*")))]) +(define_insn "*ashrsi3_1_one_bit_zext" + [(set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") + (match_operand:QI 2 "const_int_1_operand" "")))) + (clobber (reg:CC 17))] + "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands) + && (TARGET_PENTIUM || TARGET_PENTIUMPRO)" + "sar{l}\\t%k0" + [(set_attr "type" "ishift") + (set_attr "length" "2")]) + (define_insn "*ashrsi3_1" [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") @@ -10642,6 +10952,18 @@ [(set_attr "type" "ishift") (set_attr "mode" "SI")]) +(define_insn "*ashrsi3_1_zext" + [(set (match_operand:DI 0 "register_operand" "=r,r") + (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0") + (match_operand:QI 2 "nonmemory_operand" "I,c")))) + (clobber (reg:CC 17))] + "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" + "@ + sar{l}\\t{%2, %k0|%k0, %2} + sar{l}\\t{%b2, %k0|%k0, %b2}" + [(set_attr "type" "ishift") + (set_attr "mode" "SI")]) + ;; 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. @@ -10663,6 +10985,21 @@ (const_string "2") (const_string "*")))]) +(define_insn "*ashrsi3_one_bit_cmp_zext" + [(set (reg 17) + (compare + (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") + (match_operand:QI 2 "const_int_1_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))] + "TARGET_64BIT && ix86_match_ccmode (insn, CCmode) + && (TARGET_PENTIUM || TARGET_PENTIUMPRO) + && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" + "sar{l}\\t%k0" + [(set_attr "type" "ishift") + (set_attr "length" "2")]) + ;; 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. @@ -10680,6 +11017,20 @@ [(set_attr "type" "ishift") (set_attr "mode" "SI")]) +(define_insn "*ashrsi3_cmp_zext" + [(set (reg 17) + (compare + (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") + (match_operand:QI 2 "immediate_operand" "I")) + (const_int 0))) + (set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))] + "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) + && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" + "sar{l}\\t{%2, %k0|%k0, %2}" + [(set_attr "type" "ishift") + (set_attr "mode" "SI")]) + (define_expand "ashrhi3" [(set (match_operand:HI 0 "nonimmediate_operand" "") (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "") @@ -10829,20 +11180,86 @@ ;; See comment above `ashldi3' about how this works. (define_expand "lshrdi3" - [(parallel [(set (match_operand:DI 0 "register_operand" "=r") - (lshiftrt:DI (match_operand:DI 1 "register_operand" "0") - (match_operand:QI 2 "nonmemory_operand" "Jc"))) + [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "") + (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "") + (match_operand:QI 2 "nonmemory_operand" ""))) (clobber (reg:CC 17))])] "" " { - if (TARGET_CMOVE && ! immediate_operand (operands[2], QImode)) + if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode)) { emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2])); DONE; } + ix86_expand_binary_operator (LSHIFTRT, DImode, operands); + DONE; }") +(define_insn "*lshrdi3_1_one_bit_rex64" + [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") + (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") + (match_operand:QI 2 "const_int_1_operand" ""))) + (clobber (reg:CC 17))] + "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) + && (TARGET_PENTIUM || TARGET_PENTIUMPRO)" + "shr{q}\\t%0" + [(set_attr "type" "ishift") + (set (attr "length") + (if_then_else (match_operand:DI 0 "register_operand" "") + (const_string "2") + (const_string "*")))]) + +(define_insn "*lshrdi3_1_rex64" + [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm") + (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") + (match_operand:QI 2 "nonmemory_operand" "J,c"))) + (clobber (reg:CC 17))] + "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" + "@ + shr{q}\\t{%2, %0|%0, %2} + shr{q}\\t{%b2, %0|%0, %b2}" + [(set_attr "type" "ishift") + (set_attr "mode" "DI")]) + +;; 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 "*lshrdi3_cmp_one_bit_rex64" + [(set (reg 17) + (compare + (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") + (match_operand:QI 2 "const_int_1_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "nonimmediate_operand" "=rm") + (lshiftrt:DI (match_dup 1) (match_dup 2)))] + "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) + && (TARGET_PENTIUM || TARGET_PENTIUMPRO) + && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" + "shr{q}\\t%0" + [(set_attr "type" "ishift") + (set (attr "length") + (if_then_else (match_operand:DI 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 "*lshrdi3_cmp_rex64" + [(set (reg 17) + (compare + (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") + (match_operand:QI 2 "const_int_operand" "e")) + (const_int 0))) + (set (match_operand:DI 0 "nonimmediate_operand" "=rm") + (lshiftrt:DI (match_dup 1) (match_dup 2)))] + "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) + && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" + "shr{q}\\t{%2, %0|%0, %2}" + [(set_attr "type" "ishift") + (set_attr "mode" "DI")]) + (define_insn "lshrdi3_1" [(set (match_operand:DI 0 "register_operand" "=r") (lshiftrt:DI (match_operand:DI 1 "register_operand" "0") @@ -10903,6 +11320,17 @@ (const_string "2") (const_string "*")))]) +(define_insn "*lshrsi3_1_one_bit_zext" + [(set (match_operand:DI 0 "register_operand" "=r") + (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0")) + (match_operand:QI 2 "const_int_1_operand" ""))) + (clobber (reg:CC 17))] + "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) + && (TARGET_PENTIUM || TARGET_PENTIUMPRO)" + "shr{l}\\t%k0" + [(set_attr "type" "ishift") + (set_attr "length" "2")]) + (define_insn "*lshrsi3_1" [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") @@ -10915,6 +11343,19 @@ [(set_attr "type" "ishift") (set_attr "mode" "SI")]) +(define_insn "*lshrsi3_1_zext" + [(set (match_operand:DI 0 "register_operand" "=r,r") + (zero_extend:DI + (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") + (match_operand:QI 2 "nonmemory_operand" "I,c")))) + (clobber (reg:CC 17))] + "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" + "@ + shr{l}\\t{%2, %k0|%k0, %2} + shr{l}\\t{%b2, %k0|%k0, %b2}" + [(set_attr "type" "ishift") + (set_attr "mode" "SI")]) + ;; 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. @@ -10936,6 +11377,21 @@ (const_string "2") (const_string "*")))]) +(define_insn "*lshrsi3_cmp_one_bit_zext" + [(set (reg 17) + (compare + (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") + (match_operand:QI 2 "const_int_1_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "register_operand" "=r") + (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] + "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) + && (TARGET_PENTIUM || TARGET_PENTIUMPRO) + && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" + "shr{l}\\t%k0" + [(set_attr "type" "ishift") + (set_attr "length" "2")]) + ;; 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. @@ -10953,6 +11409,20 @@ [(set_attr "type" "ishift") (set_attr "mode" "SI")]) +(define_insn "*lshrsi3_cmp_zext" + [(set (reg 17) + (compare + (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") + (match_operand:QI 2 "immediate_operand" "I")) + (const_int 0))) + (set (match_operand:DI 0 "register_operand" "=r") + (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] + "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) + && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" + "shr{l}\\t{%2, %k0|%k0, %2}" + [(set_attr "type" "ishift") + (set_attr "mode" "SI")]) + (define_expand "lshrhi3" [(set (match_operand:HI 0 "nonimmediate_operand" "") (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "") @@ -11099,6 +11569,40 @@ ;; Rotate instructions +(define_expand "rotldi3" + [(set (match_operand:DI 0 "nonimmediate_operand" "") + (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "") + (match_operand:QI 2 "nonmemory_operand" ""))) + (clobber (reg:CC 17))] + "TARGET_64BIT" + "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;") + +(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 "const_int_1_operand" ""))) + (clobber (reg:CC 17))] + "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands) + && (TARGET_PENTIUM || TARGET_PENTIUMPRO)" + "rol{q}\\t%0" + [(set_attr "type" "ishift") + (set (attr "length") + (if_then_else (match_operand:DI 0 "register_operand" "") + (const_string "2") + (const_string "*")))]) + +(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 17))] + "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" "ishift") + (set_attr "mode" "DI")]) + (define_expand "rotlsi3" [(set (match_operand:SI 0 "nonimmediate_operand" "") (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "") @@ -11121,6 +11625,18 @@ (const_string "2") (const_string "*")))]) +(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 "const_int_1_operand" "")))) + (clobber (reg:CC 17))] + "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands) + && (TARGET_PENTIUM || TARGET_PENTIUMPRO)" + "rol{l}\\t%k0" + [(set_attr "type" "ishift") + (set_attr "length" "2")]) + (define_insn "*rotlsi3_1" [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") @@ -11133,6 +11649,19 @@ [(set_attr "type" "ishift") (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 17))] + "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" "ishift") + (set_attr "mode" "SI")]) + (define_expand "rotlhi3" [(set (match_operand:HI 0 "nonimmediate_operand" "") (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "") @@ -11201,6 +11730,40 @@ [(set_attr "type" "ishift") (set_attr "mode" "QI")]) +(define_expand "rotrdi3" + [(set (match_operand:DI 0 "nonimmediate_operand" "") + (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "") + (match_operand:QI 2 "nonmemory_operand" ""))) + (clobber (reg:CC 17))] + "TARGET_64BIT" + "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;") + +(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 "const_int_1_operand" ""))) + (clobber (reg:CC 17))] + "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands) + && (TARGET_PENTIUM || TARGET_PENTIUMPRO)" + "ror{q}\\t%0" + [(set_attr "type" "ishift") + (set (attr "length") + (if_then_else (match_operand:DI 0 "register_operand" "") + (const_string "2") + (const_string "*")))]) + +(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 17))] + "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" "ishift") + (set_attr "mode" "DI")]) + (define_expand "rotrsi3" [(set (match_operand:SI 0 "nonimmediate_operand" "") (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "") @@ -11223,6 +11786,21 @@ (const_string "2") (const_string "*")))]) +(define_insn "*rotrsi3_1_one_bit_zext" + [(set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI + (rotatert:SI (match_operand:SI 1 "register_operand" "0") + (match_operand:QI 2 "const_int_1_operand" "")))) + (clobber (reg:CC 17))] + "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands) + && (TARGET_PENTIUM || TARGET_PENTIUMPRO)" + "ror{l}\\t%k0" + [(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") @@ -11235,6 +11813,19 @@ [(set_attr "type" "ishift") (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")))) + (clobber (reg:CC 17))] + "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)" + "@ + ror{l}\\t{%2, %k0|%k0, %2} + ror{l}\\t{%b2, %k0|%k0, %b2}" + [(set_attr "type" "ishift") + (set_attr "mode" "SI")]) + (define_expand "rotrhi3" [(set (match_operand:HI 0 "nonimmediate_operand" "") (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "") @@ -13560,7 +14151,7 @@ (const_int 4))) (use (reg:SI 19))] "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" - "movsl|movsd" + "{movsl|movsd}" [(set_attr "type" "str") (set_attr "mode" "SI") (set_attr "memory" "both")]) @@ -13576,7 +14167,7 @@ (const_int 4))) (use (reg:SI 19))] "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" - "movsl|movsd" + "{movsl|movsd}" [(set_attr "type" "str") (set_attr "mode" "SI") (set_attr "memory" "both")]) -- 2.30.2