VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstInlineAsm.cpp@ 32878

Last change on this file since 32878 was 31412, checked in by vboxsync, 14 years ago

build fix

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 49.5 KB
Line 
1/* $Id: tstInlineAsm.cpp 31412 2010-08-05 15:19:09Z vboxsync $ */
2/** @file
3 * IPRT Testcase - inline assembly.
4 */
5
6/*
7 * Copyright (C) 2006-2010 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27/*******************************************************************************
28* Header Files *
29*******************************************************************************/
30#include <iprt/asm.h>
31#include <iprt/asm-math.h>
32
33/* See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44018. Only gcc version 4.4
34 * is affected. No harm for the VBox code: If the cpuid code compiles, it works
35 * fine. */
36#if defined(__GNUC__) && defined(RT_ARCH_X86) && defined(__PIC__)
37# if __GNUC__ == 4 && __GNUC_MINOR__ == 4
38# define GCC44_32BIT_PIC
39# endif
40#endif
41
42#if !defined(GCC44_32BIT_PIC) && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86))
43# include <iprt/asm-amd64-x86.h>
44#else
45# include <iprt/time.h>
46#endif
47#include <iprt/stream.h>
48#include <iprt/string.h>
49#include <iprt/initterm.h>
50#include <iprt/param.h>
51#include <iprt/thread.h>
52#include <iprt/test.h>
53
54
55
56/*******************************************************************************
57* Defined Constants And Macros *
58*******************************************************************************/
59#define CHECKVAL(val, expect, fmt) \
60 do \
61 { \
62 if ((val) != (expect)) \
63 { \
64 RTTestIErrorInc(); \
65 RTPrintf("%s, %d: " #val ": expected " fmt " got " fmt "\n", __FUNCTION__, __LINE__, (expect), (val)); \
66 } \
67 } while (0)
68
69#define CHECKOP(op, expect, fmt, type) \
70 do \
71 { \
72 type val = op; \
73 if (val != (type)(expect)) \
74 { \
75 RTTestIErrorInc(); \
76 RTPrintf("%s, %d: " #op ": expected " fmt " got " fmt "\n", __FUNCTION__, __LINE__, (type)(expect), val); \
77 } \
78 } while (0)
79
80
81#if !defined(GCC44_32BIT_PIC) && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86))
82
83const char *getCacheAss(unsigned u)
84{
85 if (u == 0)
86 return "res0 ";
87 if (u == 1)
88 return "direct";
89 if (u >= 256)
90 return "???";
91
92 char *pszRet;
93 RTStrAPrintf(&pszRet, "%d way", u); /* intentional leak! */
94 return pszRet;
95}
96
97
98const char *getL2CacheAss(unsigned u)
99{
100 switch (u)
101 {
102 case 0: return "off ";
103 case 1: return "direct";
104 case 2: return "2 way ";
105 case 3: return "res3 ";
106 case 4: return "4 way ";
107 case 5: return "res5 ";
108 case 6: return "8 way ";
109 case 7: return "res7 ";
110 case 8: return "16 way";
111 case 9: return "res9 ";
112 case 10: return "res10 ";
113 case 11: return "res11 ";
114 case 12: return "res12 ";
115 case 13: return "res13 ";
116 case 14: return "res14 ";
117 case 15: return "fully ";
118 default:
119 return "????";
120 }
121}
122
123
124/**
125 * Test and dump all possible info from the CPUID instruction.
126 *
127 * @remark Bits shared with the libc cpuid.c program. This all written by me, so no worries.
128 * @todo transform the dumping into a generic runtime function. We'll need it for logging!
129 */
130void tstASMCpuId(void)
131{
132 unsigned iBit;
133 struct
134 {
135 uint32_t uEBX, uEAX, uEDX, uECX;
136 } s;
137 if (!ASMHasCpuId())
138 {
139 RTPrintf("tstInlineAsm: warning! CPU doesn't support CPUID\n");
140 return;
141 }
142
143 /*
144 * Try the 0 function and use that for checking the ASMCpuId_* variants.
145 */
146 ASMCpuId(0, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
147
148 uint32_t u32;
149
150 u32 = ASMCpuId_EAX(0);
151 CHECKVAL(u32, s.uEAX, "%x");
152 u32 = ASMCpuId_EBX(0);
153 CHECKVAL(u32, s.uEBX, "%x");
154 u32 = ASMCpuId_ECX(0);
155 CHECKVAL(u32, s.uECX, "%x");
156 u32 = ASMCpuId_EDX(0);
157 CHECKVAL(u32, s.uEDX, "%x");
158
159 uint32_t uECX2 = s.uECX - 1;
160 uint32_t uEDX2 = s.uEDX - 1;
161 ASMCpuId_ECX_EDX(0, &uECX2, &uEDX2);
162 CHECKVAL(uECX2, s.uECX, "%x");
163 CHECKVAL(uEDX2, s.uEDX, "%x");
164
165 /*
166 * Done testing, dump the information.
167 */
168 RTPrintf("tstInlineAsm: CPUID Dump\n");
169 ASMCpuId(0, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
170 const uint32_t cFunctions = s.uEAX;
171
172 /* raw dump */
173 RTPrintf("\n"
174 " RAW Standard CPUIDs\n"
175 "Function eax ebx ecx edx\n");
176 for (unsigned iStd = 0; iStd <= cFunctions + 3; iStd++)
177 {
178 if (iStd == 4)
179 continue; /* Leaf 04 output depends on the initial value of ECX */
180 ASMCpuId(iStd, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
181 RTPrintf("%08x %08x %08x %08x %08x%s\n",
182 iStd, s.uEAX, s.uEBX, s.uECX, s.uEDX, iStd <= cFunctions ? "" : "*");
183
184 u32 = ASMCpuId_EAX(iStd);
185 CHECKVAL(u32, s.uEAX, "%x");
186 u32 = ASMCpuId_EBX(iStd);
187 CHECKVAL(u32, s.uEBX, "%x");
188 u32 = ASMCpuId_ECX(iStd);
189 CHECKVAL(u32, s.uECX, "%x");
190 u32 = ASMCpuId_EDX(iStd);
191 CHECKVAL(u32, s.uEDX, "%x");
192
193 uECX2 = s.uECX - 1;
194 uEDX2 = s.uEDX - 1;
195 ASMCpuId_ECX_EDX(iStd, &uECX2, &uEDX2);
196 CHECKVAL(uECX2, s.uECX, "%x");
197 CHECKVAL(uEDX2, s.uEDX, "%x");
198 }
199
200 /*
201 * Understandable output
202 */
203 ASMCpuId(0, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
204 RTPrintf("Name: %.04s%.04s%.04s\n"
205 "Support: 0-%u\n",
206 &s.uEBX, &s.uEDX, &s.uECX, s.uEAX);
207 bool const fIntel = ASMIsIntelCpuEx(s.uEBX, s.uECX, s.uEDX);
208
209 /*
210 * Get Features.
211 */
212 if (cFunctions >= 1)
213 {
214 static const char * const s_apszTypes[4] = { "primary", "overdrive", "MP", "reserved" };
215 ASMCpuId(1, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
216 RTPrintf("Family: %#x \tExtended: %#x \tEffective: %#x\n"
217 "Model: %#x \tExtended: %#x \tEffective: %#x\n"
218 "Stepping: %d\n"
219 "Type: %d (%s)\n"
220 "APIC ID: %#04x\n"
221 "Logical CPUs: %d\n"
222 "CLFLUSH Size: %d\n"
223 "Brand ID: %#04x\n",
224 (s.uEAX >> 8) & 0xf, (s.uEAX >> 20) & 0x7f, ASMGetCpuFamily(s.uEAX),
225 (s.uEAX >> 4) & 0xf, (s.uEAX >> 16) & 0x0f, ASMGetCpuModel(s.uEAX, fIntel),
226 ASMGetCpuStepping(s.uEAX),
227 (s.uEAX >> 12) & 0x3, s_apszTypes[(s.uEAX >> 12) & 0x3],
228 (s.uEBX >> 24) & 0xff,
229 (s.uEBX >> 16) & 0xff,
230 (s.uEBX >> 8) & 0xff,
231 (s.uEBX >> 0) & 0xff);
232
233 RTPrintf("Features EDX: ");
234 if (s.uEDX & RT_BIT(0)) RTPrintf(" FPU");
235 if (s.uEDX & RT_BIT(1)) RTPrintf(" VME");
236 if (s.uEDX & RT_BIT(2)) RTPrintf(" DE");
237 if (s.uEDX & RT_BIT(3)) RTPrintf(" PSE");
238 if (s.uEDX & RT_BIT(4)) RTPrintf(" TSC");
239 if (s.uEDX & RT_BIT(5)) RTPrintf(" MSR");
240 if (s.uEDX & RT_BIT(6)) RTPrintf(" PAE");
241 if (s.uEDX & RT_BIT(7)) RTPrintf(" MCE");
242 if (s.uEDX & RT_BIT(8)) RTPrintf(" CX8");
243 if (s.uEDX & RT_BIT(9)) RTPrintf(" APIC");
244 if (s.uEDX & RT_BIT(10)) RTPrintf(" 10");
245 if (s.uEDX & RT_BIT(11)) RTPrintf(" SEP");
246 if (s.uEDX & RT_BIT(12)) RTPrintf(" MTRR");
247 if (s.uEDX & RT_BIT(13)) RTPrintf(" PGE");
248 if (s.uEDX & RT_BIT(14)) RTPrintf(" MCA");
249 if (s.uEDX & RT_BIT(15)) RTPrintf(" CMOV");
250 if (s.uEDX & RT_BIT(16)) RTPrintf(" PAT");
251 if (s.uEDX & RT_BIT(17)) RTPrintf(" PSE36");
252 if (s.uEDX & RT_BIT(18)) RTPrintf(" PSN");
253 if (s.uEDX & RT_BIT(19)) RTPrintf(" CLFSH");
254 if (s.uEDX & RT_BIT(20)) RTPrintf(" 20");
255 if (s.uEDX & RT_BIT(21)) RTPrintf(" DS");
256 if (s.uEDX & RT_BIT(22)) RTPrintf(" ACPI");
257 if (s.uEDX & RT_BIT(23)) RTPrintf(" MMX");
258 if (s.uEDX & RT_BIT(24)) RTPrintf(" FXSR");
259 if (s.uEDX & RT_BIT(25)) RTPrintf(" SSE");
260 if (s.uEDX & RT_BIT(26)) RTPrintf(" SSE2");
261 if (s.uEDX & RT_BIT(27)) RTPrintf(" SS");
262 if (s.uEDX & RT_BIT(28)) RTPrintf(" HTT");
263 if (s.uEDX & RT_BIT(29)) RTPrintf(" 29");
264 if (s.uEDX & RT_BIT(30)) RTPrintf(" 30");
265 if (s.uEDX & RT_BIT(31)) RTPrintf(" 31");
266 RTPrintf("\n");
267
268 /** @todo check intel docs. */
269 RTPrintf("Features ECX: ");
270 if (s.uECX & RT_BIT(0)) RTPrintf(" SSE3");
271 for (iBit = 1; iBit < 13; iBit++)
272 if (s.uECX & RT_BIT(iBit))
273 RTPrintf(" %d", iBit);
274 if (s.uECX & RT_BIT(13)) RTPrintf(" CX16");
275 for (iBit = 14; iBit < 32; iBit++)
276 if (s.uECX & RT_BIT(iBit))
277 RTPrintf(" %d", iBit);
278 RTPrintf("\n");
279 }
280
281 /*
282 * Extended.
283 * Implemented after AMD specs.
284 */
285 /** @todo check out the intel specs. */
286 ASMCpuId(0x80000000, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
287 if (!s.uEAX && !s.uEBX && !s.uECX && !s.uEDX)
288 {
289 RTPrintf("No extended CPUID info? Check the manual on how to detect this...\n");
290 return;
291 }
292 const uint32_t cExtFunctions = s.uEAX | 0x80000000;
293
294 /* raw dump */
295 RTPrintf("\n"
296 " RAW Extended CPUIDs\n"
297 "Function eax ebx ecx edx\n");
298 for (unsigned iExt = 0x80000000; iExt <= cExtFunctions + 3; iExt++)
299 {
300 ASMCpuId(iExt, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
301 RTPrintf("%08x %08x %08x %08x %08x%s\n",
302 iExt, s.uEAX, s.uEBX, s.uECX, s.uEDX, iExt <= cExtFunctions ? "" : "*");
303
304 u32 = ASMCpuId_EAX(iExt);
305 CHECKVAL(u32, s.uEAX, "%x");
306 u32 = ASMCpuId_EBX(iExt);
307 CHECKVAL(u32, s.uEBX, "%x");
308 u32 = ASMCpuId_ECX(iExt);
309 CHECKVAL(u32, s.uECX, "%x");
310 u32 = ASMCpuId_EDX(iExt);
311 CHECKVAL(u32, s.uEDX, "%x");
312
313 uECX2 = s.uECX - 1;
314 uEDX2 = s.uEDX - 1;
315 ASMCpuId_ECX_EDX(iExt, &uECX2, &uEDX2);
316 CHECKVAL(uECX2, s.uECX, "%x");
317 CHECKVAL(uEDX2, s.uEDX, "%x");
318 }
319
320 /*
321 * Understandable output
322 */
323 ASMCpuId(0x80000000, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
324 RTPrintf("Ext Name: %.4s%.4s%.4s\n"
325 "Ext Supports: 0x80000000-%#010x\n",
326 &s.uEBX, &s.uEDX, &s.uECX, s.uEAX);
327
328 if (cExtFunctions >= 0x80000001)
329 {
330 ASMCpuId(0x80000001, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
331 RTPrintf("Family: %#x \tExtended: %#x \tEffective: %#x\n"
332 "Model: %#x \tExtended: %#x \tEffective: %#x\n"
333 "Stepping: %d\n"
334 "Brand ID: %#05x\n",
335 (s.uEAX >> 8) & 0xf, (s.uEAX >> 20) & 0x7f, ASMGetCpuFamily(s.uEAX),
336 (s.uEAX >> 4) & 0xf, (s.uEAX >> 16) & 0x0f, ASMGetCpuModel(s.uEAX, fIntel),
337 ASMGetCpuStepping(s.uEAX),
338 s.uEBX & 0xfff);
339
340 RTPrintf("Features EDX: ");
341 if (s.uEDX & RT_BIT(0)) RTPrintf(" FPU");
342 if (s.uEDX & RT_BIT(1)) RTPrintf(" VME");
343 if (s.uEDX & RT_BIT(2)) RTPrintf(" DE");
344 if (s.uEDX & RT_BIT(3)) RTPrintf(" PSE");
345 if (s.uEDX & RT_BIT(4)) RTPrintf(" TSC");
346 if (s.uEDX & RT_BIT(5)) RTPrintf(" MSR");
347 if (s.uEDX & RT_BIT(6)) RTPrintf(" PAE");
348 if (s.uEDX & RT_BIT(7)) RTPrintf(" MCE");
349 if (s.uEDX & RT_BIT(8)) RTPrintf(" CMPXCHG8B");
350 if (s.uEDX & RT_BIT(9)) RTPrintf(" APIC");
351 if (s.uEDX & RT_BIT(10)) RTPrintf(" 10");
352 if (s.uEDX & RT_BIT(11)) RTPrintf(" SysCallSysRet");
353 if (s.uEDX & RT_BIT(12)) RTPrintf(" MTRR");
354 if (s.uEDX & RT_BIT(13)) RTPrintf(" PGE");
355 if (s.uEDX & RT_BIT(14)) RTPrintf(" MCA");
356 if (s.uEDX & RT_BIT(15)) RTPrintf(" CMOV");
357 if (s.uEDX & RT_BIT(16)) RTPrintf(" PAT");
358 if (s.uEDX & RT_BIT(17)) RTPrintf(" PSE36");
359 if (s.uEDX & RT_BIT(18)) RTPrintf(" 18");
360 if (s.uEDX & RT_BIT(19)) RTPrintf(" 19");
361 if (s.uEDX & RT_BIT(20)) RTPrintf(" NX");
362 if (s.uEDX & RT_BIT(21)) RTPrintf(" 21");
363 if (s.uEDX & RT_BIT(22)) RTPrintf(" MmxExt");
364 if (s.uEDX & RT_BIT(23)) RTPrintf(" MMX");
365 if (s.uEDX & RT_BIT(24)) RTPrintf(" FXSR");
366 if (s.uEDX & RT_BIT(25)) RTPrintf(" FastFXSR");
367 if (s.uEDX & RT_BIT(26)) RTPrintf(" 26");
368 if (s.uEDX & RT_BIT(27)) RTPrintf(" RDTSCP");
369 if (s.uEDX & RT_BIT(28)) RTPrintf(" 28");
370 if (s.uEDX & RT_BIT(29)) RTPrintf(" LongMode");
371 if (s.uEDX & RT_BIT(30)) RTPrintf(" 3DNowExt");
372 if (s.uEDX & RT_BIT(31)) RTPrintf(" 3DNow");
373 RTPrintf("\n");
374
375 RTPrintf("Features ECX: ");
376 if (s.uECX & RT_BIT(0)) RTPrintf(" LahfSahf");
377 if (s.uECX & RT_BIT(1)) RTPrintf(" CmpLegacy");
378 if (s.uECX & RT_BIT(2)) RTPrintf(" SVM");
379 if (s.uECX & RT_BIT(3)) RTPrintf(" 3");
380 if (s.uECX & RT_BIT(4)) RTPrintf(" AltMovCr8");
381 for (iBit = 5; iBit < 32; iBit++)
382 if (s.uECX & RT_BIT(iBit))
383 RTPrintf(" %d", iBit);
384 RTPrintf("\n");
385 }
386
387 char szString[4*4*3+1] = {0};
388 if (cExtFunctions >= 0x80000002)
389 ASMCpuId(0x80000002, &szString[0 + 0], &szString[0 + 4], &szString[0 + 8], &szString[0 + 12]);
390 if (cExtFunctions >= 0x80000003)
391 ASMCpuId(0x80000003, &szString[16 + 0], &szString[16 + 4], &szString[16 + 8], &szString[16 + 12]);
392 if (cExtFunctions >= 0x80000004)
393 ASMCpuId(0x80000004, &szString[32 + 0], &szString[32 + 4], &szString[32 + 8], &szString[32 + 12]);
394 if (cExtFunctions >= 0x80000002)
395 RTPrintf("Full Name: %s\n", szString);
396
397 if (cExtFunctions >= 0x80000005)
398 {
399 ASMCpuId(0x80000005, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
400 RTPrintf("TLB 2/4M Instr/Uni: %s %3d entries\n"
401 "TLB 2/4M Data: %s %3d entries\n",
402 getCacheAss((s.uEAX >> 8) & 0xff), (s.uEAX >> 0) & 0xff,
403 getCacheAss((s.uEAX >> 24) & 0xff), (s.uEAX >> 16) & 0xff);
404 RTPrintf("TLB 4K Instr/Uni: %s %3d entries\n"
405 "TLB 4K Data: %s %3d entries\n",
406 getCacheAss((s.uEBX >> 8) & 0xff), (s.uEBX >> 0) & 0xff,
407 getCacheAss((s.uEBX >> 24) & 0xff), (s.uEBX >> 16) & 0xff);
408 RTPrintf("L1 Instr Cache Line Size: %d bytes\n"
409 "L1 Instr Cache Lines Per Tag: %d\n"
410 "L1 Instr Cache Associativity: %s\n"
411 "L1 Instr Cache Size: %d KB\n",
412 (s.uEDX >> 0) & 0xff,
413 (s.uEDX >> 8) & 0xff,
414 getCacheAss((s.uEDX >> 16) & 0xff),
415 (s.uEDX >> 24) & 0xff);
416 RTPrintf("L1 Data Cache Line Size: %d bytes\n"
417 "L1 Data Cache Lines Per Tag: %d\n"
418 "L1 Data Cache Associativity: %s\n"
419 "L1 Data Cache Size: %d KB\n",
420 (s.uECX >> 0) & 0xff,
421 (s.uECX >> 8) & 0xff,
422 getCacheAss((s.uECX >> 16) & 0xff),
423 (s.uECX >> 24) & 0xff);
424 }
425
426 if (cExtFunctions >= 0x80000006)
427 {
428 ASMCpuId(0x80000006, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
429 RTPrintf("L2 TLB 2/4M Instr/Uni: %s %4d entries\n"
430 "L2 TLB 2/4M Data: %s %4d entries\n",
431 getL2CacheAss((s.uEAX >> 12) & 0xf), (s.uEAX >> 0) & 0xfff,
432 getL2CacheAss((s.uEAX >> 28) & 0xf), (s.uEAX >> 16) & 0xfff);
433 RTPrintf("L2 TLB 4K Instr/Uni: %s %4d entries\n"
434 "L2 TLB 4K Data: %s %4d entries\n",
435 getL2CacheAss((s.uEBX >> 12) & 0xf), (s.uEBX >> 0) & 0xfff,
436 getL2CacheAss((s.uEBX >> 28) & 0xf), (s.uEBX >> 16) & 0xfff);
437 RTPrintf("L2 Cache Line Size: %d bytes\n"
438 "L2 Cache Lines Per Tag: %d\n"
439 "L2 Cache Associativity: %s\n"
440 "L2 Cache Size: %d KB\n",
441 (s.uEDX >> 0) & 0xff,
442 (s.uEDX >> 8) & 0xf,
443 getL2CacheAss((s.uEDX >> 12) & 0xf),
444 (s.uEDX >> 16) & 0xffff);
445 }
446
447 if (cExtFunctions >= 0x80000007)
448 {
449 ASMCpuId(0x80000007, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
450 RTPrintf("APM Features: ");
451 if (s.uEDX & RT_BIT(0)) RTPrintf(" TS");
452 if (s.uEDX & RT_BIT(1)) RTPrintf(" FID");
453 if (s.uEDX & RT_BIT(2)) RTPrintf(" VID");
454 if (s.uEDX & RT_BIT(3)) RTPrintf(" TTP");
455 if (s.uEDX & RT_BIT(4)) RTPrintf(" TM");
456 if (s.uEDX & RT_BIT(5)) RTPrintf(" STC");
457 if (s.uEDX & RT_BIT(6)) RTPrintf(" 6");
458 if (s.uEDX & RT_BIT(7)) RTPrintf(" 7");
459 if (s.uEDX & RT_BIT(8)) RTPrintf(" TscInvariant");
460 for (iBit = 9; iBit < 32; iBit++)
461 if (s.uEDX & RT_BIT(iBit))
462 RTPrintf(" %d", iBit);
463 RTPrintf("\n");
464 }
465
466 if (cExtFunctions >= 0x80000008)
467 {
468 ASMCpuId(0x80000008, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
469 RTPrintf("Physical Address Width: %d bits\n"
470 "Virtual Address Width: %d bits\n"
471 "Guest Physical Address Width: %d bits\n",
472 (s.uEAX >> 0) & 0xff,
473 (s.uEAX >> 8) & 0xff,
474 (s.uEAX >> 16) & 0xff);
475 RTPrintf("Physical Core Count: %d\n",
476 ((s.uECX >> 0) & 0xff) + 1);
477 if ((s.uECX >> 12) & 0xf)
478 RTPrintf("ApicIdCoreIdSize: %d bits\n", (s.uECX >> 12) & 0xf);
479 }
480
481 if (cExtFunctions >= 0x8000000a)
482 {
483 ASMCpuId(0x8000000a, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
484 RTPrintf("SVM Revision: %d (%#x)\n"
485 "Number of Address Space IDs: %d (%#x)\n",
486 s.uEAX & 0xff, s.uEAX & 0xff,
487 s.uEBX, s.uEBX);
488 }
489}
490
491#endif /* AMD64 || X86 */
492
493static void tstASMAtomicXchgU8(void)
494{
495 struct
496 {
497 uint8_t u8Dummy0;
498 uint8_t u8;
499 uint8_t u8Dummy1;
500 } s;
501
502 s.u8 = 0;
503 s.u8Dummy0 = s.u8Dummy1 = 0x42;
504 CHECKOP(ASMAtomicXchgU8(&s.u8, 1), 0, "%#x", uint8_t);
505 CHECKVAL(s.u8, 1, "%#x");
506
507 CHECKOP(ASMAtomicXchgU8(&s.u8, 0), 1, "%#x", uint8_t);
508 CHECKVAL(s.u8, 0, "%#x");
509
510 CHECKOP(ASMAtomicXchgU8(&s.u8, 0xff), 0, "%#x", uint8_t);
511 CHECKVAL(s.u8, 0xff, "%#x");
512
513 CHECKOP(ASMAtomicXchgU8(&s.u8, 0x87), 0xffff, "%#x", uint8_t);
514 CHECKVAL(s.u8, 0x87, "%#x");
515 CHECKVAL(s.u8Dummy0, 0x42, "%#x");
516 CHECKVAL(s.u8Dummy1, 0x42, "%#x");
517}
518
519
520static void tstASMAtomicXchgU16(void)
521{
522 struct
523 {
524 uint16_t u16Dummy0;
525 uint16_t u16;
526 uint16_t u16Dummy1;
527 } s;
528
529 s.u16 = 0;
530 s.u16Dummy0 = s.u16Dummy1 = 0x1234;
531 CHECKOP(ASMAtomicXchgU16(&s.u16, 1), 0, "%#x", uint16_t);
532 CHECKVAL(s.u16, 1, "%#x");
533
534 CHECKOP(ASMAtomicXchgU16(&s.u16, 0), 1, "%#x", uint16_t);
535 CHECKVAL(s.u16, 0, "%#x");
536
537 CHECKOP(ASMAtomicXchgU16(&s.u16, 0xffff), 0, "%#x", uint16_t);
538 CHECKVAL(s.u16, 0xffff, "%#x");
539
540 CHECKOP(ASMAtomicXchgU16(&s.u16, 0x8765), 0xffff, "%#x", uint16_t);
541 CHECKVAL(s.u16, 0x8765, "%#x");
542 CHECKVAL(s.u16Dummy0, 0x1234, "%#x");
543 CHECKVAL(s.u16Dummy1, 0x1234, "%#x");
544}
545
546
547static void tstASMAtomicXchgU32(void)
548{
549 struct
550 {
551 uint32_t u32Dummy0;
552 uint32_t u32;
553 uint32_t u32Dummy1;
554 } s;
555
556 s.u32 = 0;
557 s.u32Dummy0 = s.u32Dummy1 = 0x11223344;
558
559 CHECKOP(ASMAtomicXchgU32(&s.u32, 1), 0, "%#x", uint32_t);
560 CHECKVAL(s.u32, 1, "%#x");
561
562 CHECKOP(ASMAtomicXchgU32(&s.u32, 0), 1, "%#x", uint32_t);
563 CHECKVAL(s.u32, 0, "%#x");
564
565 CHECKOP(ASMAtomicXchgU32(&s.u32, ~0U), 0, "%#x", uint32_t);
566 CHECKVAL(s.u32, ~0U, "%#x");
567
568 CHECKOP(ASMAtomicXchgU32(&s.u32, 0x87654321), ~0U, "%#x", uint32_t);
569 CHECKVAL(s.u32, 0x87654321, "%#x");
570
571 CHECKVAL(s.u32Dummy0, 0x11223344, "%#x");
572 CHECKVAL(s.u32Dummy1, 0x11223344, "%#x");
573}
574
575
576static void tstASMAtomicXchgU64(void)
577{
578 struct
579 {
580 uint64_t u64Dummy0;
581 uint64_t u64;
582 uint64_t u64Dummy1;
583 } s;
584
585 s.u64 = 0;
586 s.u64Dummy0 = s.u64Dummy1 = 0x1122334455667788ULL;
587
588 CHECKOP(ASMAtomicXchgU64(&s.u64, 1), 0ULL, "%#llx", uint64_t);
589 CHECKVAL(s.u64, 1ULL, "%#llx");
590
591 CHECKOP(ASMAtomicXchgU64(&s.u64, 0), 1ULL, "%#llx", uint64_t);
592 CHECKVAL(s.u64, 0ULL, "%#llx");
593
594 CHECKOP(ASMAtomicXchgU64(&s.u64, ~0ULL), 0ULL, "%#llx", uint64_t);
595 CHECKVAL(s.u64, ~0ULL, "%#llx");
596
597 CHECKOP(ASMAtomicXchgU64(&s.u64, 0xfedcba0987654321ULL), ~0ULL, "%#llx", uint64_t);
598 CHECKVAL(s.u64, 0xfedcba0987654321ULL, "%#llx");
599
600 CHECKVAL(s.u64Dummy0, 0x1122334455667788ULL, "%#llx");
601 CHECKVAL(s.u64Dummy1, 0x1122334455667788ULL, "%#llx");
602}
603
604
605static void tstASMAtomicXchgPtr(void)
606{
607 void *pv = NULL;
608
609 CHECKOP(ASMAtomicXchgPtr(&pv, (void *)(~(uintptr_t)0)), NULL, "%p", void *);
610 CHECKVAL(pv, (void *)(~(uintptr_t)0), "%p");
611
612 CHECKOP(ASMAtomicXchgPtr(&pv, (void *)0x87654321), (void *)(~(uintptr_t)0), "%p", void *);
613 CHECKVAL(pv, (void *)0x87654321, "%p");
614
615 CHECKOP(ASMAtomicXchgPtr(&pv, NULL), (void *)0x87654321, "%p", void *);
616 CHECKVAL(pv, NULL, "%p");
617}
618
619
620static void tstASMAtomicCmpXchgU8(void)
621{
622 struct
623 {
624 uint8_t u8Before;
625 uint8_t u8;
626 uint8_t u8After;
627 } u = { 0xcc, 0xff, 0xaa };
628
629 CHECKOP(ASMAtomicCmpXchgU8(&u.u8, 0, 0), false, "%d", bool);
630 CHECKVAL(u.u8, 0xff, "%x"); CHECKVAL(u.u8Before, 0xcc, "%x"); CHECKVAL(u.u8After, 0xaa, "%x");
631
632 CHECKOP(ASMAtomicCmpXchgU8(&u.u8, 0, 0xff), true, "%d", bool);
633 CHECKVAL(u.u8, 0, "%x"); CHECKVAL(u.u8Before, 0xcc, "%x"); CHECKVAL(u.u8After, 0xaa, "%x");
634
635 CHECKOP(ASMAtomicCmpXchgU8(&u.u8, 0x79, 0xff), false, "%d", bool);
636 CHECKVAL(u.u8, 0, "%x"); CHECKVAL(u.u8Before, 0xcc, "%x"); CHECKVAL(u.u8After, 0xaa, "%x");
637
638 CHECKOP(ASMAtomicCmpXchgU8(&u.u8, 0x97, 0), true, "%d", bool);
639 CHECKVAL(u.u8, 0x97, "%x"); CHECKVAL(u.u8Before, 0xcc, "%x"); CHECKVAL(u.u8After, 0xaa, "%x");
640}
641
642
643static void tstASMAtomicCmpXchgU32(void)
644{
645 uint32_t u32 = 0xffffffff;
646
647 CHECKOP(ASMAtomicCmpXchgU32(&u32, 0, 0), false, "%d", bool);
648 CHECKVAL(u32, 0xffffffff, "%x");
649
650 CHECKOP(ASMAtomicCmpXchgU32(&u32, 0, 0xffffffff), true, "%d", bool);
651 CHECKVAL(u32, 0, "%x");
652
653 CHECKOP(ASMAtomicCmpXchgU32(&u32, 0x8008efd, 0xffffffff), false, "%d", bool);
654 CHECKVAL(u32, 0, "%x");
655
656 CHECKOP(ASMAtomicCmpXchgU32(&u32, 0x8008efd, 0), true, "%d", bool);
657 CHECKVAL(u32, 0x8008efd, "%x");
658}
659
660
661static void tstASMAtomicCmpXchgU64(void)
662{
663 uint64_t u64 = 0xffffffffffffffULL;
664
665 CHECKOP(ASMAtomicCmpXchgU64(&u64, 0, 0), false, "%d", bool);
666 CHECKVAL(u64, 0xffffffffffffffULL, "%#llx");
667
668 CHECKOP(ASMAtomicCmpXchgU64(&u64, 0, 0xffffffffffffffULL), true, "%d", bool);
669 CHECKVAL(u64, 0, "%x");
670
671 CHECKOP(ASMAtomicCmpXchgU64(&u64, 0x80040008008efdULL, 0xffffffff), false, "%d", bool);
672 CHECKVAL(u64, 0, "%x");
673
674 CHECKOP(ASMAtomicCmpXchgU64(&u64, 0x80040008008efdULL, 0xffffffff00000000ULL), false, "%d", bool);
675 CHECKVAL(u64, 0, "%x");
676
677 CHECKOP(ASMAtomicCmpXchgU64(&u64, 0x80040008008efdULL, 0), true, "%d", bool);
678 CHECKVAL(u64, 0x80040008008efdULL, "%#llx");
679}
680
681
682static void tstASMAtomicCmpXchgExU32(void)
683{
684 uint32_t u32 = 0xffffffff;
685 uint32_t u32Old = 0x80005111;
686
687 CHECKOP(ASMAtomicCmpXchgExU32(&u32, 0, 0, &u32Old), false, "%d", bool);
688 CHECKVAL(u32, 0xffffffff, "%x");
689 CHECKVAL(u32Old, 0xffffffff, "%x");
690
691 CHECKOP(ASMAtomicCmpXchgExU32(&u32, 0, 0xffffffff, &u32Old), true, "%d", bool);
692 CHECKVAL(u32, 0, "%x");
693 CHECKVAL(u32Old, 0xffffffff, "%x");
694
695 CHECKOP(ASMAtomicCmpXchgExU32(&u32, 0x8008efd, 0xffffffff, &u32Old), false, "%d", bool);
696 CHECKVAL(u32, 0, "%x");
697 CHECKVAL(u32Old, 0, "%x");
698
699 CHECKOP(ASMAtomicCmpXchgExU32(&u32, 0x8008efd, 0, &u32Old), true, "%d", bool);
700 CHECKVAL(u32, 0x8008efd, "%x");
701 CHECKVAL(u32Old, 0, "%x");
702
703 CHECKOP(ASMAtomicCmpXchgExU32(&u32, 0, 0x8008efd, &u32Old), true, "%d", bool);
704 CHECKVAL(u32, 0, "%x");
705 CHECKVAL(u32Old, 0x8008efd, "%x");
706}
707
708
709static void tstASMAtomicCmpXchgExU64(void)
710{
711 uint64_t u64 = 0xffffffffffffffffULL;
712 uint64_t u64Old = 0x8000000051111111ULL;
713
714 CHECKOP(ASMAtomicCmpXchgExU64(&u64, 0, 0, &u64Old), false, "%d", bool);
715 CHECKVAL(u64, 0xffffffffffffffffULL, "%llx");
716 CHECKVAL(u64Old, 0xffffffffffffffffULL, "%llx");
717
718 CHECKOP(ASMAtomicCmpXchgExU64(&u64, 0, 0xffffffffffffffffULL, &u64Old), true, "%d", bool);
719 CHECKVAL(u64, 0ULL, "%llx");
720 CHECKVAL(u64Old, 0xffffffffffffffffULL, "%llx");
721
722 CHECKOP(ASMAtomicCmpXchgExU64(&u64, 0x80040008008efdULL, 0xffffffff, &u64Old), false, "%d", bool);
723 CHECKVAL(u64, 0ULL, "%llx");
724 CHECKVAL(u64Old, 0ULL, "%llx");
725
726 CHECKOP(ASMAtomicCmpXchgExU64(&u64, 0x80040008008efdULL, 0xffffffff00000000ULL, &u64Old), false, "%d", bool);
727 CHECKVAL(u64, 0ULL, "%llx");
728 CHECKVAL(u64Old, 0ULL, "%llx");
729
730 CHECKOP(ASMAtomicCmpXchgExU64(&u64, 0x80040008008efdULL, 0, &u64Old), true, "%d", bool);
731 CHECKVAL(u64, 0x80040008008efdULL, "%llx");
732 CHECKVAL(u64Old, 0ULL, "%llx");
733
734 CHECKOP(ASMAtomicCmpXchgExU64(&u64, 0, 0x80040008008efdULL, &u64Old), true, "%d", bool);
735 CHECKVAL(u64, 0ULL, "%llx");
736 CHECKVAL(u64Old, 0x80040008008efdULL, "%llx");
737}
738
739
740static void tstASMAtomicReadU64(void)
741{
742 uint64_t u64 = 0;
743
744 CHECKOP(ASMAtomicReadU64(&u64), 0ULL, "%#llx", uint64_t);
745 CHECKVAL(u64, 0ULL, "%#llx");
746
747 u64 = ~0ULL;
748 CHECKOP(ASMAtomicReadU64(&u64), ~0ULL, "%#llx", uint64_t);
749 CHECKVAL(u64, ~0ULL, "%#llx");
750
751 u64 = 0xfedcba0987654321ULL;
752 CHECKOP(ASMAtomicReadU64(&u64), 0xfedcba0987654321ULL, "%#llx", uint64_t);
753 CHECKVAL(u64, 0xfedcba0987654321ULL, "%#llx");
754}
755
756
757static void tstASMAtomicUoReadU64(void)
758{
759 uint64_t u64 = 0;
760
761 CHECKOP(ASMAtomicUoReadU64(&u64), 0ULL, "%#llx", uint64_t);
762 CHECKVAL(u64, 0ULL, "%#llx");
763
764 u64 = ~0ULL;
765 CHECKOP(ASMAtomicUoReadU64(&u64), ~0ULL, "%#llx", uint64_t);
766 CHECKVAL(u64, ~0ULL, "%#llx");
767
768 u64 = 0xfedcba0987654321ULL;
769 CHECKOP(ASMAtomicUoReadU64(&u64), 0xfedcba0987654321ULL, "%#llx", uint64_t);
770 CHECKVAL(u64, 0xfedcba0987654321ULL, "%#llx");
771}
772
773
774static void tstASMAtomicAddS32(void)
775{
776 int32_t i32Rc;
777 int32_t i32 = 10;
778#define MYCHECK(op, rc, val) \
779 do { \
780 i32Rc = op; \
781 if (i32Rc != (rc)) \
782 { \
783 RTPrintf("%s, %d: FAILURE: %s -> %d expected %d\n", __FUNCTION__, __LINE__, #op, i32Rc, rc); \
784 RTTestIErrorInc(); \
785 } \
786 if (i32 != (val)) \
787 { \
788 RTPrintf("%s, %d: FAILURE: %s => i32=%d expected %d\n", __FUNCTION__, __LINE__, #op, i32, val); \
789 RTTestIErrorInc(); \
790 } \
791 } while (0)
792 MYCHECK(ASMAtomicAddS32(&i32, 1), 10, 11);
793 MYCHECK(ASMAtomicAddS32(&i32, -2), 11, 9);
794 MYCHECK(ASMAtomicAddS32(&i32, -9), 9, 0);
795 MYCHECK(ASMAtomicAddS32(&i32, -0x7fffffff), 0, -0x7fffffff);
796 MYCHECK(ASMAtomicAddS32(&i32, 0), -0x7fffffff, -0x7fffffff);
797 MYCHECK(ASMAtomicAddS32(&i32, 0x7fffffff), -0x7fffffff, 0);
798 MYCHECK(ASMAtomicAddS32(&i32, 0), 0, 0);
799#undef MYCHECK
800}
801
802
803static void tstASMAtomicDecIncS32(void)
804{
805 int32_t i32Rc;
806 int32_t i32 = 10;
807#define MYCHECK(op, rc) \
808 do { \
809 i32Rc = op; \
810 if (i32Rc != (rc)) \
811 { \
812 RTPrintf("%s, %d: FAILURE: %s -> %d expected %d\n", __FUNCTION__, __LINE__, #op, i32Rc, rc); \
813 RTTestIErrorInc(); \
814 } \
815 if (i32 != (rc)) \
816 { \
817 RTPrintf("%s, %d: FAILURE: %s => i32=%d expected %d\n", __FUNCTION__, __LINE__, #op, i32, rc); \
818 RTTestIErrorInc(); \
819 } \
820 } while (0)
821 MYCHECK(ASMAtomicDecS32(&i32), 9);
822 MYCHECK(ASMAtomicDecS32(&i32), 8);
823 MYCHECK(ASMAtomicDecS32(&i32), 7);
824 MYCHECK(ASMAtomicDecS32(&i32), 6);
825 MYCHECK(ASMAtomicDecS32(&i32), 5);
826 MYCHECK(ASMAtomicDecS32(&i32), 4);
827 MYCHECK(ASMAtomicDecS32(&i32), 3);
828 MYCHECK(ASMAtomicDecS32(&i32), 2);
829 MYCHECK(ASMAtomicDecS32(&i32), 1);
830 MYCHECK(ASMAtomicDecS32(&i32), 0);
831 MYCHECK(ASMAtomicDecS32(&i32), -1);
832 MYCHECK(ASMAtomicDecS32(&i32), -2);
833 MYCHECK(ASMAtomicIncS32(&i32), -1);
834 MYCHECK(ASMAtomicIncS32(&i32), 0);
835 MYCHECK(ASMAtomicIncS32(&i32), 1);
836 MYCHECK(ASMAtomicIncS32(&i32), 2);
837 MYCHECK(ASMAtomicIncS32(&i32), 3);
838 MYCHECK(ASMAtomicDecS32(&i32), 2);
839 MYCHECK(ASMAtomicIncS32(&i32), 3);
840 MYCHECK(ASMAtomicDecS32(&i32), 2);
841 MYCHECK(ASMAtomicIncS32(&i32), 3);
842#undef MYCHECK
843}
844
845
846static void tstASMAtomicAndOrU32(void)
847{
848 uint32_t u32 = 0xffffffff;
849
850 ASMAtomicOrU32(&u32, 0xffffffff);
851 CHECKVAL(u32, 0xffffffff, "%x");
852
853 ASMAtomicAndU32(&u32, 0xffffffff);
854 CHECKVAL(u32, 0xffffffff, "%x");
855
856 ASMAtomicAndU32(&u32, 0x8f8f8f8f);
857 CHECKVAL(u32, 0x8f8f8f8f, "%x");
858
859 ASMAtomicOrU32(&u32, 0x70707070);
860 CHECKVAL(u32, 0xffffffff, "%x");
861
862 ASMAtomicAndU32(&u32, 1);
863 CHECKVAL(u32, 1, "%x");
864
865 ASMAtomicOrU32(&u32, 0x80000000);
866 CHECKVAL(u32, 0x80000001, "%x");
867
868 ASMAtomicAndU32(&u32, 0x80000000);
869 CHECKVAL(u32, 0x80000000, "%x");
870
871 ASMAtomicAndU32(&u32, 0);
872 CHECKVAL(u32, 0, "%x");
873
874 ASMAtomicOrU32(&u32, 0x42424242);
875 CHECKVAL(u32, 0x42424242, "%x");
876}
877
878
879void tstASMMemZeroPage(void)
880{
881 struct
882 {
883 uint64_t u64Magic1;
884 uint8_t abPage[PAGE_SIZE];
885 uint64_t u64Magic2;
886 } Buf1, Buf2, Buf3;
887
888 Buf1.u64Magic1 = UINT64_C(0xffffffffffffffff);
889 memset(Buf1.abPage, 0x55, sizeof(Buf1.abPage));
890 Buf1.u64Magic2 = UINT64_C(0xffffffffffffffff);
891 Buf2.u64Magic1 = UINT64_C(0xffffffffffffffff);
892 memset(Buf2.abPage, 0x77, sizeof(Buf2.abPage));
893 Buf2.u64Magic2 = UINT64_C(0xffffffffffffffff);
894 Buf3.u64Magic1 = UINT64_C(0xffffffffffffffff);
895 memset(Buf3.abPage, 0x99, sizeof(Buf3.abPage));
896 Buf3.u64Magic2 = UINT64_C(0xffffffffffffffff);
897 ASMMemZeroPage(Buf1.abPage);
898 ASMMemZeroPage(Buf2.abPage);
899 ASMMemZeroPage(Buf3.abPage);
900 if ( Buf1.u64Magic1 != UINT64_C(0xffffffffffffffff)
901 || Buf1.u64Magic2 != UINT64_C(0xffffffffffffffff)
902 || Buf2.u64Magic1 != UINT64_C(0xffffffffffffffff)
903 || Buf2.u64Magic2 != UINT64_C(0xffffffffffffffff)
904 || Buf3.u64Magic1 != UINT64_C(0xffffffffffffffff)
905 || Buf3.u64Magic2 != UINT64_C(0xffffffffffffffff))
906 {
907 RTPrintf("tstInlineAsm: ASMMemZeroPage violated one/both magic(s)!\n");
908 RTTestIErrorInc();
909 }
910 for (unsigned i = 0; i < sizeof(Buf1.abPage); i++)
911 if (Buf1.abPage[i])
912 {
913 RTPrintf("tstInlineAsm: ASMMemZeroPage didn't clear byte at offset %#x!\n", i);
914 RTTestIErrorInc();
915 }
916 for (unsigned i = 0; i < sizeof(Buf2.abPage); i++)
917 if (Buf2.abPage[i])
918 {
919 RTPrintf("tstInlineAsm: ASMMemZeroPage didn't clear byte at offset %#x!\n", i);
920 RTTestIErrorInc();
921 }
922 for (unsigned i = 0; i < sizeof(Buf3.abPage); i++)
923 if (Buf3.abPage[i])
924 {
925 RTPrintf("tstInlineAsm: ASMMemZeroPage didn't clear byte at offset %#x!\n", i);
926 RTTestIErrorInc();
927 }
928}
929
930
931void tstASMMemIsZeroPage(RTTEST hTest)
932{
933 RTTestSub(hTest, "ASMMemIsZeroPage");
934
935 void *pvPage1 = RTTestGuardedAllocHead(hTest, PAGE_SIZE);
936 void *pvPage2 = RTTestGuardedAllocTail(hTest, PAGE_SIZE);
937 RTTESTI_CHECK_RETV(pvPage1 && pvPage2);
938
939 memset(pvPage1, 0, PAGE_SIZE);
940 memset(pvPage2, 0, PAGE_SIZE);
941 RTTESTI_CHECK(ASMMemIsZeroPage(pvPage1));
942 RTTESTI_CHECK(ASMMemIsZeroPage(pvPage2));
943
944 memset(pvPage1, 0xff, PAGE_SIZE);
945 memset(pvPage2, 0xff, PAGE_SIZE);
946 RTTESTI_CHECK(!ASMMemIsZeroPage(pvPage1));
947 RTTESTI_CHECK(!ASMMemIsZeroPage(pvPage2));
948
949 memset(pvPage1, 0, PAGE_SIZE);
950 memset(pvPage2, 0, PAGE_SIZE);
951 for (unsigned off = 0; off < PAGE_SIZE; off++)
952 {
953 ((uint8_t *)pvPage1)[off] = 1;
954 RTTESTI_CHECK(!ASMMemIsZeroPage(pvPage1));
955 ((uint8_t *)pvPage1)[off] = 0;
956
957 ((uint8_t *)pvPage2)[off] = 0x80;
958 RTTESTI_CHECK(!ASMMemIsZeroPage(pvPage2));
959 ((uint8_t *)pvPage2)[off] = 0;
960 }
961
962 RTTestSubDone(hTest);
963}
964
965
966void tstASMMemZero32(void)
967{
968 struct
969 {
970 uint64_t u64Magic1;
971 uint8_t abPage[PAGE_SIZE - 32];
972 uint64_t u64Magic2;
973 } Buf1, Buf2, Buf3;
974
975 Buf1.u64Magic1 = UINT64_C(0xffffffffffffffff);
976 memset(Buf1.abPage, 0x55, sizeof(Buf1.abPage));
977 Buf1.u64Magic2 = UINT64_C(0xffffffffffffffff);
978 Buf2.u64Magic1 = UINT64_C(0xffffffffffffffff);
979 memset(Buf2.abPage, 0x77, sizeof(Buf2.abPage));
980 Buf2.u64Magic2 = UINT64_C(0xffffffffffffffff);
981 Buf3.u64Magic1 = UINT64_C(0xffffffffffffffff);
982 memset(Buf3.abPage, 0x99, sizeof(Buf3.abPage));
983 Buf3.u64Magic2 = UINT64_C(0xffffffffffffffff);
984 ASMMemZero32(Buf1.abPage, sizeof(Buf1.abPage));
985 ASMMemZero32(Buf2.abPage, sizeof(Buf2.abPage));
986 ASMMemZero32(Buf3.abPage, sizeof(Buf3.abPage));
987 if ( Buf1.u64Magic1 != UINT64_C(0xffffffffffffffff)
988 || Buf1.u64Magic2 != UINT64_C(0xffffffffffffffff)
989 || Buf2.u64Magic1 != UINT64_C(0xffffffffffffffff)
990 || Buf2.u64Magic2 != UINT64_C(0xffffffffffffffff)
991 || Buf3.u64Magic1 != UINT64_C(0xffffffffffffffff)
992 || Buf3.u64Magic2 != UINT64_C(0xffffffffffffffff))
993 {
994 RTPrintf("tstInlineAsm: ASMMemZero32 violated one/both magic(s)!\n");
995 RTTestIErrorInc();
996 }
997 for (unsigned i = 0; i < RT_ELEMENTS(Buf1.abPage); i++)
998 if (Buf1.abPage[i])
999 {
1000 RTPrintf("tstInlineAsm: ASMMemZero32 didn't clear byte at offset %#x!\n", i);
1001 RTTestIErrorInc();
1002 }
1003 for (unsigned i = 0; i < RT_ELEMENTS(Buf2.abPage); i++)
1004 if (Buf2.abPage[i])
1005 {
1006 RTPrintf("tstInlineAsm: ASMMemZero32 didn't clear byte at offset %#x!\n", i);
1007 RTTestIErrorInc();
1008 }
1009 for (unsigned i = 0; i < RT_ELEMENTS(Buf3.abPage); i++)
1010 if (Buf3.abPage[i])
1011 {
1012 RTPrintf("tstInlineAsm: ASMMemZero32 didn't clear byte at offset %#x!\n", i);
1013 RTTestIErrorInc();
1014 }
1015}
1016
1017
1018void tstASMMemFill32(void)
1019{
1020 struct
1021 {
1022 uint64_t u64Magic1;
1023 uint32_t au32Page[PAGE_SIZE / 4];
1024 uint64_t u64Magic2;
1025 } Buf1;
1026 struct
1027 {
1028 uint64_t u64Magic1;
1029 uint32_t au32Page[(PAGE_SIZE / 4) - 3];
1030 uint64_t u64Magic2;
1031 } Buf2;
1032 struct
1033 {
1034 uint64_t u64Magic1;
1035 uint32_t au32Page[(PAGE_SIZE / 4) - 1];
1036 uint64_t u64Magic2;
1037 } Buf3;
1038
1039 Buf1.u64Magic1 = UINT64_C(0xffffffffffffffff);
1040 memset(Buf1.au32Page, 0x55, sizeof(Buf1.au32Page));
1041 Buf1.u64Magic2 = UINT64_C(0xffffffffffffffff);
1042 Buf2.u64Magic1 = UINT64_C(0xffffffffffffffff);
1043 memset(Buf2.au32Page, 0x77, sizeof(Buf2.au32Page));
1044 Buf2.u64Magic2 = UINT64_C(0xffffffffffffffff);
1045 Buf3.u64Magic1 = UINT64_C(0xffffffffffffffff);
1046 memset(Buf3.au32Page, 0x99, sizeof(Buf3.au32Page));
1047 Buf3.u64Magic2 = UINT64_C(0xffffffffffffffff);
1048 ASMMemFill32(Buf1.au32Page, sizeof(Buf1.au32Page), 0xdeadbeef);
1049 ASMMemFill32(Buf2.au32Page, sizeof(Buf2.au32Page), 0xcafeff01);
1050 ASMMemFill32(Buf3.au32Page, sizeof(Buf3.au32Page), 0xf00dd00f);
1051 if ( Buf1.u64Magic1 != UINT64_C(0xffffffffffffffff)
1052 || Buf1.u64Magic2 != UINT64_C(0xffffffffffffffff)
1053 || Buf2.u64Magic1 != UINT64_C(0xffffffffffffffff)
1054 || Buf2.u64Magic2 != UINT64_C(0xffffffffffffffff)
1055 || Buf3.u64Magic1 != UINT64_C(0xffffffffffffffff)
1056 || Buf3.u64Magic2 != UINT64_C(0xffffffffffffffff))
1057 {
1058 RTPrintf("tstInlineAsm: ASMMemFill32 violated one/both magic(s)!\n");
1059 RTTestIErrorInc();
1060 }
1061 for (unsigned i = 0; i < RT_ELEMENTS(Buf1.au32Page); i++)
1062 if (Buf1.au32Page[i] != 0xdeadbeef)
1063 {
1064 RTPrintf("tstInlineAsm: ASMMemFill32 %#x: %#x exepcted %#x\n", i, Buf1.au32Page[i], 0xdeadbeef);
1065 RTTestIErrorInc();
1066 }
1067 for (unsigned i = 0; i < RT_ELEMENTS(Buf2.au32Page); i++)
1068 if (Buf2.au32Page[i] != 0xcafeff01)
1069 {
1070 RTPrintf("tstInlineAsm: ASMMemFill32 %#x: %#x exepcted %#x\n", i, Buf2.au32Page[i], 0xcafeff01);
1071 RTTestIErrorInc();
1072 }
1073 for (unsigned i = 0; i < RT_ELEMENTS(Buf3.au32Page); i++)
1074 if (Buf3.au32Page[i] != 0xf00dd00f)
1075 {
1076 RTPrintf("tstInlineAsm: ASMMemFill32 %#x: %#x exepcted %#x\n", i, Buf3.au32Page[i], 0xf00dd00f);
1077 RTTestIErrorInc();
1078 }
1079}
1080
1081
1082
1083void tstASMMath(void)
1084{
1085 uint64_t u64 = ASMMult2xU32RetU64(UINT32_C(0x80000000), UINT32_C(0x10000000));
1086 CHECKVAL(u64, UINT64_C(0x0800000000000000), "%#018RX64");
1087
1088 uint32_t u32 = ASMDivU64ByU32RetU32(UINT64_C(0x0800000000000000), UINT32_C(0x10000000));
1089 CHECKVAL(u32, UINT32_C(0x80000000), "%#010RX32");
1090
1091#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
1092 u64 = ASMMultU64ByU32DivByU32(UINT64_C(0x0000000000000001), UINT32_C(0x00000001), UINT32_C(0x00000001));
1093 CHECKVAL(u64, UINT64_C(0x0000000000000001), "%#018RX64");
1094 u64 = ASMMultU64ByU32DivByU32(UINT64_C(0x0000000100000000), UINT32_C(0x80000000), UINT32_C(0x00000002));
1095 CHECKVAL(u64, UINT64_C(0x4000000000000000), "%#018RX64");
1096 u64 = ASMMultU64ByU32DivByU32(UINT64_C(0xfedcba9876543210), UINT32_C(0xffffffff), UINT32_C(0xffffffff));
1097 CHECKVAL(u64, UINT64_C(0xfedcba9876543210), "%#018RX64");
1098 u64 = ASMMultU64ByU32DivByU32(UINT64_C(0xffffffffffffffff), UINT32_C(0xffffffff), UINT32_C(0xffffffff));
1099 CHECKVAL(u64, UINT64_C(0xffffffffffffffff), "%#018RX64");
1100 u64 = ASMMultU64ByU32DivByU32(UINT64_C(0xffffffffffffffff), UINT32_C(0xfffffff0), UINT32_C(0xffffffff));
1101 CHECKVAL(u64, UINT64_C(0xfffffff0fffffff0), "%#018RX64");
1102 u64 = ASMMultU64ByU32DivByU32(UINT64_C(0x3415934810359583), UINT32_C(0x58734981), UINT32_C(0xf8694045));
1103 CHECKVAL(u64, UINT64_C(0x128b9c3d43184763), "%#018RX64");
1104 u64 = ASMMultU64ByU32DivByU32(UINT64_C(0x3415934810359583), UINT32_C(0xf8694045), UINT32_C(0x58734981));
1105 CHECKVAL(u64, UINT64_C(0x924719355cd35a27), "%#018RX64");
1106
1107# if 0 /* bird: question is whether this should trap or not:
1108 *
1109 * frank: Of course it must trap:
1110 *
1111 * 0xfffffff8 * 0x77d7daf8 = 0x77d7daf441412840
1112 *
1113 * During the following division, the quotient must fit into a 32-bit register.
1114 * Therefore the smallest valid divisor is
1115 *
1116 * (0x77d7daf441412840 >> 32) + 1 = 0x77d7daf5
1117 *
1118 * which is definitely greater than 0x3b9aca00.
1119 *
1120 * bird: No, the C version does *not* crash. So, the question is whether there's any
1121 * code depending on it not crashing.
1122 *
1123 * Of course the assembly versions of the code crash right now for the reasons you've
1124 * given, but the 32-bit MSC version does not crash.
1125 *
1126 * frank: The C version does not crash but delivers incorrect results for this case.
1127 * The reason is
1128 *
1129 * u.s.Hi = (unsigned long)(u64Hi / u32C);
1130 *
1131 * Here the division is actually 64-bit by 64-bit but the 64-bit result is truncated
1132 * to 32 bit. If using this (optimized and fast) function we should just be sure that
1133 * the operands are in a valid range.
1134 */
1135 u64 = ASMMultU64ByU32DivByU32(UINT64_C(0xfffffff8c65d6731), UINT32_C(0x77d7daf8), UINT32_C(0x3b9aca00));
1136 CHECKVAL(u64, UINT64_C(0x02b8f9a2aa74e3dc), "%#018RX64");
1137# endif
1138#endif /* AMD64 || X86 */
1139
1140 u32 = ASMModU64ByU32RetU32(UINT64_C(0x0ffffff8c65d6731), UINT32_C(0x77d7daf8));
1141 CHECKVAL(u32, UINT32_C(0x3B642451), "%#010RX32");
1142
1143 int32_t i32;
1144 i32 = ASMModS64ByS32RetS32(INT64_C(-11), INT32_C(-2));
1145 CHECKVAL(i32, INT32_C(-1), "%010RI32");
1146 i32 = ASMModS64ByS32RetS32(INT64_C(-11), INT32_C(2));
1147 CHECKVAL(i32, INT32_C(-1), "%010RI32");
1148 i32 = ASMModS64ByS32RetS32(INT64_C(11), INT32_C(-2));
1149 CHECKVAL(i32, INT32_C(1), "%010RI32");
1150
1151 i32 = ASMModS64ByS32RetS32(INT64_C(92233720368547758), INT32_C(2147483647));
1152 CHECKVAL(i32, INT32_C(2104533974), "%010RI32");
1153 i32 = ASMModS64ByS32RetS32(INT64_C(-92233720368547758), INT32_C(2147483647));
1154 CHECKVAL(i32, INT32_C(-2104533974), "%010RI32");
1155}
1156
1157
1158void tstASMByteSwap(void)
1159{
1160 RTPrintf("tstInlineASM: TESTING - ASMByteSwap*\n");
1161
1162 uint64_t u64In = UINT64_C(0x0011223344556677);
1163 uint64_t u64Out = ASMByteSwapU64(u64In);
1164 CHECKVAL(u64In, UINT64_C(0x0011223344556677), "%#018RX64");
1165 CHECKVAL(u64Out, UINT64_C(0x7766554433221100), "%#018RX64");
1166 u64Out = ASMByteSwapU64(u64Out);
1167 CHECKVAL(u64Out, u64In, "%#018RX64");
1168 u64In = UINT64_C(0x0123456789abcdef);
1169 u64Out = ASMByteSwapU64(u64In);
1170 CHECKVAL(u64In, UINT64_C(0x0123456789abcdef), "%#018RX64");
1171 CHECKVAL(u64Out, UINT64_C(0xefcdab8967452301), "%#018RX64");
1172 u64Out = ASMByteSwapU64(u64Out);
1173 CHECKVAL(u64Out, u64In, "%#018RX64");
1174 u64In = 0;
1175 u64Out = ASMByteSwapU64(u64In);
1176 CHECKVAL(u64Out, u64In, "%#018RX64");
1177 u64In = ~(uint64_t)0;
1178 u64Out = ASMByteSwapU64(u64In);
1179 CHECKVAL(u64Out, u64In, "%#018RX64");
1180
1181 uint32_t u32In = UINT32_C(0x00112233);
1182 uint32_t u32Out = ASMByteSwapU32(u32In);
1183 CHECKVAL(u32In, UINT32_C(0x00112233), "%#010RX32");
1184 CHECKVAL(u32Out, UINT32_C(0x33221100), "%#010RX32");
1185 u32Out = ASMByteSwapU32(u32Out);
1186 CHECKVAL(u32Out, u32In, "%#010RX32");
1187 u32In = UINT32_C(0x12345678);
1188 u32Out = ASMByteSwapU32(u32In);
1189 CHECKVAL(u32In, UINT32_C(0x12345678), "%#010RX32");
1190 CHECKVAL(u32Out, UINT32_C(0x78563412), "%#010RX32");
1191 u32Out = ASMByteSwapU32(u32Out);
1192 CHECKVAL(u32Out, u32In, "%#010RX32");
1193 u32In = 0;
1194 u32Out = ASMByteSwapU32(u32In);
1195 CHECKVAL(u32Out, u32In, "%#010RX32");
1196 u32In = ~(uint32_t)0;
1197 u32Out = ASMByteSwapU32(u32In);
1198 CHECKVAL(u32Out, u32In, "%#010RX32");
1199
1200 uint16_t u16In = UINT16_C(0x0011);
1201 uint16_t u16Out = ASMByteSwapU16(u16In);
1202 CHECKVAL(u16In, UINT16_C(0x0011), "%#06RX16");
1203 CHECKVAL(u16Out, UINT16_C(0x1100), "%#06RX16");
1204 u16Out = ASMByteSwapU16(u16Out);
1205 CHECKVAL(u16Out, u16In, "%#06RX16");
1206 u16In = UINT16_C(0x1234);
1207 u16Out = ASMByteSwapU16(u16In);
1208 CHECKVAL(u16In, UINT16_C(0x1234), "%#06RX16");
1209 CHECKVAL(u16Out, UINT16_C(0x3412), "%#06RX16");
1210 u16Out = ASMByteSwapU16(u16Out);
1211 CHECKVAL(u16Out, u16In, "%#06RX16");
1212 u16In = 0;
1213 u16Out = ASMByteSwapU16(u16In);
1214 CHECKVAL(u16Out, u16In, "%#06RX16");
1215 u16In = ~(uint16_t)0;
1216 u16Out = ASMByteSwapU16(u16In);
1217 CHECKVAL(u16Out, u16In, "%#06RX16");
1218}
1219
1220
1221void tstASMBench(void)
1222{
1223 /*
1224 * Make this static. We don't want to have this located on the stack.
1225 */
1226 static uint8_t volatile s_u8;
1227 static int8_t volatile s_i8;
1228 static uint16_t volatile s_u16;
1229 static int16_t volatile s_i16;
1230 static uint32_t volatile s_u32;
1231 static int32_t volatile s_i32;
1232 static uint64_t volatile s_u64;
1233 static int64_t volatile s_i64;
1234 register unsigned i;
1235 const unsigned cRounds = 2000000;
1236 register uint64_t u64Elapsed;
1237
1238 RTPrintf("tstInlineASM: Benchmarking:\n");
1239
1240#if !defined(GCC44_32BIT_PIC) && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86))
1241# define BENCH(op, str) \
1242 do { \
1243 RTThreadYield(); \
1244 u64Elapsed = ASMReadTSC(); \
1245 for (i = cRounds; i > 0; i--) \
1246 op; \
1247 u64Elapsed = ASMReadTSC() - u64Elapsed; \
1248 RTPrintf(" %-30s %3llu cycles\n", str, u64Elapsed / cRounds); \
1249 } while (0)
1250#else
1251# define BENCH(op, str) \
1252 do { \
1253 RTThreadYield(); \
1254 u64Elapsed = RTTimeNanoTS(); \
1255 for (i = cRounds; i > 0; i--) \
1256 op; \
1257 u64Elapsed = RTTimeNanoTS() - u64Elapsed; \
1258 RTPrintf(" %-30s %3llu ns\n", str, u64Elapsed / cRounds); \
1259 } while (0)
1260#endif
1261
1262 BENCH(s_u32 = 0, "s_u32 = 0:");
1263 BENCH(ASMAtomicUoReadU8(&s_u8), "ASMAtomicUoReadU8:");
1264 BENCH(ASMAtomicUoReadS8(&s_i8), "ASMAtomicUoReadS8:");
1265 BENCH(ASMAtomicUoReadU16(&s_u16), "ASMAtomicUoReadU16:");
1266 BENCH(ASMAtomicUoReadS16(&s_i16), "ASMAtomicUoReadS16:");
1267 BENCH(ASMAtomicUoReadU32(&s_u32), "ASMAtomicUoReadU32:");
1268 BENCH(ASMAtomicUoReadS32(&s_i32), "ASMAtomicUoReadS32:");
1269 BENCH(ASMAtomicUoReadU64(&s_u64), "ASMAtomicUoReadU64:");
1270 BENCH(ASMAtomicUoReadS64(&s_i64), "ASMAtomicUoReadS64:");
1271 BENCH(ASMAtomicReadU8(&s_u8), "ASMAtomicReadU8:");
1272 BENCH(ASMAtomicReadS8(&s_i8), "ASMAtomicReadS8:");
1273 BENCH(ASMAtomicReadU16(&s_u16), "ASMAtomicReadU16:");
1274 BENCH(ASMAtomicReadS16(&s_i16), "ASMAtomicReadS16:");
1275 BENCH(ASMAtomicReadU32(&s_u32), "ASMAtomicReadU32:");
1276 BENCH(ASMAtomicReadS32(&s_i32), "ASMAtomicReadS32:");
1277 BENCH(ASMAtomicReadU64(&s_u64), "ASMAtomicReadU64:");
1278 BENCH(ASMAtomicReadS64(&s_i64), "ASMAtomicReadS64:");
1279 BENCH(ASMAtomicUoWriteU8(&s_u8, 0), "ASMAtomicUoWriteU8:");
1280 BENCH(ASMAtomicUoWriteS8(&s_i8, 0), "ASMAtomicUoWriteS8:");
1281 BENCH(ASMAtomicUoWriteU16(&s_u16, 0), "ASMAtomicUoWriteU16:");
1282 BENCH(ASMAtomicUoWriteS16(&s_i16, 0), "ASMAtomicUoWriteS16:");
1283 BENCH(ASMAtomicUoWriteU32(&s_u32, 0), "ASMAtomicUoWriteU32:");
1284 BENCH(ASMAtomicUoWriteS32(&s_i32, 0), "ASMAtomicUoWriteS32:");
1285 BENCH(ASMAtomicUoWriteU64(&s_u64, 0), "ASMAtomicUoWriteU64:");
1286 BENCH(ASMAtomicUoWriteS64(&s_i64, 0), "ASMAtomicUoWriteS64:");
1287 BENCH(ASMAtomicWriteU8(&s_u8, 0), "ASMAtomicWriteU8:");
1288 BENCH(ASMAtomicWriteS8(&s_i8, 0), "ASMAtomicWriteS8:");
1289 BENCH(ASMAtomicWriteU16(&s_u16, 0), "ASMAtomicWriteU16:");
1290 BENCH(ASMAtomicWriteS16(&s_i16, 0), "ASMAtomicWriteS16:");
1291 BENCH(ASMAtomicWriteU32(&s_u32, 0), "ASMAtomicWriteU32:");
1292 BENCH(ASMAtomicWriteS32(&s_i32, 0), "ASMAtomicWriteS32:");
1293 BENCH(ASMAtomicWriteU64(&s_u64, 0), "ASMAtomicWriteU64:");
1294 BENCH(ASMAtomicWriteS64(&s_i64, 0), "ASMAtomicWriteS64:");
1295 BENCH(ASMAtomicXchgU8(&s_u8, 0), "ASMAtomicXchgU8:");
1296 BENCH(ASMAtomicXchgS8(&s_i8, 0), "ASMAtomicXchgS8:");
1297 BENCH(ASMAtomicXchgU16(&s_u16, 0), "ASMAtomicXchgU16:");
1298 BENCH(ASMAtomicXchgS16(&s_i16, 0), "ASMAtomicXchgS16:");
1299 BENCH(ASMAtomicXchgU32(&s_u32, 0), "ASMAtomicXchgU32:");
1300 BENCH(ASMAtomicXchgS32(&s_i32, 0), "ASMAtomicXchgS32:");
1301 BENCH(ASMAtomicXchgU64(&s_u64, 0), "ASMAtomicXchgU64:");
1302 BENCH(ASMAtomicXchgS64(&s_i64, 0), "ASMAtomicXchgS64:");
1303 BENCH(ASMAtomicCmpXchgU32(&s_u32, 0, 0), "ASMAtomicCmpXchgU32:");
1304 BENCH(ASMAtomicCmpXchgS32(&s_i32, 0, 0), "ASMAtomicCmpXchgS32:");
1305 BENCH(ASMAtomicCmpXchgU64(&s_u64, 0, 0), "ASMAtomicCmpXchgU64:");
1306 BENCH(ASMAtomicCmpXchgS64(&s_i64, 0, 0), "ASMAtomicCmpXchgS64:");
1307 BENCH(ASMAtomicCmpXchgU32(&s_u32, 0, 1), "ASMAtomicCmpXchgU32/neg:");
1308 BENCH(ASMAtomicCmpXchgS32(&s_i32, 0, 1), "ASMAtomicCmpXchgS32/neg:");
1309 BENCH(ASMAtomicCmpXchgU64(&s_u64, 0, 1), "ASMAtomicCmpXchgU64/neg:");
1310 BENCH(ASMAtomicCmpXchgS64(&s_i64, 0, 1), "ASMAtomicCmpXchgS64/neg:");
1311 BENCH(ASMAtomicIncU32(&s_u32), "ASMAtomicIncU32:");
1312 BENCH(ASMAtomicIncS32(&s_i32), "ASMAtomicIncS32:");
1313 BENCH(ASMAtomicDecU32(&s_u32), "ASMAtomicDecU32:");
1314 BENCH(ASMAtomicDecS32(&s_i32), "ASMAtomicDecS32:");
1315 BENCH(ASMAtomicAddU32(&s_u32, 5), "ASMAtomicAddU32:");
1316 BENCH(ASMAtomicAddS32(&s_i32, 5), "ASMAtomicAddS32:");
1317 /* The Darwin gcc does not like this ... */
1318#if !defined(RT_OS_DARWIN) && !defined(GCC44_32BIT_PIC) && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86))
1319 BENCH(s_u8 = ASMGetApicId(), "ASMGetApicId:");
1320#endif
1321
1322 RTPrintf("Done.\n");
1323
1324#undef BENCH
1325}
1326
1327
1328int main(int argc, char *argv[])
1329{
1330 RTTEST hTest;
1331 int rc = RTTestInitAndCreate("tstInlineAsm", &hTest);
1332 if (rc)
1333 return rc;
1334 RTTestBanner(hTest);
1335
1336 /*
1337 * Execute the tests.
1338 */
1339#if !defined(GCC44_32BIT_PIC) && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86))
1340 tstASMCpuId();
1341#endif
1342 tstASMAtomicXchgU8();
1343 tstASMAtomicXchgU16();
1344 tstASMAtomicXchgU32();
1345 tstASMAtomicXchgU64();
1346 tstASMAtomicXchgPtr();
1347 tstASMAtomicCmpXchgU8();
1348 tstASMAtomicCmpXchgU32();
1349 tstASMAtomicCmpXchgU64();
1350 tstASMAtomicCmpXchgExU32();
1351 tstASMAtomicCmpXchgExU64();
1352 tstASMAtomicReadU64();
1353 tstASMAtomicUoReadU64();
1354 tstASMAtomicAddS32();
1355 tstASMAtomicDecIncS32();
1356 tstASMAtomicAndOrU32();
1357 tstASMMemZeroPage();
1358 tstASMMemIsZeroPage(hTest);
1359 tstASMMemZero32();
1360 tstASMMemFill32();
1361 tstASMMath();
1362 tstASMByteSwap();
1363 tstASMBench();
1364
1365 /*
1366 * Show the result.
1367 */
1368 return RTTestSummaryAndDestroy(hTest);
1369}
1370
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette