diff options
| author | Andrew Turner <andrew@FreeBSD.org> | 2026-06-18 13:34:04 +0000 |
|---|---|---|
| committer | Andrew Turner <andrew@FreeBSD.org> | 2026-06-18 14:56:52 +0000 |
| commit | a9e12d3ec8bde29e97227757bc08cb1a0a93afa9 (patch) | |
| tree | 9ad3155675de788a78af33b76e92778299dc9932 | |
| parent | fd1ee28bd01429aa8c38199d5fc069e8b0b75442 (diff) | |
arm64: Support building sys/sysl instructions
Add support to build system instructions from a macro. These are based
on the existing support for msr/mrs instructions with adjustments for
the different instruction format.
Sponsored by: Arm Ltd
Differential Revision: https://reviews.freebsd.org/D57017
| -rw-r--r-- | sys/arm64/include/_armreg.h | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/sys/arm64/include/_armreg.h b/sys/arm64/include/_armreg.h index 0f5134e5a978..0ade9e6168c9 100644 --- a/sys/arm64/include/_armreg.h +++ b/sys/arm64/include/_armreg.h @@ -52,6 +52,34 @@ #define WRITE_SPECIALREG(reg, _val) \ __asm __volatile("msr " __STRING(reg) ", %0" : : "r"((uint64_t)_val)) + +#define __SYS_ALT_NAME(op1, crn, crm, op2) \ + "#" #op1 ", C" #crn ", C" #crm ", #" #op2 +#define _SYS_ALT_NAME(op1, crn, crm, op2) \ + __SYS_ALT_NAME(op1, crn, crm, op2) +#define SYS_ALT_NAME(insn) \ + _SYS_ALT_NAME(insn##_op1, insn##_CRn, insn##_CRm, insn##_op2) + +#define SYS(insn) do { \ + _Static_assert(insn##_op0 == 1, "Invalid SYS instruction"); \ + __asm __volatile("sys " SYS_ALT_NAME(insn)); \ +} while (0) + +#define SYS_ARG(insn, _val) do { \ + _Static_assert(insn##_op0 == 1, "Invalid SYS instruction"); \ + __asm __volatile("sys " SYS_ALT_NAME(insn) ", %0" \ + : : "r"((uint64_t)_val)); \ +} while (0) + +#define SYSL(insn) \ +({ \ + uint64_t _val; \ + _Static_assert(insn##_op0 == 1, "Invalid SYS instruction"); \ + __asm __volatile("sysl %0, " SYS_ALT_NAME(insn) \ + : "=&r"(_val)); \ + _val; \ +}) + #define UL(x) UINT64_C(x) #endif /* !_MACHINE__ARMREG_H_ */ |
