aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorUros Bizjak <ubizjak@gmail.com>2012-03-13 08:06:51 +0100
committerUros Bizjak <uros@gcc.gnu.org>2012-03-13 08:06:51 +0100
commit6c2f0f83a5c02bf30aebbba56d78687023ab0ea0 (patch)
tree341c7eaa36dd4efddab3badf0da764789a3e714b /gcc
parenta89ff70f6d482ccacab2cf72cafa6554342f83c2 (diff)
downloadgcc-6c2f0f83a5c02bf30aebbba56d78687023ab0ea0.zip
gcc-6c2f0f83a5c02bf30aebbba56d78687023ab0ea0.tar.gz
gcc-6c2f0f83a5c02bf30aebbba56d78687023ab0ea0.tar.bz2
i386.h (TARGET_TLS_INDIRECT_SEG_REFS): New.
* config/i386/i386.h (TARGET_TLS_INDIRECT_SEG_REFS): New. * config/i386/i386.c (ix86_decompose_address): Use TARGET_TLS_INDIRECT_SEG_REFS to prevent %fs:(%reg) addresses. (legitimize_tls_address): Use TARGET_TLS_INDIRECT_SEG_REFS to load thread pointer to a register. From-SVN: r185278
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/i386/i386.c20
-rw-r--r--gcc/config/i386/i386.h3
3 files changed, 23 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 477aa77..7ae84645 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2012-03-13 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.h (TARGET_TLS_INDIRECT_SEG_REFS): New.
+ * config/i386/i386.c (ix86_decompose_address): Use
+ TARGET_TLS_INDIRECT_SEG_REFS to prevent %fs:(%reg) addresses.
+ (legitimize_tls_address): Use TARGET_TLS_INDIRECT_SEG_REFS to load
+ thread pointer to a register.
+
2012-03-12 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/i386.md (*tls_global_dynamic_64_<mode>): Remove :P
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index dbcf5a9..e366892 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -11552,11 +11552,6 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
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_address *out)
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 model, bool for_mov)
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 model, bool for_mov)
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);
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index c77070b..c7d645e 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -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 of %fs:(%reg). */
+#define TARGET_TLS_INDIRECT_SEG_REFS (Pmode == word_mode)
+
/* Fence to use after loop using storent. */
extern tree x86_mfence;