On Mon, Sep 22, 2025 at 4:54 AM Srinath Parvathaneni <[email protected]> wrote: > > v4 -> v5 changes: > > * Modify check_effective_target_aarch64_sysreg_guarding_ok > to check all the ELF targets have the require assembler > support for -menable-sysreg-checking flag. > * Update the dg-do directive in the tests. > ----------------- > v3 -> v4 changes: > > * Fixed target in check_effective_target_aarch64_sysreg_guarding_ok > ------------------ > v2 -> v3 changes: > > * Replaced the explicit bool cast with a != 0 check when testing > bitmasks. > * Restricted the inlined assembly tests to run only on ELF and > Linux targets. > * Added an effective-target check to ensure the assembler (binutils) > supports the -menable-sysreg-checking flag before running the > inlined assembly tests. > ------------------- > v1 -> v2 changes: > > * Fixed the wrong conditional check. > * Fixed the typos in the testcases. > * Added support for inline assembly checking. > * Added new tests for inline assembly sysreg checking. > ------------------- > > 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. > > For inline assembly, sysreg checks are not performed by CC1 and are > instead delegated to the assembler. By default, the assembler does not > perform these checks either. With this patch, the -menable-sysreg-checking > flag passed to the compiler will also be propagated to the assembler, > enabling sysreg checking for inline assembly. > > Regression tested on aarch64-none-elf and aarch64-linux-gnu and > found no regressions. > > Ok for trunk?
LGTM but allow 24 hours for others to reply. Thanks, Andrew > > Regards, > Srinath. > > 2025-09-22 Srinath Parvathaneni <[email protected]> > > gcc/ChangeLog: > > * config/aarch64/aarch64-elf.h (ASM_SPEC): Update the macro. > * config/aarch64/aarch64.cc (aarch64_valid_sysreg_name_p): > Add feature check condition. > (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/asm-inlined-sysreg-1.c: New test. > * gcc.target/aarch64/acle/asm-inlined-sysreg-2.c: Likewise. > * gcc.target/aarch64/acle/rwsr-gated-1.c: Likewise. > * gcc.target/aarch64/acle/rwsr-gated-2.c: Likewise. > * lib/target-supports.exp > (check_effective_target_aarch64_sysreg_guarding_ok): Check > assembler support of -menable-sysreg-checking flag. > --- > gcc/config/aarch64/aarch64-elf.h | 1 + > gcc/config/aarch64/aarch64.cc | 6 ++++ > gcc/config/aarch64/aarch64.opt | 5 ++++ > gcc/doc/invoke.texi | 6 ++++ > .../aarch64/acle/asm-inlined-sysreg-1.c | 28 ++++++++++++++++++ > .../aarch64/acle/asm-inlined-sysreg-2.c | 29 +++++++++++++++++++ > .../gcc.target/aarch64/acle/rwsr-gated-1.c | 14 +++++++++ > .../gcc.target/aarch64/acle/rwsr-gated-2.c | 14 +++++++++ > gcc/testsuite/lib/target-supports.exp | 10 +++++++ > 9 files changed, 113 insertions(+) > create mode 100644 > gcc/testsuite/gcc.target/aarch64/acle/asm-inlined-sysreg-1.c > create mode 100644 > gcc/testsuite/gcc.target/aarch64/acle/asm-inlined-sysreg-2.c > 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-elf.h > b/gcc/config/aarch64/aarch64-elf.h > index f6ebb723715..57c5a319d7c 100644 > --- a/gcc/config/aarch64/aarch64-elf.h > +++ b/gcc/config/aarch64/aarch64-elf.h > @@ -136,6 +136,7 @@ > #define ASM_SPEC "\ > %{mbig-endian:-EB} \ > %{mlittle-endian:-EL} \ > +%{menable-sysreg-checking} \ > %(asm_cpu_spec)" \ > ASM_MABI_SPEC > #endif > diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc > index ef9c16598c0..badde353fde 100644 > --- a/gcc/config/aarch64/aarch64.cc > +++ b/gcc/config/aarch64/aarch64.cc > @@ -31702,6 +31702,9 @@ 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 > + && ((~aarch64_isa_flags & sysreg->arch_reqs) != 0)) > + return (aarch64_isa_flags & sysreg->arch_reqs) != 0; > return true; > } > > @@ -31725,6 +31728,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 2eab5140bc2..b742e671cb6 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 > @@ -22095,6 +22096,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/asm-inlined-sysreg-1.c > b/gcc/testsuite/gcc.target/aarch64/acle/asm-inlined-sysreg-1.c > new file mode 100644 > index 00000000000..3912c75b315 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/acle/asm-inlined-sysreg-1.c > @@ -0,0 +1,28 @@ > +/* { dg-do assemble { target elf } } */ > +/* { dg-require-effective-target aarch64_sysreg_guarding_ok } */ > +/* { dg-additional-options "-march=armv8-a -menable-sysreg-checking -###" } > */ > +/* Ensure the system registers passed through inline assembly are rejected by > + assembler when guarding is enabled through "-menable-sysreg-checking" > command > + line flag and proper feature flags are not passed. */ > + > +#define INPUT 1 > + > +static inline void > +read_write_using_sysreg (int mode) > +{ > + int b; > + > + /* write to gcspr_el0. */ > + asm volatile ("msr gcspr_el0, %[r]" ::[r] "r" (mode):); > + > + /* Read from gcspr_el0. */ > + asm volatile ("mrs %[r], gcspr_el0" :[r] "=r"(b)::); > +} > + > +int main() > +{ > + read_write_using_sysreg (INPUT); > + return 0; > +} > +/* { dg-prune-output "^(COMPILER_PATH|LIBRARY_PATH|COLLECT_GCC_OPTIONS)=.*" > } */ > +/* { dg-message ".*\/.*as .*-menable-sysreg-checking" "assembler options" > {target aarch64-*-* } 0 } */ > diff --git a/gcc/testsuite/gcc.target/aarch64/acle/asm-inlined-sysreg-2.c > b/gcc/testsuite/gcc.target/aarch64/acle/asm-inlined-sysreg-2.c > new file mode 100644 > index 00000000000..e6c96005705 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/acle/asm-inlined-sysreg-2.c > @@ -0,0 +1,29 @@ > +/* { dg-do assemble { target elf} } */ > +/* { dg-require-effective-target aarch64_sysreg_guarding_ok } */ > +/* { dg-options "-save-temps -O2 -menable-sysreg-checking > -march=armv8-a+gcs" } */ > +/* Ensure that system registers passed through inline assembly are properly > + gated on the feature flags, when the guarding is enabled through > + "-menable-sysreg-checking" command line flag. */ > + > +#define INPUT 1 > + > +static inline void > +read_write_using_sysreg (int mode) > +{ > + int b; > + > + /* write to gcspr_el0. */ > + asm volatile ("msr gcspr_el0, %[r]" ::[r] "r" (mode):); > + > + /* Read from gcspr_el0. */ > + asm volatile ("mrs %[r], gcspr_el0" :[r] "=r"(b)::); > +} > + > +int main() > +{ > + read_write_using_sysreg (INPUT); > + return 0; > +} > + > +/* { { dg-final { scan-assembler {msr\s+gcspr_el0,\s+x0} } } */ > +/* { { dg-final { scan-assembler {mrs\s+x0,\s+gcspr_el0} } } */ > 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..35a54597cd8 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/acle/rwsr-gated-1.c > @@ -0,0 +1,14 @@ > +/* { dg-do compile } */ > +/* { dg-options "-menable-sysreg-checking -march=armv8-a+sve2+sme" } */ > +/* Ensure that system registers are properly gated on the feature flags, when > + the guarding is enabled through "-menable-sysreg-checking" command line > + flag. */ > + > +#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..49e9769f710 > --- /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 registers 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'" } */ > +} > diff --git a/gcc/testsuite/lib/target-supports.exp > b/gcc/testsuite/lib/target-supports.exp > index 1acfb373beb..490bdf3ecda 100644 > --- a/gcc/testsuite/lib/target-supports.exp > +++ b/gcc/testsuite/lib/target-supports.exp > @@ -12584,6 +12584,16 @@ foreach { aarch64_ext } $exts_sve2 { > }] > } > > +proc check_effective_target_aarch64_sysreg_guarding_ok { } { > + if { [istarget aarch64*-*-*] && [check_effective_target_elf] } { > + return [check_no_compiler_messages aarch64_assembler object { > + __asm__ ("msr\ts3_3_c9_c13_4, x0"); > + } "-menable-sysreg-checking"] > + } else { > + return 0 > + } > +} > + > proc check_effective_target_aarch64_asm_sve2p1_ok { } { > if { [istarget aarch64*-*-*] } { > return [check_no_compiler_messages aarch64_sve2p1_assembler object { > -- > 2.25.1 >
