My Project
bit.c
Go to the documentation of this file.
1
14#include "bit.h"
15#include "util.h"
16
18const unsigned long long X_TO_BIT[] = {
19 0x0000000000000001ULL, 0x0000000000000002ULL, 0x0000000000000004ULL, 0x0000000000000008ULL,
20 0x0000000000000010ULL, 0x0000000000000020ULL, 0x0000000000000040ULL, 0x0000000000000080ULL,
21 0x0000000000000100ULL, 0x0000000000000200ULL, 0x0000000000000400ULL, 0x0000000000000800ULL,
22 0x0000000000001000ULL, 0x0000000000002000ULL, 0x0000000000004000ULL, 0x0000000000008000ULL,
23 0x0000000000010000ULL, 0x0000000000020000ULL, 0x0000000000040000ULL, 0x0000000000080000ULL,
24 0x0000000000100000ULL, 0x0000000000200000ULL, 0x0000000000400000ULL, 0x0000000000800000ULL,
25 0x0000000001000000ULL, 0x0000000002000000ULL, 0x0000000004000000ULL, 0x0000000008000000ULL,
26 0x0000000010000000ULL, 0x0000000020000000ULL, 0x0000000040000000ULL, 0x0000000080000000ULL,
27 0x0000000100000000ULL, 0x0000000200000000ULL, 0x0000000400000000ULL, 0x0000000800000000ULL,
28 0x0000001000000000ULL, 0x0000002000000000ULL, 0x0000004000000000ULL, 0x0000008000000000ULL,
29 0x0000010000000000ULL, 0x0000020000000000ULL, 0x0000040000000000ULL, 0x0000080000000000ULL,
30 0x0000100000000000ULL, 0x0000200000000000ULL, 0x0000400000000000ULL, 0x0000800000000000ULL,
31 0x0001000000000000ULL, 0x0002000000000000ULL, 0x0004000000000000ULL, 0x0008000000000000ULL,
32 0x0010000000000000ULL, 0x0020000000000000ULL, 0x0040000000000000ULL, 0x0080000000000000ULL,
33 0x0100000000000000ULL, 0x0200000000000000ULL, 0x0400000000000000ULL, 0x0800000000000000ULL,
34 0x1000000000000000ULL, 0x2000000000000000ULL, 0x4000000000000000ULL, 0x8000000000000000ULL,
35 0, 0 // <- hack for passing move & nomove
36};
37
39const unsigned long long NEIGHBOUR[] = {
40 0x0000000000000302ULL, 0x0000000000000705ULL, 0x0000000000000e0aULL, 0x0000000000001c14ULL,
41 0x0000000000003828ULL, 0x0000000000007050ULL, 0x000000000000e0a0ULL, 0x000000000000c040ULL,
42 0x0000000000030203ULL, 0x0000000000070507ULL, 0x00000000000e0a0eULL, 0x00000000001c141cULL,
43 0x0000000000382838ULL, 0x0000000000705070ULL, 0x0000000000e0a0e0ULL, 0x0000000000c040c0ULL,
44 0x0000000003020300ULL, 0x0000000007050700ULL, 0x000000000e0a0e00ULL, 0x000000001c141c00ULL,
45 0x0000000038283800ULL, 0x0000000070507000ULL, 0x00000000e0a0e000ULL, 0x00000000c040c000ULL,
46 0x0000000302030000ULL, 0x0000000705070000ULL, 0x0000000e0a0e0000ULL, 0x0000001c141c0000ULL,
47 0x0000003828380000ULL, 0x0000007050700000ULL, 0x000000e0a0e00000ULL, 0x000000c040c00000ULL,
48 0x0000030203000000ULL, 0x0000070507000000ULL, 0x00000e0a0e000000ULL, 0x00001c141c000000ULL,
49 0x0000382838000000ULL, 0x0000705070000000ULL, 0x0000e0a0e0000000ULL, 0x0000c040c0000000ULL,
50 0x0003020300000000ULL, 0x0007050700000000ULL, 0x000e0a0e00000000ULL, 0x001c141c00000000ULL,
51 0x0038283800000000ULL, 0x0070507000000000ULL, 0x00e0a0e000000000ULL, 0x00c040c000000000ULL,
52 0x0302030000000000ULL, 0x0705070000000000ULL, 0x0e0a0e0000000000ULL, 0x1c141c0000000000ULL,
53 0x3828380000000000ULL, 0x7050700000000000ULL, 0xe0a0e00000000000ULL, 0xc040c00000000000ULL,
54 0x0203000000000000ULL, 0x0507000000000000ULL, 0x0a0e000000000000ULL, 0x141c000000000000ULL,
55 0x2838000000000000ULL, 0x5070000000000000ULL, 0xa0e0000000000000ULL, 0x40c0000000000000ULL,
56 0, 0 // <- hack for passing move & nomove
57};
58
72DLL_API int bit_count(unsigned long long b)
73{
74#if defined(POPCOUNT)
75
76 #if defined(USE_GAS_X64)
77 __asm__("popcntq %1,%0" :"=r" (b) :"rm" (b));
78 return (int) b;
79 #elif defined(USE_MSVC_X64)
80 return __popcnt64(b);
81 #elif defined(USE_GCC_X64)
82 return __builtin_popcountll(b);
83 #endif
84
85// MMX does not help much here :-(
86#elif defined (USE_GAS_MMX)
87
88 const unsigned long long M55 = 0x5555555555555555ULL;
89 const unsigned long long M33 = 0x3333333333333333ULL;
90 const unsigned long long M0F = 0x0F0F0F0F0F0F0F0FULL;
91 int count;
92
93 __asm__ volatile(
94 "movq %1, %%mm1\n\t"
95 "pxor %%mm2, %%mm2\n\t"
96
97 "movq %%mm1, %%mm0\n\t"
98 "psrlq $1, %%mm1\n\t"
99 "pand %2, %%mm1\n\t"
100 "psubd %%mm1, %%mm0\n\t"
101
102 "movq %%mm0, %%mm1\n\t"
103 "psrlq $2, %%mm0\n\t"
104 "pand %3, %%mm1\n\t"
105 "pand %3, %%mm0\n\t"
106 "paddd %%mm1, %%mm0\n\t"
107
108 "movq %%mm0, %%mm1\n\t"
109 "psrlq $4, %%mm0\n\t"
110 "paddd %%mm1, %%mm0\n\t"
111 "pand %4, %%mm0\n\t"
112
113 "psadbw %%mm2, %%mm0\n\t"
114 "movd %%mm0, %0\n\t"
115 "emms\n\t"
116 : "=a" (count) : "m" (b), "m" (M55), "m" (M33), "m" (M0F));
117
118 return count;
119
120#else
121
122 register unsigned long long c = b
123 - ((b >> 1) & 0x7777777777777777ULL)
124 - ((b >> 2) & 0x3333333333333333ULL)
125 - ((b >> 3) & 0x1111111111111111ULL);
126 c = ((c + (c >> 4)) & 0x0F0F0F0F0F0F0F0FULL) * 0x0101010101010101ULL;
127
128 return (int)(c >> 56);
129
130#endif
131}
132
133
143int bit_weighted_count(const unsigned long long v)
144{
145#if defined(POPCOUNT)
146
147 return bit_count(v) + bit_count(v & 0x8100000000000081ULL);
148
149#else
150
151 register unsigned long long b;
152 b = v - ((v >> 1) & 0x1555555555555515ULL) + (v & 0x0100000000000001ULL);
153 b = ((b >> 2) & 0x3333333333333333ULL) + (b & 0x3333333333333333ULL);
154 b = ((b >> 4) + b) & 0x0f0f0f0f0f0f0f0fULL;
155 b *= 0x0101010101010101ULL;
156
157 return (int)(b >> 56);
158
159#endif
160}
161
173DLL_API int first_bit(unsigned long long b)
174{
175#if defined(USE_GAS_X64)
176
177 __asm__("bsfq %1,%0" : "=r" (b) : "rm" (b));
178 return (int) b;
179
180#elif defined(USE_GAS_X86)
181
182 int x1, x2;
183 __asm__ ("bsf %0,%0\n"
184 "jnz 1f\n"
185 "bsf %1,%0\n"
186 "jz 1f\n"
187 "addl $32,%0\n"
188 "1:": "=&q" (x1), "=&q" (x2):"1" ((int) (b >> 32)), "0" ((int) b));
189 return x1;
190
191#elif defined(USE_MSVC_X64)
192
193 unsigned long index;
194 _BitScanForward64(&index, b);
195 return (int) index;
196
197#elif defined(USE_GCC_X64)
198
199 return __builtin_ctzll(b);
200
201#elif defined(USE_MASM_X86)
202 __asm {
203 xor eax, eax
204 bsf edx, dword ptr b
205 jnz l1
206 bsf edx, dword ptr b+4
207 mov eax, 32
208 jnz l1
209 mov edx, -32
210 l1: add eax, edx
211 }
212
213#elif defined(USE_GCC_ARM)
214 const unsigned int lb = (unsigned int)b;
215 if (lb) {
216 return __builtin_clz(lb & -lb) ^ 31;
217 } else {
218 const unsigned int hb = b >> 32;
219 return 32 + (__builtin_clz(hb & -hb) ^ 31);
220 }
221
222#else
223
224 const int magic[64] = {
225 63, 0, 58, 1, 59, 47, 53, 2,
226 60, 39, 48, 27, 54, 33, 42, 3,
227 61, 51, 37, 40, 49, 18, 28, 20,
228 55, 30, 34, 11, 43, 14, 22, 4,
229 62, 57, 46, 52, 38, 26, 32, 41,
230 50, 36, 17, 19, 29, 10, 13, 21,
231 56, 45, 25, 31, 35, 16, 9, 12,
232 44, 24, 15, 8, 23, 7, 6, 5
233 };
234
235 return magic[((b & (-b)) * 0x07EDD5E59A4E28C2ULL) >> 58];
236
237#endif
238}
239
248int next_bit(unsigned long long *b)
249{
250 *b &= *b - 1;
251 return first_bit(*b);
252}
253
264DLL_API int last_bit(unsigned long long b)
265{
266#if defined(USE_GAS_X64)
267
268 __asm__("bsrq %1,%0" :"=r" (b) :"rm" (b));
269 return b;
270
271#elif defined(USE_MSVC_X64)
272
273 unsigned long index;
274 _BitScanReverse64(&index, b);
275 return (int) index;
276
277#elif defined(USE_GCC_X64)
278
279 return 63 - __builtin_clzll(b);
280
281#elif defined(USE_GAS_X86)
282
283 int x1, x2;
284 __asm__ ("bsr %1,%0\n"
285 "jnz 1f\n"
286 "bsr %0,%0\n"
287 "subl $32,%0\n"
288 "1: addl $32,%0\n" : "=&q" (x1), "=&q" (x2) : "1" ((int) (b >> 32)), "0" ((int) b));
289 return x1;
290
291
292#elif defined(USE_GCC_ARM)
293 const unsigned int hb = b >> 32;
294 if (hb) {
295 return 63 - __builtin_clz(hb);
296 } else {
297 return 31 - __builtin_clz((int) b);
298 }
299
300
301#elif defined(USE_MASM_X86)
302 __asm {
303 xor eax, eax
304 bsr edx, dword ptr b+4
305 jnz l1
306 bsr edx, dword ptr b
307 mov eax, 32
308 jnz l1
309 mov edx, -32
310 l1: add eax, edx
311 }
312
313
314#else
315
316 const int magic[64] = {
317 63, 0, 58, 1, 59, 47, 53, 2,
318 60, 39, 48, 27, 54, 33, 42, 3,
319 61, 51, 37, 40, 49, 18, 28, 20,
320 55, 30, 34, 11, 43, 14, 22, 4,
321 62, 57, 46, 52, 38, 26, 32, 41,
322 50, 36, 17, 19, 29, 10, 13, 21,
323 56, 45, 25, 31, 35, 16, 9, 12,
324 44, 24, 15, 8, 23, 7, 6, 5
325 };
326
327 b |= b >> 1;
328 b |= b >> 2;
329 b |= b >> 4;
330 b |= b >> 8;
331 b |= b >> 16;
332 b |= b >> 32;
333 b = (b >> 1) + 1;
334
335 return magic[(b * 0x07EDD5E59A4E28C2ULL) >> 58];
336
337#endif
338}
339
345unsigned long long transpose(unsigned long long b)
346{
347 unsigned long long t;
348
349 t = (b ^ (b >> 7)) & 0x00aa00aa00aa00aaULL;
350 b = b ^ t ^ (t << 7);
351 t = (b ^ (b >> 14)) & 0x0000cccc0000ccccULL;
352 b = b ^ t ^ (t << 14);
353 t = (b ^ (b >> 28)) & 0x00000000f0f0f0f0ULL;
354 b = b ^ t ^ (t << 28);
355
356 return b;
357}
358
364unsigned long long vertical_mirror(unsigned long long b)
365{
366 b = ((b >> 8) & 0x00FF00FF00FF00FFULL) | ((b << 8) & 0xFF00FF00FF00FF00ULL);
367 b = ((b >> 16) & 0x0000FFFF0000FFFFULL) | ((b << 16) & 0xFFFF0000FFFF0000ULL);
368 b = ((b >> 32) & 0x00000000FFFFFFFFULL) | ((b << 32) & 0xFFFFFFFF00000000ULL);
369 return b;
370}
371
377unsigned long long horizontal_mirror(unsigned long long b)
378{
379 b = ((b >> 1) & 0x5555555555555555ULL) | ((b << 1) & 0xAAAAAAAAAAAAAAAAULL);
380 b = ((b >> 2) & 0x3333333333333333ULL) | ((b << 2) & 0xCCCCCCCCCCCCCCCCULL);
381 b = ((b >> 4) & 0x0F0F0F0F0F0F0F0FULL) | ((b << 4) & 0xF0F0F0F0F0F0F0F0ULL);
382
383 return b;
384}
385
391unsigned short bswap_short(unsigned short s)
392{
393 return (unsigned short) ((s >> 8) & 0x00FF) | ((s << 8) & 0xFF00);
394}
395
401unsigned int bswap_int(unsigned int i)
402{
403 i = ((i >> 8) & 0x00FF00FFU) | ((i << 8) & 0xFF00FF00U);
404 i = ((i >> 16) & 0x0000FFFFU) | ((i << 16) & 0xFFFF0000U);
405 return i;
406}
407
415int get_rand_bit(unsigned long long b, Random *r)
416{
417 int n = bit_count(b), x;
418
419 if (n == 0) return -1;
420
421 n = random_get(r) % n;
422 foreach_bit(x, b) if (n-- == 0) return x;
423
424 return -2; // impossible.
425}
426
435void bitboard_write(const unsigned long long b, FILE *f)
436{
437 int i, j, x;
438 const char *color = ".X";
439
440 fputs(" A B C D E F G H\n", f);
441 for (i = 0; i < 8; ++i) {
442 fputc(i + '1', f);
443 fputc(' ', f);
444 for (j = 0; j < 8; ++j) {
445 x = i * 8 + j;
446 fputc(color[((b >> (unsigned)x) & 1)], f);
447 fputc(' ', f);
448 }
449 fputc(i + '1', f);
450 fputc('\n', f);
451 }
452 fputs(" A B C D E F G H\n", f);
453}
454
455
456
457
458
DLL_API int bit_count(unsigned long long b)
Count the number of bits set to one in an unsigned long long.
Definition bit.c:72
void bitboard_write(const unsigned long long b, FILE *f)
Print an unsigned long long as a board.
Definition bit.c:435
unsigned long long transpose(unsigned long long b)
Transpose the unsigned long long (symetry % A1-H8 diagonal).
Definition bit.c:345
int get_rand_bit(unsigned long long b, Random *r)
Get a random set bit index.
Definition bit.c:415
unsigned long long horizontal_mirror(unsigned long long b)
Mirror the unsigned long long (exchange the line 1 - 8, 2 - 7, 3 - 6 & 4 - 5).
Definition bit.c:377
const unsigned long long NEIGHBOUR[]
Definition bit.c:39
unsigned long long vertical_mirror(unsigned long long b)
Mirror the unsigned long long (exchange the lines A - H, B - G, C - F & D - E.).
Definition bit.c:364
DLL_API int last_bit(unsigned long long b)
Search the last bit set (same as log2()).
Definition bit.c:264
const unsigned long long X_TO_BIT[]
Definition bit.c:18
int next_bit(unsigned long long *b)
Search the next bit set.
Definition bit.c:248
unsigned int bswap_int(unsigned int i)
Mirror the unsigned int (little <-> big endian).
Definition bit.c:401
int bit_weighted_count(const unsigned long long v)
count the number of discs, counting the corners twice.
Definition bit.c:143
unsigned short bswap_short(unsigned short s)
Swap bytes of a short (little <-> big endian).
Definition bit.c:391
DLL_API int first_bit(unsigned long long b)
Search the first bit set.
Definition bit.c:173
#define DLL_API
Definition bit.h:19
#define foreach_bit(i, b)
Definition bit.h:39
static int count(uint64 b)
Definition generate_count_flip.c:70
Definition util.h:87
unsigned long long random_get(Random *random)
Pseudo-random number generator.
Definition util.c:1043
Miscellaneous utilities header.