Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove cmsis module; add acle module #557

Merged
merged 31 commits into from
Feb 18, 2019
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
066eba0
remove cmsis module; add acle module
japaric Sep 3, 2018
342786c
fix relative import
japaric Sep 3, 2018
503f9f7
add missing import
japaric Sep 3, 2018
b077652
acle::hints: use llvm.{arm,aarch64.hint}
japaric Feb 13, 2019
b6672dd
acle/hints: __dbg requires 'v7'
japaric Feb 13, 2019
5422324
acle/hints: use asm! for __nop
japaric Feb 13, 2019
5973346
acle/hints: most hints require 'v6' rather than 'v6k'
japaric Feb 13, 2019
b3f0f28
acle/simd32: also expose on the A profile
japaric Feb 13, 2019
25961be
acle/dsp: make available on the A profile
japaric Feb 13, 2019
74ddada
acle/barrier: use llvm.{arm,aarch64}.{dmb,dsb,isb} instead of asm!
japaric Feb 13, 2019
d91daff
acle/{simd32,dsp}: not available on aarch64
japaric Feb 13, 2019
0d81519
acle: move saturating intrinsics into its own module
japaric Feb 13, 2019
50b5126
acle/hints: gate sevl on 'v8' rather than on 'aarch64'
japaric Feb 14, 2019
b14287e
acle/barrier: remove cfg from re-export
japaric Feb 14, 2019
81ad620
acle/dsp: update comment
japaric Feb 14, 2019
fa0deb3
acle/dsp: note the difference between LLVM's +dsp and ACLE's __ARM_FE…
japaric Feb 14, 2019
b3822ef
acle: add ldrex, clrex and strex
japaric Feb 14, 2019
e67cf23
acle/docs: add armv8-m and armv8-r to the list of rustc targets & llv…
japaric Feb 14, 2019
53f320e
acle/hints: make sevl truly available on aarch64
japaric Feb 14, 2019
cbfd8d0
acle: move arm/dsp into acle/{dsp,simd32}
japaric Feb 14, 2019
4cb6d8c
acle/ex: fix raw pointer mutability
japaric Feb 15, 2019
f73e69f
cargo fmt
japaric Feb 15, 2019
c2e2edd
add missing imports
japaric Feb 15, 2019
f8ecff9
conditionally declare the dmb_dsb macro
japaric Feb 15, 2019
b4836bf
acle/{dsp,simd32}: add leading underscores to match ACLE spec
japaric Feb 18, 2019
660ead1
fix CI
japaric Feb 18, 2019
608fdd7
Update crates/core_arch/src/acle/simd32.rs
mati865 Feb 18, 2019
3a30a06
acle/ex: CLREX requires v6k
japaric Feb 18, 2019
f3d8449
acle/{dsp,simd32}: fix unit tests
japaric Feb 18, 2019
9d1bb44
assert_instr: bump instruction limit for simd32
japaric Feb 18, 2019
a36e20e
cargo fmt
japaric Feb 18, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions crates/core_arch/src/aarch64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ pub use self::crypto::*;
mod crc;
pub use self::crc::*;

pub use super::acle::*;

#[cfg(test)]
use stdsimd_test::assert_instr;

Expand Down
14 changes: 14 additions & 0 deletions crates/core_arch/src/acle/barrier/common.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//! Access types available on all architectures

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

dmb_dsb!(SY);

