aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/arch/arch.h2
-rw-r--r--src/arch/neon.h93
-rw-r--r--src/solvers/h48/solve.h6
-rw-r--r--src/utils/constants.h8
4 files changed, 51 insertions, 58 deletions
diff --git a/src/arch/arch.h b/src/arch/arch.h
index e5de0cf..a9f6e03 100644
--- a/src/arch/arch.h
+++ b/src/arch/arch.h
@@ -15,7 +15,7 @@ typedef __m256i cube_t;
15#include <arm_neon.h> 15#include <arm_neon.h>
16 16
17typedef struct { 17typedef struct {
18 uint8x16_t corner; 18 uint8x8_t corner;
19 uint8x16_t edge; 19 uint8x16_t edge;
20} cube_t; 20} cube_t;
21 21
diff --git a/src/arch/neon.h b/src/arch/neon.h
index 9ebebf8..c31c8f9 100644
--- a/src/arch/neon.h
+++ b/src/arch/neon.h
@@ -1,24 +1,24 @@
1#define CO2_NEON vdupq_n_u8(0x60) 1#define CO2_NEON vdup_n_u8(0x60)
2#define COCW_NEON vdupq_n_u8(0x20) 2#define COCW_NEON vdup_n_u8(0x20)
3#define CP_NEON vdupq_n_u8(0x07) 3#define CP_NEON vdup_n_u8(0x07)
4#define EP_NEON vcombine_u8(vdupq_n_u8(0x0F), vdupq_n_u8(0x0F)) 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)) 5#define EO_NEON vcombine_u8(vdupq_n_u8(0x10), vdupq_n_u8(0x10))
6 6
7STATIC_INLINE uint8x16_t compose_edges_slim(uint8x16_t, uint8x16_t); 7STATIC_INLINE uint8x16_t compose_edges_slim(uint8x16_t, uint8x16_t);
8STATIC_INLINE uint8x16_t compose_corners_slim(uint8x16_t, uint8x16_t); 8STATIC_INLINE uint8x8_t compose_corners_slim(uint8x8_t, uint8x8_t);
9 9
10// static cube 10// static cube
11#define STATIC_CUBE(c_ufr, c_ubl, c_dfl, c_dbr, c_ufl, c_ubr, c_dfr, c_dbl, \ 11#define STATIC_CUBE(c_ufr, c_ubl, c_dfl, c_dbr, c_ufl, c_ubr, c_dfr, c_dbl, \
12 e_uf, e_ub, e_db, e_df, e_ur, e_ul, e_dl, e_dr, e_fr, e_fl, e_bl, e_br) \ 12 e_uf, e_ub, e_db, e_df, e_ur, e_ul, e_dl, e_dr, e_fr, e_fl, e_bl, e_br) \
13 ((cube_t){ \ 13 ((cube_t){ \
14 .corner = {c_ufr, c_ubl, c_dfl, c_dbr, c_ufl, c_ubr, c_dfr, c_dbl, 0, 0, 0, 0, 0, 0, 0, 0}, \ 14 .corner = {c_ufr, c_ubl, c_dfl, c_dbr, c_ufl, c_ubr, c_dfr, c_dbl}, \
15 .edge = {e_uf, e_ub, e_db, e_df, e_ur, e_ul, e_dl, e_dr, e_fr, e_fl, e_bl, e_br, 0, 0, 0, 0}}) 15 .edge = {e_uf, e_ub, e_db, e_df, e_ur, e_ul, e_dl, e_dr, e_fr, e_fl, e_bl, e_br, 0, 0, 0, 0}})
16 16
17// zero cube 17// zero cube
18#define ZERO_CUBE \ 18#define ZERO_CUBE \
19 (cube_t) \ 19 (cube_t) \
20 { \ 20 { \
21 .corner = vdupq_n_u8(0), \ 21 .corner = vdup_n_u8(0), \
22 .edge = vdupq_n_u8(0) \ 22 .edge = vdupq_n_u8(0) \
23 } 23 }
24 24
@@ -30,7 +30,7 @@ STATIC void
30pieces(cube_t *cube, uint8_t c[static 8], uint8_t e[static 12]) 30pieces(cube_t *cube, uint8_t c[static 8], uint8_t e[static 12])
31{ 31{
32 // First 8 bytes of the corner vector are copied from the c array 32 // First 8 bytes of the corner vector are copied from the c array
33 vst1_u8(c, vget_low_u8(cube->corner)); 33 vst1_u8(c, cube->corner);
34 34
35 // 12 bytes of the edge vector are copied from the e array 35 // 12 bytes of the edge vector are copied from the e array
36 // First 8 bytes 36 // First 8 bytes
@@ -42,20 +42,17 @@ pieces(cube_t *cube, uint8_t c[static 8], uint8_t e[static 12])
42STATIC_INLINE bool 42STATIC_INLINE bool
43equal(cube_t c1, cube_t c2) 43equal(cube_t c1, cube_t c2)
44{ 44{
45 uint8x16_t cmp_corner, cmp_edge; 45 uint8x8_t cmp_corner;
46 uint64x2_t cmp_corner_u64, cmp_edge_u64; 46 uint8x16_t cmp_edge;
47 uint64x2_t cmp_result; 47 uint64x2_t cmp_corner_u64, cmp_edge_u64, cmp_result;
48 48
49 // compare the corner vectors 49 // compare the corner vectors and the edge vectors
50 cmp_corner = vceqq_u8(c1.corner, c2.corner); 50 cmp_corner = vceq_u8(c1.corner, c2.corner);
51 // compare the edge vectors
52 cmp_edge = vceqq_u8(c1.edge, c2.edge); 51 cmp_edge = vceqq_u8(c1.edge, c2.edge);
53 52
54 // convert the comparison vectors to 64-bit vectors 53 // convert the comparison vectors to 64-bit vectors and combine them
55 cmp_corner_u64 = vreinterpretq_u64_u8(cmp_corner); 54 cmp_corner_u64 = vreinterpretq_u64_u8(vcombine_u64(cmp_corner, cmp_corner));
56 cmp_edge_u64 = vreinterpretq_u64_u8(cmp_edge); 55 cmp_edge_u64 = vreinterpretq_u64_u8(cmp_edge);
57
58 // combine the comparison vectors
59 cmp_result = vandq_u64(cmp_corner_u64, cmp_edge_u64); 56 cmp_result = vandq_u64(cmp_corner_u64, cmp_edge_u64);
60 57
61 // check if all the bits are set 58 // check if all the bits are set
@@ -66,15 +63,15 @@ STATIC_INLINE cube_t
66invertco(cube_t c) 63invertco(cube_t c)
67{ 64{
68 cube_t ret; 65 cube_t ret;
69 uint8x16_t co, shleft, shright, summed, newco, cleanco; 66 uint8x8_t co, shleft, shright, summed, newco, cleanco;
70 67
71 co = vandq_u8(c.corner, CO2_NEON); 68 co = vand_u8(c.corner, CO2_NEON);
72 shleft = vshlq_n_u8(co, 1); 69 shleft = vshl_n_u8(co, 1);
73 shright = vshrq_n_u8(co, 1); 70 shright = vshr_n_u8(co, 1);
74 summed = vorrq_u8(shleft, shright); 71 summed = vorr_u8(shleft, shright);
75 newco = vandq_u8(summed, CO2_NEON); 72 newco = vand_u8(summed, CO2_NEON);
76 cleanco = veorq_u8(c.corner, co); 73 cleanco = veor_u8(c.corner, co);
77 ret.corner = vorrq_u8(cleanco, newco); 74 ret.corner = vorr_u8(cleanco, newco);
78 ret.edge = c.edge; 75 ret.edge = c.edge;
79 76
80 return ret; 77 return ret;
@@ -120,30 +117,25 @@ compose_edges_slim(uint8x16_t edge1, uint8x16_t edge2)
120 return ret; 117 return ret;
121} 118}
122 119
123STATIC_INLINE uint8x16_t 120STATIC_INLINE uint8x8_t
124compose_corners_slim(uint8x16_t corner1, uint8x16_t corner2) 121compose_corners_slim(uint8x8_t corner1, uint8x8_t corner2)
125{ 122{
126 // Masks 123 // Masks
127 uint8x16_t p_bits = vdupq_n_u8(PBITS); 124 uint8x8_t p_bits = vdup_n_u8(PBITS);
128 uint8x16_t cobits = vdupq_n_u8(COBITS); 125 uint8x8_t cobits = vdup_n_u8(COBITS);
129 uint8x16_t cobits2 = vdupq_n_u8(COBITS_2); 126 uint8x8_t cobits2 = vdup_n_u8(COBITS_2);
130 uint8x16_t twist_cw = vdupq_n_u8(CTWIST_CW); 127 uint8x8_t twist_cw = vdup_n_u8(CTWIST_CW);
131 128
132 // Find the index and permutation 129 // Find the index and permutation
133 uint8x16_t p = vandq_u8(corner2, p_bits); 130 uint8x8_t p = vand_u8(corner2, p_bits);
134 uint8x16_t piece1 = vqtbl1q_u8(corner1, p); 131 uint8x8_t piece1 = vtbl1_u8(corner1, p);
135 132
136 // Calculate the orientation 133 // Calculate the orientation
137 uint8x16_t aux = vaddq_u8(vandq_u8(corner2, cobits), vandq_u8(piece1, cobits)); 134 uint8x8_t aux = vadd_u8(vand_u8(corner2, cobits), vand_u8(piece1, cobits));
138 uint8x16_t auy = vshrq_n_u8(vaddq_u8(aux, twist_cw), 2); 135 uint8x8_t auy = vshr_n_u8(vadd_u8(aux, twist_cw), 2);
139 uint8x16_t orien = vandq_u8(vaddq_u8(aux, auy), cobits2); 136 uint8x8_t orien = vand_u8(vadd_u8(aux, auy), cobits2);
140
141 // Combine the results
142 uint8x16_t ret = vorrq_u8(vandq_u8(piece1, p_bits), orien);
143 137
144 // Mask to clear the last 64 bits of the result 138 uint8x8_t ret = vorr_u8(vand_u8(piece1, p_bits), orien);
145 uint8x16_t mask_last_64 = vsetq_lane_u64(0, vreinterpretq_u64_u8(ret), 1);
146 ret = vreinterpretq_u8_u64(mask_last_64);
147 139
148 return ret; 140 return ret;
149} 141}
@@ -167,14 +159,14 @@ inverse(cube_t cube)
167 159
168 // Temp arrays to store the NEON vectors 160 // Temp arrays to store the NEON vectors
169 uint8_t edges[16]; 161 uint8_t edges[16];
170 uint8_t corners[16]; 162 uint8_t corners[8];
171 163
172 // Copy the NEON vectors to the arrays 164 // Copy the NEON vectors to the arrays
173 vst1q_u8(edges, cube.edge); 165 vst1q_u8(edges, cube.edge);
174 vst1q_u8(corners, cube.corner); 166 vst1_u8(corners, cube.corner);
175 167
176 uint8_t edge_result[16] = {0}; 168 uint8_t edge_result[16] = {0};
177 uint8_t corner_result[16] = {0}; 169 uint8_t corner_result[8] = {0};
178 170
179 // Process the edges 171 // Process the edges
180 for (i = 0; i < 12; i++) 172 for (i = 0; i < 12; i++)
@@ -194,7 +186,7 @@ inverse(cube_t cube)
194 186
195 // Copy the results back to the NEON vectors 187 // Copy the results back to the NEON vectors
196 ret.edge = vld1q_u8(edge_result); 188 ret.edge = vld1q_u8(edge_result);
197 ret.corner = vld1q_u8(corner_result); 189 ret.corner = vld1_u8(corner_result);
198 190
199 return ret; 191 return ret;
200} 192}
@@ -203,8 +195,8 @@ STATIC_INLINE int64_t
203coord_co(cube_t c) 195coord_co(cube_t c)
204{ 196{
205 // Temp array to store the NEON vector 197 // Temp array to store the NEON vector
206 uint8_t mem[16]; 198 uint8_t mem[8];
207 vst1q_u8(mem, c.corner); 199 vst1_u8(mem, c.corner);
208 200
209 int i, p; 201 int i, p;
210 int64_t ret; 202 int64_t ret;
@@ -219,8 +211,8 @@ STATIC_INLINE int64_t
219coord_csep(cube_t c) 211coord_csep(cube_t c)
220{ 212{
221 // Temp array to store the NEON vector 213 // Temp array to store the NEON vector
222 uint8_t mem[16]; 214 uint8_t mem[8];
223 vst1q_u8(mem, c.corner); 215 vst1_u8(mem, c.corner);
224 216
225 int64_t ret = 0; 217 int64_t ret = 0;
226 int i, p; 218 int i, p;
@@ -228,6 +220,7 @@ coord_csep(cube_t c)
228 ret += p * ((mem[i] & CSEPBIT) >> 2); 220 ret += p * ((mem[i] & CSEPBIT) >> 2);
229 221
230 return ret; 222 return ret;
223 return 0;
231} 224}
232 225
233STATIC_INLINE int64_t 226STATIC_INLINE int64_t
diff --git a/src/solvers/h48/solve.h b/src/solvers/h48/solve.h
index 8f55501..82c8358 100644
--- a/src/solvers/h48/solve.h
+++ b/src/solvers/h48/solve.h
@@ -19,7 +19,7 @@ typedef struct {
19 uint8_t premoves[MAXLEN]; 19 uint8_t premoves[MAXLEN];
20} dfsarg_solveh48_t; 20} dfsarg_solveh48_t;
21 21
22STATIC uint32_t allowednextmove_h48(uint8_t *, uint8_t, uint32_t); 22STATIC uint32_t allowednextmove_h48(uint8_t *, uint8_t, uint8_t);
23 23
24STATIC void solve_h48_appendsolution(dfsarg_solveh48_t *); 24STATIC void solve_h48_appendsolution(dfsarg_solveh48_t *);
25STATIC_INLINE bool solve_h48_stop(dfsarg_solveh48_t *); 25STATIC_INLINE bool solve_h48_stop(dfsarg_solveh48_t *);
@@ -28,7 +28,7 @@ STATIC int64_t solve_h48(cube_t, int8_t, int8_t,
28 int8_t, uint64_t, const void *, uint64_t, char *); 28 int8_t, uint64_t, const void *, uint64_t, char *);
29 29
30STATIC uint32_t 30STATIC uint32_t
31allowednextmove_h48(uint8_t *moves, uint8_t n, uint32_t h48branch) 31allowednextmove_h48(uint8_t *moves, uint8_t n, uint8_t h48branch)
32{ 32{
33 uint32_t result = MM_ALLMOVES; 33 uint32_t result = MM_ALLMOVES;
34 if (h48branch & MM_NORMALBRANCH) 34 if (h48branch & MM_NORMALBRANCH)
@@ -258,4 +258,4 @@ solve_h48(
258solve_h48_error_data: 258solve_h48_error_data:
259 LOG("solve_h48: error reading table\n"); 259 LOG("solve_h48: error reading table\n");
260 return NISSY_ERROR_DATA; 260 return NISSY_ERROR_DATA;
261} 261} \ No newline at end of file
diff --git a/src/utils/constants.h b/src/utils/constants.h
index e985bc7..ab1b9d8 100644
--- a/src/utils/constants.h
+++ b/src/utils/constants.h
@@ -93,10 +93,10 @@ STATIC int64_t binomial[12][12] = {
93#define TRANS_BDm UINT8_C(46) 93#define TRANS_BDm UINT8_C(46)
94#define TRANS_BLm UINT8_C(47) 94#define TRANS_BLm UINT8_C(47)
95 95
96#define MM_NORMAL UINT32_C(0x00) 96#define MM_NORMAL UINT8_C(0x00)
97#define MM_INVERSE UINT32_C(0x01) 97#define MM_INVERSE UINT8_C(0x01)
98#define MM_INVERSEBRANCH UINT32_C(0x03) 98#define MM_INVERSEBRANCH UINT8_C(0x03)
99#define MM_NORMALBRANCH UINT32_C(0x02) 99#define MM_NORMALBRANCH UINT8_C(0x02)
100#define MM_ALLMOVES UINT32_C(0x3FFFF) 100#define MM_ALLMOVES UINT32_C(0x3FFFF)
101#define MM_NOHALFTURNS UINT32_C(0x2DB6D) 101#define MM_NOHALFTURNS UINT32_C(0x2DB6D)
102 102

Generated with cgit - Back to sebastiano.tronto.net