core/stdarch/crates/core_arch/src/arm_shared/
hints.rs

1// # References
2//
3// - Section 7.4 "Hints" of ACLE
4// - Section 7.7 "NOP" of ACLE
5
6/// Generates a WFI (wait for interrupt) hint instruction, or nothing.
7///
8/// The WFI instruction allows (but does not require) the processor to enter a
9/// low-power state until one of a number of asynchronous events occurs.
10// Section 10.1 of ACLE says that the supported arches are: 8, 6K, 6-M
11// LLVM says "instruction requires: armv6k"
12#[cfg(any(
13    target_feature = "v6",
14    target_arch = "aarch64",
15    target_arch = "arm64ec",
16    doc
17))]
18#[inline(always)]
19#[unstable(feature = "stdarch_arm_hints", issue = "117218")]
20pub unsafe fn __wfi() {
21    hint(HINT_WFI);
22}
23
24/// Generates a WFE (wait for event) hint instruction, or nothing.
25///
26/// The WFE instruction allows (but does not require) the processor to enter a
27/// low-power state until some event occurs such as a SEV being issued by
28/// another processor.
29// Section 10.1 of ACLE says that the supported arches are: 8, 6K, 6-M
30// LLVM says "instruction requires: armv6k"
31#[cfg(any(
32    target_feature = "v6",
33    target_arch = "aarch64",
34    target_arch = "arm64ec",
35    doc
36))]
37#[inline(always)]
38#[unstable(feature = "stdarch_arm_hints", issue = "117218")]
39pub unsafe fn __wfe() {
40    hint(HINT_WFE);
41}
42
43/// Generates a SEV (send a global event) hint instruction.
44///
45/// This causes an event to be signaled to all processors in a multiprocessor
46/// system. It is a NOP on a uniprocessor system.
47// Section 10.1 of ACLE says that the supported arches are: 8, 6K, 6-M, 7-M
48// LLVM says "instruction requires: armv6k"
49#[cfg(any(
50    target_feature = "v6",
51    target_arch = "aarch64",
52    target_arch = "arm64ec",
53    doc
54))]
55#[inline(always)]
56#[unstable(feature = "stdarch_arm_hints", issue = "117218")]
57pub unsafe fn __sev() {
58    hint(HINT_SEV);
59}
60
61/// Generates a send a local event hint instruction.
62///
63/// This causes an event to be signaled to only the processor executing this
64/// instruction. In a multiprocessor system, it is not required to affect the
65/// other processors.
66// LLVM says "instruction requires: armv8"
67#[cfg(any(
68    target_feature = "v8", // 32-bit ARMv8
69    target_arch = "aarch64", // AArch64
70    target_arch = "arm64ec", // Arm64EC
71    doc,
72))]
73#[inline(always)]
74#[unstable(feature = "stdarch_arm_hints", issue = "117218")]
75pub unsafe fn __sevl() {
76    hint(HINT_SEVL);
77}
78
79/// Generates a YIELD hint instruction.
80///
81/// This enables multithreading software to indicate to the hardware that it is
82/// performing a task, for example a spin-lock, that could be swapped out to
83/// improve overall system performance.
84// Section 10.1 of ACLE says that the supported arches are: 8, 6K, 6-M
85// LLVM says "instruction requires: armv6k"
86#[cfg(any(
87    target_feature = "v6",
88    target_arch = "aarch64",
89    target_arch = "arm64ec",
90    doc
91))]
92#[inline(always)]
93#[unstable(feature = "stdarch_arm_hints", issue = "117218")]
94pub unsafe fn __yield() {
95    hint(HINT_YIELD);
96}
97
98/// Generates an unspecified no-op instruction.
99///
100/// Note that not all architectures provide a distinguished NOP instruction. On
101/// those that do, it is unspecified whether this intrinsic generates it or
102/// another instruction. It is not guaranteed that inserting this instruction
103/// will increase execution time.
104#[inline(always)]
105#[unstable(feature = "stdarch_arm_hints", issue = "117218")]
106pub unsafe fn __nop() {
107    crate::arch::asm!("nop", options(nomem, nostack, preserves_flags));
108}
109
110unsafe extern "unadjusted" {
111    #[cfg_attr(
112        any(target_arch = "aarch64", target_arch = "arm64ec"),
113        link_name = "llvm.aarch64.hint"
114    )]
115    #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.hint")]
116    fn hint(_: i32);
117}
118
119// from LLVM 7.0.1's lib/Target/ARM/{ARMInstrThumb,ARMInstrInfo,ARMInstrThumb2}.td
120const HINT_NOP: i32 = 0;
121const HINT_YIELD: i32 = 1;
122const HINT_WFE: i32 = 2;
123const HINT_WFI: i32 = 3;
124const HINT_SEV: i32 = 4;
125const HINT_SEVL: i32 = 5;