aboutsummaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/arch.h3
-rw-r--r--src/arch/avx2.h84
-rw-r--r--src/arch/common.h5
-rw-r--r--src/arch/coordinates_unoptimized.h53
-rw-r--r--src/arch/neon.h86
-rw-r--r--src/arch/portable.h44
6 files changed, 212 insertions, 63 deletions
diff --git a/src/arch/arch.h b/src/arch/arch.h
index d0ef20c..aa4a5c5 100644
--- a/src/arch/arch.h
+++ b/src/arch/arch.h
@@ -7,7 +7,6 @@ typedef __m256i cube_t;
7#if !defined(TEST_H) 7#if !defined(TEST_H)
8#include "common.h" 8#include "common.h"
9#include "avx2.h" 9#include "avx2.h"
10#include "coordinates_unoptimized.h"
11#endif 10#endif
12 11
13#elif defined(NEON) 12#elif defined(NEON)
@@ -22,7 +21,6 @@ typedef struct {
22#if !defined(TEST_H) 21#if !defined(TEST_H)
23#include "common.h" 22#include "common.h"
24#include "neon.h" 23#include "neon.h"
25#include "coordinates_unoptimized.h"
26#endif 24#endif
27 25
28#else 26#else
@@ -35,7 +33,6 @@ typedef struct {
35#if !defined(TEST_H) 33#if !defined(TEST_H)
36#include "common.h" 34#include "common.h"
37#include "portable.h" 35#include "portable.h"
38#include "coordinates_unoptimized.h"
39#endif 36#endif
40 37
41#endif 38#endif
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}
diff --git a/src/arch/common.h b/src/arch/common.h
index 922ea51..3e7867d 100644
--- a/src/arch/common.h
+++ b/src/arch/common.h
@@ -37,6 +37,11 @@ STATIC_INLINE void set_eo(cube_t [static 1], int64_t);
37STATIC_INLINE void invcoord_esep_array(int64_t, int64_t, uint8_t[static 12]); 37STATIC_INLINE void invcoord_esep_array(int64_t, int64_t, uint8_t[static 12]);
38STATIC_INLINE cube_t invcoord_eoesep(int64_t); 38STATIC_INLINE cube_t invcoord_eoesep(int64_t);
39 39
40STATIC_INLINE int64_t coord_cp(cube_t);
41STATIC_INLINE cube_t invcoord_cp(int64_t);
42STATIC_INLINE int64_t coord_epud(cube_t);
43STATIC_INLINE cube_t invcoord_epud(int64_t);
44
40STATIC_INLINE void 45STATIC_INLINE void
41invcoord_esep_array(int64_t set1, int64_t set2, uint8_t mem[static 12]) 46invcoord_esep_array(int64_t set1, int64_t set2, uint8_t mem[static 12])
42{ 47{
diff --git a/src/arch/coordinates_unoptimized.h b/src/arch/coordinates_unoptimized.h
deleted file mode 100644
index de76018..0000000
--- a/src/arch/coordinates_unoptimized.h
+++ /dev/null
@@ -1,53 +0,0 @@
1STATIC_INLINE int64_t coord_cp(cube_t);
2STATIC_INLINE cube_t invcoord_cp(int64_t);
3STATIC_INLINE int64_t coord_epud(cube_t);
4STATIC_INLINE cube_t invcoord_epud(int64_t);
5
6STATIC_INLINE int64_t
7coord_cp(cube_t cube)
8{
9 int i;
10 uint8_t c[8], e[12];
11
12 pieces(&cube, c, e);
13 for (i = 0; i < 8; i++)
14 c[i] &= PBITS;
15
16 return permtoindex(8, c);
17}
18
19STATIC_INLINE cube_t
20invcoord_cp(int64_t i)
21{
22 uint8_t c[8];
23
24 indextoperm(i, 8, c);
25
26 return STATIC_CUBE(c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7],
27 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
28}
29
30STATIC_INLINE int64_t
31coord_epud(cube_t cube)
32{
33 int i;
34 uint8_t c[8], e[12];
35
36 pieces(&cube, c, e);
37
38 for (i = 0; i < 8; i++)
39 e[i] &= PBITS;
40
41 return permtoindex(8, e);
42}
43
44STATIC_INLINE cube_t
45invcoord_epud(int64_t i)
46{
47 uint8_t e[8];
48
49 indextoperm(i, 8, e);
50
51 return STATIC_CUBE(0, 1, 2, 3, 4, 5, 6, 7,
52 e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], 8, 9, 10, 11);
53}
diff --git a/src/arch/neon.h b/src/arch/neon.h
index 1fb1c82..a378cf9 100644
--- a/src/arch/neon.h
+++ b/src/arch/neon.h
@@ -1,8 +1,6 @@
1#define CO2_NEON vdup_n_u8(0x60) 1#define CO2_NEON vdup_n_u8(0x60)
2#define COCW_NEON vdup_n_u8(0x20) 2#define COCW_NEON vdup_n_u8(0x20)
3#define CP_NEON vdup_n_u8(0x07) 3#define PBITS8_NEON vdup_n_u8(0x07)
4#define EP_NEON vcombine_u8(vdupq_n_u8(0x0F), vdupq_n_u8(0x0F))
5#define EO_NEON vcombine_u8(vdupq_n_u8(0x10), vdupq_n_u8(0x10))
6 4
7STATIC_INLINE uint8x16_t compose_edges_slim(uint8x16_t, uint8x16_t); 5STATIC_INLINE uint8x16_t compose_edges_slim(uint8x16_t, uint8x16_t);
8STATIC_INLINE uint8x8_t compose_corners_slim(uint8x8_t, uint8x8_t); 6STATIC_INLINE uint8x8_t compose_corners_slim(uint8x8_t, uint8x8_t);
@@ -20,16 +18,20 @@ STATIC_INLINE uint8x8_t compose_corners_slim(uint8x8_t, uint8x8_t);
20 e_dl, e_dr, e_fr, e_fl, e_bl, e_br, 0, 0, 0, 0 \ 18 e_dl, e_dr, e_fr, e_fl, e_bl, e_br, 0, 0, 0, 0 \
21 } \ 19 } \
22 }) 20 })
23
24#define ZERO_CUBE \ 21#define ZERO_CUBE \
25 ((cube_t){ \ 22 ((cube_t){ \
26 .corner = vdup_n_u8(0), \ 23 .corner = vdup_n_u8(0), \
27 .edge = vdupq_n_u8(0) \ 24 .edge = vdupq_n_u8(0) \
28 }) 25 })
29
30#define SOLVED_CUBE STATIC_CUBE( \ 26#define SOLVED_CUBE STATIC_CUBE( \
31 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) 27 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
32 28
29const uint8_t SOLVED_L[8] = {0, 1, 2, 3, 4, 5, 6, 7};
30const uint8_t SOLVED_H[8] = {8, 9, 10, 11, 0, 0, 0};
31
32STATIC_INLINE int64_t permtoindex_8x8(uint8x8_t);
33STATIC_INLINE uint8x8_t indextoperm_8x8(int64_t);
34
33STATIC_INLINE int 35STATIC_INLINE int
34popcount_u32(uint32_t x) 36popcount_u32(uint32_t x)
35{ 37{
@@ -361,3 +363,77 @@ invcoord_esep(int64_t esep)
361 363
362 return ret; 364 return ret;
363} 365}
366
367STATIC_INLINE int64_t
368permtoindex_8x8(uint8x8_t a)
369{
370 int64_t i, c, ret;
371 uint8x8_t cmp;
372 uint64x1_t anum;
373 uint8_t or[8] = {0, 0, 0, 0, 0, 0, 0, 0x0F};
374
375 for (i = 0, ret = 0; i < 8; i++) {
376 cmp = vdup_lane_u8(a, 0);
377 anum = vreinterpret_u64_u8(a);
378 anum = vshr_n_u64(anum, 8);
379 a = vreinterpret_u8_u64(anum);
380 a = vorr_u8(a, vld1_u8(or));
381 cmp = vcgt_u8(cmp, a);
382 c = vaddv_u8(vshr_n_u8(cmp, 7));
383 ret += c * factorial[7-i];
384 }
385
386 return ret;
387}
388
389STATIC_INLINE uint8x8_t
390indextoperm_8x8(int64_t p)
391{
392 int used;
393 int64_t c, k, i, j;
394 uint8_t ret[8];
395
396 for (i = 0, used = 0; i < 8; i++) {
397 k = p / factorial[7-i];
398
399 /* Find k-th unused number */
400 for (j = 0, c = 0; c <= k; j++)
401 c += 1 - ((used & (1 << j)) >> j);
402
403 ret[i] = j-1;
404 used |= 1 << (j-1);
405 p %= factorial[7-i];
406 }
407
408 return vld1_u8(ret);
409}
410
411STATIC_INLINE int64_t
412coord_cp(cube_t cube)
413{
414 return permtoindex_8x8(vand_u8(cube.corner, PBITS8_NEON));
415}
416
417STATIC_INLINE cube_t
418invcoord_cp(int64_t i)
419{
420 return (cube_t) {
421 .corner = indextoperm_8x8(i),
422 .edge = vcombine_u8(vld1_u8(SOLVED_L), vld1_u8(SOLVED_H))
423 };
424}
425
426STATIC_INLINE int64_t
427coord_epud(cube_t cube)
428{
429 return permtoindex_8x8(vand_u8(vget_low_u8(cube.edge), PBITS8_NEON));
430}
431
432STATIC_INLINE cube_t
433invcoord_epud(int64_t i)
434{
435 return (cube_t) {
436 .corner = vld1_u8(SOLVED_L),
437 .edge = vcombine_u8(indextoperm_8x8(i), vld1_u8(SOLVED_H))
438 };
439}
diff --git a/src/arch/portable.h b/src/arch/portable.h
index bd67c18..ec992a8 100644
--- a/src/arch/portable.h
+++ b/src/arch/portable.h
@@ -290,3 +290,47 @@ set_eo(cube_t cube[static 1], int64_t eo)
290 } 290 }
291 cube->edge[0] = (cube->edge[0] & ~EOBIT) | (EOBIT * (sum % 2)); 291 cube->edge[0] = (cube->edge[0] & ~EOBIT) | (EOBIT * (sum % 2));
292} 292}
293
294STATIC_INLINE int64_t
295coord_cp(cube_t cube)
296{
297 int i;
298
299 for (i = 0; i < 8; i++)
300 cube.corner[i] &= PBITS;
301
302 return permtoindex(8, cube.corner);
303}
304
305STATIC_INLINE cube_t
306invcoord_cp(int64_t i)
307{
308 uint8_t c[8];
309
310 indextoperm(i, 8, c);
311
312 return STATIC_CUBE(c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7],
313 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
314}
315
316STATIC_INLINE int64_t
317coord_epud(cube_t cube)
318{
319 int i;
320
321 for (i = 0; i < 8; i++)
322 cube.edge[i] &= PBITS;
323
324 return permtoindex(8, cube.edge);
325}
326
327STATIC_INLINE cube_t
328invcoord_epud(int64_t i)
329{
330 uint8_t e[8];
331
332 indextoperm(i, 8, e);
333
334 return STATIC_CUBE(0, 1, 2, 3, 4, 5, 6, 7,
335 e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], 8, 9, 10, 11);
336}

Generated with cgit - Back to sebastiano.tronto.net