public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH][committed] PR target/108779 aarch64: Implement -mtp= option
@ 2023-04-21 17:59 Kyrylo Tkachov
  0 siblings, 0 replies; only message in thread
From: Kyrylo Tkachov @ 2023-04-21 17:59 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1493 bytes --]

Hi all,

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 [1],
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.
Pushing to trunk.

Thanks,
Kyrill


[1] https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-mtp

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.

[-- Attachment #2: mtp.patch --]
[-- Type: application/octet-stream, Size: 7533 bytes --]

diff --git a/gcc/config/aarch64/aarch64-opts.h b/gcc/config/aarch64/aarch64-opts.h
index a9f3e2715ca6f76a6610b58794907906df441a57..9d5bf77c868dc6bebb37e04764ad42a58832996b 100644
--- a/gcc/config/aarch64/aarch64-opts.h
+++ b/gcc/config/aarch64/aarch64-opts.h
@@ -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,
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 63339fa47df983fac97ed8b1cf965852a2aa8f42..4904d193647a81cbacb656416947c6011362a560 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -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);
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index c019c4c290ecf1b92afe633579c5a179f2fedc01..8a87975bbf5907ec0234a5ca75674de1958d883e 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -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;
 
@@ -17951,6 +17953,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)
@@ -27457,6 +27460,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
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 7fcd560ac93ed7a2d75d518cea715560ed9851ce..f1056d549899b7e5d4a7ba94ef1dea8b2ffa571f 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -7061,7 +7061,7 @@ (define_insn "aarch64_load_tp_hard"
   [(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")]
 )
 
diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt
index 1d7967db9c0ca867fd0699370ce67b5242235c7f..025e52d40e5c52e122890f657e3cc930f164e9ea 100644
--- a/gcc/config/aarch64/aarch64.opt
+++ b/gcc/config/aarch64/aarch64.opt
@@ -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.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index a38547f53e53563784fb85a3aa78ae44785955c0..0c61d621038a938ebb987e5cff89da3d5565967e 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -20134,6 +20134,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
index 0000000000000000000000000000000000000000..d994c377fd36fe219558a0c8fe39315421a13188
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/mtp.c
@@ -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
index 0000000000000000000000000000000000000000..5b0f40d7a6292a1824f069c5e50761a2daa75b4b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/mtp_1.c
@@ -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
index 0000000000000000000000000000000000000000..1c7635306d31410ed5088a1b758c84e11372fb35
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/mtp_2.c
@@ -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
index 0000000000000000000000000000000000000000..1b33f59b26aa301d246195949e83c499deddff40
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/mtp_3.c
@@ -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
index 0000000000000000000000000000000000000000..c4b711938872efd92b0ce4c1c2868eec9d36708e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/mtp_4.c
@@ -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 } } */

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-04-21 17:59 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-21 17:59 [PATCH][committed] PR target/108779 aarch64: Implement -mtp= option Kyrylo Tkachov

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).