Marcus Shawcroft writes: > On 21 May 2015 at 17:49, Jiong Wang <jiong.w...@arm.com> wrote: > >> 2015-05-14 Jiong Wang <jiong.w...@arm.com> >> gcc/ >> * config/aarch64/aarch64.c (aarch64_print_operand): Support tls_size. >> * config/aarch64/aarch64.md (tlsle): Choose proper instruction >> sequences. >> (tlsle_<mode>): New define_insn. >> (tlsle_movsym_<mode>): Ditto. >> * config/aarch64/constraints.md (Uta): New constraint. >> (Utb): Ditto. >> (Utc): Ditto. >> (Utd): Ditto. >> >> gcc/testsuite/ >> * gcc.target/aarch64/tlsle.c: New test source. >> * gcc.target/aarch64/tlsle12.c: New testcase. >> * gcc.target/aarch64/tlsle24.c: New testcase. >> * gcc.target/aarch64/tlsle32.c: New testcase. >> > > > case SYMBOL_TLSLE: > - asm_fprintf (asm_out_file, ":tprel_lo12_nc:"); > + if (aarch64_tls_size <= 12) > + /* Make sure TLS offset fit into 12bit. */ > + asm_fprintf (asm_out_file, ":tprel_lo12:"); > + else > + asm_fprintf (asm_out_file, ":tprel_lo12_nc:"); > break; > > Use the existing classify_symbol mechanism we use throughout the > aarch64 backend. Specifically rename SYMBOL_TLSLE as SYMBOL_TLSLE24 > and introduce the 3 missing flavours then use the symbol > classification to control behaviour such as this modifier selection.
Done. classified TLS symbol into the following sub-types according to the value of tls size. SYMBOL_TLSLE12 SYMBOL_TLSLE24 SYMBOL_TLSLE32 SYMBOL_TLSLE48 And On AArch64, instruction sequence for TLS LE under -mtls-size=32 will utilize the relocation modifier "tprel_g0_nc" together with MOVK, it's only supported in binutils since 2015-03-04 as PR gas/17843. So I adjusted tlsle32.c to make it robust by detecting whether there is such binutils support. OK for trunk? 2015-08-19 Marcus Shawcroft <marcus.shawcr...@arm.com> Jiong Wang <jiong.w...@arm.com> gcc/ * config/aarch64/aarch64.c (initialize_aarch64_tls_size): Set default tls size for tiny, small, large memory model. (aarch64_load_symref_appropriately): Support new symbol types. (aarch64_expand_mov_immediate): Likewise. (aarch64_print_operand): Likewise. (aarch64_classify_tls_symbol): Likewise. * config/aarch64/aarch64-protos.h (aarch64_symbol_context): Likewise. (aarch64_symbol_type): Likewise. * config/aarch64/aarch64.md (tlsle): Deleted. (tlsle12_<mode>): New define_insn. (tlsle24_<mode>): Likewise. (tlsle32_<mode>): Likewise. (tlsle48_<mode>): Likewise. * doc/sourcebuild.texi (AArch64-specific attributes): Document "aarch64_tlsle32". gcc/testsuite/ * lib/target-supports.exp (check_effective_target_aarch64_tlsle32): New test directive. * gcc.target/aarch64/tlsle_1.x: New test source. * gcc.target/aarch64/tlsle12.c: New testcase. * gcc.target/aarch64/tlsle24.c: New testcase. * gcc.target/aarch64/tlsle32.c: New testcase. -- Regards, Jiong
From bd5c221101a9cf241c1f4d117c643e3a5c7e344d Mon Sep 17 00:00:00 2001 From: Jiong Wang <jiong.w...@arm.com> Date: Wed, 19 Aug 2015 14:15:01 +0100 Subject: [PATCH 3/3] 3 --- gcc/config/aarch64/aarch64-protos.h | 6 +++ gcc/config/aarch64/aarch64.c | 66 ++++++++++++++++++++++++++---- gcc/config/aarch64/aarch64.md | 56 +++++++++++++++++-------- gcc/testsuite/gcc.target/aarch64/tlsle12.c | 8 ++++ gcc/testsuite/gcc.target/aarch64/tlsle24.c | 9 ++++ gcc/testsuite/gcc.target/aarch64/tlsle32.c | 10 +++++ gcc/testsuite/gcc.target/aarch64/tlsle_1.x | 14 +++++++ gcc/testsuite/lib/target-supports.exp | 17 ++++++++ 8 files changed, 161 insertions(+), 25 deletions(-) create mode 100644 gcc/testsuite/gcc.target/aarch64/tlsle12.c create mode 100644 gcc/testsuite/gcc.target/aarch64/tlsle24.c create mode 100644 gcc/testsuite/gcc.target/aarch64/tlsle32.c create mode 100644 gcc/testsuite/gcc.target/aarch64/tlsle_1.x diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index daa45bf..09d83e3 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -74,7 +74,10 @@ enum aarch64_symbol_context SYMBOL_SMALL_TLSGD SYMBOL_SMALL_TLSDESC SYMBOL_SMALL_GOTTPREL + SYMBOL_TLSLE12 SYMBOL_TLSLE24 + SYMBOL_TLSLE32 + SYMBOL_TLSLE48 Each of these represents a thread-local symbol, and corresponds to the thread local storage relocation operator for the symbol being referred to. @@ -111,7 +114,10 @@ enum aarch64_symbol_type SYMBOL_SMALL_GOTTPREL, SYMBOL_TINY_ABSOLUTE, SYMBOL_TINY_GOT, + SYMBOL_TLSLE12, SYMBOL_TLSLE24, + SYMBOL_TLSLE32, + SYMBOL_TLSLE48, SYMBOL_FORCE_TO_MEM }; diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 87f8d96..9a1e53b 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -1115,14 +1115,43 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm, return; } + case SYMBOL_TLSLE12: case SYMBOL_TLSLE24: + case SYMBOL_TLSLE32: + case SYMBOL_TLSLE48: { + machine_mode mode = GET_MODE (dest); rtx tp = aarch64_load_tp (NULL); - if (GET_MODE (dest) != Pmode) - tp = gen_lowpart (GET_MODE (dest), tp); + if (mode != Pmode) + tp = gen_lowpart (mode, tp); + + switch (type) + { + case SYMBOL_TLSLE12: + emit_insn ((mode == DImode ? gen_tlsle12_di : gen_tlsle12_si) + (dest, tp, imm)); + break; + case SYMBOL_TLSLE24: + emit_insn ((mode == DImode ? gen_tlsle24_di : gen_tlsle24_si) + (dest, tp, imm)); + break; + case SYMBOL_TLSLE32: + emit_insn ((mode == DImode ? gen_tlsle32_di : gen_tlsle32_si) + (dest, imm)); + emit_insn ((mode == DImode ? gen_adddi3 : gen_addsi3) + (dest, dest, tp)); + break; + case SYMBOL_TLSLE48: + emit_insn ((mode == DImode ? gen_tlsle48_di : gen_tlsle48_si) + (dest, imm)); + emit_insn ((mode == DImode ? gen_adddi3 : gen_addsi3) + (dest, dest, tp)); + break; + default: + gcc_unreachable (); + } - emit_insn (gen_tlsle (dest, tp, imm)); set_unique_reg_note (get_last_insn (), REG_EQUIV, imm); return; } @@ -1677,7 +1706,10 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm) case SYMBOL_SMALL_ABSOLUTE: case SYMBOL_TINY_ABSOLUTE: + case SYMBOL_TLSLE12: case SYMBOL_TLSLE24: + case SYMBOL_TLSLE32: + case SYMBOL_TLSLE48: aarch64_load_symref_appropriately (dest, imm, sty); return; @@ -4593,6 +4625,10 @@ aarch64_print_operand (FILE *f, rtx x, char code) asm_fprintf (asm_out_file, ":gottprel_lo12:"); break; + case SYMBOL_TLSLE12: + asm_fprintf (asm_out_file, ":tprel_lo12:"); + break; + case SYMBOL_TLSLE24: asm_fprintf (asm_out_file, ":tprel_lo12_nc:"); break; @@ -7514,20 +7550,27 @@ initialize_aarch64_tls_size (struct gcc_options *opts) switch (opts->x_aarch64_cmodel_var) { case AARCH64_CMODEL_TINY: - /* The maximum TLS size allowed under tiny is 1M. */ - if (aarch64_tls_size > 20) - aarch64_tls_size = 20; + /* Both the default and maximum TLS size allowed under tiny is 1M which + needs two instructions to address, so we clamp the size to 24. */ + if (aarch64_tls_size == 0 || aarch64_tls_size > 24) + aarch64_tls_size = 24; break; case AARCH64_CMODEL_SMALL: /* The maximum TLS size allowed under small is 4G. */ if (aarch64_tls_size > 32) aarch64_tls_size = 32; + /* Default tls size be 16M. */ + else if (aarch64_tls_size == 0) + aarch64_tls_size = 24; break; case AARCH64_CMODEL_LARGE: /* The maximum TLS size allowed under large is 16E. FIXME: 16E should be 64bit, we only support 48bit offset now. */ if (aarch64_tls_size > 48) aarch64_tls_size = 48; + /* Default tls size be 16M. */ + else if (aarch64_tls_size == 0) + aarch64_tls_size = 24; break; default: gcc_unreachable (); @@ -8717,7 +8760,16 @@ aarch64_classify_tls_symbol (rtx x) return SYMBOL_SMALL_GOTTPREL; case TLS_MODEL_LOCAL_EXEC: - return SYMBOL_TLSLE24; + if (aarch64_tls_size == 12) + return SYMBOL_TLSLE12; + else if (aarch64_tls_size == 24) + return SYMBOL_TLSLE24; + else if (aarch64_tls_size == 32) + return SYMBOL_TLSLE32; + else if (aarch64_tls_size == 48) + return SYMBOL_TLSLE48; + else + gcc_unreachable (); case TLS_MODEL_EMULATED: case TLS_MODEL_NONE: diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 35255e9..89fff15 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -117,7 +117,10 @@ UNSPEC_ST4_LANE UNSPEC_TLS UNSPEC_TLSDESC - UNSPEC_TLSLE + UNSPEC_TLSLE12 + UNSPEC_TLSLE24 + UNSPEC_TLSLE32 + UNSPEC_TLSLE48 UNSPEC_USHL_2S UNSPEC_VSTRUCTDUMMY UNSPEC_SP_SET @@ -4512,31 +4515,48 @@ (set_attr "length" "8")] ) -(define_expand "tlsle" - [(set (match_operand 0 "register_operand" "=r") - (unspec [(match_operand 1 "register_operand" "r") - (match_operand 2 "aarch64_tls_le_symref" "S")] - UNSPEC_TLSLE))] +(define_insn "tlsle12_<mode>" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(match_operand:P 1 "register_operand" "r") + (match_operand 2 "aarch64_tls_le_symref" "S")] + UNSPEC_TLSLE12))] "" -{ - machine_mode mode = GET_MODE (operands[0]); - emit_insn ((mode == DImode - ? gen_tlsle_di - : gen_tlsle_si) (operands[0], operands[1], operands[2])); - DONE; -}) + "add\\t%<w>0, %<w>1, #%L2"; + [(set_attr "type" "alu_sreg") + (set_attr "length" "4")] +) -(define_insn "tlsle_<mode>" +(define_insn "tlsle24_<mode>" [(set (match_operand:P 0 "register_operand" "=r") - (unspec:P [(match_operand:P 1 "register_operand" "r") - (match_operand 2 "aarch64_tls_le_symref" "S")] - UNSPEC_TLSLE))] + (unspec:P [(match_operand:P 1 "register_operand" "r") + (match_operand 2 "aarch64_tls_le_symref" "S")] + UNSPEC_TLSLE24))] "" "add\\t%<w>0, %<w>1, #%G2, lsl #12\;add\\t%<w>0, %<w>0, #%L2" - [(set_attr "type" "alu_sreg") + [(set_attr "type" "multiple") (set_attr "length" "8")] ) +(define_insn "tlsle32_<mode>" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(match_operand 1 "aarch64_tls_le_symref" "S")] + UNSPEC_TLSLE32))] + "" + "movz\\t%<w>0, #:tprel_g1:%1\;movk\\t%<w>0, #:tprel_g0_nc:%1" + [(set_attr "type" "multiple") + (set_attr "length" "8")] +) + +(define_insn "tlsle48_<mode>" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(match_operand 1 "aarch64_tls_le_symref" "S")] + UNSPEC_TLSLE48))] + "" + "movz\\t%<w>0, #:tprel_g2:%1\;movk\\t%<w>0, #:tprel_g1_nc:%1\;movk\\t%<w>0, #:tprel_g0_nc:%1" + [(set_attr "type" "multiple") + (set_attr "length" "12")] +) + (define_insn "tlsdesc_small_<mode>" [(set (reg:PTR R0_REGNUM) (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")] diff --git a/gcc/testsuite/gcc.target/aarch64/tlsle12.c b/gcc/testsuite/gcc.target/aarch64/tlsle12.c new file mode 100644 index 0000000..846aa98 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/tlsle12.c @@ -0,0 +1,8 @@ +/* { dg-do run } */ +/* { dg-require-effective-target tls_native } */ +/* { dg-options "-O2 -fpic -ftls-model=local-exec -mtls-size=12 --save-temps" } */ + +#include "tlsle_1.x" + +/* { dg-final { scan-assembler-times "#:tprel_lo12" 2 } } */ +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/tlsle24.c b/gcc/testsuite/gcc.target/aarch64/tlsle24.c new file mode 100644 index 0000000..e8b14ae --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/tlsle24.c @@ -0,0 +1,9 @@ +/* { dg-do run } */ +/* { dg-require-effective-target tls_native } */ +/* { dg-options "-O2 -fpic -ftls-model=local-exec -mtls-size=24 --save-temps" } */ + +#include "tlsle_1.x" + +/* { dg-final { scan-assembler-times "#:tprel_lo12_nc" 2 } } */ +/* { dg-final { scan-assembler-times "#:tprel_hi12" 2 } } */ +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/tlsle32.c b/gcc/testsuite/gcc.target/aarch64/tlsle32.c new file mode 100644 index 0000000..edc06ba --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/tlsle32.c @@ -0,0 +1,10 @@ +/* { dg-do run } */ +/* { dg-require-effective-target tls_native } */ +/* { dg-require-effective-target aarch64_tlsle32 } */ +/* { dg-options "-O2 -fpic -ftls-model=local-exec -mtls-size=32 --save-temps" } */ + +#include "tlsle_1.x" + +/* { dg-final { scan-assembler-times "#:tprel_g1" 2 } } */ +/* { dg-final { scan-assembler-times "#:tprel_g0_nc" 2 } } */ +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/tlsle_1.x b/gcc/testsuite/gcc.target/aarch64/tlsle_1.x new file mode 100644 index 0000000..d92281b --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/tlsle_1.x @@ -0,0 +1,14 @@ +void abort (void); + +__thread int t0 = 0x10; +__thread int t1 = 0x10; + +int +main (int argc, char **argv) +{ + if (t0 != t1) + abort (); + + return 0; +} + diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 1988301..70576b3 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -957,6 +957,23 @@ proc check_effective_target_aarch64_small_fpic { } { } } +# On AArch64, instruction sequence for TLS LE under -mtls-size=32 will utilize +# the relocation modifier "tprel_g0_nc" together with MOVK, it's only supported +# in binutils since 2015-03-04 as PR gas/17843. +# +# This test directive make sure binutils support all features needed by TLS LE +# under -mtls-size=32 on AArch64. + +proc check_effective_target_aarch64_tlsle32 { } { + if { [istarget aarch64*-*-*] } { + return [check_no_compiler_messages aarch64_tlsle32 object { + void foo (void) { asm ("movk x1,#:tprel_g0_nc:t1"); } + }] + } else { + return 0 + } +} + # Return 1 if -shared is supported, as in no warnings or errors # emitted, 0 otherwise. -- 1.9.1