Skip to content

Commit 6f41167

Browse files
committed
Allow compiler to optimize atomic_modify_at when arguments are statically known
1 parent b2d1ba2 commit 6f41167

File tree

1 file changed

+14
-6
lines changed

1 file changed

+14
-6
lines changed

src/reg.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! Register modifying support
22
3+
use core::sync::atomic::{compiler_fence, Ordering};
4+
35
/// Modify specific index of array-like register
46
macro_rules! modify_at {
57
($reg:expr, $bitwidth:expr, $index:expr, $value:expr) => {
@@ -21,17 +23,23 @@ pub(crate) unsafe fn atomic_modify_at(reg: *mut u32, bitwidth: u8, index: u8, va
2123
// Perform volatile atomic `*reg = *reg & !mask_comp | value;`
2224
let mut res: u32;
2325
while {
26+
compiler_fence(Ordering::SeqCst);
2427
core::arch::asm!(
2528
"ldrex {0}, [{1}]",
26-
"bics {0}, {2}",
27-
"orrs {0}, {3}",
28-
"strex {0}, {0}, [{1}]",
2929
out(reg) res,
3030
in(reg) reg,
31-
in(reg) mask_comp,
32-
in(reg) value,
33-
options(nostack),
31+
options(readonly, preserves_flags, nostack),
32+
);
33+
compiler_fence(Ordering::SeqCst);
34+
res = res & !mask_comp | value;
35+
compiler_fence(Ordering::SeqCst);
36+
core::arch::asm!(
37+
"strex {0}, {0}, [{1}]",
38+
inout(reg) res,
39+
in(reg) reg,
40+
options(preserves_flags, nostack),
3441
);
42+
compiler_fence(Ordering::SeqCst);
3543
res != 0
3644
} {}
3745
}

0 commit comments

Comments
 (0)