diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2025-07-29 10:00:56 +0200 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2025-07-29 10:00:56 +0200 |
| commit | 38014615238a51f1c0c1f2f96d37cbfbf765520a (patch) | |
| tree | 24fff81dd4692ba91b96dd0ab099e043b7108824 /src/arch/neon.h | |
| parent | 1d93860c6f6d3fdbdddabdcd870ef0f8b6e47c81 (diff) | |
| download | nissy-core-38014615238a51f1c0c1f2f96d37cbfbf765520a.tar.gz nissy-core-38014615238a51f1c0c1f2f96d37cbfbf765520a.zip | |
Optimized some coordinates
Diffstat (limited to 'src/arch/neon.h')
| -rw-r--r-- | src/arch/neon.h | 86 |
1 files changed, 81 insertions, 5 deletions
diff --git a/src/arch/neon.h b/src/arch/neon.h index 1fb1c82..a378cf9 100644 --- a/src/arch/neon.h +++ b/src/arch/neon.h | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | #define CO2_NEON vdup_n_u8(0x60) | 1 | #define CO2_NEON vdup_n_u8(0x60) |
| 2 | #define COCW_NEON vdup_n_u8(0x20) | 2 | #define COCW_NEON vdup_n_u8(0x20) |
| 3 | #define CP_NEON vdup_n_u8(0x07) | 3 | #define PBITS8_NEON vdup_n_u8(0x07) |
| 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)) | ||
| 6 | 4 | ||
| 7 | STATIC_INLINE uint8x16_t compose_edges_slim(uint8x16_t, uint8x16_t); | 5 | STATIC_INLINE uint8x16_t compose_edges_slim(uint8x16_t, uint8x16_t); |
| 8 | STATIC_INLINE uint8x8_t compose_corners_slim(uint8x8_t, uint8x8_t); | 6 | STATIC_INLINE uint8x8_t compose_corners_slim(uint8x8_t, uint8x8_t); |
| @@ -20,16 +18,20 @@ STATIC_INLINE uint8x8_t compose_corners_slim(uint8x8_t, uint8x8_t); | |||
| 20 | e_dl, e_dr, e_fr, e_fl, e_bl, e_br, 0, 0, 0, 0 \ | 18 | e_dl, e_dr, e_fr, e_fl, e_bl, e_br, 0, 0, 0, 0 \ |
| 21 | } \ | 19 | } \ |
| 22 | }) | 20 | }) |
| 23 | |||
| 24 | #define ZERO_CUBE \ | 21 | #define ZERO_CUBE \ |
| 25 | ((cube_t){ \ | 22 | ((cube_t){ \ |
| 26 | .corner = vdup_n_u8(0), \ | 23 | .corner = vdup_n_u8(0), \ |
| 27 | .edge = vdupq_n_u8(0) \ | 24 | .edge = vdupq_n_u8(0) \ |
| 28 | }) | 25 | }) |
| 29 | |||
| 30 | #define SOLVED_CUBE STATIC_CUBE( \ | 26 | #define SOLVED_CUBE STATIC_CUBE( \ |
| 31 | 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) | 27 | 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) |
| 32 | 28 | ||
| 29 | const uint8_t SOLVED_L[8] = {0, 1, 2, 3, 4, 5, 6, 7}; | ||
| 30 | const uint8_t SOLVED_H[8] = {8, 9, 10, 11, 0, 0, 0}; | ||
| 31 | |||
| 32 | STATIC_INLINE int64_t permtoindex_8x8(uint8x8_t); | ||
| 33 | STATIC_INLINE uint8x8_t indextoperm_8x8(int64_t); | ||
| 34 | |||
| 33 | STATIC_INLINE int | 35 | STATIC_INLINE int |
| 34 | popcount_u32(uint32_t x) | 36 | popcount_u32(uint32_t x) |
| 35 | { | 37 | { |
| @@ -361,3 +363,77 @@ invcoord_esep(int64_t esep) | |||
| 361 | 363 | ||
| 362 | return ret; | 364 | return ret; |
| 363 | } | 365 | } |
| 366 | |||
| 367 | STATIC_INLINE int64_t | ||
| 368 | permtoindex_8x8(uint8x8_t a) | ||
| 369 | { | ||
| 370 | int64_t i, c, ret; | ||
| 371 | uint8x8_t cmp; | ||
| 372 | uint64x1_t anum; | ||
| 373 | uint8_t or[8] = {0, 0, 0, 0, 0, 0, 0, 0x0F}; | ||
| 374 | |||
| 375 | for (i = 0, ret = 0; i < 8; i++) { | ||
| 376 | cmp = vdup_lane_u8(a, 0); | ||
| 377 | anum = vreinterpret_u64_u8(a); | ||
| 378 | anum = vshr_n_u64(anum, 8); | ||
| 379 | a = vreinterpret_u8_u64(anum); | ||
| 380 | a = vorr_u8(a, vld1_u8(or)); | ||
| 381 | cmp = vcgt_u8(cmp, a); | ||
| 382 | c = vaddv_u8(vshr_n_u8(cmp, 7)); | ||
| 383 | ret += c * factorial[7-i]; | ||
| 384 | } | ||
| 385 | |||
| 386 | return ret; | ||
| 387 | } | ||
| 388 | |||
| 389 | STATIC_INLINE uint8x8_t | ||
| 390 | indextoperm_8x8(int64_t p) | ||
| 391 | { | ||
| 392 | int used; | ||
| 393 | int64_t c, k, i, j; | ||
| 394 | uint8_t ret[8]; | ||
| 395 | |||
| 396 | for (i = 0, used = 0; i < 8; i++) { | ||
| 397 | k = p / factorial[7-i]; | ||
| 398 | |||
| 399 | /* Find k-th unused number */ | ||
| 400 | for (j = 0, c = 0; c <= k; j++) | ||
| 401 | c += 1 - ((used & (1 << j)) >> j); | ||
| 402 | |||
| 403 | ret[i] = j-1; | ||
| 404 | used |= 1 << (j-1); | ||
| 405 | p %= factorial[7-i]; | ||
| 406 | } | ||
| 407 | |||
| 408 | return vld1_u8(ret); | ||
| 409 | } | ||
| 410 | |||
| 411 | STATIC_INLINE int64_t | ||
| 412 | coord_cp(cube_t cube) | ||
| 413 | { | ||
| 414 | return permtoindex_8x8(vand_u8(cube.corner, PBITS8_NEON)); | ||
| 415 | } | ||
| 416 | |||
| 417 | STATIC_INLINE cube_t | ||
| 418 | invcoord_cp(int64_t i) | ||
| 419 | { | ||
| 420 | return (cube_t) { | ||
| 421 | .corner = indextoperm_8x8(i), | ||
| 422 | .edge = vcombine_u8(vld1_u8(SOLVED_L), vld1_u8(SOLVED_H)) | ||
| 423 | }; | ||
| 424 | } | ||
| 425 | |||
| 426 | STATIC_INLINE int64_t | ||
| 427 | coord_epud(cube_t cube) | ||
| 428 | { | ||
| 429 | return permtoindex_8x8(vand_u8(vget_low_u8(cube.edge), PBITS8_NEON)); | ||
| 430 | } | ||
| 431 | |||
| 432 | STATIC_INLINE cube_t | ||
| 433 | invcoord_epud(int64_t i) | ||
| 434 | { | ||
| 435 | return (cube_t) { | ||
| 436 | .corner = vld1_u8(SOLVED_L), | ||
| 437 | .edge = vcombine_u8(indextoperm_8x8(i), vld1_u8(SOLVED_H)) | ||
| 438 | }; | ||
| 439 | } | ||
