Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement coprocessor access instructions #531

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 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
1 change: 1 addition & 0 deletions cortex-m/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ cm7-r0p1 = ["cm7"]
linker-plugin-lto = []
std = []
critical-section-single-core = ["critical-section/restore-state-bool"]
coprocessor = []
spcan marked this conversation as resolved.
Show resolved Hide resolved

[package.metadata.docs.rs]
targets = [
Expand Down
94 changes: 94 additions & 0 deletions cortex-m/src/coprocessor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
//! Coprocessor access assembly instructions.



/// Internal function to create an inlined MCR instruction.
/// This instruction moves one Register to a Coprocessor Register.
/// For this function to compile to a single instruction, compile to opt-level > 2.
spcan marked this conversation as resolved.
Show resolved Hide resolved
#[inline(always)]
pub(crate) fn mcr<const CP: u32, const OP1: u32, const CRN: u32, const CRM: u32, const OP2: u32>(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.
/// For this function to compile to a single instruction, compile to opt-level > 2.
#[inline(always)]
pub(crate) fn mrc<const CP: u32, const OP1: u32, const CRN: u32, const CRM: u32, const OP2: u32>() -> 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.
/// For this function to compile to a single instruction, compile to opt-level > 2.
#[inline(always)]
pub(crate) fn mcrr<const CP: u32, const OP1: u32, const CRM: u32>(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.
/// For this function to compile to a single instruction, compile to opt-level > 2.
#[inline(always)]
pub(crate) fn mrrc<const CP: u32, const OPC: u32, const CRM: u32>() -> (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)
}
2 changes: 2 additions & 0 deletions cortex-m/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ mod macros;
pub mod asm;
#[cfg(armv8m)]
pub mod cmse;
#[cfg(all(not(armv6m), feature = "coprocessor"))]
pub mod coprocessor;
pub mod delay;
pub mod interrupt;
#[cfg(all(not(armv6m), not(armv8m_base)))]
Expand Down
Loading