summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>2016-06-24 17:32:52 +0000
committerH.J. Lu <hjl.tools@gmail.com>2016-06-25 17:18:15 -0700
commitd42e07e4f96d36e46d1538e3f2effeef2cc1595b (patch)
tree2f4a525ae89f7c2cd0575519830818fa211e0141
parent08ef2fe8a3290ede10d6827bc57ebc2488d5db7a (diff)
downloadgcc-hjl/no-plt/gcc-6-branch.tar.gz
Call tls_get_addr via GOT for GNU TLS if possiblehjl/no-plt/gcc-6-branch
There are extensions to x86-64 psABI: https://groups.google.com/forum/#!topic/x86-64-abi/de5_KnLHxtI and i386 psABI: https://groups.google.com/forum/#!topic/ia32-abi/awsRSvJOJfs to call tls_get_addr via GOT. X86 assembler and linker in binutils 2.27 implemented call *__tls_get_addr@GOTPCREL(%rip) in 64-bit and call *___tls_get_addr@GOT(%reg) in 32-bit to access global and local thread loal variables in shared library. We check if 32-bit x86 assembler and linker work with call *___tls_get_addr@GOT(%reg) as 32-bit and 64-bit assembler and linker are enabled togther. In 32-bit, since any integer register except EAX, which is used to pass parameter to ___tls_get_addr, and ESP, can be used as GOT base, a new register class, TLS_GOTBASE_REGS, along with a new constraint, Yb, are added. They are used to improve register allocation for 32-bit dynamic TLS patterns. gcc/ * configure.ac (calling ___tls_get_addr via GOT): New assembler/linker check. (HAVE_AS_IX86_TLS_GET_ADDR_GOT): New. Defined to 1 if 32-bit assembler and linker supports calling ___tls_get_addr via GOT. Otherise, defined to 0. * config.in: Regenerated. * configure: Likewise. * config/i386/constraints.md (Yb): New constraint. * config/i386/i386.h (reg_class): Add TLS_GOTBASE_REGS. (REG_CLASS_NAMES): Likewise. (REG_CLASS_CONTENTS): Likewise. * config/i386/i386.md (*tls_global_dynamic_32_gnu): Replace the b constraint with the Yb constraint. Call ___tls_get_addr via GOT for GNU TLS with -fno-plt if HAVE_AS_IX86_TLS_GET_ADDR_GOT is 1. (*tls_local_dynamic_base_32_gnu): Likewise. (*tls_global_dynamic_64_<mode>): Call _tls_get_addr via GOT for GNU TLS with -fno-plt if HAVE_AS_IX86_TLS_GET_ADDR_GOT is 1. (*tls_local_dynamic_base_64_<mode>): Likewise. gcc/testsuite/ * gcc.target/i386/noplt-gd-1.c: New test. * gcc.target/i386/noplt-gd-2.c: Likewise. * gcc.target/i386/noplt-gd-3.c: Likewise. * gcc.target/i386/noplt-ld-1.c: Likewise. * gcc.target/i386/noplt-ld-2.c: Likewise. * gcc.target/i386/noplt-ld-3.c: Likewise. * lib/target-supports.exp (check_effective_target_tls_get_addr_via_got): New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@237765 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/config.in7
-rw-r--r--gcc/config/i386/constraints.md11
-rw-r--r--gcc/config/i386/i386.h3
-rw-r--r--gcc/config/i386/i386.md33
-rwxr-xr-xgcc/configure54
-rw-r--r--gcc/configure.ac31
-rw-r--r--gcc/testsuite/gcc.target/i386/noplt-gd-1.c27
-rw-r--r--gcc/testsuite/gcc.target/i386/noplt-gd-2.c28
-rw-r--r--gcc/testsuite/gcc.target/i386/noplt-gd-3.c12
-rw-r--r--gcc/testsuite/gcc.target/i386/noplt-ld-1.c27
-rw-r--r--gcc/testsuite/gcc.target/i386/noplt-ld-2.c21
-rw-r--r--gcc/testsuite/gcc.target/i386/noplt-ld-3.c12
-rw-r--r--gcc/testsuite/lib/target-supports.exp51
13 files changed, 308 insertions, 9 deletions
diff --git a/gcc/config.in b/gcc/config.in
index f525343dd4a..3fa6e3298b9 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -478,6 +478,13 @@
#endif
+/* Define 0/1 if your assembler and linker support calling ___tls_get_addr via
+ GOT. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_AS_IX86_TLS_GET_ADDR_GOT
+#endif
+
+
/* Define if your assembler supports the 'ud2' mnemonic. */
#ifndef USED_FOR_TARGET
#undef HAVE_AS_IX86_UD2
diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md
index 1a4c701ad13..8cd273beff9 100644
--- a/gcc/config/i386/constraints.md
+++ b/gcc/config/i386/constraints.md
@@ -104,6 +104,10 @@
;; m MMX inter-unit moves to MMX register enabled
;; n MMX inter-unit moves from MMX register enabled
;; a Integer register when zero extensions with AND are disabled
+;; b Any register that can be used as the GOT base when calling
+;; ___tls_get_addr: that is, any general register except EAX
+;; and ESP, for -fno-plt if linker supports it. Otherwise,
+;; EBX.
;; p Integer register when TARGET_PARTIAL_REG_STALL is disabled
;; f x87 register when 80387 floating point arithmetic is enabled
;; r SSE regs not requiring REX prefix when prefixes avoidance is enabled
@@ -137,6 +141,13 @@
? NO_REGS : GENERAL_REGS"
"@internal Any integer register when zero extensions with AND are disabled.")
+(define_register_constraint "Yb"
+ "(!flag_plt && HAVE_AS_IX86_TLS_GET_ADDR_GOT) ? TLS_GOTBASE_REGS : BREG"
+ "@internal Any register that can be used as the GOT base when calling
+ ___tls_get_addr: that is, any general register except @code{a} and
+ @code{sp} registers, for -fno-plt if linker supports it. Otherwise,
+ @code{b} register.")
+
(define_register_constraint "Yf"
"(ix86_fpmath & FPMATH_387) ? FLOAT_REGS : NO_REGS"
"@internal Any x87 register when 80387 FP arithmetic is enabled.")
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index ec306f37d3b..d54831239a0 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -1346,6 +1346,7 @@ enum reg_class
CLOBBERED_REGS, /* call-clobbered integer registers */
Q_REGS, /* %eax %ebx %ecx %edx */
NON_Q_REGS, /* %esi %edi %ebp %esp */
+ TLS_GOTBASE_REGS, /* %ebx %ecx %edx %esi %edi %ebp */
INDEX_REGS, /* %eax %ebx %ecx %edx %esi %edi %ebp */
LEGACY_REGS, /* %eax %ebx %ecx %edx %esi %edi %ebp %esp */
GENERAL_REGS, /* %eax %ebx %ecx %edx %esi %edi %ebp %esp
@@ -1406,6 +1407,7 @@ enum reg_class
"AD_REGS", \
"CLOBBERED_REGS", \
"Q_REGS", "NON_Q_REGS", \
+ "TLS_GOTBASE_REGS", \
"INDEX_REGS", \
"LEGACY_REGS", \
"GENERAL_REGS", \
@@ -1446,6 +1448,7 @@ enum reg_class
{ 0x07, 0x0, 0x0 }, /* CLOBBERED_REGS */ \
{ 0x0f, 0x0, 0x0 }, /* Q_REGS */ \
{ 0x1100f0, 0x1fe0, 0x0 }, /* NON_Q_REGS */ \
+ { 0x7e, 0x1fe0, 0x0 }, /* TLS_GOTBASE_REGS */ \
{ 0x7f, 0x1fe0, 0x0 }, /* INDEX_REGS */ \
{ 0x1100ff, 0x0, 0x0 }, /* LEGACY_REGS */ \
{ 0x1100ff, 0x1fe0, 0x0 }, /* GENERAL_REGS */ \
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index c4c4cd85934..0b3d7913381 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -13564,7 +13564,7 @@
(define_insn "*tls_global_dynamic_32_gnu"
[(set (match_operand:SI 0 "register_operand" "=a")
(unspec:SI
- [(match_operand:SI 1 "register_operand" "b")
+ [(match_operand:SI 1 "register_operand" "Yb")
(match_operand 2 "tls_symbolic_operand")
(match_operand 3 "constant_call_address_operand" "Bz")
(reg:SI SP_REG)]
@@ -13574,15 +13574,21 @@
(clobber (reg:CC FLAGS_REG))]
"!TARGET_64BIT && TARGET_GNU_TLS"
{
- output_asm_insn
- ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
+ if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
+ output_asm_insn
+ ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
+ else
+ output_asm_insn
+ ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
if (TARGET_SUN_TLS)
#ifdef HAVE_AS_IX86_TLSGDPLT
return "call\t%a2@tlsgdplt";
#else
return "call\t%p3@plt";
#endif
- return "call\t%P3";
+ if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
+ return "call\t%P3";
+ return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
}
[(set_attr "type" "multi")
(set_attr "length" "12")])
@@ -13615,11 +13621,16 @@
fputs (ASM_BYTE "0x66\n", asm_out_file);
output_asm_insn
("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
- fputs (ASM_SHORT "0x6666\n", asm_out_file);
+ if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
+ fputs (ASM_SHORT "0x6666\n", asm_out_file);
+ else
+ fputs (ASM_BYTE "0x66\n", asm_out_file);
fputs ("\trex64\n", asm_out_file);
if (TARGET_SUN_TLS)
return "call\t%p2@plt";
- return "call\t%P2";
+ if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
+ return "call\t%P2";
+ return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
}
[(set_attr "type" "multi")
(set (attr "length")
@@ -13663,7 +13674,7 @@
(define_insn "*tls_local_dynamic_base_32_gnu"
[(set (match_operand:SI 0 "register_operand" "=a")
(unspec:SI
- [(match_operand:SI 1 "register_operand" "b")
+ [(match_operand:SI 1 "register_operand" "Yb")
(match_operand 2 "constant_call_address_operand" "Bz")
(reg:SI SP_REG)]
UNSPEC_TLS_LD_BASE))
@@ -13681,7 +13692,9 @@
else
return "call\t%p2@plt";
}
- return "call\t%P2";
+ if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
+ return "call\t%P2";
+ return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
}
[(set_attr "type" "multi")
(set_attr "length" "11")])
@@ -13712,7 +13725,9 @@
("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
if (TARGET_SUN_TLS)
return "call\t%p1@plt";
- return "call\t%P1";
+ if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
+ return "call\t%P1";
+ return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
}
[(set_attr "type" "multi")
(set_attr "length" "12")])
diff --git a/gcc/configure b/gcc/configure
index fa683d61228..960e0503589 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -25982,6 +25982,60 @@ cat >>confdefs.h <<_ACEOF
#define HAVE_AS_IX86_GOT32X `if test x"$gcc_cv_as_ix86_got32x" = xyes; then echo 1; else echo 0; fi`
_ACEOF
+
+ conftest_s='
+ .section .text,"ax",@progbits
+ .globl _start
+ .type _start, @function
+_start:
+ leal ld@tlsldm(%ecx), %eax
+ call *___tls_get_addr@GOT(%ecx)
+ leal gd@tlsgd(%ecx), %eax
+ call *___tls_get_addr@GOT(%ecx)
+
+ .section .tdata,"aw'$tls_section_flag'",@progbits
+ .type ld, @object
+ld:
+ .byte 0
+ .globl gd
+ .type gd, @object
+gd:
+ .byte 0'
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for calling ___tls_get_addr via GOT" >&5
+$as_echo_n "checking assembler for calling ___tls_get_addr via GOT... " >&6; }
+if test "${gcc_cv_as_ix86_tls_get_addr_via_got+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcc_cv_as_ix86_tls_get_addr_via_got=no
+ if test x$gcc_cv_as != x; then
+ $as_echo "$conftest_s" > conftest.s
+ if { ac_try='$gcc_cv_as $gcc_cv_as_flags $as_ix86_gas_32_opt -o conftest.o conftest.s >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }
+ then
+ if test x$gcc_cv_ld != x \
+ && $gcc_cv_ld $ld_ix86_gld_32_opt -o conftest conftest.o > /dev/null 2>&1; then
+ gcc_cv_as_ix86_tls_get_addr_via_got=yes
+ fi
+ rm -f conftest
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
+ fi
+ rm -f conftest.o conftest.s
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_ix86_tls_get_addr_via_got" >&5
+$as_echo "$gcc_cv_as_ix86_tls_get_addr_via_got" >&6; }
+
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_AS_IX86_TLS_GET_ADDR_GOT `if test x"$gcc_cv_as_ix86_tls_get_addr_via_got" = xyes; then echo 1; else echo 0; fi`
+_ACEOF
+
;;
ia64*-*-*)
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 73764f30183..38cf3c176f8 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -4207,6 +4207,37 @@ _start:
AC_DEFINE_UNQUOTED(HAVE_AS_IX86_GOT32X,
[`if test x"$gcc_cv_as_ix86_got32x" = xyes; then echo 1; else echo 0; fi`],
[Define 0/1 if your assembler and linker support @GOT.])
+
+ conftest_s='
+ .section .text,"ax",@progbits
+ .globl _start
+ .type _start, @function
+_start:
+ leal ld@tlsldm(%ecx), %eax
+ call *___tls_get_addr@GOT(%ecx)
+ leal gd@tlsgd(%ecx), %eax
+ call *___tls_get_addr@GOT(%ecx)
+
+ .section .tdata,"aw'$tls_section_flag'",@progbits
+ .type ld, @object
+ld:
+ .byte 0
+ .globl gd
+ .type gd, @object
+gd:
+ .byte 0'
+ gcc_GAS_CHECK_FEATURE([calling ___tls_get_addr via GOT],
+ gcc_cv_as_ix86_tls_get_addr_via_got,,
+ [$as_ix86_gas_32_opt],
+ [$conftest_s],
+ [if test x$gcc_cv_ld != x \
+ && $gcc_cv_ld $ld_ix86_gld_32_opt -o conftest conftest.o > /dev/null 2>&1; then
+ gcc_cv_as_ix86_tls_get_addr_via_got=yes
+ fi
+ rm -f conftest])
+ AC_DEFINE_UNQUOTED(HAVE_AS_IX86_TLS_GET_ADDR_GOT,
+ [`if test x"$gcc_cv_as_ix86_tls_get_addr_via_got" = xyes; then echo 1; else echo 0; fi`],
+ [Define 0/1 if your assembler and linker support calling ___tls_get_addr via GOT.])
;;
ia64*-*-*)
diff --git a/gcc/testsuite/gcc.target/i386/noplt-gd-1.c b/gcc/testsuite/gcc.target/i386/noplt-gd-1.c
new file mode 100644
index 00000000000..5d5b531b744
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/noplt-gd-1.c
@@ -0,0 +1,27 @@
+/* { dg-do compile { target { *-*-linux* && tls_get_addr_via_got } } } */
+/* { dg-options "-fpic -fno-plt" } */
+
+extern __thread int gd;
+
+int *
+get_gd (void)
+{
+ return &gd;
+}
+
+void
+set_gd (int i)
+{
+ gd = i;
+}
+
+int
+test_gd (int i)
+{
+ return gd == i;
+}
+
+/* { dg-final { scan-assembler "call\[ \t\]\\*__tls_get_addr@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]\\*___tls_get_addr@GOT\\(" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "call\[ \t\]__tls_get_addr@PLT" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "call\[ \t\]___tls_get_addr@PLT" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/noplt-gd-2.c b/gcc/testsuite/gcc.target/i386/noplt-gd-2.c
new file mode 100644
index 00000000000..9a6c275ac1e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/noplt-gd-2.c
@@ -0,0 +1,28 @@
+/* { dg-do run { target { *-*-linux* } } } */
+/* { dg-options "-O2 -fpic -fno-plt" } */
+/* { dg-additional-sources noplt-gd-1.c } */
+
+__thread int gd = 1;
+extern void abort (void);
+extern int * get_gd (void);
+extern void set_gd (int);
+extern int test_gd (int);
+
+int
+main ()
+{
+ int *p;
+
+ if (gd != 1)
+ abort ();
+
+ p = get_gd ();
+ if (*p != gd)
+ abort ();
+
+ set_gd (4);
+ if (*p != 4 || !test_gd (4))
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/noplt-gd-3.c b/gcc/testsuite/gcc.target/i386/noplt-gd-3.c
new file mode 100644
index 00000000000..6b0e780b745
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/noplt-gd-3.c
@@ -0,0 +1,12 @@
+/* { dg-do compile { target { *-*-linux* && { ia32 && tls_get_addr_via_got } } } } */
+/* { dg-options "-fpic -fno-plt" } */
+
+extern __thread int gd;
+
+int *
+get_gd (void)
+{
+ return &gd;
+}
+
+/* { dg-final { scan-assembler-not "call\[ \t\]\\*___tls_get_addr@GOT\\(%ebx\\)" } } */
diff --git a/gcc/testsuite/gcc.target/i386/noplt-ld-1.c b/gcc/testsuite/gcc.target/i386/noplt-ld-1.c
new file mode 100644
index 00000000000..87698301bff
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/noplt-ld-1.c
@@ -0,0 +1,27 @@
+/* { dg-do compile { target { *-*-linux* && tls_get_addr_via_got } } } */
+/* { dg-options "-fpic -fno-plt" } */
+
+static __thread int ld;
+
+int *
+get_ld (void)
+{
+ return &ld;
+}
+
+void
+set_ld (int i)
+{
+ ld = i;
+}
+
+int
+test_ld (int i)
+{
+ return ld == i;
+}
+
+/* { dg-final { scan-assembler "call\[ \t\]\\*__tls_get_addr@GOTPCREL" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]\\*___tls_get_addr@GOT\\(" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "call\[ \t\]__tls_get_addr@PLT" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-not "call\[ \t\]___tls_get_addr@PLT" { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/noplt-ld-2.c b/gcc/testsuite/gcc.target/i386/noplt-ld-2.c
new file mode 100644
index 00000000000..86cc93e0844
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/noplt-ld-2.c
@@ -0,0 +1,21 @@
+/* { dg-do run { target { *-*-linux* } } } */
+/* { dg-options "-O2 -fpic -fno-plt" } */
+/* { dg-additional-sources noplt-ld-1.c } */
+
+extern void abort (void);
+extern int * get_ld (void);
+extern void set_ld (int);
+extern int test_ld (int);
+
+int
+main ()
+{
+ int *p;
+
+ p = get_ld ();
+ set_ld (4);
+ if (*p != 4 || !test_ld (4))
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/noplt-ld-3.c b/gcc/testsuite/gcc.target/i386/noplt-ld-3.c
new file mode 100644
index 00000000000..b014d53baab
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/noplt-ld-3.c
@@ -0,0 +1,12 @@
+/* { dg-do compile { target { *-*-linux* && { ia32 && tls_get_addr_via_got } } } } */
+/* { dg-options "-fpic -fno-plt" } */
+
+static __thread int ld;
+
+int *
+get_ld (void)
+{
+ return &ld;
+}
+
+/* { dg-final { scan-assembler-not "call\[ \t\]\\*___tls_get_addr@GOT\\(%ebx\\)" } } */
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 20e8853515c..095fd36d2e3 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -6991,6 +6991,57 @@ proc check_effective_target_got32x_reloc { } {
return $got32x_reloc_available_saved
}
+# Return 1 if the x86 target supports calling ___tls_get_addr via GOT,
+# 0 otherwise. Cache the result.
+
+proc check_effective_target_tls_get_addr_via_got { } {
+ global tls_get_addr_via_got_available_saved
+ global tool
+ global GCC_UNDER_TEST
+
+ if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } {
+ return 0
+ }
+
+ # Need auto-host.h to check linker support.
+ if { ![file exists ../../auto-host.h ] } {
+ return 0
+ }
+
+ if [info exists tls_get_addr_via_got_available_saved] {
+ verbose "check_effective_target_tls_get_addr_via_got returning saved $tls_get_addr_via_got_available_saved" 2
+ } else {
+ # Include the current process ID in the file names to prevent
+ # conflicts with invocations for multiple testsuites.
+
+ set src tls_get_addr_via_got[pid].c
+ set obj tls_get_addr_via_got[pid].o
+
+ set f [open $src "w"]
+ puts $f "#include \"../../auto-host.h\""
+ puts $f "#if HAVE_AS_IX86_TLS_GET_ADDR_GOT == 0"
+ puts $f "# error Assembler/linker do not support calling ___tls_get_addr via GOT."
+ puts $f "#endif"
+ close $f
+
+ verbose "check_effective_target_tls_get_addr_via_got compiling testfile $src" 2
+ set lines [${tool}_target_compile $src $obj object ""]
+
+ file delete $src
+ file delete $obj
+
+ if [string match "" $lines] then {
+ verbose "check_effective_target_tls_get_addr_via_got testfile compilation passed" 2
+ set tls_get_addr_via_got_available_saved 1
+ } else {
+ verbose "check_effective_target_tls_get_addr_via_got testfile compilation failed" 2
+ set tls_get_addr_via_got_available_saved 0
+ }
+ }
+
+ return $tls_get_addr_via_got_available_saved
+}
+
# Return 1 if the target uses comdat groups.
proc check_effective_target_comdat_group {} {