Commit 09255652 by H.J. Lu Committed by H.J. Lu

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
parent 21d1335b
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> 2012-03-10 Chung-Lin Tang <cltang@codesourcery.com>
PR rtl-optimization/52528 PR rtl-optimization/52528
......
...@@ -11524,6 +11524,11 @@ ix86_decompose_address (rtx addr, struct ix86_address *out) ...@@ -11524,6 +11524,11 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
else else
disp = addr; /* displacement */ 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 (index)
{ {
if (REG_P (index)) if (REG_P (index))
...@@ -12618,6 +12623,17 @@ legitimize_tls_address (rtx x, enum tls_model model, bool for_mov) ...@@ -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)); emit_insn (gen_tls_initial_exec_64_sun (dest, x));
return dest; 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; pic = NULL;
type = UNSPEC_GOTNTPOFF; type = UNSPEC_GOTNTPOFF;
...@@ -96,6 +96,7 @@ ...@@ -96,6 +96,7 @@
UNSPEC_TLS_LD_BASE UNSPEC_TLS_LD_BASE
UNSPEC_TLSDESC UNSPEC_TLSDESC
UNSPEC_TLS_IE_SUN UNSPEC_TLS_IE_SUN
UNSPEC_TLS_IE_X32
;; Other random patterns ;; Other random patterns
UNSPEC_SCAS UNSPEC_SCAS
...@@ -12777,6 +12778,28 @@ ...@@ -12777,6 +12778,28 @@
} }
[(set_attr "type" "multi")]) [(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. ;; GNU2 TLS patterns can be split.
(define_expand "tls_dynamic_gnu2_32" (define_expand "tls_dynamic_gnu2_32"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment