On Mon, Sep 22, 2025 at 12:53:12PM +0100, Srinath Parvathaneni 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?
> 
> 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;

This condition is still wrong.  It can be fixed (and simplified) by replacing
these last four lines with:

return (!aarch64_enable_sysreg_guarding
        || (~aarch64_isa_flags & sysreg->arch_reqs == 0));

Alice

>  }
>  
> @@ -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
> 

Reply via email to