use core::arch::asm;
use core::sync::atomic::{compiler_fence, Ordering};
#[inline(always)]
pub unsafe fn __bkpt() {
asm!("bkpt", options(nomem, nostack, preserves_flags));
}
#[inline(always)]
pub unsafe fn __control_r() -> u32 {
let r;
asm!("mrs {}, CONTROL", out(reg) r, options(nomem, nostack, preserves_flags));
r
}
#[inline(always)]
pub unsafe fn __control_w(w: u32) {
asm!(
"msr CONTROL, {}",
"isb",
in(reg) w,
options(nomem, nostack, preserves_flags),
);
compiler_fence(Ordering::SeqCst);
}
#[inline(always)]
pub unsafe fn __cpsid() {
asm!("cpsid i", options(nomem, nostack, preserves_flags));
compiler_fence(Ordering::SeqCst);
}
#[inline(always)]
pub unsafe fn __cpsie() {
compiler_fence(Ordering::SeqCst);
asm!("cpsie i", options(nomem, nostack, preserves_flags));
}
#[inline(always)]
pub unsafe fn __delay(cyc: u32) {
let real_cyc = 1 + cyc / 2;
asm!(
"1:",
"subs {}, #1",
"bne 1b",
inout(reg) real_cyc => _,
options(nomem, nostack),
);
}
#[inline(always)]
pub unsafe fn __dmb() {
compiler_fence(Ordering::SeqCst);
asm!("dmb", options(nomem, nostack, preserves_flags));
compiler_fence(Ordering::SeqCst);
}
#[inline(always)]
pub unsafe fn __dsb() {
compiler_fence(Ordering::SeqCst);
asm!("dsb", options(nomem, nostack, preserves_flags));
compiler_fence(Ordering::SeqCst);
}
#[inline(always)]
pub unsafe fn __isb() {
compiler_fence(Ordering::SeqCst);
asm!("isb", options(nomem, nostack, preserves_flags));
compiler_fence(Ordering::SeqCst);
}
#[inline(always)]
pub unsafe fn __msp_r() -> u32 {
let r;
asm!("mrs {}, MSP", out(reg) r, options(nomem, nostack, preserves_flags));
r
}
#[inline(always)]
pub unsafe fn __msp_w(val: u32) {
asm!("msr MSP, {}", in(reg) val, options(nomem, nostack, preserves_flags));
}
#[inline(always)]
pub unsafe fn __apsr_r() -> u32 {
let r;
asm!("mrs {}, APSR", out(reg) r, options(nomem, nostack, preserves_flags));
r
}
#[inline(always)]
pub unsafe fn __nop() {
asm!("nop", options(nomem, nostack, preserves_flags));
}
#[inline(always)]
pub unsafe fn __pc_r() -> u32 {
let r;
asm!("mov {}, pc", out(reg) r, options(nomem, nostack, preserves_flags));
r
}
#[inline(always)]
pub unsafe fn __pc_w(val: u32) {
asm!("mov pc, {}", in(reg) val, options(nomem, nostack, preserves_flags));
}
#[inline(always)]
pub unsafe fn __lr_r() -> u32 {
let r;
asm!("mov {}, lr", out(reg) r, options(nomem, nostack, preserves_flags));
r
}
#[inline(always)]
pub unsafe fn __lr_w(val: u32) {
asm!("mov lr, {}", in(reg) val, options(nomem, nostack, preserves_flags));
}
#[inline(always)]
pub unsafe fn __primask_r() -> u32 {
let r;
asm!("mrs {}, PRIMASK", out(reg) r, options(nomem, nostack, preserves_flags));
r
}
#[inline(always)]
pub unsafe fn __psp_r() -> u32 {
let r;
asm!("mrs {}, PSP", out(reg) r, options(nomem, nostack, preserves_flags));
r
}
#[inline(always)]
pub unsafe fn __psp_w(val: u32) {
asm!("msr PSP, {}", in(reg) val, options(nomem, nostack, preserves_flags));
}
#[inline(always)]
pub unsafe fn __sev() {
asm!("sev", options(nomem, nostack, preserves_flags));
}
#[inline(always)]
pub unsafe fn __udf() -> ! {
asm!("udf #0", options(noreturn, nomem, nostack, preserves_flags));
}
#[inline(always)]
pub unsafe fn __wfe() {
asm!("wfe", options(nomem, nostack, preserves_flags));
}
#[inline(always)]
pub unsafe fn __wfi() {
asm!("wfi", options(nomem, nostack, preserves_flags));
}
#[inline(always)]
pub unsafe fn __sh_syscall(mut nr: u32, arg: u32) -> u32 {
asm!("bkpt #0xab", inout("r0") nr, in("r1") arg, options(nomem, nostack, preserves_flags));
nr
}
#[inline(always)]
pub unsafe fn __bootstrap(msp: u32, rv: u32) -> ! {
asm!(
"mrs {tmp}, CONTROL",
"bics {tmp}, {spsel}",
"msr CONTROL, {tmp}",
"isb",
"msr MSP, {msp}",
"bx {rv}",
tmp = in(reg) 0,
spsel = in(reg) 2,
msp = in(reg) msp,
rv = in(reg) rv,
options(noreturn, nomem, nostack),
);
}
#[cfg(any(armv7m, armv8m_main))]
pub use self::v7m::*;
#[cfg(any(armv7m, armv8m_main))]
mod v7m {
use core::arch::asm;
use core::sync::atomic::{compiler_fence, Ordering};
#[inline(always)]
pub unsafe fn __basepri_max(val: u8) {
asm!("msr BASEPRI_MAX, {}", in(reg) val, options(nomem, nostack, preserves_flags));
}
#[inline(always)]
pub unsafe fn __basepri_r() -> u8 {
let r;
asm!("mrs {}, BASEPRI", out(reg) r, options(nomem, nostack, preserves_flags));
r
}
#[inline(always)]
pub unsafe fn __basepri_w(val: u8) {
asm!("msr BASEPRI, {}", in(reg) val, options(nomem, nostack, preserves_flags));
}
#[inline(always)]
pub unsafe fn __faultmask_r() -> u32 {
let r;
asm!("mrs {}, FAULTMASK", out(reg) r, options(nomem, nostack, preserves_flags));
r
}
#[inline(always)]
pub unsafe fn __enable_icache() {
asm!(
"ldr {0}, =0xE000ED14", "mrs {2}, PRIMASK", "cpsid i", "ldr {1}, [{0}]", "orr.w {1}, {1}, #(1 << 17)", "str {1}, [{0}]", "dsb", "isb", "msr PRIMASK, {2}", out(reg) _,
out(reg) _,
out(reg) _,
options(nostack),
);
compiler_fence(Ordering::SeqCst);
}
#[inline(always)]
pub unsafe fn __enable_dcache() {
asm!(
"ldr {0}, =0xE000ED14", "mrs {2}, PRIMASK", "cpsid i", "ldr {1}, [{0}]", "orr.w {1}, {1}, #(1 << 16)", "str {1}, [{0}]", "dsb", "isb", "msr PRIMASK, {2}", out(reg) _,
out(reg) _,
out(reg) _,
options(nostack),
);
compiler_fence(Ordering::SeqCst);
}
}
#[cfg(armv7em)]
pub use self::v7em::*;
#[cfg(armv7em)]
mod v7em {
use core::arch::asm;
#[inline(always)]
pub unsafe fn __basepri_max_cm7_r0p1(val: u8) {
asm!(
"mrs {1}, PRIMASK",
"cpsid i",
"tst.w {1}, #1",
"msr BASEPRI_MAX, {0}",
"it ne",
"bxne lr",
"cpsie i",
in(reg) val,
out(reg) _,
options(nomem, nostack, preserves_flags),
);
}
#[inline(always)]
pub unsafe fn __basepri_w_cm7_r0p1(val: u8) {
asm!(
"mrs {1}, PRIMASK",
"cpsid i",
"tst.w {1}, #1",
"msr BASEPRI, {0}",
"it ne",
"bxne lr",
"cpsie i",
in(reg) val,
out(reg) _,
options(nomem, nostack, preserves_flags),
);
}
}
#[cfg(armv8m)]
pub use self::v8m::*;
#[cfg(armv8m)]
mod v8m {
use core::arch::asm;
#[inline(always)]
pub unsafe fn __tt(mut target: u32) -> u32 {
asm!(
"tt {target}, {target}",
target = inout(reg) target,
options(nomem, nostack, preserves_flags),
);
target
}
#[inline(always)]
pub unsafe fn __ttt(mut target: u32) -> u32 {
asm!(
"ttt {target}, {target}",
target = inout(reg) target,
options(nomem, nostack, preserves_flags),
);
target
}
#[inline(always)]
pub unsafe fn __tta(mut target: u32) -> u32 {
asm!(
"tta {target}, {target}",
target = inout(reg) target,
options(nomem, nostack, preserves_flags),
);
target
}
#[inline(always)]
pub unsafe fn __ttat(mut target: u32) -> u32 {
asm!(
"ttat {target}, {target}",
target = inout(reg) target,
options(nomem, nostack, preserves_flags),
);
target
}
#[inline(always)]
pub unsafe fn __msp_ns_r() -> u32 {
let r;
asm!("mrs {}, MSP_NS", out(reg) r, options(nomem, nostack, preserves_flags));
r
}
#[inline(always)]
pub unsafe fn __msp_ns_w(val: u32) {
asm!("msr MSP_NS, {}", in(reg) val, options(nomem, nostack, preserves_flags));
}
#[inline(always)]
pub unsafe fn __bxns(val: u32) {
asm!("BXNS {}", in(reg) val, options(nomem, nostack, preserves_flags));
}
}
#[cfg(armv8m_main)]
pub use self::v8m_main::*;
#[cfg(armv8m_main)]
mod v8m_main {
use core::arch::asm;
#[inline(always)]
pub unsafe fn __msplim_r() -> u32 {
let r;
asm!("mrs {}, MSPLIM", out(reg) r, options(nomem, nostack, preserves_flags));
r
}
#[inline(always)]
pub unsafe fn __msplim_w(val: u32) {
asm!("msr MSPLIM, {}", in(reg) val, options(nomem, nostack, preserves_flags));
}
#[inline(always)]
pub unsafe fn __psplim_r() -> u32 {
let r;
asm!("mrs {}, PSPLIM", out(reg) r, options(nomem, nostack, preserves_flags));
r
}
#[inline(always)]
pub unsafe fn __psplim_w(val: u32) {
asm!("msr PSPLIM, {}", in(reg) val, options(nomem, nostack, preserves_flags));
}
}
#[cfg(has_fpu)]
pub use self::fpu::*;
#[cfg(has_fpu)]
mod fpu {
use core::arch::asm;
#[inline(always)]
pub unsafe fn __fpscr_r() -> u32 {
let r;
asm!("vmrs {}, fpscr", out(reg) r, options(nomem, nostack, preserves_flags));
r
}
#[inline(always)]
pub unsafe fn __fpscr_w(val: u32) {
asm!("vmsr fpscr, {}", in(reg) val, options(nomem, nostack));
}
}