From 653a4407cb221fbbc8bb06c518fd599d18f90111 Mon Sep 17 00:00:00 2001 From: Dániel Buga Date: Wed, 27 May 2020 11:45:05 +0200 Subject: Implement accessing FPSCR --- src/register/fpscr.rs | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/register/mod.rs | 7 +++ 2 files changed, 159 insertions(+) create mode 100644 src/register/fpscr.rs (limited to 'src') diff --git a/src/register/fpscr.rs b/src/register/fpscr.rs new file mode 100644 index 0000000..22f6ce1 --- /dev/null +++ b/src/register/fpscr.rs @@ -0,0 +1,152 @@ +//! Floating-point Status Control Register + +#[allow(clippy::missing_inline_in_public_items)] +#[derive(Clone, Copy, Debug)] +pub struct Fpscr { + bits: u32, +} + +#[derive(Clone, Copy, Debug)] +pub enum RMode { + Nearest, + PlusInfinity, + MinusInfinity, + Zero, +} + +impl Fpscr { + /// Returns the contents of the register as raw bits + #[inline] + pub fn bits(self) -> u32 { + self.bits + } + + //! Read the Negative condition code flag + #[inline] + pub fn n(self) -> bool { + self.bits & (1 << 31) != 0 + } + + //! Read the Zero condition code flag + #[inline] + pub fn z(self) -> bool { + self.bits & (1 << 30) != 0 + } + + //! Read the Carry condition code flag + #[inline] + pub fn c(self) -> bool { + self.bits & (1 << 29) != 0 + } + + //! Read the Overflow condition code flag + #[inline] + pub fn v(self) -> bool { + self.bits & (1 << 28) != 0 + } + + #[inline] + pub fn ahp(self) -> bool { + if self.bits & (1 << 26) != 0 + } + + #[inline] + pub fn dn(self) -> bool { + if self.bits & (1 << 25) != 0 + } + + #[inline] + pub fn fz(self) -> bool { + if self.bits & (1 << 24) != 0 + } + + #[inline] + pub fn rmode(self) -> RMode { + match self.bits & (3 << 22) { + 0 << 22 => RMode::Nearest, + 1 << 22 => RMode::PlusInfinity, + 2 << 22 => RMode::MinusInfinity, + 3 << 22 => RMode::Zero, + } + } + + #[inline] + pub fn idc(self) -> bool { + if self.bits & (1 << 7) != 0 + } + + #[inline] + pub fn ixc(self) -> bool { + if self.bits & (1 << 4) != 0 + } + + #[inline] + pub fn ufc(self) -> bool { + if self.bits & (1 << 3) != 0 + } + + #[inline] + pub fn ofc(self) -> bool { + if self.bits & (1 << 2) != 0 + } + + #[inline] + pub fn dzc(self) -> bool { + if self.bits & (1 << 1) != 0 + } + + #[inline] + pub fn ioc(self) -> bool { + if self.bits & (1 << 0) != 0 + } +} + +/// Read the FPSCR register +pub fn read() -> Fpscr { + match () { + #[cfg(all(cortex_m, feature = "inline-asm"))] + () => { + let r: u32; + unsafe { + llvm_asm!("vmrs $0, fpscr" : "=r"(r) ::: "volatile"); + } + Fpscr { bits: r } + } + + #[cfg(all(cortex_m, not(feature = "inline-asm")))] + () => unsafe { + extern "C" { + fn __get_FPSCR() -> u32; + } + + Fpscr { bits: __get_FPSCR() } + }, + + #[cfg(not(cortex_m))] + () => unimplemented!(), + } +} + +/// Set the value of the FPSCR register +pub unsafe fn write(value: u32) { + match () { + #[cfg(all(cortex_m, feature = "inline-asm"))] + () => { + unsafe { + llvm_asm!("vmrs fpscr, $0" :: "r"(value) :: "volatile"); + } + } + + #[cfg(all(cortex_m, not(feature = "inline-asm")))] + () => unsafe { + extern "C" { + fn __set_FPSCR(value: u32); + } + + __set_FPSCR(value); + }, + + #[cfg(not(cortex_m))] + () => unimplemented!(), + } +} diff --git a/src/register/mod.rs b/src/register/mod.rs index d69c1a5..efbe6ef 100644 --- a/src/register/mod.rs +++ b/src/register/mod.rs @@ -22,6 +22,10 @@ //! - BASEPRI //! - FAULTMASK //! +//! The following registers are only available for devices with an FPU: +//! +//! - FPSCR +//! //! # References //! //! - Cortex-M* Devices Generic User Guide - Section 2.1.3 Core registers @@ -37,6 +41,9 @@ pub mod control; #[cfg(all(not(armv6m), not(armv8m_base)))] pub mod faultmask; +#[cfg(has_fpu)] +pub mod fpscr; + pub mod msp; pub mod primask; -- cgit v1.2.3