diff options
author | Kyrylo Tkachov <kyrylo.tkachov@arm.com> | 2023-06-13 10:17:24 +0100 |
---|---|---|
committer | Kyrylo Tkachov <kyrylo.tkachov@arm.com> | 2023-06-13 10:17:24 +0100 |
commit | cca8d9e5be2ffffd6ef7276234e1097763b15e19 (patch) | |
tree | c1f9a583d39d711dbd324f41835fbb7434a39fac /gcc/config | |
parent | 4389a2d2d0cc639cbeeb8453dc20bf315316d4e3 (diff) | |
download | gcc-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.h | 4 | ||||
-rw-r--r-- | gcc/config/arm/arm-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/arm/arm.cc | 32 | ||||
-rw-r--r-- | gcc/config/arm/arm.h | 2 | ||||
-rw-r--r-- | gcc/config/arm/arm.md | 4 | ||||
-rw-r--r-- | gcc/config/arm/arm.opt | 11 |
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) |