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