1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
// # References
//
// - ACLE 第 7.4 节 "Hints" 部分
// - ACLE 第 7.7 节 "NOP" 部分
/// 生成 WFI (等待中断) 提示指令,或不执行任何操作。
///
/// WFI 指令允许 (但不要求) 处理器进入低功耗状态,直到发生许多异步事件之一。
///
// ACLE 的 10.1 部分说受支持的 arches 是: 8、6K,6-M LLVM 说 "instruction requires: armv6k"
//
#[cfg(any(target_feature = "v6", target_arch = "aarch64", doc))]
#[inline(always)]
pub unsafe fn __wfi() {
hint(HINT_WFI);
}
/// 生成 WFE (等待事件) 提示指令,否则不生成任何内容。
///
/// WFE 指令允许 (但不要求) 处理器进入低功耗状态,直到发生某些事件 (例如,另一处理器发出 SEV)。
///
///
// ACLE 的 10.1 部分说受支持的 arches 是: 8、6K,6-M LLVM 说 "instruction requires: armv6k"
//
#[cfg(any(target_feature = "v6", target_arch = "aarch64", doc))]
#[inline(always)]
pub unsafe fn __wfe() {
hint(HINT_WFE);
}
/// 生成 SEV (发送事件) 提示指令。
///
/// 这导致事件被发送到多处理器系统中的所有处理器。
/// 它是单处理器系统上的 NOP。
// ACLE 的 10.1 部分说受支持的 arches 是: 8,6K,6-M,7-M LLVM 说 "instruction requires: armv6k"
//
#[cfg(any(target_feature = "v6", target_arch = "aarch64", doc))]
#[inline(always)]
pub unsafe fn __sev() {
hint(HINT_SEV);
}
/// 生成发送本地事件提示指令。
///
/// 这导致仅将信号通知执行该指令的处理器。
/// 在多处理器系统中,不需要影响其他处理器。
///
// LLVM 说 "指令要求: armv8"
#[cfg(any(
target_feature = "v8", // 32 位 ARMv8
target_arch = "aarch64", // AArch64
doc,
))]
#[inline(always)]
pub unsafe fn __sevl() {
hint(HINT_SEVL);
}
/// 生成一条 YIELD 提示指令。
///
/// 这使多线程软件能够向硬件指示其正在执行任务 (例如自旋锁),可以将其换出以提高整体系统性能。
///
///
// ACLE 的 10.1 部分说受支持的 arches 是: 8、6K,6-M LLVM 说 "instruction requires: armv6k"
//
#[cfg(any(target_feature = "v6", target_arch = "aarch64", doc))]
#[inline(always)]
pub unsafe fn __yield() {
hint(HINT_YIELD);
}
/// 生成未指定的无操作指令。
///
/// 请注意,并非所有体系结构都提供专有的 NOP 指令。
/// 在执行此操作的对象上,不确定此内部函数是生成它还是其他指令。
///
/// 不保证插入该指令会增加执行时间。
#[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);
}
// 来自 LLVM 7.0.1 的 lib/Target/ 分支 /{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;