From cbf5629ef1510dac7c80f9b3edfb590293f5933e Mon Sep 17 00:00:00 2001 From: Jiong Wang Date: Wed, 26 Aug 2015 13:09:35 +0000 Subject: [PATCH] [AArch64][TLSLE][3/3] Implement local executable mode for all memory model 2015-08-26 Marcus Shawcroft Jiong Wang 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_): New define_insn. (tlsle24_): Likewise. (tlsle32_): Likewise. (tlsle48_): 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_1.c: New testcase. * gcc.target/aarch64/tlsle24_1.c: Likewise. * gcc.target/aarch64/tlsle32_1.c: Likewise. From-SVN: r227215 --- gcc/ChangeLog | 19 +++++++ gcc/config/aarch64/aarch64-protos.h | 6 +++ gcc/config/aarch64/aarch64.c | 53 ++++++++++++++++-- gcc/config/aarch64/aarch64.md | 56 +++++++++++++------- gcc/testsuite/ChangeLog | 9 ++++ gcc/testsuite/gcc.target/aarch64/tlsle12_1.c | 8 +++ gcc/testsuite/gcc.target/aarch64/tlsle24_1.c | 9 ++++ gcc/testsuite/gcc.target/aarch64/tlsle32_1.c | 10 ++++ gcc/testsuite/gcc.target/aarch64/tlsle_1.x | 14 +++++ gcc/testsuite/lib/target-supports.exp | 17 ++++++ 10 files changed, 179 insertions(+), 22 deletions(-) create mode 100644 gcc/testsuite/gcc.target/aarch64/tlsle12_1.c create mode 100644 gcc/testsuite/gcc.target/aarch64/tlsle24_1.c create mode 100644 gcc/testsuite/gcc.target/aarch64/tlsle32_1.c create mode 100644 gcc/testsuite/gcc.target/aarch64/tlsle_1.x diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 04f52ebcbc0..57458876ce1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2015-08-26 Marcus Shawcroft + Jiong Wang + + * 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_): New define_insn. + (tlsle24_): Likewise. + (tlsle32_): Likewise. + (tlsle48_): Likewise. + * doc/sourcebuild.texi (AArch64-specific attributes): Document + "aarch64_tlsle32". + 2015-08-26 Matthew Wahab * config/arm/arm-protos.h (FL_NONE): New. diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index 55f287e2335..59c364dc72e 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 b473e4af7d7..626589859e7 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -1114,14 +1114,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; } @@ -1676,7 +1705,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; @@ -4579,6 +4611,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; @@ -8695,7 +8731,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 f8c44683752..deac21150b5 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_" + [(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%0, %1, #%L2"; + [(set_attr "type" "alu_sreg") + (set_attr "length" "4")] +) -(define_insn "tlsle_" +(define_insn "tlsle24_" [(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%0, %1, #%G2, lsl #12\;add\\t%0, %0, #%L2" - [(set_attr "type" "alu_sreg") + [(set_attr "type" "multiple") (set_attr "length" "8")] ) +(define_insn "tlsle32_" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(match_operand 1 "aarch64_tls_le_symref" "S")] + UNSPEC_TLSLE32))] + "" + "movz\\t%0, #:tprel_g1:%1\;movk\\t%0, #:tprel_g0_nc:%1" + [(set_attr "type" "multiple") + (set_attr "length" "8")] +) + +(define_insn "tlsle48_" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(match_operand 1 "aarch64_tls_le_symref" "S")] + UNSPEC_TLSLE48))] + "" + "movz\\t%0, #:tprel_g2:%1\;movk\\t%0, #:tprel_g1_nc:%1\;movk\\t%0, #:tprel_g0_nc:%1" + [(set_attr "type" "multiple") + (set_attr "length" "12")] +) + (define_insn "tlsdesc_small_" [(set (reg:PTR R0_REGNUM) (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")] diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ac549889d7e..7e3828fb05d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2015-08-26 Jiong Wang + + * 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_1.c: New testcase. + * gcc.target/aarch64/tlsle24_1.c: Likewise. + * gcc.target/aarch64/tlsle32_1.c: Likewise. + 2015-08-26 Francois-Xavier Coudert PR fortran/29600 diff --git a/gcc/testsuite/gcc.target/aarch64/tlsle12_1.c b/gcc/testsuite/gcc.target/aarch64/tlsle12_1.c new file mode 100644 index 00000000000..846aa9897d9 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/tlsle12_1.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_1.c b/gcc/testsuite/gcc.target/aarch64/tlsle24_1.c new file mode 100644 index 00000000000..e8b14aea36e --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/tlsle24_1.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_1.c b/gcc/testsuite/gcc.target/aarch64/tlsle32_1.c new file mode 100644 index 00000000000..edc06ba0281 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/tlsle32_1.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 00000000000..d92281b6de2 --- /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 1a0ad787ac0..728d02026b5 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -977,6 +977,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. -- 2.30.2