;; 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))])]
""
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")])
(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")])
(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;")
(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;")
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.
(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" "")
;; 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")])
(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")])
(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;")
(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;")
(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" "")
(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")
[(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.
(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.
[(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" "")
;; 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")
(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")
[(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.
(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.
[(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" "")
\f
;; 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" "")
(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")
[(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" "")
[(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" "")
(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")
[(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" "")
(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")])
(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")])