| // # References |
| // |
| // - Section 7.4 "Hints" of ACLE |
| // - Section 7.7 "NOP" of ACLE |
| |
| /// Generates a WFI (wait for interrupt) hint instruction, or nothing. |
| /// |
| /// The WFI instruction allows (but does not require) the processor to enter a |
| /// low-power state until one of a number of asynchronous events occurs. |
| // Section 10.1 of ACLE says that the supported arches are: 8, 6K, 6-M |
| // LLVM says "instruction requires: armv6k" |
| #[cfg(any(target_feature = "v6", target_arch = "aarch64", doc))] |
| #[inline(always)] |
| pub unsafe fn __wfi() { |
| hint(HINT_WFI); |
| } |
| |
| /// Generates a WFE (wait for event) hint instruction, or nothing. |
| /// |
| /// The WFE instruction allows (but does not require) the processor to enter a |
| /// low-power state until some event occurs such as a SEV being issued by |
| /// another processor. |
| // Section 10.1 of ACLE says that the supported arches are: 8, 6K, 6-M |
| // LLVM says "instruction requires: armv6k" |
| #[cfg(any(target_feature = "v6", target_arch = "aarch64", doc))] |
| #[inline(always)] |
| pub unsafe fn __wfe() { |
| hint(HINT_WFE); |
| } |
| |
| /// Generates a SEV (send a global event) hint instruction. |
| /// |
| /// This causes an event to be signaled to all processors in a multiprocessor |
| /// system. It is a NOP on a uniprocessor system. |
| // Section 10.1 of ACLE says that the supported arches are: 8, 6K, 6-M, 7-M |
| // LLVM says "instruction requires: armv6k" |
| #[cfg(any(target_feature = "v6", target_arch = "aarch64", doc))] |
| #[inline(always)] |
| pub unsafe fn __sev() { |
| hint(HINT_SEV); |
| } |
| |
| /// Generates a send a local event hint instruction. |
| /// |
| /// This causes an event to be signaled to only the processor executing this |
| /// instruction. In a multiprocessor system, it is not required to affect the |
| /// other processors. |
| // LLVM says "instruction requires: armv8" |
| #[cfg(any( |
| target_feature = "v8", // 32-bit ARMv8 |
| target_arch = "aarch64", // AArch64 |
| doc, |
| ))] |
| #[inline(always)] |
| pub unsafe fn __sevl() { |
| hint(HINT_SEVL); |
| } |
| |
| /// Generates a YIELD hint instruction. |
| /// |
| /// This enables multithreading software to indicate to the hardware that it is |
| /// performing a task, for example a spin-lock, that could be swapped out to |
| /// improve overall system performance. |
| // Section 10.1 of ACLE says that the supported arches are: 8, 6K, 6-M |
| // LLVM says "instruction requires: armv6k" |
| #[cfg(any(target_feature = "v6", target_arch = "aarch64", doc))] |
| #[inline(always)] |
| pub unsafe fn __yield() { |
| hint(HINT_YIELD); |
| } |
| |
| /// Generates an unspecified no-op instruction. |
| /// |
| /// Note that not all architectures provide a distinguished NOP instruction. On |
| /// those that do, it is unspecified whether this intrinsic generates it or |
| /// another instruction. It is not guaranteed that inserting this instruction |
| /// will increase execution time. |
| #[inline(always)] |
| pub unsafe fn __nop() { |
| crate::arch::asm!("nop", options(nomem, nostack, preserves_flags)); |
| } |
| |
| extern "unadjusted" { |
| #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.hint")] |
| #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.hint")] |
| fn hint(_: i32); |
| } |
| |
| // from LLVM 7.0.1's lib/Target/ARM/{ARMInstrThumb,ARMInstrInfo,ARMInstrThumb2}.td |
| const HINT_NOP: i32 = 0; |
| const HINT_YIELD: i32 = 1; |
| const HINT_WFE: i32 = 2; |
| const HINT_WFI: i32 = 3; |
| const HINT_SEV: i32 = 4; |
| const HINT_SEVL: i32 = 5; |