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(
79 arm_architecture = "v4t",
80 arm_architecture = "v5te",
81 arm_architecture = "v6"
82 ),
83 instruction_set(arm::a32)
84 )]
85 pub fn read() -> Self {
86 let r: u32;
87
88 #[cfg(target_arch = "arm")]
89 unsafe {
90 core::arch::asm!("mrs {}, CPSR", out(reg) r, options(nomem, nostack, preserves_flags));
91 }
92 #[cfg(not(target_arch = "arm"))]
93 {
94 r = 0;
95 }
96 Self::new_with_raw_value(r)
97 }
98
99 #[cfg_attr(not(feature = "check-asm"), inline)]
114 #[cfg_attr(
115 any(
116 arm_architecture = "v4t",
117 arm_architecture = "v5te",
118 arm_architecture = "v6"
119 ),
120 instruction_set(arm::a32)
121 )]
122 pub unsafe fn write(_value: Self) {
123 #[cfg(target_arch = "arm")]
125 unsafe {
126 core::arch::asm!("msr CPSR, {}", in(reg) _value.raw_value());
127 }
128 }
129
130 #[inline]
136 pub unsafe fn modify<F>(f: F)
137 where
138 F: FnOnce(&mut Self),
139 {
140 let mut value = Self::read();
141 f(&mut value);
142 unsafe {
143 Self::write(value);
144 }
145 }
146}
147
148impl core::fmt::Debug for Cpsr {
149 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
150 write!(
151 f,
152 "CPSR {{ N={} Z={} C={} V={} Q={} J={} E={} A={} I={} F={} T={} MODE={:?} }}",
153 self.n() as u8,
154 self.z() as u8,
155 self.c() as u8,
156 self.v() as u8,
157 self.q() as u8,
158 self.j() as u8,
159 self.e() as u8,
160 self.a() as u8,
161 self.i() as u8,
162 self.f() as u8,
163 self.t() as u8,
164 self.mode(),
165 )
166 }
167}
168
169#[cfg(feature = "defmt")]
170impl defmt::Format for Cpsr {
171 fn format(&self, f: defmt::Formatter) {
172 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())
173 }
174}