Last active
June 1, 2025 12:23
-
-
Save lovely-error/7a66616bcbf5389edd0bfb03d81e88e5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://developer.arm.com/documentation/102336/0100/Load-Acquire-and-Store-Release-instructions | |
// https://developer.arm.com/documentation/ddi0602/2025-03/Base-Instructions/DMB--Data-memory-barrier-?lang=en | |
#[derive(Copy, Clone)] | |
enum Ordering { | |
Unordered, | |
Reads, | |
Writes, | |
ReadsWrites | |
} | |
#[unsafe(no_mangle)] | |
#[inline(always)] | |
fn load_link_atomic_aarch64( | |
addr:*const u64, | |
before: Ordering, | |
after: Ordering | |
) -> u64 { | |
let mut val:u64; | |
match (before, after) { | |
(Ordering::Unordered, Ordering::Unordered) => unsafe { | |
core::arch::asm!( | |
"ldxr {val}, [{addr}]", | |
val = out(reg) val, | |
addr = in(reg) addr, | |
options(nostack) | |
) | |
}, | |
(Ordering::Unordered, Ordering::ReadsWrites) => unsafe { | |
core::arch::asm!( | |
"ldaxr {val}, [{addr}]", | |
val = out(reg) val, | |
addr = in(reg) addr, | |
options(nostack) | |
) | |
}, | |
(Ordering::ReadsWrites, Ordering::ReadsWrites) => unsafe { | |
core::arch::asm!( | |
"dmb ish", | |
"ldaxr {val}, [{addr}]", | |
val = out(reg) val, | |
addr = in(reg) addr, | |
options(nostack) | |
) | |
} | |
(Ordering::Reads, Ordering::Reads) => { | |
panic!("invalid ordering parameters: use other after ordering"); | |
}, | |
(Ordering::Reads, Ordering::ReadsWrites) => unsafe { | |
core::arch::asm!( | |
"dmb ishld", | |
"ldaxr {val}, [{addr}]", | |
val = out(reg) val, | |
addr = in(reg) addr, | |
options(nostack) | |
) | |
}, | |
(Ordering::Writes, _) => { | |
panic!("invalid ordering paramters: use other ordering for before"); | |
}, | |
(Ordering::Unordered, Ordering::Reads) => unsafe { | |
core::arch::asm!( | |
"ldxr {val}, [{addr}]", | |
"dmb ishld", | |
val = out(reg) val, | |
addr = in(reg) addr, | |
options(nostack) | |
) | |
}, | |
(Ordering::Unordered, Ordering::Writes) => { | |
panic!("invalid ordering paramters: use other ordering for after"); | |
}, | |
(Ordering::Reads, Ordering::Unordered) => unsafe { | |
core::arch::asm!( | |
"dmb ishld", | |
"ldxr {val}, [{addr}]", | |
val = out(reg) val, | |
addr = in(reg) addr, | |
options(nostack) | |
) | |
}, | |
(Ordering::Reads, Ordering::Writes) => { | |
panic!("invalid ordering paramters: use other ordering for after"); | |
}, | |
(Ordering::ReadsWrites, Ordering::Unordered) => unsafe { | |
core::arch::asm!( | |
"dmb ish", | |
"ldxr {val}, [{addr}]", | |
val = out(reg) val, | |
addr = in(reg) addr, | |
options(nostack) | |
) | |
}, | |
(Ordering::ReadsWrites, Ordering::Reads) => { | |
panic!("invalid ordering paramters: use other ordering for after"); | |
}, | |
(Ordering::ReadsWrites, Ordering::Writes) => { | |
panic!("invalid ordering paramters: use other ordering for after"); | |
} | |
} | |
return val | |
} | |
#[unsafe(no_mangle)] | |
#[inline(always)] | |
fn try_store_atomic_aarch64(addr:*mut u64, val: u64, before:Ordering, after:Ordering) -> bool { | |
let mut ok: u32; | |
match (before, after) { | |
(Ordering::Unordered, Ordering::Unordered) => unsafe { | |
core::arch::asm!( | |
"stxr {ok:w}, {val}, [{addr}]", | |
ok = out(reg) ok, | |
val = in(reg) val, | |
addr = in(reg) addr, | |
options(nostack) | |
); | |
} | |
(Ordering::ReadsWrites, Ordering::Unordered) => unsafe { | |
core::arch::asm!( | |
"stlxr {ok:w}, {val}, [{addr}]", | |
ok = out(reg) ok, | |
val = in(reg) val, | |
addr = in(reg) addr, | |
options(nostack) | |
); | |
}, | |
(Ordering::ReadsWrites, Ordering::ReadsWrites) => unsafe { | |
core::arch::asm!( | |
"stlxr {ok:w}, {val}, [{addr}]", | |
"dmb ish", | |
ok = out(reg) ok, | |
val = in(reg) val, | |
addr = in(reg) addr, | |
options(nostack) | |
); | |
}, | |
(Ordering::Writes, Ordering::Writes) => unsafe { | |
core::arch::asm!( | |
"dmb ishst", | |
"stxr {ok:w}, {val}, [{addr}]", | |
"dmb ishst", | |
ok = out(reg) ok, | |
val = in(reg) val, | |
addr = in(reg) addr, | |
options(nostack) | |
); | |
}, | |
(Ordering::Reads, Ordering::Unordered) => unsafe { | |
core::arch::asm!( | |
"dmb ishld", | |
"stxr {ok:w}, {val}, [{addr}]", | |
ok = out(reg) ok, | |
val = in(reg) val, | |
addr = in(reg) addr, | |
options(nostack) | |
); | |
}, | |
(Ordering::Reads, Ordering::Writes) => unsafe { | |
core::arch::asm!( | |
"dmb ishld", | |
"stxr {ok:w}, {val}, [{addr}]", | |
"dmb ishst", | |
ok = out(reg) ok, | |
val = in(reg) val, | |
addr = in(reg) addr, | |
options(nostack) | |
); | |
}, | |
(Ordering::Unordered, Ordering::ReadsWrites) => unsafe { | |
core::arch::asm!( | |
"stxr {ok:w}, {val}, [{addr}]", | |
"dmb ish", | |
ok = out(reg) ok, | |
val = in(reg) val, | |
addr = in(reg) addr, | |
options(nostack) | |
); | |
}, | |
(Ordering::Reads, Ordering::Reads) => { | |
panic!("invalid ordering combination: use different order for after") | |
}, | |
(Ordering::Unordered, Ordering::Reads) => { | |
panic!("invalid ordering combination: use different order for after") | |
}, | |
(Ordering::Unordered, Ordering::Writes) => unsafe { | |
core::arch::asm!( | |
"stxr {ok:w}, {val}, [{addr}]", | |
"dmb ishst", | |
ok = out(reg) ok, | |
val = in(reg) val, | |
addr = in(reg) addr, | |
options(nostack) | |
); | |
}, | |
(Ordering::Reads, Ordering::ReadsWrites) => unsafe { | |
core::arch::asm!( | |
"dmb ishld", | |
"stxr {ok:w}, {val}, [{addr}]", | |
"dmb ish", | |
ok = out(reg) ok, | |
val = in(reg) val, | |
addr = in(reg) addr, | |
options(nostack) | |
); | |
}, | |
(Ordering::Writes, Ordering::Unordered) => unsafe { | |
core::arch::asm!( | |
"dmb ishst", | |
"stxr {ok:w}, {val}, [{addr}]", | |
ok = out(reg) ok, | |
val = in(reg) val, | |
addr = in(reg) addr, | |
options(nostack) | |
); | |
}, | |
(Ordering::Writes, Ordering::Reads) => { | |
panic!("invalid ordering combination: use other after ordering") | |
}, | |
(Ordering::Writes, Ordering::ReadsWrites) => unsafe { | |
core::arch::asm!( | |
"dmb ishst", | |
"stxr {ok:w}, {val}, [{addr}]", | |
"dmb ish", | |
ok = out(reg) ok, | |
val = in(reg) val, | |
addr = in(reg) addr, | |
options(nostack) | |
); | |
}, | |
(Ordering::ReadsWrites, Ordering::Reads) => { | |
panic!("invalid ordering combination: use other after ordering"); | |
}, | |
(Ordering::ReadsWrites, Ordering::Writes) => unsafe { | |
core::arch::asm!( | |
"dmb ish", | |
"stxr {ok:w}, {val}, [{addr}]", | |
"dmb ishst", | |
ok = out(reg) ok, | |
val = in(reg) val, | |
addr = in(reg) addr, | |
options(nostack) | |
); | |
} | |
} | |
return ok == 0 | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment