Hi, 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?
Thanks. H.J. 2012-03-02 H.J. Lu <hongjiu...@intel.com> * config/i386/i386.c (legitimize_tls_address): Load TP into register for TLS_MODEL_LOCAL_EXEC modes in x32. 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 { -- 1.7.6.5