diff --git a/cortex-m/src/coprocessor.rs b/cortex-m/src/coprocessor.rs new file mode 100644 index 00000000..1f606d59 --- /dev/null +++ b/cortex-m/src/coprocessor.rs @@ -0,0 +1,90 @@ +//! Coprocessor access assembly instructions. + + + +/// Internal function to create an inlined MCR instruction. +/// This instruction moves one Register to a Coprocessor Register. +#[inline(always)] +pub fn mcr(value: u32) { + unsafe { + core::arch::asm!( + "MCR p{cp}, #{op1}, {0}, c{crn}, c{crm}, #{op2}", + in(reg) value, + cp = const CP, + op1 = const OP1, + crn = const CRN, + crm = const CRM, + op2 = const OP2, + options(nostack, nomem) + ) + } +} + + + +/// Internal function to create an inlined MRC instruction. +/// This instruction moves one Coprocessor Register to a Register. +#[inline(always)] +pub fn mrc() -> u32 { + // Preallocate the value. + let a: u32; + + unsafe { + core::arch::asm!( + "MRC p{cp}, #{op1}, {0}, c{crn}, c{crm}, #{op2}", + out(reg) a, + cp = const CP, + op1 = const OP1, + crn = const CRN, + crm = const CRM, + op2 = const OP2, + options(nostack, nomem) + ) + } + + a +} + + + +/// Internal function to create an inlined MCRR instruction. +/// This instruction moves two Registers to Coprocessor Registers. +#[inline(always)] +pub fn mcrr(a: u32, b: u32) { + unsafe { + core::arch::asm!( + "MCRR p{cp}, #{op1}, {0}, {1}, c{crm}", + in(reg) a, + in(reg) b, + cp = const CP, + op1 = const OP1, + crm = const CRM, + options(nostack, nomem) + ) + } +} + + + +/// Internal function to create an inlined MRRC instruction. +/// This instruction moves two Coprocessor Registers to Registers. +#[inline(always)] +pub fn mrrc() -> (u32, u32) { + // Preallocate the values. + let a: u32; + let b: u32; + + unsafe { + core::arch::asm!( + "MRRC p{cp}, #{opc}, {0}, {1}, c{crm}", + out(reg) a, + out(reg) b, + cp = const CP, + opc = const OPC, + crm = const CRM, + options(nostack, nomem) + ) + } + + (a, b) +} diff --git a/cortex-m/src/lib.rs b/cortex-m/src/lib.rs index f74fcbf7..70ef61dd 100644 --- a/cortex-m/src/lib.rs +++ b/cortex-m/src/lib.rs @@ -59,6 +59,8 @@ mod macros; pub mod asm; #[cfg(armv8m)] pub mod cmse; +#[cfg(not(armv6m))] +pub mod coprocessor; pub mod delay; pub mod interrupt; #[cfg(all(not(armv6m), not(armv8m_base)))]