Hi All, In the current Binutils we have disabled the feature gating for sysreg by default and we have introduced a new flag "-meanble-sysreg-checking" to renable some of this checking.
However in GCC, we have disabled the feature gating of sysreg to read/write intrinsics __arm_[wr]sr* and we have not added any mechanism to check the feature gating if needed similar to Binutils. This patch adds the support for the flag "-meanble-sysreg-checking" which renables some of the feature checking of sysreg to read/write intrinsics __arm_[wr]sr* similar to Binutils. Regression tested on aarch64-none-elf and found no regressions. Ok for trunk? Regards, Srinath. 2025-09-12 Srinath Parvathaneni <[email protected]> gcc/ChangeLog: * config/aarch64/aarch64.cc (aarch64_valid_sysreg_name_p): Add feature check. (aarch64_retrieve_sysreg): Likewise. * config/aarch64/aarch64.opt (menable-sysreg-checking): Define new flag. * doc/invoke.texi (menable-sysreg-checking): Document new flag. gcc/testsuite/ChangeLog: * gcc.target/aarch64/acle/rwsr-gated-1.c: New test. * gcc.target/aarch64/acle/rwsr-gated-2.c: Likewise. --- gcc/config/aarch64/aarch64.cc | 5 +++++ gcc/config/aarch64/aarch64.opt | 5 +++++ gcc/doc/invoke.texi | 6 ++++++ .../gcc.target/aarch64/acle/rwsr-gated-1.c | 13 +++++++++++++ .../gcc.target/aarch64/acle/rwsr-gated-2.c | 14 ++++++++++++++ 5 files changed, 43 insertions(+) create mode 100644 gcc/testsuite/gcc.target/aarch64/acle/rwsr-gated-1.c create mode 100644 gcc/testsuite/gcc.target/aarch64/acle/rwsr-gated-2.c diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index ef9c16598c0..5eb7e4dc17c 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -31702,6 +31702,8 @@ aarch64_valid_sysreg_name_p (const char *regname) const sysreg_t *sysreg = aarch64_lookup_sysreg_map (regname); if (sysreg == NULL) return aarch64_is_implem_def_reg (regname); + if (aarch64_enable_sysreg_guarding && sysreg->arch_reqs) + return bool (aarch64_isa_flags & sysreg->arch_reqs); return true; } @@ -31725,6 +31727,9 @@ aarch64_retrieve_sysreg (const char *regname, bool write_p, bool is128op) if ((write_p && (sysreg->properties & F_REG_READ)) || (!write_p && (sysreg->properties & F_REG_WRITE))) return NULL; + if (aarch64_enable_sysreg_guarding + && ((~aarch64_isa_flags & sysreg->arch_reqs) != 0)) + return NULL; return sysreg->encoding; } diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt index 9ca753e6a88..5df5a159459 100644 --- a/gcc/config/aarch64/aarch64.opt +++ b/gcc/config/aarch64/aarch64.opt @@ -82,6 +82,11 @@ mbig-endian Target RejectNegative Mask(BIG_END) Assume target CPU is configured as big endian. +menable-sysreg-checking +Target RejectNegative Var(aarch64_enable_sysreg_guarding) Init(0) +Generates an error message if an attempt is made to access a system register +which will not execute on the target architecture. + mgeneral-regs-only Target RejectNegative Mask(GENERAL_REGS_ONLY) Save Generate code which uses only the general registers. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index d0c13d4a24e..f2a4929f793 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -823,6 +823,7 @@ Objective-C and Objective-C++ Dialects}. @emph{AArch64 Options} (@ref{AArch64 Options}) @gccoptlist{-mabi=@var{name} -mbig-endian -mlittle-endian +-menable-sysreg-checking -mgeneral-regs-only -mcmodel=tiny -mcmodel=small -mcmodel=large -mstrict-align -mno-strict-align @@ -22091,6 +22092,11 @@ The @samp{ilp32} model is deprecated. Generate big-endian code. This is the default when GCC is configured for an @samp{aarch64_be-*-*} target. +@opindex menable-sysreg-checking +@item -menable-sysreg-checking +Generates an error message if an attempt is made to access a system register +which will not execute on the target architecture. + @opindex mgeneral-regs-only @item -mgeneral-regs-only Generate code which uses only the general-purpose registers. This will prevent diff --git a/gcc/testsuite/gcc.target/aarch64/acle/rwsr-gated-1.c b/gcc/testsuite/gcc.target/aarch64/acle/rwsr-gated-1.c new file mode 100644 index 00000000000..b9fb39cf0c6 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/acle/rwsr-gated-1.c @@ -0,0 +1,13 @@ +/* Ensure that system register are properly gated on the feature flags, when the + guarding is enabled through "-menable-sysreg-checking" command line flag. */ +/* { dg-do compile } */ +/* { dg-options "-menable-sysreg-checking -march=armv8-a+sve2+sme" } */ + +#include <arm_acle.h> + +uint64_t +foo (uint64_t a) +{ + __arm_wsr64 ("zcr_el1", a); /* { { dg-final { scan-assembler "msr\ts3_0_c1_c2_0, x0" } } */ + return __arm_rsr64 ("smcr_el1"); /* { { dg-final { scan-assembler "mrs\tx0, s3_0_c1_c2_6" } } */ +} diff --git a/gcc/testsuite/gcc.target/aarch64/acle/rwsr-gated-2.c b/gcc/testsuite/gcc.target/aarch64/acle/rwsr-gated-2.c new file mode 100644 index 00000000000..ef143af3ec8 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/acle/rwsr-gated-2.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-menable-sysreg-checking -march=armv8-a" } */ +/* Ensure the system register are rejected by compiler when guarding is + enabled through "-menable-sysreg-checking" command line flag and proper + feature flags are not passed. */ + +#include <arm_acle.h> + +uint64_t +foo (uint64_t a) +{ + __arm_wsr64 ("zcr_el1", a); /* { dg-error "invalid system register name 'zcr_el1'" } */ + return __arm_rsr64 ("smcr_el1"); /* { dg-error "invalid system register name 'smcr_el1'" } */ +} -- 2.25.1
