summaryrefslogtreecommitdiff
path: root/gcc/config/i386/i386.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/i386/i386.md')
-rw-r--r--gcc/config/i386/i386.md64
1 files changed, 62 insertions, 2 deletions
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 1ca5d223272..c0823b608d8 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -81,8 +81,6 @@
(UNSPEC_FLDCW 25)
(UNSPEC_REP 26)
(UNSPEC_EH_RETURN 27)
- (UNSPEC_SP_SET 28)
- (UNSPEC_SP_TEST 29)
; For SSE/MMX support:
(UNSPEC_FIX_NOTRUNC 30)
@@ -140,6 +138,12 @@
(UNSPEC_FPREM_U 89)
(UNSPEC_FPREM1_F 90)
(UNSPEC_FPREM1_U 91)
+
+ ; SSP patterns
+ (UNSPEC_SP_SET 100)
+ (UNSPEC_SP_TEST 101)
+ (UNSPEC_SP_TLS_SET 102)
+ (UNSPEC_SP_TLS_TEST 103)
])
(define_constants
@@ -19613,10 +19617,19 @@
(match_operand 1 "memory_operand" "")]
""
{
+#ifdef TARGET_THREAD_SSP_OFFSET
+ if (TARGET_64BIT)
+ emit_insn (gen_stack_tls_protect_set_di (operands[0],
+ GEN_INT (TARGET_THREAD_SSP_OFFSET)));
+ else
+ emit_insn (gen_stack_tls_protect_set_si (operands[0],
+ GEN_INT (TARGET_THREAD_SSP_OFFSET)));
+#else
if (TARGET_64BIT)
emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
else
emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
+#endif
DONE;
})
@@ -19638,6 +19651,24 @@
"mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
[(set_attr "type" "multi")])
+(define_insn "stack_tls_protect_set_si"
+ [(set (match_operand:SI 0 "memory_operand" "=m")
+ (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
+ (set (match_scratch:SI 2 "=&r") (const_int 0))
+ (clobber (reg:CC FLAGS_REG))]
+ ""
+ "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
+ [(set_attr "type" "multi")])
+
+(define_insn "stack_tls_protect_set_di"
+ [(set (match_operand:DI 0 "memory_operand" "=m")
+ (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
+ (set (match_scratch:DI 2 "=&r") (const_int 0))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_64BIT"
+ "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
+ [(set_attr "type" "multi")])
+
(define_expand "stack_protect_test"
[(match_operand 0 "memory_operand" "")
(match_operand 1 "memory_operand" "")
@@ -19649,10 +19680,19 @@
ix86_compare_op1 = operands[1];
ix86_compare_emitted = flags;
+#ifdef TARGET_THREAD_SSP_OFFSET
+ if (TARGET_64BIT)
+ emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
+ GEN_INT (TARGET_THREAD_SSP_OFFSET)));
+ else
+ emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
+ GEN_INT (TARGET_THREAD_SSP_OFFSET)));
+#else
if (TARGET_64BIT)
emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
else
emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
+#endif
emit_jump_insn (gen_beq (operands[2]));
DONE;
})
@@ -19677,6 +19717,26 @@
"mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
[(set_attr "type" "multi")])
+(define_insn "stack_tls_protect_test_si"
+ [(set (match_operand:CCZ 0 "flags_reg_operand" "")
+ (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
+ (match_operand:SI 2 "const_int_operand" "i")]
+ UNSPEC_SP_TLS_TEST))
+ (clobber (match_scratch:SI 3 "=r"))]
+ ""
+ "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
+ [(set_attr "type" "multi")])
+
+(define_insn "stack_tls_protect_test_di"
+ [(set (match_operand:CCZ 0 "flags_reg_operand" "")
+ (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
+ (match_operand:DI 2 "const_int_operand" "i")]
+ UNSPEC_SP_TLS_TEST))
+ (clobber (match_scratch:DI 3 "=r"))]
+ "TARGET_64BIT"
+ "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
+ [(set_attr "type" "multi")])
+
(include "sse.md")
(include "mmx.md")
(include "sync.md")