Fix force mode after setboard
[bonanza.git] / bitop.c
1 #include "shogi.h"
2
3 int CONV
4 popu_count012( unsigned int u0, unsigned int u1, unsigned int u2 )
5 {
6   int counter = 0;
7   while ( u0 ) { counter++;  u0 &= u0 - 1U; }
8   while ( u1 ) { counter++;  u1 &= u1 - 1U; }
9   while ( u2 ) { counter++;  u2 &= u2 - 1U; }
10   return counter;
11 }
12
13
14 #if defined(_MSC_VER)
15
16 int CONV
17 first_one012( unsigned int u0, unsigned int u1, unsigned int u2 )
18 {
19   unsigned long index;
20
21   if ( _BitScanReverse( &index, u0 ) ) { return 26 - index; }
22   if ( _BitScanReverse( &index, u1 ) ) { return 53 - index; }
23   _BitScanReverse( &index, u2 );
24   return 80 - index;
25 }
26
27 int CONV
28 last_one210( unsigned int u2, unsigned int u1, unsigned int u0 )
29 {
30   unsigned long index;
31
32   if ( _BitScanForward( &index, u2 ) ) { return 80 - index; }
33   if ( _BitScanForward( &index, u1 ) ) { return 53 - index; }
34   _BitScanForward( &index, u0 );
35   return 26 - index;
36 }
37
38 int CONV
39 first_one01( unsigned int u0, unsigned int u1 )
40 {
41   unsigned long index;
42
43   if ( _BitScanReverse( &index, u0 ) ) { return 26 - index; }
44   _BitScanReverse( &index, u1 );
45   return 53 - index;
46 }
47
48 int CONV
49 first_one12( unsigned int u1, unsigned int u2 )
50 {
51   unsigned long index;
52   
53   if ( _BitScanReverse( &index, u1 ) ) { return 53 - index; }
54   _BitScanReverse( &index, u2 );
55   return 80 - index;
56 }
57
58 int CONV
59 last_one01( unsigned int u0, unsigned int u1 )
60 {
61   unsigned long index;
62
63   if ( _BitScanForward( &index, u1 ) ) { return 53 - index; }
64   _BitScanForward( &index, u0 );
65   return 26 - index;
66 }
67
68 int CONV
69 last_one12( unsigned int u1, unsigned u2 )
70 {
71   unsigned long index;
72
73   if ( _BitScanForward( &index, u2 ) ) { return 80 - index; }
74   _BitScanForward( &index, u1 );
75   return 53 - index;
76 }
77
78 int CONV
79 first_one1( unsigned int u1 )
80 {
81   unsigned long index;
82   
83   _BitScanReverse( &index, u1 );
84   return 53 - index;
85 }
86
87 int CONV
88 first_one2( unsigned int u2 )
89 {
90   unsigned long index;
91   
92   _BitScanReverse( &index, u2 );
93   return 80 - index;
94 }
95
96 int CONV
97 last_one0( unsigned int u0 )
98 {
99   unsigned long index;
100   
101   _BitScanForward( &index, u0 );
102   return 26 - index;
103 }
104
105 int CONV
106 last_one1( unsigned int u1 )
107 {
108   unsigned long index;
109   
110   _BitScanForward( &index, u1 );
111   return 53 - index;
112 }
113
114 #elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) )
115
116 int
117 first_one012( unsigned int u0, unsigned int u1, unsigned int u2 )
118 {
119   if ( u0 ) { return __builtin_clz( u0 ) - 5; }
120   if ( u1 ) { return __builtin_clz( u1 ) + 22; }
121   return __builtin_clz( u2 ) + 49;
122 }
123
124
125 int
126 last_one210( unsigned int u2, unsigned int u1, unsigned int u0 )
127 {
128   if ( u2 ) { return 80 - __builtin_ctz( u2 ); }
129   if ( u1 ) { return 53 - __builtin_ctz( u1 ); }
130   return 26 - __builtin_ctz( u0 );
131 }
132
133
134 int
135 first_one01( unsigned int u0, unsigned int u1 )
136 {
137   if ( u0 ) { return __builtin_clz( u0 ) - 5; }
138   return __builtin_clz( u1 ) + 22;
139 }
140
141
142 int
143 first_one12( unsigned int u1, unsigned int u2 )
144 {
145   if ( u1 ) { return __builtin_clz( u1 ) + 22; }
146   return __builtin_clz( u2 ) + 49;
147 }
148
149
150 int
151 last_one01( unsigned int u0, unsigned int u1 )
152 {
153   if ( u1 ) { return 53 - __builtin_ctz( u1 ); }
154   return 26 - __builtin_ctz( u0 );
155 }
156
157
158 int
159 last_one12( unsigned int u1, unsigned int u2 )
160 {
161   if ( u2 ) { return 80 - __builtin_ctz( u2 ); }
162   return 53 - __builtin_ctz( u1 );
163 }
164
165
166 int first_one1( unsigned int u1 ) { return __builtin_clz( u1 ) + 22; }
167 int first_one2( unsigned int u2 ) { return __builtin_clz( u2 ) + 49; }
168 int last_one0( unsigned int u0 ) { return 26 - __builtin_ctz( u0 ); }
169 int last_one1( unsigned int u1 ) { return 53 - __builtin_ctz( u1 ); }
170
171 #else
172
173 int
174 first_one012( unsigned int u0, unsigned int u1, unsigned int u2 )
175 {
176   if ( u0 & 0x7fc0000 ) { return aifirst_one[u0>>18] +  0; }
177   if ( u0 & 0x7fffe00 ) { return aifirst_one[u0>> 9] +  9; }
178   if ( u0 & 0x7ffffff ) { return aifirst_one[u0    ] + 18; }
179
180   if ( u1 & 0x7fc0000 ) { return aifirst_one[u1>>18] + 27; }
181   if ( u1 & 0x7fffe00 ) { return aifirst_one[u1>> 9] + 36; }
182   if ( u1 & 0x7ffffff ) { return aifirst_one[u1    ] + 45; }
183
184   if ( u2 & 0x7fc0000 ) { return aifirst_one[u2>>18] + 54; }
185   if ( u2 & 0x7fffe00 ) { return aifirst_one[u2>> 9] + 63; }
186   return aifirst_one[u2] + 72;
187 }
188
189
190 int
191 last_one210( unsigned int u2, unsigned int u1, unsigned int u0 )
192 {
193   unsigned int j;
194
195   j = u2 & 0x00001ff;  if ( j ) { return ailast_one[j    ] + 72; }
196   j = u2 & 0x003ffff;  if ( j ) { return ailast_one[j>> 9] + 63; }
197   if ( u2 & 0x7ffffff ) { return ailast_one[u2>>18] + 54; }
198
199   j = u1 & 0x00001ff;  if ( j ) { return ailast_one[j    ] + 45; }
200   j = u1 & 0x003ffff;  if ( j ) { return ailast_one[j>> 9] + 36; }
201   if ( u1 & 0x7ffffff ) { return ailast_one[u1>>18] + 27; }
202
203   j = u0 & 0x00001ff;  if ( j ) { return ailast_one[j    ] + 18; }
204   j = u0 & 0x003ffff;  if ( j ) { return ailast_one[j>> 9] +  9; }
205   return ailast_one[u0>>18];
206 }
207
208
209 int
210 first_one01( unsigned int u0, unsigned int u1 )
211 {
212   if ( u0 & 0x7fc0000 ) { return aifirst_one[u0>>18] +  0; }
213   if ( u0 & 0x7fffe00 ) { return aifirst_one[u0>> 9] +  9; }
214   if ( u0 & 0x7ffffff ) { return aifirst_one[u0    ] + 18; }
215
216   if ( u1 & 0x7fc0000 ) { return aifirst_one[u1>>18] + 27; }
217   if ( u1 & 0x7fffe00 ) { return aifirst_one[u1>> 9] + 36; }
218   return aifirst_one[ u1 ] + 45;
219 }
220
221
222 int
223 first_one12( unsigned int u1, unsigned int u2 )
224 {
225   if ( u1 & 0x7fc0000 ) { return aifirst_one[u1>>18] + 27; }
226   if ( u1 & 0x7fffe00 ) { return aifirst_one[u1>> 9] + 36; }
227   if ( u1 & 0x7ffffff ) { return aifirst_one[u1    ] + 45; }
228
229   if ( u2 & 0x7fc0000 ) { return aifirst_one[u2>>18] + 54; }
230   if ( u2 & 0x7fffe00 ) { return aifirst_one[u2>> 9] + 63; }
231   return aifirst_one[ u2 ] + 72;
232 }
233
234
235 int
236 last_one01( unsigned int u0, unsigned int u1 )
237 {
238   unsigned int j;
239
240   j = u1 & 0x00001ff;  if ( j ) { return ailast_one[j    ] + 45; }
241   j = u1 & 0x003ffff;  if ( j ) { return ailast_one[j>> 9] + 36; }
242   if ( u1 & 0x7ffffff ) { return ailast_one[u1>>18] + 27; }
243
244   j = u0 & 0x00001ff;  if ( j ) { return ailast_one[j    ] + 18; }
245   j = u0 & 0x003ffff;  if ( j ) { return ailast_one[j>> 9] +  9; }
246   return ailast_one[u0>>18];
247 }
248
249
250 int
251 last_one12( unsigned int u1, unsigned int u2 )
252 {
253   unsigned int j;
254
255   j = u2 & 0x00001ff;  if ( j ) { return ailast_one[j    ] + 72; }
256   j = u2 & 0x003ffff;  if ( j ) { return ailast_one[j>> 9] + 63; }
257   if ( u2 & 0x7ffffff ) { return ailast_one[u2>>18] + 54; }
258
259   j = u1 & 0x00001ff;  if ( j ) { return ailast_one[j    ] + 45; }
260   j = u1 & 0x003ffff;  if ( j ) { return ailast_one[j>> 9] + 36; }
261   return ailast_one[u1>>18] + 27;
262 }
263
264
265 int
266 first_one1( unsigned int u1 )
267 {
268   if ( u1 & 0x7fc0000U ) { return aifirst_one[u1>>18] + 27; }
269   if ( u1 & 0x7fffe00U ) { return aifirst_one[u1>> 9] + 36; }
270   return aifirst_one[u1] + 45;
271 }
272
273
274 int
275 first_one2( unsigned int u2 )
276 {
277   if ( u2 & 0x7fc0000U ) { return aifirst_one[u2>>18] + 54; }
278   if ( u2 & 0x7fffe00U ) { return aifirst_one[u2>> 9] + 63; }
279   return aifirst_one[u2] + 72;
280 }
281
282
283 int
284 last_one0( unsigned int i )
285 {
286   unsigned int j;
287
288   j = i & 0x00001ffU;  if ( j ) { return ailast_one[j    ] + 18; }
289   j = i & 0x003ffffU;  if ( j ) { return ailast_one[j>> 9] +  9; }
290   return ailast_one[i>>18];
291 }
292
293
294 int
295 last_one1( unsigned int u1 )
296 {
297   unsigned int j;
298
299   j = u1 & 0x00001ffU;  if ( j ) { return ailast_one[j    ] + 45; }
300   j = u1 & 0x003ffffU;  if ( j ) { return ailast_one[j>> 9] + 36; }
301   return ailast_one[u1>>18] + 27;
302 }
303
304 #endif