This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[AArch64] [TLSIE][2/2] Implement TLS IE for tiny model
- From: Jiong Wang <jiong dot wang at arm dot com>
- To: gcc-patches <gcc-patches at gnu dot org>
- Date: Fri, 19 Jun 2015 10:15:38 +0100
- Subject: [AArch64] [TLSIE][2/2] Implement TLS IE for tiny model
- Authentication-results: sourceware.org; auth=none
Currently, TLS IE is supported on small model only. This patch implement
TLS Initial-exec model support for AArch64 tiny memory model.
Under tiny model, we only allow 1M loadable segment size, one single ldr
instruction is enough for addressing the got entry for TLS IE directly.
The code sequence is:
A: mrs tp, tpidr_el0
B0: ldr t0, :gottprel:x1 R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 x1
B1: add t0, t0, tp
B0 and B1 should not be scheduled, as the pattern will be recognized
later for linker IE model to LE model optimization.
2015-06-19 Marcus Shawcroft <marcus.shawcroft@arm.com>
Jiong Wang <jiong.wang@arm.com>
gcc/
* config/aarch64/aarch64.md (UNSPEC_GOTTINYTLS): New UNSPEC.
(tlsie_tiny_<mode>): New define_insn.
(tlsie_tiny_sidi): Ditto.
* config/aarch64/aarch64-protos.h (aarch64_symbol_type): Define
SYMBOL_TINY_TLSIE.
(aarch64_symbol_context): New comment for SYMBOL_TINY_TLSIE.
* config/aarch64/aarch64.c (aarch64_load_symref_appropriately): Support
SYMBOL_TINY_TLSIE.
(aarch64_expand_mov_immediate): Ditto.
(aarch64_print_operand): Ditto.
(arch64_classify_tls_symbol): Ditto.
gcc/testsuite/
* gcc.target/aarch64/tlsie_tiny.c: New testcase.
--
Regards,
Jiong
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 12cc5ee..7b5c86e1 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -64,6 +64,7 @@ enum aarch64_symbol_context
SYMBOL_SMALL_TLSGD
SYMBOL_SMALL_TLSDESC
SYMBOL_SMALL_GOTTPREL
+ SYMBOL_TINY_TLSIE
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.
@@ -100,6 +101,7 @@ enum aarch64_symbol_type
SYMBOL_SMALL_GOTTPREL,
SYMBOL_TINY_ABSOLUTE,
SYMBOL_TINY_GOT,
+ SYMBOL_TINY_TLSIE,
SYMBOL_TLSLE,
SYMBOL_FORCE_TO_MEM
};
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 569f22d..ac73bcd 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -994,6 +994,31 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm,
emit_insn (gen_ldr_got_tiny (dest, imm));
return;
+ case SYMBOL_TINY_TLSIE:
+ {
+ machine_mode mode = GET_MODE (dest);
+ rtx tp = aarch64_load_tp (NULL);
+
+ if (mode == ptr_mode)
+ {
+ if (mode == DImode)
+ emit_insn (gen_tlsie_tiny_di (dest, imm, tp));
+ else
+ {
+ tp = gen_lowpart (mode, tp);
+ emit_insn (gen_tlsie_tiny_si (dest, imm, tp));
+ }
+ }
+ else
+ {
+ gcc_assert (mode == Pmode);
+ emit_insn (gen_tlsie_tiny_sidi (dest, imm, tp));
+ }
+
+ set_unique_reg_note (get_last_insn (), REG_EQUIV, imm);
+ return;
+ }
+
default:
gcc_unreachable ();
}
@@ -1527,6 +1552,7 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
case SYMBOL_SMALL_GOTTPREL:
case SYMBOL_SMALL_GOT:
case SYMBOL_TINY_GOT:
+ case SYMBOL_TINY_TLSIE:
if (offset != const0_rtx)
{
gcc_assert(can_create_pseudo_p ());
@@ -4461,6 +4487,10 @@ aarch64_print_operand (FILE *f, rtx x, char code)
asm_fprintf (asm_out_file, ":got:");
break;
+ case SYMBOL_TINY_TLSIE:
+ asm_fprintf (asm_out_file, ":gottprel:");
+ break;
+
default:
break;
}
@@ -7245,7 +7275,14 @@ aarch64_classify_tls_symbol (rtx x)
return TARGET_TLS_DESC ? SYMBOL_SMALL_TLSDESC : SYMBOL_SMALL_TLSGD;
case TLS_MODEL_INITIAL_EXEC:
- return SYMBOL_SMALL_GOTTPREL;
+ switch (aarch64_cmodel)
+ {
+ case AARCH64_CMODEL_TINY:
+ case AARCH64_CMODEL_TINY_PIC:
+ return SYMBOL_TINY_TLSIE;
+ default:
+ return SYMBOL_SMALL_GOTTPREL;
+ }
case TLS_MODEL_LOCAL_EXEC:
return SYMBOL_TLSLE;
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 8b061ba..be9da5b 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -89,6 +89,7 @@
UNSPEC_GOTSMALLPIC
UNSPEC_GOTSMALLTLS
UNSPEC_GOTTINYPIC
+ UNSPEC_GOTTINYTLS
UNSPEC_LD1
UNSPEC_LD2
UNSPEC_LD2_DUP
@@ -4296,6 +4297,30 @@
(set_attr "length" "8")]
)
+(define_insn "tlsie_tiny_<mode>"
+ [(set (match_operand:PTR 0 "register_operand" "=&r")
+ (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")
+ (match_operand:PTR 2 "register_operand" "r")]
+ UNSPEC_GOTTINYTLS))]
+ ""
+ "ldr\\t%<w>0, %L1\;add\\t%<w>0, %<w>0, %<w>2"
+ [(set_attr "type" "multiple")
+ (set_attr "length" "8")]
+)
+
+(define_insn "tlsie_tiny_sidi"
+ [(set (match_operand:DI 0 "register_operand" "=&r")
+ (zero_extend:DI
+ (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")
+ (match_operand:DI 2 "register_operand" "r")
+ ]
+ UNSPEC_GOTTINYTLS)))]
+ ""
+ "ldr\\t%w0, %L1\;add\\t%<w>0, %<w>0, %<w>2"
+ [(set_attr "type" "multiple")
+ (set_attr "length" "8")]
+)
+
(define_expand "tlsle"
[(set (match_operand 0 "register_operand" "=r")
(unspec [(match_operand 1 "register_operand" "r")
diff --git a/gcc/testsuite/gcc.target/aarch64/tlsie_tiny.c b/gcc/testsuite/gcc.target/aarch64/tlsie_tiny.c
new file mode 100644
index 0000000..8ac01b2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/tlsie_tiny.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftls-model=initial-exec -mcmodel=tiny" } */
+
+#include "tls.c"
+
+/* { dg-final { scan-assembler-times ":gottprel:" 2 } } */