]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR target/108779 aarch64: Implement -mtp= option
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>
Fri, 21 Apr 2023 18:00:02 +0000 (19:00 +0100)
committerKyrylo Tkachov <kyrylo.tkachov@arm.com>
Fri, 21 Apr 2023 18:00:02 +0000 (19:00 +0100)
A user has requested that we support the -mtp= option in aarch64 GCC for changing
the TPIDR register to read for TLS accesses. I'm not a big fan of the option name,
but we already support it in the arm port and Clang supports it for AArch64 already,
where it accepts the 'el0', 'el1', 'el2', 'el3' values.

This patch implements the same functionality in GCC.

Bootstrapped and tested on aarch64-none-linux-gnu.
Confirmed with godbolt that the sequences and options are the same as what Clang accepts/generates.

gcc/ChangeLog:

PR target/108779
* config/aarch64/aarch64-opts.h (enum aarch64_tp_reg): Define.
* config/aarch64/aarch64-protos.h (aarch64_output_load_tp):
Define prototype.
* config/aarch64/aarch64.cc (aarch64_tpidr_register): Declare.
(aarch64_override_options_internal): Handle the above.
(aarch64_output_load_tp): New function.
* config/aarch64/aarch64.md (aarch64_load_tp_hard): Call
aarch64_output_load_tp.
* config/aarch64/aarch64.opt (aarch64_tp_reg): Define enum.
(mtp=): New option.
* doc/invoke.texi (AArch64 Options): Document -mtp=.

gcc/testsuite/ChangeLog:

PR target/108779
* gcc.target/aarch64/mtp.c: New test.
* gcc.target/aarch64/mtp_1.c: New test.
* gcc.target/aarch64/mtp_2.c: New test.
* gcc.target/aarch64/mtp_3.c: New test.
* gcc.target/aarch64/mtp_4.c: New test.

gcc/config/aarch64/aarch64-opts.h
gcc/config/aarch64/aarch64-protos.h
gcc/config/aarch64/aarch64.cc
gcc/config/aarch64/aarch64.md
gcc/config/aarch64/aarch64.opt
gcc/doc/invoke.texi
gcc/testsuite/gcc.target/aarch64/mtp.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/mtp_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/mtp_2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/mtp_3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/mtp_4.c [new file with mode: 0644]

index a9f3e2715ca6f76a6610b58794907906df441a57..9d5bf77c868dc6bebb37e04764ad42a58832996b 100644 (file)
@@ -75,6 +75,15 @@ enum aarch64_code_model {
   AARCH64_CMODEL_LARGE
 };
 
+/* The register to use as a thread pointer for TLS accesses.
+   tpidr_el0 by default, but can be changed through the -mtp option.  */
+enum aarch64_tp_reg {
+  AARCH64_TPIDR_EL0 = 0,
+  AARCH64_TPIDR_EL1 = 1,
+  AARCH64_TPIDR_EL2 = 2,
+  AARCH64_TPIDR_EL3 = 3
+};
+
 /* SVE vector register sizes.  */
 enum aarch64_sve_vector_bits_enum {
   SVE_SCALABLE,
index 63339fa47df983fac97ed8b1cf965852a2aa8f42..4904d193647a81cbacb656416947c6011362a560 100644 (file)
@@ -838,6 +838,7 @@ int aarch64_movk_shift (const wide_int_ref &, const wide_int_ref &);
 bool aarch64_is_mov_xn_imm (unsigned HOST_WIDE_INT);
 bool aarch64_use_return_insn_p (void);
 const char *aarch64_output_casesi (rtx *);
+const char *aarch64_output_load_tp (rtx);
 
 unsigned int aarch64_tlsdesc_abi_id ();
 enum aarch64_symbol_type aarch64_classify_symbol (rtx, HOST_WIDE_INT);
index 321580d7f6a1aa58202b8aedddb396ce7f4421c3..d7e895f8d348ecc10e0bc33f6d136bf68a401856 100644 (file)
@@ -281,6 +281,8 @@ private:
 /* The current code model.  */
 enum aarch64_code_model aarch64_cmodel;
 
+enum aarch64_tp_reg aarch64_tpidr_register;
+
 /* The number of 64-bit elements in an SVE vector.  */
 poly_uint16 aarch64_sve_vg;
 
@@ -17889,6 +17891,7 @@ aarch64_override_options_internal (struct gcc_options *opts)
 
   initialize_aarch64_code_model (opts);
   initialize_aarch64_tls_size (opts);
+  aarch64_tpidr_register = opts->x_aarch64_tpidr_reg;
 
   int queue_depth = 0;
   switch (aarch64_tune_params.autoprefetcher_model)
@@ -27415,6 +27418,20 @@ aarch64_indirect_call_asm (rtx addr)
   return "";
 }
 
+/* Emit the assembly instruction to load the thread pointer into DEST.
+   Select between different tpidr_elN registers depending on -mtp= setting.  */
+
+const char *
+aarch64_output_load_tp (rtx dest)
+{
+  const char *tpidrs[] = {"tpidr_el0", "tpidr_el1", "tpidr_el2", "tpidr_el3"};
+  char buffer[64];
+  snprintf (buffer, sizeof (buffer), "mrs\t%%0, %s",
+           tpidrs[aarch64_tpidr_register]);
+  output_asm_insn (buffer, &dest);
+  return "";
+}
+
 /* Target-specific selftests.  */
 
 #if CHECKING_P
