1 
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <assert.h>
5 
6 typedef unsigned int UInt;
7 
8 /* Given a word, do bt/bts/btr/btc on bits 0, 1, 2 and 3 of it, and
9    also reconstruct the original bits 0, 1, 2, 3 by looking at the
10    carry flag.  Returned result has mashed bits 0-3 at the bottom and
11    the reconstructed original bits 0-3 as 4-7. */
mash_reg_L(UInt orig)12 UInt mash_reg_L ( UInt orig )
13 {
14   UInt reconstructed, mashed;
15   __asm__ __volatile__ (
16      "movl %2, %%edx\n\t"
17      ""
18      "movl $0, %%eax\n\t"
19      "\n\t"
20      "btl  $0, %%edx\n\t"
21      "setb %%cl\n\t"
22      "movzbl %%cl, %%ecx\n\t"
23      "orl %%ecx, %%eax\n\t"
24      "\n\t"
25      "btsl $1, %%edx\n\t"
26      "setb %%cl\n\t"
27      "movzbl %%cl, %%ecx\n\t"
28      "shll $1, %%ecx\n\t"
29      "orl %%ecx, %%eax\n\t"
30      "\n\t"
31      "btrl $2, %%edx\n\t"
32      "setb %%cl\n\t"
33      "movzbl %%cl, %%ecx\n\t"
34      "shll $2, %%ecx\n\t"
35      "orl %%ecx, %%eax\n\t"
36      "\n\t"
37      "btcl $3, %%edx\n\t"
38      "setb %%cl\n\t"
39      "movzbl %%cl, %%ecx\n\t"
40      "shll $3, %%ecx\n\t"
41      "orl %%ecx, %%eax\n\t"
42      "\n\t"
43      "movl %%eax, %0\n\t"
44      "movl %%edx, %1"
45 
46      : "=r" (reconstructed), "=r" (mashed)
47      : "r" (orig)
48      : "eax", "ecx", "edx", "cc");
49   return (mashed & 0xF) | ((reconstructed & 0xF) << 4);
50 }
51 
52 
53 
54 
mash_mem_L(int * origp)55 UInt mash_mem_L ( int* origp )
56 {
57   UInt reconstructed, mashed;
58   __asm__ __volatile__ (
59      "movl %2, %%edx\n\t"
60      ""
61      "movl $0, %%eax\n\t"
62      "\n\t"
63      "btl  $0, (%%edx)\n\t"
64      "setb %%cl\n\t"
65      "movzbl %%cl, %%ecx\n\t"
66      "orl %%ecx, %%eax\n\t"
67      "\n\t"
68      "btsl $1, (%%edx)\n\t"
69      "setb %%cl\n\t"
70      "movzbl %%cl, %%ecx\n\t"
71      "shll $1, %%ecx\n\t"
72      "orl %%ecx, %%eax\n\t"
73      "\n\t"
74      "btrl $2, (%%edx)\n\t"
75      "setb %%cl\n\t"
76      "movzbl %%cl, %%ecx\n\t"
77      "shll $2, %%ecx\n\t"
78      "orl %%ecx, %%eax\n\t"
79      "\n\t"
80      "btcl $3, (%%edx)\n\t"
81      "setb %%cl\n\t"
82      "movzbl %%cl, %%ecx\n\t"
83      "shll $3, %%ecx\n\t"
84      "orl %%ecx, %%eax\n\t"
85      "\n\t"
86      "movl %%eax, %0\n\t"
87      "movl (%%edx), %1"
88 
89      : "=r" (reconstructed), "=r" (mashed)
90      : "r" (origp)
91      : "eax", "ecx", "edx", "cc");
92   return (mashed & 0xF) | ((reconstructed & 0xF) << 4);
93 }
94 
95 
96 
mash_reg_W(UInt orig)97 UInt mash_reg_W ( UInt orig )
98 {
99   UInt reconstructed, mashed;
100   __asm__ __volatile__ (
101      "movl %2, %%edx\n\t"
102      ""
103      "movl $0, %%eax\n\t"
104      "\n\t"
105      "btw  $0, %%dx\n\t"
106      "setb %%cl\n\t"
107      "movzbl %%cl, %%ecx\n\t"
108      "orl %%ecx, %%eax\n\t"
109      "\n\t"
110      "btsw $1, %%dx\n\t"
111      "setb %%cl\n\t"
112      "movzbl %%cl, %%ecx\n\t"
113      "shll $1, %%ecx\n\t"
114      "orl %%ecx, %%eax\n\t"
115      "\n\t"
116      "btrw $2, %%dx\n\t"
117      "setb %%cl\n\t"
118      "movzbl %%cl, %%ecx\n\t"
119      "shll $2, %%ecx\n\t"
120      "orl %%ecx, %%eax\n\t"
121      "\n\t"
122      "btcw $3, %%dx\n\t"
123      "setb %%cl\n\t"
124      "movzbl %%cl, %%ecx\n\t"
125      "shll $3, %%ecx\n\t"
126      "orl %%ecx, %%eax\n\t"
127      "\n\t"
128      "movl %%eax, %0\n\t"
129      "movl %%edx, %1"
130 
131      : "=r" (reconstructed), "=r" (mashed)
132      : "r" (orig)
133      : "eax", "ecx", "edx", "cc");
134   return (mashed & 0xF) | ((reconstructed & 0xF) << 4);
135 }
136 
137 
138 
139 
main(void)140 int main ( void )
141 {
142   int i, ii;
143   for (i = 0; i < 0x10; i++) {
144     ii = i;
145     printf("0x%x -> 0x%2x 0x%2x 0x%2x\n", i,
146            mash_reg_L(i), mash_mem_L(&ii), mash_reg_W(i));
147   }
148   return 1;
149 }
150 
151