const MAX_SFENCE_OPS: usize = 64;

#[inline(always)]
pub(super) fn arch_local_flush_tlb_all() {
    unsafe {
        core::arch::asm!("sfence.vma");
    }
}

#[inline(always)]
pub(super) fn arch_flush_tlb_space(asid: usize) {
    unsafe {
        core::arch::asm!("sfence.vma x0, {0}", in(reg) asid);
    }
}

pub(super) fn arch_flush_tlb_range(asid: usize, start: usize, end: usize, stride: usize) {
    if (end - start) / stride > MAX_SFENCE_OPS {
        arch_flush_tlb_space(asid);
        return;
    }

    let mut addr = start;
    while addr < end {
        unsafe {
            core::arch::asm!("sfence.vma {0}, {1}", in(reg) addr, in(reg) asid);
        }
        addr += stride;
    }
}
