#[cfg(not(portable_atomic_no_asm))]
use core::arch::asm;
#[cfg_attr(
portable_atomic_no_cfg_target_has_atomic,
cfg(any(test, portable_atomic_no_atomic_cas))
)]
#[cfg_attr(
not(portable_atomic_no_cfg_target_has_atomic),
cfg(any(test, not(target_has_atomic = "ptr")))
)]
pub(super) use super::super::riscv as atomic;
cfg_sel!({
#[cfg(portable_atomic_s_mode)]
{
macro_rules! status {
() => {
"sstatus"
};
}
#[cfg(portable_atomic_s_mode)]
macro_rules! mask {
() => {
"0x2"
};
}
}
#[cfg(else)]
{
macro_rules! status {
() => {
"mstatus"
};
}
macro_rules! mask {
() => {
"0x8"
};
}
}
});
pub(crate) type State = crate::utils::RegSize;
#[inline(always)]
pub(crate) fn disable() -> State {
let status: State;
unsafe {
asm!(
concat!("csrrci {status}, ", status!(), ", ", mask!()), status = out(reg) status,
options(nostack, preserves_flags),
);
}
status
}
#[inline(always)]
pub(crate) unsafe fn restore(prev_status: State) {
unsafe {
asm!(
concat!("csrw ", status!(), ", {prev_status}"), prev_status = in(reg) prev_status,
options(nostack, preserves_flags),
);
}
}