aarch32_cpu/register/
cpsr.rs1#[derive(Debug, PartialEq, Eq)]
5#[cfg_attr(feature = "defmt", derive(defmt::Format))]
6#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7#[bitbybit::bitenum(u5, exhaustive = false)]
8pub enum ProcessorMode {
9 Usr = 0b10000,
11 Fiq = 0b10001,
13 Irq = 0b10010,
15 Svc = 0b10011,
17 Mon = 0b10110,
19 Abt = 0b10111,
21 Hyp = 0b11010,
23 Und = 0b11011,
25 Sys = 0b11111,
27}
28
29#[bitbybit::bitfield(u32)]
31#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
32pub struct Cpsr {
33 #[bits(31..=31, r)]
35 n: bool,
36 #[bits(30..=30, r)]
38 z: bool,
39 #[bits(29..=29, r)]
41 c: bool,
42 #[bits(28..=28, r)]
44 v: bool,
45 #[bits(27..=27, r)]
47 q: bool,
48 #[bits(24..=24, r)]
50 j: bool,
51 #[bits(9..=9, rw)]
53 e: bool,
54 #[bits(8..=8, rw)]
56 a: bool,
57 #[bits(7..=7, rw)]
59 i: bool,
60 #[bits(6..=6, rw)]
62 f: bool,
63 #[bits(5..=5, rw)]
65 t: bool,
66 #[bits(0..=4, rw)]
68 mode: Option<ProcessorMode>,
69}
70
71impl Cpsr {
72 #[cfg_attr(not(feature = "check-asm"), inline)]
77 #[cfg_attr(
78 any(arm_architecture = "v4t", arm_architecture = "v5te"),
79 instruction_set(arm::a32)
80 )]
81 pub fn read() -> Self {
82 let r: u32;
83 #[cfg(target_arch = "arm")]
85 unsafe {
86 core::arch::asm!("mrs {}, CPSR", out(reg) r, options(nomem, nostack, preserves_flags));
87 }
88 #[cfg(not(target_arch = "arm"))]
89 {
90 r = 0;
91 }
92 Self::new_with_raw_value(r)
93 }
94
95 #[cfg_attr(not(feature = "check-asm"), inline)]
110 #[cfg_attr(
111 any(arm_architecture = "v4t", arm_architecture = "v5te"),
112 instruction_set(arm::a32)
113 )]
114 pub unsafe fn write(_value: Self) {
115 #[cfg(target_arch = "arm")]
117 unsafe {
118 core::arch::asm!("msr CPSR, {}", in(reg) _value.raw_value());
119 }
120 }
121
122 #[inline]
128 pub unsafe fn modify<F>(f: F)
129 where
130 F: FnOnce(&mut Self),
131 {
132 let mut value = Self::read();
133 f(&mut value);
134 unsafe {
135 Self::write(value);
136 }
137 }
138}
139
140impl core::fmt::Debug for Cpsr {
141 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
142 write!(
143 f,
144 "CPSR {{ N={} Z={} C={} V={} Q={} J={} E={} A={} I={} F={} T={} MODE={:?} }}",
145 self.n() as u8,
146 self.z() as u8,
147 self.c() as u8,
148 self.v() as u8,
149 self.q() as u8,
150 self.j() as u8,
151 self.e() as u8,
152 self.a() as u8,
153 self.i() as u8,
154 self.f() as u8,
155 self.t() as u8,
156 self.mode(),
157 )
158 }
159}
160
161#[cfg(feature = "defmt")]
162impl defmt::Format for Cpsr {
163 fn format(&self, f: defmt::Formatter) {
164 defmt::write!(f, "CPSR {{ N={0=31..32} Z={0=30..31} C={0=29..30} V={0=28..29} Q={0=27..28} J={0=24..25} E={0=9..10} A={0=8..9} I={0=7..8} F={0=6..7} T={0=5..6} MODE={0=0..5} }}", self.raw_value())
165 }
166}