aboutsummaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2025-08-01 16:52:44 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2025-08-01 16:52:44 +0200
commit1bd4691d9cc46ec75adbe899b289a1ebc5460721 (patch)
treeea71166e05d399e57a13d6e3d7d96d4737f8f7bd /src/arch
parent0844b0ecd00bd6d68a7bafaeae0ee3d420db8ff6 (diff)
downloadnissy-core-1bd4691d9cc46ec75adbe899b289a1ebc5460721.tar.gz
nissy-core-1bd4691d9cc46ec75adbe899b289a1ebc5460721.zip
Added CPEPE coordinate in preparation of full DRFIN solver
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/avx2.h73
-rw-r--r--src/arch/common.h2
-rw-r--r--src/arch/neon.h79
-rw-r--r--src/arch/portable.h22
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 27STATIC_INLINE uint64_t permtoindex_Nx8(uint64_t, int64_t);
28STATIC_INLINE uint64_t permtoindex_8x8(int64_t);
29STATIC_INLINE int64_t indextoperm_8x8(uint64_t); 28STATIC_INLINE int64_t indextoperm_8x8(uint64_t);
29STATIC_INLINE int64_t indextoperm_4x8(uint64_t);
30 30
31STATIC_INLINE int 31STATIC_INLINE int
32popcount_u32(uint32_t x) 32popcount_u32(uint32_t x)
@@ -295,17 +295,17 @@ set_eo(cube_t cube[static 1], uint64_t eo)
295} 295}
296 296
297STATIC_INLINE uint64_t 297STATIC_INLINE uint64_t
298permtoindex_8x8(int64_t a) 298permtoindex_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
335STATIC_INLINE int64_t
336indextoperm_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
335STATIC_INLINE uint64_t 368STATIC_INLINE uint64_t
336coord_cp(cube_t cube) 369coord_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
347STATIC_INLINE cube_t 380STATIC_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
365STATIC_INLINE cube_t 398STATIC_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
404STATIC_INLINE uint64_t
405coord_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
417STATIC_INLINE cube_t
418invcoord_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);
41STATIC_INLINE cube_t invcoord_cp(uint64_t); 41STATIC_INLINE cube_t invcoord_cp(uint64_t);
42STATIC_INLINE uint64_t coord_epud(cube_t); 42STATIC_INLINE uint64_t coord_epud(cube_t);
43STATIC_INLINE cube_t invcoord_epud(uint64_t); 43STATIC_INLINE cube_t invcoord_epud(uint64_t);
44STATIC_INLINE uint64_t coord_epe(cube_t);
45STATIC_INLINE cube_t invcoord_epe(uint64_t);
44 46
45STATIC_INLINE void 47STATIC_INLINE void
46invcoord_esep_array(uint64_t set1, uint64_t set2, uint8_t mem[static 12]) 48invcoord_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
5STATIC_INLINE uint8x16_t compose_edges_slim(uint8x16_t, uint8x16_t); 5STATIC_INLINE uint8x16_t compose_edges_slim(uint8x16_t, uint8x16_t);
6STATIC_INLINE uint8x8_t compose_corners_slim(uint8x8_t, uint8x8_t); 6STATIC_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);
29const uint8_t SOLVED_L[8] = {0, 1, 2, 3, 4, 5, 6, 7}; 29const uint8_t SOLVED_L[8] = {0, 1, 2, 3, 4, 5, 6, 7};
30const uint8_t SOLVED_H[8] = {8, 9, 10, 11, 0, 0, 0}; 30const uint8_t SOLVED_H[8] = {8, 9, 10, 11, 0, 0, 0};
31 31
32STATIC_INLINE uint64_t permtoindex_8x8(uint8x8_t); 32STATIC_INLINE uint64_t permtoindex_Nx8(uint64_t, uint8x8_t);
33STATIC_INLINE uint8x8_t indextoperm_8x8(uint64_t); 33STATIC_INLINE uint8x8_t indextoperm_8x8(uint64_t);
34STATIC_INLINE uint8x8_t indextoperm_4x8(uint64_t);
34 35
35STATIC_INLINE int 36STATIC_INLINE int
36popcount_u32(uint32_t x) 37popcount_u32(uint32_t x)
@@ -364,14 +365,14 @@ invcoord_esep(uint64_t esep)
364} 365}
365 366
366STATIC_INLINE uint64_t 367STATIC_INLINE uint64_t
367permtoindex_8x8(uint8x8_t a) 368permtoindex_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
411STATIC_INLINE uint8x8_t
412indextoperm_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
410STATIC_INLINE uint64_t 444STATIC_INLINE uint64_t
411coord_cp(cube_t cube) 445coord_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
416STATIC_INLINE cube_t 450STATIC_INLINE cube_t
@@ -425,7 +459,12 @@ invcoord_cp(uint64_t i)
425STATIC_INLINE uint64_t 459STATIC_INLINE uint64_t
426coord_epud(cube_t cube) 460coord_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
431STATIC_INLINE cube_t 470STATIC_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
479STATIC_INLINE uint64_t
480coord_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
491STATIC_INLINE cube_t
492invcoord_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
338STATIC_INLINE uint64_t
339coord_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
349STATIC_INLINE cube_t
350invcoord_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}

Generated with cgit - Back to sebastiano.tronto.net