Skip to content

Commit a22087c

Browse files
committed
Implementation for Aarch64 TME intrinsics
1 parent ec6fccd commit a22087c

File tree

3 files changed

+128
-0
lines changed

3 files changed

+128
-0
lines changed

crates/core_arch/src/aarch64/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ pub use self::neon::*;
1515
mod crypto;
1616
pub use self::crypto::*;
1717

18+
mod tme;
19+
pub use self::tme::*;
20+
1821
mod crc;
1922
pub use self::crc::*;
2023

crates/core_arch/src/aarch64/tme.rs

+124
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
//! ARM's Transactional Memory Extensions (TME).
2+
//!
3+
//! This CPU feature is available on Aarch64 – ARMv8-A arch. onwards.
4+
//! This feature is in the non-neon feature set. TME specific vendor documentation can
5+
//! be found [TME Intrinsics Introduction][tme_intrinsics_intro].
6+
//!
7+
//! The reference is [ACLE Q4 2019][acle_q4_2019_ref].
8+
//!
9+
//! ACLE has a section for TME extensions and state masks for aborts and failure codes.
10+
//! In addition to that [LLVM Aarch64 Intrinsics][llvm_aarch64_int] are
11+
//! self explanatory for what needs to be exported.
12+
//!
13+
//! [acle_q4_2019_ref]: https://static.docs.arm.com/101028/0010/ACLE_2019Q4_release-0010.pdf
14+
//! [tme_intrinsics_intro]: https://developer.arm.com/docs/101028/0010/transactional-memory-extension-tme-intrinsics
15+
//! [llvm_aarch64_int]: https://github.com/llvm/llvm-project/commit/a36d31478c182903523e04eb271bbf102bfab2cc#diff-ff24e1c35f4d54f1110ce5d90c709319R626-R646
16+
17+
#[cfg(test)]
18+
use stdarch_test::assert_instr;
19+
20+
extern "C" {
21+
#[link_name = "llvm.aarch64.tstart"]
22+
fn aarch64_tstart() -> i32;
23+
#[link_name = "llvm.aarch64.tcommit"]
24+
fn aarch64_tcommit() -> ();
25+
#[link_name = "llvm.aarch64.tcancel"]
26+
fn aarch64_tcancel(imm0: i64) -> ();
27+
#[link_name = "llvm.aarch64.ttest"]
28+
fn aarch64_ttest() -> i32;
29+
}
30+
31+
/// Transaction successfully started.
32+
pub const _TMSTART_SUCCESS: u32 = 0x00_u32;
33+
34+
/// Extraction mask for failure reason
35+
pub const _TMFAILURE_REASON: u32 = 0x00007FFF_u32;
36+
37+
/// Transaction retry is possible.
38+
pub const _TMFAILURE_RTRY: u32 = 1 << 15;
39+
40+
/// Transaction cancelled.
41+
pub const _TMFAILURE_CNCL: u32 = 1 << 16;
42+
43+
/// Transaction cancelled due to high memory usage.
44+
pub const _TMFAILURE_MEM: u32 = 1 << 17;
45+
46+
///
47+
pub const _TMFAILURE_IMP: u32 = 1 << 18;
48+
49+
///
50+
pub const _TMFAILURE_ERR: u32 = 1 << 19;
51+
52+
///
53+
pub const _TMFAILURE_SIZE: u32 = 1 << 20;
54+
55+
/// Transaction abort in a inner nested transaction.
56+
pub const _TMFAILURE_NEST: u32 = 1 << 21;
57+
58+
/// Transaction abort due to a debug trap.
59+
pub const _TMFAILURE_DBG: u32 = 1 << 22;
60+
61+
///
62+
pub const _TMFAILURE_INT: u32 = 1 << 23;
63+
64+
///
65+
pub const _TMFAILURE_TRIVIAL: u32 = 1 << 24;
66+
67+
68+
/// Starts a new transaction. When the transaction starts successfully the return value is 0.
69+
/// If the transaction fails, all state modifications are discarded and a cause of the failure
70+
/// is encoded in the return value.
71+
///
72+
/// [ARM TME Intrinsics](https://developer.arm.com/docs/101028/0010/transactional-memory-extension-tme-intrinsics).
73+
#[inline]
74+
#[target_feature(enable = "tme")]
75+
#[cfg_attr(test, assert_instr(tstart))]
76+
pub unsafe fn __tstart() -> u32 {
77+
aarch64_tstart() as _
78+
}
79+
80+
/// Commits the current transaction. For a nested transaction, the only effect is that the
81+
/// transactional nesting depth is decreased. For an outer transaction, the state modifications
82+
/// performed transactionally are committed to the architectural state.
83+
///
84+
/// [ARM TME Intrinsics](https://developer.arm.com/docs/101028/0010/transactional-memory-extension-tme-intrinsics).
85+
#[inline]
86+
#[target_feature(enable = "tme")]
87+
#[cfg_attr(test, assert_instr(tcommit))]
88+
pub unsafe fn __tcommit() {
89+
aarch64_tcommit()
90+
}
91+
92+
/// Cancels the current transaction and discards all state modifications that were performed transactionally.
93+
///
94+
/// [ARM TME Intrinsics](https://developer.arm.com/docs/101028/0010/transactional-memory-extension-tme-intrinsics).
95+
#[inline]
96+
#[target_feature(enable = "tme")]
97+
#[cfg_attr(test, assert_instr(tcancel, imm0 = 0x0))]
98+
#[rustc_args_required_const(0)]
99+
pub unsafe fn __tcancel(imm0: u32) {
100+
macro_rules! call {
101+
($imm0:expr) => {
102+
aarch64_tcancel($imm0)
103+
};
104+
}
105+
constify_imm8!(imm0, call)
106+
}
107+
108+
/// Tests if executing inside a transaction. If no transaction is currently executing,
109+
/// the return value is 0. Otherwise, this intrinsic returns the depth of the transaction.
110+
///
111+
/// [ARM TME Intrinsics](https://developer.arm.com/docs/101028/0010/transactional-memory-extension-tme-intrinsics).
112+
#[inline]
113+
#[target_feature(enable = "tme")]
114+
#[cfg_attr(test, assert_instr(ttest))]
115+
pub unsafe fn __ttest() -> u32 {
116+
aarch64_ttest() as _
117+
}
118+
119+
/// Encodes cancellation reason, which is the parameter passed to [`__tcancel`]
120+
/// Takes cancellation reason flags and retry-ability.
121+
#[inline]
122+
pub const fn _tcancel_code(reason: u32, retryable: bool) -> u32 {
123+
(retryable as i32) << 15 | (reason & _TMFAILURE_REASON)
124+
}

crates/std_detect/tests/cpu-detection.rs

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ fn aarch64_linux() {
4545
println!("rdm: {}", is_aarch64_feature_detected!("rdm"));
4646
println!("rcpc: {}", is_aarch64_feature_detected!("rcpc"));
4747
println!("dotprod: {}", is_aarch64_feature_detected!("dotprod"));
48+
println!("tme: {}", is_aarch64_feature_detected!("tme"));
4849
}
4950

5051
#[test]

0 commit comments

Comments
 (0)