cortex_m/register/
fpscr.rs

1//! Floating-point Status Control Register
2
3/// Floating-point Status Control Register
4#[derive(Clone, Copy, Debug)]
5pub struct Fpscr {
6    bits: u32,
7}
8
9impl Fpscr {
10    /// Creates a `Fspcr` value from raw bits.
11    #[inline]
12    pub fn from_bits(bits: u32) -> Self {
13        Self { bits }
14    }
15
16    /// Returns the contents of the register as raw bits
17    #[inline]
18    pub fn bits(self) -> u32 {
19        self.bits
20    }
21
22    /// Read the Negative condition code flag
23    #[inline]
24    pub fn n(self) -> bool {
25        self.bits & (1 << 31) != 0
26    }
27
28    /// Sets the Negative condition code flag
29    #[inline]
30    pub fn set_n(&mut self, n: bool) {
31        let mask = 1 << 31;
32        match n {
33            true => self.bits |= mask,
34            false => self.bits &= !mask,
35        }
36    }
37
38    /// Read the Zero condition code flag
39    #[inline]
40    pub fn z(self) -> bool {
41        self.bits & (1 << 30) != 0
42    }
43
44    /// Sets the Zero condition code flag
45    #[inline]
46    pub fn set_z(&mut self, z: bool) {
47        let mask = 1 << 30;
48        match z {
49            true => self.bits |= mask,
50            false => self.bits &= !mask,
51        }
52    }
53
54    /// Read the Carry condition code flag
55    #[inline]
56    pub fn c(self) -> bool {
57        self.bits & (1 << 29) != 0
58    }
59
60    /// Sets the Carry condition code flag
61    #[inline]
62    pub fn set_c(&mut self, c: bool) {
63        let mask = 1 << 29;
64        match c {
65            true => self.bits |= mask,
66            false => self.bits &= !mask,
67        }
68    }
69
70    /// Read the Overflow condition code flag
71    #[inline]
72    pub fn v(self) -> bool {
73        self.bits & (1 << 28) != 0
74    }
75
76    /// Sets the Zero condition code flag
77    #[inline]
78    pub fn set_v(&mut self, v: bool) {
79        let mask = 1 << 28;
80        match v {
81            true => self.bits |= mask,
82            false => self.bits &= !mask,
83        }
84    }
85
86    /// Read the Alternative Half Precision bit
87    #[inline]
88    pub fn ahp(self) -> bool {
89        self.bits & (1 << 26) != 0
90    }
91
92    /// Sets the Alternative Half Precision bit
93    #[inline]
94    pub fn set_ahp(&mut self, ahp: bool) {
95        let mask = 1 << 26;
96        match ahp {
97            true => self.bits |= mask,
98            false => self.bits &= !mask,
99        }
100    }
101
102    /// Read the Default NaN mode bit
103    #[inline]
104    pub fn dn(self) -> bool {
105        self.bits & (1 << 25) != 0
106    }
107
108    /// Sets the Default NaN mode bit
109    #[inline]
110    pub fn set_dn(&mut self, dn: bool) {
111        let mask = 1 << 25;
112        match dn {
113            true => self.bits |= mask,
114            false => self.bits &= !mask,
115        }
116    }
117
118    /// Read the Flush to Zero mode bit
119    #[inline]
120    pub fn fz(self) -> bool {
121        self.bits & (1 << 24) != 0
122    }
123
124    /// Sets the Flush to Zero mode bit
125    #[inline]
126    pub fn set_fz(&mut self, fz: bool) {
127        let mask = 1 << 24;
128        match fz {
129            true => self.bits |= mask,
130            false => self.bits &= !mask,
131        }
132    }
133
134    /// Read the Rounding Mode control field
135    #[inline]
136    pub fn rmode(self) -> RMode {
137        match (self.bits & (3 << 22)) >> 22 {
138            0 => RMode::Nearest,
139            1 => RMode::PlusInfinity,
140            2 => RMode::MinusInfinity,
141            _ => RMode::Zero,
142        }
143    }
144
145    /// Sets the Rounding Mode control field
146    #[inline]
147    pub fn set_rmode(&mut self, rmode: RMode) {
148        let mask = 3 << 22;
149        match rmode {
150            RMode::Nearest => self.bits &= !mask,
151            RMode::PlusInfinity => self.bits = (self.bits & !mask) | (1 << 22),
152            RMode::MinusInfinity => self.bits = (self.bits & !mask) | (2 << 22),
153            RMode::Zero => self.bits |= mask,
154        }
155    }
156
157    /// Read the Input Denormal cumulative exception bit
158    #[inline]
159    pub fn idc(self) -> bool {
160        self.bits & (1 << 7) != 0
161    }
162
163    /// Sets the Input Denormal cumulative exception bit
164    #[inline]
165    pub fn set_idc(&mut self, idc: bool) {
166        let mask = 1 << 7;
167        match idc {
168            true => self.bits |= mask,
169            false => self.bits &= !mask,
170        }
171    }
172
173    /// Read the Inexact cumulative exception bit
174    #[inline]
175    pub fn ixc(self) -> bool {
176        self.bits & (1 << 4) != 0
177    }
178
179    /// Sets the Inexact cumulative exception bit
180    #[inline]
181    pub fn set_ixc(&mut self, ixc: bool) {
182        let mask = 1 << 4;
183        match ixc {
184            true => self.bits |= mask,
185            false => self.bits &= !mask,
186        }
187    }
188
189    /// Read the Underflow cumulative exception bit
190    #[inline]
191    pub fn ufc(self) -> bool {
192        self.bits & (1 << 3) != 0
193    }
194
195    /// Sets the Underflow cumulative exception bit
196    #[inline]
197    pub fn set_ufc(&mut self, ufc: bool) {
198        let mask = 1 << 3;
199        match ufc {
200            true => self.bits |= mask,
201            false => self.bits &= !mask,
202        }
203    }
204
205    /// Read the Overflow cumulative exception bit
206    #[inline]
207    pub fn ofc(self) -> bool {
208        self.bits & (1 << 2) != 0
209    }
210
211    /// Sets the Overflow cumulative exception bit
212    #[inline]
213    pub fn set_ofc(&mut self, ofc: bool) {
214        let mask = 1 << 2;
215        match ofc {
216            true => self.bits |= mask,
217            false => self.bits &= !mask,
218        }
219    }
220
221    /// Read the Division by Zero cumulative exception bit
222    #[inline]
223    pub fn dzc(self) -> bool {
224        self.bits & (1 << 1) != 0
225    }
226
227    /// Sets the Division by Zero cumulative exception bit
228    #[inline]
229    pub fn set_dzc(&mut self, dzc: bool) {
230        let mask = 1 << 1;
231        match dzc {
232            true => self.bits |= mask,
233            false => self.bits &= !mask,
234        }
235    }
236
237    /// Read the Invalid Operation cumulative exception bit
238    #[inline]
239    pub fn ioc(self) -> bool {
240        self.bits & (1 << 0) != 0
241    }
242
243    /// Sets the Invalid Operation cumulative exception bit
244    #[inline]
245    pub fn set_ioc(&mut self, ioc: bool) {
246        let mask = 1 << 0;
247        match ioc {
248            true => self.bits |= mask,
249            false => self.bits &= !mask,
250        }
251    }
252}
253
254/// Rounding mode
255#[derive(Clone, Copy, Debug, Eq, PartialEq)]
256pub enum RMode {
257    /// Round to Nearest (RN) mode. This is the reset value.
258    Nearest,
259    /// Round towards Plus Infinity (RP) mode.
260    PlusInfinity,
261    /// Round towards Minus Infinity (RM) mode.
262    MinusInfinity,
263    /// Round towards Zero (RZ) mode.
264    Zero,
265}
266
267impl RMode {
268    /// Is Nearest the current rounding mode?
269    #[inline]
270    pub fn is_nearest(self) -> bool {
271        self == RMode::Nearest
272    }
273
274    /// Is Plus Infinity the current rounding mode?
275    #[inline]
276    pub fn is_plus_infinity(self) -> bool {
277        self == RMode::PlusInfinity
278    }
279
280    /// Is Minus Infinity the current rounding mode?
281    #[inline]
282    pub fn is_minus_infinity(self) -> bool {
283        self == RMode::MinusInfinity
284    }
285
286    /// Is Zero the current rounding mode?
287    #[inline]
288    pub fn is_zero(self) -> bool {
289        self == RMode::Zero
290    }
291}
292
293/// Read the FPSCR register
294#[inline]
295pub fn read() -> Fpscr {
296    let r: u32 = call_asm!(__fpscr_r() -> u32);
297    Fpscr::from_bits(r)
298}
299
300/// Set the value of the FPSCR register
301#[inline]
302pub unsafe fn write(fpscr: Fpscr) {
303    let fpscr = fpscr.bits();
304    call_asm!(__fpscr_w(fpscr: u32));
305}