aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>2023-06-13 10:17:24 +0100
committerKyrylo Tkachov <kyrylo.tkachov@arm.com>2023-06-13 10:17:24 +0100
commitcca8d9e5be2ffffd6ef7276234e1097763b15e19 (patch)
treec1f9a583d39d711dbd324f41835fbb7434a39fac /gcc/config
parent4389a2d2d0cc639cbeeb8453dc20bf315316d4e3 (diff)
downloadgcc-cca8d9e5be2ffffd6ef7276234e1097763b15e19.zip
gcc-cca8d9e5be2ffffd6ef7276234e1097763b15e19.tar.gz
gcc-cca8d9e5be2ffffd6ef7276234e1097763b15e19.tar.bz2
arm: Extend -mtp= arguments
After discussing the -mtp= option with Arm's LLVM developers we'd like to extend the functionality of the option somewhat. There are actually 3 system registers that can be accessed for the thread pointer in aarch32: tpidrurw, tpidruro, tpidrprw. They are all read through the CP15 co-processor mechanism. The current -mtp=cp15 option reads the tpidruro register. This patch extends -mtp to allow for the above three explicit tpidr names and keeps -mtp=cp15 as an alias of -mtp=tpidruro for backwards compatibility. Bootstrapped and tested on arm-none-linux-gnueabihf. gcc/ChangeLog: * config/arm/arm-opts.h (enum arm_tp_type): Remove TP_CP15. Add TP_TPIDRURW, TP_TPIDRURO, TP_TPIDRPRW values. * config/arm/arm-protos.h (arm_output_load_tpidr): Declare prototype. * config/arm/arm.cc (arm_option_reconfigure_globals): Replace TP_CP15 with TP_TPIDRURO. (arm_output_load_tpidr): Define. * config/arm/arm.h (TARGET_HARD_TP): Define in terms of TARGET_SOFT_TP. * config/arm/arm.md (load_tp_hard): Call arm_output_load_tpidr to output assembly. (reload_tp_hard): Likewise. * config/arm/arm.opt (tpidrurw, tpidruro, tpidrprw): New values for arm_tp_type. * doc/invoke.texi (Arm Options, mtp): Document new values. gcc/testsuite/ChangeLog: * gcc.target/arm/mtp.c: New test. * gcc.target/arm/mtp_1.c: New test. * gcc.target/arm/mtp_2.c: New test. * gcc.target/arm/mtp_3.c: New test. * gcc.target/arm/mtp_4.c: New test.
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/arm/arm-opts.h4
-rw-r--r--gcc/config/arm/arm-protos.h1
-rw-r--r--gcc/config/arm/arm.cc32
-rw-r--r--gcc/config/arm/arm.h2
-rw-r--r--gcc/config/arm/arm.md4
-rw-r--r--gcc/config/arm/arm.opt11
6 files changed, 48 insertions, 6 deletions
diff --git a/gcc/config/arm/arm-opts.h b/gcc/config/arm/arm-opts.h
index 9964fd2..174dbc5 100644
--- a/gcc/config/arm/arm-opts.h
+++ b/gcc/config/arm/arm-opts.h
@@ -61,7 +61,9 @@ enum float_abi_type
enum arm_tp_type {
TP_AUTO,
TP_SOFT,
- TP_CP15
+ TP_TPIDRURW,
+ TP_TPIDRURO,
+ TP_TPIDRPRW
};
/* Which TLS scheme to use. */
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index 61fcd67..7d73c66 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -182,6 +182,7 @@ extern bool arm_is_long_call_p (tree);
extern int arm_emit_vector_const (FILE *, rtx);
extern void arm_emit_fp16_const (rtx c);
extern const char * arm_output_load_gr (rtx *);
+extern const char * arm_output_load_tpidr (rtx, bool);
extern const char *vfp_output_vstmd (rtx *);
extern void arm_output_multireg_pop (rtx *, bool, rtx, bool, bool);
extern void arm_set_return_address (rtx, rtx);
diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc
index c3e731b..38f0839 100644
--- a/gcc/config/arm/arm.cc
+++ b/gcc/config/arm/arm.cc
@@ -3927,7 +3927,7 @@ arm_option_reconfigure_globals (void)
if (target_thread_pointer == TP_AUTO)
{
if (arm_arch6k && !TARGET_THUMB1)
- target_thread_pointer = TP_CP15;
+ target_thread_pointer = TP_TPIDRURO;
else
target_thread_pointer = TP_SOFT;
}
@@ -34648,4 +34648,34 @@ arm_get_mask_mode (machine_mode mode)
return default_get_mask_mode (mode);
}
+/* Output assembly to read the thread pointer from the appropriate TPIDR
+ register into DEST. If PRED_P also emit the %? that can be used to
+ output the predication code. */
+
+const char *
+arm_output_load_tpidr (rtx dst, bool pred_p)
+{
+ char buf[64];
+ int tpidr_coproc_num = -1;
+ switch (target_thread_pointer)
+ {
+ case TP_TPIDRURW:
+ tpidr_coproc_num = 2;
+ break;
+ case TP_TPIDRURO:
+ tpidr_coproc_num = 3;
+ break;
+ case TP_TPIDRPRW:
+ tpidr_coproc_num = 4;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ snprintf (buf, sizeof (buf),
+ "mrc%s\tp15, 0, %%0, c13, c0, %d\t@ load_tp_hard",
+ pred_p ? "%?" : "", tpidr_coproc_num);
+ output_asm_insn (buf, &dst);
+ return "";
+}
+
#include "gt-arm.h"
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 7d40b8b..4f54530 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -152,8 +152,8 @@ emission of floating point pcs attributes. */
#define TARGET_AAPCS_BASED \
(arm_abi != ARM_ABI_APCS && arm_abi != ARM_ABI_ATPCS)
-#define TARGET_HARD_TP (target_thread_pointer == TP_CP15)
#define TARGET_SOFT_TP (target_thread_pointer == TP_SOFT)
+#define TARGET_HARD_TP !TARGET_SOFT_TP
#define TARGET_GNU2_TLS (target_tls_dialect == TLS_GNU2)
/* Only 16-bit thumb code. */
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 2c7249f..2ac9723 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -12275,7 +12275,7 @@
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(const_int 0)] UNSPEC_TLS))]
"TARGET_HARD_TP"
- "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
+ "* return arm_output_load_tpidr (operands[0], true);"
[(set_attr "predicable" "yes")
(set_attr "type" "mrs")]
)
@@ -12285,7 +12285,7 @@
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec_volatile:SI [(const_int 0)] VUNSPEC_MRC))]
"TARGET_HARD_TP"
- "mrc\\tp15, 0, %0, c13, c0, 3\\t@ reload_tp_hard"
+ "* return arm_output_load_tpidr (operands[0], false);"
[(set_attr "type" "mrs")]
)
diff --git a/gcc/config/arm/arm.opt b/gcc/config/arm/arm.opt
index 3a49b51..88299da 100644
--- a/gcc/config/arm/arm.opt
+++ b/gcc/config/arm/arm.opt
@@ -230,7 +230,16 @@ EnumValue
Enum(arm_tp_type) String(auto) Value(TP_AUTO)
EnumValue
-Enum(arm_tp_type) String(cp15) Value(TP_CP15)
+Enum(arm_tp_type) String(tpidrurw) Value(TP_TPIDRURW)
+
+EnumValue
+Enum(arm_tp_type) String(cp15) Value(TP_TPIDRURO)
+
+EnumValue
+Enum(arm_tp_type) String(tpidruro) Value(TP_TPIDRURO)
+
+EnumValue
+Enum(arm_tp_type) String(tpidrprw) Value(TP_TPIDRPRW)
mtpcs-frame
Target Mask(TPCS_FRAME)