1
2#include <stdio.h>
3#include <stdlib.h>
4#include <assert.h>
5
6typedef 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. */
12UInt 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
55UInt 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
97UInt 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
140int 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