Jiong Wang writes:

> 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.

Reworked this patch.

The old approach is to generalize the support for global dynamic
traditional on all memory model into one define_insn as them share the
same code logic listed below:

  param_reg = GOT descriptor address for tls variable.
  call __tls_get_addr
  nop

There is one thing bad that we haven't classified GD symbol in the first
place, we was generating different instruction sequences by doing a
final model check in the instruction pattern.

While in the new approach we classify GD symbol into tiny and small
version in the first place, then implement a seperate instruction
pattern for tiny.  The GD code logic is still generalized, because both
tiny and small share the same symbol handling code in aarch64.c.

NOTE: TLS GD for tiny model will utilize the relocation type
BFD_RELOC_AARCH64_TLSGD_ADR_PREL21 which is not available in binutils
2.25 and before, so feature detection is added to make sure GD for tiny
only enabled when there is binutils support, otherwise fall back to GD
for small.

This patch removes the unncessary define_expand "tlsgd_small". It was
there purely because operands[2] need to be generated from another rtx
gen function while it's better to move that to the call site, thus this
redundant expand pattern can be removed.

2015-08-27  Jiong Wang  <jiong.w...@arm.com>

gcc/
  * config/aarch64/aarch64.md (tlsgd_small): Delete this define_expand.
  (*tlsgd_small): Rename this define_insn to "tlsgd_small";

-- 
Regards,
Jiong

diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index c74bf84..988062c 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -1028,9 +1028,10 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm,
       {
 	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_small (result, imm));
+	aarch64_emit_call_insn (gen_tlsgd_small (result, imm, resolver));
 	insns = get_insns ();
 	end_sequence ();
 
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 80fd6c4..cf787d8 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -4474,17 +4474,7 @@
 ;; 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_small"
   [(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)

Reply via email to