diff options
Diffstat (limited to 'src/arch')
| -rw-r--r-- | src/arch/avx2.h | 73 | ||||
| -rw-r--r-- | src/arch/common.h | 2 | ||||
| -rw-r--r-- | src/arch/neon.h | 79 | ||||
| -rw-r--r-- | src/arch/portable.h | 22 |
4 files changed, 162 insertions, 14 deletions
diff --git a/src/arch/avx2.h b/src/arch/avx2.h index 24c8280..3fb46c9 100644 --- a/src/arch/avx2.h +++ b/src/arch/avx2.h | |||
| @@ -24,9 +24,9 @@ | |||
| 24 | #define ZERO_CUBE _mm256_set_epi64x(0, 0, 0, 0) | 24 | #define ZERO_CUBE _mm256_set_epi64x(0, 0, 0, 0) |
| 25 | #define SOLVED_CUBE _mm256_set_epi64x(SOLVED_H, SOLVED_L, 0, SOLVED_L) | 25 | #define SOLVED_CUBE _mm256_set_epi64x(SOLVED_H, SOLVED_L, 0, SOLVED_L) |
| 26 | 26 | ||
| 27 | 27 | STATIC_INLINE uint64_t permtoindex_Nx8(uint64_t, int64_t); | |
| 28 | STATIC_INLINE uint64_t permtoindex_8x8(int64_t); | ||
| 29 | STATIC_INLINE int64_t indextoperm_8x8(uint64_t); | 28 | STATIC_INLINE int64_t indextoperm_8x8(uint64_t); |
| 29 | STATIC_INLINE int64_t indextoperm_4x8(uint64_t); | ||
| 30 | 30 | ||
| 31 | STATIC_INLINE int | 31 | STATIC_INLINE int |
| 32 | popcount_u32(uint32_t x) | 32 | popcount_u32(uint32_t x) |
| @@ -295,17 +295,17 @@ set_eo(cube_t cube[static 1], uint64_t eo) | |||
| 295 | } | 295 | } |
| 296 | 296 | ||
| 297 | STATIC_INLINE uint64_t | 297 | STATIC_INLINE uint64_t |
| 298 | permtoindex_8x8(int64_t a) | 298 | permtoindex_Nx8(uint64_t n, int64_t a) |
| 299 | { | 299 | { |
| 300 | uint64_t i, c, ret; | 300 | uint64_t i, c, ret; |
| 301 | __m64 cmp; | 301 | __m64 cmp; |
| 302 | 302 | ||
| 303 | for (i = 0, ret = 0; i < 8; i++) { | 303 | for (i = 0, ret = 0; i < n; i++) { |
| 304 | cmp = _mm_set1_pi8(a & INT64_C(0xFF)); | 304 | cmp = _mm_set1_pi8(a & INT64_C(0xFF)); |
| 305 | a = (a >> INT64_C(8)) | INT64_C(0x0F00000000000000); | 305 | a = (a >> INT64_C(8)) | INT64_C(0x0F00000000000000); |
| 306 | cmp = _mm_cmpgt_pi8(cmp, _mm_cvtsi64_m64(a)); | 306 | cmp = _mm_cmpgt_pi8(cmp, _mm_cvtsi64_m64(a)); |
| 307 | c = _mm_popcnt_u64(_mm_cvtm64_si64(cmp)) >> UINT64_C(3); | 307 | c = _mm_popcnt_u64(_mm_cvtm64_si64(cmp)) >> UINT64_C(3); |
| 308 | ret += c * factorial[7-i]; | 308 | ret += c * factorial[n-1-i]; |
| 309 | } | 309 | } |
| 310 | 310 | ||
| 311 | return ret; | 311 | return ret; |
| @@ -332,6 +332,39 @@ indextoperm_8x8(uint64_t p) | |||
| 332 | return ret; | 332 | return ret; |
| 333 | } | 333 | } |
| 334 | 334 | ||
| 335 | STATIC_INLINE int64_t | ||
| 336 | indextoperm_4x8(uint64_t p) | ||
| 337 | { | ||
| 338 | static const int64_t A[FACT_4] = { | ||
| 339 | [0] = INT64_C(0x03020100), | ||
| 340 | [1] = INT64_C(0x02030100), | ||
| 341 | [2] = INT64_C(0x03010200), | ||
| 342 | [3] = INT64_C(0x01030200), | ||
| 343 | [4] = INT64_C(0x02010300), | ||
| 344 | [5] = INT64_C(0x01020300), | ||
| 345 | [6] = INT64_C(0x03020001), | ||
| 346 | [7] = INT64_C(0x02030001), | ||
| 347 | [8] = INT64_C(0x03000201), | ||
| 348 | [9] = INT64_C(0x00030201), | ||
| 349 | [10] = INT64_C(0x02000301), | ||
| 350 | [11] = INT64_C(0x00020301), | ||
| 351 | [12] = INT64_C(0x03010002), | ||
| 352 | [13] = INT64_C(0x01030002), | ||
| 353 | [14] = INT64_C(0x03000102), | ||
| 354 | [15] = INT64_C(0x00030102), | ||
| 355 | [16] = INT64_C(0x01000302), | ||
| 356 | [17] = INT64_C(0x00010302), | ||
| 357 | [18] = INT64_C(0x02010003), | ||
| 358 | [19] = INT64_C(0x01020003), | ||
| 359 | [20] = INT64_C(0x02000103), | ||
| 360 | [21] = INT64_C(0x00020103), | ||
| 361 | [22] = INT64_C(0x01000203), | ||
| 362 | [23] = INT64_C(0x00010203), | ||
| 363 | }; | ||
| 364 | |||
| 365 | return A[p]; | ||
| 366 | } | ||
| 367 | |||
| 335 | STATIC_INLINE uint64_t | 368 | STATIC_INLINE uint64_t |
| 336 | coord_cp(cube_t cube) | 369 | coord_cp(cube_t cube) |
| 337 | { | 370 | { |
| @@ -341,7 +374,7 @@ coord_cp(cube_t cube) | |||
| 341 | cp = _mm256_and_si256(cube, CP_AVX2); | 374 | cp = _mm256_and_si256(cube, CP_AVX2); |
| 342 | _mm256_storeu_si256((__m256i_u *)aux, cp); | 375 | _mm256_storeu_si256((__m256i_u *)aux, cp); |
| 343 | 376 | ||
| 344 | return permtoindex_8x8(aux[0]); | 377 | return permtoindex_Nx8(8, aux[0]); |
| 345 | } | 378 | } |
| 346 | 379 | ||
| 347 | STATIC_INLINE cube_t | 380 | STATIC_INLINE cube_t |
| @@ -359,7 +392,7 @@ coord_epud(cube_t cube) | |||
| 359 | ep = _mm256_and_si256(cube, EP_AVX2); | 392 | ep = _mm256_and_si256(cube, EP_AVX2); |
| 360 | _mm256_storeu_si256((__m256i_u *)aux, ep); | 393 | _mm256_storeu_si256((__m256i_u *)aux, ep); |
| 361 | 394 | ||
| 362 | return permtoindex_8x8(aux[2]); | 395 | return permtoindex_Nx8(8, aux[2]); |
| 363 | } | 396 | } |
| 364 | 397 | ||
| 365 | STATIC_INLINE cube_t | 398 | STATIC_INLINE cube_t |
| @@ -367,3 +400,29 @@ invcoord_epud(uint64_t i) | |||
| 367 | { | 400 | { |
| 368 | return _mm256_set_epi64x(SOLVED_H, indextoperm_8x8(i), 0, SOLVED_L); | 401 | return _mm256_set_epi64x(SOLVED_H, indextoperm_8x8(i), 0, SOLVED_L); |
| 369 | } | 402 | } |
| 403 | |||
| 404 | STATIC_INLINE uint64_t | ||
| 405 | coord_epe(cube_t cube) | ||
| 406 | { | ||
| 407 | cube_t ep; | ||
| 408 | int64_t aux[4]; | ||
| 409 | |||
| 410 | ep = _mm256_and_si256(cube, EP_AVX2); | ||
| 411 | ep = _mm256_xor_si256(ep, _mm256_set1_epi8(8)); | ||
| 412 | _mm256_storeu_si256((__m256i_u *)aux, ep); | ||
| 413 | |||
| 414 | return permtoindex_Nx8(4, aux[3]); | ||
| 415 | } | ||
| 416 | |||
| 417 | STATIC_INLINE cube_t | ||
| 418 | invcoord_epe(uint64_t i) | ||
| 419 | { | ||
| 420 | int64_t a; | ||
| 421 | __m64 a64; | ||
| 422 | |||
| 423 | a = indextoperm_4x8(i); | ||
| 424 | a64 = _mm_add_pi8(_mm_cvtsi64_m64(a), _mm_set_pi32(0, 0x08080808)); | ||
| 425 | a = _mm_cvtm64_si64(a64); | ||
| 426 | |||
| 427 | return _mm256_set_epi64x(a, SOLVED_L, 0, SOLVED_L); | ||
| 428 | } | ||
diff --git a/src/arch/common.h b/src/arch/common.h index 6c62a2e..1c8c0b0 100644 --- a/src/arch/common.h +++ b/src/arch/common.h | |||
| @@ -41,6 +41,8 @@ STATIC_INLINE uint64_t coord_cp(cube_t); | |||
| 41 | STATIC_INLINE cube_t invcoord_cp(uint64_t); | 41 | STATIC_INLINE cube_t invcoord_cp(uint64_t); |
| 42 | STATIC_INLINE uint64_t coord_epud(cube_t); | 42 | STATIC_INLINE uint64_t coord_epud(cube_t); |
| 43 | STATIC_INLINE cube_t invcoord_epud(uint64_t); | 43 | STATIC_INLINE cube_t invcoord_epud(uint64_t); |
| 44 | STATIC_INLINE uint64_t coord_epe(cube_t); | ||
| 45 | STATIC_INLINE cube_t invcoord_epe(uint64_t); | ||
| 44 | 46 | ||
| 45 | STATIC_INLINE void | 47 | STATIC_INLINE void |
| 46 | invcoord_esep_array(uint64_t set1, uint64_t set2, uint8_t mem[static 12]) | 48 | invcoord_esep_array(uint64_t set1, uint64_t set2, uint8_t mem[static 12]) |
diff --git a/src/arch/neon.h b/src/arch/neon.h index fef6220..5723b60 100644 --- a/src/arch/neon.h +++ b/src/arch/neon.h | |||
| @@ -1,6 +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 PBITS8_NEON vdup_n_u8(0x07) | 3 | #define PBITS8_NEON vdup_n_u8(PBITS) |
| 4 | 4 | ||
| 5 | STATIC_INLINE uint8x16_t compose_edges_slim(uint8x16_t, uint8x16_t); | 5 | STATIC_INLINE uint8x16_t compose_edges_slim(uint8x16_t, uint8x16_t); |
| 6 | STATIC_INLINE uint8x8_t compose_corners_slim(uint8x8_t, uint8x8_t); | 6 | STATIC_INLINE uint8x8_t compose_corners_slim(uint8x8_t, uint8x8_t); |
| @@ -29,8 +29,9 @@ STATIC_INLINE uint8x8_t compose_corners_slim(uint8x8_t, uint8x8_t); | |||
| 29 | const uint8_t SOLVED_L[8] = {0, 1, 2, 3, 4, 5, 6, 7}; | 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}; | 30 | const uint8_t SOLVED_H[8] = {8, 9, 10, 11, 0, 0, 0}; |
| 31 | 31 | ||
| 32 | STATIC_INLINE uint64_t permtoindex_8x8(uint8x8_t); | 32 | STATIC_INLINE uint64_t permtoindex_Nx8(uint64_t, uint8x8_t); |
| 33 | STATIC_INLINE uint8x8_t indextoperm_8x8(uint64_t); | 33 | STATIC_INLINE uint8x8_t indextoperm_8x8(uint64_t); |
| 34 | STATIC_INLINE uint8x8_t indextoperm_4x8(uint64_t); | ||
| 34 | 35 | ||
| 35 | STATIC_INLINE int | 36 | STATIC_INLINE int |
| 36 | popcount_u32(uint32_t x) | 37 | popcount_u32(uint32_t x) |
| @@ -364,14 +365,14 @@ invcoord_esep(uint64_t esep) | |||
| 364 | } | 365 | } |
| 365 | 366 | ||
| 366 | STATIC_INLINE uint64_t | 367 | STATIC_INLINE uint64_t |
| 367 | permtoindex_8x8(uint8x8_t a) | 368 | permtoindex_Nx8(uint64_t n, uint8x8_t a) |
| 368 | { | 369 | { |
| 369 | uint64_t i, c, ret; | 370 | uint64_t i, c, ret; |
| 370 | uint8x8_t cmp; | 371 | uint8x8_t cmp; |
| 371 | uint64x1_t anum; | 372 | uint64x1_t anum; |
| 372 | uint8_t or[8] = {0, 0, 0, 0, 0, 0, 0, 0x0F}; | 373 | uint8_t or[8] = {0, 0, 0, 0, 0, 0, 0, 0x0F}; |
| 373 | 374 | ||
| 374 | for (i = 0, ret = 0; i < 8; i++) { | 375 | for (i = 0, ret = 0; i < n; i++) { |
| 375 | cmp = vdup_lane_u8(a, 0); | 376 | cmp = vdup_lane_u8(a, 0); |
| 376 | anum = vreinterpret_u64_u8(a); | 377 | anum = vreinterpret_u64_u8(a); |
| 377 | anum = vshr_n_u64(anum, 8); | 378 | anum = vshr_n_u64(anum, 8); |
| @@ -379,7 +380,7 @@ permtoindex_8x8(uint8x8_t a) | |||
| 379 | a = vorr_u8(a, vld1_u8(or)); | 380 | a = vorr_u8(a, vld1_u8(or)); |
| 380 | cmp = vcgt_u8(cmp, a); | 381 | cmp = vcgt_u8(cmp, a); |
| 381 | c = vaddv_u8(vshr_n_u8(cmp, 7)); | 382 | c = vaddv_u8(vshr_n_u8(cmp, 7)); |
| 382 | ret += c * factorial[7-i]; | 383 | ret += c * factorial[n-1-i]; |
| 383 | } | 384 | } |
| 384 | 385 | ||
| 385 | return ret; | 386 | return ret; |
| @@ -407,10 +408,43 @@ indextoperm_8x8(uint64_t p) | |||
| 407 | return vld1_u8(ret); | 408 | return vld1_u8(ret); |
| 408 | } | 409 | } |
| 409 | 410 | ||
| 411 | STATIC_INLINE uint8x8_t | ||
| 412 | indextoperm_4x8(uint64_t p) | ||
| 413 | { | ||
| 414 | static const int64_t A[FACT_4] = { | ||
| 415 | [0] = UINT64_C(0x03020100), | ||
| 416 | [1] = UINT64_C(0x02030100), | ||
| 417 | [2] = UINT64_C(0x03010200), | ||
| 418 | [3] = UINT64_C(0x01030200), | ||
| 419 | [4] = UINT64_C(0x02010300), | ||
| 420 | [5] = UINT64_C(0x01020300), | ||
| 421 | [6] = UINT64_C(0x03020001), | ||
| 422 | [7] = UINT64_C(0x02030001), | ||
| 423 | [8] = UINT64_C(0x03000201), | ||
| 424 | [9] = UINT64_C(0x00030201), | ||
| 425 | [10] = UINT64_C(0x02000301), | ||
| 426 | [11] = UINT64_C(0x00020301), | ||
| 427 | [12] = UINT64_C(0x03010002), | ||
| 428 | [13] = UINT64_C(0x01030002), | ||
| 429 | [14] = UINT64_C(0x03000102), | ||
| 430 | [15] = UINT64_C(0x00030102), | ||
| 431 | [16] = UINT64_C(0x01000302), | ||
| 432 | [17] = UINT64_C(0x00010302), | ||
| 433 | [18] = UINT64_C(0x02010003), | ||
| 434 | [19] = UINT64_C(0x01020003), | ||
| 435 | [20] = UINT64_C(0x02000103), | ||
| 436 | [21] = UINT64_C(0x00020103), | ||
| 437 | [22] = UINT64_C(0x01000203), | ||
| 438 | [23] = UINT64_C(0x00010203), | ||
| 439 | }; | ||
| 440 | |||
| 441 | return vreinterpret_u8_u64(vdup_n_u64(A[p])); | ||
| 442 | } | ||
| 443 | |||
| 410 | STATIC_INLINE uint64_t | 444 | STATIC_INLINE uint64_t |
| 411 | coord_cp(cube_t cube) | 445 | coord_cp(cube_t cube) |
| 412 | { | 446 | { |
| 413 | return permtoindex_8x8(vand_u8(cube.corner, PBITS8_NEON)); | 447 | return permtoindex_Nx8(8, vand_u8(cube.corner, PBITS8_NEON)); |
| 414 | } | 448 | } |
| 415 | 449 | ||
| 416 | STATIC_INLINE cube_t | 450 | STATIC_INLINE cube_t |
| @@ -425,7 +459,12 @@ invcoord_cp(uint64_t i) | |||
| 425 | STATIC_INLINE uint64_t | 459 | STATIC_INLINE uint64_t |
| 426 | coord_epud(cube_t cube) | 460 | coord_epud(cube_t cube) |
| 427 | { | 461 | { |
| 428 | return permtoindex_8x8(vand_u8(vget_low_u8(cube.edge), PBITS8_NEON)); | 462 | uint8x8_t a; |
| 463 | |||
| 464 | a = vget_low_u8(cube.edge); | ||
| 465 | a = vand_u8(a, PBITS8_NEON); | ||
| 466 | |||
| 467 | return permtoindex_Nx8(8, a); | ||
| 429 | } | 468 | } |
| 430 | 469 | ||
| 431 | STATIC_INLINE cube_t | 470 | STATIC_INLINE cube_t |
| @@ -436,3 +475,29 @@ invcoord_epud(uint64_t i) | |||
| 436 | .edge = vcombine_u8(indextoperm_8x8(i), vld1_u8(SOLVED_H)) | 475 | .edge = vcombine_u8(indextoperm_8x8(i), vld1_u8(SOLVED_H)) |
| 437 | }; | 476 | }; |
| 438 | } | 477 | } |
| 478 | |||
| 479 | STATIC_INLINE uint64_t | ||
| 480 | coord_epe(cube_t cube) | ||
| 481 | { | ||
| 482 | uint8x8_t a; | ||
| 483 | |||
| 484 | a = vget_high_u8(cube.edge); | ||
| 485 | a = vand_u8(a, PBITS8_NEON); | ||
| 486 | a = veor_u8(a, vdup_n_u8(8)); | ||
| 487 | |||
| 488 | return permtoindex_Nx8(4, a); | ||
| 489 | } | ||
| 490 | |||
| 491 | STATIC_INLINE cube_t | ||
| 492 | invcoord_epe(uint64_t i) | ||
| 493 | { | ||
| 494 | uint8x8_t a; | ||
| 495 | |||
| 496 | a = indextoperm_4x8(i); | ||
| 497 | a = vadd_u8(a, vreinterpret_u8_u64(vdup_n_u64(UINT64_C(0x08080808)))); | ||
| 498 | |||
| 499 | return (cube_t) { | ||
| 500 | .corner = vld1_u8(SOLVED_L), | ||
| 501 | .edge = vcombine_u8(vld1_u8(SOLVED_L), a) | ||
| 502 | }; | ||
| 503 | } | ||
diff --git a/src/arch/portable.h b/src/arch/portable.h index 5acccf2..26001ee 100644 --- a/src/arch/portable.h +++ b/src/arch/portable.h | |||
| @@ -334,3 +334,25 @@ invcoord_epud(uint64_t i) | |||
| 334 | return STATIC_CUBE(0, 1, 2, 3, 4, 5, 6, 7, | 334 | return STATIC_CUBE(0, 1, 2, 3, 4, 5, 6, 7, |
| 335 | e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], 8, 9, 10, 11); | 335 | e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], 8, 9, 10, 11); |
| 336 | } | 336 | } |
| 337 | |||
| 338 | STATIC_INLINE uint64_t | ||
| 339 | coord_epe(cube_t cube) | ||
| 340 | { | ||
| 341 | int i; | ||
| 342 | |||
| 343 | for (i = 8; i < 12; i++) | ||
| 344 | cube.edge[i] = (cube.edge[i] & PBITS) - 8; | ||
| 345 | |||
| 346 | return permtoindex(4, cube.edge+8); | ||
| 347 | } | ||
| 348 | |||
| 349 | STATIC_INLINE cube_t | ||
| 350 | invcoord_epe(uint64_t i) | ||
| 351 | { | ||
| 352 | uint8_t e[4]; | ||
| 353 | |||
| 354 | indextoperm(i, 4, e); | ||
| 355 | |||
| 356 | return STATIC_CUBE(0, 1, 2, 3, 4, 5, 6, 7, | ||
| 357 | 0, 1, 2, 3, 4, 5, 6, 7, e[0]+8, e[1]+8, e[2]+8, e[3]+8); | ||
| 358 | } | ||
