@@ -24281,6 +24281,141 @@ (define_expand "restore_stack_nonlocal"
DONE;
})
+(define_expand "stack_protect_set"
+ [(match_operand 0 "memory_operand")
+ (match_operand 1 "memory_operand")]
+ ""
+{
+ rtx scratch = gen_reg_rtx (word_mode);
+
+ emit_insn (gen_stack_protect_set_1
+ (ptr_mode, word_mode, operands[0], operands[1], scratch));
+ DONE;
+})
+
+(define_insn "@stack_protect_set_1_<PTR:mode>_<SWI48:mode>"
+ [(set (match_operand:PTR 0 "memory_operand" "=m")
+ (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
+ UNSPEC_SP_SET))
+ (set (match_operand:SWI48 2 "register_operand" "=&r") (const_int 0))
+ (clobber (reg:CC FLAGS_REG))]
+ ""
+{
+ output_asm_insn ("mov{<PTR:imodesuffix>}\t{%1, %<PTR:k>2|%<PTR:k>2, %1}",
+ operands);
+ output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>2, %0|%0, %<PTR:k>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, 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_peephole2
+ [(parallel [(set (match_operand:PTR 0 "memory_operand")
+ (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
+ UNSPEC_SP_SET))
+ (set (match_operand:W 2 "general_reg_operand") (const_int 0))
+ (clobber (reg:CC FLAGS_REG))])
+ (parallel [(set (match_operand:SWI48 3 "general_reg_operand")
+ (match_operand:SWI48 4 "const0_operand"))
+ (clobber (reg:CC FLAGS_REG))])]
+ "peep2_reg_dead_p (0, operands[3])
+ && peep2_reg_dead_p (1, operands[2])"
+ [(parallel [(set (match_dup 0)
+ (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
+ (set (match_dup 3) (const_int 0))
+ (clobber (reg:CC FLAGS_REG))])])
+
+(define_insn "*stack_protect_set_2_<mode>_si"
+ [(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"))]
+ "reload_completed"
+{
+ 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_insn "*stack_protect_set_2_<mode>_di"
+ [(set (match_operand:PTR 0 "memory_operand" "=m,m,m")
+ (unspec:PTR [(match_operand:PTR 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"))]
+ "TARGET_64BIT && reload_completed"
+{
+ 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], DImode))
+ return "lea{q}\t{%E2, %1|%1, %E2}";
+ else 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 (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:PTR 0 "memory_operand")
+ (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
+ UNSPEC_SP_SET))
+ (set (match_operand:W 2 "general_reg_operand") (const_int 0))
+ (clobber (reg:CC FLAGS_REG))])
+ (set (match_operand:SWI48 3 "general_reg_operand")
+ (match_operand:SWI48 4 "general_gr_operand"))]
+ "peep2_reg_dead_p (0, operands[3])
+ && peep2_reg_dead_p (1, operands[2])"
+ [(parallel [(set (match_dup 0)
+ (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
+ (set (match_dup 3) (match_dup 4))])])
+
+(define_expand "stack_protect_test"
+ [(match_operand 0 "memory_operand")
+ (match_operand 1 "memory_operand")
+ (match_operand 2)]
+ ""
+{
+ rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
+
+ emit_insn (gen_stack_protect_test_1
+ (ptr_mode, flags, operands[0], operands[1]));
+
+ emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
+ flags, const0_rtx, operands[2]));
+ DONE;
+})
+
+(define_insn "@stack_protect_test_1_<mode>"
+ [(set (match_operand:CCZ 0 "flags_reg_operand")
+ (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
+ (match_operand:PTR 2 "memory_operand" "m")]
+ UNSPEC_SP_TEST))
+ (clobber (match_scratch:PTR 3 "=&r"))]
+ ""
+{
+ output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
+ return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
+}
+ [(set_attr "type" "multi")])
;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
;; Do not split instructions with mask registers.
@@ -25648,142 +25783,6 @@ (define_insn "prefetchi"
(symbol_ref "memory_address_length (operands[0], false)"))
(set_attr "memory" "none")])
-(define_expand "stack_protect_set"
- [(match_operand 0 "memory_operand")
- (match_operand 1 "memory_operand")]
- ""
-{
- rtx scratch = gen_reg_rtx (word_mode);
-
- emit_insn (gen_stack_protect_set_1
- (ptr_mode, word_mode, operands[0], operands[1], scratch));
- DONE;
-})
-
-(define_insn "@stack_protect_set_1_<PTR:mode>_<SWI48:mode>"
- [(set (match_operand:PTR 0 "memory_operand" "=m")
- (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
- UNSPEC_SP_SET))
- (set (match_operand:SWI48 2 "register_operand" "=&r") (const_int 0))
- (clobber (reg:CC FLAGS_REG))]
- ""
-{
- output_asm_insn ("mov{<PTR:imodesuffix>}\t{%1, %<PTR:k>2|%<PTR:k>2, %1}",
- operands);
- output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>2, %0|%0, %<PTR:k>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, 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_peephole2
- [(parallel [(set (match_operand:PTR 0 "memory_operand")
- (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
- UNSPEC_SP_SET))
- (set (match_operand:W 2 "general_reg_operand") (const_int 0))
- (clobber (reg:CC FLAGS_REG))])
- (parallel [(set (match_operand:SWI48 3 "general_reg_operand")
- (match_operand:SWI48 4 "const0_operand"))
- (clobber (reg:CC FLAGS_REG))])]
- "peep2_reg_dead_p (0, operands[3])
- && peep2_reg_dead_p (1, operands[2])"
- [(parallel [(set (match_dup 0)
- (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
- (set (match_dup 3) (const_int 0))
- (clobber (reg:CC FLAGS_REG))])])
-
-(define_insn "*stack_protect_set_2_<mode>_si"
- [(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"))]
- "reload_completed"
-{
- 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_insn "*stack_protect_set_2_<mode>_di"
- [(set (match_operand:PTR 0 "memory_operand" "=m,m,m")
- (unspec:PTR [(match_operand:PTR 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"))]
- "TARGET_64BIT && reload_completed"
-{
- 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], DImode))
- return "lea{q}\t{%E2, %1|%1, %E2}";
- else 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 (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:PTR 0 "memory_operand")
- (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
- UNSPEC_SP_SET))
- (set (match_operand:W 2 "general_reg_operand") (const_int 0))
- (clobber (reg:CC FLAGS_REG))])
- (set (match_operand:SWI48 3 "general_reg_operand")
- (match_operand:SWI48 4 "general_gr_operand"))]
- "peep2_reg_dead_p (0, operands[3])
- && peep2_reg_dead_p (1, operands[2])"
- [(parallel [(set (match_dup 0)
- (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
- (set (match_dup 3) (match_dup 4))])])
-
-(define_expand "stack_protect_test"
- [(match_operand 0 "memory_operand")
- (match_operand 1 "memory_operand")
- (match_operand 2)]
- ""
-{
- rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
-
- emit_insn (gen_stack_protect_test_1
- (ptr_mode, flags, operands[0], operands[1]));
-
- emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
- flags, const0_rtx, operands[2]));
- DONE;
-})
-
-(define_insn "@stack_protect_test_1_<mode>"
- [(set (match_operand:CCZ 0 "flags_reg_operand")
- (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
- (match_operand:PTR 2 "memory_operand" "m")]
- UNSPEC_SP_TEST))
- (clobber (match_scratch:PTR 3 "=&r"))]
- ""
-{
- 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>"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI