use core::arch::asm;

const PSR_I_BIT: usize = 0x00000080;

#[inline(always)]
pub(crate) fn arch_local_irq_save() -> usize {
    let flags: usize;
    unsafe {
        asm!(
            "mrs {0}, daif",
            "msr daifset, #2",
            out(reg) flags,
        );
    }
    flags
}

#[inline(always)]
pub(crate) fn arch_local_irq_restore(flags: usize) {
    unsafe {
        asm!(
            "msr daif, {0}",
            in(reg) flags,
        );
    }
}

#[inline(always)]
pub(crate) fn arch_local_irq_enable() {
    unsafe {
        asm!("msr daifclr, #2");
    }
}

#[inline(always)]
pub(crate) fn arch_local_irq_disable() {
    unsafe {
        asm!("msr daifset, #2");
    }
}

#[inline(always)]
pub(crate) fn arch_local_save_flags() -> usize {
    let flags: usize;
    unsafe {
        asm!(
            "mrs {0}, daif",
            out(reg) flags
        );
        flags
    }
}

#[inline(always)]
pub(crate) fn arch_irqs_disabled_flags(flags: usize) -> bool {
    flags & PSR_I_BIT == PSR_I_BIT
}

#[inline(always)]
pub(crate) fn arch_irqs_disabled() -> bool {
    arch_irqs_disabled_flags(arch_local_save_flags())
}

#[inline(always)]
pub(crate) fn arch_local_daif_mask() {
    unsafe {
        asm!("msr daifset, #0xf");
    }
}
