Message ID | n99616krrb1.fsf@arm.com |
---|---|
State | New |
Headers | show |
On 19 June 2015 at 10:15, Jiong Wang <jiong.wang@arm.com> wrote: > > 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 > OK /Marcus
Hi Jiong, I was looking at another bug and in the process of auditing our code spotted an issue with this patch from back in June... On Fri, Jun 19, 2015 at 10:15:38AM +0100, Jiong Wang wrote: > 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 > +(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" Here, you have no iterators, so the <w> will never be replaced. Consequently, you are likely to hit an ICE if this pattern is ever used. I presume you intended this to say "ldr\\t%w0, %L1\;add\\t%w0, %w0, %w2" If so, consider that change preapproved. Thanks, James > + [(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 } } */
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 } } */