diff --git a/cortex-m/src/asm.rs b/cortex-m/src/asm.rs index 3dc4c8e1..39417d28 100644 --- a/cortex-m/src/asm.rs +++ b/cortex-m/src/asm.rs @@ -388,3 +388,118 @@ pub unsafe fn bootload(vector_table: *const u32) -> ! { bootstrap(msp as *const u32, rv as *const u32); } } + +/// This instruction moves one Register to a Coprocessor Register. +/// This function generates inline assembly and needs the instruction configuration +/// during compilation time (i.e. as `const`). +/// The values of the constants required by this function should be defined by +/// the coprocessor's reference manual. +/// - CP: The coprocessor's index. +/// - OP1: First optional operation for the coprocessor. +/// - CRN: Coprocessor register N. +/// - CRM: Coprocessor register M. +/// - OP2: Second optional operation for the coprocessor. +#[inline(always)] +#[asm_cfg(any(armv7m, armv8m))] +pub unsafe 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) + ) + }; +} + +/// This instruction moves one Coprocessor Register to a Register. +/// This function generates inline assembly and needs the instruction configuration +/// during compilation time (i.e. as `const`). +/// The values of the constants required by this function should be defined by +/// the coprocessor's reference manual. +/// - CP: The coprocessor's index. +/// - OP1: First optional operation for the coprocessor. +/// - CRN: Coprocessor register N. +/// - CRM: Coprocessor register M. +/// - OP2: Second optional operation for the coprocessor. +#[inline(always)] +#[asm_cfg(any(armv7m, armv8m))] +pub unsafe fn mrc() +-> u32 { + 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 +} + +/// This instruction moves two Registers to Coprocessor Registers. +/// This function generates inline assembly and needs the instruction configuration +/// during compilation time (i.e. as `const`). +/// The values of the constants required by this function should be defined by +/// the coprocessor's reference manual. +/// - CP: The coprocessor's index. +/// - OP1: First optional operation for the coprocessor. +/// - CRM: Coprocessor register M. +#[inline(always)] +#[asm_cfg(any(armv7m, armv8m))] +pub unsafe 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) + ) + }; +} + +/// This instruction moves two Coprocessor Registers to Registers. +/// This function generates inline assembly and needs the instruction configuration +/// during compilation time (i.e. as `const`). +/// The values of the constants required by this function should be defined by +/// the coprocessor's reference manual. +/// - CP: The coprocessor's index. +/// - OP1: First optional operation for the coprocessor. +/// - CRM: Coprocessor register M. +#[inline(always)] +#[asm_cfg(any(armv7m, armv8m))] +pub unsafe 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) +}