Skip to content

Instantly share code, notes, and snippets.

@lovely-error
Last active June 1, 2025 12:23
Show Gist options
  • Save lovely-error/7a66616bcbf5389edd0bfb03d81e88e5 to your computer and use it in GitHub Desktop.
Save lovely-error/7a66616bcbf5389edd0bfb03d81e88e5 to your computer and use it in GitHub Desktop.
// 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