diff options
| author | enricotenuti <tenutz_27@outlook.it> | 2024-10-15 10:34:13 +0200 |
|---|---|---|
| committer | enricotenuti <tenutz_27@outlook.it> | 2024-10-15 10:34:13 +0200 |
| commit | 8c5f48d61627a986dc9feb8092f1f465b7f90ebc (patch) | |
| tree | eb0761367093403ebf17c13a8cb1550992203bf1 /src | |
| parent | 3c12def93ed667548bcd9c534c31ec31bfefb8e0 (diff) | |
| download | nissy-core-8c5f48d61627a986dc9feb8092f1f465b7f90ebc.tar.gz nissy-core-8c5f48d61627a986dc9feb8092f1f465b7f90ebc.zip | |
Neon uint8x8_t corners and minor fixes
Diffstat (limited to '')
| -rw-r--r-- | src/arch/arch.h | 2 | ||||
| -rw-r--r-- | src/arch/neon.h | 93 | ||||
| -rw-r--r-- | src/solvers/h48/solve.h | 6 | ||||
| -rw-r--r-- | src/utils/constants.h | 8 |
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 | ||
| 17 | typedef struct { | 17 | typedef 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 | ||
| 7 | STATIC_INLINE uint8x16_t compose_edges_slim(uint8x16_t, uint8x16_t); | 7 | STATIC_INLINE uint8x16_t compose_edges_slim(uint8x16_t, uint8x16_t); |
| 8 | STATIC_INLINE uint8x16_t compose_corners_slim(uint8x16_t, uint8x16_t); | 8 | STATIC_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 | |||
| 30 | pieces(cube_t *cube, uint8_t c[static 8], uint8_t e[static 12]) | 30 | pieces(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]) | |||
| 42 | STATIC_INLINE bool | 42 | STATIC_INLINE bool |
| 43 | equal(cube_t c1, cube_t c2) | 43 | equal(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 | |||
| 66 | invertco(cube_t c) | 63 | invertco(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 | ||
| 123 | STATIC_INLINE uint8x16_t | 120 | STATIC_INLINE uint8x8_t |
| 124 | compose_corners_slim(uint8x16_t corner1, uint8x16_t corner2) | 121 | compose_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 | |||
| 203 | coord_co(cube_t c) | 195 | coord_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 | |||
| 219 | coord_csep(cube_t c) | 211 | coord_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 | ||
| 233 | STATIC_INLINE int64_t | 226 | STATIC_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 | ||
| 22 | STATIC uint32_t allowednextmove_h48(uint8_t *, uint8_t, uint32_t); | 22 | STATIC uint32_t allowednextmove_h48(uint8_t *, uint8_t, uint8_t); |
| 23 | 23 | ||
| 24 | STATIC void solve_h48_appendsolution(dfsarg_solveh48_t *); | 24 | STATIC void solve_h48_appendsolution(dfsarg_solveh48_t *); |
| 25 | STATIC_INLINE bool solve_h48_stop(dfsarg_solveh48_t *); | 25 | STATIC_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 | ||
| 30 | STATIC uint32_t | 30 | STATIC uint32_t |
| 31 | allowednextmove_h48(uint8_t *moves, uint8_t n, uint32_t h48branch) | 31 | allowednextmove_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( | |||
| 258 | solve_h48_error_data: | 258 | solve_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 | ||
