aboutsummaryrefslogtreecommitdiff
path: root/src/cube_avx2.h
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2024-05-10 09:10:12 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2024-05-10 09:10:12 +0200
commita660922d738b78b11fc78207daabea031058f710 (patch)
treedb46bd95bffeb330cea6066c77f2709f96c033aa /src/cube_avx2.h
parent75966319fd5891c2c1bd35b1f7c93eab172fd28e (diff)
downloadnissy-core-a660922d738b78b11fc78207daabea031058f710.tar.gz
nissy-core-a660922d738b78b11fc78207daabea031058f710.zip
Split into .h files
Diffstat (limited to 'src/cube_avx2.h')
-rw-r--r--src/cube_avx2.h229
1 files changed, 229 insertions, 0 deletions
diff --git a/src/cube_avx2.h b/src/cube_avx2.h
new file mode 100644
index 0000000..c61813f
--- /dev/null
+++ b/src/cube_avx2.h
@@ -0,0 +1,229 @@
1typedef __m256i cube_fast_t;
2
3#define _co2_avx2 _mm256_set_epi64x(0, 0, 0, 0x6060606060606060)
4#define _cocw_avx2 _mm256_set_epi64x(0, 0, 0, 0x2020202020202020)
5#define _cp_avx2 _mm256_set_epi64x(0, 0, 0, 0x0707070707070707)
6#define _ep_avx2 _mm256_set_epi64x(0x0F0F0F0F, 0x0F0F0F0F0F0F0F0F, 0, 0)
7#define _eo_avx2 _mm256_set_epi64x(0x10101010, 0x1010101010101010, 0, 0)
8
9_static_inline cube_fast_t fastcube(
10 uint8_t, uint8_t, uint8_t, uint8_t, uint8_t,
11 uint8_t, uint8_t, uint8_t, uint8_t, uint8_t,
12 uint8_t, uint8_t, uint8_t, uint8_t, uint8_t,
13 uint8_t, uint8_t, uint8_t, uint8_t, uint8_t
14);
15_static cube_fast_t cubetofast(cube_t);
16_static cube_t fasttocube(cube_fast_t);
17_static_inline bool equal_fast(cube_fast_t, cube_fast_t);
18_static_inline bool issolved_fast(cube_fast_t);
19_static_inline cube_fast_t invertco_fast(cube_fast_t);
20_static_inline cube_fast_t compose_fast(cube_fast_t, cube_fast_t);
21
22_static_inline int64_t coord_fast_co(cube_fast_t);
23_static_inline int64_t coord_fast_csep(cube_fast_t);
24_static_inline int64_t coord_fast_cocsep(cube_fast_t);
25_static_inline int64_t coord_fast_eo(cube_fast_t);
26_static_inline int64_t coord_fast_esep(cube_fast_t);
27
28_static_inline cube_fast_t
29fastcube(
30 uint8_t c_ufr,
31 uint8_t c_ubl,
32 uint8_t c_dfl,
33 uint8_t c_dbr,
34 uint8_t c_ufl,
35 uint8_t c_ubr,
36 uint8_t c_dfr,
37 uint8_t c_dbl,
38
39 uint8_t e_uf,
40 uint8_t e_ub,
41 uint8_t e_db,
42 uint8_t e_df,
43 uint8_t e_ur,
44 uint8_t e_ul,
45 uint8_t e_dl,
46 uint8_t e_dr,
47 uint8_t e_fr,
48 uint8_t e_fl,
49 uint8_t e_bl,
50 uint8_t e_br
51)
52{
53 return _mm256_set_epi8(
54 0, 0, 0, 0, e_br, e_bl, e_fl, e_fr,
55 e_dr, e_dl, e_ul, e_ur, e_df, e_db, e_ub, e_uf,
56 0, 0, 0, 0, 0, 0, 0, 0,
57 c_dbl, c_dfr, c_ubr, c_ufl, c_dbr, c_dfl, c_ubl, c_ufr
58 );
59}
60
61_static cube_fast_t
62cubetofast(cube_t a)
63{
64 uint8_t aux[32];
65
66 memset(aux, 0, 32);
67 memcpy(aux, &a.corner, 8);
68 memcpy(aux + 16, &a.edge, 12);
69
70 return _mm256_loadu_si256((__m256i_u *)&aux);
71}
72
73_static cube_t
74fasttocube(cube_fast_t c)
75{
76 cube_t a;
77 uint8_t aux[32];
78
79 _mm256_storeu_si256((__m256i_u *)aux, c);
80 memcpy(&a.corner, aux, 8);
81 memcpy(&a.edge, aux + 16, 12);
82
83 return a;
84}
85
86_static_inline bool
87equal_fast(cube_fast_t c1, cube_fast_t c2)
88{
89 int32_t mask;
90 __m256i cmp;
91
92 cmp = _mm256_cmpeq_epi8(c1, c2);
93 mask = _mm256_movemask_epi8(cmp);
94
95 return mask == ~0;
96}
97
98_static_inline bool
99issolved_fast(cube_fast_t cube)
100{
101 return equal_fast(cube, solved_fast);
102}
103
104_static_inline cube_fast_t
105invertco_fast(cube_fast_t c)
106{
107 cube_fast_t co, shleft, shright, summed, newco, cleanco, ret;
108
109 co = _mm256_and_si256(c, _co2_avx2);
110 shleft = _mm256_slli_epi32(co, 1);
111 shright = _mm256_srli_epi32(co, 1);
112 summed = _mm256_or_si256(shleft, shright);
113 newco = _mm256_and_si256(summed, _co2_avx2);
114 cleanco = _mm256_xor_si256(c, co);
115 ret = _mm256_or_si256(cleanco, newco);
116
117 return ret;
118}
119
120_static_inline cube_fast_t
121compose_fast(cube_fast_t c1, cube_fast_t c2)
122{
123 cube_fast_t s, b, eo2, co1, co2, aux, auy1, auy2, auz1, auz2;
124
125 /* Permute and clean unused bits */
126 s = _mm256_shuffle_epi8(c1, c2);
127 b = _mm256_set_epi8(
128 ~0, ~0, ~0, ~0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
129 ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, 0, 0, 0, 0, 0, 0, 0, 0
130 );
131 s = _mm256_andnot_si256(b, s);
132
133 /* Change EO */
134 eo2 = _mm256_and_si256(c2, _eo_avx2);
135 s = _mm256_xor_si256(s, eo2);
136
137 /* Change CO */
138 co1 = _mm256_and_si256(s, _co2_avx2);
139 co2 = _mm256_and_si256(c2, _co2_avx2);
140 aux = _mm256_add_epi8(co1, co2);
141 auy1 = _mm256_add_epi8(aux, _cocw_avx2);
142 auy2 = _mm256_srli_epi32(auy1, 2);
143 auz1 = _mm256_add_epi8(aux, auy2);
144 auz2 = _mm256_and_si256(auz1, _co2_avx2);
145
146 /* Put together */
147 s = _mm256_andnot_si256(_co2_avx2, s);
148 s = _mm256_or_si256(s, auz2);
149
150 return s;
151}
152
153_static_inline int64_t
154coord_fast_co(cube_fast_t c)
155{
156 cube_fast_t co;
157 int64_t mem[4], ret, i, p;
158
159 co = _mm256_and_si256(c, _co2_avx2);
160 _mm256_storeu_si256((__m256i *)mem, co);
161
162 mem[0] >>= 5L;
163 for (i = 0, ret = 0, p = 1; i < 7; i++, mem[0] >>= 8L, p *= 3)
164 ret += (mem[0] & 3L) * p;
165
166 return ret;
167}
168
169_static_inline int64_t
170coord_fast_csep(cube_fast_t c)
171{
172 cube_fast_t cp, shifted;
173 int64_t mask;
174
175 cp = _mm256_and_si256(c, _cp_avx2);
176 shifted = _mm256_slli_epi32(cp, 5);
177 mask = _mm256_movemask_epi8(shifted);
178
179 return mask & 0x7F;
180}
181
182_static_inline int64_t
183coord_fast_cocsep(cube_fast_t c)
184{
185 return (coord_fast_co(c) << 7) + coord_fast_csep(c);
186}
187
188_static_inline int64_t
189coord_fast_eo(cube_fast_t c)
190{
191 cube_fast_t eo, shifted;
192 int64_t mask;
193
194 eo = _mm256_and_si256(c, _eo_avx2);
195 shifted = _mm256_slli_epi32(eo, 3);
196 mask = _mm256_movemask_epi8(shifted);
197
198 return mask >> 17;
199}
200
201_static_inline int64_t
202coord_fast_esep(cube_fast_t c)
203{
204 cube_fast_t ep;
205 int64_t e, mem[4], i, j, k, l, ret1, ret2, bit1, bit2, is1;
206
207 ep = _mm256_and_si256(c, _ep_avx2);
208 _mm256_storeu_si256((__m256i *)mem, ep);
209
210 mem[3] <<= 8L;
211 ret1 = ret2 = 0;
212 k = l = 4;
213 for (i = 0, j = 0; i < 12; i++, mem[i/8 + 2] >>= 8L) {
214 e = mem[i/8 + 2];
215
216 bit1 = (e & _esepbit1) >> 2L;
217 bit2 = (e & _esepbit2) >> 3L;
218 is1 = (1 - bit2) * bit1;
219
220 ret1 += bit2 * binomial[11-i][k];
221 k -= bit2;
222
223 ret2 += is1 * binomial[7-j][l];
224 l -= is1;
225 j += (1-bit2);
226 }
227
228 return ret1 * 70 + ret2;
229}

Generated with cgit - Back to sebastiano.tronto.net