Skip to content

Commit 9fb45e7

Browse files
committed
Fix cancellation code arithmetic
1 parent e4c4124 commit 9fb45e7

File tree

2 files changed

+80
-18
lines changed

2 files changed

+80
-18
lines changed

crates/core_arch/src/aarch64/tme.rs

+79-18
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
//! ARM's Transactional Memory Extensions (TME).
22
//!
3-
//! This CPU feature is available on Aarch64 – ARMv8-A arch. onwards.
3+
//! This CPU feature is available on Aarch64 - A architecture profile.
44
//! This feature is in the non-neon feature set. TME specific vendor documentation can
55
//! be found [TME Intrinsics Introduction][tme_intrinsics_intro].
66
//!
77
//! The reference is [ACLE Q4 2019][acle_q4_2019_ref].
88
//!
99
//! 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.
10+
//! [ARM A64 Architecture Register Datasheet][a_profile_future] also describes possible failure code scenarios.
1211
//!
1312
//! [acle_q4_2019_ref]: https://static.docs.arm.com/101028/0010/ACLE_2019Q4_release-0010.pdf
1413
//! [tme_intrinsics_intro]: https://developer.arm.com/docs/101028/0010/transactional-memory-extension-tme-intrinsics
1514
//! [llvm_aarch64_int]: https://github.com/llvm/llvm-project/commit/a36d31478c182903523e04eb271bbf102bfab2cc#diff-ff24e1c35f4d54f1110ce5d90c709319R626-R646
15+
//! [a_profile_future]: https://static.docs.arm.com/ddi0601/a/SysReg_xml_futureA-2019-04.pdf?_ga=2.116560387.441514988.1590524918-1110153136.1588469296
1616
1717
#[cfg(test)]
1818
use stdarch_test::assert_instr;
@@ -37,34 +37,33 @@ pub const _TMFAILURE_REASON: u32 = 0x00007FFF_u32;
3737
/// Transaction retry is possible.
3838
pub const _TMFAILURE_RTRY: u32 = 1 << 15;
3939

40-
/// Transaction cancelled.
40+
/// Transaction executed a TCANCEL instruction
4141
pub const _TMFAILURE_CNCL: u32 = 1 << 16;
4242

43-
/// Transaction cancelled due to high memory usage.
43+
/// Transaction aborted because a conflict occurred
4444
pub const _TMFAILURE_MEM: u32 = 1 << 17;
4545

46-
///
46+
/// Fallback error type for any other reason
4747
pub const _TMFAILURE_IMP: u32 = 1 << 18;
4848

49-
///
49+
/// Transaction aborted because a non-permissible operation was attempted
5050
pub const _TMFAILURE_ERR: u32 = 1 << 19;
5151

52-
///
52+
/// Transaction aborted due to read or write set limit was exceeded
5353
pub const _TMFAILURE_SIZE: u32 = 1 << 20;
5454

55-
/// Transaction abort in a inner nested transaction.
55+
/// Transaction aborted due to transactional nesting level was exceeded
5656
pub const _TMFAILURE_NEST: u32 = 1 << 21;
5757

58-
/// Transaction abort due to a debug trap.
58+
/// Transaction aborted due to a debug trap.
5959
pub const _TMFAILURE_DBG: u32 = 1 << 22;
6060

61-
///
61+
/// Transaction failed from interrupt
6262
pub const _TMFAILURE_INT: u32 = 1 << 23;
6363

64-
///
64+
/// Indicates a TRIVIAL version of TM is available
6565
pub const _TMFAILURE_TRIVIAL: u32 = 1 << 24;
6666

67-
6867
/// Starts a new transaction. When the transaction starts successfully the return value is 0.
6968
/// If the transaction fails, all state modifications are discarded and a cause of the failure
7069
/// is encoded in the return value.
@@ -116,9 +115,71 @@ pub unsafe fn __ttest() -> u32 {
116115
aarch64_ttest() as _
117116
}
118117

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)
118+
#[cfg(test)]
119+
mod tests {
120+
use stdarch_test::simd_test;
121+
122+
use crate::core_arch::aarch64::*;
123+
124+
#[simd_test(enable = "tme")]
125+
unsafe fn test_tstart() {
126+
let mut x = 0;
127+
for i in 0..10 {
128+
let code = tme::__tstart();
129+
if code == _TMSTART_SUCCESS {
130+
x += 1;
131+
assert_eq!(x, i+1);
132+
break;
133+
}
134+
assert_eq!(x, 0);
135+
}
136+
}
137+
138+
#[simd_test(enable = "tme")]
139+
unsafe fn test_tcommit() {
140+
let mut x = 0;
141+
for i in 0..10 {
142+
let code = tme::__tstart();
143+
if code == _TMSTART_SUCCESS {
144+
x += 1;
145+
assert_eq!(x, i+1);
146+
tme::__tcommit();
147+
}
148+
assert_eq!(x, i+1);
149+
}
150+
}
151+
152+
#[simd_test(enable = "tme")]
153+
unsafe fn test_tcancel() {
154+
let reason = 0x123;
155+
let cancel_code = (0 | (reason & _TMFAILURE_REASON) as i32) as u32;
156+
let mut x = 0;
157+
158+
for i in 0..10 {
159+
let code = tme::__tstart();
160+
if code == _TMSTART_SUCCESS {
161+
x += 1;
162+
assert_eq!(x, i+1);
163+
tme::__tcancel(cancel_code);
164+
break;
165+
}
166+
}
167+
168+
assert_eq!(x, 0);
169+
}
170+
171+
#[simd_test(enable = "tme")]
172+
unsafe fn test_ttest() {
173+
let reason = 0x123;
174+
let cancel_code = (0 | (reason & _TMFAILURE_REASON) as i32) as u32;
175+
for _ in 0..10 {
176+
let code = tme::__tstart();
177+
if code == _TMSTART_SUCCESS {
178+
if tme::__ttest() == 2 {
179+
tme::__tcancel(cancel_code);
180+
break;
181+
}
182+
}
183+
}
184+
}
124185
}

crates/stdarch-verify/tests/arm.rs

+1
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,7 @@ fn verify_all_signatures() {
366366
&& !rust.file.ends_with("v6.rs\"")
367367
&& !rust.file.ends_with("v7.rs\"")
368368
&& !rust.file.ends_with("v8.rs\"")
369+
&& !rust.file.ends_with("tme.rs\"")
369370
{
370371
println!(
371372
"missing arm definition for {:?} in {}",

0 commit comments

Comments
 (0)