8 typedef unsigned int UInt
;
9 typedef unsigned char UChar
;
10 typedef unsigned long long int ULong
;
11 typedef signed long long int Long
;
12 typedef signed int Int
;
13 typedef unsigned short UShort
;
14 typedef unsigned long UWord
;
17 unsigned myrandom(void)
19 /* Simple multiply-with-carry random generator. */
20 static unsigned m_w
= 11;
21 static unsigned m_z
= 13;
23 m_z
= 36969 * (m_z
& 65535) + (m_z
>> 16);
24 m_w
= 18000 * (m_w
& 65535) + (m_w
>> 16);
26 return (m_z
<< 16) + m_w
;
29 /////////////////////////////////////////////////////////////////
30 // BEGIN crc32 stuff //
31 /////////////////////////////////////////////////////////////////
33 static const UInt crc32Table
[256] = {
35 /*-- Ugly, innit? --*/
37 0x00000000L
, 0x04c11db7L
, 0x09823b6eL
, 0x0d4326d9L
,
38 0x130476dcL
, 0x17c56b6bL
, 0x1a864db2L
, 0x1e475005L
,
39 0x2608edb8L
, 0x22c9f00fL
, 0x2f8ad6d6L
, 0x2b4bcb61L
,
40 0x350c9b64L
, 0x31cd86d3L
, 0x3c8ea00aL
, 0x384fbdbdL
,
41 0x4c11db70L
, 0x48d0c6c7L
, 0x4593e01eL
, 0x4152fda9L
,
42 0x5f15adacL
, 0x5bd4b01bL
, 0x569796c2L
, 0x52568b75L
,
43 0x6a1936c8L
, 0x6ed82b7fL
, 0x639b0da6L
, 0x675a1011L
,
44 0x791d4014L
, 0x7ddc5da3L
, 0x709f7b7aL
, 0x745e66cdL
,
45 0x9823b6e0L
, 0x9ce2ab57L
, 0x91a18d8eL
, 0x95609039L
,
46 0x8b27c03cL
, 0x8fe6dd8bL
, 0x82a5fb52L
, 0x8664e6e5L
,
47 0xbe2b5b58L
, 0xbaea46efL
, 0xb7a96036L
, 0xb3687d81L
,
48 0xad2f2d84L
, 0xa9ee3033L
, 0xa4ad16eaL
, 0xa06c0b5dL
,
49 0xd4326d90L
, 0xd0f37027L
, 0xddb056feL
, 0xd9714b49L
,
50 0xc7361b4cL
, 0xc3f706fbL
, 0xceb42022L
, 0xca753d95L
,
51 0xf23a8028L
, 0xf6fb9d9fL
, 0xfbb8bb46L
, 0xff79a6f1L
,
52 0xe13ef6f4L
, 0xe5ffeb43L
, 0xe8bccd9aL
, 0xec7dd02dL
,
53 0x34867077L
, 0x30476dc0L
, 0x3d044b19L
, 0x39c556aeL
,
54 0x278206abL
, 0x23431b1cL
, 0x2e003dc5L
, 0x2ac12072L
,
55 0x128e9dcfL
, 0x164f8078L
, 0x1b0ca6a1L
, 0x1fcdbb16L
,
56 0x018aeb13L
, 0x054bf6a4L
, 0x0808d07dL
, 0x0cc9cdcaL
,
57 0x7897ab07L
, 0x7c56b6b0L
, 0x71159069L
, 0x75d48ddeL
,
58 0x6b93dddbL
, 0x6f52c06cL
, 0x6211e6b5L
, 0x66d0fb02L
,
59 0x5e9f46bfL
, 0x5a5e5b08L
, 0x571d7dd1L
, 0x53dc6066L
,
60 0x4d9b3063L
, 0x495a2dd4L
, 0x44190b0dL
, 0x40d816baL
,
61 0xaca5c697L
, 0xa864db20L
, 0xa527fdf9L
, 0xa1e6e04eL
,
62 0xbfa1b04bL
, 0xbb60adfcL
, 0xb6238b25L
, 0xb2e29692L
,
63 0x8aad2b2fL
, 0x8e6c3698L
, 0x832f1041L
, 0x87ee0df6L
,
64 0x99a95df3L
, 0x9d684044L
, 0x902b669dL
, 0x94ea7b2aL
,
65 0xe0b41de7L
, 0xe4750050L
, 0xe9362689L
, 0xedf73b3eL
,
66 0xf3b06b3bL
, 0xf771768cL
, 0xfa325055L
, 0xfef34de2L
,
67 0xc6bcf05fL
, 0xc27dede8L
, 0xcf3ecb31L
, 0xcbffd686L
,
68 0xd5b88683L
, 0xd1799b34L
, 0xdc3abdedL
, 0xd8fba05aL
,
69 0x690ce0eeL
, 0x6dcdfd59L
, 0x608edb80L
, 0x644fc637L
,
70 0x7a089632L
, 0x7ec98b85L
, 0x738aad5cL
, 0x774bb0ebL
,
71 0x4f040d56L
, 0x4bc510e1L
, 0x46863638L
, 0x42472b8fL
,
72 0x5c007b8aL
, 0x58c1663dL
, 0x558240e4L
, 0x51435d53L
,
73 0x251d3b9eL
, 0x21dc2629L
, 0x2c9f00f0L
, 0x285e1d47L
,
74 0x36194d42L
, 0x32d850f5L
, 0x3f9b762cL
, 0x3b5a6b9bL
,
75 0x0315d626L
, 0x07d4cb91L
, 0x0a97ed48L
, 0x0e56f0ffL
,
76 0x1011a0faL
, 0x14d0bd4dL
, 0x19939b94L
, 0x1d528623L
,
77 0xf12f560eL
, 0xf5ee4bb9L
, 0xf8ad6d60L
, 0xfc6c70d7L
,
78 0xe22b20d2L
, 0xe6ea3d65L
, 0xeba91bbcL
, 0xef68060bL
,
79 0xd727bbb6L
, 0xd3e6a601L
, 0xdea580d8L
, 0xda649d6fL
,
80 0xc423cd6aL
, 0xc0e2d0ddL
, 0xcda1f604L
, 0xc960ebb3L
,
81 0xbd3e8d7eL
, 0xb9ff90c9L
, 0xb4bcb610L
, 0xb07daba7L
,
82 0xae3afba2L
, 0xaafbe615L
, 0xa7b8c0ccL
, 0xa379dd7bL
,
83 0x9b3660c6L
, 0x9ff77d71L
, 0x92b45ba8L
, 0x9675461fL
,
84 0x8832161aL
, 0x8cf30badL
, 0x81b02d74L
, 0x857130c3L
,
85 0x5d8a9099L
, 0x594b8d2eL
, 0x5408abf7L
, 0x50c9b640L
,
86 0x4e8ee645L
, 0x4a4ffbf2L
, 0x470cdd2bL
, 0x43cdc09cL
,
87 0x7b827d21L
, 0x7f436096L
, 0x7200464fL
, 0x76c15bf8L
,
88 0x68860bfdL
, 0x6c47164aL
, 0x61043093L
, 0x65c52d24L
,
89 0x119b4be9L
, 0x155a565eL
, 0x18197087L
, 0x1cd86d30L
,
90 0x029f3d35L
, 0x065e2082L
, 0x0b1d065bL
, 0x0fdc1becL
,
91 0x3793a651L
, 0x3352bbe6L
, 0x3e119d3fL
, 0x3ad08088L
,
92 0x2497d08dL
, 0x2056cd3aL
, 0x2d15ebe3L
, 0x29d4f654L
,
93 0xc5a92679L
, 0xc1683bceL
, 0xcc2b1d17L
, 0xc8ea00a0L
,
94 0xd6ad50a5L
, 0xd26c4d12L
, 0xdf2f6bcbL
, 0xdbee767cL
,
95 0xe3a1cbc1L
, 0xe760d676L
, 0xea23f0afL
, 0xeee2ed18L
,
96 0xf0a5bd1dL
, 0xf464a0aaL
, 0xf9278673L
, 0xfde69bc4L
,
97 0x89b8fd09L
, 0x8d79e0beL
, 0x803ac667L
, 0x84fbdbd0L
,
98 0x9abc8bd5L
, 0x9e7d9662L
, 0x933eb0bbL
, 0x97ffad0cL
,
99 0xafb010b1L
, 0xab710d06L
, 0xa6322bdfL
, 0xa2f33668L
,
100 0xbcb4666dL
, 0xb8757bdaL
, 0xb5365d03L
, 0xb1f740b4L
103 #define UPDATE_CRC(crcVar,cha) \
105 crcVar = (crcVar << 8) ^ \
106 crc32Table[(crcVar >> 24) ^ \
110 static UInt
crcBytes ( UChar
* bytes
, UWord nBytes
, UInt crcIn
)
113 while (nBytes
>= 4) {
114 UPDATE_CRC(crc
, bytes
[0]);
115 UPDATE_CRC(crc
, bytes
[1]);
116 UPDATE_CRC(crc
, bytes
[2]);
117 UPDATE_CRC(crc
, bytes
[3]);
121 while (nBytes
>= 1) {
122 UPDATE_CRC(crc
, bytes
[0]);
129 static UInt
crcFinalise ( UInt crc
) {
135 static UInt theCRC
= 0xFFFFFFFF;
137 static HChar outBuf
[1024];
138 // take output that's in outBuf, length as specified, and
139 // update the running crc.
140 static void send ( int nbytes
)
142 assert( ((unsigned int)nbytes
) < sizeof(outBuf
)-1);
143 assert(outBuf
[nbytes
] == 0);
144 theCRC
= crcBytes( (UChar
*)&outBuf
[0], nbytes
, theCRC
);
145 if (VERBOSE
) printf("SEND %08x %s", theCRC
, outBuf
);
149 /////////////////////////////////////////////////////////////////
150 // END crc32 stuff //
151 /////////////////////////////////////////////////////////////////
158 static unsigned int val
[NVALS
]
159 = { 0x00, 0x01, 0x02, 0x03,
161 0x7E, 0x7F, 0x80, 0x81, 0x82,
163 0xFC, 0xFD, 0xFE, 0xFF,
165 0xFF00, 0xFF01, 0xFF02, 0xFF03,
166 0xFF3F, 0xFF40, 0xFF41,
167 0xFF7E, 0xFF7F, 0xFF80, 0xFF81, 0xFF82,
168 0xFFBF, 0xFFC0, 0xFFC1,
169 0xFFFC, 0xFFFD, 0xFFFE, 0xFFFF,
171 0xFFFFFF00, 0xFFFFFF01, 0xFFFFFF02, 0xFFFFFF03,
172 0xFFFFFF3F, 0xFFFFFF40, 0xFFFFFF41,
173 0xFFFFFF7E, 0xFFFFFF7F, 0xFFFFFF80, 0xFFFFFF81, 0xFFFFFF82,
174 0xFFFFFFBF, 0xFFFFFFC0, 0xFFFFFFC1,
175 0xFFFFFFFC, 0xFFFFFFFD, 0xFFFFFFFE, 0xFFFFFFFF
180 // shortened version, for use as valgrind regtest
183 static unsigned int val
[NVALS
]
196 0xFFFFFF00, 0xFFFFFF01,
197 0xFFFFFF3F, 0xFFFFFF40,
198 0xFFFFFF7F, 0xFFFFFF80,
199 0xFFFFFFBF, 0xFFFFFFC0,
205 /////////////////////////////////////
214 #define CC_MASK (CC_C | CC_P | CC_A | CC_Z | CC_S | CC_O)
216 #define GEN_do_locked_G_E(_name,_eax) \
218 __attribute__((noinline)) void do_locked_G_E_##_name ( void ) \
220 volatile int e_val, g_val, e_val_before; \
221 int o, s, z, a, c, p, v1, v2, flags_in; \
224 for (v1 = 0; v1 < NVALS; v1++) { \
225 for (v2 = 0; v2 < NVALS; v2++) { \
227 for (o = 0; o < 2; o++) { \
228 for (s = 0; s < 2; s++) { \
229 for (z = 0; z < 2; z++) { \
230 for (a = 0; a < 2; a++) { \
231 for (c = 0; c < 2; c++) { \
232 for (p = 0; p < 2; p++) { \
234 flags_in = (o ? CC_O : 0) \
243 e_val_before = e_val; \
245 block[0] = flags_in; \
247 block[2] = (int)(long)&e_val; \
249 __asm__ __volatile__( \
250 "movl 0(%0), %%eax\n\t" \
253 "movl 4(%0), %%eax\n\t" \
254 "movl 8(%0), %%ebx\n\t" \
255 "lock; " #_name " %%" #_eax ",(%%ebx)\n\t" \
258 "movl %%eax, 12(%0)\n\t" \
259 : : "r"(&block[0]) : "eax","ebx","cc","memory" \
264 "%s G=%08x E=%08x CCIN=%08x -> E=%08x CCOUT=%08x\n", \
265 #_name, g_val, e_val_before, flags_in, \
266 e_val, block[3] & CC_MASK) ); \
273 GEN_do_locked_G_E(addb
,al
)
274 GEN_do_locked_G_E(addw
,ax
)
275 GEN_do_locked_G_E(addl
,eax
)
277 GEN_do_locked_G_E(orb
, al
)
278 GEN_do_locked_G_E(orw
, ax
)
279 GEN_do_locked_G_E(orl
, eax
)
281 GEN_do_locked_G_E(adcb
,al
)
282 GEN_do_locked_G_E(adcw
,ax
)
283 GEN_do_locked_G_E(adcl
,eax
)
285 GEN_do_locked_G_E(sbbb
,al
)
286 GEN_do_locked_G_E(sbbw
,ax
)
287 GEN_do_locked_G_E(sbbl
,eax
)
289 GEN_do_locked_G_E(andb
,al
)
290 GEN_do_locked_G_E(andw
,ax
)
291 GEN_do_locked_G_E(andl
,eax
)
293 GEN_do_locked_G_E(subb
,al
)
294 GEN_do_locked_G_E(subw
,ax
)
295 GEN_do_locked_G_E(subl
,eax
)
297 GEN_do_locked_G_E(xorb
,al
)
298 GEN_do_locked_G_E(xorw
,ax
)
299 GEN_do_locked_G_E(xorl
,eax
)
304 #define GEN_do_locked_imm_E(_name,_eax,_imm) \
306 __attribute__((noinline)) void do_locked_imm_E_##_name##_##_imm ( void ) \
308 volatile int e_val, e_val_before; \
309 int o, s, z, a, c, p, v2, flags_in; \
312 for (v2 = 0; v2 < NVALS; v2++) { \
314 for (o = 0; o < 2; o++) { \
315 for (s = 0; s < 2; s++) { \
316 for (z = 0; z < 2; z++) { \
317 for (a = 0; a < 2; a++) { \
318 for (c = 0; c < 2; c++) { \
319 for (p = 0; p < 2; p++) { \
321 flags_in = (o ? CC_O : 0) \
329 e_val_before = e_val; \
331 block[0] = flags_in; \
332 block[1] = (int)(long)&e_val; \
334 __asm__ __volatile__( \
335 "movl 0(%0), %%eax\n\t" \
338 "movl 4(%0), %%ebx\n\t" \
339 "lock; " #_name " $" #_imm ",(%%ebx)\n\t" \
342 "movl %%eax, 8(%0)\n\t" \
343 : : "r"(&block[0]) : "eax","ebx","cc","memory" \
348 "%s I=%s E=%08x CCIN=%08x -> E=%08x CCOUT=%08x\n", \
349 #_name, #_imm, e_val_before, flags_in, \
350 e_val, block[2] & CC_MASK) ); \
357 GEN_do_locked_imm_E(addb
,al
,0x7F)
358 GEN_do_locked_imm_E(addb
,al
,0xF1)
359 GEN_do_locked_imm_E(addw
,ax
,0x7E)
360 GEN_do_locked_imm_E(addw
,ax
,0x9325)
361 GEN_do_locked_imm_E(addl
,eax
,0x7D)
362 GEN_do_locked_imm_E(addl
,eax
,0x31415927)
364 GEN_do_locked_imm_E(orb
,al
,0x7F)
365 GEN_do_locked_imm_E(orb
,al
,0xF1)
366 GEN_do_locked_imm_E(orw
,ax
,0x7E)
367 GEN_do_locked_imm_E(orw
,ax
,0x9325)
368 GEN_do_locked_imm_E(orl
,eax
,0x7D)
369 GEN_do_locked_imm_E(orl
,eax
,0x31415927)
371 GEN_do_locked_imm_E(adcb
,al
,0x7F)
372 GEN_do_locked_imm_E(adcb
,al
,0xF1)
373 GEN_do_locked_imm_E(adcw
,ax
,0x7E)
374 GEN_do_locked_imm_E(adcw
,ax
,0x9325)
375 GEN_do_locked_imm_E(adcl
,eax
,0x7D)
376 GEN_do_locked_imm_E(adcl
,eax
,0x31415927)
378 GEN_do_locked_imm_E(sbbb
,al
,0x7F)
379 GEN_do_locked_imm_E(sbbb
,al
,0xF1)
380 GEN_do_locked_imm_E(sbbw
,ax
,0x7E)
381 GEN_do_locked_imm_E(sbbw
,ax
,0x9325)
382 GEN_do_locked_imm_E(sbbl
,eax
,0x7D)
383 GEN_do_locked_imm_E(sbbl
,eax
,0x31415927)
385 GEN_do_locked_imm_E(andb
,al
,0x7F)
386 GEN_do_locked_imm_E(andb
,al
,0xF1)
387 GEN_do_locked_imm_E(andw
,ax
,0x7E)
388 GEN_do_locked_imm_E(andw
,ax
,0x9325)
389 GEN_do_locked_imm_E(andl
,eax
,0x7D)
390 GEN_do_locked_imm_E(andl
,eax
,0x31415927)
392 GEN_do_locked_imm_E(subb
,al
,0x7F)
393 GEN_do_locked_imm_E(subb
,al
,0xF1)
394 GEN_do_locked_imm_E(subw
,ax
,0x7E)
395 GEN_do_locked_imm_E(subw
,ax
,0x9325)
396 GEN_do_locked_imm_E(subl
,eax
,0x7D)
397 GEN_do_locked_imm_E(subl
,eax
,0x31415927)
399 GEN_do_locked_imm_E(xorb
,al
,0x7F)
400 GEN_do_locked_imm_E(xorb
,al
,0xF1)
401 GEN_do_locked_imm_E(xorw
,ax
,0x7E)
402 GEN_do_locked_imm_E(xorw
,ax
,0x9325)
403 GEN_do_locked_imm_E(xorl
,eax
,0x7D)
404 GEN_do_locked_imm_E(xorl
,eax
,0x31415927)
406 #define GEN_do_locked_unary_E(_name,_eax) \
408 __attribute__((noinline)) void do_locked_unary_E_##_name ( void ) \
410 volatile int e_val, e_val_before; \
411 int o, s, z, a, c, p, v2, flags_in; \
414 for (v2 = 0; v2 < NVALS; v2++) { \
416 for (o = 0; o < 2; o++) { \
417 for (s = 0; s < 2; s++) { \
418 for (z = 0; z < 2; z++) { \
419 for (a = 0; a < 2; a++) { \
420 for (c = 0; c < 2; c++) { \
421 for (p = 0; p < 2; p++) { \
423 flags_in = (o ? CC_O : 0) \
431 e_val_before = e_val; \
433 block[0] = flags_in; \
434 block[1] = (int)(long)&e_val; \
436 __asm__ __volatile__( \
437 "movl 0(%0), %%eax\n\t" \
440 "movl 4(%0), %%ebx\n\t" \
441 "lock; " #_name " (%%ebx)\n\t" \
444 "movl %%eax, 8(%0)\n\t" \
445 : : "r"(&block[0]) : "eax","ebx","cc","memory" \
450 "%s E=%08x CCIN=%08x -> E=%08x CCOUT=%08x\n", \
451 #_name, e_val_before, flags_in, \
452 e_val, block[2] & CC_MASK)); \
459 GEN_do_locked_unary_E(decb
,al
)
460 GEN_do_locked_unary_E(decw
,ax
)
461 GEN_do_locked_unary_E(decl
,eax
)
463 GEN_do_locked_unary_E(incb
,al
)
464 GEN_do_locked_unary_E(incw
,ax
)
465 GEN_do_locked_unary_E(incl
,eax
)
467 GEN_do_locked_unary_E(negb
,al
)
468 GEN_do_locked_unary_E(negw
,ax
)
469 GEN_do_locked_unary_E(negl
,eax
)
471 GEN_do_locked_unary_E(notb
,al
)
472 GEN_do_locked_unary_E(notw
,ax
)
473 GEN_do_locked_unary_E(notl
,eax
)
476 /////////////////////////////////////////////////////////////////
478 unsigned int btsl_mem ( UChar
* base
, int bitno
)
482 __volatile__("lock; btsl\t%2, %0\n\t"
484 : "=m" (*base
), "=q" (res
)
486 /* Pretty meaningless to dereference base here, but that's what you
487 have to do to get a btsl insn which refers to memory starting at
491 unsigned int btsw_mem ( UChar
* base
, int bitno
)
495 __volatile__("lock; btsw\t%w2, %0\n\t"
497 : "=m" (*base
), "=q" (res
)
502 unsigned int btrl_mem ( UChar
* base
, int bitno
)
506 __volatile__("lock; btrl\t%2, %0\n\t"
508 : "=m" (*base
), "=q" (res
)
512 unsigned int btrw_mem ( UChar
* base
, int bitno
)
516 __volatile__("lock; btrw\t%w2, %0\n\t"
518 : "=m" (*base
), "=q" (res
)
523 unsigned int btcl_mem ( UChar
* base
, int bitno
)
527 __volatile__("lock; btcl\t%2, %0\n\t"
529 : "=m" (*base
), "=q" (res
)
533 unsigned int btcw_mem ( UChar
* base
, int bitno
)
537 __volatile__("lock; btcw\t%w2, %0\n\t"
539 : "=m" (*base
), "=q" (res
)
544 unsigned int btl_mem ( UChar
* base
, int bitno
)
548 __volatile__("btl\t%2, %0\n\t"
550 : "=m" (*base
), "=q" (res
)
555 unsigned int btw_mem ( UChar
* base
, int bitno
)
559 __volatile__("btw\t%w2, %0\n\t"
561 : "=m" (*base
), "=q" (res
)
566 ULong
rol1 ( ULong x
)
568 return (x
<< 1) | (x
>> 63);
571 void do_bt_G_E_tests ( void )
576 ULong carrydep
, res
;;
578 /*------------------------ MEM-L -----------------------*/
581 block
= calloc(200,1);
583 /* Valid bit offsets are -800 .. 799 inclusive. */
585 for (n
= 0; n
< 10000; n
++) {
586 bitoff
= (myrandom() % 1600) - 800;
590 case 0: c
= btsl_mem(block
, bitoff
); break;
591 case 1: c
= btrl_mem(block
, bitoff
); break;
592 case 2: c
= btcl_mem(block
, bitoff
); break;
593 case 3: c
= btl_mem(block
, bitoff
); break;
596 assert(c
== 0 || c
== 1);
597 carrydep
= c
? (rol1(carrydep
) ^ (Long
)(Int
)bitoff
) : carrydep
;
600 /* Compute final result */
603 for (n
= 0; n
< 200; n
++) {
605 /* printf("%d ", (int)block[n]); */
606 res
= rol1(res
) ^ (ULong
)ch
;
609 send( sprintf(outBuf
,
610 "bt{s,r,c}l: final res 0x%llx, carrydep 0x%llx\n",
614 /*------------------------ MEM-W -----------------------*/
617 block
= calloc(200,1);
619 /* Valid bit offsets are -800 .. 799 inclusive. */
621 for (n
= 0; n
< 10000; n
++) {
622 bitoff
= (myrandom() % 1600) - 800;
626 case 0: c
= btsw_mem(block
, bitoff
); break;
627 case 1: c
= btrw_mem(block
, bitoff
); break;
628 case 2: c
= btcw_mem(block
, bitoff
); break;
629 case 3: c
= btw_mem(block
, bitoff
); break;
632 assert(c
== 0 || c
== 1);
633 carrydep
= c
? (rol1(carrydep
) ^ (Long
)(Int
)bitoff
) : carrydep
;
636 /* Compute final result */
639 for (n
= 0; n
< 200; n
++) {
641 /* printf("%d ", (int)block[n]); */
642 res
= rol1(res
) ^ (ULong
)ch
;
645 send( sprintf(outBuf
,
646 "bt{s,r,c}w: final res 0x%llx, carrydep 0x%llx\n",
652 /////////////////////////////////////////////////////////////////
654 /* Given a word, do bt/bts/btr/btc on bits 0, 1, 2 and 3 of it, and
655 also reconstruct the original bits 0, 1, 2, 3 by looking at the
656 carry flag. Returned result has mashed bits 0-3 at the bottom and
657 the reconstructed original bits 0-3 as 4-7. */
659 UInt
mash_mem_L ( UInt
* origp
)
661 UInt reconstructed
, mashed
;
662 __asm__
__volatile__ (
667 "btl $0, (%%edx)\n\t"
669 "movzbl %%cl, %%ecx\n\t"
670 "orl %%ecx, %%eax\n\t"
672 "lock; btsl $1, (%%edx)\n\t"
674 "movzbl %%cl, %%ecx\n\t"
676 "orl %%ecx, %%eax\n\t"
678 "lock; btrl $2, (%%edx)\n\t"
680 "movzbl %%cl, %%ecx\n\t"
682 "orl %%ecx, %%eax\n\t"
684 "lock; btcl $3, (%%edx)\n\t"
686 "movzbl %%cl, %%ecx\n\t"
688 "orl %%ecx, %%eax\n\t"
693 : "=r" (reconstructed
), "=r" (mashed
)
695 : "eax", "ecx", "edx", "cc");
696 return (mashed
& 0xF) | ((reconstructed
& 0xF) << 4);
699 UInt
mash_mem_W ( UShort
* origp
)
701 UInt reconstructed
, mashed
;
702 __asm__
__volatile__ (
707 "btw $0, (%%edx)\n\t"
709 "movzbl %%cl, %%ecx\n\t"
710 "orl %%ecx, %%eax\n\t"
712 "lock; btsw $1, (%%edx)\n\t"
714 "movzbl %%cl, %%ecx\n\t"
716 "orl %%ecx, %%eax\n\t"
718 "lock; btrw $2, (%%edx)\n\t"
720 "movzbl %%cl, %%ecx\n\t"
722 "orl %%ecx, %%eax\n\t"
724 "lock; btcw $3, (%%edx)\n\t"
726 "movzbl %%cl, %%ecx\n\t"
728 "orl %%ecx, %%eax\n\t"
733 : "=r" (reconstructed
), "=r" (mashed
)
735 : "eax", "ecx", "edx", "cc");
736 return (mashed
& 0xF) | ((reconstructed
& 0xF) << 4);
740 void do_bt_imm_E_tests( void )
743 UInt
* iil
= malloc(sizeof(UInt
));
744 UShort
* iiw
= malloc(sizeof(UShort
));
745 for (i
= 0; i
< 0x10; i
++) {
748 send( sprintf(outBuf
, "0x%x -> 0x%02x 0x%02x\n", i
,
749 mash_mem_L(iil
), mash_mem_W(iiw
)));
757 /////////////////////////////////////////////////////////////////
761 do_locked_G_E_addb();
762 do_locked_G_E_addw();
763 do_locked_G_E_addl();
769 do_locked_G_E_adcb();
770 do_locked_G_E_adcw();
771 do_locked_G_E_adcl();
773 do_locked_G_E_sbbb();
774 do_locked_G_E_sbbw();
775 do_locked_G_E_sbbl();
777 do_locked_G_E_andb();
778 do_locked_G_E_andw();
779 do_locked_G_E_andl();
781 do_locked_G_E_subb();
782 do_locked_G_E_subw();
783 do_locked_G_E_subl();
785 do_locked_G_E_xorb();
786 do_locked_G_E_xorw();
787 do_locked_G_E_xorl();
789 do_locked_imm_E_addb_0x7F();
790 do_locked_imm_E_addb_0xF1();
791 do_locked_imm_E_addw_0x7E();
792 do_locked_imm_E_addw_0x9325();
793 do_locked_imm_E_addl_0x7D();
794 do_locked_imm_E_addl_0x31415927();
796 do_locked_imm_E_orb_0x7F();
797 do_locked_imm_E_orb_0xF1();
798 do_locked_imm_E_orw_0x7E();
799 do_locked_imm_E_orw_0x9325();
800 do_locked_imm_E_orl_0x7D();
801 do_locked_imm_E_orl_0x31415927();
803 do_locked_imm_E_adcb_0x7F();
804 do_locked_imm_E_adcb_0xF1();
805 do_locked_imm_E_adcw_0x7E();
806 do_locked_imm_E_adcw_0x9325();
807 do_locked_imm_E_adcl_0x7D();
808 do_locked_imm_E_adcl_0x31415927();
810 do_locked_imm_E_sbbb_0x7F();
811 do_locked_imm_E_sbbb_0xF1();
812 do_locked_imm_E_sbbw_0x7E();
813 do_locked_imm_E_sbbw_0x9325();
814 do_locked_imm_E_sbbl_0x7D();
815 do_locked_imm_E_sbbl_0x31415927();
817 do_locked_imm_E_andb_0x7F();
818 do_locked_imm_E_andb_0xF1();
819 do_locked_imm_E_andw_0x7E();
820 do_locked_imm_E_andw_0x9325();
821 do_locked_imm_E_andl_0x7D();
822 do_locked_imm_E_andl_0x31415927();
824 do_locked_imm_E_subb_0x7F();
825 do_locked_imm_E_subb_0xF1();
826 do_locked_imm_E_subw_0x7E();
827 do_locked_imm_E_subw_0x9325();
828 do_locked_imm_E_subl_0x7D();
829 do_locked_imm_E_subl_0x31415927();
831 do_locked_imm_E_xorb_0x7F();
832 do_locked_imm_E_xorb_0xF1();
833 do_locked_imm_E_xorw_0x7E();
834 do_locked_imm_E_xorw_0x9325();
835 do_locked_imm_E_xorl_0x7D();
836 do_locked_imm_E_xorl_0x31415927();
838 do_locked_unary_E_decb();
839 do_locked_unary_E_decw();
840 do_locked_unary_E_decl();
842 do_locked_unary_E_incb();
843 do_locked_unary_E_incw();
844 do_locked_unary_E_incl();
846 do_locked_unary_E_negb();
847 do_locked_unary_E_negw();
848 do_locked_unary_E_negl();
850 do_locked_unary_E_notb();
851 do_locked_unary_E_notw();
852 do_locked_unary_E_notl();
858 // So there should be 87 lock-prefixed instructions in the
859 // disassembly of this compilation unit.
861 // objdump -d ./x86locked | grep lock | grep -v do_lock | grep -v elf32 | wc
863 { UInt crcExpd
= 0xB2D75045;
864 theCRC
= crcFinalise( theCRC
);
865 if (theCRC
== crcExpd
) {
866 printf("x86locked: PASS: CRCs actual 0x%08X expected 0x%08X\n",
869 printf("x86locked: FAIL: CRCs actual 0x%08X expected 0x%08X\n",
871 printf("x86locked: set #define VERBOSE 1 to diagnose\n");