aboutsummaryrefslogtreecommitdiff
path: root/src/arch/neon.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/neon.h')
-rw-r--r--src/arch/neon.h86
1 files changed, 81 insertions, 5 deletions
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}

Generated with cgit - Back to sebastiano.tronto.net