|
1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of the License "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // e32test\system\t_atomic.cpp |
|
15 // |
|
16 // |
|
17 |
|
18 #define __E32TEST_EXTENSION__ |
|
19 |
|
20 #include <e32test.h> |
|
21 #include <e32atomics.h> |
|
22 #include <u32hal.h> |
|
23 #include "u32std.h" |
|
24 #include <e32svr.h> |
|
25 #include <hal.h> |
|
26 |
|
27 RTest test(_L("T_ATOMIC")); |
|
28 |
|
29 #include "t_atomic.h" |
|
30 |
|
31 #ifdef __EPOC32__ |
|
32 RTestAtomic DD; |
|
33 #endif |
|
34 |
|
35 extern "C" { |
|
36 extern const char* FuncName[]; |
|
37 extern const PFV AtomicFuncPtr[]; |
|
38 extern const PFV ControlFuncPtr[]; |
|
39 extern const TUint FuncAttr[]; |
|
40 } |
|
41 |
|
42 class TestOverflowTruncate2 : public TDes16Overflow |
|
43 { |
|
44 public: |
|
45 virtual void Overflow(TDes16 &aDes); |
|
46 }; |
|
47 |
|
48 void TestOverflowTruncate2::Overflow(TDes16& /*aDes*/) |
|
49 { |
|
50 } |
|
51 |
|
52 void UPrintf(const char* aFmt, ...) |
|
53 { |
|
54 // Print to a console screen. |
|
55 TestOverflowTruncate2 overflow; |
|
56 VA_LIST list; |
|
57 VA_START(list, aFmt); |
|
58 TBuf8<256> fmtBuf8((const TUint8*)aFmt); |
|
59 TBuf<256> buf; |
|
60 buf.AppendFormatList(fmtBuf8.Expand(), list, &overflow); |
|
61 test.Printf(_L("%S\n"),&buf); |
|
62 } |
|
63 |
|
64 /****************************************************************************** |
|
65 * Single thread normal operation tests |
|
66 ******************************************************************************/ |
|
67 template<class T> |
|
68 struct TD |
|
69 { |
|
70 T i0; |
|
71 T i1; |
|
72 T i2; |
|
73 T i3; |
|
74 TInt iF; |
|
75 TInt iPadding; |
|
76 }; |
|
77 |
|
78 struct TDG : public TDGBase |
|
79 { |
|
80 void Set(const TD<TUint8> aTD8, TInt aOrd); |
|
81 void Set(const TD<TUint16> aTD16, TInt aOrd); |
|
82 void Set(const TD<TUint32> aTD32, TInt aOrd); |
|
83 void Set(const TD<TUint64> aTD64, TInt aOrd); |
|
84 |
|
85 TInt ExecuteUser(); |
|
86 TInt ExecuteKernel(); |
|
87 }; |
|
88 |
|
89 TInt GetAtomicFuncIndex(TInt aFunc, TInt aSize, TInt aOrd) |
|
90 { |
|
91 test_NotNegative(aFunc); |
|
92 test_Compare(aFunc,<,EAtomicFuncN); |
|
93 test_NotNegative(aOrd); |
|
94 test_Compare(aOrd,<,4); |
|
95 aFunc *= 4; |
|
96 switch(aSize) |
|
97 { |
|
98 case 1: break; |
|
99 case 2: aFunc += INDEXES_PER_SIZE; break; |
|
100 case 4: aFunc += 2*INDEXES_PER_SIZE; break; |
|
101 case 8: aFunc += 3*INDEXES_PER_SIZE; break; |
|
102 default: test_Equal(8,aSize); break; |
|
103 } |
|
104 aFunc += aOrd; |
|
105 if (AtomicFuncPtr[aFunc]) |
|
106 return aFunc; |
|
107 return -1; |
|
108 } |
|
109 |
|
110 void TDG::Set(const TD<TUint8> aTD8, TInt aOrd) |
|
111 { |
|
112 i0 = aTD8.i0; |
|
113 i1 = aTD8.i1; |
|
114 i2 = aTD8.i2; |
|
115 i3 = aTD8.i3; |
|
116 iIndex = GetAtomicFuncIndex(aTD8.iF, 1, aOrd); |
|
117 #ifdef __EXTRA_DEBUG__ |
|
118 DEBUGPRINT(" 8: iF=%2d aOrd=%1d -> %d", aTD8.iF, aOrd, iIndex); |
|
119 #endif |
|
120 } |
|
121 |
|
122 void TDG::Set(const TD<TUint16> aTD16, TInt aOrd) |
|
123 { |
|
124 i0 = aTD16.i0; |
|
125 i1 = aTD16.i1; |
|
126 i2 = aTD16.i2; |
|
127 i3 = aTD16.i3; |
|
128 iIndex = GetAtomicFuncIndex(aTD16.iF, 2, aOrd); |
|
129 #ifdef __EXTRA_DEBUG__ |
|
130 DEBUGPRINT("16: iF=%2d aOrd=%1d -> %d", aTD16.iF, aOrd, iIndex); |
|
131 #endif |
|
132 } |
|
133 |
|
134 void TDG::Set(const TD<TUint32> aTD32, TInt aOrd) |
|
135 { |
|
136 i0 = aTD32.i0; |
|
137 i1 = aTD32.i1; |
|
138 i2 = aTD32.i2; |
|
139 i3 = aTD32.i3; |
|
140 iIndex = GetAtomicFuncIndex(aTD32.iF, 4, aOrd); |
|
141 #ifdef __EXTRA_DEBUG__ |
|
142 DEBUGPRINT("32: iF=%2d aOrd=%1d -> %d", aTD32.iF, aOrd, iIndex); |
|
143 #endif |
|
144 } |
|
145 |
|
146 void TDG::Set(const TD<TUint64> aTD64, TInt aOrd) |
|
147 { |
|
148 i0 = aTD64.i0; |
|
149 i1 = aTD64.i1; |
|
150 i2 = aTD64.i2; |
|
151 i3 = aTD64.i3; |
|
152 iIndex = GetAtomicFuncIndex(aTD64.iF, 8, aOrd); |
|
153 #ifdef __EXTRA_DEBUG__ |
|
154 DEBUGPRINT("64: iF=%2d aOrd=%1d -> %d", aTD64.iF, aOrd, iIndex); |
|
155 #endif |
|
156 } |
|
157 |
|
158 TInt TDG::ExecuteUser() |
|
159 { |
|
160 return Execute(); |
|
161 } |
|
162 |
|
163 #ifdef __EPOC32__ |
|
164 TInt TDG::ExecuteKernel() |
|
165 { |
|
166 return DD.TDGExecuteK(*this); |
|
167 } |
|
168 #endif |
|
169 |
|
170 |
|
171 #define DCL_TEST_BLOCK(type,name) \ |
|
172 static const TD<type> name[] = |
|
173 #define DCL_TEST1(type,func,a0) \ |
|
174 { (type)(a0), (type)(0), (type)(0), (type)(0), (EAtomicFunc##func), 0 } |
|
175 #define DCL_TEST2(type,func,a0,a1) \ |
|
176 { (type)(a0), (type)(a1), (type)(0), (type)(0), (EAtomicFunc##func), 0 } |
|
177 #define DCL_TEST3(type,func,a0,a1,a2) \ |
|
178 { (type)(a0), (type)(a1), (type)(a2), (type)(0), (EAtomicFunc##func), 0 } |
|
179 #define DCL_TEST4(type,func,a0,a1,a2,a3) \ |
|
180 { (type)(a0), (type)(a1), (type)(a2), (type)(a3), (EAtomicFunc##func), 0 } |
|
181 |
|
182 DCL_TEST_BLOCK(TUint8,TestData8) |
|
183 { |
|
184 DCL_TEST1(TUint8, LOAD, 0x00), |
|
185 DCL_TEST1(TUint8, LOAD, 0xFF), |
|
186 |
|
187 DCL_TEST2(TUint8, STORE, 0xBB, 0x00), |
|
188 DCL_TEST2(TUint8, STORE, 0xBB, 0xFF), |
|
189 |
|
190 DCL_TEST2(TUint8, SWP, 0xBB, 0x00), |
|
191 DCL_TEST2(TUint8, SWP, 0xBB, 0xFF), |
|
192 DCL_TEST2(TUint8, SWP, 0x55, 0x00), |
|
193 DCL_TEST2(TUint8, SWP, 0x55, 0xFF), |
|
194 |
|
195 DCL_TEST2(TUint8, ADD, 0x00, 0x01), |
|
196 DCL_TEST2(TUint8, ADD, 0xFF, 0x01), |
|
197 DCL_TEST2(TUint8, ADD, 0xFE, 0x01), |
|
198 DCL_TEST2(TUint8, ADD, 0xFE, 0x02), |
|
199 DCL_TEST2(TUint8, ADD, 0xFE, 0x03), |
|
200 DCL_TEST2(TUint8, ADD, 0x12, 0x23), |
|
201 |
|
202 DCL_TEST2(TUint8, AND, 0x00, 0x01), |
|
203 DCL_TEST2(TUint8, AND, 0xFF, 0x01), |
|
204 DCL_TEST2(TUint8, AND, 0xFE, 0x01), |
|
205 DCL_TEST2(TUint8, AND, 0xFE, 0xFF), |
|
206 DCL_TEST2(TUint8, AND, 0xFE, 0x03), |
|
207 DCL_TEST2(TUint8, AND, 0x5F, 0xAF), |
|
208 |
|
209 DCL_TEST2(TUint8, IOR, 0x00, 0x01), |
|
210 DCL_TEST2(TUint8, IOR, 0xFF, 0x01), |
|
211 DCL_TEST2(TUint8, IOR, 0xFE, 0x01), |
|
212 DCL_TEST2(TUint8, IOR, 0x0D, 0x5F), |
|
213 DCL_TEST2(TUint8, IOR, 0x30, 0x03), |
|
214 DCL_TEST2(TUint8, IOR, 0x5F, 0xAF), |
|
215 |
|
216 DCL_TEST2(TUint8, XOR, 0x00, 0x01), |
|
217 DCL_TEST2(TUint8, XOR, 0xFF, 0x01), |
|
218 DCL_TEST2(TUint8, XOR, 0xFE, 0x01), |
|
219 DCL_TEST2(TUint8, XOR, 0xFE, 0xFF), |
|
220 DCL_TEST2(TUint8, XOR, 0xFE, 0x03), |
|
221 DCL_TEST2(TUint8, XOR, 0x5F, 0xAF), |
|
222 |
|
223 DCL_TEST3(TUint8, AXO, 0x00, 0xFF, 0x00), |
|
224 DCL_TEST3(TUint8, AXO, 0x00, 0xFF, 0x33), |
|
225 DCL_TEST3(TUint8, AXO, 0x00, 0xFF, 0x7D), |
|
226 DCL_TEST3(TUint8, AXO, 0x00, 0xFF, 0xBB), |
|
227 DCL_TEST3(TUint8, AXO, 0xAA, 0x00, 0x00), |
|
228 DCL_TEST3(TUint8, AXO, 0xAA, 0x00, 0x33), |
|
229 DCL_TEST3(TUint8, AXO, 0xAA, 0x00, 0x7D), |
|
230 DCL_TEST3(TUint8, AXO, 0xAA, 0x00, 0xBB), |
|
231 DCL_TEST3(TUint8, AXO, 0xAA, 0x33, 0xF0), |
|
232 DCL_TEST3(TUint8, AXO, 0xAA, 0x33, 0x0F), |
|
233 DCL_TEST3(TUint8, AXO, 0xAA, 0xCC, 0xF0), |
|
234 DCL_TEST3(TUint8, AXO, 0xAA, 0xCC, 0x0F), |
|
235 |
|
236 DCL_TEST3(TUint8, CAS, 0x00, 0xFF, 0xEE), |
|
237 DCL_TEST3(TUint8, CAS, 0x00, 0x01, 0x11), |
|
238 DCL_TEST3(TUint8, CAS, 0x00, 0x00, 0xEE), |
|
239 DCL_TEST3(TUint8, CAS, 0x00, 0x00, 0x23), |
|
240 DCL_TEST3(TUint8, CAS, 0x2A, 0xFF, 0x2B), |
|
241 DCL_TEST3(TUint8, CAS, 0x2A, 0x01, 0x2B), |
|
242 DCL_TEST3(TUint8, CAS, 0x2A, 0x2A, 0x2B), |
|
243 DCL_TEST3(TUint8, CAS, 0x2A, 0x2A, 0x3B), |
|
244 |
|
245 DCL_TEST4(TUint8, TAU, 0x00, 0x00, 0x02, 0x03), |
|
246 DCL_TEST4(TUint8, TAU, 0x01, 0x00, 0x02, 0x03), |
|
247 DCL_TEST4(TUint8, TAU, 0xFF, 0x00, 0x02, 0x03), |
|
248 DCL_TEST4(TUint8, TAU, 0x00, 0x01, 0x02, 0x03), |
|
249 DCL_TEST4(TUint8, TAU, 0x01, 0x01, 0x02, 0x03), |
|
250 DCL_TEST4(TUint8, TAU, 0x02, 0x01, 0x02, 0x03), |
|
251 DCL_TEST4(TUint8, TAU, 0xFF, 0x01, 0x02, 0x03), |
|
252 DCL_TEST4(TUint8, TAU, 0xFE, 0xFE, 0x23, 0x0B), |
|
253 DCL_TEST4(TUint8, TAU, 0xEE, 0xFE, 0x23, 0x0B), |
|
254 DCL_TEST4(TUint8, TAU, 0xFF, 0xFE, 0x23, 0x0B), |
|
255 DCL_TEST4(TUint8, TAU, 0x00, 0xFE, 0x23, 0x0B), |
|
256 DCL_TEST4(TUint8, TAU, 0xFE, 0xFE, 0x80, 0x7F), |
|
257 DCL_TEST4(TUint8, TAU, 0xEE, 0xFE, 0x80, 0x7F), |
|
258 DCL_TEST4(TUint8, TAU, 0xFF, 0xFE, 0x80, 0x7F), |
|
259 DCL_TEST4(TUint8, TAU, 0x00, 0xFE, 0x80, 0x7F), |
|
260 DCL_TEST4(TUint8, TAU, 0xFE, 0x80, 0x81, 0x7E), |
|
261 DCL_TEST4(TUint8, TAU, 0x7F, 0x80, 0x81, 0x7E), |
|
262 DCL_TEST4(TUint8, TAU, 0x80, 0x80, 0x81, 0x7E), |
|
263 DCL_TEST4(TUint8, TAU, 0x81, 0x80, 0x81, 0x7E), |
|
264 DCL_TEST4(TUint8, TAU, 0x00, 0x80, 0x81, 0x7E), |
|
265 DCL_TEST4(TUint8, TAU, 0x7E, 0x7F, 0x81, 0x7E), |
|
266 DCL_TEST4(TUint8, TAU, 0x7F, 0x7F, 0x81, 0x7E), |
|
267 DCL_TEST4(TUint8, TAU, 0x80, 0x7F, 0x81, 0x7E), |
|
268 DCL_TEST4(TUint8, TAU, 0x81, 0x7F, 0x81, 0x7E), |
|
269 DCL_TEST4(TUint8, TAU, 0x00, 0x7F, 0x81, 0x7E), |
|
270 |
|
271 DCL_TEST4(TUint8, TAS, 0x00, 0x00, 0x02, 0x03), |
|
272 DCL_TEST4(TUint8, TAS, 0x01, 0x00, 0x02, 0x03), |
|
273 DCL_TEST4(TUint8, TAS, 0xFF, 0x00, 0x02, 0x03), |
|
274 DCL_TEST4(TUint8, TAS, 0x00, 0x01, 0x02, 0x03), |
|
275 DCL_TEST4(TUint8, TAS, 0x01, 0x01, 0x02, 0x03), |
|
276 DCL_TEST4(TUint8, TAS, 0x02, 0x01, 0x02, 0x03), |
|
277 DCL_TEST4(TUint8, TAS, 0xFF, 0x01, 0x02, 0x03), |
|
278 DCL_TEST4(TUint8, TAS, 0xFE, 0xFE, 0x23, 0x0B), |
|
279 DCL_TEST4(TUint8, TAS, 0xEE, 0xFE, 0x23, 0x0B), |
|
280 DCL_TEST4(TUint8, TAS, 0xFF, 0xFE, 0x23, 0x0B), |
|
281 DCL_TEST4(TUint8, TAS, 0x00, 0xFE, 0x23, 0x0B), |
|
282 DCL_TEST4(TUint8, TAS, 0xFE, 0xFE, 0x80, 0x7F), |
|
283 DCL_TEST4(TUint8, TAS, 0xEE, 0xFE, 0x80, 0x7F), |
|
284 DCL_TEST4(TUint8, TAS, 0xFF, 0xFE, 0x80, 0x7F), |
|
285 DCL_TEST4(TUint8, TAS, 0x00, 0xFE, 0x80, 0x7F), |
|
286 DCL_TEST4(TUint8, TAS, 0xFE, 0x80, 0x81, 0x7E), |
|
287 DCL_TEST4(TUint8, TAS, 0x7F, 0x80, 0x81, 0x7E), |
|
288 DCL_TEST4(TUint8, TAS, 0x80, 0x80, 0x81, 0x7E), |
|
289 DCL_TEST4(TUint8, TAS, 0x81, 0x80, 0x81, 0x7E), |
|
290 DCL_TEST4(TUint8, TAS, 0x00, 0x80, 0x81, 0x7E), |
|
291 DCL_TEST4(TUint8, TAS, 0x7E, 0x7F, 0x81, 0x7E), |
|
292 DCL_TEST4(TUint8, TAS, 0x7F, 0x7F, 0x81, 0x7E), |
|
293 DCL_TEST4(TUint8, TAS, 0x80, 0x7F, 0x81, 0x7E), |
|
294 DCL_TEST4(TUint8, TAS, 0x81, 0x7F, 0x81, 0x7E), |
|
295 DCL_TEST4(TUint8, TAS, 0x00, 0x7F, 0x81, 0x7E) |
|
296 }; |
|
297 |
|
298 DCL_TEST_BLOCK(TUint16,TestData16) |
|
299 { |
|
300 DCL_TEST1(TUint16, LOAD, 0x0055), |
|
301 DCL_TEST1(TUint16, LOAD, 0xFFAA), |
|
302 |
|
303 DCL_TEST2(TUint16, STORE, 0xBBBB, 0x0055), |
|
304 DCL_TEST2(TUint16, STORE, 0xBBBB, 0xFFAA), |
|
305 |
|
306 DCL_TEST2(TUint16, SWP, 0xBBCC, 0x0055), |
|
307 DCL_TEST2(TUint16, SWP, 0xBBCC, 0xFFAA), |
|
308 DCL_TEST2(TUint16, SWP, 0x55AA, 0x0033), |
|
309 DCL_TEST2(TUint16, SWP, 0x55AA, 0xFFCC), |
|
310 |
|
311 DCL_TEST2(TUint16, ADD, 0x0000, 0x0001), |
|
312 DCL_TEST2(TUint16, ADD, 0xFFFF, 0x0001), |
|
313 DCL_TEST2(TUint16, ADD, 0xFFFE, 0x0001), |
|
314 DCL_TEST2(TUint16, ADD, 0xFFFE, 0x0002), |
|
315 DCL_TEST2(TUint16, ADD, 0xFFFE, 0x0003), |
|
316 DCL_TEST2(TUint16, ADD, 0x0012, 0x0023), |
|
317 DCL_TEST2(TUint16, ADD, 0x0012, 0xBCFF), |
|
318 |
|
319 DCL_TEST2(TUint16, AND, 0x0000, 0x0001), |
|
320 DCL_TEST2(TUint16, AND, 0xFFFF, 0x0001), |
|
321 DCL_TEST2(TUint16, AND, 0xFFFE, 0x0001), |
|
322 DCL_TEST2(TUint16, AND, 0xFFFE, 0xFFFF), |
|
323 DCL_TEST2(TUint16, AND, 0xFFFE, 0x0F03), |
|
324 DCL_TEST2(TUint16, AND, 0xBC5F, 0x14AF), |
|
325 |
|
326 DCL_TEST2(TUint16, IOR, 0x0000, 0x0001), |
|
327 DCL_TEST2(TUint16, IOR, 0xFFFF, 0x0001), |
|
328 DCL_TEST2(TUint16, IOR, 0xFFFE, 0x0001), |
|
329 DCL_TEST2(TUint16, IOR, 0x000D, 0x005F), |
|
330 DCL_TEST2(TUint16, IOR, 0x8030, 0x0803), |
|
331 DCL_TEST2(TUint16, IOR, 0x145F, 0x56AF), |
|
332 |
|
333 DCL_TEST2(TUint16, XOR, 0x0000, 0x0001), |
|
334 DCL_TEST2(TUint16, XOR, 0xFFFF, 0x0001), |
|
335 DCL_TEST2(TUint16, XOR, 0xFFFE, 0x0001), |
|
336 DCL_TEST2(TUint16, XOR, 0xFFFE, 0xFFFF), |
|
337 DCL_TEST2(TUint16, XOR, 0xFFFE, 0x0003), |
|
338 DCL_TEST2(TUint16, XOR, 0x145F, 0xBCAF), |
|
339 |
|
340 DCL_TEST3(TUint16, AXO, 0x0000, 0xFFFF, 0x0000), |
|
341 DCL_TEST3(TUint16, AXO, 0x0000, 0xFFFF, 0x6633), |
|
342 DCL_TEST3(TUint16, AXO, 0x0000, 0xFFFF, 0x827D), |
|
343 DCL_TEST3(TUint16, AXO, 0x0000, 0xFFFF, 0xCCBB), |
|
344 DCL_TEST3(TUint16, AXO, 0xAAAA, 0x0000, 0x0000), |
|
345 DCL_TEST3(TUint16, AXO, 0xAAAA, 0x0000, 0x6633), |
|
346 DCL_TEST3(TUint16, AXO, 0xAAAA, 0x0000, 0x827D), |
|
347 DCL_TEST3(TUint16, AXO, 0xAAAA, 0x0000, 0xCCBB), |
|
348 DCL_TEST3(TUint16, AXO, 0xAAAA, 0xCC33, 0x0FF0), |
|
349 DCL_TEST3(TUint16, AXO, 0xAAAA, 0xCC33, 0xF00F), |
|
350 DCL_TEST3(TUint16, AXO, 0xAAAA, 0x33CC, 0x0FF0), |
|
351 DCL_TEST3(TUint16, AXO, 0xAAAA, 0x33CC, 0xF00F), |
|
352 |
|
353 DCL_TEST3(TUint16, CAS, 0x0000, 0x00FF, 0x99EE), |
|
354 DCL_TEST3(TUint16, CAS, 0x0000, 0x0001, 0x7711), |
|
355 DCL_TEST3(TUint16, CAS, 0x0000, 0x0000, 0x99EE), |
|
356 DCL_TEST3(TUint16, CAS, 0x0000, 0x0000, 0x1123), |
|
357 DCL_TEST3(TUint16, CAS, 0x832A, 0xFFFF, 0x832B), |
|
358 DCL_TEST3(TUint16, CAS, 0x832A, 0x0001, 0x832B), |
|
359 DCL_TEST3(TUint16, CAS, 0x832A, 0x822A, 0x832B), |
|
360 DCL_TEST3(TUint16, CAS, 0x832A, 0x832B, 0x943B), |
|
361 DCL_TEST3(TUint16, CAS, 0x832A, 0x832A, 0x832B), |
|
362 DCL_TEST3(TUint16, CAS, 0x832A, 0x832A, 0x943B), |
|
363 |
|
364 DCL_TEST4(TUint16, TAU, 0x0000, 0x0000, 0x0002, 0x0003), |
|
365 DCL_TEST4(TUint16, TAU, 0x0001, 0x0000, 0x0002, 0x0003), |
|
366 DCL_TEST4(TUint16, TAU, 0xFFFF, 0x0000, 0x0002, 0x0003), |
|
367 DCL_TEST4(TUint16, TAU, 0x0000, 0x0001, 0x0002, 0x0003), |
|
368 DCL_TEST4(TUint16, TAU, 0x0001, 0x0001, 0x0002, 0x0003), |
|
369 DCL_TEST4(TUint16, TAU, 0x0002, 0x0001, 0x0002, 0x0003), |
|
370 DCL_TEST4(TUint16, TAU, 0xFFFF, 0x0001, 0x0002, 0x0003), |
|
371 DCL_TEST4(TUint16, TAU, 0xFFFE, 0xFFFE, 0x1023, 0x000B), |
|
372 DCL_TEST4(TUint16, TAU, 0xFFEE, 0xFFFE, 0x1423, 0x000B), |
|
373 DCL_TEST4(TUint16, TAU, 0xFFFF, 0xFFFE, 0x1423, 0x000B), |
|
374 DCL_TEST4(TUint16, TAU, 0x0000, 0xFFFE, 0x1423, 0x000B), |
|
375 DCL_TEST4(TUint16, TAU, 0xFFFE, 0xFFFE, 0x8000, 0x7FFF), |
|
376 DCL_TEST4(TUint16, TAU, 0xFFEE, 0xFFFE, 0x8000, 0x7FFF), |
|
377 DCL_TEST4(TUint16, TAU, 0xFFFF, 0xFFFE, 0x8000, 0x7FFF), |
|
378 DCL_TEST4(TUint16, TAU, 0x0000, 0xFFFE, 0x8000, 0x7FFF), |
|
379 DCL_TEST4(TUint16, TAU, 0xFFFE, 0x8000, 0x8001, 0x7FFE), |
|
380 DCL_TEST4(TUint16, TAU, 0x7FFF, 0x8000, 0x8001, 0x7FFE), |
|
381 DCL_TEST4(TUint16, TAU, 0x8000, 0x8000, 0x8001, 0x7FFE), |
|
382 DCL_TEST4(TUint16, TAU, 0x8001, 0x8000, 0x8001, 0x7FFE), |
|
383 DCL_TEST4(TUint16, TAU, 0x0000, 0x8000, 0x8001, 0x7FFE), |
|
384 DCL_TEST4(TUint16, TAU, 0x7FFE, 0x7FFF, 0x8001, 0x7FFE), |
|
385 DCL_TEST4(TUint16, TAU, 0x7FFF, 0x7FFF, 0x8001, 0x7FFE), |
|
386 DCL_TEST4(TUint16, TAU, 0x8000, 0x7FFF, 0x8001, 0x7FFE), |
|
387 DCL_TEST4(TUint16, TAU, 0x8001, 0x7FFF, 0x8001, 0x7FFE), |
|
388 DCL_TEST4(TUint16, TAU, 0x0000, 0x7FFF, 0x8001, 0x7FFE), |
|
389 |
|
390 DCL_TEST4(TUint16, TAS, 0x0000, 0x0000, 0x0002, 0x0003), |
|
391 DCL_TEST4(TUint16, TAS, 0x0001, 0x0000, 0x0002, 0x0003), |
|
392 DCL_TEST4(TUint16, TAS, 0xFFFF, 0x0000, 0x0002, 0x0003), |
|
393 DCL_TEST4(TUint16, TAS, 0x0000, 0x0001, 0x0002, 0x0003), |
|
394 DCL_TEST4(TUint16, TAS, 0x0001, 0x0001, 0x0002, 0x0003), |
|
395 DCL_TEST4(TUint16, TAS, 0x0002, 0x0001, 0x0002, 0x0003), |
|
396 DCL_TEST4(TUint16, TAS, 0xFFFF, 0x0001, 0x0002, 0x0003), |
|
397 DCL_TEST4(TUint16, TAS, 0xFFFE, 0xFFFE, 0x1023, 0x000B), |
|
398 DCL_TEST4(TUint16, TAS, 0xFFEE, 0xFFFE, 0x1423, 0x000B), |
|
399 DCL_TEST4(TUint16, TAS, 0xFFFF, 0xFFFE, 0x1423, 0x000B), |
|
400 DCL_TEST4(TUint16, TAS, 0x0000, 0xFFFE, 0x1423, 0x000B), |
|
401 DCL_TEST4(TUint16, TAS, 0xFFFE, 0xFFFE, 0x8000, 0x7FFF), |
|
402 DCL_TEST4(TUint16, TAS, 0xFFEE, 0xFFFE, 0x8000, 0x7FFF), |
|
403 DCL_TEST4(TUint16, TAS, 0xFFFF, 0xFFFE, 0x8000, 0x7FFF), |
|
404 DCL_TEST4(TUint16, TAS, 0x0000, 0xFFFE, 0x8000, 0x7FFF), |
|
405 DCL_TEST4(TUint16, TAS, 0xFFFE, 0x8000, 0x8001, 0x7FFE), |
|
406 DCL_TEST4(TUint16, TAS, 0x7FFF, 0x8000, 0x8001, 0x7FFE), |
|
407 DCL_TEST4(TUint16, TAS, 0x8000, 0x8000, 0x8001, 0x7FFE), |
|
408 DCL_TEST4(TUint16, TAS, 0x8001, 0x8000, 0x8001, 0x7FFE), |
|
409 DCL_TEST4(TUint16, TAS, 0x0000, 0x8000, 0x8001, 0x7FFE), |
|
410 DCL_TEST4(TUint16, TAS, 0x7FFE, 0x7FFF, 0x8001, 0x7FFE), |
|
411 DCL_TEST4(TUint16, TAS, 0x7FFF, 0x7FFF, 0x8001, 0x7FFE), |
|
412 DCL_TEST4(TUint16, TAS, 0x8000, 0x7FFF, 0x8001, 0x7FFE), |
|
413 DCL_TEST4(TUint16, TAS, 0x8001, 0x7FFF, 0x8001, 0x7FFE), |
|
414 DCL_TEST4(TUint16, TAS, 0x0000, 0x7FFF, 0x8001, 0x7FFE) |
|
415 }; |
|
416 |
|
417 DCL_TEST_BLOCK(TUint32,TestData32) |
|
418 { |
|
419 DCL_TEST1(TUint32, LOAD, 0x00334455), |
|
420 DCL_TEST1(TUint32, LOAD, 0xFFCCBBAA), |
|
421 |
|
422 DCL_TEST2(TUint32, STORE, 0xBBBBBBBB, 0x00334455), |
|
423 DCL_TEST2(TUint32, STORE, 0xBBBBBBBB, 0xFFCCBBAA), |
|
424 |
|
425 DCL_TEST2(TUint32, SWP, 0xBB1234CC, 0x00EDCB55), |
|
426 DCL_TEST2(TUint32, SWP, 0xBB1234CC, 0xFF9876AA), |
|
427 DCL_TEST2(TUint32, SWP, 0x551971AA, 0x00112233), |
|
428 DCL_TEST2(TUint32, SWP, 0x551971AA, 0xFFEEDDCC), |
|
429 |
|
430 DCL_TEST2(TUint32, ADD, 0x00000000, 0x00000001), |
|
431 DCL_TEST2(TUint32, ADD, 0xFFFFFFFF, 0x00000001), |
|
432 DCL_TEST2(TUint32, ADD, 0xFFFFFFFE, 0x00000001), |
|
433 DCL_TEST2(TUint32, ADD, 0xFFFFFFFE, 0x00000002), |
|
434 DCL_TEST2(TUint32, ADD, 0xFFFFFFFE, 0x00000003), |
|
435 DCL_TEST2(TUint32, ADD, 0x00009912, 0x00000023), |
|
436 DCL_TEST2(TUint32, ADD, 0x00009912, 0x4937BCFF), |
|
437 |
|
438 DCL_TEST2(TUint32, AND, 0x00000000, 0x00000001), |
|
439 DCL_TEST2(TUint32, AND, 0xFFFFFFFF, 0x00000001), |
|
440 DCL_TEST2(TUint32, AND, 0xFFFFFFFE, 0x00000001), |
|
441 DCL_TEST2(TUint32, AND, 0xFFFFFFFE, 0xFFFFFFFF), |
|
442 DCL_TEST2(TUint32, AND, 0xFFFFFFFE, 0x00000F03), |
|
443 DCL_TEST2(TUint32, AND, 0xEDCBBC5F, 0xDCBA14AF), |
|
444 |
|
445 DCL_TEST2(TUint32, IOR, 0x00000000, 0x00000001), |
|
446 DCL_TEST2(TUint32, IOR, 0xFFFFFFFF, 0x00000001), |
|
447 DCL_TEST2(TUint32, IOR, 0xFFFFFFFE, 0x00000001), |
|
448 DCL_TEST2(TUint32, IOR, 0x0000000D, 0x0000005F), |
|
449 DCL_TEST2(TUint32, IOR, 0x80000030, 0x00000803), |
|
450 DCL_TEST2(TUint32, IOR, 0x89AB145F, 0x415256AF), |
|
451 |
|
452 DCL_TEST2(TUint32, XOR, 0x00000000, 0x00000001), |
|
453 DCL_TEST2(TUint32, XOR, 0xFFFFFFFF, 0x00000001), |
|
454 DCL_TEST2(TUint32, XOR, 0xFFFFFFFE, 0x00000001), |
|
455 DCL_TEST2(TUint32, XOR, 0xFFFFFFFE, 0xFFFFFFFF), |
|
456 DCL_TEST2(TUint32, XOR, 0xFFFFFFFE, 0x00000003), |
|
457 DCL_TEST2(TUint32, XOR, 0x89AB145F, 0x4152BCAF), |
|
458 |
|
459 DCL_TEST3(TUint32, AXO, 0x00000000, 0xFFFFFFFF, 0x00000000), |
|
460 DCL_TEST3(TUint32, AXO, 0x00000000, 0xFFFFFFFF, 0x99CC6633), |
|
461 DCL_TEST3(TUint32, AXO, 0x00000000, 0xFFFFFFFF, 0x8000027D), |
|
462 DCL_TEST3(TUint32, AXO, 0x00000000, 0xFFFFFFFF, 0xEEDDCCBB), |
|
463 DCL_TEST3(TUint32, AXO, 0xAAAAAAAA, 0x00000000, 0x00000000), |
|
464 DCL_TEST3(TUint32, AXO, 0xAAAAAAAA, 0x00000000, 0x99CC6633), |
|
465 DCL_TEST3(TUint32, AXO, 0xAAAAAAAA, 0x00000000, 0x8000027D), |
|
466 DCL_TEST3(TUint32, AXO, 0xAAAAAAAA, 0x00000000, 0xEEDDCCBB), |
|
467 DCL_TEST3(TUint32, AXO, 0xAAAAAAAA, 0x9966CC33, 0x0FF00FF0), |
|
468 DCL_TEST3(TUint32, AXO, 0xAAAAAAAA, 0x9966CC33, 0xF00FF00F), |
|
469 DCL_TEST3(TUint32, AXO, 0xAAAAAAAA, 0x669933CC, 0x0FF00FF0), |
|
470 DCL_TEST3(TUint32, AXO, 0xAAAAAAAA, 0x669933CC, 0xF00FF00F), |
|
471 |
|
472 DCL_TEST3(TUint32, CAS, 0x00000000, 0x000000FF, 0x99ABCDEE), |
|
473 DCL_TEST3(TUint32, CAS, 0x00000000, 0x00000001, 0x7FFFF711), |
|
474 DCL_TEST3(TUint32, CAS, 0x00000000, 0x00000000, 0x99ABCDEE), |
|
475 DCL_TEST3(TUint32, CAS, 0x00000000, 0x00000000, 0x11234567), |
|
476 DCL_TEST3(TUint32, CAS, 0x8000032A, 0xFFFFFFFF, 0x8000032B), |
|
477 DCL_TEST3(TUint32, CAS, 0x8000032A, 0x00000001, 0x8000032B), |
|
478 DCL_TEST3(TUint32, CAS, 0x8000032A, 0x8000022A, 0x8000032B), |
|
479 DCL_TEST3(TUint32, CAS, 0x8000032A, 0x8000032B, 0x943BFCD1), |
|
480 DCL_TEST3(TUint32, CAS, 0x8000032A, 0x8000032A, 0x8000032B), |
|
481 DCL_TEST3(TUint32, CAS, 0x8000032A, 0x8000032A, 0x943BFCD1), |
|
482 |
|
483 DCL_TEST4(TUint32, TAU, 0x00000000, 0x00000000, 0x00000002, 0x00000003), |
|
484 DCL_TEST4(TUint32, TAU, 0x00000001, 0x00000000, 0x00000002, 0x00000003), |
|
485 DCL_TEST4(TUint32, TAU, 0xFFFFFFFF, 0x00000000, 0x00000002, 0x00000003), |
|
486 DCL_TEST4(TUint32, TAU, 0x00000000, 0x00000001, 0x00000002, 0x00000003), |
|
487 DCL_TEST4(TUint32, TAU, 0x00000001, 0x00000001, 0x00000002, 0x00000003), |
|
488 DCL_TEST4(TUint32, TAU, 0x00000002, 0x00000001, 0x00000002, 0x00000003), |
|
489 DCL_TEST4(TUint32, TAU, 0xFFFFFFFF, 0x00000001, 0x00000002, 0x00000003), |
|
490 DCL_TEST4(TUint32, TAU, 0xFFFFFFFE, 0xFFFFFFFE, 0x1023144F, 0x0000000B), |
|
491 DCL_TEST4(TUint32, TAU, 0xFFFFFFEE, 0xFFFFFFFE, 0x1423144F, 0x0000000B), |
|
492 DCL_TEST4(TUint32, TAU, 0xFFFFFFFF, 0xFFFFFFFE, 0x1423144F, 0x0000000B), |
|
493 DCL_TEST4(TUint32, TAU, 0x00000000, 0xFFFFFFFE, 0x1423144F, 0x0000000B), |
|
494 DCL_TEST4(TUint32, TAU, 0xFFFFFFFE, 0xFFFFFFFE, 0x80000000, 0x7FFFFFFF), |
|
495 DCL_TEST4(TUint32, TAU, 0xFFFFFFEE, 0xFFFFFFFE, 0x80000000, 0x7FFFFFFF), |
|
496 DCL_TEST4(TUint32, TAU, 0xFFFFFFFF, 0xFFFFFFFE, 0x80000000, 0x7FFFFFFF), |
|
497 DCL_TEST4(TUint32, TAU, 0x00000000, 0xFFFFFFFE, 0x80000000, 0x7FFFFFFF), |
|
498 DCL_TEST4(TUint32, TAU, 0xFFFFFFFE, 0x80000000, 0x80000001, 0x7FFFFFFE), |
|
499 DCL_TEST4(TUint32, TAU, 0x7FFFFFFF, 0x80000000, 0x80000001, 0x7FFFFFFE), |
|
500 DCL_TEST4(TUint32, TAU, 0x80000000, 0x80000000, 0x80000001, 0x7FFFFFFE), |
|
501 DCL_TEST4(TUint32, TAU, 0x80000001, 0x80000000, 0x80000001, 0x7FFFFFFE), |
|
502 DCL_TEST4(TUint32, TAU, 0x00000000, 0x80000000, 0x80000001, 0x7FFFFFFE), |
|
503 DCL_TEST4(TUint32, TAU, 0x7FFFFFFE, 0x7FFFFFFF, 0x80000001, 0x7FFFFFFE), |
|
504 DCL_TEST4(TUint32, TAU, 0x7FFFFFFF, 0x7FFFFFFF, 0x80000001, 0x7FFFFFFE), |
|
505 DCL_TEST4(TUint32, TAU, 0x80000000, 0x7FFFFFFF, 0x80000001, 0x7FFFFFFE), |
|
506 DCL_TEST4(TUint32, TAU, 0x80000001, 0x7FFFFFFF, 0x80000001, 0x7FFFFFFE), |
|
507 DCL_TEST4(TUint32, TAU, 0x00000000, 0x7FFFFFFF, 0x80000001, 0x7FFFFFFE), |
|
508 |
|
509 DCL_TEST4(TUint32, TAS, 0x00000000, 0x00000000, 0x00000002, 0x00000003), |
|
510 DCL_TEST4(TUint32, TAS, 0x00000001, 0x00000000, 0x00000002, 0x00000003), |
|
511 DCL_TEST4(TUint32, TAS, 0xFFFFFFFF, 0x00000000, 0x00000002, 0x00000003), |
|
512 DCL_TEST4(TUint32, TAS, 0x00000000, 0x00000001, 0x00000002, 0x00000003), |
|
513 DCL_TEST4(TUint32, TAS, 0x00000001, 0x00000001, 0x00000002, 0x00000003), |
|
514 DCL_TEST4(TUint32, TAS, 0x00000002, 0x00000001, 0x00000002, 0x00000003), |
|
515 DCL_TEST4(TUint32, TAS, 0xFFFFFFFF, 0x00000001, 0x00000002, 0x00000003), |
|
516 DCL_TEST4(TUint32, TAS, 0xFFFFFFFE, 0xFFFFFFFE, 0x1023144F, 0x0000000B), |
|
517 DCL_TEST4(TUint32, TAS, 0xFFFFFFEE, 0xFFFFFFFE, 0x1423144F, 0x0000000B), |
|
518 DCL_TEST4(TUint32, TAS, 0xFFFFFFFF, 0xFFFFFFFE, 0x1423144F, 0x0000000B), |
|
519 DCL_TEST4(TUint32, TAS, 0x00000000, 0xFFFFFFFE, 0x1423144F, 0x0000000B), |
|
520 DCL_TEST4(TUint32, TAS, 0xFFFFFFFE, 0xFFFFFFFE, 0x80000000, 0x7FFFFFFF), |
|
521 DCL_TEST4(TUint32, TAS, 0xFFFFFFEE, 0xFFFFFFFE, 0x80000000, 0x7FFFFFFF), |
|
522 DCL_TEST4(TUint32, TAS, 0xFFFFFFFF, 0xFFFFFFFE, 0x80000000, 0x7FFFFFFF), |
|
523 DCL_TEST4(TUint32, TAS, 0x00000000, 0xFFFFFFFE, 0x80000000, 0x7FFFFFFF), |
|
524 DCL_TEST4(TUint32, TAS, 0xFFFFFFFE, 0x80000000, 0x80000001, 0x7FFFFFFE), |
|
525 DCL_TEST4(TUint32, TAS, 0x7FFFFFFF, 0x80000000, 0x80000001, 0x7FFFFFFE), |
|
526 DCL_TEST4(TUint32, TAS, 0x80000000, 0x80000000, 0x80000001, 0x7FFFFFFE), |
|
527 DCL_TEST4(TUint32, TAS, 0x80000001, 0x80000000, 0x80000001, 0x7FFFFFFE), |
|
528 DCL_TEST4(TUint32, TAS, 0x00000000, 0x80000000, 0x80000001, 0x7FFFFFFE), |
|
529 DCL_TEST4(TUint32, TAS, 0x7FFFFFFE, 0x7FFFFFFF, 0x80000001, 0x7FFFFFFE), |
|
530 DCL_TEST4(TUint32, TAS, 0x7FFFFFFF, 0x7FFFFFFF, 0x80000001, 0x7FFFFFFE), |
|
531 DCL_TEST4(TUint32, TAS, 0x80000000, 0x7FFFFFFF, 0x80000001, 0x7FFFFFFE), |
|
532 DCL_TEST4(TUint32, TAS, 0x80000001, 0x7FFFFFFF, 0x80000001, 0x7FFFFFFE), |
|
533 DCL_TEST4(TUint32, TAS, 0x00000000, 0x7FFFFFFF, 0x80000001, 0x7FFFFFFE) |
|
534 }; |
|
535 |
|
536 DCL_TEST_BLOCK(TUint64,TestData64) |
|
537 { |
|
538 DCL_TEST1(TUint64, LOAD, MAKE_TUINT64(0x00000000,0x00000000)), |
|
539 DCL_TEST1(TUint64, LOAD, MAKE_TUINT64(0xFEDCBA98,0x76543210)), |
|
540 |
|
541 DCL_TEST2(TUint64, STORE, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0xFCD1CC9F,0xDB27CC8B)), |
|
542 DCL_TEST2(TUint64, STORE, MAKE_TUINT64(0xFEDCBA98,0x76543210), MAKE_TUINT64(0x06931471,0x80559945)), |
|
543 |
|
544 DCL_TEST2(TUint64, SWP, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0xFCD1CC9F,0xDB27CC8B)), |
|
545 DCL_TEST2(TUint64, SWP, MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xFCD1CC9F,0xDB27CC8B)), |
|
546 DCL_TEST2(TUint64, SWP, MAKE_TUINT64(0xDEADBEEF,0xBAD0BEEF), MAKE_TUINT64(0x06931471,0x80559945)), |
|
547 DCL_TEST2(TUint64, SWP, MAKE_TUINT64(0xFEDCBA98,0x76543210), MAKE_TUINT64(0x06931471,0x80559945)), |
|
548 |
|
549 DCL_TEST2(TUint64, ADD, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0x00000000,0x00000001)), |
|
550 DCL_TEST2(TUint64, ADD, MAKE_TUINT64(0x00000000,0xFFFFFFFF), MAKE_TUINT64(0x00000000,0x00000001)), |
|
551 DCL_TEST2(TUint64, ADD, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0xFCD1CC9F,0xDB27CC8B)), |
|
552 DCL_TEST2(TUint64, ADD, MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xFCD1CC9F,0xDB27CC8B)), |
|
553 |
|
554 DCL_TEST2(TUint64, AND, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0x00000000,0x00000001)), |
|
555 DCL_TEST2(TUint64, AND, MAKE_TUINT64(0x00000000,0xFFFFFFFF), MAKE_TUINT64(0x00000000,0x00000001)), |
|
556 DCL_TEST2(TUint64, AND, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0xFCD1CC9F,0xDB27CC8B)), |
|
557 DCL_TEST2(TUint64, AND, MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xFCD1CC9F,0xDB27CC8B)), |
|
558 |
|
559 DCL_TEST2(TUint64, IOR, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0x00000000,0x00000001)), |
|
560 DCL_TEST2(TUint64, IOR, MAKE_TUINT64(0x00000000,0xFFFFFFFF), MAKE_TUINT64(0x00000000,0x00000001)), |
|
561 DCL_TEST2(TUint64, IOR, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0xFCD1CC9F,0xDB27CC8B)), |
|
562 DCL_TEST2(TUint64, IOR, MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xFCD1CC9F,0xDB27CC8B)), |
|
563 DCL_TEST2(TUint64, IOR, MAKE_TUINT64(0x11111111,0x22222222), MAKE_TUINT64(0x44444444,0x55555555)), |
|
564 |
|
565 DCL_TEST2(TUint64, XOR, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0x00000000,0x00000001)), |
|
566 DCL_TEST2(TUint64, XOR, MAKE_TUINT64(0x00000000,0xFFFFFFFF), MAKE_TUINT64(0x00000000,0x00000001)), |
|
567 DCL_TEST2(TUint64, XOR, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0xFCD1CC9F,0xDB27CC8B)), |
|
568 DCL_TEST2(TUint64, XOR, MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xFCD1CC9F,0xDB27CC8B)), |
|
569 DCL_TEST2(TUint64, XOR, MAKE_TUINT64(0x11111111,0x22222222), MAKE_TUINT64(0x44444444,0x77777777)), |
|
570 |
|
571 DCL_TEST3(TUint64, AXO, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0xFFFFFFFF,0xFFFFFFFF), MAKE_TUINT64(0x00000000,0x00000001)), |
|
572 DCL_TEST3(TUint64, AXO, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0xFFFFFFFF,0xFFFFFFFF), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED)), |
|
573 DCL_TEST3(TUint64, AXO, MAKE_TUINT64(0xFFFFFFFF,0xFFFFFFFF), MAKE_TUINT64(0xFFFFFFFF,0xFFFFFFFF), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED)), |
|
574 DCL_TEST3(TUint64, AXO, MAKE_TUINT64(0xFFFFFFFF,0xFFFFFFFF), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED)), |
|
575 DCL_TEST3(TUint64, AXO, MAKE_TUINT64(0xFFFFFFFF,0xFFFFFFFF), MAKE_TUINT64(0xFACEFEED,0xFEEDFACE), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED)), |
|
576 DCL_TEST3(TUint64, AXO, MAKE_TUINT64(0xBAD8BEEF,0xDEADDEAD), MAKE_TUINT64(0xFACEFEED,0xFEEDFACE), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED)), |
|
577 |
|
578 DCL_TEST3(TUint64, CAS, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED)), |
|
579 DCL_TEST3(TUint64, CAS, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0x00000001,0x00000000), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED)), |
|
580 DCL_TEST3(TUint64, CAS, MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED)), |
|
581 DCL_TEST3(TUint64, CAS, MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0x00000001,0x00000000), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED)), |
|
582 DCL_TEST3(TUint64, CAS, MAKE_TUINT64(0x00000001,0x00000000), MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED)), |
|
583 DCL_TEST3(TUint64, CAS, MAKE_TUINT64(0x00000001,0x00000000), MAKE_TUINT64(0x00000001,0x00000000), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED)), |
|
584 |
|
585 DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
586 DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
587 DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0xFFFFFFFF,0xFFFFFFFF), MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
588 DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
589 DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
590 DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x00000000,0x00000002), MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
591 DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0xFFFFFFFF,0xFFFFFFFF), MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
592 DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0xFFFFFFFF,0x00000000), MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
593 DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x80000000,0x00000000), MAKE_TUINT64(0x80000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
594 DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x80000000,0x00000001), MAKE_TUINT64(0x80000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
595 DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x80000000,0x00000002), MAKE_TUINT64(0x80000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
596 DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x7FFFFFFF,0xFFFFFFFF), MAKE_TUINT64(0x80000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
597 DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x7FFFFFFF,0x00000000), MAKE_TUINT64(0x80000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
598 DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
599 DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x7FFFFFFF,0x80000000), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
600 DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x7FFFFFFF,0x80000002), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
601 DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x7FFFFFFF,0xFFFFFFFF), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
602 DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x7FFFFFFF,0x7FFFFFFF), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
603 DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x80000000,0x00000000), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
604 DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x80000000,0x80000000), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
605 DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x80000000,0x80000001), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
606 DCL_TEST4(TUint64, TAU, MAKE_TUINT64(0x80000000,0x80000002), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
607 |
|
608 DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
609 DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
610 DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0xFFFFFFFF,0xFFFFFFFF), MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
611 DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x00000000,0x00000000), MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
612 DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
613 DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x00000000,0x00000002), MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
614 DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0xFFFFFFFF,0xFFFFFFFF), MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
615 DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0xFFFFFFFF,0x00000000), MAKE_TUINT64(0x00000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
616 DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x80000000,0x00000000), MAKE_TUINT64(0x80000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
617 DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x80000000,0x00000001), MAKE_TUINT64(0x80000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
618 DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x80000000,0x00000002), MAKE_TUINT64(0x80000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
619 DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x7FFFFFFF,0xFFFFFFFF), MAKE_TUINT64(0x80000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
620 DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x7FFFFFFF,0x00000000), MAKE_TUINT64(0x80000000,0x00000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
621 DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
622 DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x7FFFFFFF,0x80000000), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
623 DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x7FFFFFFF,0x80000002), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
624 DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x7FFFFFFF,0xFFFFFFFF), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
625 DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x7FFFFFFF,0x7FFFFFFF), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
626 DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x80000000,0x00000000), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
627 DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x80000000,0x80000000), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
628 DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x80000000,0x80000001), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)), |
|
629 DCL_TEST4(TUint64, TAS, MAKE_TUINT64(0x80000000,0x80000002), MAKE_TUINT64(0x7FFFFFFF,0x80000001), MAKE_TUINT64(0xFEEDFACE,0xFACEFEED), MAKE_TUINT64(0xBAD9BEEF,0x00FAECE5)) |
|
630 }; |
|
631 |
|
632 |
|
633 |
|
634 template<class T> |
|
635 void DoTestBlock(const TD<T>* aTests, TInt aCount) |
|
636 { |
|
637 const TD<T>* p = aTests; |
|
638 const TD<T>* e = aTests + aCount; |
|
639 for (; p<e; ++p) |
|
640 { |
|
641 TInt ord; |
|
642 for (ord=EOrderRelaxed; ord<=EOrderOrdered; ++ord) |
|
643 { |
|
644 TDG tdg; |
|
645 tdg.Set(*p, ord); |
|
646 if (tdg.iIndex<0) |
|
647 continue; |
|
648 #ifdef __EXTRA_DEBUG__ |
|
649 TPtrC8 fname8((const TText8*)FuncName[tdg.iIndex]); |
|
650 TBuf<64> fname; |
|
651 fname.Copy(fname8); |
|
652 test.Printf(_L("%S\n"), &fname); |
|
653 #endif |
|
654 TInt res; |
|
655 res = tdg.ExecuteUser(); |
|
656 if (res!=0) |
|
657 { |
|
658 tdg.Dump("ExecuteUser"); |
|
659 test.Printf(_L("FAIL %d\n"),res); |
|
660 test(0); |
|
661 } |
|
662 #ifdef __EPOC32__ |
|
663 #ifdef __EXTRA_DEBUG__ |
|
664 test.Printf(_L("%S K\n"), &fname); |
|
665 #endif |
|
666 res = tdg.ExecuteKernel(); |
|
667 if (res!=0) |
|
668 { |
|
669 tdg.Dump("ExecuteKernel"); |
|
670 test.Printf(_L("FAIL %d\n"),res); |
|
671 test(0); |
|
672 } |
|
673 #endif |
|
674 } |
|
675 } |
|
676 } |
|
677 |
|
678 #define DO_TEST_BLOCK(type,array) \ |
|
679 DoTestBlock<type>(&(array)[0],(TInt)(sizeof(array)/sizeof(TD<type>))) |
|
680 |
|
681 void TestSingleThread() |
|
682 { |
|
683 test.Next(_L("8 bit, single thread")); |
|
684 DO_TEST_BLOCK(TUint8, TestData8); |
|
685 test.Next(_L("16 bit, single thread")); |
|
686 DO_TEST_BLOCK(TUint16, TestData16); |
|
687 test.Next(_L("32 bit, single thread")); |
|
688 DO_TEST_BLOCK(TUint32, TestData32); |
|
689 test.Next(_L("64 bit, single thread")); |
|
690 DO_TEST_BLOCK(TUint64, TestData64); |
|
691 } |
|
692 |
|
693 |
|
694 |
|
695 /****************************************************************************** |
|
696 * Test invalid address handling when called from user mode |
|
697 ******************************************************************************/ |
|
698 const TLinAddr KSpecialAddr = 0x100u; |
|
699 const TInt KIndexRead = -1; |
|
700 const TInt KIndexReadWrite = -2; |
|
701 |
|
702 struct TE |
|
703 { |
|
704 static TInt Execute(TInt aIndex, TAny* aPtr1, TAny* aPtr2, TInt aResult); |
|
705 TInt DoExecute(); |
|
706 static TInt ThreadFn(TAny*); |
|
707 |
|
708 TInt iIndex; |
|
709 TAny* iPtr1; |
|
710 TAny* iPtr2; |
|
711 }; |
|
712 |
|
713 template<class T> TInt DoLoadErrorTest(TInt aIndex, const T* aPtr) |
|
714 { |
|
715 typename TLoadFn<T>::F atomic = (typename TLoadFn<T>::F)AtomicFuncPtr[aIndex]; |
|
716 atomic(aPtr); |
|
717 return 0; |
|
718 } |
|
719 |
|
720 template<class T> TInt DoRmw1ErrorTest(TInt aIndex, T* aPtr) |
|
721 { |
|
722 typename TRmw1Fn<T>::F atomic = (typename TRmw1Fn<T>::F)AtomicFuncPtr[aIndex]; |
|
723 T a1 = 0; |
|
724 atomic(aPtr, a1); |
|
725 return 0; |
|
726 } |
|
727 |
|
728 template<class T> TInt DoRmw2ErrorTest(TInt aIndex, T* aPtr) |
|
729 { |
|
730 typename TRmw2Fn<T>::F atomic = (typename TRmw2Fn<T>::F)AtomicFuncPtr[aIndex]; |
|
731 T a1 = 0; |
|
732 T a2 = 0; |
|
733 atomic(aPtr, a1, a2); |
|
734 return 0; |
|
735 } |
|
736 |
|
737 template<class T> TInt DoRmw3ErrorTest(TInt aIndex, T* aPtr) |
|
738 { |
|
739 typename TRmw3Fn<T>::F atomic = (typename TRmw3Fn<T>::F)AtomicFuncPtr[aIndex]; |
|
740 T a1 = 0; |
|
741 T a2 = 0; |
|
742 T a3 = 0; |
|
743 atomic(aPtr, a1, a2, a3); |
|
744 return 0; |
|
745 } |
|
746 |
|
747 template<class T> TInt DoCasErrorTest(TInt aIndex, T* aPtr1, T* aPtr2) |
|
748 { |
|
749 typename TCasFn<T>::F atomic = (typename TCasFn<T>::F)AtomicFuncPtr[aIndex]; |
|
750 TLinAddr a1 = (TLinAddr)aPtr1; |
|
751 TLinAddr a2 = (TLinAddr)aPtr2; |
|
752 T reg; |
|
753 T exp; |
|
754 T f; |
|
755 memset(&f, 0xbb, sizeof(T)); |
|
756 if ((a1&~0xff)==KSpecialAddr) |
|
757 { |
|
758 memset(®, (a1&0xff), sizeof(T)); |
|
759 aPtr1 = ® |
|
760 } |
|
761 if ((a2&~0xff)==KSpecialAddr) |
|
762 { |
|
763 memset(&exp, (a2&0xff), sizeof(T)); |
|
764 aPtr2 = &exp; |
|
765 } |
|
766 TInt r = atomic(aPtr1, aPtr2, f); |
|
767 return r ? 1 : 0; |
|
768 } |
|
769 |
|
770 TInt TE::DoExecute() |
|
771 { |
|
772 if (iIndex == KIndexRead) |
|
773 { |
|
774 return *(volatile TUint8*)iPtr1; |
|
775 } |
|
776 if (iIndex == KIndexReadWrite) |
|
777 { |
|
778 volatile TUint8* p = (volatile TUint8*)iPtr1; |
|
779 TUint8 x = *p; |
|
780 *p = x; |
|
781 return 0; |
|
782 } |
|
783 TUint attr = FuncAttr[iIndex]; |
|
784 TInt type = ATTR_TO_TYPE(attr); |
|
785 TInt size = ATTR_TO_SIZE(attr); |
|
786 if (type==EFuncTypeInvalid) |
|
787 return KErrNotSupported; |
|
788 TInt res; |
|
789 switch (type) |
|
790 { |
|
791 case EFuncTypeLoad: |
|
792 { |
|
793 switch (size) |
|
794 { |
|
795 case 1: res = DoLoadErrorTest<TUint8>(iIndex, (TUint8*)iPtr1); break; |
|
796 case 2: res = DoLoadErrorTest<TUint16>(iIndex, (TUint16*)iPtr1); break; |
|
797 case 4: res = DoLoadErrorTest<TUint32>(iIndex, (TUint32*)iPtr1); break; |
|
798 case 8: res = DoLoadErrorTest<TUint64>(iIndex, (TUint64*)iPtr1); break; |
|
799 default: res = KErrNotSupported; break; |
|
800 } |
|
801 break; |
|
802 } |
|
803 case EFuncTypeRmw1: |
|
804 { |
|
805 switch (size) |
|
806 { |
|
807 case 1: res = DoRmw1ErrorTest<TUint8>(iIndex, (TUint8*)iPtr1); break; |
|
808 case 2: res = DoRmw1ErrorTest<TUint16>(iIndex, (TUint16*)iPtr1); break; |
|
809 case 4: res = DoRmw1ErrorTest<TUint32>(iIndex, (TUint32*)iPtr1); break; |
|
810 case 8: res = DoRmw1ErrorTest<TUint64>(iIndex, (TUint64*)iPtr1); break; |
|
811 default: res = KErrNotSupported; break; |
|
812 } |
|
813 break; |
|
814 } |
|
815 case EFuncTypeRmw2: |
|
816 { |
|
817 switch (size) |
|
818 { |
|
819 case 1: res = DoRmw2ErrorTest<TUint8>(iIndex, (TUint8*)iPtr1); break; |
|
820 case 2: res = DoRmw2ErrorTest<TUint16>(iIndex, (TUint16*)iPtr1); break; |
|
821 case 4: res = DoRmw2ErrorTest<TUint32>(iIndex, (TUint32*)iPtr1); break; |
|
822 case 8: res = DoRmw2ErrorTest<TUint64>(iIndex, (TUint64*)iPtr1); break; |
|
823 default: res = KErrNotSupported; break; |
|
824 } |
|
825 break; |
|
826 } |
|
827 case EFuncTypeRmw3: |
|
828 { |
|
829 switch (size) |
|
830 { |
|
831 case 1: res = DoRmw3ErrorTest<TUint8>(iIndex, (TUint8*)iPtr1); break; |
|
832 case 2: res = DoRmw3ErrorTest<TUint16>(iIndex, (TUint16*)iPtr1); break; |
|
833 case 4: res = DoRmw3ErrorTest<TUint32>(iIndex, (TUint32*)iPtr1); break; |
|
834 case 8: res = DoRmw3ErrorTest<TUint64>(iIndex, (TUint64*)iPtr1); break; |
|
835 default: res = KErrNotSupported; break; |
|
836 } |
|
837 break; |
|
838 } |
|
839 case EFuncTypeCas: |
|
840 { |
|
841 switch (size) |
|
842 { |
|
843 case 1: res = DoCasErrorTest<TUint8>(iIndex, (TUint8*)iPtr1, (TUint8*)iPtr2); break; |
|
844 case 2: res = DoCasErrorTest<TUint16>(iIndex, (TUint16*)iPtr1, (TUint16*)iPtr2); break; |
|
845 case 4: res = DoCasErrorTest<TUint32>(iIndex, (TUint32*)iPtr1, (TUint32*)iPtr2); break; |
|
846 case 8: res = DoCasErrorTest<TUint64>(iIndex, (TUint64*)iPtr1, (TUint64*)iPtr2); break; |
|
847 default: res = KErrNotSupported; break; |
|
848 } |
|
849 break; |
|
850 } |
|
851 default: |
|
852 res = KErrNotSupported; |
|
853 break; |
|
854 } |
|
855 return res; |
|
856 } |
|
857 |
|
858 TInt TE::ThreadFn(TAny* aPtr) |
|
859 { |
|
860 return ((TE*)aPtr)->DoExecute(); |
|
861 } |
|
862 |
|
863 _LIT(KLitKERNEXEC,"KERN-EXEC"); |
|
864 TInt TE::Execute(TInt aIndex, TAny* aPtr1, TAny* aPtr2, TInt aResult) |
|
865 { |
|
866 DEBUGPRINT("I=%3d P1=%08x P2=%08x R=%d", aIndex, aPtr1, aPtr2, aResult); |
|
867 TE te; |
|
868 te.iIndex = aIndex; |
|
869 te.iPtr1 = aPtr1; |
|
870 te.iPtr2 = aPtr2; |
|
871 RThread t; |
|
872 TInt r = t.Create(KNullDesC, &ThreadFn, 0x1000, 0, &te); |
|
873 test_KErrNone(r); |
|
874 TRequestStatus s; |
|
875 t.Logon(s); |
|
876 test_Equal(KRequestPending, s.Int()); |
|
877 TBool jit = User::JustInTime(); |
|
878 User::SetJustInTime(EFalse); |
|
879 t.Resume(); |
|
880 User::WaitForRequest(s); |
|
881 User::SetJustInTime(jit); |
|
882 TInt xt = t.ExitType(); |
|
883 TInt xr = t.ExitReason(); |
|
884 const TDesC& xc = t.ExitCategory(); |
|
885 DEBUGPRINT("Exit type: %d,%d,%S", xt, xr, &xc); |
|
886 TInt res = KErrNone; |
|
887 if (aResult == KErrUnknown) |
|
888 { |
|
889 if (xt==EExitPanic) |
|
890 { |
|
891 test_Equal(ECausedException, xr); |
|
892 test(xc==KLitKERNEXEC); |
|
893 res = KErrDied; |
|
894 } |
|
895 else |
|
896 test_Equal(EExitKill, xt); |
|
897 } |
|
898 else if (aResult == KErrDied) |
|
899 { |
|
900 test_Equal(EExitPanic, xt); |
|
901 test_Equal(ECausedException, xr); |
|
902 test(xc==KLitKERNEXEC); |
|
903 } |
|
904 else |
|
905 { |
|
906 test_Equal(EExitKill, xt); |
|
907 test_Equal(aResult, xr); |
|
908 } |
|
909 CLOSE_AND_WAIT(t); |
|
910 return res; |
|
911 } |
|
912 |
|
913 TInt ThreadAlign(TAny*) |
|
914 { |
|
915 TUint32 array[2]; |
|
916 TUint32* p = (TUint32*)(((TLinAddr)array)+1); |
|
917 *p = 5; |
|
918 return KErrNone; |
|
919 } |
|
920 |
|
921 const TUint64 Zero = UI64LIT(0); |
|
922 const TUint64 BFBF = UI64LIT(0xbfbfbfbfbfbfbfbf); |
|
923 |
|
924 void TestInvalidAddresses() |
|
925 { |
|
926 TAny* bad_addr[11]; |
|
927 TInt c = 0; |
|
928 TInt read_only = 0; |
|
929 TInt alignmentEnd = 0; |
|
930 TInt mminfo = UserSvr::HalFunction(EHalGroupKernel, EKernelHalMemModelInfo, 0, 0); |
|
931 // TInt mmtype = mminfo & EMemModelTypeMask; |
|
932 #ifdef __EPOC32__ |
|
933 if (mminfo & EMemModelAttrWriteProt) |
|
934 { |
|
935 bad_addr[c++] = (TAny*)UserSvr::RomHeaderAddress(); |
|
936 bad_addr[c++] = (TAny*)&Zero; |
|
937 bad_addr[c++] = (TAny*)&BFBF; |
|
938 read_only = c; |
|
939 } |
|
940 #endif |
|
941 if (mminfo & EMemModelAttrNonExProt) |
|
942 { |
|
943 bad_addr[c++] = 0; // address 0 is read only on ARM7 cores, nonexistent on others |
|
944 if (TE::Execute(KIndexRead, 0, 0, KErrUnknown)==KErrNone) |
|
945 read_only = c; // address 0 is readable |
|
946 TLinAddr nonex = 0; |
|
947 do { |
|
948 nonex += 0x1000; |
|
949 } while (TE::Execute(KIndexRead, (TAny*)nonex, 0, KErrUnknown)==KErrNone); |
|
950 bad_addr[c++] = (TAny*)nonex; |
|
951 } |
|
952 #ifdef __EPOC32__ |
|
953 if (mminfo & EMemModelAttrKernProt) |
|
954 { |
|
955 bad_addr[c++] = DD.KernelMemoryAddress(); |
|
956 } |
|
957 // If alignment checking is enabled add alignment tests for 64 bit. |
|
958 TUint64A alignArray[2]; |
|
959 RThread t; |
|
960 TInt r = t.Create(KNullDesC, &ThreadAlign, 0x1000, 0, NULL); |
|
961 test_KErrNone(r); |
|
962 TRequestStatus s; |
|
963 t.Logon(s); |
|
964 test_Equal(KRequestPending, s.Int()); |
|
965 TBool jit = User::JustInTime(); |
|
966 User::SetJustInTime(EFalse); |
|
967 t.Resume(); |
|
968 User::WaitForRequest(s); |
|
969 User::SetJustInTime(jit); |
|
970 TInt xt = t.ExitType(); |
|
971 TInt xr = t.ExitReason(); |
|
972 const TDesC& xc = t.ExitCategory(); |
|
973 if (EExitPanic == xt) |
|
974 {// Took an alignment fault so add alignment test. |
|
975 test_Equal(ECausedException, xr); |
|
976 test(xc==KLitKERNEXEC); |
|
977 alignmentEnd = c; |
|
978 bad_addr[alignmentEnd++] = (TAny*)(((TUint)&alignArray[0]) + 1); |
|
979 bad_addr[alignmentEnd++] = (TAny*)(((TUint)&alignArray[0]) + 2); |
|
980 bad_addr[alignmentEnd++] = (TAny*)(((TUint)&alignArray[0]) + 4); |
|
981 } |
|
982 |
|
983 #endif |
|
984 TInt i; |
|
985 TInt allBadAddr = (alignmentEnd)? c+3 : c; |
|
986 DEBUGPRINT("%d invalid addresses", allBadAddr); |
|
987 for (i=0; i < allBadAddr; ++i) |
|
988 { |
|
989 if (i<read_only) |
|
990 { |
|
991 DEBUGPRINT("bad_addr[%d]=%08x (RO)", i, bad_addr[i]); |
|
992 } |
|
993 else |
|
994 { |
|
995 DEBUGPRINT("bad_addr[%d]=%08x", i, bad_addr[i]); |
|
996 } |
|
997 } |
|
998 if (c==0) |
|
999 return; |
|
1000 TInt ix; |
|
1001 for (ix=0; ix<TOTAL_INDEXES; ++ix) |
|
1002 { |
|
1003 TUint attr = FuncAttr[ix]; |
|
1004 TUint func = ATTR_TO_FUNC(attr); |
|
1005 TUint type = ATTR_TO_TYPE(attr); |
|
1006 if (type==EFuncTypeInvalid) |
|
1007 continue; |
|
1008 if (func==TUint(EAtomicFuncCAS)) |
|
1009 { |
|
1010 // both addresses OK |
|
1011 TE::Execute(ix, (TAny*)(KSpecialAddr+0), (TAny*)(KSpecialAddr+0), 1); // should do the swap |
|
1012 TE::Execute(ix, (TAny*)(KSpecialAddr+0), (TAny*)(KSpecialAddr+1), 0); // should not do the swap |
|
1013 |
|
1014 // RMW address OK, expected bad |
|
1015 for (i=0; i<c; ++i) |
|
1016 { |
|
1017 TAny* p = bad_addr[i]; |
|
1018 TInt res = (bad_addr[i]==(TAny*)&BFBF) ? 1 : KErrDied; |
|
1019 TE::Execute(ix, (TAny*)(KSpecialAddr+0xbf), p, res); |
|
1020 } |
|
1021 |
|
1022 // RMW address bad, expected OK |
|
1023 for (i=0; i<c; ++i) |
|
1024 { |
|
1025 TAny* p = bad_addr[i]; |
|
1026 #if defined(__CPU_X86) |
|
1027 TInt res = KErrDied; // on X86 location must be writeable |
|
1028 #elif defined(__CPU_ARM) |
|
1029 TInt res = (i<read_only && bad_addr[i]!=(TAny*)&BFBF) ? 0 : KErrDied; |
|
1030 // 64-bit operations on platforms that use a slow exec for 64 bit |
|
1031 // will always write to bad_addr[i] but other platforms won't. |
|
1032 if (ATTR_TO_SIZE(attr) == 8) |
|
1033 res = KErrUnknown; |
|
1034 #else |
|
1035 #error CPU? |
|
1036 #endif |
|
1037 TE::Execute(ix, p, (TAny*)(KSpecialAddr+0xbf), res); |
|
1038 } |
|
1039 |
|
1040 // Both addresses bad |
|
1041 TInt j; |
|
1042 for (i=0; i<c; ++i) |
|
1043 { |
|
1044 for (j=0; j<c; ++j) |
|
1045 { |
|
1046 TE::Execute(ix, bad_addr[i], bad_addr[j], KErrDied); |
|
1047 } |
|
1048 } |
|
1049 } |
|
1050 else |
|
1051 { |
|
1052 // just run through all the bad addresses |
|
1053 for (i=0; i<c; ++i) |
|
1054 { |
|
1055 TAny* p = bad_addr[i]; |
|
1056 TBool ro = (i<read_only); |
|
1057 TInt res = ((func == TUint(EAtomicFuncLOAD)) && ro) ? KErrNone : KErrDied; |
|
1058 if (func==TUint(EAtomicFuncLOAD) && ATTR_TO_SIZE(attr)==8) |
|
1059 res = KErrUnknown; // 64-bit atomic loads may or may not write as well |
|
1060 TE::Execute(ix, p, 0, res); |
|
1061 } |
|
1062 } |
|
1063 // Checks for 8 byte alignment not enabled on old gcc (arm4) as it is not eabi compliant. |
|
1064 #if (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__EABI__) |
|
1065 if (ATTR_TO_SIZE(attr) == 8) |
|
1066 { |
|
1067 for (i = c; i < alignmentEnd; i++) |
|
1068 {// 64 bit unaligned accesses should cause exceptions if |
|
1069 // alignment checking is enabled. |
|
1070 TE::Execute(ix, bad_addr[i], 0, KErrDied); |
|
1071 } |
|
1072 } |
|
1073 #endif |
|
1074 } |
|
1075 } |
|
1076 |
|
1077 |
|
1078 |
|
1079 /****************************************************************************** |
|
1080 * Multiple thread normal operation tests |
|
1081 ******************************************************************************/ |
|
1082 class CThread; |
|
1083 class CThreads : public CBase |
|
1084 { |
|
1085 public: |
|
1086 static CThreads* New(); |
|
1087 CThreads(); |
|
1088 ~CThreads(); |
|
1089 CThread* NewThread(TInt aId); |
|
1090 void StartTest(TInt aIndex, TBool aKernel); |
|
1091 void StopTest(); |
|
1092 void Finish(); |
|
1093 TUint32 DoCasTest(TInt aIndex, TBool aKernel, TUint32 aFailLimit); |
|
1094 void DoRmwTest(TInt aIndex, TBool aKernel, TInt aTime); |
|
1095 inline TInt NumCpus() const {return iNumCpus;} |
|
1096 private: |
|
1097 TInt iNumCpus; |
|
1098 TInt iNumThreads; |
|
1099 CThread* iThreads[KMaxThreads]; |
|
1100 RSemaphore iSem; |
|
1101 volatile TInt iIndex; |
|
1102 volatile TBool iKernel; |
|
1103 volatile TBool iStop; |
|
1104 volatile TUint64 iReg; |
|
1105 TInt iFailCount; |
|
1106 TInt iTimeslice; |
|
1107 private: |
|
1108 friend class CThread; |
|
1109 }; |
|
1110 |
|
1111 class CThread : public CBase |
|
1112 { |
|
1113 private: |
|
1114 CThread(); |
|
1115 ~CThread(); |
|
1116 static TInt ThreadFunction(TAny*); |
|
1117 TInt Run(); |
|
1118 TInt Create(); |
|
1119 void Start(); |
|
1120 void DoTest(); |
|
1121 TUint64 Random(); |
|
1122 void Kick(); |
|
1123 private: |
|
1124 RThread iThread; |
|
1125 TInt iId; |
|
1126 CThreads* iThreads; |
|
1127 TRequestStatus iStatus; |
|
1128 TBool iStarted; |
|
1129 TPerThread iPerThread; |
|
1130 TUint64 iSeed; |
|
1131 private: |
|
1132 friend class CThreads; |
|
1133 }; |
|
1134 |
|
1135 CThreads::CThreads() |
|
1136 { |
|
1137 iNumCpus = UserSvr::HalFunction(EHalGroupKernel, EKernelHalNumLogicalCpus, 0, 0); |
|
1138 iNumThreads = iNumCpus; |
|
1139 if (iNumThreads<2) |
|
1140 iNumThreads=2; |
|
1141 TInt khz; |
|
1142 TInt r = HAL::Get(HAL::ECPUSpeed, khz); |
|
1143 if (r==KErrNone) |
|
1144 iTimeslice = Max(10000000/khz, 100); |
|
1145 else if (r==KErrNotSupported) |
|
1146 iTimeslice = 227; |
|
1147 else |
|
1148 User::Panic(_L("TIMESLICE"),r); |
|
1149 } |
|
1150 |
|
1151 CThreads::~CThreads() |
|
1152 { |
|
1153 TInt i; |
|
1154 for (i=0; i<iNumThreads; ++i) |
|
1155 delete iThreads[i]; |
|
1156 iSem.Close(); |
|
1157 } |
|
1158 |
|
1159 CThreads* CThreads::New() |
|
1160 { |
|
1161 CThreads* p = new CThreads; |
|
1162 if (p) |
|
1163 { |
|
1164 TInt r; |
|
1165 r = p->iSem.CreateLocal(0); |
|
1166 TInt i; |
|
1167 for (i=0; i<p->iNumThreads && r==KErrNone; ++i) |
|
1168 { |
|
1169 p->iThreads[i] = p->NewThread(i); |
|
1170 if (!p->iThreads[i]) |
|
1171 r = KErrNoMemory; |
|
1172 } |
|
1173 if (r!=KErrNone) |
|
1174 { |
|
1175 delete p; |
|
1176 return 0; |
|
1177 } |
|
1178 p->iStop = ETrue; |
|
1179 for (i=0; i<p->iNumThreads; ++i) |
|
1180 p->iThreads[i]->Start(); |
|
1181 } |
|
1182 return p; |
|
1183 } |
|
1184 |
|
1185 CThread* CThreads::NewThread(TInt aId) |
|
1186 { |
|
1187 CThread* t = new CThread; |
|
1188 if (t) |
|
1189 { |
|
1190 t->iId = aId; |
|
1191 t->iThreads = this; |
|
1192 TInt r = t->Create(); |
|
1193 if (r!=KErrNone) |
|
1194 { |
|
1195 delete t; |
|
1196 t = 0; |
|
1197 } |
|
1198 } |
|
1199 return t; |
|
1200 } |
|
1201 |
|
1202 void CThreads::StartTest(TInt aIndex, TBool aKernel) |
|
1203 { |
|
1204 iIndex = aIndex; |
|
1205 iKernel = aKernel; |
|
1206 iReg = 0; |
|
1207 iStop = EFalse; |
|
1208 #ifdef __EPOC32__ |
|
1209 if (iKernel) |
|
1210 DD.Initialise(iReg); |
|
1211 #endif |
|
1212 TInt i; |
|
1213 for (i=0; i<iNumThreads; ++i) |
|
1214 iThreads[i]->Kick(); |
|
1215 } |
|
1216 |
|
1217 void CThreads::StopTest() |
|
1218 { |
|
1219 iStop = ETrue; |
|
1220 TInt i; |
|
1221 for (i=0; i<iNumThreads; ++i) |
|
1222 iSem.Wait(); |
|
1223 #ifdef __EPOC32__ |
|
1224 if (iKernel) |
|
1225 iReg = DD.Retrieve(); |
|
1226 #endif |
|
1227 } |
|
1228 |
|
1229 void CThreads::Finish() |
|
1230 { |
|
1231 iStop = EFalse; |
|
1232 iIndex = -1; |
|
1233 TInt i; |
|
1234 for (i=0; i<iNumThreads; ++i) |
|
1235 { |
|
1236 iThreads[i]->Kick(); |
|
1237 iSem.Wait(); |
|
1238 } |
|
1239 test(iFailCount==0); |
|
1240 } |
|
1241 |
|
1242 TUint32 CThreads::DoCasTest(TInt aIndex, TBool aKernel, TUint32 aFailLimit) |
|
1243 { |
|
1244 TInt i; |
|
1245 test.Printf(_L("DoCasTest I=%d K=%1d F=%d\n"), aIndex, aKernel, aFailLimit); |
|
1246 TUint32 initial = User::FastCounter(); |
|
1247 StartTest(aIndex, aKernel); |
|
1248 FOREVER |
|
1249 { |
|
1250 User::AfterHighRes(1000000); |
|
1251 TUint64 minf = 0; |
|
1252 --minf; |
|
1253 for (i=0; i<iNumThreads; ++i) |
|
1254 { |
|
1255 CThread* t = iThreads[i]; |
|
1256 test.Printf(_L("T%1d: C=%lu R=%lu\n"), i, t->iPerThread.iDiff, t->iPerThread.iFailCount); |
|
1257 TUint64 f = t->iPerThread.iFailCount; |
|
1258 if (f<minf) |
|
1259 minf=f; |
|
1260 } |
|
1261 if (minf>=TUint64(aFailLimit)) |
|
1262 break; |
|
1263 if (iNumCpus>1) // 1 second is enough for SMP, except on VMPlayer |
|
1264 break; |
|
1265 } |
|
1266 StopTest(); |
|
1267 TUint32 final = User::FastCounter(); |
|
1268 TUint32 time = final - initial; |
|
1269 test.Printf(_L("Time %d\n"), time); |
|
1270 TUint64 total = 0; |
|
1271 TUint64 txor = 0; |
|
1272 for (i=0; i<iNumThreads; ++i) |
|
1273 { |
|
1274 CThread* t = iThreads[i]; |
|
1275 test.Printf(_L("T%1d: %lu completed %lu retries\n"), i, t->iPerThread.iDiff, t->iPerThread.iFailCount); |
|
1276 total += t->iPerThread.iDiff; |
|
1277 txor ^= t->iPerThread.iXor; |
|
1278 } |
|
1279 TUint size = ATTR_TO_SIZE(FuncAttr[aIndex]); |
|
1280 TUint64 expected = 0; |
|
1281 switch (size) |
|
1282 { |
|
1283 case 1: expected = Transform<TUint8>::F_iter(0, total); break; |
|
1284 case 2: expected = Transform<TUint16>::F_iter(0, total); break; |
|
1285 case 4: expected = Transform<TUint32>::F_iter(0, total); break; |
|
1286 case 8: expected = Transform<TUint64>::F_iter(0, total); break; |
|
1287 } |
|
1288 test.Printf(_L("Total iterations %lu\n"), total); |
|
1289 test.Printf(_L("Expected result %08x %08x\n"), I64HIGH(expected), I64LOW(expected)); |
|
1290 test.Printf(_L("Actual result %08x %08x\n"), I64HIGH(iReg), I64LOW(iReg)); |
|
1291 test.Printf(_L("Tot. XOR result %08x %08x\n"), I64HIGH(txor), I64LOW(txor)); |
|
1292 // test(expected==iReg); |
|
1293 // test(expected==txor); |
|
1294 if (expected!=iReg || expected!=txor) |
|
1295 { |
|
1296 test.Printf(_L("***FAIL***\n")); |
|
1297 ++iFailCount; |
|
1298 } |
|
1299 return time; |
|
1300 } |
|
1301 |
|
1302 void CThreads::DoRmwTest(TInt aIndex, TBool aKernel, TInt aTime) |
|
1303 { |
|
1304 TInt i; |
|
1305 test.Printf(_L("DoRmwTest I=%d K=%1d T=%d\n"), aIndex, aKernel, aTime); |
|
1306 StartTest(aIndex, aKernel); |
|
1307 User::AfterHighRes(aTime); |
|
1308 StopTest(); |
|
1309 TUint64 total = 0; |
|
1310 TUint64 txor = 0; |
|
1311 for (i=0; i<iNumThreads; ++i) |
|
1312 { |
|
1313 CThread* t = iThreads[i]; |
|
1314 test.Printf(_L("T%1d: C=%10lu D=%lx X=%lx\n"), i, t->iPerThread.iCount, t->iPerThread.iDiff, t->iPerThread.iXor); |
|
1315 total += t->iPerThread.iDiff; |
|
1316 txor ^= t->iPerThread.iXor; |
|
1317 } |
|
1318 TUint size = ATTR_TO_SIZE(FuncAttr[aIndex]); |
|
1319 switch (size) |
|
1320 { |
|
1321 case 1: |
|
1322 { |
|
1323 TUint8 expected = (TUint8)total; |
|
1324 TUint8 exor = (TUint8)txor; |
|
1325 TUint8 got = (TUint8)iReg; |
|
1326 test.Printf(_L("Expected %02x Got %02x XOR %02x\n"), expected, got, exor); |
|
1327 // test(expected==got && exor==got); |
|
1328 if (expected!=got || exor!=got) |
|
1329 { |
|
1330 test.Printf(_L("***FAIL***\n")); |
|
1331 ++iFailCount; |
|
1332 } |
|
1333 break; |
|
1334 } |
|
1335 case 2: |
|
1336 { |
|
1337 TUint16 expected = (TUint16)total; |
|
1338 TUint16 exor = (TUint16)txor; |
|
1339 TUint16 got = (TUint16)iReg; |
|
1340 test.Printf(_L("Expected %04x Got %04x XOR %04x\n"), expected, got, exor); |
|
1341 // test(expected==got && exor==got); |
|
1342 if (expected!=got || exor!=got) |
|
1343 { |
|
1344 test.Printf(_L("***FAIL***\n")); |
|
1345 ++iFailCount; |
|
1346 } |
|
1347 break; |
|
1348 } |
|
1349 case 4: |
|
1350 { |
|
1351 TUint32 expected = (TUint32)total; |
|
1352 TUint32 exor = (TUint32)txor; |
|
1353 TUint32 got = (TUint32)iReg; |
|
1354 test.Printf(_L("Expected %08x Got %08x XOR %08x\n"), expected, got, exor); |
|
1355 // test(expected==got && exor==got); |
|
1356 if (expected!=got || exor!=got) |
|
1357 { |
|
1358 test.Printf(_L("***FAIL***\n")); |
|
1359 ++iFailCount; |
|
1360 } |
|
1361 break; |
|
1362 } |
|
1363 case 8: |
|
1364 { |
|
1365 TUint64 expected = total; |
|
1366 test.Printf(_L("Expected result %08x %08x\n"), I64HIGH(expected), I64LOW(expected)); |
|
1367 test.Printf(_L("Actual result %08x %08x\n"), I64HIGH(iReg), I64LOW(iReg)); |
|
1368 test.Printf(_L("Tot. XOR result %08x %08x\n"), I64HIGH(txor), I64LOW(txor)); |
|
1369 // test(expected==iReg && expected==txor); |
|
1370 if (expected!=iReg || expected!=txor) |
|
1371 { |
|
1372 test.Printf(_L("***FAIL***\n")); |
|
1373 ++iFailCount; |
|
1374 } |
|
1375 break; |
|
1376 } |
|
1377 } |
|
1378 } |
|
1379 |
|
1380 CThread::CThread() |
|
1381 { |
|
1382 } |
|
1383 |
|
1384 CThread::~CThread() |
|
1385 { |
|
1386 TInt h = iThread.Handle(); |
|
1387 if (h && h!=KCurrentThreadHandle) |
|
1388 { |
|
1389 if (!iStarted) |
|
1390 iThread.Kill(0); |
|
1391 User::WaitForRequest(iStatus); |
|
1392 } |
|
1393 iThread.Close(); |
|
1394 } |
|
1395 |
|
1396 TInt CThread::Create() |
|
1397 { |
|
1398 TInt r = iThread.Create(KNullDesC, &ThreadFunction, 0x2000, 0, this); |
|
1399 if (r==KErrNone) |
|
1400 { |
|
1401 iThread.Logon(iStatus); |
|
1402 if (iStatus.Int() != KRequestPending) |
|
1403 r = iStatus.Int(); |
|
1404 } |
|
1405 return r; |
|
1406 } |
|
1407 |
|
1408 void CThread::Start() |
|
1409 { |
|
1410 iThread.Resume(); |
|
1411 iThreads->iSem.Wait(); |
|
1412 } |
|
1413 |
|
1414 void CThread::Kick() |
|
1415 { |
|
1416 TRequestStatus s; |
|
1417 TRequestStatus* pS = &s; |
|
1418 iThread.RequestComplete(pS,0); |
|
1419 } |
|
1420 |
|
1421 TInt CThread::ThreadFunction(TAny* aPtr) |
|
1422 { |
|
1423 return ((CThread*)aPtr)->Run(); |
|
1424 } |
|
1425 |
|
1426 TInt CThread::Run() |
|
1427 { |
|
1428 #ifdef __EPOC32__ |
|
1429 DD.SetCurrentThreadTimeslice(iThreads->iTimeslice); |
|
1430 #endif |
|
1431 RThread().SetPriority(EPriorityLess); |
|
1432 FOREVER |
|
1433 { |
|
1434 if (iThreads->iStop) |
|
1435 { |
|
1436 iThreads->iSem.Signal(); |
|
1437 if (iThreads->iNumCpus > 1) |
|
1438 RThread().SetPriority(EPriorityAbsoluteHigh); // encourage spreading out of threads between CPUs |
|
1439 User::WaitForAnyRequest(); |
|
1440 if (iThreads->iIndex<0) |
|
1441 break; |
|
1442 if (iThreads->iNumCpus > 1) |
|
1443 { |
|
1444 TUint32 tick = User::NTickCount(); |
|
1445 while(User::NTickCount()-tick < 2) {} // spin to discourage putting other threads on this CPU |
|
1446 RThread().SetPriority(EPriorityLess); |
|
1447 } |
|
1448 } |
|
1449 DoTest(); |
|
1450 } |
|
1451 iThreads->iSem.Signal(); |
|
1452 return 0; |
|
1453 } |
|
1454 |
|
1455 TUint64 CThread::Random() |
|
1456 { |
|
1457 iSeed = Transform<TUint64>::F(iSeed); |
|
1458 return iSeed; |
|
1459 } |
|
1460 |
|
1461 void CThread::DoTest() |
|
1462 { |
|
1463 iPerThread.iDiff = 0; |
|
1464 iPerThread.iXor = 0; |
|
1465 iPerThread.iFailCount = 0; |
|
1466 iPerThread.iCount = 0; |
|
1467 TInt index = iThreads->iIndex; |
|
1468 TAny* p = (TAny*)&iThreads->iReg; |
|
1469 #ifdef __EPOC32__ |
|
1470 TBool kernel = iThreads->iKernel; |
|
1471 if (kernel) |
|
1472 { |
|
1473 DD.SwitchExecTables(iId); |
|
1474 RTestAtomic::SetThreadInfo(iPerThread); |
|
1475 } |
|
1476 TInt iter = 0; |
|
1477 #endif |
|
1478 iSeed = iId; |
|
1479 while (!iThreads->iStop) |
|
1480 { |
|
1481 TAtomicAction action; |
|
1482 action.i0 = Random(); |
|
1483 action.i1 = Random(); |
|
1484 action.i2 = Random(); |
|
1485 action.iIndex = index; |
|
1486 action.iThread = iId; |
|
1487 #ifdef __EPOC32__ |
|
1488 if (kernel) |
|
1489 { |
|
1490 RTestAtomic::AtomicAction(action); |
|
1491 } |
|
1492 else |
|
1493 #endif |
|
1494 DoAtomicAction(p, &iPerThread, action); |
|
1495 #ifdef __EPOC32__ |
|
1496 if (kernel && ++iter==1024) |
|
1497 { |
|
1498 iter = 0; |
|
1499 RTestAtomic::GetThreadInfo(iPerThread); |
|
1500 } |
|
1501 #endif |
|
1502 } |
|
1503 #ifdef __EPOC32__ |
|
1504 if (kernel) |
|
1505 { |
|
1506 RTestAtomic::GetThreadInfo(iPerThread); |
|
1507 RTestAtomic::RestoreExecTable(); |
|
1508 } |
|
1509 #endif |
|
1510 } |
|
1511 |
|
1512 void TestMultipleThreads() |
|
1513 { |
|
1514 CThreads* p = CThreads::New(); |
|
1515 test(p!=0); |
|
1516 |
|
1517 TInt KRequiredRetries = 1000; |
|
1518 if (p->NumCpus()==1) |
|
1519 KRequiredRetries = 10; |
|
1520 |
|
1521 TUint32 time; |
|
1522 TUint32 total_time = 0; |
|
1523 TUint32 total_time_k = 0; |
|
1524 TUint32 count = 0; |
|
1525 TInt ix; |
|
1526 for (ix=0; ix<TOTAL_INDEXES; ++ix) |
|
1527 { |
|
1528 TUint attr = FuncAttr[ix]; |
|
1529 TUint func = ATTR_TO_FUNC(attr); |
|
1530 TUint type = ATTR_TO_TYPE(attr); |
|
1531 if (p->NumCpus()==1) |
|
1532 { |
|
1533 TUint ord = ATTR_TO_ORD(attr); |
|
1534 if (ord != EOrderOrdered) |
|
1535 continue; |
|
1536 } |
|
1537 if (type==EFuncTypeInvalid) |
|
1538 continue; |
|
1539 if (func!=TUint(EAtomicFuncCAS)) |
|
1540 continue; |
|
1541 time = p->DoCasTest(ix, EFalse, KRequiredRetries); |
|
1542 total_time += time; |
|
1543 ++count; |
|
1544 time = p->DoCasTest(ix, ETrue, KRequiredRetries); |
|
1545 total_time_k += time; |
|
1546 } |
|
1547 TUint32 avg_time = total_time / count; |
|
1548 TUint32 avg_time_k = total_time_k / count; |
|
1549 TUint32 fcf=0; |
|
1550 TInt r = HAL::Get(HAL::EFastCounterFrequency, (TInt&)fcf); |
|
1551 test_KErrNone(r); |
|
1552 test.Printf(_L("FastCounterFrequency = %u\n"), fcf); |
|
1553 TUint64 avg_time_us64(avg_time); |
|
1554 avg_time_us64*=UI64LIT(1000000); |
|
1555 avg_time_us64/=TUint64(fcf); |
|
1556 TInt avg_time_us = KMaxTInt; |
|
1557 TInt avg_time_k_us = KMaxTInt; |
|
1558 if (avg_time_us64<TUint64(KMaxTInt)) |
|
1559 avg_time_us = (TInt)avg_time_us64; |
|
1560 TUint64 avg_time_k_us64(avg_time); |
|
1561 avg_time_k_us64*=UI64LIT(1000000); |
|
1562 avg_time_k_us64/=TUint64(fcf); |
|
1563 if (avg_time_k_us64<TUint64(KMaxTInt)) |
|
1564 avg_time_k_us = (TInt)avg_time_k_us64; |
|
1565 |
|
1566 test.Printf(_L("Average time (user) %u (%dus)\n"), avg_time, avg_time_us); |
|
1567 test.Printf(_L("Average time (kernel) %u (%dus)\n"), avg_time_k, avg_time_k_us); |
|
1568 |
|
1569 TInt limit_us = (p->NumCpus()==1) ? 15*1000*1000 : 4*1000*1000; |
|
1570 |
|
1571 for (ix=0; ix<TOTAL_INDEXES; ++ix) |
|
1572 { |
|
1573 TUint attr = FuncAttr[ix]; |
|
1574 TUint func = ATTR_TO_FUNC(attr); |
|
1575 TUint type = ATTR_TO_TYPE(attr); |
|
1576 if (p->NumCpus()==1) |
|
1577 { |
|
1578 TUint ord = ATTR_TO_ORD(attr); |
|
1579 if (ord != EOrderOrdered) |
|
1580 continue; |
|
1581 } |
|
1582 if (type==EFuncTypeInvalid) |
|
1583 continue; |
|
1584 if (func<TUint(EAtomicFuncSWP) || func>=TUint(EAtomicFuncCAS)) |
|
1585 continue; |
|
1586 if (func==TUint(EAtomicFuncIOR)) // can only test AND and IOR together |
|
1587 continue; |
|
1588 p->DoRmwTest(ix, EFalse, Min(avg_time_us,limit_us)); |
|
1589 p->DoRmwTest(ix, ETrue, Min(avg_time_k_us,limit_us)); |
|
1590 } |
|
1591 |
|
1592 p->Finish(); |
|
1593 delete p; |
|
1594 } |
|
1595 |
|
1596 |
|
1597 |
|
1598 /****************************************************************************** |
|
1599 * Main |
|
1600 ******************************************************************************/ |
|
1601 TInt E32Main() |
|
1602 { |
|
1603 test.Title(); |
|
1604 test.Start(_L("Opening device driver")); |
|
1605 #ifdef __EPOC32__ |
|
1606 TInt r; |
|
1607 r = User::LoadLogicalDevice(KAtomicTestLddName); |
|
1608 test(r==KErrNone||r==KErrAlreadyExists); |
|
1609 r = DD.Open(); |
|
1610 test_KErrNone(r); |
|
1611 #endif |
|
1612 test.Next(_L("Testing atomic operations ...")); |
|
1613 test.Next(_L("Single thread, normal operation")); |
|
1614 TestSingleThread(); |
|
1615 test.Next(_L("Single thread, bad addresses")); |
|
1616 TestInvalidAddresses(); |
|
1617 test.Next(_L("Multiple threads")); |
|
1618 TestMultipleThreads(); |
|
1619 test.End(); |
|
1620 return 0; |
|
1621 } |
|
1622 |