Message ID | 20120302205603.GC2179@intel.com |
---|---|
State | New |
Headers | show |
On Fri, Mar 2, 2012 at 9:56 PM, H.J. Lu <hongjiu.lu@intel.com> wrote: > Since the 0x67 address prefix only zeros out the upper 32bits of the > (reg) part in address fs:(reg), we can't use fs:(reg) as memory operand > for x32 with Pmode == SImode. We have to load the address into a > register first and use it as memory operand. Tested on Linux/x86-64. > OK for trunk? This patch won't be needed when TARGET_TLS_DIRECT_SEG_REFS will be cleared, as suggested in [1]. [1] http://gcc.gnu.org/ml/gcc-patches/2012-03/msg00252.html Uros.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 7cb8fda..d6ec6ff 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -12687,7 +12687,16 @@ legitimize_tls_address (rtx x, enum tls_model model, bool for_mov) if (TARGET_64BIT || TARGET_ANY_GNU_TLS) { base = get_thread_pointer (for_mov || !TARGET_TLS_DIRECT_SEG_REFS); - return gen_rtx_PLUS (Pmode, base, off); + if (Pmode != word_mode) + { + /* Since address override works only on the (reg) part in + fs:(reg), we can't use it as memory operand. */ + rtx reg = gen_reg_rtx (Pmode); + emit_move_insn (reg, base); + return gen_rtx_PLUS (Pmode, reg, off); + } + else + return gen_rtx_PLUS (Pmode, base, off); } else {