(set (match_scratch:PTR 2 "=&r") (const_int 0))
(clobber (reg:CC FLAGS_REG))]
""
- "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
+{
+ output_asm_insn ("mov{<imodesuffix>}\t{%1, %2|%2, %1}", operands);
+ output_asm_insn ("mov{<imodesuffix>}\t{%2, %0|%0, %2}", operands);
+ return "xor{l}\t%k2, %k2";
+}
[(set_attr "type" "multi")])
+;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
+;; immediately followed by *mov{s,d}i_internal to the same register,
+;; where we can avoid the xor{l} above. We don't split this, so that
+;; scheduling or anything else doesn't separate the *stack_protect_set*
+;; pattern from the set of the register that overwrites the register
+;; with a new value.
+(define_insn "*stack_protect_set_2_<mode>"
+ [(set (match_operand:PTR 0 "memory_operand" "=m")
+ (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
+ UNSPEC_SP_SET))
+ (set (match_operand:SI 1 "register_operand" "=&r")
+ (match_operand:SI 2 "general_operand" "g"))
+ (clobber (reg:CC FLAGS_REG))]
+ "reload_completed
+ && !reg_overlap_mentioned_p (operands[1], operands[2])"
+{
+ output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
+ output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
+ if (pic_32bit_operand (operands[2], SImode)
+ || ix86_use_lea_for_mov (insn, operands + 1))
+ return "lea{l}\t{%E2, %1|%1, %E2}";
+ else
+ return "mov{l}\t{%2, %1|%1, %2}";
+}
+ [(set_attr "type" "multi")
+ (set_attr "length" "24")])
+
+(define_peephole2
+ [(parallel [(set (match_operand:PTR 0 "memory_operand")
+ (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
+ UNSPEC_SP_SET))
+ (set (match_operand:PTR 2 "general_reg_operand") (const_int 0))
+ (clobber (reg:CC FLAGS_REG))])
+ (set (match_operand:SI 3 "general_reg_operand")
+ (match_operand:SI 4))]
+ "REGNO (operands[2]) == REGNO (operands[3])
+ && (general_reg_operand (operands[4], SImode)
+ || memory_operand (operands[4], SImode)
+ || immediate_operand (operands[4], SImode))
+ && !reg_overlap_mentioned_p (operands[3], operands[4])"
+ [(parallel [(set (match_dup 0)
+ (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
+ (set (match_dup 3) (match_dup 4))
+ (clobber (reg:CC FLAGS_REG))])])
+
+(define_insn "*stack_protect_set_3"
+ [(set (match_operand:DI 0 "memory_operand" "=m,m,m")
+ (unspec:DI [(match_operand:DI 3 "memory_operand" "m,m,m")]
+ UNSPEC_SP_SET))
+ (set (match_operand:DI 1 "register_operand" "=&r,r,r")
+ (match_operand:DI 2 "general_operand" "Z,rem,i"))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_64BIT
+ && reload_completed
+ && !reg_overlap_mentioned_p (operands[1], operands[2])"
+{
+ output_asm_insn ("mov{q}\t{%3, %1|%1, %3}", operands);
+ output_asm_insn ("mov{q}\t{%1, %0|%0, %1}", operands);
+ if (which_alternative == 0)
+ return "mov{l}\t{%k2, %k1|%k1, %k2}";
+ else if (which_alternative == 2)
+ return "movabs{q}\t{%2, %1|%1, %2}";
+ else if (pic_32bit_operand (operands[2], DImode)
+ || ix86_use_lea_for_mov (insn, operands + 1))
+ return "lea{q}\t{%E2, %1|%1, %E2}";
+ else
+ return "mov{q}\t{%2, %1|%1, %2}";
+}
+ [(set_attr "type" "multi")
+ (set_attr "length" "24")])
+
+(define_peephole2
+ [(parallel [(set (match_operand:DI 0 "memory_operand")
+ (unspec:DI [(match_operand:DI 1 "memory_operand")]
+ UNSPEC_SP_SET))
+ (set (match_operand:DI 2 "general_reg_operand") (const_int 0))
+ (clobber (reg:CC FLAGS_REG))])
+ (set (match_dup 2) (match_operand:DI 3))]
+ "TARGET_64BIT
+ && (general_reg_operand (operands[3], DImode)
+ || memory_operand (operands[3], DImode)
+ || x86_64_zext_immediate_operand (operands[3], DImode)
+ || x86_64_immediate_operand (operands[3], DImode)
+ || (CONSTANT_P (operands[3])
+ && (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[3]))))
+ && !reg_overlap_mentioned_p (operands[2], operands[3])"
+ [(parallel [(set (match_dup 0)
+ (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
+ (set (match_dup 2) (match_dup 3))
+ (clobber (reg:CC FLAGS_REG))])])
+
(define_expand "stack_protect_test"
[(match_operand 0 "memory_operand")
(match_operand 1 "memory_operand")
UNSPEC_SP_TEST))
(clobber (match_scratch:PTR 3 "=&r"))]
""
- "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;sub{<imodesuffix>}\t{%2, %3|%3, %2}"
+{
+ output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
+ return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
+}
[(set_attr "type" "multi")])
(define_insn "sse4_2_crc32<mode>"