aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/asm.rs295
-rw-r--r--src/call_asm.rs24
-rw-r--r--src/interrupt.rs38
-rw-r--r--src/lib.rs9
-rw-r--r--src/register/apsr.rs15
-rw-r--r--src/register/basepri.rs64
-rw-r--r--src/register/basepri_max.rs45
-rw-r--r--src/register/control.rs55
-rw-r--r--src/register/faultmask.rs36
-rw-r--r--src/register/fpscr.rs46
-rw-r--r--src/register/lr.rs22
-rw-r--r--src/register/mod.rs6
-rw-r--r--src/register/msp.rs40
-rw-r--r--src/register/msplim.rs40
-rw-r--r--src/register/pc.rs22
-rw-r--r--src/register/primask.rs37
-rw-r--r--src/register/psp.rs40
-rw-r--r--src/register/psplim.rs40
18 files changed, 121 insertions, 753 deletions
diff --git a/src/asm.rs b/src/asm.rs
index 39cd8ef..3165aca 100644
--- a/src/asm.rs
+++ b/src/asm.rs
@@ -1,27 +1,18 @@
//! Miscellaneous assembly instructions
+// When inline assembly is enabled, pull in the assembly routines here. `call_asm!` will invoke
+// these routines.
+#[cfg(feature = "inline-asm")]
+#[path = "../asm/inline.rs"]
+pub(crate) mod inline;
+
/// Puts the processor in Debug state. Debuggers can pick this up as a "breakpoint".
///
/// **NOTE** calling `bkpt` when the processor is not connected to a debugger will cause an
/// exception.
#[inline(always)]
pub fn bkpt() {
- match () {
- #[cfg(all(cortex_m, feature = "inline-asm"))]
- () => unsafe { llvm_asm!("bkpt" :::: "volatile") },
-
- #[cfg(all(cortex_m, not(feature = "inline-asm")))]
- () => unsafe {
- extern "C" {
- fn __bkpt();
- }
-
- __bkpt();
- },
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+ call_asm!(__bkpt());
}
/// Blocks the program for *at least* `n` instruction cycles
@@ -29,151 +20,47 @@ pub fn bkpt() {
/// This is implemented in assembly so its execution time is independent of the optimization
/// level, however it is dependent on the specific architecture and core configuration.
///
-/// NOTE that the delay can take much longer if interrupts are serviced during its execution
+/// NOTE that the delay can take much longer if interrupts are serviced during its execution
/// and the execution time may vary with other factors. This delay is mainly useful for simple
/// timer-less initialization of peripherals if and only if accurate timing is not essential. In
/// any other case please use a more accurate method to produce a delay.
#[inline]
-pub fn delay(_n: u32) {
+pub fn delay(n: u32) {
// NOTE(divide by 4) is easier to compute than `/ 3` because it's just a shift (`>> 2`).
- match () {
- #[cfg(all(cortex_m, feature = "inline-asm"))]
- () => unsafe {
- llvm_asm!("1:
- nop
- subs $0, $$1
- bne.n 1b"
- : "+r"(_n / 4 + 1)
- :
- : "cpsr"
- : "volatile");
- },
-
- #[cfg(all(cortex_m, not(feature = "inline-asm")))]
- () => unsafe {
- extern "C" {
- fn __delay(n: u32);
- }
-
- __delay(_n / 4 + 1);
- },
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+ let real_cyc = n / 4 + 1;
+ call_asm!(__delay(real_cyc: u32));
}
/// A no-operation. Useful to prevent delay loops from being optimized away.
#[inline]
pub fn nop() {
- match () {
- #[cfg(all(cortex_m, feature = "inline-asm"))]
- () => unsafe { llvm_asm!("nop" :::: "volatile") },
-
- #[cfg(all(cortex_m, not(feature = "inline-asm")))]
- () => unsafe {
- extern "C" {
- fn __nop();
- }
-
- __nop()
- },
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+ call_asm!(__nop());
}
-
/// Generate an Undefined Instruction exception.
///
/// Can be used as a stable alternative to `core::intrinsics::abort`.
#[inline]
pub fn udf() -> ! {
- match () {
- #[cfg(all(cortex_m, feature = "inline-asm"))]
- () => unsafe {
- llvm_asm!("udf" :::: "volatile");
- core::hint::unreachable_unchecked();
- },
-
- #[cfg(all(cortex_m, not(feature = "inline-asm")))]
- () => unsafe {
- extern "C" {
- fn __udf();
- }
-
- __udf();
-
- core::hint::unreachable_unchecked();
- },
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+ call_asm!(__udf() -> !)
}
/// Wait For Event
#[inline]
pub fn wfe() {
- match () {
- #[cfg(all(cortex_m, feature = "inline-asm"))]
- () => unsafe { llvm_asm!("wfe" :::: "volatile") },
-
- #[cfg(all(cortex_m, not(feature = "inline-asm")))]
- () => unsafe {
- extern "C" {
- fn __wfe();
- }
-
- __wfe()
- },
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+ call_asm!(__wfe())
}
/// Wait For Interrupt
#[inline]
pub fn wfi() {
- match () {
- #[cfg(all(cortex_m, feature = "inline-asm"))]
- () => unsafe { llvm_asm!("wfi" :::: "volatile") },
-
- #[cfg(all(cortex_m, not(feature = "inline-asm")))]
- () => unsafe {
- extern "C" {
- fn __wfi();
- }
-
- __wfi()
- },
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+ call_asm!(__wfi())
}
/// Send Event
#[inline]
pub fn sev() {
- match () {
- #[cfg(all(cortex_m, feature = "inline-asm"))]
- () => unsafe { llvm_asm!("sev" :::: "volatile") },
-
- #[cfg(all(cortex_m, not(feature = "inline-asm")))]
- () => unsafe {
- extern "C" {
- fn __sev();
- }
-
- __sev()
- },
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+ call_asm!(__sev())
}
/// Instruction Synchronization Barrier
@@ -182,23 +69,7 @@ pub fn sev() {
/// from cache or memory, after the instruction has been completed.
#[inline]
pub fn isb() {
- match () {
- #[cfg(all(cortex_m, feature = "inline-asm"))]
- () => unsafe { llvm_asm!("isb 0xF" ::: "memory" : "volatile") },
-
- #[cfg(all(cortex_m, not(feature = "inline-asm")))]
- () => unsafe {
- extern "C" {
- fn __isb();
- }
-
- __isb()
- // XXX do we need a explicit compiler barrier here?
- },
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+ call_asm!(__isb())
}
/// Data Synchronization Barrier
@@ -210,23 +81,7 @@ pub fn isb() {
/// * all cache and branch predictor maintenance operations before this instruction complete
#[inline]
pub fn dsb() {
- match () {
- #[cfg(all(cortex_m, feature = "inline-asm"))]
- () => unsafe { llvm_asm!("dsb 0xF" ::: "memory" : "volatile") },
-
- #[cfg(all(cortex_m, not(feature = "inline-asm")))]
- () => unsafe {
- extern "C" {
- fn __dsb();
- }
-
- __dsb()
- // XXX do we need a explicit compiler barrier here?
- },
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+ call_asm!(__dsb())
}
/// Data Memory Barrier
@@ -236,23 +91,7 @@ pub fn dsb() {
/// after the `DMB` instruction.
#[inline]
pub fn dmb() {
- match () {
- #[cfg(all(cortex_m, feature = "inline-asm"))]
- () => unsafe { llvm_asm!("dmb 0xF" ::: "memory" : "volatile") },
-
- #[cfg(all(cortex_m, not(feature = "inline-asm")))]
- () => unsafe {
- extern "C" {
- fn __dmb();
- }
-
- __dmb()
- // XXX do we need a explicit compiler barrier here?
- },
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+ call_asm!(__dmb())
}
/// Test Target
@@ -265,28 +104,8 @@ pub fn dmb() {
// The __tt function does not dereference the pointer received.
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub fn tt(addr: *mut u32) -> u32 {
- match () {
- #[cfg(all(cortex_m, feature = "inline-asm"))]
- () => {
- let tt_resp: u32;
- unsafe {
- llvm_asm!("tt $0, $1" : "=r"(tt_resp) : "r"(addr) :: "volatile");
- }
- tt_resp
- }
-
- #[cfg(all(cortex_m, not(feature = "inline-asm")))]
- () => unsafe {
- extern "C" {
- fn __tt(_: *mut u32) -> u32;
- }
-
- __tt(addr)
- },
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+ let addr = addr as u32;
+ call_asm!(__tt(addr: u32) -> u32)
}
/// Test Target Unprivileged
@@ -300,28 +119,8 @@ pub fn tt(addr: *mut u32) -> u32 {
// The __ttt function does not dereference the pointer received.
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub fn ttt(addr: *mut u32) -> u32 {
- match () {
- #[cfg(all(cortex_m, feature = "inline-asm"))]
- () => {
- let tt_resp: u32;
- unsafe {
- llvm_asm!("ttt $0, $1" : "=r"(tt_resp) : "r"(addr) :: "volatile");
- }
- tt_resp
- }
-
- #[cfg(all(cortex_m, not(feature = "inline-asm")))]
- () => unsafe {
- extern "C" {
- fn __ttt(_: *mut u32) -> u32;
- }
-
- __ttt(addr)
- },
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+ let addr = addr as u32;
+ call_asm!(__ttt(addr: u32) -> u32)
}
/// Test Target Alternate Domain
@@ -336,28 +135,8 @@ pub fn ttt(addr: *mut u32) -> u32 {
// The __tta function does not dereference the pointer received.
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub fn tta(addr: *mut u32) -> u32 {
- match () {
- #[cfg(all(cortex_m, feature = "inline-asm"))]
- () => {
- let tt_resp: u32;
- unsafe {
- llvm_asm!("tta $0, $1" : "=r"(tt_resp) : "r"(addr) :: "volatile");
- }
- tt_resp
- }
-
- #[cfg(all(cortex_m, not(feature = "inline-asm")))]
- () => unsafe {
- extern "C" {
- fn __tta(_: *mut u32) -> u32;
- }
-
- __tta(addr)
- },
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+ let addr = addr as u32;
+ call_asm!(__tta(addr: u32) -> u32)
}
/// Test Target Alternate Domain Unprivileged
@@ -372,26 +151,6 @@ pub fn tta(addr: *mut u32) -> u32 {
// The __ttat function does not dereference the pointer received.
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub fn ttat(addr: *mut u32) -> u32 {
- match () {
- #[cfg(all(cortex_m, feature = "inline-asm"))]
- () => {
- let tt_resp: u32;
- unsafe {
- llvm_asm!("ttat $0, $1" : "=r"(tt_resp) : "r"(addr) :: "volatile");
- }
- tt_resp
- }
-
- #[cfg(all(cortex_m, not(feature = "inline-asm")))]
- () => unsafe {
- extern "C" {
- fn __ttat(_: *mut u32) -> u32;
- }
-
- __ttat(addr)
- },
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+ let addr = addr as u32;
+ call_asm!(__ttat(addr: u32) -> u32)
}
diff --git a/src/call_asm.rs b/src/call_asm.rs
new file mode 100644
index 0000000..295277f
--- /dev/null
+++ b/src/call_asm.rs
@@ -0,0 +1,24 @@
+/// An internal macro to invoke an assembly routine.
+///
+/// Depending on whether the unstable `inline-asm` feature is enabled, this will either call into
+/// the inline assembly implementation directly, or through the FFI shim (see `asm/lib.rs`).
+macro_rules! call_asm {
+ ( $func:ident ( $($args:ident: $tys:ty),* ) $(-> $ret:ty)? ) => {{
+ #[allow(unused_unsafe)]
+ unsafe {
+ match () {
+ #[cfg(feature = "inline-asm")]
+ () => crate::asm::inline::$func($($args),*),
+
+ #[cfg(not(feature = "inline-asm"))]
+ () => {
+ extern "C" {
+ fn $func($($args: $tys),*) $(-> $ret)?;
+ }
+
+ $func($($args),*)
+ },
+ }
+ }
+ }};
+}
diff --git a/src/interrupt.rs b/src/interrupt.rs
index c5da48d..68719ec 100644
--- a/src/interrupt.rs
+++ b/src/interrupt.rs
@@ -26,25 +26,7 @@ pub unsafe trait InterruptNumber: Copy {
/// Disables all interrupts
#[inline]
pub fn disable() {
- match () {
- #[cfg(all(cortex_m, feature = "inline-asm"))]
- () => unsafe {
- llvm_asm!("cpsid i" ::: "memory" : "volatile");
- },
-
- #[cfg(all(cortex_m, not(feature = "inline-asm")))]
- () => unsafe {
- extern "C" {
- fn __cpsid();
- }
-
- // XXX do we need a explicit compiler barrier here?
- __cpsid();
- },
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+ call_asm!(__cpsid());
}
/// Enables all the interrupts
@@ -54,23 +36,7 @@ pub fn disable() {
/// - Do not call this function inside an `interrupt::free` critical section
#[inline]
pub unsafe fn enable() {
- match () {
- #[cfg(all(cortex_m, feature = "inline-asm"))]
- () => llvm_asm!("cpsie i" ::: "memory" : "volatile"),
-
- #[cfg(all(cortex_m, not(feature = "inline-asm")))]
- () => {
- extern "C" {
- fn __cpsie();
- }
-
- // XXX do we need a explicit compiler barrier here?
- __cpsie();
- }
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+ call_asm!(__cpsie());
}
/// Execute closure `f` in an interrupt-free context.
diff --git a/src/lib.rs b/src/lib.rs
index 723816a..f30408e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -12,7 +12,7 @@
//! ## `inline-asm`
//!
//! When this feature is enabled the implementation of all the functions inside the `asm` and
-//! `register` modules use inline assembly (`llvm_asm!`) instead of external assembly (FFI into separate
+//! `register` modules use inline assembly (`asm!`) instead of external assembly (FFI into separate
//! assembly files pre-compiled using `arm-none-eabi-gcc`). The advantages of enabling `inline-asm`
//! are:
//!
@@ -52,17 +52,16 @@
//!
//! # Minimum Supported Rust Version (MSRV)
//!
-//! This crate is guaranteed to compile on stable Rust 1.31 and up. It *might*
+//! This crate is guaranteed to compile on stable Rust 1.38 and up. It *might*
//! compile with older versions but that may change in any new patch release.
-#![cfg_attr(feature = "inline-asm", feature(llvm_asm))]
+#![cfg_attr(feature = "inline-asm", feature(asm))]
#![deny(missing_docs)]
#![no_std]
#![allow(clippy::identity_op)]
#![allow(clippy::missing_safety_doc)]
// Prevent clippy from complaining about empty match expression that are used for cfg gating.
#![allow(clippy::match_single_binding)]
-
// This makes clippy warn about public functions which are not #[inline].
//
// Almost all functions in this crate result in trivial or even no assembly.
@@ -82,6 +81,8 @@ extern crate bare_metal;
extern crate volatile_register;
#[macro_use]
+mod call_asm;
+#[macro_use]
mod macros;
pub mod asm;
diff --git a/src/register/apsr.rs b/src/register/apsr.rs
index 3db8aeb..b81d892 100644
--- a/src/register/apsr.rs
+++ b/src/register/apsr.rs
@@ -50,17 +50,6 @@ impl Apsr {
/// **NOTE** This function is available if `cortex-m` is built with the `"inline-asm"` feature.
#[inline]
pub fn read() -> Apsr {
- match () {
- #[cfg(cortex_m)]
- () => {
- let r: u32;
- unsafe {
- llvm_asm!("mrs $0, APSR" : "=r"(r) ::: "volatile");
- }
- Apsr { bits: r }
- }
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+ let bits: u32 = call_asm!(__apsr_r() -> u32);
+ Apsr { bits }
}
diff --git a/src/register/basepri.rs b/src/register/basepri.rs
index 6caf938..07084cd 100644
--- a/src/register/basepri.rs
+++ b/src/register/basepri.rs
@@ -3,28 +3,7 @@
/// Reads the CPU register
#[inline]
pub fn read() -> u8 {
- match () {
- #[cfg(all(cortex_m, feature = "inline-asm"))]
- () => {
- let r: u32;
- unsafe {
- llvm_asm!("mrs $0, BASEPRI" : "=r"(r) ::: "volatile");
- }
- r as u8
- }
-
- #[cfg(all(cortex_m, not(feature = "inline-asm")))]
- () => unsafe {
- extern "C" {
- fn __basepri_r() -> u8;
- }
-
- __basepri_r()
- },
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+ call_asm!(__basepri_r() -> u8)
}
/// Writes to the CPU register
@@ -32,39 +11,14 @@ pub fn read() -> u8 {
/// **IMPORTANT** If you are using a Cortex-M7 device with revision r0p1 you MUST enable the
/// `cm7-r0p1` Cargo feature or this function WILL misbehave.
#[inline]
-pub unsafe fn write(_basepri: u8) {
- match () {
- #[cfg(all(cortex_m, feature = "inline-asm"))]
- () => match () {
- #[cfg(not(feature = "cm7-r0p1"))]
- () => llvm_asm!("msr BASEPRI, $0" :: "r"(_basepri) : "memory" : "volatile"),
- #[cfg(feature = "cm7-r0p1")]
- () => crate::interrupt::free(
- |_| llvm_asm!("msr BASEPRI, $0" :: "r"(_basepri) : "memory" : "volatile"),
- ),
- },
-
- #[cfg(all(cortex_m, not(feature = "inline-asm")))]
- () => match () {
- #[cfg(not(feature = "cm7-r0p1"))]
- () => {
- extern "C" {
- fn __basepri_w(_: u8);
- }
-
- __basepri_w(_basepri);
- }
- #[cfg(feature = "cm7-r0p1")]
- () => {
- extern "C" {
- fn __basepri_w_cm7_r0p1(_: u8);
- }
-
- __basepri_w_cm7_r0p1(_basepri);
- }
- },
+pub unsafe fn write(basepri: u8) {
+ #[cfg(feature = "cm7-r0p1")]
+ {
+ call_asm!(__basepri_w_cm7_r0p1(basepri: u8));
+ }
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
+ #[cfg(not(feature = "cm7-r0p1"))]
+ {
+ call_asm!(__basepri_w(basepri: u8));
}
}
diff --git a/src/register/basepri_max.rs b/src/register/basepri_max.rs
index 0e66f69..cea3838 100644
--- a/src/register/basepri_max.rs
+++ b/src/register/basepri_max.rs
@@ -8,43 +8,14 @@
/// **IMPORTANT** If you are using a Cortex-M7 device with revision r0p1 you MUST enable the
/// `cm7-r0p1` Cargo feature or this function WILL misbehave.
#[inline]
-pub fn write(_basepri: u8) {
- match () {
- #[cfg(all(cortex_m, feature = "inline-asm"))]
- () => unsafe {
- match () {
- #[cfg(not(feature = "cm7-r0p1"))]
- () => llvm_asm!("msr BASEPRI_MAX, $0" :: "r"(_basepri) : "memory" : "volatile"),
- #[cfg(feature = "cm7-r0p1")]
- () => crate::interrupt::free(
- |_| llvm_asm!("msr BASEPRI_MAX, $0" :: "r"(_basepri) : "memory" : "volatile"),
- ),
- }
- },
-
- #[cfg(all(cortex_m, not(feature = "inline-asm")))]
- () => unsafe {
- match () {
- #[cfg(not(feature = "cm7-r0p1"))]
- () => {
- extern "C" {
- fn __basepri_max(_: u8);
- }
-
- __basepri_max(_basepri)
- }
- #[cfg(feature = "cm7-r0p1")]
- () => {
- extern "C" {
- fn __basepri_max_cm7_r0p1(_: u8);
- }
-
- __basepri_max_cm7_r0p1(_basepri)
- }
- }
- },
+pub fn write(basepri: u8) {
+ #[cfg(feature = "cm7-r0p1")]
+ {
+ call_asm!(__basepri_max_cm7_r0p1(basepri: u8));
+ }
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
+ #[cfg(not(feature = "cm7-r0p1"))]
+ {
+ call_asm!(__basepri_max(basepri: u8));
}
}
diff --git a/src/register/control.rs b/src/register/control.rs
index 211b532..938b10f 100644
--- a/src/register/control.rs
+++ b/src/register/control.rs
@@ -156,58 +156,13 @@ impl Fpca {
/// Reads the CPU register
#[inline]
pub fn read() -> Control {
- match () {
- #[cfg(cortex_m)]
- () => {
- let r = match () {
- #[cfg(feature = "inline-asm")]
- () => {
- let r: u32;
- unsafe { llvm_asm!("mrs $0, CONTROL" : "=r"(r) ::: "volatile") }
- r
- }
-
- #[cfg(not(feature = "inline-asm"))]
- () => unsafe {
- extern "C" {
- fn __control_r() -> u32;
- }
-
- __control_r()
- },
- };
-
- Control { bits: r }
- }
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+ let bits: u32 = call_asm!(__control_r() -> u32);
+ Control { bits }
}
/// Writes to the CPU register.
#[inline]
-pub unsafe fn write(_control: Control) {
- match () {
- #[cfg(cortex_m)]
- () => match () {
- #[cfg(feature = "inline-asm")]
- () => {
- let control = _control.bits();
- llvm_asm!("msr CONTROL, $0" :: "r"(control) : "memory" : "volatile");
- }
-
- #[cfg(not(feature = "inline-asm"))]
- () => {
- extern "C" {
- fn __control_w(bits: u32);
- }
-
- __control_w(_control.bits());
- }
- },
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+pub unsafe fn write(control: Control) {
+ let control = control.bits();
+ call_asm!(__control_w(control: u32));
}
diff --git a/src/register/faultmask.rs b/src/register/faultmask.rs
index 06f60fe..1f19d97 100644
--- a/src/register/faultmask.rs
+++ b/src/register/faultmask.rs
@@ -27,36 +27,10 @@ impl Faultmask {
/// Reads the CPU register
#[inline]
pub fn read() -> Faultmask {
- match () {
- #[cfg(cortex_m)]
- () => {
- let r = match () {
- #[cfg(feature = "inline-asm")]
- () => {
- let r: u32;
- unsafe { llvm_asm!("mrs $0, FAULTMASK" : "=r"(r) ::: "volatile") }
- r
- }
-
- #[cfg(not(feature = "inline-asm"))]
- () => unsafe {
- extern "C" {
- fn __faultmask() -> u32;
-
- }
-
- __faultmask()
- },
- };
-
- if r & (1 << 0) == (1 << 0) {
- Faultmask::Inactive
- } else {
- Faultmask::Active
- }
- }
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
+ let r: u32 = call_asm!(__faultmask_r() -> u32);
+ if r & (1 << 0) == (1 << 0) {
+ Faultmask::Inactive
+ } else {
+ Faultmask::Active
}
}
diff --git a/src/register/fpscr.rs b/src/register/fpscr.rs
index 2ca00e1..dd538e9 100644
--- a/src/register/fpscr.rs
+++ b/src/register/fpscr.rs
@@ -295,49 +295,13 @@ impl RMode {
/// Read the FPSCR register
#[inline]
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::from_bits(r)
- }
-
- #[cfg(all(cortex_m, not(feature = "inline-asm")))]
- () => unsafe {
- extern "C" {
- fn __get_FPSCR() -> u32;
- }
- Fpscr::from_bits(__get_FPSCR())
- },
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+ let r: u32 = call_asm!(__fpscr_r() -> u32);
+ Fpscr::from_bits(r)
}
/// Set the value of the FPSCR register
#[inline]
-pub unsafe fn write(_fspcr: Fpscr) {
- match () {
- #[cfg(all(cortex_m, feature = "inline-asm"))]
- () => {
- let bits = _fspcr.bits();
- llvm_asm!("vmsr fpscr, $0" :: "r"(bits) :: "volatile");
- }
-
- #[cfg(all(cortex_m, not(feature = "inline-asm")))]
- () => {
- extern "C" {
- fn __set_FPSCR(bits: u32);
- }
-
- __set_FPSCR(_fspcr.bits());
- }
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+pub unsafe fn write(fpscr: Fpscr) {
+ let fpscr = fpscr.bits();
+ call_asm!(__fpscr_w(fpscr: u32));
}
diff --git a/src/register/lr.rs b/src/register/lr.rs
index 6919e10..1aa546c 100644
--- a/src/register/lr.rs
+++ b/src/register/lr.rs
@@ -5,29 +5,13 @@
/// **NOTE** This function is available if `cortex-m` is built with the `"inline-asm"` feature.
#[inline]
pub fn read() -> u32 {
- match () {
- #[cfg(cortex_m)]
- () => {
- let r: u32;
- unsafe { llvm_asm!("mov $0,R14" : "=r"(r) ::: "volatile") }
- r
- }
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+ call_asm!(__lr_r() -> u32)
}
/// Writes `bits` to the CPU register
///
/// **NOTE** This function is available if `cortex-m` is built with the `"inline-asm"` feature.
#[inline]
-pub unsafe fn write(_bits: u32) {
- match () {
- #[cfg(cortex_m)]
- () => llvm_asm!("mov R14,$0" :: "r"(_bits) :: "volatile"),
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+pub unsafe fn write(bits: u32) {
+ call_asm!(__lr_w(bits: u32));
}
diff --git a/src/register/mod.rs b/src/register/mod.rs
index efbe6ef..48d157a 100644
--- a/src/register/mod.rs
+++ b/src/register/mod.rs
@@ -58,11 +58,11 @@ pub mod psplim;
// Accessing these registers requires inline assembly because their contents are tied to the current
// stack frame
-#[cfg(any(feature = "inline-asm", target_arch = "x86_64"))]
+#[cfg(feature = "inline-asm")]
pub mod apsr;
-#[cfg(any(feature = "inline-asm", target_arch = "x86_64"))]
+#[cfg(feature = "inline-asm")]
pub mod lr;
-#[cfg(any(feature = "inline-asm", target_arch = "x86_64"))]
+#[cfg(feature = "inline-asm")]
pub mod pc;
diff --git a/src/register/msp.rs b/src/register/msp.rs
index b5460ed..275023d 100644
--- a/src/register/msp.rs
+++ b/src/register/msp.rs
@@ -3,45 +3,11 @@
/// Reads the CPU register
#[inline]
pub fn read() -> u32 {
- match () {
- #[cfg(all(cortex_m, feature = "inline-asm"))]
- () => {
- let r;
- unsafe { llvm_asm!("mrs $0,MSP" : "=r"(r) ::: "volatile") }
- r
- }
-
- #[cfg(all(cortex_m, not(feature = "inline-asm")))]
- () => unsafe {
- extern "C" {
- fn __msp_r() -> u32;
- }
-
- __msp_r()
- },
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+ call_asm!(__msp_r() -> u32)
}
/// Writes `bits` to the CPU register
#[inline]
-pub unsafe fn write(_bits: u32) {
- match () {
- #[cfg(all(cortex_m, feature = "inline-asm"))]
- () => llvm_asm!("msr MSP,$0" :: "r"(_bits) :: "volatile"),
-
- #[cfg(all(cortex_m, not(feature = "inline-asm")))]
- () => {
- extern "C" {
- fn __msp_w(_: u32);
- }
-
- __msp_w(_bits);
- }
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+pub unsafe fn write(bits: u32) {
+ call_asm!(__msp_w(bits: u32));
}
diff --git a/src/register/msplim.rs b/src/register/msplim.rs
index 68915c4..ac6f9ed 100644
--- a/src/register/msplim.rs
+++ b/src/register/msplim.rs
@@ -3,45 +3,11 @@
/// Reads the CPU register
#[inline]
pub fn read() -> u32 {
- match () {
- #[cfg(all(cortex_m, feature = "inline-asm"))]
- () => {
- let r;
- unsafe { llvm_asm!("mrs $0,MSPLIM" : "=r"(r) ::: "volatile") }
- r
- }
-
- #[cfg(all(cortex_m, not(feature = "inline-asm")))]
- () => unsafe {
- extern "C" {
- fn __msplim_r() -> u32;
- }
-
- __msplim_r()
- },
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+ call_asm!(__msplim_r() -> u32)
}
/// Writes `bits` to the CPU register
#[inline]
-pub unsafe fn write(_bits: u32) {
- match () {
- #[cfg(all(cortex_m, feature = "inline-asm"))]
- () => llvm_asm!("msr MSPLIM,$0" :: "r"(_bits) :: "volatile"),
-
- #[cfg(all(cortex_m, not(feature = "inline-asm")))]
- () => {
- extern "C" {
- fn __msplim_w(_: u32);
- }
-
- __msplim_w(_bits);
- }
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+pub unsafe fn write(bits: u32) {
+ call_asm!(__msplim_w(bits: u32))
}
diff --git a/src/register/pc.rs b/src/register/pc.rs
index f4486c4..0b33629 100644
--- a/src/register/pc.rs
+++ b/src/register/pc.rs
@@ -5,29 +5,13 @@
/// **NOTE** This function is available if `cortex-m` is built with the `"inline-asm"` feature.
#[inline]
pub fn read() -> u32 {
- match () {
- #[cfg(cortex_m)]
- () => {
- let r;
- unsafe { llvm_asm!("mov $0,R15" : "=r"(r) ::: "volatile") }
- r
- }
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+ call_asm!(__pc_r() -> u32)
}
/// Writes `bits` to the CPU register
///
/// **NOTE** This function is available if `cortex-m` is built with the `"inline-asm"` feature.
#[inline]
-pub unsafe fn write(_bits: u32) {
- match () {
- #[cfg(cortex_m)]
- () => llvm_asm!("mov R15,$0" :: "r"(_bits) :: "volatile"),
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+pub unsafe fn write(bits: u32) {
+ call_asm!(__pc_w(bits: u32));
}
diff --git a/src/register/primask.rs b/src/register/primask.rs
index 4b6df3c..20692a2 100644
--- a/src/register/primask.rs
+++ b/src/register/primask.rs
@@ -27,35 +27,14 @@ impl Primask {
/// Reads the CPU register
#[inline]
pub fn read() -> Primask {
- match () {
- #[cfg(cortex_m)]
- () => {
- let r = match () {
- #[cfg(feature = "inline-asm")]
- () => {
- let r: u32;
- unsafe { llvm_asm!("mrs $0, PRIMASK" : "=r"(r) ::: "volatile") }
- r
- }
-
- #[cfg(not(feature = "inline-asm"))]
- () => {
- extern "C" {
- fn __primask() -> u32;
- }
-
- unsafe { __primask() }
- }
- };
-
- if r & (1 << 0) == (1 << 0) {
- Primask::Inactive
- } else {
- Primask::Active
- }
- }
+ fn read_raw() -> u32 {
+ call_asm!(__primask_r() -> u32)
+ }
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
+ let r = read_raw();
+ if r & (1 << 0) == (1 << 0) {
+ Primask::Inactive
+ } else {
+ Primask::Active
}
}
diff --git a/src/register/psp.rs b/src/register/psp.rs
index c020e4f..0bca22c 100644
--- a/src/register/psp.rs
+++ b/src/register/psp.rs
@@ -3,45 +3,11 @@
/// Reads the CPU register
#[inline]
pub fn read() -> u32 {
- match () {
- #[cfg(all(cortex_m, feature = "inline-asm"))]
- () => {
- let r;
- unsafe { llvm_asm!("mrs $0,PSP" : "=r"(r) ::: "volatile") }
- r
- }
-
- #[cfg(all(cortex_m, not(feature = "inline-asm")))]
- () => unsafe {
- extern "C" {
- fn __psp_r() -> u32;
- }
-
- __psp_r()
- },
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+ call_asm!(__psp_r() -> u32)
}
/// Writes `bits` to the CPU register
#[inline]
-pub unsafe fn write(_bits: u32) {
- match () {
- #[cfg(all(cortex_m, feature = "inline-asm"))]
- () => llvm_asm!("msr PSP,$0" :: "r"(_bits) :: "volatile"),
-
- #[cfg(all(cortex_m, not(feature = "inline-asm")))]
- () => {
- extern "C" {
- fn __psp_w(_: u32);
- }
-
- __psp_w(_bits);
- }
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+pub unsafe fn write(bits: u32) {
+ call_asm!(__psp_w(bits: u32))
}
diff --git a/src/register/psplim.rs b/src/register/psplim.rs
index 8cb8f1c..8ee1e94 100644
--- a/src/register/psplim.rs
+++ b/src/register/psplim.rs
@@ -3,45 +3,11 @@
/// Reads the CPU register
#[inline]
pub fn read() -> u32 {
- match () {
- #[cfg(all(cortex_m, feature = "inline-asm"))]
- () => {
- let r;
- unsafe { llvm_asm!("mrs $0,PSPLIM" : "=r"(r) ::: "volatile") }
- r
- }
-
- #[cfg(all(cortex_m, not(feature = "inline-asm")))]
- () => unsafe {
- extern "C" {
- fn __psplim_r() -> u32;
- }
-
- __psplim_r()
- },
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+ call_asm!(__psplim_r() -> u32)
}
/// Writes `bits` to the CPU register
#[inline]
-pub unsafe fn write(_bits: u32) {
- match () {
- #[cfg(all(cortex_m, feature = "inline-asm"))]
- () => llvm_asm!("msr PSPLIM,$0" :: "r"(_bits) :: "volatile"),
-
- #[cfg(all(cortex_m, not(feature = "inline-asm")))]
- () => {
- extern "C" {
- fn __psplim_w(_: u32);
- }
-
- __psplim_w(_bits);
- }
-
- #[cfg(not(cortex_m))]
- () => unimplemented!(),
- }
+pub unsafe fn write(bits: u32) {
+ call_asm!(__psplim_w(bits: u32))
}