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 https://github.com/rust-lang-nursery/stdsimd/pull/557#discussion_r255312214
This commit is contained in:
Jorge Aparicio 2019-02-13 19:45:27 +01:00 committed by gnzlbg
parent 240468f652
commit 627bcddb4f
4 changed files with 100 additions and 15 deletions

View file

@ -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)
}
}

View file

@ -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")
}
}

View file

@ -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")]
@ -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;
}

View file

@ -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(