VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstRTInlineAsm.cpp@ 53401

Last change on this file since 53401 was 52454, checked in by vboxsync, 10 years ago

ASMMultU32ByU32DivByU32: Cleaned up mess. Tested on x86 and amd64-msc.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 65.0 KB
Line 
1/* $Id: tstRTInlineAsm.cpp 52454 2014-08-22 07:12:23Z vboxsync $ */
2/** @file
3 * IPRT Testcase - inline assembly.
4 */
5
6/*
7 * Copyright (C) 2006-2013 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/param.h>
50#include <iprt/thread.h>
51#include <iprt/test.h>
52#include <iprt/time.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 RTTestFailed(g_hTest, "%s, %d: " #val ": expected " fmt " got " fmt "\n", __FUNCTION__, __LINE__, (expect), (val)); \
65 } \
66 } while (0)
67
68#define CHECKOP(op, expect, fmt, type) \
69 do \
70 { \
71 type val = op; \
72 if (val != (type)(expect)) \
73 { \
74 RTTestFailed(g_hTest, "%s, %d: " #op ": expected " fmt " got " fmt "\n", __FUNCTION__, __LINE__, (type)(expect), val); \
75 } \
76 } while (0)
77
78/**
79 * Calls a worker function with different worker variable storage types.
80 */
81#define DO_SIMPLE_TEST(name, type) \
82 do \
83 { \
84 RTTestISub(#name); \
85 type StackVar; \
86 tst ## name ## Worker(&StackVar); \
87 \
88 type *pVar = (type *)RTTestGuardedAllocHead(g_hTest, sizeof(type)); \
89 RTTEST_CHECK_BREAK(g_hTest, pVar); \
90 tst ## name ## Worker(pVar); \
91 RTTestGuardedFree(g_hTest, pVar); \
92 \
93 pVar = (type *)RTTestGuardedAllocTail(g_hTest, sizeof(type)); \
94 RTTEST_CHECK_BREAK(g_hTest, pVar); \
95 tst ## name ## Worker(pVar); \
96 RTTestGuardedFree(g_hTest, pVar); \
97 } while (0)
98
99
100/*******************************************************************************
101* Global Variables *
102*******************************************************************************/
103/** The test instance. */
104static RTTEST g_hTest;
105
106
107
108#if !defined(GCC44_32BIT_PIC) && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86))
109
110const char *getCacheAss(unsigned u)
111{
112 if (u == 0)
113 return "res0 ";
114 if (u == 1)
115 return "direct";
116 if (u >= 256)
117 return "???";
118
119 char *pszRet;
120 RTStrAPrintf(&pszRet, "%d way", u); /* intentional leak! */
121 return pszRet;
122}
123
124
125const char *getL2CacheAss(unsigned u)
126{
127 switch (u)
128 {
129 case 0: return "off ";
130 case 1: return "direct";
131 case 2: return "2 way ";
132 case 3: return "res3 ";
133 case 4: return "4 way ";
134 case 5: return "res5 ";
135 case 6: return "8 way ";
136 case 7: return "res7 ";
137 case 8: return "16 way";
138 case 9: return "res9 ";
139 case 10: return "res10 ";
140 case 11: return "res11 ";
141 case 12: return "res12 ";
142 case 13: return "res13 ";
143 case 14: return "res14 ";
144 case 15: return "fully ";
145 default:
146 return "????";
147 }
148}
149
150
151/**
152 * Test and dump all possible info from the CPUID instruction.
153 *
154 * @remark Bits shared with the libc cpuid.c program. This all written by me, so no worries.
155 * @todo transform the dumping into a generic runtime function. We'll need it for logging!
156 */
157void tstASMCpuId(void)
158{
159 RTTestISub("ASMCpuId");
160
161 unsigned iBit;
162 struct
163 {
164 uint32_t uEBX, uEAX, uEDX, uECX;
165 } s;
166 if (!ASMHasCpuId())
167 {
168 RTTestIPrintf(RTTESTLVL_ALWAYS, "warning! CPU doesn't support CPUID\n");
169 return;
170 }
171
172 /*
173 * Try the 0 function and use that for checking the ASMCpuId_* variants.
174 */
175 ASMCpuId(0, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
176
177 uint32_t u32;
178
179 u32 = ASMCpuId_EAX(0);
180 CHECKVAL(u32, s.uEAX, "%x");
181 u32 = ASMCpuId_EBX(0);
182 CHECKVAL(u32, s.uEBX, "%x");
183 u32 = ASMCpuId_ECX(0);
184 CHECKVAL(u32, s.uECX, "%x");
185 u32 = ASMCpuId_EDX(0);
186 CHECKVAL(u32, s.uEDX, "%x");
187
188 uint32_t uECX2 = s.uECX - 1;
189 uint32_t uEDX2 = s.uEDX - 1;
190 ASMCpuId_ECX_EDX(0, &uECX2, &uEDX2);
191 CHECKVAL(uECX2, s.uECX, "%x");
192 CHECKVAL(uEDX2, s.uEDX, "%x");
193
194 uint32_t uEAX2 = s.uEAX - 1;
195 uint32_t uEBX2 = s.uEBX - 1;
196 uECX2 = s.uECX - 1;
197 uEDX2 = s.uEDX - 1;
198 ASMCpuIdExSlow(0, 0, 0, 0, &uEAX2, &uEBX2, &uECX2, &uEDX2);
199 CHECKVAL(uEAX2, s.uEAX, "%x");
200 CHECKVAL(uEBX2, s.uEBX, "%x");
201 CHECKVAL(uECX2, s.uECX, "%x");
202 CHECKVAL(uEDX2, s.uEDX, "%x");
203
204 /*
205 * Done testing, dump the information.
206 */
207 RTTestIPrintf(RTTESTLVL_ALWAYS, "CPUID Dump\n");
208 ASMCpuId(0, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
209 const uint32_t cFunctions = s.uEAX;
210
211 /* raw dump */
212 RTTestIPrintf(RTTESTLVL_ALWAYS,
213 "\n"
214 " RAW Standard CPUIDs\n"
215 "Function eax ebx ecx edx\n");
216 for (unsigned iStd = 0; iStd <= cFunctions + 3; iStd++)
217 {
218 ASMCpuId_Idx_ECX(iStd, 0, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
219 RTTestIPrintf(RTTESTLVL_ALWAYS, "%08x %08x %08x %08x %08x%s\n",
220 iStd, s.uEAX, s.uEBX, s.uECX, s.uEDX, iStd <= cFunctions ? "" : "*");
221
222 /* Leaf 04 and leaf 0d output depend on the initial value of ECX
223 * The same seems to apply to invalid standard functions */
224 if (iStd > cFunctions)
225 continue;
226 if (iStd != 0x04 && iStd != 0x0b && iStd != 0x0d)
227 {
228 u32 = ASMCpuId_EAX(iStd);
229 CHECKVAL(u32, s.uEAX, "%x");
230
231 uint32_t u32EbxMask = UINT32_MAX;
232 if (iStd == 1)
233 u32EbxMask = UINT32_C(0x00ffffff); /* Omit the local apic ID in case we're rescheduled. */
234 u32 = ASMCpuId_EBX(iStd);
235 CHECKVAL(u32 & u32EbxMask, s.uEBX & u32EbxMask, "%x");
236
237 u32 = ASMCpuId_ECX(iStd);
238 CHECKVAL(u32, s.uECX, "%x");
239 u32 = ASMCpuId_EDX(iStd);
240 CHECKVAL(u32, s.uEDX, "%x");
241
242 uECX2 = s.uECX - 1;
243 uEDX2 = s.uEDX - 1;
244 ASMCpuId_ECX_EDX(iStd, &uECX2, &uEDX2);
245 CHECKVAL(uECX2, s.uECX, "%x");
246 CHECKVAL(uEDX2, s.uEDX, "%x");
247 }
248
249 if (iStd == 0x04)
250 for (uint32_t uECX = 1; s.uEAX & 0x1f; uECX++)
251 {
252 ASMCpuId_Idx_ECX(iStd, uECX, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
253 RTTestIPrintf(RTTESTLVL_ALWAYS, " [%02x] %08x %08x %08x %08x\n", uECX, s.uEAX, s.uEBX, s.uECX, s.uEDX);
254 RTTESTI_CHECK_BREAK(uECX < 128);
255 }
256 else if (iStd == 0x0b)
257 for (uint32_t uECX = 1; (s.uEAX & 0x1f) && (s.uEBX & 0xffff); uECX++)
258 {
259 ASMCpuId_Idx_ECX(iStd, uECX, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
260 RTTestIPrintf(RTTESTLVL_ALWAYS, " [%02x] %08x %08x %08x %08x\n", uECX, s.uEAX, s.uEBX, s.uECX, s.uEDX);
261 RTTESTI_CHECK_BREAK(uECX < 128);
262 }
263 else if (iStd == 0x0d)
264 for (uint32_t uECX = 1; s.uEAX != 0 || s.uEBX != 0 || s.uECX != 0 || s.uEDX != 0; uECX++)
265 {
266 ASMCpuId_Idx_ECX(iStd, uECX, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
267 RTTestIPrintf(RTTESTLVL_ALWAYS, " [%02x] %08x %08x %08x %08x\n", uECX, s.uEAX, s.uEBX, s.uECX, s.uEDX);
268 RTTESTI_CHECK_BREAK(uECX < 128);
269 }
270 }
271
272 /*
273 * Understandable output
274 */
275 ASMCpuId(0, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
276 RTTestIPrintf(RTTESTLVL_ALWAYS,
277 "Name: %.04s%.04s%.04s\n"
278 "Support: 0-%u\n",
279 &s.uEBX, &s.uEDX, &s.uECX, s.uEAX);
280 bool const fIntel = ASMIsIntelCpuEx(s.uEBX, s.uECX, s.uEDX);
281
282 /*
283 * Get Features.
284 */
285 if (cFunctions >= 1)
286 {
287 static const char * const s_apszTypes[4] = { "primary", "overdrive", "MP", "reserved" };
288 ASMCpuId(1, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
289 RTTestIPrintf(RTTESTLVL_ALWAYS,
290 "Family: %#x \tExtended: %#x \tEffective: %#x\n"
291 "Model: %#x \tExtended: %#x \tEffective: %#x\n"
292 "Stepping: %d\n"
293 "Type: %d (%s)\n"
294 "APIC ID: %#04x\n"
295 "Logical CPUs: %d\n"
296 "CLFLUSH Size: %d\n"
297 "Brand ID: %#04x\n",
298 (s.uEAX >> 8) & 0xf, (s.uEAX >> 20) & 0x7f, ASMGetCpuFamily(s.uEAX),
299 (s.uEAX >> 4) & 0xf, (s.uEAX >> 16) & 0x0f, ASMGetCpuModel(s.uEAX, fIntel),
300 ASMGetCpuStepping(s.uEAX),
301 (s.uEAX >> 12) & 0x3, s_apszTypes[(s.uEAX >> 12) & 0x3],
302 (s.uEBX >> 24) & 0xff,
303 (s.uEBX >> 16) & 0xff,
304 (s.uEBX >> 8) & 0xff,
305 (s.uEBX >> 0) & 0xff);
306
307 RTTestIPrintf(RTTESTLVL_ALWAYS, "Features EDX: ");
308 if (s.uEDX & RT_BIT(0)) RTTestIPrintf(RTTESTLVL_ALWAYS, " FPU");
309 if (s.uEDX & RT_BIT(1)) RTTestIPrintf(RTTESTLVL_ALWAYS, " VME");
310 if (s.uEDX & RT_BIT(2)) RTTestIPrintf(RTTESTLVL_ALWAYS, " DE");
311 if (s.uEDX & RT_BIT(3)) RTTestIPrintf(RTTESTLVL_ALWAYS, " PSE");
312 if (s.uEDX & RT_BIT(4)) RTTestIPrintf(RTTESTLVL_ALWAYS, " TSC");
313 if (s.uEDX & RT_BIT(5)) RTTestIPrintf(RTTESTLVL_ALWAYS, " MSR");
314 if (s.uEDX & RT_BIT(6)) RTTestIPrintf(RTTESTLVL_ALWAYS, " PAE");
315 if (s.uEDX & RT_BIT(7)) RTTestIPrintf(RTTESTLVL_ALWAYS, " MCE");
316 if (s.uEDX & RT_BIT(8)) RTTestIPrintf(RTTESTLVL_ALWAYS, " CX8");
317 if (s.uEDX & RT_BIT(9)) RTTestIPrintf(RTTESTLVL_ALWAYS, " APIC");
318 if (s.uEDX & RT_BIT(10)) RTTestIPrintf(RTTESTLVL_ALWAYS, " 10");
319 if (s.uEDX & RT_BIT(11)) RTTestIPrintf(RTTESTLVL_ALWAYS, " SEP");
320 if (s.uEDX & RT_BIT(12)) RTTestIPrintf(RTTESTLVL_ALWAYS, " MTRR");
321 if (s.uEDX & RT_BIT(13)) RTTestIPrintf(RTTESTLVL_ALWAYS, " PGE");
322 if (s.uEDX & RT_BIT(14)) RTTestIPrintf(RTTESTLVL_ALWAYS, " MCA");
323 if (s.uEDX & RT_BIT(15)) RTTestIPrintf(RTTESTLVL_ALWAYS, " CMOV");
324 if (s.uEDX & RT_BIT(16)) RTTestIPrintf(RTTESTLVL_ALWAYS, " PAT");
325 if (s.uEDX & RT_BIT(17)) RTTestIPrintf(RTTESTLVL_ALWAYS, " PSE36");
326 if (s.uEDX & RT_BIT(18)) RTTestIPrintf(RTTESTLVL_ALWAYS, " PSN");
327 if (s.uEDX & RT_BIT(19)) RTTestIPrintf(RTTESTLVL_ALWAYS, " CLFSH");
328 if (s.uEDX & RT_BIT(20)) RTTestIPrintf(RTTESTLVL_ALWAYS, " 20");
329 if (s.uEDX & RT_BIT(21)) RTTestIPrintf(RTTESTLVL_ALWAYS, " DS");
330 if (s.uEDX & RT_BIT(22)) RTTestIPrintf(RTTESTLVL_ALWAYS, " ACPI");
331 if (s.uEDX & RT_BIT(23)) RTTestIPrintf(RTTESTLVL_ALWAYS, " MMX");
332 if (s.uEDX & RT_BIT(24)) RTTestIPrintf(RTTESTLVL_ALWAYS, " FXSR");
333 if (s.uEDX & RT_BIT(25)) RTTestIPrintf(RTTESTLVL_ALWAYS, " SSE");
334 if (s.uEDX & RT_BIT(26)) RTTestIPrintf(RTTESTLVL_ALWAYS, " SSE2");
335 if (s.uEDX & RT_BIT(27)) RTTestIPrintf(RTTESTLVL_ALWAYS, " SS");
336 if (s.uEDX & RT_BIT(28)) RTTestIPrintf(RTTESTLVL_ALWAYS, " HTT");
337 if (s.uEDX & RT_BIT(29)) RTTestIPrintf(RTTESTLVL_ALWAYS, " 29");
338 if (s.uEDX & RT_BIT(30)) RTTestIPrintf(RTTESTLVL_ALWAYS, " 30");
339 if (s.uEDX & RT_BIT(31)) RTTestIPrintf(RTTESTLVL_ALWAYS, " 31");
340 RTTestIPrintf(RTTESTLVL_ALWAYS, "\n");
341
342 /** @todo check intel docs. */
343 RTTestIPrintf(RTTESTLVL_ALWAYS, "Features ECX: ");
344 if (s.uECX & RT_BIT(0)) RTTestIPrintf(RTTESTLVL_ALWAYS, " SSE3");
345 for (iBit = 1; iBit < 13; iBit++)
346 if (s.uECX & RT_BIT(iBit))
347 RTTestIPrintf(RTTESTLVL_ALWAYS, " %d", iBit);
348 if (s.uECX & RT_BIT(13)) RTTestIPrintf(RTTESTLVL_ALWAYS, " CX16");
349 for (iBit = 14; iBit < 32; iBit++)
350 if (s.uECX & RT_BIT(iBit))
351 RTTestIPrintf(RTTESTLVL_ALWAYS, " %d", iBit);
352 RTTestIPrintf(RTTESTLVL_ALWAYS, "\n");
353 }
354
355 /*
356 * Extended.
357 * Implemented after AMD specs.
358 */
359 /** @todo check out the intel specs. */
360 ASMCpuId(0x80000000, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
361 if (!s.uEAX && !s.uEBX && !s.uECX && !s.uEDX)
362 {
363 RTTestIPrintf(RTTESTLVL_ALWAYS, "No extended CPUID info? Check the manual on how to detect this...\n");
364 return;
365 }
366 const uint32_t cExtFunctions = s.uEAX | 0x80000000;
367
368 /* raw dump */
369 RTTestIPrintf(RTTESTLVL_ALWAYS,
370 "\n"
371 " RAW Extended CPUIDs\n"
372 "Function eax ebx ecx edx\n");
373 for (unsigned iExt = 0x80000000; iExt <= cExtFunctions + 3; iExt++)
374 {
375 ASMCpuId(iExt, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
376 RTTestIPrintf(RTTESTLVL_ALWAYS, "%08x %08x %08x %08x %08x%s\n",
377 iExt, s.uEAX, s.uEBX, s.uECX, s.uEDX, iExt <= cExtFunctions ? "" : "*");
378
379 if (iExt > cExtFunctions)
380 continue; /* Invalid extended functions seems change the value if ECX changes */
381 if (iExt == 0x8000001d)
382 continue; /* Takes cache level in ecx. */
383
384 u32 = ASMCpuId_EAX(iExt);
385 CHECKVAL(u32, s.uEAX, "%x");
386 u32 = ASMCpuId_EBX(iExt);
387 CHECKVAL(u32, s.uEBX, "%x");
388 u32 = ASMCpuId_ECX(iExt);
389 CHECKVAL(u32, s.uECX, "%x");
390 u32 = ASMCpuId_EDX(iExt);
391 CHECKVAL(u32, s.uEDX, "%x");
392
393 uECX2 = s.uECX - 1;
394 uEDX2 = s.uEDX - 1;
395 ASMCpuId_ECX_EDX(iExt, &uECX2, &uEDX2);
396 CHECKVAL(uECX2, s.uECX, "%x");
397 CHECKVAL(uEDX2, s.uEDX, "%x");
398 }
399
400 /*
401 * Understandable output
402 */
403 ASMCpuId(0x80000000, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
404 RTTestIPrintf(RTTESTLVL_ALWAYS,
405 "Ext Name: %.4s%.4s%.4s\n"
406 "Ext Supports: 0x80000000-%#010x\n",
407 &s.uEBX, &s.uEDX, &s.uECX, s.uEAX);
408
409 if (cExtFunctions >= 0x80000001)
410 {
411 ASMCpuId(0x80000001, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
412 RTTestIPrintf(RTTESTLVL_ALWAYS,
413 "Family: %#x \tExtended: %#x \tEffective: %#x\n"
414 "Model: %#x \tExtended: %#x \tEffective: %#x\n"
415 "Stepping: %d\n"
416 "Brand ID: %#05x\n",
417 (s.uEAX >> 8) & 0xf, (s.uEAX >> 20) & 0x7f, ASMGetCpuFamily(s.uEAX),
418 (s.uEAX >> 4) & 0xf, (s.uEAX >> 16) & 0x0f, ASMGetCpuModel(s.uEAX, fIntel),
419 ASMGetCpuStepping(s.uEAX),
420 s.uEBX & 0xfff);
421
422 RTTestIPrintf(RTTESTLVL_ALWAYS, "Features EDX: ");
423 if (s.uEDX & RT_BIT(0)) RTTestIPrintf(RTTESTLVL_ALWAYS, " FPU");
424 if (s.uEDX & RT_BIT(1)) RTTestIPrintf(RTTESTLVL_ALWAYS, " VME");
425 if (s.uEDX & RT_BIT(2)) RTTestIPrintf(RTTESTLVL_ALWAYS, " DE");
426 if (s.uEDX & RT_BIT(3)) RTTestIPrintf(RTTESTLVL_ALWAYS, " PSE");
427 if (s.uEDX & RT_BIT(4)) RTTestIPrintf(RTTESTLVL_ALWAYS, " TSC");
428 if (s.uEDX & RT_BIT(5)) RTTestIPrintf(RTTESTLVL_ALWAYS, " MSR");
429 if (s.uEDX & RT_BIT(6)) RTTestIPrintf(RTTESTLVL_ALWAYS, " PAE");
430 if (s.uEDX & RT_BIT(7)) RTTestIPrintf(RTTESTLVL_ALWAYS, " MCE");
431 if (s.uEDX & RT_BIT(8)) RTTestIPrintf(RTTESTLVL_ALWAYS, " CMPXCHG8B");
432 if (s.uEDX & RT_BIT(9)) RTTestIPrintf(RTTESTLVL_ALWAYS, " APIC");
433 if (s.uEDX & RT_BIT(10)) RTTestIPrintf(RTTESTLVL_ALWAYS, " 10");
434 if (s.uEDX & RT_BIT(11)) RTTestIPrintf(RTTESTLVL_ALWAYS, " SysCallSysRet");
435 if (s.uEDX & RT_BIT(12)) RTTestIPrintf(RTTESTLVL_ALWAYS, " MTRR");
436 if (s.uEDX & RT_BIT(13)) RTTestIPrintf(RTTESTLVL_ALWAYS, " PGE");
437 if (s.uEDX & RT_BIT(14)) RTTestIPrintf(RTTESTLVL_ALWAYS, " MCA");
438 if (s.uEDX & RT_BIT(15)) RTTestIPrintf(RTTESTLVL_ALWAYS, " CMOV");
439 if (s.uEDX & RT_BIT(16)) RTTestIPrintf(RTTESTLVL_ALWAYS, " PAT");
440 if (s.uEDX & RT_BIT(17)) RTTestIPrintf(RTTESTLVL_ALWAYS, " PSE36");
441 if (s.uEDX & RT_BIT(18)) RTTestIPrintf(RTTESTLVL_ALWAYS, " 18");
442 if (s.uEDX & RT_BIT(19)) RTTestIPrintf(RTTESTLVL_ALWAYS, " 19");
443 if (s.uEDX & RT_BIT(20)) RTTestIPrintf(RTTESTLVL_ALWAYS, " NX");
444 if (s.uEDX & RT_BIT(21)) RTTestIPrintf(RTTESTLVL_ALWAYS, " 21");
445 if (s.uEDX & RT_BIT(22)) RTTestIPrintf(RTTESTLVL_ALWAYS, " MmxExt");
446 if (s.uEDX & RT_BIT(23)) RTTestIPrintf(RTTESTLVL_ALWAYS, " MMX");
447 if (s.uEDX & RT_BIT(24)) RTTestIPrintf(RTTESTLVL_ALWAYS, " FXSR");
448 if (s.uEDX & RT_BIT(25)) RTTestIPrintf(RTTESTLVL_ALWAYS, " FastFXSR");
449 if (s.uEDX & RT_BIT(26)) RTTestIPrintf(RTTESTLVL_ALWAYS, " 26");
450 if (s.uEDX & RT_BIT(27)) RTTestIPrintf(RTTESTLVL_ALWAYS, " RDTSCP");
451 if (s.uEDX & RT_BIT(28)) RTTestIPrintf(RTTESTLVL_ALWAYS, " 28");
452 if (s.uEDX & RT_BIT(29)) RTTestIPrintf(RTTESTLVL_ALWAYS, " LongMode");
453 if (s.uEDX & RT_BIT(30)) RTTestIPrintf(RTTESTLVL_ALWAYS, " 3DNowExt");
454 if (s.uEDX & RT_BIT(31)) RTTestIPrintf(RTTESTLVL_ALWAYS, " 3DNow");
455 RTTestIPrintf(RTTESTLVL_ALWAYS, "\n");
456
457 RTTestIPrintf(RTTESTLVL_ALWAYS, "Features ECX: ");
458 if (s.uECX & RT_BIT(0)) RTTestIPrintf(RTTESTLVL_ALWAYS, " LahfSahf");
459 if (s.uECX & RT_BIT(1)) RTTestIPrintf(RTTESTLVL_ALWAYS, " CmpLegacy");
460 if (s.uECX & RT_BIT(2)) RTTestIPrintf(RTTESTLVL_ALWAYS, " SVM");
461 if (s.uECX & RT_BIT(3)) RTTestIPrintf(RTTESTLVL_ALWAYS, " 3");
462 if (s.uECX & RT_BIT(4)) RTTestIPrintf(RTTESTLVL_ALWAYS, " AltMovCr8");
463 for (iBit = 5; iBit < 32; iBit++)
464 if (s.uECX & RT_BIT(iBit))
465 RTTestIPrintf(RTTESTLVL_ALWAYS, " %d", iBit);
466 RTTestIPrintf(RTTESTLVL_ALWAYS, "\n");
467 }
468
469 char szString[4*4*3+1] = {0};
470 if (cExtFunctions >= 0x80000002)
471 ASMCpuId(0x80000002, &szString[0 + 0], &szString[0 + 4], &szString[0 + 8], &szString[0 + 12]);
472 if (cExtFunctions >= 0x80000003)
473 ASMCpuId(0x80000003, &szString[16 + 0], &szString[16 + 4], &szString[16 + 8], &szString[16 + 12]);
474 if (cExtFunctions >= 0x80000004)
475 ASMCpuId(0x80000004, &szString[32 + 0], &szString[32 + 4], &szString[32 + 8], &szString[32 + 12]);
476 if (cExtFunctions >= 0x80000002)
477 RTTestIPrintf(RTTESTLVL_ALWAYS, "Full Name: %s\n", szString);
478
479 if (cExtFunctions >= 0x80000005)
480 {
481 ASMCpuId(0x80000005, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
482 RTTestIPrintf(RTTESTLVL_ALWAYS,
483 "TLB 2/4M Instr/Uni: %s %3d entries\n"
484 "TLB 2/4M Data: %s %3d entries\n",
485 getCacheAss((s.uEAX >> 8) & 0xff), (s.uEAX >> 0) & 0xff,
486 getCacheAss((s.uEAX >> 24) & 0xff), (s.uEAX >> 16) & 0xff);
487 RTTestIPrintf(RTTESTLVL_ALWAYS,
488 "TLB 4K Instr/Uni: %s %3d entries\n"
489 "TLB 4K Data: %s %3d entries\n",
490 getCacheAss((s.uEBX >> 8) & 0xff), (s.uEBX >> 0) & 0xff,
491 getCacheAss((s.uEBX >> 24) & 0xff), (s.uEBX >> 16) & 0xff);
492 RTTestIPrintf(RTTESTLVL_ALWAYS,
493 "L1 Instr Cache Line Size: %d bytes\n"
494 "L1 Instr Cache Lines Per Tag: %d\n"
495 "L1 Instr Cache Associativity: %s\n"
496 "L1 Instr Cache Size: %d KB\n",
497 (s.uEDX >> 0) & 0xff,
498 (s.uEDX >> 8) & 0xff,
499 getCacheAss((s.uEDX >> 16) & 0xff),
500 (s.uEDX >> 24) & 0xff);
501 RTTestIPrintf(RTTESTLVL_ALWAYS,
502 "L1 Data Cache Line Size: %d bytes\n"
503 "L1 Data Cache Lines Per Tag: %d\n"
504 "L1 Data Cache Associativity: %s\n"
505 "L1 Data Cache Size: %d KB\n",
506 (s.uECX >> 0) & 0xff,
507 (s.uECX >> 8) & 0xff,
508 getCacheAss((s.uECX >> 16) & 0xff),
509 (s.uECX >> 24) & 0xff);
510 }
511
512 if (cExtFunctions >= 0x80000006)
513 {
514 ASMCpuId(0x80000006, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
515 RTTestIPrintf(RTTESTLVL_ALWAYS,
516 "L2 TLB 2/4M Instr/Uni: %s %4d entries\n"
517 "L2 TLB 2/4M Data: %s %4d entries\n",
518 getL2CacheAss((s.uEAX >> 12) & 0xf), (s.uEAX >> 0) & 0xfff,
519 getL2CacheAss((s.uEAX >> 28) & 0xf), (s.uEAX >> 16) & 0xfff);
520 RTTestIPrintf(RTTESTLVL_ALWAYS,
521 "L2 TLB 4K Instr/Uni: %s %4d entries\n"
522 "L2 TLB 4K Data: %s %4d entries\n",
523 getL2CacheAss((s.uEBX >> 12) & 0xf), (s.uEBX >> 0) & 0xfff,
524 getL2CacheAss((s.uEBX >> 28) & 0xf), (s.uEBX >> 16) & 0xfff);
525 RTTestIPrintf(RTTESTLVL_ALWAYS,
526 "L2 Cache Line Size: %d bytes\n"
527 "L2 Cache Lines Per Tag: %d\n"
528 "L2 Cache Associativity: %s\n"
529 "L2 Cache Size: %d KB\n",
530 (s.uEDX >> 0) & 0xff,
531 (s.uEDX >> 8) & 0xf,
532 getL2CacheAss((s.uEDX >> 12) & 0xf),
533 (s.uEDX >> 16) & 0xffff);
534 }
535
536 if (cExtFunctions >= 0x80000007)
537 {
538 ASMCpuId(0x80000007, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
539 RTTestIPrintf(RTTESTLVL_ALWAYS, "APM Features: ");
540 if (s.uEDX & RT_BIT(0)) RTTestIPrintf(RTTESTLVL_ALWAYS, " TS");
541 if (s.uEDX & RT_BIT(1)) RTTestIPrintf(RTTESTLVL_ALWAYS, " FID");
542 if (s.uEDX & RT_BIT(2)) RTTestIPrintf(RTTESTLVL_ALWAYS, " VID");
543 if (s.uEDX & RT_BIT(3)) RTTestIPrintf(RTTESTLVL_ALWAYS, " TTP");
544 if (s.uEDX & RT_BIT(4)) RTTestIPrintf(RTTESTLVL_ALWAYS, " TM");
545 if (s.uEDX & RT_BIT(5)) RTTestIPrintf(RTTESTLVL_ALWAYS, " STC");
546 if (s.uEDX & RT_BIT(6)) RTTestIPrintf(RTTESTLVL_ALWAYS, " 6");
547 if (s.uEDX & RT_BIT(7)) RTTestIPrintf(RTTESTLVL_ALWAYS, " 7");
548 if (s.uEDX & RT_BIT(8)) RTTestIPrintf(RTTESTLVL_ALWAYS, " TscInvariant");
549 for (iBit = 9; iBit < 32; iBit++)
550 if (s.uEDX & RT_BIT(iBit))
551 RTTestIPrintf(RTTESTLVL_ALWAYS, " %d", iBit);
552 RTTestIPrintf(RTTESTLVL_ALWAYS, "\n");
553 }
554
555 if (cExtFunctions >= 0x80000008)
556 {
557 ASMCpuId(0x80000008, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
558 RTTestIPrintf(RTTESTLVL_ALWAYS,
559 "Physical Address Width: %d bits\n"
560 "Virtual Address Width: %d bits\n"
561 "Guest Physical Address Width: %d bits\n",
562 (s.uEAX >> 0) & 0xff,
563 (s.uEAX >> 8) & 0xff,
564 (s.uEAX >> 16) & 0xff);
565 RTTestIPrintf(RTTESTLVL_ALWAYS,
566 "Physical Core Count: %d\n",
567 ((s.uECX >> 0) & 0xff) + 1);
568 if ((s.uECX >> 12) & 0xf)
569 RTTestIPrintf(RTTESTLVL_ALWAYS, "ApicIdCoreIdSize: %d bits\n", (s.uECX >> 12) & 0xf);
570 }
571
572 if (cExtFunctions >= 0x8000000a)
573 {
574 ASMCpuId(0x8000000a, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
575 RTTestIPrintf(RTTESTLVL_ALWAYS,
576 "SVM Revision: %d (%#x)\n"
577 "Number of Address Space IDs: %d (%#x)\n",
578 s.uEAX & 0xff, s.uEAX & 0xff,
579 s.uEBX, s.uEBX);
580 }
581}
582
583# if 0
584static void bruteForceCpuId(void)
585{
586 RTTestISub("brute force CPUID leafs");
587 uint32_t auPrevValues[4] = { 0, 0, 0, 0};
588 uint32_t uLeaf = 0;
589 do
590 {
591 uint32_t auValues[4];
592 ASMCpuIdExSlow(uLeaf, 0, 0, 0, &auValues[0], &auValues[1], &auValues[2], &auValues[3]);
593 if ( (auValues[0] != auPrevValues[0] && auValues[0] != uLeaf)
594 || (auValues[1] != auPrevValues[1] && auValues[1] != 0)
595 || (auValues[2] != auPrevValues[2] && auValues[2] != 0)
596 || (auValues[3] != auPrevValues[3] && auValues[3] != 0)
597 || (uLeaf & (UINT32_C(0x08000000) - UINT32_C(1))) == 0)
598 {
599 RTTestIPrintf(RTTESTLVL_ALWAYS,
600 "%08x: %08x %08x %08x %08x\n", uLeaf,
601 auValues[0], auValues[1], auValues[2], auValues[3]);
602 }
603 auPrevValues[0] = auValues[0];
604 auPrevValues[1] = auValues[1];
605 auPrevValues[2] = auValues[2];
606 auPrevValues[3] = auValues[3];
607
608 //uint32_t uSubLeaf = 0;
609 //do
610 //{
611 //
612 //
613 //} while (false);
614 } while (uLeaf++ < UINT32_MAX);
615}
616# endif
617
618#endif /* AMD64 || X86 */
619
620DECLINLINE(void) tstASMAtomicXchgU8Worker(uint8_t volatile *pu8)
621{
622 *pu8 = 0;
623 CHECKOP(ASMAtomicXchgU8(pu8, 1), 0, "%#x", uint8_t);
624 CHECKVAL(*pu8, 1, "%#x");
625
626 CHECKOP(ASMAtomicXchgU8(pu8, 0), 1, "%#x", uint8_t);
627 CHECKVAL(*pu8, 0, "%#x");
628
629 CHECKOP(ASMAtomicXchgU8(pu8, 0xff), 0, "%#x", uint8_t);
630 CHECKVAL(*pu8, 0xff, "%#x");
631
632 CHECKOP(ASMAtomicXchgU8(pu8, 0x87), 0xffff, "%#x", uint8_t);
633 CHECKVAL(*pu8, 0x87, "%#x");
634}
635
636
637static void tstASMAtomicXchgU8(void)
638{
639 DO_SIMPLE_TEST(ASMAtomicXchgU8, uint8_t);
640}
641
642
643DECLINLINE(void) tstASMAtomicXchgU16Worker(uint16_t volatile *pu16)
644{
645 *pu16 = 0;
646
647 CHECKOP(ASMAtomicXchgU16(pu16, 1), 0, "%#x", uint16_t);
648 CHECKVAL(*pu16, 1, "%#x");
649
650 CHECKOP(ASMAtomicXchgU16(pu16, 0), 1, "%#x", uint16_t);
651 CHECKVAL(*pu16, 0, "%#x");
652
653 CHECKOP(ASMAtomicXchgU16(pu16, 0xffff), 0, "%#x", uint16_t);
654 CHECKVAL(*pu16, 0xffff, "%#x");
655
656 CHECKOP(ASMAtomicXchgU16(pu16, 0x8765), 0xffff, "%#x", uint16_t);
657 CHECKVAL(*pu16, 0x8765, "%#x");
658}
659
660
661static void tstASMAtomicXchgU16(void)
662{
663 DO_SIMPLE_TEST(ASMAtomicXchgU16, uint16_t);
664}
665
666
667DECLINLINE(void) tstASMAtomicXchgU32Worker(uint32_t volatile *pu32)
668{
669 *pu32 = 0;
670
671 CHECKOP(ASMAtomicXchgU32(pu32, 1), 0, "%#x", uint32_t);
672 CHECKVAL(*pu32, 1, "%#x");
673
674 CHECKOP(ASMAtomicXchgU32(pu32, 0), 1, "%#x", uint32_t);
675 CHECKVAL(*pu32, 0, "%#x");
676
677 CHECKOP(ASMAtomicXchgU32(pu32, ~UINT32_C(0)), 0, "%#x", uint32_t);
678 CHECKVAL(*pu32, ~UINT32_C(0), "%#x");
679
680 CHECKOP(ASMAtomicXchgU32(pu32, 0x87654321), ~UINT32_C(0), "%#x", uint32_t);
681 CHECKVAL(*pu32, 0x87654321, "%#x");
682}
683
684
685static void tstASMAtomicXchgU32(void)
686{
687 DO_SIMPLE_TEST(ASMAtomicXchgU32, uint32_t);
688}
689
690
691DECLINLINE(void) tstASMAtomicXchgU64Worker(uint64_t volatile *pu64)
692{
693 *pu64 = 0;
694
695 CHECKOP(ASMAtomicXchgU64(pu64, 1), UINT64_C(0), "%#llx", uint64_t);
696 CHECKVAL(*pu64, UINT64_C(1), "%#llx");
697
698 CHECKOP(ASMAtomicXchgU64(pu64, 0), UINT64_C(1), "%#llx", uint64_t);
699 CHECKVAL(*pu64, UINT64_C(0), "%#llx");
700
701 CHECKOP(ASMAtomicXchgU64(pu64, ~UINT64_C(0)), UINT64_C(0), "%#llx", uint64_t);
702 CHECKVAL(*pu64, ~UINT64_C(0), "%#llx");
703
704 CHECKOP(ASMAtomicXchgU64(pu64, UINT64_C(0xfedcba0987654321)), ~UINT64_C(0), "%#llx", uint64_t);
705 CHECKVAL(*pu64, UINT64_C(0xfedcba0987654321), "%#llx");
706}
707
708
709static void tstASMAtomicXchgU64(void)
710{
711 DO_SIMPLE_TEST(ASMAtomicXchgU64, uint64_t);
712}
713
714
715DECLINLINE(void) tstASMAtomicXchgPtrWorker(void * volatile *ppv)
716{
717 *ppv = NULL;
718
719 CHECKOP(ASMAtomicXchgPtr(ppv, (void *)(~(uintptr_t)0)), NULL, "%p", void *);
720 CHECKVAL(*ppv, (void *)(~(uintptr_t)0), "%p");
721
722 CHECKOP(ASMAtomicXchgPtr(ppv, (void *)0x87654321), (void *)(~(uintptr_t)0), "%p", void *);
723 CHECKVAL(*ppv, (void *)0x87654321, "%p");
724
725 CHECKOP(ASMAtomicXchgPtr(ppv, NULL), (void *)0x87654321, "%p", void *);
726 CHECKVAL(*ppv, NULL, "%p");
727}
728
729
730static void tstASMAtomicXchgPtr(void)
731{
732 DO_SIMPLE_TEST(ASMAtomicXchgPtr, void *);
733}
734
735
736DECLINLINE(void) tstASMAtomicCmpXchgU8Worker(uint8_t volatile *pu8)
737{
738 *pu8 = 0xff;
739
740 CHECKOP(ASMAtomicCmpXchgU8(pu8, 0, 0), false, "%d", bool);
741 CHECKVAL(*pu8, 0xff, "%x");
742
743 CHECKOP(ASMAtomicCmpXchgU8(pu8, 0, 0xff), true, "%d", bool);
744 CHECKVAL(*pu8, 0, "%x");
745
746 CHECKOP(ASMAtomicCmpXchgU8(pu8, 0x79, 0xff), false, "%d", bool);
747 CHECKVAL(*pu8, 0, "%x");
748
749 CHECKOP(ASMAtomicCmpXchgU8(pu8, 0x97, 0), true, "%d", bool);
750 CHECKVAL(*pu8, 0x97, "%x");
751}
752
753
754static void tstASMAtomicCmpXchgU8(void)
755{
756 DO_SIMPLE_TEST(ASMAtomicCmpXchgU8, uint8_t);
757}
758
759
760DECLINLINE(void) tstASMAtomicCmpXchgU32Worker(uint32_t volatile *pu32)
761{
762 *pu32 = UINT32_C(0xffffffff);
763
764 CHECKOP(ASMAtomicCmpXchgU32(pu32, 0, 0), false, "%d", bool);
765 CHECKVAL(*pu32, UINT32_C(0xffffffff), "%x");
766
767 CHECKOP(ASMAtomicCmpXchgU32(pu32, 0, UINT32_C(0xffffffff)), true, "%d", bool);
768 CHECKVAL(*pu32, 0, "%x");
769
770 CHECKOP(ASMAtomicCmpXchgU32(pu32, UINT32_C(0x8008efd), UINT32_C(0xffffffff)), false, "%d", bool);
771 CHECKVAL(*pu32, 0, "%x");
772
773 CHECKOP(ASMAtomicCmpXchgU32(pu32, UINT32_C(0x8008efd), 0), true, "%d", bool);
774 CHECKVAL(*pu32, UINT32_C(0x8008efd), "%x");
775}
776
777
778static void tstASMAtomicCmpXchgU32(void)
779{
780 DO_SIMPLE_TEST(ASMAtomicCmpXchgU32, uint32_t);
781}
782
783
784
785DECLINLINE(void) tstASMAtomicCmpXchgU64Worker(uint64_t volatile *pu64)
786{
787 *pu64 = UINT64_C(0xffffffffffffff);
788
789 CHECKOP(ASMAtomicCmpXchgU64(pu64, 0, 0), false, "%d", bool);
790 CHECKVAL(*pu64, UINT64_C(0xffffffffffffff), "%#llx");
791
792 CHECKOP(ASMAtomicCmpXchgU64(pu64, 0, UINT64_C(0xffffffffffffff)), true, "%d", bool);
793 CHECKVAL(*pu64, 0, "%x");
794
795 CHECKOP(ASMAtomicCmpXchgU64(pu64, UINT64_C(0x80040008008efd), UINT64_C(0xffffffff)), false, "%d", bool);
796 CHECKVAL(*pu64, 0, "%x");
797
798 CHECKOP(ASMAtomicCmpXchgU64(pu64, UINT64_C(0x80040008008efd), UINT64_C(0xffffffff00000000)), false, "%d", bool);
799 CHECKVAL(*pu64, 0, "%x");
800
801 CHECKOP(ASMAtomicCmpXchgU64(pu64, UINT64_C(0x80040008008efd), 0), true, "%d", bool);
802 CHECKVAL(*pu64, UINT64_C(0x80040008008efd), "%#llx");
803}
804
805
806static void tstASMAtomicCmpXchgU64(void)
807{
808 DO_SIMPLE_TEST(ASMAtomicCmpXchgU64, uint64_t);
809}
810
811
812DECLINLINE(void) tstASMAtomicCmpXchgExU32Worker(uint32_t volatile *pu32)
813{
814 *pu32 = UINT32_C(0xffffffff);
815 uint32_t u32Old = UINT32_C(0x80005111);
816
817 CHECKOP(ASMAtomicCmpXchgExU32(pu32, 0, 0, &u32Old), false, "%d", bool);
818 CHECKVAL(*pu32, UINT32_C(0xffffffff), "%x");
819 CHECKVAL(u32Old, UINT32_C(0xffffffff), "%x");
820
821 CHECKOP(ASMAtomicCmpXchgExU32(pu32, 0, UINT32_C(0xffffffff), &u32Old), true, "%d", bool);
822 CHECKVAL(*pu32, 0, "%x");
823 CHECKVAL(u32Old, UINT32_C(0xffffffff), "%x");
824
825 CHECKOP(ASMAtomicCmpXchgExU32(pu32, UINT32_C(0x8008efd), UINT32_C(0xffffffff), &u32Old), false, "%d", bool);
826 CHECKVAL(*pu32, 0, "%x");
827 CHECKVAL(u32Old, 0, "%x");
828
829 CHECKOP(ASMAtomicCmpXchgExU32(pu32, UINT32_C(0x8008efd), 0, &u32Old), true, "%d", bool);
830 CHECKVAL(*pu32, UINT32_C(0x8008efd), "%x");
831 CHECKVAL(u32Old, 0, "%x");
832
833 CHECKOP(ASMAtomicCmpXchgExU32(pu32, 0, UINT32_C(0x8008efd), &u32Old), true, "%d", bool);
834 CHECKVAL(*pu32, 0, "%x");
835 CHECKVAL(u32Old, UINT32_C(0x8008efd), "%x");
836}
837
838
839static void tstASMAtomicCmpXchgExU32(void)
840{
841 DO_SIMPLE_TEST(ASMAtomicCmpXchgExU32, uint32_t);
842}
843
844
845DECLINLINE(void) tstASMAtomicCmpXchgExU64Worker(uint64_t volatile *pu64)
846{
847 *pu64 = UINT64_C(0xffffffffffffffff);
848 uint64_t u64Old = UINT64_C(0x8000000051111111);
849
850 CHECKOP(ASMAtomicCmpXchgExU64(pu64, 0, 0, &u64Old), false, "%d", bool);
851 CHECKVAL(*pu64, UINT64_C(0xffffffffffffffff), "%llx");
852 CHECKVAL(u64Old, UINT64_C(0xffffffffffffffff), "%llx");
853
854 CHECKOP(ASMAtomicCmpXchgExU64(pu64, 0, UINT64_C(0xffffffffffffffff), &u64Old), true, "%d", bool);
855 CHECKVAL(*pu64, UINT64_C(0), "%llx");
856 CHECKVAL(u64Old, UINT64_C(0xffffffffffffffff), "%llx");
857
858 CHECKOP(ASMAtomicCmpXchgExU64(pu64, UINT64_C(0x80040008008efd), 0xffffffff, &u64Old), false, "%d", bool);
859 CHECKVAL(*pu64, UINT64_C(0), "%llx");
860 CHECKVAL(u64Old, UINT64_C(0), "%llx");
861
862 CHECKOP(ASMAtomicCmpXchgExU64(pu64, UINT64_C(0x80040008008efd), UINT64_C(0xffffffff00000000), &u64Old), false, "%d", bool);
863 CHECKVAL(*pu64, UINT64_C(0), "%llx");
864 CHECKVAL(u64Old, UINT64_C(0), "%llx");
865
866 CHECKOP(ASMAtomicCmpXchgExU64(pu64, UINT64_C(0x80040008008efd), 0, &u64Old), true, "%d", bool);
867 CHECKVAL(*pu64, UINT64_C(0x80040008008efd), "%llx");
868 CHECKVAL(u64Old, UINT64_C(0), "%llx");
869
870 CHECKOP(ASMAtomicCmpXchgExU64(pu64, 0, UINT64_C(0x80040008008efd), &u64Old), true, "%d", bool);
871 CHECKVAL(*pu64, UINT64_C(0), "%llx");
872 CHECKVAL(u64Old, UINT64_C(0x80040008008efd), "%llx");
873}
874
875
876static void tstASMAtomicCmpXchgExU64(void)
877{
878 DO_SIMPLE_TEST(ASMAtomicCmpXchgExU64, uint64_t);
879}
880
881
882DECLINLINE(void) tstASMAtomicReadU64Worker(uint64_t volatile *pu64)
883{
884 *pu64 = 0;
885
886 CHECKOP(ASMAtomicReadU64(pu64), UINT64_C(0), "%#llx", uint64_t);
887 CHECKVAL(*pu64, UINT64_C(0), "%#llx");
888
889 *pu64 = ~UINT64_C(0);
890 CHECKOP(ASMAtomicReadU64(pu64), ~UINT64_C(0), "%#llx", uint64_t);
891 CHECKVAL(*pu64, ~UINT64_C(0), "%#llx");
892
893 *pu64 = UINT64_C(0xfedcba0987654321);
894 CHECKOP(ASMAtomicReadU64(pu64), UINT64_C(0xfedcba0987654321), "%#llx", uint64_t);
895 CHECKVAL(*pu64, UINT64_C(0xfedcba0987654321), "%#llx");
896}
897
898
899static void tstASMAtomicReadU64(void)
900{
901 DO_SIMPLE_TEST(ASMAtomicReadU64, uint64_t);
902}
903
904
905DECLINLINE(void) tstASMAtomicUoReadU64Worker(uint64_t volatile *pu64)
906{
907 *pu64 = 0;
908
909 CHECKOP(ASMAtomicUoReadU64(pu64), UINT64_C(0), "%#llx", uint64_t);
910 CHECKVAL(*pu64, UINT64_C(0), "%#llx");
911
912 *pu64 = ~UINT64_C(0);
913 CHECKOP(ASMAtomicUoReadU64(pu64), ~UINT64_C(0), "%#llx", uint64_t);
914 CHECKVAL(*pu64, ~UINT64_C(0), "%#llx");
915
916 *pu64 = UINT64_C(0xfedcba0987654321);
917 CHECKOP(ASMAtomicUoReadU64(pu64), UINT64_C(0xfedcba0987654321), "%#llx", uint64_t);
918 CHECKVAL(*pu64, UINT64_C(0xfedcba0987654321), "%#llx");
919}
920
921
922static void tstASMAtomicUoReadU64(void)
923{
924 DO_SIMPLE_TEST(ASMAtomicUoReadU64, uint64_t);
925}
926
927
928DECLINLINE(void) tstASMAtomicAddS32Worker(int32_t *pi32)
929{
930 int32_t i32Rc;
931 *pi32 = 10;
932#define MYCHECK(op, rc, val) \
933 do { \
934 i32Rc = op; \
935 if (i32Rc != (rc)) \
936 RTTestFailed(g_hTest, "%s, %d: FAILURE: %s -> %d expected %d\n", __FUNCTION__, __LINE__, #op, i32Rc, rc); \
937 if (*pi32 != (val)) \
938 RTTestFailed(g_hTest, "%s, %d: FAILURE: %s => *pi32=%d expected %d\n", __FUNCTION__, __LINE__, #op, *pi32, val); \
939 } while (0)
940 MYCHECK(ASMAtomicAddS32(pi32, 1), 10, 11);
941 MYCHECK(ASMAtomicAddS32(pi32, -2), 11, 9);
942 MYCHECK(ASMAtomicAddS32(pi32, -9), 9, 0);
943 MYCHECK(ASMAtomicAddS32(pi32, -0x7fffffff), 0, -0x7fffffff);
944 MYCHECK(ASMAtomicAddS32(pi32, 0), -0x7fffffff, -0x7fffffff);
945 MYCHECK(ASMAtomicAddS32(pi32, 0x7fffffff), -0x7fffffff, 0);
946 MYCHECK(ASMAtomicAddS32(pi32, 0), 0, 0);
947#undef MYCHECK
948}
949
950
951static void tstASMAtomicAddS32(void)
952{
953 DO_SIMPLE_TEST(ASMAtomicAddS32, int32_t);
954}
955
956
957DECLINLINE(void) tstASMAtomicUoIncU32Worker(uint32_t volatile *pu32)
958{
959 *pu32 = 0;
960
961 CHECKOP(ASMAtomicUoIncU32(pu32), UINT32_C(1), "%#x", uint32_t);
962 CHECKVAL(*pu32, UINT32_C(1), "%#x");
963
964 *pu32 = ~UINT32_C(0);
965 CHECKOP(ASMAtomicUoIncU32(pu32), 0, "%#x", uint32_t);
966 CHECKVAL(*pu32, 0, "%#x");
967
968 *pu32 = UINT32_C(0x7fffffff);
969 CHECKOP(ASMAtomicUoIncU32(pu32), UINT32_C(0x80000000), "%#x", uint32_t);
970 CHECKVAL(*pu32, UINT32_C(0x80000000), "%#x");
971}
972
973
974static void tstASMAtomicUoIncU32(void)
975{
976 DO_SIMPLE_TEST(ASMAtomicUoIncU32, uint32_t);
977}
978
979
980DECLINLINE(void) tstASMAtomicUoDecU32Worker(uint32_t volatile *pu32)
981{
982 *pu32 = 0;
983
984 CHECKOP(ASMAtomicUoDecU32(pu32), ~UINT32_C(0), "%#x", uint32_t);
985 CHECKVAL(*pu32, ~UINT32_C(0), "%#x");
986
987 *pu32 = ~UINT32_C(0);
988 CHECKOP(ASMAtomicUoDecU32(pu32), UINT32_C(0xfffffffe), "%#x", uint32_t);
989 CHECKVAL(*pu32, UINT32_C(0xfffffffe), "%#x");
990
991 *pu32 = UINT32_C(0x80000000);
992 CHECKOP(ASMAtomicUoDecU32(pu32), UINT32_C(0x7fffffff), "%#x", uint32_t);
993 CHECKVAL(*pu32, UINT32_C(0x7fffffff), "%#x");
994}
995
996
997static void tstASMAtomicUoDecU32(void)
998{
999 DO_SIMPLE_TEST(ASMAtomicUoDecU32, uint32_t);
1000}
1001
1002
1003DECLINLINE(void) tstASMAtomicAddS64Worker(int64_t volatile *pi64)
1004{
1005 int64_t i64Rc;
1006 *pi64 = 10;
1007#define MYCHECK(op, rc, val) \
1008 do { \
1009 i64Rc = op; \
1010 if (i64Rc != (rc)) \
1011 RTTestFailed(g_hTest, "%s, %d: FAILURE: %s -> %llx expected %llx\n", __FUNCTION__, __LINE__, #op, i64Rc, (int64_t)rc); \
1012 if (*pi64 != (val)) \
1013 RTTestFailed(g_hTest, "%s, %d: FAILURE: %s => *pi64=%llx expected %llx\n", __FUNCTION__, __LINE__, #op, *pi64, (int64_t)(val)); \
1014 } while (0)
1015 MYCHECK(ASMAtomicAddS64(pi64, 1), 10, 11);
1016 MYCHECK(ASMAtomicAddS64(pi64, -2), 11, 9);
1017 MYCHECK(ASMAtomicAddS64(pi64, -9), 9, 0);
1018 MYCHECK(ASMAtomicAddS64(pi64, -INT64_MAX), 0, -INT64_MAX);
1019 MYCHECK(ASMAtomicAddS64(pi64, 0), -INT64_MAX, -INT64_MAX);
1020 MYCHECK(ASMAtomicAddS64(pi64, -1), -INT64_MAX, INT64_MIN);
1021 MYCHECK(ASMAtomicAddS64(pi64, INT64_MAX), INT64_MIN, -1);
1022 MYCHECK(ASMAtomicAddS64(pi64, 1), -1, 0);
1023 MYCHECK(ASMAtomicAddS64(pi64, 0), 0, 0);
1024#undef MYCHECK
1025}
1026
1027
1028static void tstASMAtomicAddS64(void)
1029{
1030 DO_SIMPLE_TEST(ASMAtomicAddS64, int64_t);
1031}
1032
1033
1034DECLINLINE(void) tstASMAtomicDecIncS32Worker(int32_t volatile *pi32)
1035{
1036 int32_t i32Rc;
1037 *pi32 = 10;
1038#define MYCHECK(op, rc) \
1039 do { \
1040 i32Rc = op; \
1041 if (i32Rc != (rc)) \
1042 RTTestFailed(g_hTest, "%s, %d: FAILURE: %s -> %d expected %d\n", __FUNCTION__, __LINE__, #op, i32Rc, rc); \
1043 if (*pi32 != (rc)) \
1044 RTTestFailed(g_hTest, "%s, %d: FAILURE: %s => *pi32=%d expected %d\n", __FUNCTION__, __LINE__, #op, *pi32, rc); \
1045 } while (0)
1046 MYCHECK(ASMAtomicDecS32(pi32), 9);
1047 MYCHECK(ASMAtomicDecS32(pi32), 8);
1048 MYCHECK(ASMAtomicDecS32(pi32), 7);
1049 MYCHECK(ASMAtomicDecS32(pi32), 6);
1050 MYCHECK(ASMAtomicDecS32(pi32), 5);
1051 MYCHECK(ASMAtomicDecS32(pi32), 4);
1052 MYCHECK(ASMAtomicDecS32(pi32), 3);
1053 MYCHECK(ASMAtomicDecS32(pi32), 2);
1054 MYCHECK(ASMAtomicDecS32(pi32), 1);
1055 MYCHECK(ASMAtomicDecS32(pi32), 0);
1056 MYCHECK(ASMAtomicDecS32(pi32), -1);
1057 MYCHECK(ASMAtomicDecS32(pi32), -2);
1058 MYCHECK(ASMAtomicIncS32(pi32), -1);
1059 MYCHECK(ASMAtomicIncS32(pi32), 0);
1060 MYCHECK(ASMAtomicIncS32(pi32), 1);
1061 MYCHECK(ASMAtomicIncS32(pi32), 2);
1062 MYCHECK(ASMAtomicIncS32(pi32), 3);
1063 MYCHECK(ASMAtomicDecS32(pi32), 2);
1064 MYCHECK(ASMAtomicIncS32(pi32), 3);
1065 MYCHECK(ASMAtomicDecS32(pi32), 2);
1066 MYCHECK(ASMAtomicIncS32(pi32), 3);
1067#undef MYCHECK
1068}
1069
1070
1071static void tstASMAtomicDecIncS32(void)
1072{
1073 DO_SIMPLE_TEST(ASMAtomicDecIncS32, int32_t);
1074}
1075
1076
1077DECLINLINE(void) tstASMAtomicDecIncS64Worker(int64_t volatile *pi64)
1078{
1079 int64_t i64Rc;
1080 *pi64 = 10;
1081#define MYCHECK(op, rc) \
1082 do { \
1083 i64Rc = op; \
1084 if (i64Rc != (rc)) \
1085 RTTestFailed(g_hTest, "%s, %d: FAILURE: %s -> %lld expected %lld\n", __FUNCTION__, __LINE__, #op, i64Rc, rc); \
1086 if (*pi64 != (rc)) \
1087 RTTestFailed(g_hTest, "%s, %d: FAILURE: %s => *pi64=%lld expected %lld\n", __FUNCTION__, __LINE__, #op, *pi64, rc); \
1088 } while (0)
1089 MYCHECK(ASMAtomicDecS64(pi64), 9);
1090 MYCHECK(ASMAtomicDecS64(pi64), 8);
1091 MYCHECK(ASMAtomicDecS64(pi64), 7);
1092 MYCHECK(ASMAtomicDecS64(pi64), 6);
1093 MYCHECK(ASMAtomicDecS64(pi64), 5);
1094 MYCHECK(ASMAtomicDecS64(pi64), 4);
1095 MYCHECK(ASMAtomicDecS64(pi64), 3);
1096 MYCHECK(ASMAtomicDecS64(pi64), 2);
1097 MYCHECK(ASMAtomicDecS64(pi64), 1);
1098 MYCHECK(ASMAtomicDecS64(pi64), 0);
1099 MYCHECK(ASMAtomicDecS64(pi64), -1);
1100 MYCHECK(ASMAtomicDecS64(pi64), -2);
1101 MYCHECK(ASMAtomicIncS64(pi64), -1);
1102 MYCHECK(ASMAtomicIncS64(pi64), 0);
1103 MYCHECK(ASMAtomicIncS64(pi64), 1);
1104 MYCHECK(ASMAtomicIncS64(pi64), 2);
1105 MYCHECK(ASMAtomicIncS64(pi64), 3);
1106 MYCHECK(ASMAtomicDecS64(pi64), 2);
1107 MYCHECK(ASMAtomicIncS64(pi64), 3);
1108 MYCHECK(ASMAtomicDecS64(pi64), 2);
1109 MYCHECK(ASMAtomicIncS64(pi64), 3);
1110#undef MYCHECK
1111}
1112
1113
1114static void tstASMAtomicDecIncS64(void)
1115{
1116 DO_SIMPLE_TEST(ASMAtomicDecIncS64, int64_t);
1117}
1118
1119
1120DECLINLINE(void) tstASMAtomicAndOrU32Worker(uint32_t volatile *pu32)
1121{
1122 *pu32 = UINT32_C(0xffffffff);
1123
1124 ASMAtomicOrU32(pu32, UINT32_C(0xffffffff));
1125 CHECKVAL(*pu32, UINT32_C(0xffffffff), "%x");
1126
1127 ASMAtomicAndU32(pu32, UINT32_C(0xffffffff));
1128 CHECKVAL(*pu32, UINT32_C(0xffffffff), "%x");
1129
1130 ASMAtomicAndU32(pu32, UINT32_C(0x8f8f8f8f));
1131 CHECKVAL(*pu32, UINT32_C(0x8f8f8f8f), "%x");
1132
1133 ASMAtomicOrU32(pu32, UINT32_C(0x70707070));
1134 CHECKVAL(*pu32, UINT32_C(0xffffffff), "%x");
1135
1136 ASMAtomicAndU32(pu32, UINT32_C(1));
1137 CHECKVAL(*pu32, UINT32_C(1), "%x");
1138
1139 ASMAtomicOrU32(pu32, UINT32_C(0x80000000));
1140 CHECKVAL(*pu32, UINT32_C(0x80000001), "%x");
1141
1142 ASMAtomicAndU32(pu32, UINT32_C(0x80000000));
1143 CHECKVAL(*pu32, UINT32_C(0x80000000), "%x");
1144
1145 ASMAtomicAndU32(pu32, UINT32_C(0));
1146 CHECKVAL(*pu32, UINT32_C(0), "%x");
1147
1148 ASMAtomicOrU32(pu32, UINT32_C(0x42424242));
1149 CHECKVAL(*pu32, UINT32_C(0x42424242), "%x");
1150}
1151
1152
1153static void tstASMAtomicAndOrU32(void)
1154{
1155 DO_SIMPLE_TEST(ASMAtomicAndOrU32, uint32_t);
1156}
1157
1158
1159DECLINLINE(void) tstASMAtomicAndOrU64Worker(uint64_t volatile *pu64)
1160{
1161 *pu64 = UINT64_C(0xffffffff);
1162
1163 ASMAtomicOrU64(pu64, UINT64_C(0xffffffff));
1164 CHECKVAL(*pu64, UINT64_C(0xffffffff), "%x");
1165
1166 ASMAtomicAndU64(pu64, UINT64_C(0xffffffff));
1167 CHECKVAL(*pu64, UINT64_C(0xffffffff), "%x");
1168
1169 ASMAtomicAndU64(pu64, UINT64_C(0x8f8f8f8f));
1170 CHECKVAL(*pu64, UINT64_C(0x8f8f8f8f), "%x");
1171
1172 ASMAtomicOrU64(pu64, UINT64_C(0x70707070));
1173 CHECKVAL(*pu64, UINT64_C(0xffffffff), "%x");
1174
1175 ASMAtomicAndU64(pu64, UINT64_C(1));
1176 CHECKVAL(*pu64, UINT64_C(1), "%x");
1177
1178 ASMAtomicOrU64(pu64, UINT64_C(0x80000000));
1179 CHECKVAL(*pu64, UINT64_C(0x80000001), "%x");
1180
1181 ASMAtomicAndU64(pu64, UINT64_C(0x80000000));
1182 CHECKVAL(*pu64, UINT64_C(0x80000000), "%x");
1183
1184 ASMAtomicAndU64(pu64, UINT64_C(0));
1185 CHECKVAL(*pu64, UINT64_C(0), "%x");
1186
1187 ASMAtomicOrU64(pu64, UINT64_C(0x42424242));
1188 CHECKVAL(*pu64, UINT64_C(0x42424242), "%x");
1189
1190 // Same as above, but now 64-bit wide.
1191 ASMAtomicAndU64(pu64, UINT64_C(0));
1192 CHECKVAL(*pu64, UINT64_C(0), "%x");
1193
1194 ASMAtomicOrU64(pu64, UINT64_C(0xffffffffffffffff));
1195 CHECKVAL(*pu64, UINT64_C(0xffffffffffffffff), "%x");
1196
1197 ASMAtomicAndU64(pu64, UINT64_C(0xffffffffffffffff));
1198 CHECKVAL(*pu64, UINT64_C(0xffffffffffffffff), "%x");
1199
1200 ASMAtomicAndU64(pu64, UINT64_C(0x8f8f8f8f8f8f8f8f));
1201 CHECKVAL(*pu64, UINT64_C(0x8f8f8f8f8f8f8f8f), "%x");
1202
1203 ASMAtomicOrU64(pu64, UINT64_C(0x7070707070707070));
1204 CHECKVAL(*pu64, UINT64_C(0xffffffffffffffff), "%x");
1205
1206 ASMAtomicAndU64(pu64, UINT64_C(1));
1207 CHECKVAL(*pu64, UINT64_C(1), "%x");
1208
1209 ASMAtomicOrU64(pu64, UINT64_C(0x8000000000000000));
1210 CHECKVAL(*pu64, UINT64_C(0x8000000000000001), "%x");
1211
1212 ASMAtomicAndU64(pu64, UINT64_C(0x8000000000000000));
1213 CHECKVAL(*pu64, UINT64_C(0x8000000000000000), "%x");
1214
1215 ASMAtomicAndU64(pu64, UINT64_C(0));
1216 CHECKVAL(*pu64, UINT64_C(0), "%x");
1217
1218 ASMAtomicOrU64(pu64, UINT64_C(0x4242424242424242));
1219 CHECKVAL(*pu64, UINT64_C(0x4242424242424242), "%x");
1220}
1221
1222
1223static void tstASMAtomicAndOrU64(void)
1224{
1225 DO_SIMPLE_TEST(ASMAtomicAndOrU64, uint64_t);
1226}
1227
1228
1229DECLINLINE(void) tstASMAtomicUoAndOrU32Worker(uint32_t volatile *pu32)
1230{
1231 *pu32 = UINT32_C(0xffffffff);
1232
1233 ASMAtomicUoOrU32(pu32, UINT32_C(0xffffffff));
1234 CHECKVAL(*pu32, UINT32_C(0xffffffff), "%#x");
1235
1236 ASMAtomicUoAndU32(pu32, UINT32_C(0xffffffff));
1237 CHECKVAL(*pu32, UINT32_C(0xffffffff), "%#x");
1238
1239 ASMAtomicUoAndU32(pu32, UINT32_C(0x8f8f8f8f));
1240 CHECKVAL(*pu32, UINT32_C(0x8f8f8f8f), "%#x");
1241
1242 ASMAtomicUoOrU32(pu32, UINT32_C(0x70707070));
1243 CHECKVAL(*pu32, UINT32_C(0xffffffff), "%#x");
1244
1245 ASMAtomicUoAndU32(pu32, UINT32_C(1));
1246 CHECKVAL(*pu32, UINT32_C(1), "%#x");
1247
1248 ASMAtomicUoOrU32(pu32, UINT32_C(0x80000000));
1249 CHECKVAL(*pu32, UINT32_C(0x80000001), "%#x");
1250
1251 ASMAtomicUoAndU32(pu32, UINT32_C(0x80000000));
1252 CHECKVAL(*pu32, UINT32_C(0x80000000), "%#x");
1253
1254 ASMAtomicUoAndU32(pu32, UINT32_C(0));
1255 CHECKVAL(*pu32, UINT32_C(0), "%#x");
1256
1257 ASMAtomicUoOrU32(pu32, UINT32_C(0x42424242));
1258 CHECKVAL(*pu32, UINT32_C(0x42424242), "%#x");
1259}
1260
1261
1262static void tstASMAtomicUoAndOrU32(void)
1263{
1264 DO_SIMPLE_TEST(ASMAtomicUoAndOrU32, uint32_t);
1265}
1266
1267
1268typedef struct
1269{
1270 uint8_t ab[PAGE_SIZE];
1271} TSTPAGE;
1272
1273
1274DECLINLINE(void) tstASMMemZeroPageWorker(TSTPAGE *pPage)
1275{
1276 for (unsigned j = 0; j < 16; j++)
1277 {
1278 memset(pPage, 0x11 * j, sizeof(*pPage));
1279 ASMMemZeroPage(pPage);
1280 for (unsigned i = 0; i < sizeof(pPage->ab); i++)
1281 if (pPage->ab[i])
1282 RTTestFailed(g_hTest, "ASMMemZeroPage didn't clear byte at offset %#x!\n", i);
1283 }
1284}
1285
1286
1287static void tstASMMemZeroPage(void)
1288{
1289 DO_SIMPLE_TEST(ASMMemZeroPage, TSTPAGE);
1290}
1291
1292
1293void tstASMMemIsZeroPage(RTTEST hTest)
1294{
1295 RTTestSub(hTest, "ASMMemIsZeroPage");
1296
1297 void *pvPage1 = RTTestGuardedAllocHead(hTest, PAGE_SIZE);
1298 void *pvPage2 = RTTestGuardedAllocTail(hTest, PAGE_SIZE);
1299 RTTESTI_CHECK_RETV(pvPage1 && pvPage2);
1300
1301 memset(pvPage1, 0, PAGE_SIZE);
1302 memset(pvPage2, 0, PAGE_SIZE);
1303 RTTESTI_CHECK(ASMMemIsZeroPage(pvPage1));
1304 RTTESTI_CHECK(ASMMemIsZeroPage(pvPage2));
1305
1306 memset(pvPage1, 0xff, PAGE_SIZE);
1307 memset(pvPage2, 0xff, PAGE_SIZE);
1308 RTTESTI_CHECK(!ASMMemIsZeroPage(pvPage1));
1309 RTTESTI_CHECK(!ASMMemIsZeroPage(pvPage2));
1310
1311 memset(pvPage1, 0, PAGE_SIZE);
1312 memset(pvPage2, 0, PAGE_SIZE);
1313 for (unsigned off = 0; off < PAGE_SIZE; off++)
1314 {
1315 ((uint8_t *)pvPage1)[off] = 1;
1316 RTTESTI_CHECK(!ASMMemIsZeroPage(pvPage1));
1317 ((uint8_t *)pvPage1)[off] = 0;
1318
1319 ((uint8_t *)pvPage2)[off] = 0x80;
1320 RTTESTI_CHECK(!ASMMemIsZeroPage(pvPage2));
1321 ((uint8_t *)pvPage2)[off] = 0;
1322 }
1323
1324 RTTestSubDone(hTest);
1325}
1326
1327
1328void tstASMMemZero32(void)
1329{
1330 RTTestSub(g_hTest, "ASMMemFill32");
1331
1332 struct
1333 {
1334 uint64_t u64Magic1;
1335 uint8_t abPage[PAGE_SIZE - 32];
1336 uint64_t u64Magic2;
1337 } Buf1, Buf2, Buf3;
1338
1339 Buf1.u64Magic1 = UINT64_C(0xffffffffffffffff);
1340 memset(Buf1.abPage, 0x55, sizeof(Buf1.abPage));
1341 Buf1.u64Magic2 = UINT64_C(0xffffffffffffffff);
1342 Buf2.u64Magic1 = UINT64_C(0xffffffffffffffff);
1343 memset(Buf2.abPage, 0x77, sizeof(Buf2.abPage));
1344 Buf2.u64Magic2 = UINT64_C(0xffffffffffffffff);
1345 Buf3.u64Magic1 = UINT64_C(0xffffffffffffffff);
1346 memset(Buf3.abPage, 0x99, sizeof(Buf3.abPage));
1347 Buf3.u64Magic2 = UINT64_C(0xffffffffffffffff);
1348 ASMMemZero32(Buf1.abPage, sizeof(Buf1.abPage));
1349 ASMMemZero32(Buf2.abPage, sizeof(Buf2.abPage));
1350 ASMMemZero32(Buf3.abPage, sizeof(Buf3.abPage));
1351 if ( Buf1.u64Magic1 != UINT64_C(0xffffffffffffffff)
1352 || Buf1.u64Magic2 != UINT64_C(0xffffffffffffffff)
1353 || Buf2.u64Magic1 != UINT64_C(0xffffffffffffffff)
1354 || Buf2.u64Magic2 != UINT64_C(0xffffffffffffffff)
1355 || Buf3.u64Magic1 != UINT64_C(0xffffffffffffffff)
1356 || Buf3.u64Magic2 != UINT64_C(0xffffffffffffffff))
1357 {
1358 RTTestFailed(g_hTest, "ASMMemZero32 violated one/both magic(s)!\n");
1359 }
1360 for (unsigned i = 0; i < RT_ELEMENTS(Buf1.abPage); i++)
1361 if (Buf1.abPage[i])
1362 RTTestFailed(g_hTest, "ASMMemZero32 didn't clear byte at offset %#x!\n", i);
1363 for (unsigned i = 0; i < RT_ELEMENTS(Buf2.abPage); i++)
1364 if (Buf2.abPage[i])
1365 RTTestFailed(g_hTest, "ASMMemZero32 didn't clear byte at offset %#x!\n", i);
1366 for (unsigned i = 0; i < RT_ELEMENTS(Buf3.abPage); i++)
1367 if (Buf3.abPage[i])
1368 RTTestFailed(g_hTest, "ASMMemZero32 didn't clear byte at offset %#x!\n", i);
1369}
1370
1371
1372void tstASMMemFill32(void)
1373{
1374 RTTestSub(g_hTest, "ASMMemFill32");
1375
1376 struct
1377 {
1378 uint64_t u64Magic1;
1379 uint32_t au32Page[PAGE_SIZE / 4];
1380 uint64_t u64Magic2;
1381 } Buf1;
1382 struct
1383 {
1384 uint64_t u64Magic1;
1385 uint32_t au32Page[(PAGE_SIZE / 4) - 3];
1386 uint64_t u64Magic2;
1387 } Buf2;
1388 struct
1389 {
1390 uint64_t u64Magic1;
1391 uint32_t au32Page[(PAGE_SIZE / 4) - 1];
1392 uint64_t u64Magic2;
1393 } Buf3;
1394
1395 Buf1.u64Magic1 = UINT64_C(0xffffffffffffffff);
1396 memset(Buf1.au32Page, 0x55, sizeof(Buf1.au32Page));
1397 Buf1.u64Magic2 = UINT64_C(0xffffffffffffffff);
1398 Buf2.u64Magic1 = UINT64_C(0xffffffffffffffff);
1399 memset(Buf2.au32Page, 0x77, sizeof(Buf2.au32Page));
1400 Buf2.u64Magic2 = UINT64_C(0xffffffffffffffff);
1401 Buf3.u64Magic1 = UINT64_C(0xffffffffffffffff);
1402 memset(Buf3.au32Page, 0x99, sizeof(Buf3.au32Page));
1403 Buf3.u64Magic2 = UINT64_C(0xffffffffffffffff);
1404 ASMMemFill32(Buf1.au32Page, sizeof(Buf1.au32Page), 0xdeadbeef);
1405 ASMMemFill32(Buf2.au32Page, sizeof(Buf2.au32Page), 0xcafeff01);
1406 ASMMemFill32(Buf3.au32Page, sizeof(Buf3.au32Page), 0xf00dd00f);
1407 if ( Buf1.u64Magic1 != UINT64_C(0xffffffffffffffff)
1408 || Buf1.u64Magic2 != UINT64_C(0xffffffffffffffff)
1409 || Buf2.u64Magic1 != UINT64_C(0xffffffffffffffff)
1410 || Buf2.u64Magic2 != UINT64_C(0xffffffffffffffff)
1411 || Buf3.u64Magic1 != UINT64_C(0xffffffffffffffff)
1412 || Buf3.u64Magic2 != UINT64_C(0xffffffffffffffff))
1413 RTTestFailed(g_hTest, "ASMMemFill32 violated one/both magic(s)!\n");
1414 for (unsigned i = 0; i < RT_ELEMENTS(Buf1.au32Page); i++)
1415 if (Buf1.au32Page[i] != 0xdeadbeef)
1416 RTTestFailed(g_hTest, "ASMMemFill32 %#x: %#x exepcted %#x\n", i, Buf1.au32Page[i], 0xdeadbeef);
1417 for (unsigned i = 0; i < RT_ELEMENTS(Buf2.au32Page); i++)
1418 if (Buf2.au32Page[i] != 0xcafeff01)
1419 RTTestFailed(g_hTest, "ASMMemFill32 %#x: %#x exepcted %#x\n", i, Buf2.au32Page[i], 0xcafeff01);
1420 for (unsigned i = 0; i < RT_ELEMENTS(Buf3.au32Page); i++)
1421 if (Buf3.au32Page[i] != 0xf00dd00f)
1422 RTTestFailed(g_hTest, "ASMMemFill32 %#x: %#x exepcted %#x\n", i, Buf3.au32Page[i], 0xf00dd00f);
1423}
1424
1425
1426
1427void tstASMMath(void)
1428{
1429 RTTestSub(g_hTest, "Math");
1430
1431 uint64_t u64 = ASMMult2xU32RetU64(UINT32_C(0x80000000), UINT32_C(0x10000000));
1432 CHECKVAL(u64, UINT64_C(0x0800000000000000), "%#018RX64");
1433
1434 uint32_t u32 = ASMDivU64ByU32RetU32(UINT64_C(0x0800000000000000), UINT32_C(0x10000000));
1435 CHECKVAL(u32, UINT32_C(0x80000000), "%#010RX32");
1436
1437 u32 = ASMMultU32ByU32DivByU32(UINT32_C(0x00000001), UINT32_C(0x00000001), UINT32_C(0x00000001));
1438 CHECKVAL(u32, UINT32_C(0x00000001), "%#018RX32");
1439 u32 = ASMMultU32ByU32DivByU32(UINT32_C(0x10000000), UINT32_C(0x80000000), UINT32_C(0x20000000));
1440 CHECKVAL(u32, UINT32_C(0x40000000), "%#018RX32");
1441 u32 = ASMMultU32ByU32DivByU32(UINT32_C(0x76543210), UINT32_C(0xffffffff), UINT32_C(0xffffffff));
1442 CHECKVAL(u32, UINT32_C(0x76543210), "%#018RX32");
1443 u32 = ASMMultU32ByU32DivByU32(UINT32_C(0xffffffff), UINT32_C(0xffffffff), UINT32_C(0xffffffff));
1444 CHECKVAL(u32, UINT32_C(0xffffffff), "%#018RX32");
1445 u32 = ASMMultU32ByU32DivByU32(UINT32_C(0xffffffff), UINT32_C(0xfffffff0), UINT32_C(0xffffffff));
1446 CHECKVAL(u32, UINT32_C(0xfffffff0), "%#018RX32");
1447 u32 = ASMMultU32ByU32DivByU32(UINT32_C(0x10359583), UINT32_C(0x58734981), UINT32_C(0xf8694045));
1448 CHECKVAL(u32, UINT32_C(0x05c584ce), "%#018RX32");
1449 u32 = ASMMultU32ByU32DivByU32(UINT32_C(0x10359583), UINT32_C(0xf8694045), UINT32_C(0x58734981));
1450 CHECKVAL(u32, UINT32_C(0x2d860795), "%#018RX32");
1451
1452#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
1453 u64 = ASMMultU64ByU32DivByU32(UINT64_C(0x0000000000000001), UINT32_C(0x00000001), UINT32_C(0x00000001));
1454 CHECKVAL(u64, UINT64_C(0x0000000000000001), "%#018RX64");
1455 u64 = ASMMultU64ByU32DivByU32(UINT64_C(0x0000000100000000), UINT32_C(0x80000000), UINT32_C(0x00000002));
1456 CHECKVAL(u64, UINT64_C(0x4000000000000000), "%#018RX64");
1457 u64 = ASMMultU64ByU32DivByU32(UINT64_C(0xfedcba9876543210), UINT32_C(0xffffffff), UINT32_C(0xffffffff));
1458 CHECKVAL(u64, UINT64_C(0xfedcba9876543210), "%#018RX64");
1459 u64 = ASMMultU64ByU32DivByU32(UINT64_C(0xffffffffffffffff), UINT32_C(0xffffffff), UINT32_C(0xffffffff));
1460 CHECKVAL(u64, UINT64_C(0xffffffffffffffff), "%#018RX64");
1461 u64 = ASMMultU64ByU32DivByU32(UINT64_C(0xffffffffffffffff), UINT32_C(0xfffffff0), UINT32_C(0xffffffff));
1462 CHECKVAL(u64, UINT64_C(0xfffffff0fffffff0), "%#018RX64");
1463 u64 = ASMMultU64ByU32DivByU32(UINT64_C(0x3415934810359583), UINT32_C(0x58734981), UINT32_C(0xf8694045));
1464 CHECKVAL(u64, UINT64_C(0x128b9c3d43184763), "%#018RX64");
1465 u64 = ASMMultU64ByU32DivByU32(UINT64_C(0x3415934810359583), UINT32_C(0xf8694045), UINT32_C(0x58734981));
1466 CHECKVAL(u64, UINT64_C(0x924719355cd35a27), "%#018RX64");
1467
1468# if 0 /* bird: question is whether this should trap or not:
1469 *
1470 * frank: Of course it must trap:
1471 *
1472 * 0xfffffff8 * 0x77d7daf8 = 0x77d7daf441412840
1473 *
1474 * During the following division, the quotient must fit into a 32-bit register.
1475 * Therefore the smallest valid divisor is
1476 *
1477 * (0x77d7daf441412840 >> 32) + 1 = 0x77d7daf5
1478 *
1479 * which is definitely greater than 0x3b9aca00.
1480 *
1481 * bird: No, the C version does *not* crash. So, the question is whether there's any
1482 * code depending on it not crashing.
1483 *
1484 * Of course the assembly versions of the code crash right now for the reasons you've
1485 * given, but the 32-bit MSC version does not crash.
1486 *
1487 * frank: The C version does not crash but delivers incorrect results for this case.
1488 * The reason is
1489 *
1490 * u.s.Hi = (unsigned long)(u64Hi / u32C);
1491 *
1492 * Here the division is actually 64-bit by 64-bit but the 64-bit result is truncated
1493 * to 32 bit. If using this (optimized and fast) function we should just be sure that
1494 * the operands are in a valid range.
1495 */
1496 u64 = ASMMultU64ByU32DivByU32(UINT64_C(0xfffffff8c65d6731), UINT32_C(0x77d7daf8), UINT32_C(0x3b9aca00));
1497 CHECKVAL(u64, UINT64_C(0x02b8f9a2aa74e3dc), "%#018RX64");
1498# endif
1499#endif /* AMD64 || X86 */
1500
1501 u32 = ASMModU64ByU32RetU32(UINT64_C(0x0ffffff8c65d6731), UINT32_C(0x77d7daf8));
1502 CHECKVAL(u32, UINT32_C(0x3B642451), "%#010RX32");
1503
1504 int32_t i32;
1505 i32 = ASMModS64ByS32RetS32(INT64_C(-11), INT32_C(-2));
1506 CHECKVAL(i32, INT32_C(-1), "%010RI32");
1507 i32 = ASMModS64ByS32RetS32(INT64_C(-11), INT32_C(2));
1508 CHECKVAL(i32, INT32_C(-1), "%010RI32");
1509 i32 = ASMModS64ByS32RetS32(INT64_C(11), INT32_C(-2));
1510 CHECKVAL(i32, INT32_C(1), "%010RI32");
1511
1512 i32 = ASMModS64ByS32RetS32(INT64_C(92233720368547758), INT32_C(2147483647));
1513 CHECKVAL(i32, INT32_C(2104533974), "%010RI32");
1514 i32 = ASMModS64ByS32RetS32(INT64_C(-92233720368547758), INT32_C(2147483647));
1515 CHECKVAL(i32, INT32_C(-2104533974), "%010RI32");
1516}
1517
1518
1519void tstASMByteSwap(void)
1520{
1521 RTTestSub(g_hTest, "ASMByteSwap*");
1522
1523 uint64_t u64In = UINT64_C(0x0011223344556677);
1524 uint64_t u64Out = ASMByteSwapU64(u64In);
1525 CHECKVAL(u64In, UINT64_C(0x0011223344556677), "%#018RX64");
1526 CHECKVAL(u64Out, UINT64_C(0x7766554433221100), "%#018RX64");
1527 u64Out = ASMByteSwapU64(u64Out);
1528 CHECKVAL(u64Out, u64In, "%#018RX64");
1529 u64In = UINT64_C(0x0123456789abcdef);
1530 u64Out = ASMByteSwapU64(u64In);
1531 CHECKVAL(u64In, UINT64_C(0x0123456789abcdef), "%#018RX64");
1532 CHECKVAL(u64Out, UINT64_C(0xefcdab8967452301), "%#018RX64");
1533 u64Out = ASMByteSwapU64(u64Out);
1534 CHECKVAL(u64Out, u64In, "%#018RX64");
1535 u64In = 0;
1536 u64Out = ASMByteSwapU64(u64In);
1537 CHECKVAL(u64Out, u64In, "%#018RX64");
1538 u64In = ~(uint64_t)0;
1539 u64Out = ASMByteSwapU64(u64In);
1540 CHECKVAL(u64Out, u64In, "%#018RX64");
1541
1542 uint32_t u32In = UINT32_C(0x00112233);
1543 uint32_t u32Out = ASMByteSwapU32(u32In);
1544 CHECKVAL(u32In, UINT32_C(0x00112233), "%#010RX32");
1545 CHECKVAL(u32Out, UINT32_C(0x33221100), "%#010RX32");
1546 u32Out = ASMByteSwapU32(u32Out);
1547 CHECKVAL(u32Out, u32In, "%#010RX32");
1548 u32In = UINT32_C(0x12345678);
1549 u32Out = ASMByteSwapU32(u32In);
1550 CHECKVAL(u32In, UINT32_C(0x12345678), "%#010RX32");
1551 CHECKVAL(u32Out, UINT32_C(0x78563412), "%#010RX32");
1552 u32Out = ASMByteSwapU32(u32Out);
1553 CHECKVAL(u32Out, u32In, "%#010RX32");
1554 u32In = 0;
1555 u32Out = ASMByteSwapU32(u32In);
1556 CHECKVAL(u32Out, u32In, "%#010RX32");
1557 u32In = ~(uint32_t)0;
1558 u32Out = ASMByteSwapU32(u32In);
1559 CHECKVAL(u32Out, u32In, "%#010RX32");
1560
1561 uint16_t u16In = UINT16_C(0x0011);
1562 uint16_t u16Out = ASMByteSwapU16(u16In);
1563 CHECKVAL(u16In, UINT16_C(0x0011), "%#06RX16");
1564 CHECKVAL(u16Out, UINT16_C(0x1100), "%#06RX16");
1565 u16Out = ASMByteSwapU16(u16Out);
1566 CHECKVAL(u16Out, u16In, "%#06RX16");
1567 u16In = UINT16_C(0x1234);
1568 u16Out = ASMByteSwapU16(u16In);
1569 CHECKVAL(u16In, UINT16_C(0x1234), "%#06RX16");
1570 CHECKVAL(u16Out, UINT16_C(0x3412), "%#06RX16");
1571 u16Out = ASMByteSwapU16(u16Out);
1572 CHECKVAL(u16Out, u16In, "%#06RX16");
1573 u16In = 0;
1574 u16Out = ASMByteSwapU16(u16In);
1575 CHECKVAL(u16Out, u16In, "%#06RX16");
1576 u16In = ~(uint16_t)0;
1577 u16Out = ASMByteSwapU16(u16In);
1578 CHECKVAL(u16Out, u16In, "%#06RX16");
1579}
1580
1581
1582void tstASMBench(void)
1583{
1584 /*
1585 * Make this static. We don't want to have this located on the stack.
1586 */
1587 static uint8_t volatile s_u8;
1588 static int8_t volatile s_i8;
1589 static uint16_t volatile s_u16;
1590 static int16_t volatile s_i16;
1591 static uint32_t volatile s_u32;
1592 static int32_t volatile s_i32;
1593 static uint64_t volatile s_u64;
1594 static int64_t volatile s_i64;
1595 register unsigned i;
1596 const unsigned cRounds = _2M;
1597 register uint64_t u64Elapsed;
1598
1599 RTTestSub(g_hTest, "Benchmarking");
1600
1601#if 0 && !defined(GCC44_32BIT_PIC) && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86))
1602# define BENCH(op, str) \
1603 do { \
1604 RTThreadYield(); \
1605 u64Elapsed = ASMReadTSC(); \
1606 for (i = cRounds; i > 0; i--) \
1607 op; \
1608 u64Elapsed = ASMReadTSC() - u64Elapsed; \
1609 RTTestValue(g_hTest, str, u64Elapsed / cRounds, RTTESTUNIT_TICKS_PER_CALL); \
1610 } while (0)
1611#else
1612# define BENCH(op, str) \
1613 do { \
1614 RTThreadYield(); \
1615 u64Elapsed = RTTimeNanoTS(); \
1616 for (i = cRounds; i > 0; i--) \
1617 op; \
1618 u64Elapsed = RTTimeNanoTS() - u64Elapsed; \
1619 RTTestValue(g_hTest, str, u64Elapsed / cRounds, RTTESTUNIT_NS_PER_CALL); \
1620 } while (0)
1621#endif
1622
1623 BENCH(s_u32 = 0, "s_u32 = 0");
1624 BENCH(ASMAtomicUoReadU8(&s_u8), "ASMAtomicUoReadU8");
1625 BENCH(ASMAtomicUoReadS8(&s_i8), "ASMAtomicUoReadS8");
1626 BENCH(ASMAtomicUoReadU16(&s_u16), "ASMAtomicUoReadU16");
1627 BENCH(ASMAtomicUoReadS16(&s_i16), "ASMAtomicUoReadS16");
1628 BENCH(ASMAtomicUoReadU32(&s_u32), "ASMAtomicUoReadU32");
1629 BENCH(ASMAtomicUoReadS32(&s_i32), "ASMAtomicUoReadS32");
1630 BENCH(ASMAtomicUoReadU64(&s_u64), "ASMAtomicUoReadU64");
1631 BENCH(ASMAtomicUoReadS64(&s_i64), "ASMAtomicUoReadS64");
1632 BENCH(ASMAtomicReadU8(&s_u8), "ASMAtomicReadU8");
1633 BENCH(ASMAtomicReadS8(&s_i8), "ASMAtomicReadS8");
1634 BENCH(ASMAtomicReadU16(&s_u16), "ASMAtomicReadU16");
1635 BENCH(ASMAtomicReadS16(&s_i16), "ASMAtomicReadS16");
1636 BENCH(ASMAtomicReadU32(&s_u32), "ASMAtomicReadU32");
1637 BENCH(ASMAtomicReadS32(&s_i32), "ASMAtomicReadS32");
1638 BENCH(ASMAtomicReadU64(&s_u64), "ASMAtomicReadU64");
1639 BENCH(ASMAtomicReadS64(&s_i64), "ASMAtomicReadS64");
1640 BENCH(ASMAtomicUoWriteU8(&s_u8, 0), "ASMAtomicUoWriteU8");
1641 BENCH(ASMAtomicUoWriteS8(&s_i8, 0), "ASMAtomicUoWriteS8");
1642 BENCH(ASMAtomicUoWriteU16(&s_u16, 0), "ASMAtomicUoWriteU16");
1643 BENCH(ASMAtomicUoWriteS16(&s_i16, 0), "ASMAtomicUoWriteS16");
1644 BENCH(ASMAtomicUoWriteU32(&s_u32, 0), "ASMAtomicUoWriteU32");
1645 BENCH(ASMAtomicUoWriteS32(&s_i32, 0), "ASMAtomicUoWriteS32");
1646 BENCH(ASMAtomicUoWriteU64(&s_u64, 0), "ASMAtomicUoWriteU64");
1647 BENCH(ASMAtomicUoWriteS64(&s_i64, 0), "ASMAtomicUoWriteS64");
1648 BENCH(ASMAtomicWriteU8(&s_u8, 0), "ASMAtomicWriteU8");
1649 BENCH(ASMAtomicWriteS8(&s_i8, 0), "ASMAtomicWriteS8");
1650 BENCH(ASMAtomicWriteU16(&s_u16, 0), "ASMAtomicWriteU16");
1651 BENCH(ASMAtomicWriteS16(&s_i16, 0), "ASMAtomicWriteS16");
1652 BENCH(ASMAtomicWriteU32(&s_u32, 0), "ASMAtomicWriteU32");
1653 BENCH(ASMAtomicWriteS32(&s_i32, 0), "ASMAtomicWriteS32");
1654 BENCH(ASMAtomicWriteU64(&s_u64, 0), "ASMAtomicWriteU64");
1655 BENCH(ASMAtomicWriteS64(&s_i64, 0), "ASMAtomicWriteS64");
1656 BENCH(ASMAtomicXchgU8(&s_u8, 0), "ASMAtomicXchgU8");
1657 BENCH(ASMAtomicXchgS8(&s_i8, 0), "ASMAtomicXchgS8");
1658 BENCH(ASMAtomicXchgU16(&s_u16, 0), "ASMAtomicXchgU16");
1659 BENCH(ASMAtomicXchgS16(&s_i16, 0), "ASMAtomicXchgS16");
1660 BENCH(ASMAtomicXchgU32(&s_u32, 0), "ASMAtomicXchgU32");
1661 BENCH(ASMAtomicXchgS32(&s_i32, 0), "ASMAtomicXchgS32");
1662 BENCH(ASMAtomicXchgU64(&s_u64, 0), "ASMAtomicXchgU64");
1663 BENCH(ASMAtomicXchgS64(&s_i64, 0), "ASMAtomicXchgS64");
1664 BENCH(ASMAtomicCmpXchgU32(&s_u32, 0, 0), "ASMAtomicCmpXchgU32");
1665 BENCH(ASMAtomicCmpXchgS32(&s_i32, 0, 0), "ASMAtomicCmpXchgS32");
1666 BENCH(ASMAtomicCmpXchgU64(&s_u64, 0, 0), "ASMAtomicCmpXchgU64");
1667 BENCH(ASMAtomicCmpXchgS64(&s_i64, 0, 0), "ASMAtomicCmpXchgS64");
1668 BENCH(ASMAtomicCmpXchgU32(&s_u32, 0, 1), "ASMAtomicCmpXchgU32/neg");
1669 BENCH(ASMAtomicCmpXchgS32(&s_i32, 0, 1), "ASMAtomicCmpXchgS32/neg");
1670 BENCH(ASMAtomicCmpXchgU64(&s_u64, 0, 1), "ASMAtomicCmpXchgU64/neg");
1671 BENCH(ASMAtomicCmpXchgS64(&s_i64, 0, 1), "ASMAtomicCmpXchgS64/neg");
1672 BENCH(ASMAtomicIncU32(&s_u32), "ASMAtomicIncU32");
1673 BENCH(ASMAtomicIncS32(&s_i32), "ASMAtomicIncS32");
1674 BENCH(ASMAtomicDecU32(&s_u32), "ASMAtomicDecU32");
1675 BENCH(ASMAtomicDecS32(&s_i32), "ASMAtomicDecS32");
1676 BENCH(ASMAtomicAddU32(&s_u32, 5), "ASMAtomicAddU32");
1677 BENCH(ASMAtomicAddS32(&s_i32, 5), "ASMAtomicAddS32");
1678 BENCH(ASMAtomicUoIncU32(&s_u32), "ASMAtomicUoIncU32");
1679 BENCH(ASMAtomicUoDecU32(&s_u32), "ASMAtomicUoDecU32");
1680 BENCH(ASMAtomicUoAndU32(&s_u32, 0xffffffff), "ASMAtomicUoAndU32");
1681 BENCH(ASMAtomicUoOrU32(&s_u32, 0xffffffff), "ASMAtomicUoOrU32");
1682
1683 /* The Darwin gcc does not like this ... */
1684#if !defined(RT_OS_DARWIN) && !defined(GCC44_32BIT_PIC) && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86))
1685 BENCH(s_u8 = ASMGetApicId(), "ASMGetApicId");
1686#endif
1687
1688#undef BENCH
1689}
1690
1691
1692int main(int argc, char *argv[])
1693{
1694 int rc = RTTestInitAndCreate("tstRTInlineAsm", &g_hTest);
1695 if (rc)
1696 return rc;
1697 RTTestBanner(g_hTest);
1698
1699 /*
1700 * Execute the tests.
1701 */
1702#if !defined(GCC44_32BIT_PIC) && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86))
1703 tstASMCpuId();
1704 //bruteForceCpuId();
1705#endif
1706#if 1
1707 tstASMAtomicXchgU8();
1708 tstASMAtomicXchgU16();
1709 tstASMAtomicXchgU32();
1710 tstASMAtomicXchgU64();
1711 tstASMAtomicXchgPtr();
1712 tstASMAtomicCmpXchgU8();
1713 tstASMAtomicCmpXchgU32();
1714 tstASMAtomicCmpXchgU64();
1715 tstASMAtomicCmpXchgExU32();
1716 tstASMAtomicCmpXchgExU64();
1717 tstASMAtomicReadU64();
1718 tstASMAtomicUoReadU64();
1719
1720 tstASMAtomicAddS32();
1721 tstASMAtomicAddS64();
1722 tstASMAtomicDecIncS32();
1723 tstASMAtomicDecIncS64();
1724 tstASMAtomicAndOrU32();
1725 tstASMAtomicAndOrU64();
1726
1727 tstASMAtomicUoIncU32();
1728 tstASMAtomicUoDecU32();
1729 tstASMAtomicUoAndOrU32();
1730
1731 tstASMMemZeroPage();
1732 tstASMMemIsZeroPage(g_hTest);
1733 tstASMMemZero32();
1734 tstASMMemFill32();
1735
1736 tstASMMath();
1737
1738 tstASMByteSwap();
1739
1740 tstASMBench();
1741#endif
1742
1743 /*
1744 * Show the result.
1745 */
1746 return RTTestSummaryAndDestroy(g_hTest);
1747}
1748
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