From: Jiong Wang <jiong.wang@arm.com>
To: Marcus Shawcroft <marcus.shawcroft@gmail.com>
Cc: gcc-patches <gcc-patches@gnu.org>
Subject: [AArch64][TLSLE][3/3] Implement local executable mode for all memory model
Date: Wed, 19 Aug 2015 14:50:00 -0000 [thread overview]
Message-ID: <n99fv3f5oo1.fsf@arm.com> (raw)
In-Reply-To: <CAFqB+Pwi=xRgu7e-mxmwijS-QyVjzP4dCwow-25Nmwr1qKce6w@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 2959 bytes --]
Marcus Shawcroft writes:
> On 21 May 2015 at 17:49, Jiong Wang <jiong.wang@arm.com> wrote:
>
>> 2015-05-14 Jiong Wang <jiong.wang@arm.com>
>> gcc/
>> * config/aarch64/aarch64.c (aarch64_print_operand): Support tls_size.
>> * config/aarch64/aarch64.md (tlsle): Choose proper instruction
>> sequences.
>> (tlsle_<mode>): New define_insn.
>> (tlsle_movsym_<mode>): Ditto.
>> * config/aarch64/constraints.md (Uta): New constraint.
>> (Utb): Ditto.
>> (Utc): Ditto.
>> (Utd): Ditto.
>>
>> gcc/testsuite/
>> * gcc.target/aarch64/tlsle.c: New test source.
>> * gcc.target/aarch64/tlsle12.c: New testcase.
>> * gcc.target/aarch64/tlsle24.c: New testcase.
>> * gcc.target/aarch64/tlsle32.c: New testcase.
>>
>
>
> case SYMBOL_TLSLE:
> - asm_fprintf (asm_out_file, ":tprel_lo12_nc:");
> + if (aarch64_tls_size <= 12)
> + /* Make sure TLS offset fit into 12bit. */
> + asm_fprintf (asm_out_file, ":tprel_lo12:");
> + else
> + asm_fprintf (asm_out_file, ":tprel_lo12_nc:");
> break;
>
> Use the existing classify_symbol mechanism we use throughout the
> aarch64 backend. Specifically rename SYMBOL_TLSLE as SYMBOL_TLSLE24
> and introduce the 3 missing flavours then use the symbol
> classification to control behaviour such as this modifier selection.
Done.
classified TLS symbol into the following sub-types according to the value of tls size.
SYMBOL_TLSLE12
SYMBOL_TLSLE24
SYMBOL_TLSLE32
SYMBOL_TLSLE48
And On AArch64, instruction sequence for TLS LE under -mtls-size=32 will
utilize the relocation modifier "tprel_g0_nc" together with MOVK, it's
only supported in binutils since 2015-03-04 as PR gas/17843. So I
adjusted tlsle32.c to make it robust by detecting whether there is such
binutils support.
OK for trunk?
2015-08-19 Marcus Shawcroft <marcus.shawcroft@arm.com>
Jiong Wang <jiong.wang@arm.com>
gcc/
* config/aarch64/aarch64.c (initialize_aarch64_tls_size): Set default
tls size for tiny, small, large memory model.
(aarch64_load_symref_appropriately): Support new symbol types.
(aarch64_expand_mov_immediate): Likewise.
(aarch64_print_operand): Likewise.
(aarch64_classify_tls_symbol): Likewise.
* config/aarch64/aarch64-protos.h (aarch64_symbol_context): Likewise.
(aarch64_symbol_type): Likewise.
* config/aarch64/aarch64.md (tlsle): Deleted.
(tlsle12_<mode>): New define_insn.
(tlsle24_<mode>): Likewise.
(tlsle32_<mode>): Likewise.
(tlsle48_<mode>): Likewise.
* doc/sourcebuild.texi (AArch64-specific attributes): Document
"aarch64_tlsle32".
gcc/testsuite/
* lib/target-supports.exp (check_effective_target_aarch64_tlsle32):
New test directive.
* gcc.target/aarch64/tlsle_1.x: New test source.
* gcc.target/aarch64/tlsle12.c: New testcase.
* gcc.target/aarch64/tlsle24.c: New testcase.
* gcc.target/aarch64/tlsle32.c: New testcase.
--
Regards,
Jiong
[-- Attachment #2: 0003-3.patch --]
[-- Type: text/x-diff, Size: 11462 bytes --]
From bd5c221101a9cf241c1f4d117c643e3a5c7e344d Mon Sep 17 00:00:00 2001
From: Jiong Wang <jiong.wang@arm.com>
Date: Wed, 19 Aug 2015 14:15:01 +0100
Subject: [PATCH 3/3] 3
---
gcc/config/aarch64/aarch64-protos.h | 6 +++
gcc/config/aarch64/aarch64.c | 66 ++++++++++++++++++++++++++----
gcc/config/aarch64/aarch64.md | 56 +++++++++++++++++--------
gcc/testsuite/gcc.target/aarch64/tlsle12.c | 8 ++++
gcc/testsuite/gcc.target/aarch64/tlsle24.c | 9 ++++
gcc/testsuite/gcc.target/aarch64/tlsle32.c | 10 +++++
gcc/testsuite/gcc.target/aarch64/tlsle_1.x | 14 +++++++
gcc/testsuite/lib/target-supports.exp | 17 ++++++++
8 files changed, 161 insertions(+), 25 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/aarch64/tlsle12.c
create mode 100644 gcc/testsuite/gcc.target/aarch64/tlsle24.c
create mode 100644 gcc/testsuite/gcc.target/aarch64/tlsle32.c
create mode 100644 gcc/testsuite/gcc.target/aarch64/tlsle_1.x
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index daa45bf..09d83e3 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -74,7 +74,10 @@ enum aarch64_symbol_context
SYMBOL_SMALL_TLSGD
SYMBOL_SMALL_TLSDESC
SYMBOL_SMALL_GOTTPREL
+ SYMBOL_TLSLE12
SYMBOL_TLSLE24
+ SYMBOL_TLSLE32
+ SYMBOL_TLSLE48
Each of these represents a thread-local symbol, and corresponds to the
thread local storage relocation operator for the symbol being referred to.
@@ -111,7 +114,10 @@ enum aarch64_symbol_type
SYMBOL_SMALL_GOTTPREL,
SYMBOL_TINY_ABSOLUTE,
SYMBOL_TINY_GOT,
+ SYMBOL_TLSLE12,
SYMBOL_TLSLE24,
+ SYMBOL_TLSLE32,
+ SYMBOL_TLSLE48,
SYMBOL_FORCE_TO_MEM
};
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 87f8d96..9a1e53b 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -1115,14 +1115,43 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm,
return;
}
+ case SYMBOL_TLSLE12:
case SYMBOL_TLSLE24:
+ case SYMBOL_TLSLE32:
+ case SYMBOL_TLSLE48:
{
+ machine_mode mode = GET_MODE (dest);
rtx tp = aarch64_load_tp (NULL);
- if (GET_MODE (dest) != Pmode)
- tp = gen_lowpart (GET_MODE (dest), tp);
+ if (mode != Pmode)
+ tp = gen_lowpart (mode, tp);
+
+ switch (type)
+ {
+ case SYMBOL_TLSLE12:
+ emit_insn ((mode == DImode ? gen_tlsle12_di : gen_tlsle12_si)
+ (dest, tp, imm));
+ break;
+ case SYMBOL_TLSLE24:
+ emit_insn ((mode == DImode ? gen_tlsle24_di : gen_tlsle24_si)
+ (dest, tp, imm));
+ break;
+ case SYMBOL_TLSLE32:
+ emit_insn ((mode == DImode ? gen_tlsle32_di : gen_tlsle32_si)
+ (dest, imm));
+ emit_insn ((mode == DImode ? gen_adddi3 : gen_addsi3)
+ (dest, dest, tp));
+ break;
+ case SYMBOL_TLSLE48:
+ emit_insn ((mode == DImode ? gen_tlsle48_di : gen_tlsle48_si)
+ (dest, imm));
+ emit_insn ((mode == DImode ? gen_adddi3 : gen_addsi3)
+ (dest, dest, tp));
+ break;
+ default:
+ gcc_unreachable ();
+ }
- emit_insn (gen_tlsle (dest, tp, imm));
set_unique_reg_note (get_last_insn (), REG_EQUIV, imm);
return;
}
@@ -1677,7 +1706,10 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
case SYMBOL_SMALL_ABSOLUTE:
case SYMBOL_TINY_ABSOLUTE:
+ case SYMBOL_TLSLE12:
case SYMBOL_TLSLE24:
+ case SYMBOL_TLSLE32:
+ case SYMBOL_TLSLE48:
aarch64_load_symref_appropriately (dest, imm, sty);
return;
@@ -4593,6 +4625,10 @@ aarch64_print_operand (FILE *f, rtx x, char code)
asm_fprintf (asm_out_file, ":gottprel_lo12:");
break;
+ case SYMBOL_TLSLE12:
+ asm_fprintf (asm_out_file, ":tprel_lo12:");
+ break;
+
case SYMBOL_TLSLE24:
asm_fprintf (asm_out_file, ":tprel_lo12_nc:");
break;
@@ -7514,20 +7550,27 @@ initialize_aarch64_tls_size (struct gcc_options *opts)
switch (opts->x_aarch64_cmodel_var)
{
case AARCH64_CMODEL_TINY:
- /* The maximum TLS size allowed under tiny is 1M. */
- if (aarch64_tls_size > 20)
- aarch64_tls_size = 20;
+ /* Both the default and maximum TLS size allowed under tiny is 1M which
+ needs two instructions to address, so we clamp the size to 24. */
+ if (aarch64_tls_size == 0 || aarch64_tls_size > 24)
+ aarch64_tls_size = 24;
break;
case AARCH64_CMODEL_SMALL:
/* The maximum TLS size allowed under small is 4G. */
if (aarch64_tls_size > 32)
aarch64_tls_size = 32;
+ /* Default tls size be 16M. */
+ else if (aarch64_tls_size == 0)
+ aarch64_tls_size = 24;
break;
case AARCH64_CMODEL_LARGE:
/* The maximum TLS size allowed under large is 16E.
FIXME: 16E should be 64bit, we only support 48bit offset now. */
if (aarch64_tls_size > 48)
aarch64_tls_size = 48;
+ /* Default tls size be 16M. */
+ else if (aarch64_tls_size == 0)
+ aarch64_tls_size = 24;
break;
default:
gcc_unreachable ();
@@ -8717,7 +8760,16 @@ aarch64_classify_tls_symbol (rtx x)
return SYMBOL_SMALL_GOTTPREL;
case TLS_MODEL_LOCAL_EXEC:
- return SYMBOL_TLSLE24;
+ if (aarch64_tls_size == 12)
+ return SYMBOL_TLSLE12;
+ else if (aarch64_tls_size == 24)
+ return SYMBOL_TLSLE24;
+ else if (aarch64_tls_size == 32)
+ return SYMBOL_TLSLE32;
+ else if (aarch64_tls_size == 48)
+ return SYMBOL_TLSLE48;
+ else
+ gcc_unreachable ();
case TLS_MODEL_EMULATED:
case TLS_MODEL_NONE:
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 35255e9..89fff15 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -117,7 +117,10 @@
UNSPEC_ST4_LANE
UNSPEC_TLS
UNSPEC_TLSDESC
- UNSPEC_TLSLE
+ UNSPEC_TLSLE12
+ UNSPEC_TLSLE24
+ UNSPEC_TLSLE32
+ UNSPEC_TLSLE48
UNSPEC_USHL_2S
UNSPEC_VSTRUCTDUMMY
UNSPEC_SP_SET
@@ -4512,31 +4515,48 @@
(set_attr "length" "8")]
)
-(define_expand "tlsle"
- [(set (match_operand 0 "register_operand" "=r")
- (unspec [(match_operand 1 "register_operand" "r")
- (match_operand 2 "aarch64_tls_le_symref" "S")]
- UNSPEC_TLSLE))]
+(define_insn "tlsle12_<mode>"
+ [(set (match_operand:P 0 "register_operand" "=r")
+ (unspec:P [(match_operand:P 1 "register_operand" "r")
+ (match_operand 2 "aarch64_tls_le_symref" "S")]
+ UNSPEC_TLSLE12))]
""
-{
- machine_mode mode = GET_MODE (operands[0]);
- emit_insn ((mode == DImode
- ? gen_tlsle_di
- : gen_tlsle_si) (operands[0], operands[1], operands[2]));
- DONE;
-})
+ "add\\t%<w>0, %<w>1, #%L2";
+ [(set_attr "type" "alu_sreg")
+ (set_attr "length" "4")]
+)
-(define_insn "tlsle_<mode>"
+(define_insn "tlsle24_<mode>"
[(set (match_operand:P 0 "register_operand" "=r")
- (unspec:P [(match_operand:P 1 "register_operand" "r")
- (match_operand 2 "aarch64_tls_le_symref" "S")]
- UNSPEC_TLSLE))]
+ (unspec:P [(match_operand:P 1 "register_operand" "r")
+ (match_operand 2 "aarch64_tls_le_symref" "S")]
+ UNSPEC_TLSLE24))]
""
"add\\t%<w>0, %<w>1, #%G2, lsl #12\;add\\t%<w>0, %<w>0, #%L2"
- [(set_attr "type" "alu_sreg")
+ [(set_attr "type" "multiple")
(set_attr "length" "8")]
)
+(define_insn "tlsle32_<mode>"
+ [(set (match_operand:P 0 "register_operand" "=r")
+ (unspec:P [(match_operand 1 "aarch64_tls_le_symref" "S")]
+ UNSPEC_TLSLE32))]
+ ""
+ "movz\\t%<w>0, #:tprel_g1:%1\;movk\\t%<w>0, #:tprel_g0_nc:%1"
+ [(set_attr "type" "multiple")
+ (set_attr "length" "8")]
+)
+
+(define_insn "tlsle48_<mode>"
+ [(set (match_operand:P 0 "register_operand" "=r")
+ (unspec:P [(match_operand 1 "aarch64_tls_le_symref" "S")]
+ UNSPEC_TLSLE48))]
+ ""
+ "movz\\t%<w>0, #:tprel_g2:%1\;movk\\t%<w>0, #:tprel_g1_nc:%1\;movk\\t%<w>0, #:tprel_g0_nc:%1"
+ [(set_attr "type" "multiple")
+ (set_attr "length" "12")]
+)
+
(define_insn "tlsdesc_small_<mode>"
[(set (reg:PTR R0_REGNUM)
(unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
diff --git a/gcc/testsuite/gcc.target/aarch64/tlsle12.c b/gcc/testsuite/gcc.target/aarch64/tlsle12.c
new file mode 100644
index 0000000..846aa98
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/tlsle12.c
@@ -0,0 +1,8 @@
+/* { dg-do run } */
+/* { dg-require-effective-target tls_native } */
+/* { dg-options "-O2 -fpic -ftls-model=local-exec -mtls-size=12 --save-temps" } */
+
+#include "tlsle_1.x"
+
+/* { dg-final { scan-assembler-times "#:tprel_lo12" 2 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/tlsle24.c b/gcc/testsuite/gcc.target/aarch64/tlsle24.c
new file mode 100644
index 0000000..e8b14ae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/tlsle24.c
@@ -0,0 +1,9 @@
+/* { dg-do run } */
+/* { dg-require-effective-target tls_native } */
+/* { dg-options "-O2 -fpic -ftls-model=local-exec -mtls-size=24 --save-temps" } */
+
+#include "tlsle_1.x"
+
+/* { dg-final { scan-assembler-times "#:tprel_lo12_nc" 2 } } */
+/* { dg-final { scan-assembler-times "#:tprel_hi12" 2 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/tlsle32.c b/gcc/testsuite/gcc.target/aarch64/tlsle32.c
new file mode 100644
index 0000000..edc06ba
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/tlsle32.c
@@ -0,0 +1,10 @@
+/* { dg-do run } */
+/* { dg-require-effective-target tls_native } */
+/* { dg-require-effective-target aarch64_tlsle32 } */
+/* { dg-options "-O2 -fpic -ftls-model=local-exec -mtls-size=32 --save-temps" } */
+
+#include "tlsle_1.x"
+
+/* { dg-final { scan-assembler-times "#:tprel_g1" 2 } } */
+/* { dg-final { scan-assembler-times "#:tprel_g0_nc" 2 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/tlsle_1.x b/gcc/testsuite/gcc.target/aarch64/tlsle_1.x
new file mode 100644
index 0000000..d92281b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/tlsle_1.x
@@ -0,0 +1,14 @@
+void abort (void);
+
+__thread int t0 = 0x10;
+__thread int t1 = 0x10;
+
+int
+main (int argc, char **argv)
+{
+ if (t0 != t1)
+ abort ();
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 1988301..70576b3 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -957,6 +957,23 @@ proc check_effective_target_aarch64_small_fpic { } {
}
}
+# On AArch64, instruction sequence for TLS LE under -mtls-size=32 will utilize
+# the relocation modifier "tprel_g0_nc" together with MOVK, it's only supported
+# in binutils since 2015-03-04 as PR gas/17843.
+#
+# This test directive make sure binutils support all features needed by TLS LE
+# under -mtls-size=32 on AArch64.
+
+proc check_effective_target_aarch64_tlsle32 { } {
+ if { [istarget aarch64*-*-*] } {
+ return [check_no_compiler_messages aarch64_tlsle32 object {
+ void foo (void) { asm ("movk x1,#:tprel_g0_nc:t1"); }
+ }]
+ } else {
+ return 0
+ }
+}
+
# Return 1 if -shared is supported, as in no warnings or errors
# emitted, 0 otherwise.
--
1.9.1
next prev parent reply other threads:[~2015-08-19 14:38 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-21 16:58 [AArch64][TLSLE][N/N] " Jiong Wang
2015-06-26 16:02 ` Marcus Shawcroft
2015-08-19 14:50 ` Jiong Wang [this message]
2015-08-25 9:50 ` [AArch64][TLSLE][3/3] " Marcus Shawcroft
2015-08-27 7:52 ` Christophe Lyon
2015-08-27 9:21 ` Jiong Wang
2015-08-27 9:41 ` Christophe Lyon
2015-08-27 9:53 ` Jiong Wang
2015-08-27 10:34 ` Jiong Wang
2015-08-27 13:23 ` Christophe Lyon
2015-08-27 13:36 ` Jiong Wang
2015-08-27 13:45 ` Christophe Lyon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=n99fv3f5oo1.fsf@arm.com \
--to=jiong.wang@arm.com \
--cc=gcc-patches@gnu.org \
--cc=marcus.shawcroft@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).