diff options
author | hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-03-10 18:47:52 +0000 |
---|---|---|
committer | hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-03-10 18:47:52 +0000 |
commit | fe73ce464d6780175d5d8add5fbff7a9e5c639da (patch) | |
tree | 509d003bc07727357da8824fb54ec875c92e9a2f /gcc/config/i386/i386.md | |
parent | 553877d921e5d7e7d156c95e1214106d2edfa37c (diff) | |
download | gcc-fe73ce464d6780175d5d8add5fbff7a9e5c639da.tar.gz |
Properly generate x32 TLS IE sequence
2012-03-10 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/i386.c (ix86_decompose_address): Disallow fs:(reg)
if Pmode != word_mode.
(legitimize_tls_address): Call gen_tls_initial_exec_x32 if
Pmode == SImode for x32.
* config/i386/i386.md (UNSPEC_TLS_IE_X32): New.
(tls_initial_exec_x32): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@185179 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/i386/i386.md')
-rw-r--r-- | gcc/config/i386/i386.md | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index a4a7d3ab1b8..dcbfab43eee 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -96,6 +96,7 @@ UNSPEC_TLS_LD_BASE UNSPEC_TLSDESC UNSPEC_TLS_IE_SUN + UNSPEC_TLS_IE_X32 ;; Other random patterns UNSPEC_SCAS @@ -12777,6 +12778,28 @@ } [(set_attr "type" "multi")]) +;; When Pmode == SImode, there may be no REX prefix for ADD. Avoid +;; any instructions between MOV and ADD, which may interfere linker +;; IE->LE optimization, since the last byte of the previous instruction +;; before ADD may look like a REX prefix. This also avoids +;; movl x@gottpoff(%rip), %reg32 +;; movl $fs:(%reg32), %reg32 +;; Since address override works only on the (reg32) part in fs:(reg32), +;; we can't use it as memory operand. +(define_insn "tls_initial_exec_x32" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec:SI + [(match_operand:SI 1 "tls_symbolic_operand" "")] + UNSPEC_TLS_IE_X32)) + (clobber (reg:CC FLAGS_REG))] + "TARGET_X32" +{ + output_asm_insn + ("mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}", operands); + return "add{l}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}"; +} + [(set_attr "type" "multi")]) + ;; GNU2 TLS patterns can be split. (define_expand "tls_dynamic_gnu2_32" |