fn main() {
    unsafe {
        let foo = 1;
        let mut o = 0;
        core::arch::asm!(
            "%input = OpLoad _ {0}",
            concat!("%result = ", "bar", " _ %input"),
            "OpStore {1} %result",
            in(reg) &foo,
            in(reg) &mut o,
        );

        let thread_id: usize;
        core::arch::asm!("
            mov {0}, gs:[0x30]
            mov {0}, [{0}+0x48]
        ", out(reg) thread_id, options(pure, readonly, nostack));

        static UNMAP_BASE: usize;
        const MEM_RELEASE: usize;
        static VirtualFree: usize;
        const OffPtr: usize;
        const OffFn: usize;
        core::arch::asm!("
            push {free_type}
            push {free_size}
            push {base}

            mov eax, fs:[30h]
            mov eax, [eax+8h]
            add eax, {off_fn}
            mov [eax-{off_fn}+{off_ptr}], eax

            push eax

            jmp {virtual_free}
            ",
            off_ptr = const OffPtr,
            off_fn  = const OffFn,

            free_size = const 0,
            free_type = const MEM_RELEASE,

            virtual_free = sym VirtualFree,

            base = sym UNMAP_BASE,
            options(noreturn),
        );
    }
}
// taken from https://github.com/rust-embedded/cortex-m/blob/47921b51f8b960344fcfa1255a50a0d19efcde6d/cortex-m/src/asm.rs#L254-L274
#[inline]
pub unsafe fn bootstrap(msp: *const u32, rv: *const u32) -> ! {
    // Ensure thumb mode is set.
    let rv = (rv as u32) | 1;
    let msp = msp as u32;
    core::arch::asm!(
        "mrs {tmp}, CONTROL",
        "bics {tmp}, {spsel}",
        "msr CONTROL, {tmp}",
        "isb",
        "msr MSP, {msp}",
        "bx {rv}",
        // `out(reg) _` is not permitted in a `noreturn` asm! call,
        // so instead use `in(reg) 0` and don't restore it afterwards.
        tmp = in(reg) 0,
        spsel = in(reg) 2,
        msp = in(reg) msp,
        rv = in(reg) rv,
        options(noreturn, nomem, nostack),
    );
}