Fix force mode after setboard
[bonanza.git] / bitop.h
1 #ifndef BITOP_H
2 #define BITOP_H
3
4 #define BBToU(b)            ( (b).p[0] | (b).p[1] | (b).p[2] )
5 #define BBToUShift(b)       ( (b).p[0]<<2 | (b).p[1]<<1 | (b).p[2])
6 #define PopuCount(bb)       popu_count012( bb.p[0], bb.p[1], bb.p[2] )
7 #define FirstOne(bb)        first_one012( bb.p[0], bb.p[1], bb.p[2] )
8 #define LastOne(bb)         last_one210( bb.p[2], bb.p[1], bb.p[0] )
9 #define BBCmp(b1,b2)        ( (b1).p[0] != (b2).p[0]                    \
10                                 || (b1).p[1] != (b2).p[1]               \
11                                 || (b1).p[2] != (b2).p[2] )
12 #define BBContractShift(b1,b2) ( ( (b1).p[0] & (b2).p[0] ) << 2         \
13                                | ( (b1).p[1] & (b2).p[1] ) << 1         \
14                                | ( (b1).p[2] & (b2).p[2] ) )
15
16 #if defined(HAVE_SSE2) || defined(HAVE_SSE4)
17
18 #if defined(HAVE_SSE4)
19
20 #  include <smmintrin.h>
21
22 #  define BBContract(b1,b2) ( ! _mm_testz_si128( (b1).m, (b2).m ) )
23 #  define BBTest(b)         ( ! _mm_testz_si128( (b).m, _mm_set1_epi8(0xff) ) )
24
25
26 #else /* no SSE4 */
27
28 #  include <emmintrin.h>
29 #  define BBContract(b1,b2) ( ( (b1).p[0] & (b2).p[0] )                 \
30                             | ( (b1).p[1] & (b2).p[1] )                 \
31                             | ( (b1).p[2] & (b2).p[2] ) )
32 #  define BBTest(b)         ( (b).p[0] | (b).p[1] | (b).p[2] )
33
34 #endif /* HAVE_SSE4 */
35
36 #define BBNot(b,b1)         (b).m = _mm_andnot_si128( (b1).m,                 \
37                                                       _mm_set1_epi8(0xff) )
38 #define BBIni(b)            (b).m = _mm_setzero_si128()
39 #define BBAnd(b,b1,b2)      (b).m = _mm_and_si128( (b1).m, (b2).m )
40 #define BBOr(b,b1,b2)       (b).m = _mm_or_si128( (b1).m, (b2).m )
41 #define BBXor(b,b1,b2)      (b).m = _mm_xor_si128( (b1).m, (b2).m )
42 #define BBAndOr(b,b1,b2)    (b).m = _mm_or_si128( (b).m,                      \
43                                     _mm_and_si128( (b1).m, (b2).m ) )
44 #define BBNotAnd(b,b1,b2)   (b).m = _mm_andnot_si128( (b2).m, (b1).m )
45 #define Xor(sq,b)           (b).m = _mm_xor_si128( (b).m, abb_mask[sq].m )
46 #define XorFile(sq,b)       (b).m = _mm_xor_si128( (b).m, abb_mask_rl90[sq].m )
47 #define XorDiag1(sq,b)      (b).m = _mm_xor_si128( (b).m, abb_mask_rr45[sq].m )
48 #define XorDiag2(sq,b)      (b).m = _mm_xor_si128( (b).m, abb_mask_rl45[sq].m )
49 #define SetClear(b)         (b).m = _mm_xor_si128( (b).m, bb_set_clear.m )
50 #define SetClearFile(sq1,sq2,b)  (b).m= _mm_xor_si128( (b).m,                 \
51                                         _mm_or_si128( abb_mask_rl90[sq1].m,   \
52                                                       abb_mask_rl90[sq2].m ) )
53 #define SetClearDiag1(sq1,sq2,b) (b).m= _mm_xor_si128( (b).m,                 \
54                                         _mm_or_si128( abb_mask_rr45[sq1].m,   \
55                                                       abb_mask_rr45[sq2].m ) )
56 #define SetClearDiag2(sq1,sq2,b) (b).m= _mm_xor_si128( (b).m,                 \
57                                         _mm_or_si128( abb_mask_rl45[sq1].m,   \
58                                                       abb_mask_rl45[sq2].m ) )
59
60 typedef union {
61   unsigned int p[4];
62   __m128i m;
63 } bitboard_t;
64
65 #else /* NO SSE2 */
66
67 #define BBTest(b)           ( (b).p[0] | (b).p[1] | (b).p[2] )
68 #define BBIni(b)            (b).p[0] = (b).p[1] = (b).p[2] = 0
69 #define BBNot(b,b1)         (b).p[0] = ~(b1).p[0],                      \
70                             (b).p[1] = ~(b1).p[1],                      \
71                             (b).p[2] = ~(b1).p[2]
72 #define BBAnd(b,b1,b2)      (b).p[0] = (b1).p[0] & (b2).p[0],           \
73                             (b).p[1] = (b1).p[1] & (b2).p[1],           \
74                             (b).p[2] = (b1).p[2] & (b2).p[2]
75 #define BBOr(b,b1,b2)       (b).p[0] = (b1).p[0] | (b2).p[0],           \
76                             (b).p[1] = (b1).p[1] | (b2).p[1],           \
77                             (b).p[2] = (b1).p[2] | (b2).p[2]
78 #define BBXor(b,b1,b2)      (b).p[0] = (b1).p[0] ^ (b2).p[0],           \
79                             (b).p[1] = (b1).p[1] ^ (b2).p[1],           \
80                             (b).p[2] = (b1).p[2] ^ (b2).p[2]
81 #define BBAndOr(b,b1,b2)    (b).p[0] |= (b1).p[0] & (b2).p[0],          \
82                             (b).p[1] |= (b1).p[1] & (b2).p[1],          \
83                             (b).p[2] |= (b1).p[2] & (b2).p[2]
84 #define BBNotAnd(b,b1,b2)   (b).p[0] = (b1).p[0] & ~(b2).p[0],          \
85                             (b).p[1] = (b1).p[1] & ~(b2).p[1],          \
86                             (b).p[2] = (b1).p[2] & ~(b2).p[2]
87 #define BBContract(b1,b2)   ( ( (b1).p[0] & (b2).p[0] )                 \
88                             | ( (b1).p[1] & (b2).p[1] )                 \
89                             | ( (b1).p[2] & (b2).p[2] ) )
90 #define Xor(sq,b)           (b).p[0] ^= abb_mask[sq].p[0],              \
91                             (b).p[1] ^= abb_mask[sq].p[1],              \
92                             (b).p[2] ^= abb_mask[sq].p[2]
93 #define XorFile(sq,b)       (b).p[0] ^= abb_mask_rl90[sq].p[0],         \
94                             (b).p[1] ^= abb_mask_rl90[sq].p[1],         \
95                             (b).p[2] ^= abb_mask_rl90[sq].p[2]
96 #define XorDiag1(sq,b)      (b).p[0] ^= abb_mask_rr45[sq].p[0],         \
97                             (b).p[1] ^= abb_mask_rr45[sq].p[1],         \
98                             (b).p[2] ^= abb_mask_rr45[sq].p[2]
99 #define XorDiag2(sq,b)      (b).p[0] ^= abb_mask_rl45[sq].p[0],         \
100                             (b).p[1] ^= abb_mask_rl45[sq].p[1],         \
101                             (b).p[2] ^= abb_mask_rl45[sq].p[2]
102 #define SetClear(b)         (b).p[0] ^= (bb_set_clear.p[0]),            \
103                             (b).p[1] ^= (bb_set_clear.p[1]),            \
104                             (b).p[2] ^= (bb_set_clear.p[2])
105 #define SetClearFile(sq1,sq2,b)                                         \
106     (b).p[0] ^= ( abb_mask_rl90[sq1].p[0] | abb_mask_rl90[sq2].p[0] ),  \
107     (b).p[1] ^= ( abb_mask_rl90[sq1].p[1] | abb_mask_rl90[sq2].p[1] ),  \
108     (b).p[2] ^= ( abb_mask_rl90[sq1].p[2] | abb_mask_rl90[sq2].p[2] )
109
110 #define SetClearDiag1(sq1,sq2,b) \
111     (b).p[0] ^= ((abb_mask_rr45[sq1].p[0])|(abb_mask_rr45[sq2].p[0])), \
112     (b).p[1] ^= ((abb_mask_rr45[sq1].p[1])|(abb_mask_rr45[sq2].p[1])), \
113     (b).p[2] ^= ((abb_mask_rr45[sq1].p[2])|(abb_mask_rr45[sq2].p[2]))
114
115 #define SetClearDiag2(sq1,sq2,b) \
116     (b).p[0] ^= ((abb_mask_rl45[sq1].p[0])|(abb_mask_rl45[sq2].p[0])), \
117     (b).p[1] ^= ((abb_mask_rl45[sq1].p[1])|(abb_mask_rl45[sq2].p[1])), \
118     (b).p[2] ^= ((abb_mask_rl45[sq1].p[2])|(abb_mask_rl45[sq2].p[2]))
119
120
121
122 typedef struct { unsigned int p[3]; } bitboard_t;
123
124 #endif /* HAVE_SSE2 */
125
126 #endif /* BITOP_H */