use core::arch::asm;
use super::{OperationNumber, ParamRegR, ParamRegW, RetReg};
macro_rules! trap {
() => {
".balign 16
.option push
.option norvc
slli zero, zero, 0x1F
ebreak
srai zero, zero, 0x7
.option pop"
};
}
#[inline]
pub unsafe fn syscall(number: OperationNumber, parameter: ParamRegW<'_>) -> RetReg {
let ret;
unsafe {
asm!(
trap!(),
inout("a0") number.0 as usize => ret, inout("a1") parameter.0 => _, options(nostack, preserves_flags),
);
}
RetReg(ret)
}
#[inline]
pub unsafe fn syscall_readonly(number: OperationNumber, parameter: ParamRegR<'_>) -> RetReg {
let ret;
unsafe {
asm!(
trap!(),
inout("a0") number.0 as usize => ret, inout("a1") parameter.0 => _, options(nostack, preserves_flags, readonly),
);
}
RetReg(ret)
}
#[inline]
pub(crate) unsafe fn syscall_param_unchanged(
number: OperationNumber,
parameter: ParamRegW<'_>,
) -> RetReg {
let ret;
#[cfg(not(debug_assertions))]
unsafe {
asm!(
trap!(),
inout("a0") number.0 as usize => ret, in("a1") parameter.0, options(nostack, preserves_flags),
);
}
#[cfg(debug_assertions)]
unsafe {
let param_new;
asm!(
trap!(),
inout("a0") number.0 as usize => ret, inout("a1") parameter.0 => param_new, options(nostack, preserves_flags),
);
assert_eq!(parameter.0, param_new);
}
RetReg(ret)
}
#[inline]
pub(crate) unsafe fn syscall_param_unchanged_readonly(
number: OperationNumber,
parameter: ParamRegR<'_>,
) -> RetReg {
let ret;
#[cfg(not(debug_assertions))]
unsafe {
asm!(
trap!(),
inout("a0") number.0 as usize => ret, in("a1") parameter.0, options(nostack, preserves_flags, readonly),
);
}
#[cfg(debug_assertions)]
unsafe {
let param_new;
asm!(
trap!(),
inout("a0") number.0 as usize => ret, inout("a1") parameter.0 => param_new, options(nostack, preserves_flags, readonly),
);
assert_eq!(parameter.0, param_new);
}
RetReg(ret)
}
#[inline]
pub(crate) unsafe fn syscall_noreturn_readonly(
number: OperationNumber,
parameter: ParamRegR<'_>,
) -> ! {
unsafe {
asm!(
trap!(),
"2:",
"j 2b",
in("a0") number.0 as usize, in("a1") parameter.0, options(nostack, noreturn, preserves_flags, readonly),
)
}
}