aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2001-03-25 15:03:31 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2001-03-25 13:03:31 +0000
commit371bc54b8fb7548c53164af04550915105d7a63d (patch)
tree4d50151522c755fee14cbc08a23185216d4f0e51
parent0945b39d44197d6beffecaec708c89a1695a199b (diff)
downloadgcc-371bc54b8fb7548c53164af04550915105d7a63d.zip
gcc-371bc54b8fb7548c53164af04550915105d7a63d.tar.gz
gcc-371bc54b8fb7548c53164af04550915105d7a63d.tar.bz2
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
-rw-r--r--gcc/ChangeLog21
-rw-r--r--gcc/config/i386/i386.c14
-rw-r--r--gcc/config/i386/i386.h1
-rw-r--r--gcc/config/i386/i386.md633
4 files changed, 648 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e681730..bd87ea7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,24 @@
+Sun Mar 25 15:01:40 CEST 2001 Jan Hubicka <jh@suse.cz>
+
+ * 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 <jh@suse.cz>
* i386.md (movstrsi): Move offline.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 962d053..fa6633d 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 efc1e65..7312108 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 7a4e0fc..4850ca4 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")])