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. From-SVN: r185179
This commit is contained in:
parent
21d1335b2a
commit
0925565205
|
@ -1,3 +1,13 @@
|
|||
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.
|
||||
|
||||
2012-03-10 Chung-Lin Tang <cltang@codesourcery.com>
|
||||
|
||||
PR rtl-optimization/52528
|
||||
|
|
|
@ -11524,6 +11524,11 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
|
|||
else
|
||||
disp = addr; /* displacement */
|
||||
|
||||
/* Since address override works only on the (reg32) part in fs:(reg32),
|
||||
we can't use it as memory operand. */
|
||||
if (Pmode != word_mode && seg == SEG_FS && (base || index))
|
||||
return 0;
|
||||
|
||||
if (index)
|
||||
{
|
||||
if (REG_P (index))
|
||||
|
@ -12618,6 +12623,17 @@ legitimize_tls_address (rtx x, enum tls_model model, bool for_mov)
|
|||
emit_insn (gen_tls_initial_exec_64_sun (dest, x));
|
||||
return dest;
|
||||
}
|
||||
else if (Pmode == SImode)
|
||||
{
|
||||
/* Always generate
|
||||
movl %fs:0, %reg32
|
||||
addl xgottpoff(%rip), %reg32
|
||||
to support linker IE->LE optimization and avoid
|
||||
fs:(%reg32) as memory operand. */
|
||||
dest = gen_reg_rtx (Pmode);
|
||||
emit_insn (gen_tls_initial_exec_x32 (dest, x));
|
||||
return dest;
|
||||
}
|
||||
|
||||
pic = NULL;
|
||||
type = UNSPEC_GOTNTPOFF;
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue