Currently, there is only small model support for TLS Global Dynamic
(Desciptor) on AArch64. While TLS Global Dynamic (Descriptor) is
actually the same for all memory mode.
We always generate below code sequences:
R0 = GOT entry address of tls descriptor for var.
Rx = speialize_func
.tlsdesccall var
blr Rx
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:
ldr xr, :tlsdesc:var
adr x0, :tlsdesc:var
.tlsdesccall var
blr xr
Small:
adrp x0, :tlsdesc:var
ldr xr, [x0, #:tlsdesc_lo12:var]
add x0, x0, #:tlsdesc_lo12:var
.tlsdesccall var
blr xr
Large:
movz x0, #:tlsdesc_off_g1:var
movk x0, #:tlsdesc_off_g0_nc:var
.tlsdescldr var
ldr xr, [gp, x0]
.tlsdescadd var
add x0, gp, x0
.tlsdesccall var
blr xr
This patch generalize TLS Global Dynamic Descriptor code for all memory
model. Another seperate patch will add descriptor support for Tiny model.
OK for trunk?
2015-06-22 Jiong Wang <[email protected]>
gcc/
* config/aarch64/aarch64-protos.h (aarch64_symbol_context): Rename
SYMBOL_SMALL_TLSDESC to SYMBOL_TLSDESC.
(aarch64_symbol_context): Ditto.
* config/aarch64/aarch64.md (tlsdesc_small_<mode>): Renamed into
"tlsdesc_<mode>".
* config/aarch64/aarch64.c (aarch64_load_symref_appropriately): Rename
SYMBOL_SMALL_TLSDESC to SYMBOL_TLSDESC. Rename gen_tlsdesc_small_* to
gen_tlsdesc_*.
(aarch64_expand_mov_immediate): Ditto.
(aarch64_print_operand): Ditto.
(aarch64_classify_tls_symbol): Ditto.
--
Regards,
Jiong
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 7fad48b..576acc0 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -61,9 +61,9 @@ enum aarch64_symbol_context
This corresponds to the small PIC model of the compiler.
- SYMBOL_SMALL_TLSDESC
SYMBOL_SMALL_GOTTPREL
SYMBOL_TINY_TLSIE
+ SYMBOL_TLSDESC
SYMBOL_TLSGD
SYMBOL_TLSLE
Each of of these represents a thread-local symbol, and corresponds to the
@@ -96,11 +96,11 @@ enum aarch64_symbol_type
{
SYMBOL_SMALL_ABSOLUTE,
SYMBOL_SMALL_GOT,
- SYMBOL_SMALL_TLSDESC,
SYMBOL_SMALL_GOTTPREL,
SYMBOL_TINY_ABSOLUTE,
SYMBOL_TINY_GOT,
SYMBOL_TINY_TLSIE,
+ SYMBOL_TLSDESC,
SYMBOL_TLSGD,
SYMBOL_TLSLE,
SYMBOL_FORCE_TO_MEM
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index e724bd4..16c8dba 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -921,7 +921,7 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm,
return;
}
- case SYMBOL_SMALL_TLSDESC:
+ case SYMBOL_TLSDESC:
{
machine_mode mode = GET_MODE (dest);
rtx x0 = gen_rtx_REG (mode, R0_REGNUM);
@@ -932,9 +932,9 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm,
/* In ILP32, the got entry is always of SImode size. Unlike
small GOT, the dest is fixed at reg 0. */
if (TARGET_ILP32)
- emit_insn (gen_tlsdesc_small_si (imm));
+ emit_insn (gen_tlsdesc_si (imm));
else
- emit_insn (gen_tlsdesc_small_di (imm));
+ emit_insn (gen_tlsdesc_di (imm));
tp = aarch64_load_tp (NULL);
if (mode != Pmode)
@@ -1549,11 +1549,11 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
return;
case SYMBOL_TLSGD:
- case SYMBOL_SMALL_TLSDESC:
case SYMBOL_SMALL_GOTTPREL:
case SYMBOL_SMALL_GOT:
case SYMBOL_TINY_GOT:
case SYMBOL_TINY_TLSIE:
+ case SYMBOL_TLSDESC:
if (offset != const0_rtx)
{
gcc_assert(can_create_pseudo_p ());
@@ -4435,7 +4435,7 @@ aarch64_print_operand (FILE *f, rtx x, char code)
asm_fprintf (asm_out_file, ":tlsgd:");
break;
- case SYMBOL_SMALL_TLSDESC:
+ case SYMBOL_TLSDESC:
asm_fprintf (asm_out_file, ":tlsdesc:");
break;
@@ -4468,7 +4468,7 @@ aarch64_print_operand (FILE *f, rtx x, char code)
asm_fprintf (asm_out_file, ":tlsgd_lo12:");
break;
- case SYMBOL_SMALL_TLSDESC:
+ case SYMBOL_TLSDESC:
asm_fprintf (asm_out_file, ":tlsdesc_lo12:");
break;
@@ -7273,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_TLSGD;
+ return TARGET_TLS_DESC ? SYMBOL_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 9f1b26e..f3d9082 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -4378,7 +4378,7 @@
(set_attr "length" "8, 12")]
)
-(define_insn "tlsdesc_small_<mode>"
+(define_insn "tlsdesc_<mode>"
[(set (reg:PTR R0_REGNUM)
(unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
UNSPEC_TLSDESC))