#define ASM_SPEC "\
%{mbig-endian:-EB} \
%{mlittle-endian:-EL} \
+%{menable-sysreg-checking} \
%(asm_cpu_spec)" \
ASM_MABI_SPEC
#endif
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
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;
}
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 is not available on the target architecture.
+
mgeneral-regs-only
Target RejectNegative Mask(GENERAL_REGS_ONLY) Save
Generate code which uses only the general registers.
@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
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 is not available on the target architecture.
+
@opindex mgeneral-regs-only
@item -mgeneral-regs-only
Generate code which uses only the general-purpose registers. This will prevent
--- /dev/null
+/* { 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 } */
--- /dev/null
+/* { 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} } } */
--- /dev/null
+/* { 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" } } */
+}
--- /dev/null
+/* { 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'" } */
+}
}]
}
+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 {