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:
parent
240468f652
commit
627bcddb4f
4 changed files with 100 additions and 15 deletions
|
|
@ -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
library/stdarch/crates/core_arch/src/acle/barrier/cp15.rs
Normal file
27
library/stdarch/crates/core_arch/src/acle/barrier/cp15.rs
Normal 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")
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue