aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cube_neon.h44
1 files changed, 16 insertions, 28 deletions
diff --git a/src/cube_neon.h b/src/cube_neon.h
index fadc58d..23e5565 100644
--- a/src/cube_neon.h
+++ b/src/cube_neon.h
@@ -5,6 +5,12 @@ typedef struct
5 uint8x16_t edge; 5 uint8x16_t edge;
6} cube_t; 6} cube_t;
7 7
8#define _co2_neon vdupq_n_u8(0x60)
9#define _cocw_neon vdupq_n_u8(0x20)
10#define _cp_neon vdupq_n_u8(0x07)
11#define _ep_neon vcombine_u8(vdupq_n_u8(0x0F), vdupq_n_u8(0x0F))
12#define _eo_neon vcombine_u8(vdupq_n_u8(0x10), vdupq_n_u8(0x10))
13
8// static cube 14// static cube
9#define static_cube(c_ufr, c_ubl, c_dfl, c_dbr, c_ufl, c_ubr, c_dfr, c_dbl, \ 15#define static_cube(c_ufr, c_ubl, c_dfl, c_dbr, c_ufl, c_ubr, c_dfr, c_dbl, \
10 e_uf, e_ub, e_db, e_df, e_ur, e_ul, e_dl, e_dr, e_fr, e_fl, e_bl, e_br) \ 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) \
@@ -82,39 +88,21 @@ equal(cube_t c1, cube_t c2)
82 return vgetq_lane_u64(cmp_result, 0) == ~0ULL && vgetq_lane_u64(cmp_result, 1) == ~0ULL; 88 return vgetq_lane_u64(cmp_result, 0) == ~0ULL && vgetq_lane_u64(cmp_result, 1) == ~0ULL;
83} 89}
84 90
85_static_inline cube_t 91_static_inline cube_t
86invertco(cube_t c) 92invertco(cube_t c)
87{ 93{
88 cube_t ret; 94 cube_t ret;
95 uint8x16_t co, shleft, shright, summed, newco, cleanco;
89 96
90 // Copy the corner vector to an array 97 co = vandq_u8(c.corner, _co2_neon);
91 uint8_t corners[16]; 98 shleft = vshlq_n_u8(co, 1);
92 vst1q_u8(corners, c.corner); 99 shright = vshrq_n_u8(co, 1);
93 100 summed = vorrq_u8(shleft, shright);
94 uint8_t corner_result[16] = {0}; 101 newco = vandq_u8(summed, _co2_neon);
95 102 cleanco = veorq_u8(c.corner, co);
96 // Process the corners 103 ret.corner = vorrq_u8(cleanco, newco);
97 for (uint8_t i = 0; i < 8; i++)
98 {
99 uint8_t piece = corners[i];
100 uint8_t orien = ((piece << 1) | (piece >> 1)) & _cobits2;
101 corner_result[i] = (piece & _pbits) | orien;
102 }
103
104 // Copy the results back to the NEON corner vector
105 ret.corner = vld1q_u8(corner_result);
106
107 // Mask to clear the last 64 bits of the corner field
108 uint8x16_t mask_last_64 = vsetq_lane_u64(0, vreinterpretq_u64_u8(ret.corner), 1);
109 ret.corner = vreinterpretq_u8_u64(mask_last_64);
110
111 // Copy the edge vector as it is
112 ret.edge = c.edge; 104 ret.edge = c.edge;
113 105
114 // Mask to clear the last 32 bits of the edge field
115 uint8x16_t mask_last_32 = vsetq_lane_u32(0, vreinterpretq_u32_u8(ret.edge), 3);
116 ret.edge = vreinterpretq_u8_u32(mask_last_32);
117
118 return ret; 106 return ret;
119} 107}
120 108

Generated with cgit - Back to sebastiano.tronto.net