Ping !! ________________________________ From: Srinath Parvathaneni <[email protected]> Sent: 06 October 2025 10:12 To: [email protected] <[email protected]> Cc: Alice Carlotti <[email protected]>; Alex Coplan <[email protected]>; [email protected] <[email protected]>; Andre Simoes Dias Vieira <[email protected]>; [email protected] <[email protected]> Subject: Re: [PATCH v6][GCC] aarch64: Add support for menable-sysreg-checking flag.
Ping!! ________________________________ From: Srinath Parvathaneni <[email protected]> Sent: 25 September 2025 15:19 To: [email protected] <[email protected]> Cc: Alice Carlotti <[email protected]>; Alex Coplan <[email protected]>; [email protected] <[email protected]>; Andre Simoes Dias Vieira <[email protected]>; [email protected] <[email protected]>; Srinath Parvathaneni <[email protected]> Subject: [PATCH v6][GCC] aarch64: Add support for menable-sysreg-checking flag. v5 -> v6 changes: * Fix the wrong conditional check in aarch64_valid_sysreg_name_p. --------------- 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? Regards, Srinath. 2025-09-25 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 | 7 ++++- 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(+), 1 deletion(-) 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 9ccee4b8f3f..6759cc09c8a 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -31641,7 +31641,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); - return true; + + return (!aarch64_enable_sysreg_guarding + || ((~aarch64_isa_flags & sysreg->arch_reqs) == 0)); } /* Return the generic sysreg specification for a valid system register @@ -31664,6 +31666,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 8aae953e60d..d38f8ef4c29 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 e1bf45aaf4e..8e4195e3e19 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -824,6 +824,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
