Currently, there is only small model support for TLS GD on AArch64. While TLS Global Dynamic (Traditional) is actually the same for all memory mode.
For TLSGD, the code logic is always the following: RegA = GOT descriptor address of tls variable. call __tls_get_addr/ nop Instruction sequences for different memory model differs only for how to addressing the GOT descriptor of that TLS variable, and they should always be packed together for later linker relaxation. Tiny == adr a0, :tlsgd:x Small == adrp a0, :tlsgd:x add a0, a0, #:tlsgd_lo12:x Large == movz a0, #:tlsgd_g1:x movk a0, #:tlsgd_g0_nc:x add a0, gp, a0 This patch generalize TLS GD code for all memory model and remove the duplicated define_expand. Another seperate patch will add GD support for Tiny model. OK for trunk? 2015-06-19 Jiong Wang <jiong.w...@arm.com> gcc/ * config/aarch64/aarch64-protos.h (aarch64_symbol_context): Rename SYMBOL_SMALL_TLSGD to SYMBOL_TLSGD. (aarch64_symbol_context): Ditto. * config/aarch64/aarch64.md (tlsgd_small): Deleted. (*tlsgd_small): Renamed into "tlsgd". (UNSPEC_TLSGD): New. * config/aarch64/aarch64.c (aarch64_load_symref_appropriately): Rename SYMBOL_SMALL_TLSGD to SYMBOL_TLSGD. Update parameter for gen_tlsgd. (aarch64_expand_mov_immediate): Ditto. (aarch64_print_operand): Ditto. (aarch64_classify_tls_symbol): Ditto. -- Regards, Jiong
commit c1ed4442a4d81db8a421b74c6a9d65c69e095779 Author: Jiong Wang <jiong.w...@arm.com> Date: Mon May 18 16:48:33 2015 +0100 Generalize GD diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index 7b5c86e1..7fad48b 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -61,10 +61,10 @@ enum aarch64_symbol_context This corresponds to the small PIC model of the compiler. - SYMBOL_SMALL_TLSGD SYMBOL_SMALL_TLSDESC SYMBOL_SMALL_GOTTPREL SYMBOL_TINY_TLSIE + SYMBOL_TLSGD SYMBOL_TLSLE Each of of these represents a thread-local symbol, and corresponds to the thread local storage relocation operator for the symbol being referred to. @@ -96,12 +96,12 @@ enum aarch64_symbol_type { SYMBOL_SMALL_ABSOLUTE, SYMBOL_SMALL_GOT, - SYMBOL_SMALL_TLSGD, SYMBOL_SMALL_TLSDESC, SYMBOL_SMALL_GOTTPREL, SYMBOL_TINY_ABSOLUTE, SYMBOL_TINY_GOT, SYMBOL_TINY_TLSIE, + SYMBOL_TLSGD, SYMBOL_TLSLE, SYMBOL_FORCE_TO_MEM }; diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index be1e83d..e724bd4 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -905,13 +905,14 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm, return; } - case SYMBOL_SMALL_TLSGD: + case SYMBOL_TLSGD: { rtx_insn *insns; rtx result = gen_rtx_REG (Pmode, R0_REGNUM); + rtx func = aarch64_tls_get_addr (); start_sequence (); - aarch64_emit_call_insn (gen_tlsgd_small (result, imm)); + aarch64_emit_call_insn (gen_tlsgd (result, imm, func)); insns = get_insns (); end_sequence (); @@ -1547,7 +1548,7 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm) emit_insn (gen_rtx_SET (dest, mem)); return; - case SYMBOL_SMALL_TLSGD: + case SYMBOL_TLSGD: case SYMBOL_SMALL_TLSDESC: case SYMBOL_SMALL_GOTTPREL: case SYMBOL_SMALL_GOT: @@ -4430,7 +4431,7 @@ aarch64_print_operand (FILE *f, rtx x, char code) asm_fprintf (asm_out_file, ":got:"); break; - case SYMBOL_SMALL_TLSGD: + case SYMBOL_TLSGD: asm_fprintf (asm_out_file, ":tlsgd:"); break; @@ -4463,7 +4464,7 @@ aarch64_print_operand (FILE *f, rtx x, char code) asm_fprintf (asm_out_file, ":lo12:"); break; - case SYMBOL_SMALL_TLSGD: + case SYMBOL_TLSGD: asm_fprintf (asm_out_file, ":tlsgd_lo12:"); break; @@ -7272,7 +7273,7 @@ aarch64_classify_tls_symbol (rtx x) { case TLS_MODEL_GLOBAL_DYNAMIC: case TLS_MODEL_LOCAL_DYNAMIC: - return TARGET_TLS_DESC ? SYMBOL_SMALL_TLSDESC : SYMBOL_SMALL_TLSGD; + return TARGET_TLS_DESC ? SYMBOL_SMALL_TLSDESC : SYMBOL_TLSGD; case TLS_MODEL_INITIAL_EXEC: switch (aarch64_cmodel) diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index be9da5b..4fe54c9 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -117,6 +117,7 @@ UNSPEC_ST4_LANE UNSPEC_TLS UNSPEC_TLSDESC + UNSPEC_TLSGD UNSPEC_TLSLE UNSPEC_USHL_2S UNSPEC_VSTRUCTDUMMY @@ -4255,20 +4256,10 @@ ;; The TLS ABI specifically requires that the compiler does not schedule ;; instructions in the TLS stubs, in order to enable linker relaxation. ;; Therefore we treat the stubs as an atomic sequence. -(define_expand "tlsgd_small" - [(parallel [(set (match_operand 0 "register_operand" "") - (call (mem:DI (match_dup 2)) (const_int 1))) - (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS) - (clobber (reg:DI LR_REGNUM))])] - "" -{ - operands[2] = aarch64_tls_get_addr (); -}) - -(define_insn "*tlsgd_small" +(define_insn "tlsgd" [(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_GOTSMALLTLS) + (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_TLSGD) (clobber (reg:DI LR_REGNUM)) ] ""