index 065cf4bd8b6b90dfa7f6b0cb01fe5ffbd0a43cde..f46d738b8c61d279c19acbdb3efb584d60917a02 100644 (file)
   [(set (match_operand:DI 0 "register_operand" "=r")
        (unspec:DI [(const_int 0)] UNSPEC_TLS))]
   ""
-  "mrs\\t%0, tpidr_el0"
+  "* return aarch64_output_load_tp (operands[0]);"
   [(set_attr "type" "mrs")]
 )
 
index 1d7967db9c0ca867fd0699370ce67b5242235c7f..025e52d40e5c52e122890f657e3cc930f164e9ea 100644 (file)
@@ -97,6 +97,26 @@ mcmodel=
 Target RejectNegative Joined Enum(cmodel) Var(aarch64_cmodel_var) Init(AARCH64_CMODEL_SMALL) Save
 Specify the code model.
 
+Enum
+Name(tp_reg) Type(enum aarch64_tp_reg)
+The register used to access the thread pointer:
+
+EnumValue
+Enum(tp_reg) String(el0) Value(AARCH64_TPIDR_EL0)
+
+EnumValue
+Enum(tp_reg) String(el1) Value(AARCH64_TPIDR_EL1)
+
+EnumValue
+Enum(tp_reg) String(el2) Value(AARCH64_TPIDR_EL2)
+
+EnumValue
+Enum(tp_reg) String(el3) Value(AARCH64_TPIDR_EL3)
+
+mtp=
+Target RejectNegative Joined Enum(tp_reg) Var(aarch64_tpidr_reg) Init(AARCH64_TPIDR_EL0) Save
+Specify the thread pointer register.
+
 mstrict-align
 Target Mask(STRICT_ALIGN) Save
 Don't assume that unaligned accesses are handled by the system.
index 54dcccbc148ccfc4d5a5da5eb4842b3b117aeb6c..e5ee2d536fccb5d39bf1f6e26b2171b3d80b1639 100644 (file)
@@ -20142,6 +20142,16 @@ addresses and sizes of sections.  Programs can be statically linked only.  The
 @option{-mcmodel=large} option is incompatible with @option{-mabi=ilp32},
 @option{-fpic} and @option{-fPIC}.
 
+@item -mtp=@var{name}
+@opindex mtp
+Specify the system register to use as a thread pointer.  The valid values
+are @samp{el0}, @samp{el1}, @samp{el2}, @samp{el3}.  These correspond to
+using the @samp{tpidr_el0}, @samp{tpidr_el1}, @samp{tpidr_el2},
+@samp{tpidr_el3} registers accordingly.  The default setting is @samp{el0}.
+It is recommended to compile all code intended to interoperate with the same
+value of this option to avoid accessing a different thread pointer from the
+wrong exception level.
+
 @opindex mstrict-align
 @opindex mno-strict-align
 @item -mstrict-align
diff --git a/gcc/testsuite/gcc.target/aarch64/mtp.c b/gcc/testsuite/gcc.target/aarch64/mtp.c
new file mode 100644 (file)
index 0000000..d994c37
--- /dev/null
@@ -0,0 +1,8 @@
+__thread int i;
+
+int
+foo (void)
+{
+  return i;
+}
+
diff --git a/gcc/testsuite/gcc.target/aarch64/mtp_1.c b/gcc/testsuite/gcc.target/aarch64/mtp_1.c
new file mode 100644 (file)
index 0000000..5b0f40d
--- /dev/null
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target tls_native } */
+/* { dg-options "-O -mtp=el0" } */
+
+#include "mtp.c"
+
+/* { dg-final { scan-assembler-times {mrs\tx[0-9]+, tpidr_el0} 1 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/mtp_2.c b/gcc/testsuite/gcc.target/aarch64/mtp_2.c
new file mode 100644 (file)
index 0000000..1c76353
--- /dev/null
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target tls_native } */
+/* { dg-options "-O -mtp=el1" } */
+
+#include "mtp.c"
+
+/* { dg-final { scan-assembler-times {mrs\tx[0-9]+, tpidr_el1} 1 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/mtp_3.c b/gcc/testsuite/gcc.target/aarch64/mtp_3.c
new file mode 100644 (file)
index 0000000..1b33f59
--- /dev/null
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target tls_native } */
+/* { dg-options "-O -mtp=el2" } */
+
+#include "mtp.c"
+
+/* { dg-final { scan-assembler-times {mrs\tx[0-9]+, tpidr_el2} 1 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/mtp_4.c b/gcc/testsuite/gcc.target/aarch64/mtp_4.c
new file mode 100644 (file)
index 0000000..c4b7119
--- /dev/null
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target tls_native } */
+/* { dg-options "-O -mtp=el3" } */
+
+#include "mtp.c"
+
+/* { dg-final { scan-assembler-times {mrs\tx[0-9]+, tpidr_el3} 1 } } */