Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions cortex-m/src/coprocessor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
//! Coprocessor access assembly instructions.

/// 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)]
pub unsafe fn mcr<const CP: u32, const OP1: u32, const CRN: u32, const CRM: u32, const OP2: u32>(
value: u32,
) {
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)]
pub unsafe fn mrc<const CP: u32, const OP1: u32, const CRN: u32, const CRM: u32, const OP2: u32>(
) -> u32 {
let a: u32;

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)]
pub unsafe fn mcrr<const CP: u32, const OP1: u32, const CRM: u32>(a: u32, b: u32) {
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)]
pub unsafe fn mrrc<const CP: u32, const OPC: u32, const CRM: u32>() -> (u32, u32) {
// Preallocate the values.
let a: u32;
let b: u32;

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)
}
2 changes: 2 additions & 0 deletions cortex-m/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,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)))]
Expand Down
Loading