diff options
Diffstat (limited to 'src/arch')
| -rw-r--r-- | src/arch/neon.h | 41 |
1 files changed, 25 insertions, 16 deletions
diff --git a/src/arch/neon.h b/src/arch/neon.h index fc0e612..45db305 100644 --- a/src/arch/neon.h +++ b/src/arch/neon.h | |||
| @@ -7,23 +7,27 @@ | |||
| 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 uint8x8_t compose_corners_slim(uint8x8_t, uint8x8_t); | 8 | STATIC_INLINE uint8x8_t compose_corners_slim(uint8x8_t, uint8x8_t); |
| 9 | 9 | ||
| 10 | // static cube | 10 | #define STATIC_CUBE( \ |
| 11 | #define STATIC_CUBE(c_ufr, c_ubl, c_dfl, c_dbr, c_ufl, c_ubr, c_dfr, c_dbl, \ | 11 | 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}, \ | 14 | .corner = { \ |
| 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 | c_ufr, c_ubl, c_dfl, c_dbr, \ |
| 16 | c_ufl, c_ubr, c_dfr, c_dbl \ | ||
| 17 | }, \ | ||
| 18 | .edge = { \ | ||
| 19 | e_uf, e_ub, e_db, e_df, e_ur, e_ul, \ | ||
| 20 | e_dl, e_dr, e_fr, e_fl, e_bl, e_br, 0, 0, 0, 0 \ | ||
| 21 | } \ | ||
| 22 | }) | ||
| 16 | 23 | ||
| 17 | // zero cube | ||
| 18 | #define ZERO_CUBE \ | 24 | #define ZERO_CUBE \ |
| 19 | (cube_t) \ | 25 | ((cube_t){ \ |
| 20 | { \ | ||
| 21 | .corner = vdup_n_u8(0), \ | 26 | .corner = vdup_n_u8(0), \ |
| 22 | .edge = vdupq_n_u8(0) \ | 27 | .edge = vdupq_n_u8(0) \ |
| 23 | } | 28 | }) |
| 24 | 29 | ||
| 25 | // solved cube | 30 | #define SOLVED_CUBE STATIC_CUBE( \ |
| 26 | #define SOLVED_CUBE STATIC_CUBE( \ | ||
| 27 | 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) | 31 | 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) |
| 28 | 32 | ||
| 29 | /* TODO: optimize this (use intrinsics?) */ | 33 | /* TODO: optimize this (use intrinsics?) */ |
| @@ -48,7 +52,8 @@ pieces(cube_t cube[static 1], uint8_t c[static 8], uint8_t e[static 12]) | |||
| 48 | // First 8 bytes | 52 | // First 8 bytes |
| 49 | vst1_u8(e, vget_low_u8(cube->edge)); | 53 | vst1_u8(e, vget_low_u8(cube->edge)); |
| 50 | // Next 4 bytes | 54 | // Next 4 bytes |
| 51 | vst1_lane_u32((uint32_t *)(e + 8), vreinterpret_u32_u8(vget_high_u8(cube->edge)), 0); | 55 | vst1_lane_u32((uint32_t *)(e + 8), |
| 56 | vreinterpret_u32_u8(vget_high_u8(cube->edge)), 0); | ||
| 52 | } | 57 | } |
| 53 | 58 | ||
| 54 | STATIC_INLINE bool | 59 | STATIC_INLINE bool |
| @@ -63,12 +68,14 @@ equal(cube_t c1, cube_t c2) | |||
| 63 | cmp_edge = vceqq_u8(c1.edge, c2.edge); | 68 | cmp_edge = vceqq_u8(c1.edge, c2.edge); |
| 64 | 69 | ||
| 65 | // convert the comparison vectors to 64-bit vectors and combine them | 70 | // convert the comparison vectors to 64-bit vectors and combine them |
| 66 | cmp_corner_u64 = vreinterpretq_u64_u8(vcombine_u64(cmp_corner, cmp_corner)); | 71 | cmp_corner_u64 = vreinterpretq_u64_u8( |
| 72 | vcombine_u64(cmp_corner, cmp_corner)); | ||
| 67 | cmp_edge_u64 = vreinterpretq_u64_u8(cmp_edge); | 73 | cmp_edge_u64 = vreinterpretq_u64_u8(cmp_edge); |
| 68 | cmp_result = vandq_u64(cmp_corner_u64, cmp_edge_u64); | 74 | cmp_result = vandq_u64(cmp_corner_u64, cmp_edge_u64); |
| 69 | 75 | ||
| 70 | // check if all the bits are set | 76 | // check if all the bits are set |
| 71 | return vgetq_lane_u64(cmp_result, 0) == ~0ULL && vgetq_lane_u64(cmp_result, 1) == ~0ULL; | 77 | return vgetq_lane_u64(cmp_result, 0) == ~0ULL && |
| 78 | vgetq_lane_u64(cmp_result, 1) == ~0ULL; | ||
| 72 | } | 79 | } |
| 73 | 80 | ||
| 74 | STATIC_INLINE cube_t | 81 | STATIC_INLINE cube_t |
| @@ -123,7 +130,8 @@ compose_edges_slim(uint8x16_t edge1, uint8x16_t edge2) | |||
| 123 | uint8x16_t ret = vorrq_u8(vandq_u8(piece1, p_bits), orien); | 130 | uint8x16_t ret = vorrq_u8(vandq_u8(piece1, p_bits), orien); |
| 124 | 131 | ||
| 125 | // Mask to clear the last 32 bits of the result | 132 | // Mask to clear the last 32 bits of the result |
| 126 | uint8x16_t mask_last_32 = vsetq_lane_u32(0, vreinterpretq_u32_u8(ret), 3); | 133 | uint8x16_t mask_last_32 = |
| 134 | vsetq_lane_u32(0, vreinterpretq_u32_u8(ret), 3); | ||
| 127 | ret = vreinterpretq_u8_u32(mask_last_32); | 135 | ret = vreinterpretq_u8_u32(mask_last_32); |
| 128 | 136 | ||
| 129 | return ret; | 137 | return ret; |
| @@ -143,7 +151,8 @@ compose_corners_slim(uint8x8_t corner1, uint8x8_t corner2) | |||
| 143 | uint8x8_t piece1 = vtbl1_u8(corner1, p); | 151 | uint8x8_t piece1 = vtbl1_u8(corner1, p); |
| 144 | 152 | ||
| 145 | // Calculate the orientation | 153 | // Calculate the orientation |
| 146 | uint8x8_t aux = vadd_u8(vand_u8(corner2, cobits), vand_u8(piece1, cobits)); | 154 | uint8x8_t aux = |
| 155 | vadd_u8(vand_u8(corner2, cobits), vand_u8(piece1, cobits)); | ||
| 147 | uint8x8_t auy = vshr_n_u8(vadd_u8(aux, twist_cw), 2); | 156 | uint8x8_t auy = vshr_n_u8(vadd_u8(aux, twist_cw), 2); |
| 148 | uint8x8_t orien = vand_u8(vadd_u8(aux, auy), cobits2); | 157 | uint8x8_t orien = vand_u8(vadd_u8(aux, auy), cobits2); |
| 149 | 158 | ||
