6 typedef unsigned long long int ULong;
7 typedef unsigned int UInt;
8 typedef unsigned short UShort;
9 typedef unsigned char UChar;
11 typedef signed int Int;
12 typedef signed short Short;
14 typedef signed long int Word;
16 /* ------------ MEM, Q ------------ */
18 ULong btsq_mem ( char* base, Word bitno )
22 __volatile__("btsq\t%2, %0\n\t"
24 : "=m" (*base), "=q" (res)
26 /* Pretty meaningless to dereference base here, but that's what you
27 have to do to get a btsl insn which refers to memory starting at
32 ULong btrq_mem ( char* base, Word bitno )
36 __volatile__("btrq\t%2, %0\n\t"
38 : "=m" (*base), "=q" (res)
43 ULong btcq_mem ( char* base, Word bitno )
47 __volatile__("btcq\t%2, %0\n\t"
49 : "=m" (*base), "=q" (res)
54 ULong btq_mem ( char* base, Word bitno )
58 __volatile__("btq\t%2, %0\n\t"
60 : "=m" (*base), "=q" (res)
67 /* ------------ MEM, L ------------ */
69 ULong btsl_mem ( char* base, Word bitno )
73 __volatile__("btsl\t%2, %0\n\t"
75 : "=m" (*base), "=q" (res)
77 /* Pretty meaningless to dereference base here, but that's what you
78 have to do to get a btsl insn which refers to memory starting at
83 ULong btrl_mem ( char* base, Word bitno )
87 __volatile__("btrl\t%2, %0\n\t"
89 : "=m" (*base), "=q" (res)
94 ULong btcl_mem ( char* base, Word bitno )
98 __volatile__("btcl\t%2, %0\n\t"
100 : "=m" (*base), "=q" (res)
105 ULong btl_mem ( char* base, Word bitno )
109 __volatile__("btl\t%2, %0\n\t"
111 : "=m" (*base), "=q" (res)
119 /* ------------ MEM, W ------------ */
121 ULong btsw_mem ( char* base, Word bitno )
125 __volatile__("btsw\t%2, %0\n\t"
127 : "=m" (*base), "=q" (res)
128 : "r" ((Short)bitno));
129 /* Pretty meaningless to dereference base here, but that's what you
130 have to do to get a btsl insn which refers to memory starting at
135 ULong btrw_mem ( char* base, Word bitno )
139 __volatile__("btrw\t%2, %0\n\t"
141 : "=m" (*base), "=q" (res)
142 : "r" ((Short)bitno));
146 ULong btcw_mem ( char* base, Word bitno )
150 __volatile__("btcw\t%2, %0\n\t"
152 : "=m" (*base), "=q" (res)
153 : "r" ((Short)bitno));
157 ULong btw_mem ( char* base, Word bitno )
161 __volatile__("btw\t%2, %0\n\t"
163 : "=m" (*base), "=q" (res)
171 /* ------------ REG, Q ------------ */
173 ULong btsq_reg ( ULong reg_in, Word bitno,
179 __volatile__("movq\t%3, %%rax\n\t"
180 "btsq\t%2, %%rax\n\t"
181 "movq\t%%rax, %1\n\t"
183 : "=q" (res), "=r" (reg_out)
184 : "r" (bitno), "r" (reg_in)
186 *reg_out_p = reg_out;
191 ULong btrq_reg ( ULong reg_in, Word bitno,
197 __volatile__("movq\t%3, %%rax\n\t"
198 "btrq\t%2, %%rax\n\t"
199 "movq\t%%rax, %1\n\t"
201 : "=q" (res), "=r" (reg_out)
202 : "r" (bitno), "r" (reg_in)
204 *reg_out_p = reg_out;
209 ULong btcq_reg ( ULong reg_in, Word bitno,
215 __volatile__("movq\t%3, %%rax\n\t"
216 "btcq\t%2, %%rax\n\t"
217 "movq\t%%rax, %1\n\t"
219 : "=q" (res), "=r" (reg_out)
220 : "r" (bitno), "r" (reg_in)
222 *reg_out_p = reg_out;
227 ULong btq_reg ( ULong reg_in, Word bitno,
233 __volatile__("movq\t%3, %%rax\n\t"
235 "movq\t%%rax, %1\n\t"
237 : "=q" (res), "=r" (reg_out)
238 : "r" (bitno), "r" (reg_in)
240 *reg_out_p = reg_out;
246 /* ------------ REG, L ------------ */
248 ULong btsl_reg ( ULong reg_in, Word bitno,
254 __volatile__("movq\t%3, %%rax\n\t"
255 "btsl\t%2, %%eax\n\t"
256 "movq\t%%rax, %1\n\t"
258 : "=q" (res), "=r" (reg_out)
259 : "r" ((Int)bitno), "r" (reg_in)
261 *reg_out_p = reg_out;
266 ULong btrl_reg ( ULong reg_in, Word bitno,
272 __volatile__("movq\t%3, %%rax\n\t"
273 "btrl\t%2, %%eax\n\t"
274 "movq\t%%rax, %1\n\t"
276 : "=q" (res), "=r" (reg_out)
277 : "r" ((Int)bitno), "r" (reg_in)
279 *reg_out_p = reg_out;
284 ULong btcl_reg ( ULong reg_in, Word bitno,
290 __volatile__("movq\t%3, %%rax\n\t"
291 "btcl\t%2, %%eax\n\t"
292 "movq\t%%rax, %1\n\t"
294 : "=q" (res), "=r" (reg_out)
295 : "r" ((Int)bitno), "r" (reg_in)
297 *reg_out_p = reg_out;
302 ULong btl_reg ( ULong reg_in, Word bitno,
308 __volatile__("movq\t%3, %%rax\n\t"
310 "movq\t%%rax, %1\n\t"
312 : "=q" (res), "=r" (reg_out)
313 : "r" ((Int)bitno), "r" (reg_in)
315 *reg_out_p = reg_out;
321 /* ------------ REG, W ------------ */
323 ULong btsw_reg ( ULong reg_in, Word bitno,
329 __volatile__("movq\t%3, %%rax\n\t"
331 "movq\t%%rax, %1\n\t"
333 : "=q" (res), "=r" (reg_out)
334 : "r" ((Short)bitno), "r" (reg_in)
336 *reg_out_p = reg_out;
341 ULong btrw_reg ( ULong reg_in, Word bitno,
347 __volatile__("movq\t%3, %%rax\n\t"
349 "movq\t%%rax, %1\n\t"
351 : "=q" (res), "=r" (reg_out)
352 : "r" ((Short)bitno), "r" (reg_in)
354 *reg_out_p = reg_out;
359 ULong btcw_reg ( ULong reg_in, Word bitno,
365 __volatile__("movq\t%3, %%rax\n\t"
367 "movq\t%%rax, %1\n\t"
369 : "=q" (res), "=r" (reg_out)
370 : "r" ((Short)bitno), "r" (reg_in)
372 *reg_out_p = reg_out;
377 ULong btw_reg ( ULong reg_in, Word bitno,
383 __volatile__("movq\t%3, %%rax\n\t"
385 "movq\t%%rax, %1\n\t"
387 : "=q" (res), "=r" (reg_out)
388 : "r" ((Short)bitno), "r" (reg_in)
390 *reg_out_p = reg_out;
400 ULong rol1 ( ULong x )
402 return (x << 1) | (x >> 63);
408 ULong carrydep, c, res;
413 /*------------------------ MEM-L -----------------------*/
416 block = calloc(200,1);
418 /* Valid bit offsets are -800 .. 799 inclusive. */
420 for (n = 0; n < 10000; n++) {
421 bitoff = (random() % 1600) - 800;
425 case 0: c = btsl_mem(block, bitoff); break;
426 case 1: c = btrl_mem(block, bitoff); break;
427 case 2: c = btcl_mem(block, bitoff); break;
428 case 3: c = btl_mem(block, bitoff); break;
429 case 4: c = btsq_mem(block, bitoff); break;
430 case 5: c = btrq_mem(block, bitoff); break;
431 case 6: c = btcq_mem(block, bitoff); break;
432 case 7: c = btq_mem(block, bitoff); break;
433 case 8: c = btsw_mem(block, bitoff); break;
434 case 9: c = btrw_mem(block, bitoff); break;
435 case 10: c = btcw_mem(block, bitoff); break;
436 case 11: c = btw_mem(block, bitoff); break;
439 assert(c == 0 || c == 1);
440 carrydep = c ? (rol1(carrydep) ^ bitoff) : carrydep;
443 /* Compute final result */
446 for (n = 0; n < 200; n++) {
448 /* printf("%d ", (int)block[n]); */
449 res = rol1(res) ^ (UInt)ch;
452 printf("MEM-L: final res 0x%llx, carrydep 0x%llx\n", res, carrydep);
454 /*------------------------ REG-L -----------------------*/
459 for (n = 0; n < 1000; n++) {
460 bitoff = (random() % 100) - 50;
464 case 0: c = btsl_reg(reg, bitoff, ®); break;
465 case 1: c = btrl_reg(reg, bitoff, ®); break;
466 case 2: c = btcl_reg(reg, bitoff, ®); break;
467 case 3: c = btl_reg(reg, bitoff, ®); break;
468 case 4: c = btsq_reg(reg, bitoff, ®); break;
469 case 5: c = btrq_reg(reg, bitoff, ®); break;
470 case 6: c = btcq_reg(reg, bitoff, ®); break;
471 case 7: c = btq_reg(reg, bitoff, ®); break;
472 case 8: c = btsw_reg(reg, bitoff, ®); break;
473 case 9: c = btrw_reg(reg, bitoff, ®); break;
474 case 10: c = btcw_reg(reg, bitoff, ®); break;
475 case 11: c = btw_reg(reg, bitoff, ®); break;
478 assert(c == 0 || c == 1);
479 carrydep = c ? (rol1(carrydep) ^ bitoff) : carrydep;
482 printf("REG-L: final res 0x%llx, carrydep 0x%llx\n", reg, carrydep);
486 /* Just try one of these at once; more than one can cause a
487 confusing merging of error messages. */
488 //btsl_mem(block, -800); /* should not complain */
489 //btsl_mem(block, -801); /* should complain */
490 //btsl_mem(block, 799); /* should not complain */
491 //btsl_mem(block, 800); /* should complain */