diff options
Diffstat (limited to 'src/cube_neon.h')
| -rw-r--r-- | src/cube_neon.h | 44 |
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 |
| 86 | invertco(cube_t c) | 92 | invertco(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 | ||
