aboutsummaryrefslogtreecommitdiff
path: root/src/arch/avx2.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/avx2.h')
-rw-r--r--src/arch/avx2.h84
1 files changed, 82 insertions, 2 deletions
diff --git a/src/arch/avx2.h b/src/arch/avx2.h
index b1f8a59..7764c6b 100644
--- a/src/arch/avx2.h
+++ b/src/arch/avx2.h
@@ -12,6 +12,9 @@
12#define CARRY_AVX2 _mm256_set_epi64x(INT64_C(0x20202020), \ 12#define CARRY_AVX2 _mm256_set_epi64x(INT64_C(0x20202020), \
13 INT64_C(0x2020202020202020), 0, INT64_C(0x6060606060606060)) 13 INT64_C(0x2020202020202020), 0, INT64_C(0x6060606060606060))
14 14
15#define SOLVED_L INT64_C(0x0706050403020100)
16#define SOLVED_H INT64_C(0x0B0A0908)
17
15#define STATIC_CUBE(c_ufr, c_ubl, c_dfl, c_dbr, c_ufl, c_ubr, c_dfr, c_dbl, \ 18#define STATIC_CUBE(c_ufr, c_ubl, c_dfl, c_dbr, c_ufl, c_ubr, c_dfr, c_dbl, \
16 e_uf, e_ub, e_db, e_df, e_ur, e_ul, e_dl, e_dr, e_fr, e_fl, e_bl, e_br) \ 19 e_uf, e_ub, e_db, e_df, e_ur, e_ul, e_dl, e_dr, e_fr, e_fl, e_bl, e_br) \
17 _mm256_set_epi8(0, 0, 0, 0, e_br, e_bl, e_fl, e_fr, \ 20 _mm256_set_epi8(0, 0, 0, 0, e_br, e_bl, e_fl, e_fr, \
@@ -19,8 +22,11 @@
19 0, 0, 0, 0, 0, 0, 0, 0, \ 22 0, 0, 0, 0, 0, 0, 0, 0, \
20 c_dbl, c_dfr, c_ubr, c_ufl, c_dbr, c_dfl, c_ubl, c_ufr) 23 c_dbl, c_dfr, c_ubr, c_ufl, c_dbr, c_dfl, c_ubl, c_ufr)
21#define ZERO_CUBE _mm256_set_epi64x(0, 0, 0, 0) 24#define ZERO_CUBE _mm256_set_epi64x(0, 0, 0, 0)
22#define SOLVED_CUBE STATIC_CUBE( \ 25#define SOLVED_CUBE _mm256_set_epi64x(SOLVED_H, SOLVED_L, 0, SOLVED_L)
23 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) 26
27
28STATIC_INLINE int64_t permtoindex_8x8(int64_t);
29STATIC_INLINE int64_t indextoperm_8x8(int64_t);
24 30
25STATIC_INLINE int 31STATIC_INLINE int
26popcount_u32(uint32_t x) 32popcount_u32(uint32_t x)
@@ -287,3 +293,77 @@ set_eo(cube_t cube[static 1], int64_t eo)
287 *cube = _mm256_andnot_si256(EO_AVX2, *cube); 293 *cube = _mm256_andnot_si256(EO_AVX2, *cube);
288 *cube = _mm256_or_si256(*cube, veo); 294 *cube = _mm256_or_si256(*cube, veo);
289} 295}
296
297STATIC_INLINE int64_t
298permtoindex_8x8(int64_t a)
299{
300 int64_t i, c, ret;
301 __m64 cmp;
302
303 for (i = 0, ret = 0; i < 8; i++) {
304 cmp = _mm_set1_pi8(a & INT64_C(0xFF));
305 a = (a >> INT64_C(8)) | INT64_C(0x0F00000000000000);
306 cmp = _mm_cmpgt_pi8(cmp, _mm_cvtsi64_m64(a));
307 c = _mm_popcnt_u64(_mm_cvtm64_si64(cmp)) >> INT64_C(3);
308 ret += c * factorial[7-i];
309 }
310
311 return ret;
312}
313
314STATIC_INLINE int64_t
315indextoperm_8x8(int64_t p)
316{
317 int used;
318 int64_t c, k, i, j, ret;
319
320 for (i = 0, ret = 0, used = 0; i < 8; i++) {
321 k = p / factorial[7-i];
322
323 /* Find k-th unused number */
324 for (j = 0, c = 0; c <= k; j++)
325 c += 1 - ((used & (1 << j)) >> j);
326
327 ret |= (j-1) << (8*i);
328 used |= 1 << (j-1);
329 p %= factorial[7-i];
330 }
331
332 return ret;
333}
334
335STATIC_INLINE int64_t
336coord_cp(cube_t cube)
337{
338 cube_t cp;
339 int64_t aux[4];
340
341 cp = _mm256_and_si256(cube, CP_AVX2);
342 _mm256_storeu_si256((__m256i_u *)aux, cp);
343
344 return permtoindex_8x8(aux[0]);
345}
346
347STATIC_INLINE cube_t
348invcoord_cp(int64_t i)
349{
350 return _mm256_set_epi64x(SOLVED_H, SOLVED_L, 0, indextoperm_8x8(i));
351}
352
353STATIC_INLINE int64_t
354coord_epud(cube_t cube)
355{
356 cube_t ep;
357 int64_t aux[4];
358
359 ep = _mm256_and_si256(cube, EP_AVX2);
360 _mm256_storeu_si256((__m256i_u *)aux, ep);
361
362 return permtoindex_8x8(aux[2]);
363}
364
365STATIC_INLINE cube_t
366invcoord_epud(int64_t i)
367{
368 return _mm256_set_epi64x(SOLVED_H, indextoperm_8x8(i), 0, SOLVED_L);
369}

Generated with cgit - Back to sebastiano.tronto.net