Marcus Shawcroft writes:
+#ifdef HAVE_AS_TINY_TLSGD_RELOCS
+ return SYMBOL_TINY_TLSGD;
+#else
+ return SYMBOL_SMALL_TLSGD;
+#endif
Rather than introduce blocks of conditional compilation it is better
to gate different behaviours with a test on a constant expression. In
this case add something like this:
#if define(HAVE_AS_TINY_TLSGD_RELOCS)
#define USE_TINY_TLSGD 1
#else
#define USE_TINY_TLSGD 0
#endif
up near the definition of TARGET_HAVE_TLS then write the above
fragment without using the preprocessor:
return USE_TINY_TLSGD ? SYMBOL_TINY_TLSGD : SYMBOL_SMALL_TLSGD;
Done.
- aarch64_emit_call_insn (gen_tlsgd_small (result, imm, resolver));
+ if (type == SYMBOL_SMALL_TLSGD)
+ aarch64_emit_call_insn (gen_tlsgd_small (result, imm, resolver));
+ else
+ aarch64_emit_call_insn (gen_tlsgd_tiny (result, imm, resolver));
insns = get_insns ();
end_sequence ();
Add a separate case statment for SYMBOL_TINY_TLSGD rather than reusing
the case statement for SYMBOL_SMALL_TLSGD and then needing to add
another test against symbol type within the body of the case
statement.
Done.
+(define_insn "tlsgd_tiny"
+ [(set (match_operand 0 "register_operand" "")
+ (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
+ (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
UNSPEC_GOTTINYTLS)
+ (clobber (reg:DI LR_REGNUM))
+ ]
+ ""
+ "adr\tx0, %A1;bl\t%2;nop";
+ [(set_attr "type" "multiple")
+ (set_attr "length" "12")])
I don't think the explicit clobber LR_REGNUM is required since your
change last September:
https://gcc.gnu.org/ml/gcc-patches/2014-09/msg02654.html
We don't need this explict clobber LR_REGNUM only if operand 0 happen
be allocated to LR_REGNUM as after my above patch LR_REGNUM is allocable.
However we still need the explict clobber here. Because for all other
cases LR_REGNUM not allocated, gcc data flow analysis can't deduct LR_REGNUM
will still be clobbered implicitly by the call instruction.
Without this "clobber" tag, a direct impact is df_regs_ever_live is calculated
incorrectly for x30, then for the following simple testcase:
__thread int t0 = 0x10;
__thread int t1 = 0x10;
int
main (int argc, char **argv)
{
if (t0 != t1)
return 1;
return 0;
}
if you compile with
"-O2 -ftls-model=global-dynamic -fpic -mtls-dialect=trad t.c -mcmodel=tiny
-fomit-frame-pointer",
wrong code will be generated:
main:
str x19, [sp, -16]! <--- x30 is not saved.
adr x0, :tlsgd:t0
bl __tls_get_addr
nop
Patch updated. tls regression OK
OK for trunk?
2015-11-05 Jiong Wang <jiong.w...@arm.com>
gcc/
* configure.ac: Add check for binutils global dynamic tiny code model
relocation support.
* configure: Regenerate.
* config.in: Regenerate.
* config/aarch64/aarch64.md (tlsgd_tiny): New define_insn.
* config/aarch64/aarch64-protos.h (aarch64_symbol_type): New
enumeration SYMBOL_TINY_TLSGD.
(aarch64_symbol_context): New comment on SYMBOL_TINY_TLSGD.
* config/aarch64/aarch64.c (aarch64_classify_tls_symbol): Support
SYMBOL_TINY_TLSGD.
(aarch64_print_operand): Likewise.
(aarch64_expand_mov_immediate): Likewise.
(aarch64_load_symref_appropriately): Likewise.
gcc/testsuite/
* lib/target-supports.exp (check_effective_target_aarch64_tlsgdtiny):
New effective check.
* gcc.target/aarch64/tlsgd_small_1.c: New testcase.
* gcc.target/aarch64/tlsgd_small_ilp32_1.c: Likewise.
* gcc.target/aarch64/tlsgd_tiny_1.c: Likewise.
* gcc.target/aarch64/tlsgd_tiny_ilp32_1.c: Likewise.
--
Regards,
Jiong
diff --git a/gcc/config.in b/gcc/config.in
index 093478c..617278f 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -618,6 +618,13 @@
#endif
+/* Define if your assembler supports relocs needed by global dynamic for tiny
+ code model. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_AS_TINY_TLSGD_RELOCS
+#endif
+
+
/* Define if your assembler and linker support thread-local storage. */
#ifndef USED_FOR_TARGET
#undef HAVE_AS_TLS
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index baaf1bd..9128baa 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -62,6 +62,7 @@
SYMBOL_SMALL_TLSGD
SYMBOL_SMALL_TLSDESC
SYMBOL_SMALL_TLSIE
+ SYMBOL_TINY_TLSGD
SYMBOL_TINY_TLSIE
SYMBOL_TLSLE12
SYMBOL_TLSLE24
@@ -103,6 +104,7 @@ enum aarch64_symbol_type
SYMBOL_SMALL_TLSIE,
SYMBOL_TINY_ABSOLUTE,
SYMBOL_TINY_GOT,
+ SYMBOL_TINY_TLSGD,
SYMBOL_TINY_TLSIE,
SYMBOL_TLSLE12,
SYMBOL_TLSLE24,
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 7e61b16..8c24740 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -1042,6 +1042,22 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm,
return;
}
+ case SYMBOL_TINY_TLSGD:
+ {
+ rtx_insn *insns;
+ rtx result = gen_rtx_REG (Pmode, R0_REGNUM);
+ rtx resolver = aarch64_tls_get_addr ();
+
+ start_sequence ();
+ aarch64_emit_call_insn (gen_tlsgd_tiny (result, imm, resolver));
+ insns = get_insns ();
+ end_sequence ();
+
+ RTL_CONST_CALL_P (insns) = 1;
+ emit_libcall_block (insns, dest, result, imm);
+ return;
+ }
+
case SYMBOL_SMALL_TLSGD:
{
rtx_insn *insns;
@@ -1573,6 +1589,7 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
case SYMBOL_SMALL_GOT_28K:
case SYMBOL_SMALL_GOT_4G:
case SYMBOL_TINY_GOT:
+ case SYMBOL_TINY_TLSGD:
case SYMBOL_TINY_TLSIE:
if (offset != const0_rtx)
{
@@ -4426,6 +4443,7 @@ aarch64_print_operand (FILE *f, rtx x, char code)
break;
case SYMBOL_SMALL_TLSGD:
+ case SYMBOL_TINY_TLSGD:
asm_fprintf (asm_out_file, ":tlsgd:");
break;
@@ -8695,6 +8713,23 @@ aarch64_classify_tls_symbol (rtx x)
switch (tls_kind)
{
case TLS_MODEL_GLOBAL_DYNAMIC:
+ if (TARGET_TLS_DESC)
+ return SYMBOL_SMALL_TLSDESC;
+
+ /* Traditional model. */
+ switch (aarch64_cmodel)
+ {
+#ifdef HAVE_AS_TINY_TLSGD_RELOCS
+#define USE_TINY_TLSGD 1
+#else
+#define USE_TINY_TLSGD 0
+#endif
+ case AARCH64_CMODEL_TINY:
+ case AARCH64_CMODEL_TINY_PIC:
+ return USE_TINY_TLSGD ? SYMBOL_TINY_TLSGD : SYMBOL_SMALL_TLSGD;
+ default:
+ return SYMBOL_SMALL_TLSGD;
+ }
case TLS_MODEL_LOCAL_DYNAMIC:
return TARGET_TLS_DESC ? SYMBOL_SMALL_TLSDESC : SYMBOL_SMALL_TLSGD;
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index a80213d..b87730d 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -4688,6 +4688,17 @@
[(set_attr "type" "call")
(set_attr "length" "16")])
+(define_insn "tlsgd_tiny"
+ [(set (match_operand 0 "register_operand" "")
+ (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
+ (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTTINYTLS)
+ (clobber (reg:DI LR_REGNUM))
+ ]
+ ""
+ "adr\tx0, %A1;bl\t%2;nop";
+ [(set_attr "type" "multiple")
+ (set_attr "length" "12")])
+
(define_insn "tlsie_small_<mode>"
[(set (match_operand:PTR 0 "register_operand" "=r")
(unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")]
diff --git a/gcc/configure b/gcc/configure
index f6ae9906..6b7772a 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -24388,6 +24388,41 @@ if test $gcc_cv_as_aarch64_picreloc = yes; then
$as_echo "#define HAVE_AS_SMALL_PIC_RELOCS 1" >>confdefs.h
fi
+ # Check if we have binutils support for relocations types needed by TLSGD
+ # for tiny code model.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for global dynamic for tiny relocs" >&5
+$as_echo_n "checking assembler for global dynamic for tiny relocs... " >&6; }
+if test "${gcc_cv_as_aarch64_gdtinyreloc+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcc_cv_as_aarch64_gdtinyreloc=no
+ if test x$gcc_cv_as != x; then
+ $as_echo '
+ .text
+ adr x0, :tlsgd:globalsym
+ ' > conftest.s
+ if { ac_try='$gcc_cv_as $gcc_cv_as_flags -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
+ gcc_cv_as_aarch64_gdtinyreloc=yes
+ 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_aarch64_gdtinyreloc" >&5
+$as_echo "$gcc_cv_as_aarch64_gdtinyreloc" >&6; }
+if test $gcc_cv_as_aarch64_gdtinyreloc = yes; then
+
+$as_echo "#define HAVE_AS_TINY_TLSGD_RELOCS 1" >>confdefs.h
+
+fi
# Enable default workaround for AArch64 Cortex-A53 erratum 835769.
# Check whether --enable-fix-cortex-a53-835769 was given.
if test "${enable_fix_cortex_a53_835769+set}" = set; then :
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 88fb9bf..7ba497c 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -3637,6 +3637,14 @@ case "$target" in
ldr x0, [[x2, #:gotpage_lo15:globalsym]]
],,[AC_DEFINE(HAVE_AS_SMALL_PIC_RELOCS, 1,
[Define if your assembler supports relocs needed by -fpic.])])
+ # Check if we have binutils support for relocations types needed by TLSGD
+ # for tiny code model.
+ gcc_GAS_CHECK_FEATURE([global dynamic for tiny relocs], gcc_cv_as_aarch64_gdtinyreloc,,,
+ [
+ .text
+ adr x0, :tlsgd:globalsym
+ ],,[AC_DEFINE(HAVE_AS_TINY_TLSGD_RELOCS, 1,
+ [Define if your assembler supports relocs needed by global dynamic for tiny code model.])])
# Enable default workaround for AArch64 Cortex-A53 erratum 835769.
AC_ARG_ENABLE(fix-cortex-a53-835769,
[
diff --git a/gcc/testsuite/gcc.target/aarch64/tlsgd_small_1.c b/gcc/testsuite/gcc.target/aarch64/tlsgd_small_1.c
new file mode 100644
index 0000000..6fba678
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/tlsgd_small_1.c
@@ -0,0 +1,9 @@
+/* { dg-do run } */
+/* { dg-require-effective-target tls_native } */
+/* { dg-options "-O2 -ftls-model=global-dynamic -fpic -mtls-dialect=trad --save-temps" } */
+/* { dg-skip-if "TLS GD for small" { aarch64*-*-* } { "-mcmodel=tiny" "-mcmodel=large" } { "" } } */
+
+#include "tls_1.x"
+
+/* { dg-final { scan-assembler-times "adrp\tx\[0-9\]+, :tlsgd:" 2 } } */
+/* { dg-final { scan-assembler-times "bl\t__tls_get_addr" 2 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/tlsgd_small_ilp32_1.c b/gcc/testsuite/gcc.target/aarch64/tlsgd_small_ilp32_1.c
new file mode 100644
index 0000000..1b189a4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/tlsgd_small_ilp32_1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-require-effective-target tls_native } */
+/* { dg-options "-O2 -ftls-model=global-dynamic -fpic -mtls-dialect=trad -mabi=ilp32 --save-temps" } */
+/* { dg-skip-if "TLS GD for small" { aarch64*-*-* } { "-mcmodel=tiny" "-mcmodel=large" } { "" } } */
+
+#include "tls_1.x"
+
+/* { dg-final { scan-assembler-times "adrp\tx\[0-9\]+, :tlsgd:" 2 } } */
+/* { dg-final { scan-assembler-times "bl\t__tls_get_addr" 2 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/tlsgd_tiny_1.c b/gcc/testsuite/gcc.target/aarch64/tlsgd_tiny_1.c
new file mode 100644
index 0000000..1a1053d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/tlsgd_tiny_1.c
@@ -0,0 +1,10 @@
+/* { dg-do run } */
+/* { dg-require-effective-target tls_native } */
+/* { dg-require-effective-target aarch64_tlsgdtiny } */
+/* { dg-options "-O2 -ftls-model=global-dynamic -fpic -mtls-dialect=trad -mcmodel=tiny --save-temps" } */
+/* { dg-skip-if "TLS GD for tiny" { aarch64*-*-* } { "-mcmodel=small" "-mcmodel=large" } { "" } } */
+
+#include "tls_1.x"
+
+/* { dg-final { scan-assembler-times "adr\tx\[0-9\]+, :tlsgd:" 2 } } */
+/* { dg-final { scan-assembler-times "bl\t__tls_get_addr" 2 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/tlsgd_tiny_ilp32_1.c b/gcc/testsuite/gcc.target/aarch64/tlsgd_tiny_ilp32_1.c
new file mode 100644
index 0000000..df00c60
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/tlsgd_tiny_ilp32_1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-require-effective-target tls_native } */
+/* { dg-require-effective-target aarch64_tlsgdtiny } */
+/* { dg-options "-O2 -ftls-model=global-dynamic -fpic -mtls-dialect=trad -mcmodel=tiny -mabi=ilp32 --save-temps" } */
+/* { dg-skip-if "TLS GD for tiny" { aarch64*-*-* } { "-mcmodel=small" "-mcmodel=large" } { "" } } */
+
+#include "tls_1.x"
+
+/* { dg-final { scan-assembler-times "adr\tx\[0-9\]+, :tlsgd:" 2 } } */
+/* { dg-final { scan-assembler-times "bl\t__tls_get_addr" 2 } } */
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 9057a27..1c6f2f7 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -1023,6 +1023,19 @@ proc check_effective_target_aarch64_tlsle32 { } {
}
}
+# On AArch64, instruction sequence for TLS GD on tiny code model will utilize
+# the relocation modifier ":tlsgd:" together with ADR, it's only supported
+# in binutils higher than 2.25.
+
+proc check_effective_target_aarch64_tlsgdtiny { } {
+ if { [istarget aarch64*-*-*] } {
+ return [check_no_compiler_messages aarch64_tlsgdtiny object {
+ void foo (void) { asm ("adr x1,:tlsgd:t1"); }
+ }]
+ } else {
+ return 0
+ }
+}
# Return 1 if -shared is supported, as in no warnings or errors
# emitted, 0 otherwise.