aboutsummaryrefslogtreecommitdiff
path: root/src/registers/macros.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/registers/macros.rs')
-rw-r--r--src/registers/macros.rs76
1 files changed, 76 insertions, 0 deletions
diff --git a/src/registers/macros.rs b/src/registers/macros.rs
new file mode 100644
index 0000000..536670d
--- /dev/null
+++ b/src/registers/macros.rs
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+macro_rules! __read_raw {
+ ($width:ty, $asm_instr:tt, $asm_reg_name:tt, $asm_width:tt) => {
+ /// Reads the raw bits of the CPU register.
+ #[inline]
+ fn get(&self) -> $width {
+ match () {
+ #[cfg(target_arch = "aarch64")]
+ () => {
+ let reg;
+ unsafe {
+ core::arch::asm!(concat!($asm_instr, " {reg:", $asm_width, "}, ", $asm_reg_name), reg = out(reg) reg, options(nomem, nostack));
+ }
+ reg
+ }
+
+ #[cfg(not(target_arch = "aarch64"))]
+ () => unimplemented!(),
+ }
+ }
+ };
+}
+
+macro_rules! __write_raw {
+ ($width:ty, $asm_instr:tt, $asm_reg_name:tt, $asm_width:tt) => {
+ /// Writes raw bits to the CPU register.
+ #[cfg_attr(not(target_arch = "aarch64"), allow(unused_variables))]
+ #[inline]
+ fn set(&self, value: $width) {
+ match () {
+ #[cfg(target_arch = "aarch64")]
+ () => {
+ unsafe {
+ core::arch::asm!(concat!($asm_instr, " ", $asm_reg_name, ", {reg:", $asm_width, "}"), reg = in(reg) value, options(nomem, nostack))
+ }
+ }
+
+ #[cfg(not(target_arch = "aarch64"))]
+ () => unimplemented!(),
+ }
+ }
+ };
+}
+
+/// Raw read from system coprocessor registers.
+macro_rules! sys_coproc_read_raw {
+ ($width:ty, $asm_reg_name:tt, $asm_width:tt) => {
+ __read_raw!($width, "mrs", $asm_reg_name, $asm_width);
+ };
+}
+
+/// Raw write to system coprocessor registers.
+macro_rules! sys_coproc_write_raw {
+ ($width:ty, $asm_reg_name:tt, $asm_width:tt) => {
+ __write_raw!($width, "msr", $asm_reg_name, $asm_width);
+ };
+}
+
+/// Raw read from (ordinary) registers.
+macro_rules! read_raw {
+ ($width:ty, $asm_reg_name:tt, $asm_width:tt) => {
+ __read_raw!($width, "mov", $asm_reg_name, $asm_width);
+ };
+}
+/// Raw write to (ordinary) registers.
+macro_rules! write_raw {
+ ($width:ty, $asm_reg_name:tt, $asm_width:tt) => {
+ __write_raw!($width, "mov", $asm_reg_name, $asm_width);
+ };
+}