From patchwork Fri Jun 24 15:57:29 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Lu, Hongjiu" X-Patchwork-Id: 13360 Received: (qmail 68293 invoked by alias); 24 Jun 2016 15:58:03 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 68282 invoked by uid 89); 24 Jun 2016 15:58:03 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=0.4 required=5.0 tests=BAYES_50, KAM_LAZY_DOMAIN_SECURITY, NO_DNS_FOR_FROM, RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=xgcc_cv_ld, conftest, sk:x"$gcc_, conftesto X-HELO: mga02.intel.com X-ExtLoop1: 1 Date: Fri, 24 Jun 2016 08:57:29 -0700 From: "H.J. Lu" To: GNU C Library Cc: Uros Bizjak Subject: [PATCH] Call tls_get_addr via GOT for GNU TLS if possible Message-ID: <20160624155729.GA12941@intel.com> Reply-To: "H.J. Lu" MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.6.1 (2016-04-27) 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_REGS, along with a new constraint, Yb, are added. They are used to improve register allocation for 32-bit dynamic TLS patterns. Tested on i686 and x86-64. OK for trunk? Thanks. H.J. --- 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_REGS. (REG_CLASS_NAMES): Add TLS_REGS. (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_): 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_): 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. --- gcc/config.in | 7 ++++ gcc/config/i386/constraints.md | 11 ++++++ gcc/config/i386/i386.h | 3 ++ gcc/config/i386/i386.md | 33 +++++++++++++----- gcc/configure | 54 ++++++++++++++++++++++++++++++ gcc/configure.ac | 31 +++++++++++++++++ gcc/testsuite/gcc.target/i386/noplt-gd-1.c | 27 +++++++++++++++ gcc/testsuite/gcc.target/i386/noplt-gd-2.c | 28 ++++++++++++++++ gcc/testsuite/gcc.target/i386/noplt-gd-3.c | 12 +++++++ gcc/testsuite/gcc.target/i386/noplt-ld-1.c | 27 +++++++++++++++ gcc/testsuite/gcc.target/i386/noplt-ld-2.c | 21 ++++++++++++ gcc/testsuite/gcc.target/i386/noplt-ld-3.c | 12 +++++++ gcc/testsuite/lib/target-supports.exp | 51 ++++++++++++++++++++++++++++ 13 files changed, 308 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/noplt-gd-1.c create mode 100644 gcc/testsuite/gcc.target/i386/noplt-gd-2.c create mode 100644 gcc/testsuite/gcc.target/i386/noplt-gd-3.c create mode 100644 gcc/testsuite/gcc.target/i386/noplt-ld-1.c create mode 100644 gcc/testsuite/gcc.target/i386/noplt-ld-2.c create mode 100644 gcc/testsuite/gcc.target/i386/noplt-ld-3.c diff --git a/gcc/config.in b/gcc/config.in index 5f80176..fc3321c 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -485,6 +485,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 a2466a9..8f17bca 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_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 cab0a5d..acd6f90 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -1347,6 +1347,7 @@ enum reg_class CLOBBERED_REGS, /* call-clobbered integer registers */ Q_REGS, /* %eax %ebx %ecx %edx */ NON_Q_REGS, /* %esi %edi %ebp %esp */ + TLS_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 @@ -1407,6 +1408,7 @@ enum reg_class "AD_REGS", \ "CLOBBERED_REGS", \ "Q_REGS", "NON_Q_REGS", \ + "TLS_REGS", \ "INDEX_REGS", \ "LEGACY_REGS", \ "GENERAL_REGS", \ @@ -1447,6 +1449,7 @@ enum reg_class { 0x07, 0x0, 0x0 }, /* CLOBBERED_REGS */ \ { 0x0f, 0x0, 0x0 }, /* Q_REGS */ \ { 0x1100f0, 0x1fe0, 0x0 }, /* NON_Q_REGS */ \ + { 0x7e, 0x1fe0, 0x0 }, /* TLS_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 85dda3f..bb70102 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -13565,7 +13565,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)] @@ -13575,15 +13575,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")]) @@ -13616,11 +13622,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") @@ -13664,7 +13675,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)) @@ -13682,7 +13693,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")]) @@ -13713,7 +13726,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 94ba9bd..09706b9 100755 --- a/gcc/configure +++ b/gcc/configure @@ -26010,6 +26010,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 b0f38d1..99e8b0c 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -4229,6 +4229,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 0000000..5d5b531 --- /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 0000000..9a6c275 --- /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 0000000..6b0e780 --- /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 0000000..8769830 --- /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 0000000..86cc93e --- /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 0000000..b014d53 --- /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 2b80f6e..de6c072 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -7111,6 +7111,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 {} {