impl super::super::sealed::Isb for SY {
#[inline(always)]
unsafe fn __isb(&self) {
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")
}
}
154 changes: 154 additions & 0 deletions crates/core_arch/src/acle/barrier/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
// 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
#[cfg(any(
target_arch = "aarch64",
target_feature = "v7",
target_feature = "mclass"
))]
macro_rules! dmb_dsb {
($A:ident) => {
impl super::super::sealed::Dmb for $A {
#[inline(always)]
unsafe fn __dmb(&self) {
super::dmb(super::arg::$A)
}
}

impl super::super::sealed::Dsb for $A {
#[inline(always)]
unsafe fn __dsb(&self) {
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(any(target_arch = "aarch64", target_feature = "v7",))]
mod not_mclass;

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

#[cfg(target_arch = "aarch64")]
mod v8;

#[cfg(target_arch = "aarch64")]
pub use self::v8::*;

/// Generates a DMB (data memory barrier) instruction or equivalent CP15 instruction.
///
/// DMB ensures the observed ordering of memory accesses. Memory accesses of the specified type
/// issued before the DMB are guaranteed to be observed (in the specified scope) before memory
/// accesses issued after the DMB.
///
/// For example, DMB should be used between storing data, and updating a flag variable that makes
/// that data available to another core.
///
/// The __dmb() intrinsic also acts as a compiler memory barrier of the appropriate type.
#[inline(always)]
pub unsafe fn __dmb<A>(arg: A)
where
A: super::sealed::Dmb,
{
arg.__dmb()
}

/// Generates a DSB (data synchronization barrier) instruction or equivalent CP15 instruction.
///
/// DSB ensures the completion of memory accesses. A DSB behaves as the equivalent DMB and has
/// additional properties. After a DSB instruction completes, all memory accesses of the specified
/// type issued before the DSB are guaranteed to have completed.
///
/// The __dsb() intrinsic also acts as a compiler memory barrier of the appropriate type.
#[inline(always)]
pub unsafe fn __dsb<A>(arg: A)
where
A: super::sealed::Dsb,
{
arg.__dsb()
}

/// Generates an ISB (instruction synchronization barrier) instruction or equivalent CP15
/// instruction.
///
/// This instruction flushes the processor pipeline fetch buffers, so that following instructions
/// are fetched from cache or memory.
///
/// An ISB is needed after some system maintenance operations. An ISB is also needed before
/// transferring control to code that has been loaded or modified in memory, for example by an
/// overlay mechanism or just-in-time code generator. (Note that if instruction and data caches are
/// separate, privileged cache maintenance operations would be needed in order to unify the caches.)
///
/// The only supported argument for the __isb() intrinsic is 15, corresponding to the SY (full
/// system) scope of the ISB instruction.
#[inline(always)]
pub unsafe fn __isb<A>(arg: A)
where
A: super::sealed::Isb,
{
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;
}
43 changes: 43 additions & 0 deletions crates/core_arch/src/acle/barrier/not_mclass.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//! Access types available on v7 and v8 but not on v7(E)-M or v8-M

/// Full system is the required shareability domain, writes are the required
/// access type
pub struct ST;

dmb_dsb!(ST);

/// Inner Shareable is the required shareability domain, reads and writes are
/// the required access types
pub struct ISH;

dmb_dsb!(ISH);

/// Inner Shareable is the required shareability domain, writes are the required
/// access type
pub struct ISHST;

dmb_dsb!(ISHST);

/// Non-shareable is the required shareability domain, reads and writes are the
/// required access types
pub struct NSH;

dmb_dsb!(NSH);

/// Non-shareable is the required shareability domain, writes are the required
/// access type
pub struct NSHST;

dmb_dsb!(NSHST);

/// Outer Shareable is the required shareability domain, reads and writes are
/// the required access types
pub struct OSH;

dmb_dsb!(OSH);

/// Outer Shareable is the required shareability domain, writes are the required
/// access type
pub struct OSHST;

dmb_dsb!(OSHST);
23 changes: 23 additions & 0 deletions crates/core_arch/src/acle/barrier/v8.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/// Full system is the required shareability domain, reads are the required
/// access type
pub struct LD;

dmb_dsb!(LD);

/// Inner Shareable is the required shareability domain, reads are the required
/// access type
pub struct ISHLD;

dmb_dsb!(ISHLD);

/// Non-shareable is the required shareability domain, reads are the required
/// access type
pub struct NSHLD;

dmb_dsb!(NSHLD);

/// Outher Shareable is the required shareability domain, reads are the required
/// access type
pub struct OSHLD;

dmb_dsb!(OSHLD);
51 changes: 51 additions & 0 deletions crates/core_arch/src/acle/dsp.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//! # References:
//!
//! - Section 8.3 "16-bit multiplications"
//!
//! Intrinsics that could live here:
//!
//! - [ ] __smulbb
//! - [ ] __smulbt
//! - [ ] __smultb
//! - [ ] __smultt
//! - [ ] __smulwb
//! - [ ] __smulwt
//! - [x] __qadd
//! - [x] __qsub
//! - [ ] __qdbl
//! - [ ] __smlabb
//! - [ ] __smlabt
//! - [ ] __smlatb
//! - [ ] __smlatt
//! - [ ] __smlawb
//! - [ ] __smlawt

#[cfg(test)]
use stdsimd_test::assert_instr;

extern "C" {
#[link_name = "llvm.arm.qadd"]
fn arm_qadd(a: i32, b: i32) -> i32;

#[link_name = "llvm.arm.qsub"]
fn arm_qsub(a: i32, b: i32) -> i32;

}

/// Signed saturating addition
///
/// Returns the 32-bit saturating signed equivalent of a + b.
#[inline]
#[cfg_attr(test, assert_instr(qadd))]
pub unsafe fn __qadd(a: i32, b: i32) -> i32 {
arm_qadd(a, b)
}

/// Signed saturating subtraction
///
/// Returns the 32-bit saturating signed equivalent of a - b.
#[inline]
#[cfg_attr(test, assert_instr(qsub))]
pub unsafe fn __qsub(a: i32, b: i32) -> i32 {
arm_qsub(a, b)
}
Loading