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;