PATCH: Properly generate X32 IE sequence
Uros Bizjak
ubizjak@gmail.com
Mon Mar 12 19:39:00 GMT 2012
On Sun, Mar 11, 2012 at 10:24 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> Here is the patch which is equivalent to clearing MASK_TLS_DIRECT_SEG_REFS
> when Pmode != word_mode. We need to keep
>
> 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;
> }
>
> to support linker IE->LE optimization. TARGET_TLS_DIRECT_SEG_REFS only affects
> TLS LE access and fs:(%reg) is only generated by combine.
>
> So the main impact of disabling TARGET_TLS_DIRECT_SEG_REFS is to disable
> fs:immediate memory operand for TLS LE access, which doesn't have any problems
> to begin with.
>
> I would prefer to keep TARGET_TLS_DIRECT_SEG_REFS and disable only
> fs:(%reg), which is generated by combine.
Please try attached patch. It introduces TARGET_TLS_INDIRECT_SEG_REFS
to block only indirect seg references.
Uros.
-------------- next part --------------
Index: i386.c
===================================================================
--- i386.c (revision 185250)
+++ i386.c (working copy)
@@ -11552,11 +11552,6 @@ ix86_decompose_address (rtx addr, struct ix86_addr
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))
@@ -11568,6 +11563,10 @@ ix86_decompose_address (rtx addr, struct ix86_addr
return 0;
}
+ if (seg != SEG_DEFAULT && (base || index)
+ && !TARGET_TLS_INDIRECT_SEG_REFS)
+ return 0;
+
/* Extract the integral value of scale. */
if (scale_rtx)
{
@@ -12696,7 +12695,9 @@ legitimize_tls_address (rtx x, enum tls_model mode
if (TARGET_64BIT || TARGET_ANY_GNU_TLS)
{
- base = get_thread_pointer (for_mov || !TARGET_TLS_DIRECT_SEG_REFS);
+ base = get_thread_pointer (for_mov
+ || !(TARGET_TLS_DIRECT_SEG_REFS
+ && TARGET_TLS_INDIRECT_SEG_REFS));
off = force_reg (Pmode, off);
return gen_rtx_PLUS (Pmode, base, off);
}
@@ -12716,7 +12717,9 @@ legitimize_tls_address (rtx x, enum tls_model mode
if (TARGET_64BIT || TARGET_ANY_GNU_TLS)
{
- base = get_thread_pointer (for_mov || !TARGET_TLS_DIRECT_SEG_REFS);
+ base = get_thread_pointer (for_mov
+ || !(TARGET_TLS_DIRECT_SEG_REFS
+ && TARGET_TLS_INDIRECT_SEG_REFS));
return gen_rtx_PLUS (Pmode, base, off);
}
else
@@ -13249,7 +13252,8 @@ ix86_delegitimize_tls_address (rtx orig_x)
rtx x = orig_x, unspec;
struct ix86_address addr;
- if (!TARGET_TLS_DIRECT_SEG_REFS)
+ if (!(TARGET_TLS_DIRECT_SEG_REFS
+ && TARGET_TLS_INDIRECT_SEG_REFS))
return orig_x;
if (MEM_P (x))
x = XEXP (x, 0);
Index: i386.h
===================================================================
--- i386.h (revision 185250)
+++ i386.h (working copy)
@@ -467,6 +467,9 @@ extern int x86_prefetch_sse;
#define TARGET_TLS_DIRECT_SEG_REFS_DEFAULT 0
#endif
+/* Address override works only on the (%reg) part in %fs:(%reg). */
+#define TARGET_TLS_INDIRECT_SEG_REFS (Pmode == word_mode)
+
/* Fence to use after loop using storent. */
extern tree x86_mfence;
More information about the Gcc-patches
mailing list