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

Reply via email to