Skip to content

Commit

Permalink
acle/barrier: use llvm.{arm,aarch64}.{dmb,dsb,isb} instead of asm!
Browse files Browse the repository at this point in the history
also make these available on architectures that don't have a dedicated DMB / DSB
/ ISB instruction

addresses #557 (comment)
  • Loading branch information
japaric authored and gnzlbg committed Feb 18, 2019
1 parent 52d32dd commit 7af0a08
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 15 deletions.
2 changes: 1 addition & 1 deletion crates/core_arch/src/acle/barrier/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ dmb_dsb!(SY);
impl super::super::sealed::Isb for SY {
#[inline(always)]
unsafe fn __isb(&self) {
asm!("ISB SY" : : : "memory" : "volatile")
super::isb(super::arg::SY)
}
}
27 changes: 27 additions & 0 deletions crates/core_arch/src/acle/barrier/cp15.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Reference: ARM11 MPCore Processor Technical Reference Manual (ARM DDI 0360E) Section 3.5 "Summary
// of CP15 instructions"

/// Full system is the required shareability domain, reads and writes are the
/// required access types
pub struct SY;

impl super::super::sealed::Dmb for SY {
#[inline(always)]
unsafe fn __dmb(&self) {
asm!("mcr p15, 0, r0, c7, c10, 5" : : : "memory" : "volatile")
}
}

impl super::super::sealed::Dsb for SY {
#[inline(always)]
unsafe fn __dsb(&self) {
asm!("mcr p15, 0, r0, c7, c10, 4" : : : "memory" : "volatile")
}
}

impl super::super::sealed::Isb for SY {
#[inline(always)]
unsafe fn __isb(&self) {
asm!("mcr p15, 0, r0, c7, c5, 4" : : : "memory" : "volatile")
}
}
74 changes: 70 additions & 4 deletions crates/core_arch/src/acle/barrier/mod.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,66 @@
// Reference: Section 7.4 "Hints" of ACLE

// CP15 instruction
#[cfg(not(any(
// v8
target_arch = "aarch64",
// v7
target_feature = "v7",
// v6-M
target_feature = "mclass"
)))]
mod cp15;

#[cfg(not(any(
target_arch = "aarch64",
target_feature = "v7",
target_feature = "mclass"
)))]
pub use self::cp15::*;

// Dedicated instructions
macro_rules! dmb_dsb {
($A:ident) => {
impl super::super::sealed::Dmb for $A {
#[inline(always)]
unsafe fn __dmb(&self) {
asm!(concat!("DMB ", stringify!($A)) : : : "memory" : "volatile")
super::dmb(super::arg::$A)
}
}

impl super::super::sealed::Dsb for $A {
#[inline(always)]
unsafe fn __dsb(&self) {
asm!(concat!("DSB ", stringify!($A)) : : : "memory" : "volatile")
super::dsb(super::arg::$A)
}
}
};
}

#[cfg(any(
target_arch = "aarch64",
target_feature = "v7",
target_feature = "mclass"
))]
mod common;

#[cfg(any(
target_arch = "aarch64",
target_feature = "v7",
target_feature = "mclass"
))]
pub use self::common::*;

#[cfg(not(target_feature = "mclass"))]
#[cfg(any(
target_arch = "aarch64",
target_feature = "v7",
))]
mod not_mclass;

#[cfg(not(target_feature = "mclass"))]
#[cfg(any(
target_arch = "aarch64",
target_feature = "v7",
))]
pub use self::not_mclass::*;

#[cfg(target_arch = "aarch64")]
Expand Down Expand Up @@ -87,3 +122,34 @@ where
{
arg.__isb()
}

extern "C" {
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.dmb")]
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.dmb")]
fn dmb(_: i32);

#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.dsb")]
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.dsb")]
fn dsb(_: i32);

#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.isb")]
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.isb")]
fn isb(_: i32);
}

// we put these in a module to prevent weirdness with glob re-exports
mod arg {
// See Section 7.3 Memory barriers of ACLE
pub const SY: i32 = 15;
pub const ST: i32 = 14;
pub const LD: i32 = 13;
pub const ISH: i32 = 11;
pub const ISHST: i32 = 10;
pub const ISHLD: i32 = 9;
pub const NSH: i32 = 7;
pub const NSHST: i32 = 6;
pub const NSHLD: i32 = 5;
pub const OSH: i32 = 3;
pub const OSHST: i32 = 2;
pub const OSHLD: i32 = 1;
}
12 changes: 2 additions & 10 deletions crates/core_arch/src/acle/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,8 @@
//!
//! - [ACLE Q2 2018](https://developer.arm.com/docs/101028/latest)

// Supported arches: 8, 7, 6-M. See Section 10.1 of ACLE (e.g. DMB)
// But this is further refined within the module
#[cfg(any(
// v8
target_arch = "aarch64",
// v7
target_feature = "v7",
// v6-M
target_feature = "mclass"
))]
// 8, 7 and 6-M are supported via dedicated instructions like DMB. All other arches are supported
// via CP15 instructions. See Section 10.1 of ACLE
mod barrier;

#[cfg(any(
Expand Down

0 comments on commit 7af0a08

Please sign in to comment.