1
1
//! ARM's Transactional Memory Extensions (TME).
2
2
//!
3
- //! This CPU feature is available on Aarch64 – ARMv8-A arch. onwards .
3
+ //! This CPU feature is available on Aarch64 - A architecture profile .
4
4
//! This feature is in the non-neon feature set. TME specific vendor documentation can
5
5
//! be found [TME Intrinsics Introduction][tme_intrinsics_intro].
6
6
//!
7
7
//! The reference is [ACLE Q4 2019][acle_q4_2019_ref].
8
8
//!
9
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.
10
+ //! [ARM A64 Architecture Register Datasheet][a_profile_future] also describes possible failure code scenarios.
12
11
//!
13
12
//! [acle_q4_2019_ref]: https://static.docs.arm.com/101028/0010/ACLE_2019Q4_release-0010.pdf
14
13
//! [tme_intrinsics_intro]: https://developer.arm.com/docs/101028/0010/transactional-memory-extension-tme-intrinsics
15
14
//! [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
16
16
17
17
#[ cfg( test) ]
18
18
use stdarch_test:: assert_instr;
@@ -40,16 +40,16 @@ pub const _TMFAILURE_RTRY: u32 = 1 << 15;
40
40
/// Transaction cancelled.
41
41
pub const _TMFAILURE_CNCL: u32 = 1 << 16 ;
42
42
43
- /// Transaction cancelled due to high memory usage.
43
+ /// Transaction cancelled due to a memory fault
44
44
pub const _TMFAILURE_MEM: u32 = 1 << 17 ;
45
45
46
- ///
46
+ /// Transaction error caused by implementation defined feature
47
47
pub const _TMFAILURE_IMP: u32 = 1 << 18 ;
48
48
49
- ///
49
+ /// Transaction aborted because of non-recovera
50
50
pub const _TMFAILURE_ERR: u32 = 1 << 19 ;
51
51
52
- ///
52
+ /// Transaction cancelled due to size doesn't fit
53
53
pub const _TMFAILURE_SIZE: u32 = 1 << 20 ;
54
54
55
55
/// Transaction abort in a inner nested transaction.
@@ -58,10 +58,10 @@ pub const _TMFAILURE_NEST: u32 = 1 << 21;
58
58
/// Transaction abort due to a debug trap.
59
59
pub const _TMFAILURE_DBG: u32 = 1 << 22 ;
60
60
61
- ///
61
+ /// Transaction failed from interrupt
62
62
pub const _TMFAILURE_INT: u32 = 1 << 23 ;
63
63
64
- ///
64
+ /// Transaction aborted in trivial TM implementation
65
65
pub const _TMFAILURE_TRIVIAL: u32 = 1 << 24 ;
66
66
67
67
@@ -116,9 +116,72 @@ pub unsafe fn __ttest() -> u32 {
116
116
aarch64_ttest ( ) as _
117
117
}
118
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)
119
+
120
+ #[ cfg( test) ]
121
+ mod tests {
122
+ use stdarch_test:: simd_test;
123
+
124
+ use crate :: core_arch:: aarch64:: * ;
125
+
126
+ #[ simd_test( enable = "tme" ) ]
127
+ unsafe fn test_tstart ( ) {
128
+ let mut x = 0 ;
129
+ for i in 0 ..10 {
130
+ let code = tme:: __tstart ( ) ;
131
+ if code == _TMSTART_SUCCESS {
132
+ x += 1 ;
133
+ assert_eq ! ( x, i+1 ) ;
134
+ break ;
135
+ }
136
+ assert_eq ! ( x, 0 ) ;
137
+ }
138
+ }
139
+
140
+ #[ simd_test( enable = "tme" ) ]
141
+ unsafe fn test_tcommit ( ) {
142
+ let mut x = 0 ;
143
+ for i in 0 ..10 {
144
+ let code = tme:: __tstart ( ) ;
145
+ if code == _TMSTART_SUCCESS {
146
+ x += 1 ;
147
+ assert_eq ! ( x, i+1 ) ;
148
+ tme:: __tcommit ( ) ;
149
+ }
150
+ assert_eq ! ( x, i+1 ) ;
151
+ }
152
+ }
153
+
154
+ #[ simd_test( enable = "tme" ) ]
155
+ unsafe fn test_tcancel ( ) {
156
+ let reason = 0x123 ;
157
+ let cancel_code = ( 0 | ( reason & _TMFAILURE_REASON) as i32 ) as u32 ;
158
+ let mut x = 0 ;
159
+
160
+ for i in 0 ..10 {
161
+ let code = tme:: __tstart ( ) ;
162
+ if code == _TMSTART_SUCCESS {
163
+ x += 1 ;
164
+ assert_eq ! ( x, i+1 ) ;
165
+ tme:: __tcancel ( cancel_code) ;
166
+ break ;
167
+ }
168
+ }
169
+
170
+ assert_eq ! ( x, 0 ) ;
171
+ }
172
+
173
+ #[ simd_test( enable = "tme" ) ]
174
+ unsafe fn test_ttest ( ) {
175
+ let reason = 0x123 ;
176
+ let cancel_code = ( 0 | ( reason & _TMFAILURE_REASON) as i32 ) as u32 ;
177
+ for _ in 0 ..10 {
178
+ let code = tme:: __tstart ( ) ;
179
+ if code == _TMSTART_SUCCESS {
180
+ if tme:: __ttest ( ) == 2 {
181
+ tme:: __tcancel ( cancel_code) ;
182
+ break ;
183
+ }
184
+ }
185
+ }
186
+ }
124
187
}
0 commit comments