core/stdarch/crates/core_arch/src/arm_shared/barrier/
mod.rs

1// Reference: Section 7.4 "Hints" of ACLE
2
3// CP15 instruction
4#[cfg(not(any(
5    // v8
6    target_arch = "aarch64",
7    target_arch = "arm64ec",
8    // v7
9    target_feature = "v7",
10    // v6-M
11    target_feature = "mclass"
12)))]
13mod cp15;
14
15#[cfg(not(any(
16    target_arch = "aarch64",
17    target_arch = "arm64ec",
18    target_feature = "v7",
19    target_feature = "mclass"
20)))]
21#[unstable(feature = "stdarch_arm_barrier", issue = "117219")]
22pub use self::cp15::*;
23
24// Dedicated instructions
25#[cfg(any(
26    target_arch = "aarch64",
27    target_arch = "arm64ec",
28    target_feature = "v7",
29    target_feature = "mclass"
30))]
31macro_rules! dmb_dsb {
32    ($A:ident) => {
33        #[unstable(feature = "stdarch_arm_barrier", issue = "117219")]
34        impl super::super::sealed::Dmb for $A {
35            #[inline(always)]
36            unsafe fn __dmb(&self) {
37                super::dmb(super::arg::$A)
38            }
39        }
40
41        #[unstable(feature = "stdarch_arm_barrier", issue = "117219")]
42        impl super::super::sealed::Dsb for $A {
43            #[inline(always)]
44            unsafe fn __dsb(&self) {
45                super::dsb(super::arg::$A)
46            }
47        }
48    };
49}
50
51#[cfg(any(
52    target_arch = "aarch64",
53    target_arch = "arm64ec",
54    target_feature = "v7",
55    target_feature = "mclass"
56))]
57mod common;
58
59#[cfg(any(
60    target_arch = "aarch64",
61    target_arch = "arm64ec",
62    target_feature = "v7",
63    target_feature = "mclass"
64))]
65#[unstable(feature = "stdarch_arm_barrier", issue = "117219")]
66pub use self::common::*;
67
68#[cfg(any(
69    target_arch = "aarch64",
70    target_arch = "arm64ec",
71    target_feature = "v7",
72))]
73mod not_mclass;
74
75#[cfg(any(
76    target_arch = "aarch64",
77    target_arch = "arm64ec",
78    target_feature = "v7",
79))]
80#[unstable(feature = "stdarch_arm_barrier", issue = "117219")]
81pub use self::not_mclass::*;
82
83#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))]
84mod v8;
85
86#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))]
87#[unstable(feature = "stdarch_arm_barrier", issue = "117219")]
88pub use self::v8::*;
89
90/// Generates a DMB (data memory barrier) instruction or equivalent CP15 instruction.
91///
92/// DMB ensures the observed ordering of memory accesses. Memory accesses of the specified type
93/// issued before the DMB are guaranteed to be observed (in the specified scope) before memory
94/// accesses issued after the DMB.
95///
96/// For example, DMB should be used between storing data, and updating a flag variable that makes
97/// that data available to another core.
98///
99/// The __dmb() intrinsic also acts as a compiler memory barrier of the appropriate type.
100#[inline(always)]
101#[unstable(feature = "stdarch_arm_barrier", issue = "117219")]
102pub unsafe fn __dmb<A>(arg: A)
103where
104    A: super::sealed::Dmb,
105{
106    arg.__dmb()
107}
108
109/// Generates a DSB (data synchronization barrier) instruction or equivalent CP15 instruction.
110///
111/// DSB ensures the completion of memory accesses. A DSB behaves as the equivalent DMB and has
112/// additional properties. After a DSB instruction completes, all memory accesses of the specified
113/// type issued before the DSB are guaranteed to have completed.
114///
115/// The __dsb() intrinsic also acts as a compiler memory barrier of the appropriate type.
116#[inline(always)]
117#[unstable(feature = "stdarch_arm_barrier", issue = "117219")]
118pub unsafe fn __dsb<A>(arg: A)
119where
120    A: super::sealed::Dsb,
121{
122    arg.__dsb()
123}
124
125/// Generates an ISB (instruction synchronization barrier) instruction or equivalent CP15
126/// instruction.
127///
128/// This instruction flushes the processor pipeline fetch buffers, so that following instructions
129/// are fetched from cache or memory.
130///
131/// An ISB is needed after some system maintenance operations. An ISB is also needed before
132/// transferring control to code that has been loaded or modified in memory, for example by an
133/// overlay mechanism or just-in-time code generator.  (Note that if instruction and data caches are
134/// separate, privileged cache maintenance operations would be needed in order to unify the caches.)
135///
136/// The only supported argument for the __isb() intrinsic is 15, corresponding to the SY (full
137/// system) scope of the ISB instruction.
138#[inline(always)]
139#[unstable(feature = "stdarch_arm_barrier", issue = "117219")]
140pub unsafe fn __isb<A>(arg: A)
141where
142    A: super::sealed::Isb,
143{
144    arg.__isb()
145}
146
147extern "unadjusted" {
148    #[cfg_attr(
149        any(target_arch = "aarch64", target_arch = "arm64ec"),
150        link_name = "llvm.aarch64.dmb"
151    )]
152    #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.dmb")]
153    fn dmb(_: i32);
154
155    #[cfg_attr(
156        any(target_arch = "aarch64", target_arch = "arm64ec"),
157        link_name = "llvm.aarch64.dsb"
158    )]
159    #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.dsb")]
160    fn dsb(_: i32);
161
162    #[cfg_attr(
163        any(target_arch = "aarch64", target_arch = "arm64ec"),
164        link_name = "llvm.aarch64.isb"
165    )]
166    #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.isb")]
167    fn isb(_: i32);
168}
169
170// we put these in a module to prevent weirdness with glob re-exports
171mod arg {
172    // See Section 7.3  Memory barriers of ACLE
173    pub const SY: i32 = 15;
174    pub const ST: i32 = 14;
175    pub const LD: i32 = 13;
176    pub const ISH: i32 = 11;
177    pub const ISHST: i32 = 10;
178    pub const ISHLD: i32 = 9;
179    pub const NSH: i32 = 7;
180    pub const NSHST: i32 = 6;
181    pub const NSHLD: i32 = 5;
182    pub const OSH: i32 = 3;
183    pub const OSHST: i32 = 2;
184    pub const OSHLD: i32 = 1;
185}