Skip to content

Commit 7af0a08

Browse files
japaricgnzlbg
authored andcommitted
acle/barrier: use llvm.{arm,aarch64}.{dmb,dsb,isb} instead of asm!
also make these available on architectures that don't have a dedicated DMB / DSB / ISB instruction addresses #557 (comment)
1 parent 52d32dd commit 7af0a08

File tree

4 files changed

+100
-15
lines changed

4 files changed

+100
-15
lines changed

crates/core_arch/src/acle/barrier/common.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ dmb_dsb!(SY);
99
impl super::super::sealed::Isb for SY {
1010
#[inline(always)]
1111
unsafe fn __isb(&self) {
12-
asm!("ISB SY" : : : "memory" : "volatile")
12+
super::isb(super::arg::SY)
1313
}
1414
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Reference: ARM11 MPCore Processor Technical Reference Manual (ARM DDI 0360E) Section 3.5 "Summary
2+
// of CP15 instructions"
3+
4+
/// Full system is the required shareability domain, reads and writes are the
5+
/// required access types
6+
pub struct SY;
7+
8+
impl super::super::sealed::Dmb for SY {
9+
#[inline(always)]
10+
unsafe fn __dmb(&self) {
11+
asm!("mcr p15, 0, r0, c7, c10, 5" : : : "memory" : "volatile")
12+
}
13+
}
14+
15+
impl super::super::sealed::Dsb for SY {
16+
#[inline(always)]
17+
unsafe fn __dsb(&self) {
18+
asm!("mcr p15, 0, r0, c7, c10, 4" : : : "memory" : "volatile")
19+
}
20+
}
21+
22+
impl super::super::sealed::Isb for SY {
23+
#[inline(always)]
24+
unsafe fn __isb(&self) {
25+
asm!("mcr p15, 0, r0, c7, c5, 4" : : : "memory" : "volatile")
26+
}
27+
}

crates/core_arch/src/acle/barrier/mod.rs

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,66 @@
11
// Reference: Section 7.4 "Hints" of ACLE
22

3+
// CP15 instruction
4+
#[cfg(not(any(
5+
// v8
6+
target_arch = "aarch64",
7+
// v7
8+
target_feature = "v7",
9+
// v6-M
10+
target_feature = "mclass"
11+
)))]
12+
mod cp15;
13+
14+
#[cfg(not(any(
15+
target_arch = "aarch64",
16+
target_feature = "v7",
17+
target_feature = "mclass"
18+
)))]
19+
pub use self::cp15::*;
20+
21+
// Dedicated instructions
322
macro_rules! dmb_dsb {
423
($A:ident) => {
524
impl super::super::sealed::Dmb for $A {
625
#[inline(always)]
726
unsafe fn __dmb(&self) {
8-
asm!(concat!("DMB ", stringify!($A)) : : : "memory" : "volatile")
27+
super::dmb(super::arg::$A)
928
}
1029
}
1130

1231
impl super::super::sealed::Dsb for $A {
1332
#[inline(always)]
1433
unsafe fn __dsb(&self) {
15-
asm!(concat!("DSB ", stringify!($A)) : : : "memory" : "volatile")
34+
super::dsb(super::arg::$A)
1635
}
1736
}
1837
};
1938
}
2039

40+
#[cfg(any(
41+
target_arch = "aarch64",
42+
target_feature = "v7",
43+
target_feature = "mclass"
44+
))]
2145
mod common;
2246

47+
#[cfg(any(
48+
target_arch = "aarch64",
49+
target_feature = "v7",
50+
target_feature = "mclass"
51+
))]
2352
pub use self::common::*;
2453

25-
#[cfg(not(target_feature = "mclass"))]
54+
#[cfg(any(
55+
target_arch = "aarch64",
56+
target_feature = "v7",
57+
))]
2658
mod not_mclass;
2759

28-
#[cfg(not(target_feature = "mclass"))]
60+
#[cfg(any(
61+
target_arch = "aarch64",
62+
target_feature = "v7",
63+
))]
2964
pub use self::not_mclass::*;
3065

3166
#[cfg(target_arch = "aarch64")]
@@ -87,3 +122,34 @@ where
87122
{
88123
arg.__isb()
89124
}
125+
126+
extern "C" {
127+
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.dmb")]
128+
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.dmb")]
129+
fn dmb(_: i32);
130+
131+
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.dsb")]
132+
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.dsb")]
133+
fn dsb(_: i32);
134+
135+
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.isb")]
136+
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.isb")]
137+
fn isb(_: i32);
138+
}
139+
140+
// we put these in a module to prevent weirdness with glob re-exports
141+
mod arg {
142+
// See Section 7.3 Memory barriers of ACLE
143+
pub const SY: i32 = 15;
144+
pub const ST: i32 = 14;
145+
pub const LD: i32 = 13;
146+
pub const ISH: i32 = 11;
147+
pub const ISHST: i32 = 10;
148+
pub const ISHLD: i32 = 9;
149+
pub const NSH: i32 = 7;
150+
pub const NSHST: i32 = 6;
151+
pub const NSHLD: i32 = 5;
152+
pub const OSH: i32 = 3;
153+
pub const OSHST: i32 = 2;
154+
pub const OSHLD: i32 = 1;
155+
}

crates/core_arch/src/acle/mod.rs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,8 @@
3737
//!
3838
//! - [ACLE Q2 2018](https://developer.arm.com/docs/101028/latest)
3939
40-
// Supported arches: 8, 7, 6-M. See Section 10.1 of ACLE (e.g. DMB)
41-
// But this is further refined within the module
42-
#[cfg(any(
43-
// v8
44-
target_arch = "aarch64",
45-
// v7
46-
target_feature = "v7",
47-
// v6-M
48-
target_feature = "mclass"
49-
))]
40+
// 8, 7 and 6-M are supported via dedicated instructions like DMB. All other arches are supported
41+
// via CP15 instructions. See Section 10.1 of ACLE
5042
mod barrier;
5143

5244
#[cfg(any(

0 commit comments

Comments
 (0)