From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- .../crates/core_arch/src/arm_shared/barrier/mod.rs | 154 +++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 library/stdarch/crates/core_arch/src/arm_shared/barrier/mod.rs (limited to 'library/stdarch/crates/core_arch/src/arm_shared/barrier/mod.rs') diff --git a/library/stdarch/crates/core_arch/src/arm_shared/barrier/mod.rs b/library/stdarch/crates/core_arch/src/arm_shared/barrier/mod.rs new file mode 100644 index 000000000..6ccced00e --- /dev/null +++ b/library/stdarch/crates/core_arch/src/arm_shared/barrier/mod.rs @@ -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(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(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(arg: A) +where + A: super::sealed::Isb, +{ + arg.__isb() +} + +extern "unadjusted" { + #[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; +} -- cgit v1.2.3