Message ID | 563B6E62.20900@foss.arm.com |
---|---|
State | New |
Headers | show |
On 05/11/15 14:57, Jiong Wang wrote: > 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.wang@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. Ping ~
On 13/11/15 15:21, Jiong Wang wrote: > > On 05/11/15 14:57, Jiong Wang wrote: >> 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.wang@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. > Ping ~ Ping^2
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.