aboutsummaryrefslogtreecommitdiff
path: root/src/cube.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cube.c')
-rw-r--r--src/cube.c128
1 files changed, 101 insertions, 27 deletions
diff --git a/src/cube.c b/src/cube.c
index 4651b00..fc04ee7 100644
--- a/src/cube.c
+++ b/src/cube.c
@@ -14,10 +14,38 @@
14 14
15#include "_constants.c" 15#include "_constants.c"
16 16
17cube_arr_t solvedcube_arr = {
18 .c = {0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0},
19 .e = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, 0, 0}
20};
21cube_arr_t zerocube_arr = { .e = {0}, .c = {0} };
22
17#ifdef CUBE_AVX2 23#ifdef CUBE_AVX2
18#include "_base_avx2.c" 24
25#define setsolved(cube) cube = _mm256_loadu_si256((__m256i_u *)&solvedcube_arr)
26#define setzero(cube) cube = _mm256_setzero_si256()
27#define _c _mm256_set_epi64x(0, 0, 0, 0xFF)
28#define _e _mm256_set_epi64x(0, 0xFF, 0, 0)
29/* TODO: in the next 4 macros, all 0 should be i, but must be constant! */
30#define get_edge(cube, i) _mm256_extract_epi8(cube, 0+16)
31#define get_corner(cube, i) _mm256_extract_epi8(cube, 0)
32#define set_edge(cube, i, p) _mm256_or_si256( \
33 _mm256_andnot_si256(cube, _mm256_slli_si256(_e, 0)), \
34 _mm256_and_si256(_mm256_set1_epi8(p), _mm256_slli_si256(_e, 0)))
35#define set_corner(cube, i, p) _mm256_or_si256( \
36 _mm256_andnot_si256(cube, _mm256_slli_si256(_c, 0)), \
37 _mm256_and_si256(_mm256_set1_epi8(p), _mm256_slli_si256(_c, 0)))
38
19#else 39#else
20#include "_base_arr.c" 40
41#define setsolved(cube) cube = solvedcube_arr
42#define setzero(cube) cube = zerocube_arr
43#define _c _mm256_set_epi64x(0, 0, 0, 0xFF)
44#define get_edge(cube, i) (cube).e[(i)]
45#define get_corner(cube, i) (cube).c[(i)]
46#define set_edge(cube, i, p) (cube).e[(i)] = (p)
47#define set_corner(cube, i, p) (cube).c[(i)] = (p)
48
21#endif 49#endif
22 50
23static bool isconsistent(cube_t); 51static bool isconsistent(cube_t);
@@ -34,6 +62,22 @@ static int writepiece_SRC(uint8_t, char *);
34static void writecube_SRC(cube_t, char *); 62static void writecube_SRC(cube_t, char *);
35static int permsign(uint8_t *, int); 63static int permsign(uint8_t *, int);
36 64
65cube_t
66solvedcube(void)
67{
68 cube_t solved;
69 setsolved(solved);
70 return solved;
71}
72
73cube_t
74zerocube(void)
75{
76 cube_t solved;
77 setzero(solved);
78 return solved;
79}
80
37static uint8_t 81static uint8_t
38readco(char *str) 82readco(char *str)
39{ 83{
@@ -100,30 +144,34 @@ readcube_H48(char *buf)
100{ 144{
101 int i; 145 int i;
102 uint8_t piece, orient; 146 uint8_t piece, orient;
103 cube_t ret = zerocube; 147 cube_t ret, err;
104 char *b = buf; 148 char *b;
149
150 setzero(ret);
151 setzero(err);
152 b = buf;
105 153
106 for (i = 0; i < 12; i++) { 154 for (i = 0; i < 12; i++) {
107 while (*b == ' ' || *b == '\t' || *b == '\n') 155 while (*b == ' ' || *b == '\t' || *b == '\n')
108 b++; 156 b++;
109 if ((piece = readep(b)) == _error) 157 if ((piece = readep(b)) == _error)
110 return errorcube; 158 return err;
111 b += 2; 159 b += 2;
112 if ((orient = readeo(b)) == _error) 160 if ((orient = readeo(b)) == _error)
113 return errorcube; 161 return err;
114 b++; 162 b++;
115 set_edge(&ret, i, piece | orient); 163 set_edge(ret, i, piece | orient);
116 } 164 }
117 for (i = 0; i < 8; i++) { 165 for (i = 0; i < 8; i++) {
118 while (*b == ' ' || *b == '\t' || *b == '\n') 166 while (*b == ' ' || *b == '\t' || *b == '\n')
119 b++; 167 b++;
120 if ((piece = readcp(b)) == _error) 168 if ((piece = readcp(b)) == _error)
121 return errorcube; 169 return err;
122 b += 3; 170 b += 3;
123 if ((orient = readco(b)) == _error) 171 if ((orient = readco(b)) == _error)
124 return errorcube; 172 return err;
125 b++; 173 b++;
126 set_corner(&ret, i, piece | orient); 174 set_corner(ret, i, piece | orient);
127 } 175 }
128 176
129 return ret; 177 return ret;
@@ -142,7 +190,7 @@ readcube(format_t format, char *buf)
142 #ifdef DEBUG 190 #ifdef DEBUG
143 fprintf(stderr, "Cannot read cube in the given format\n"); 191 fprintf(stderr, "Cannot read cube in the given format\n");
144 #endif 192 #endif
145 ret = errorcube; 193 setzero(ret);
146 } 194 }
147 195
148#ifdef DEBUG 196#ifdef DEBUG
@@ -373,6 +421,18 @@ writetrans(trans_t t, char *buf)
373 buf[11] = '\0'; 421 buf[11] = '\0';
374} 422}
375 423
424move_t
425inverse_move(move_t m)
426{
427 return inverse_move_arr[m];
428}
429
430trans_t
431inverse_trans(trans_t t)
432{
433 return inverse_trans_arr[t];
434}
435
376static int 436static int
377permsign(uint8_t *a, int n) 437permsign(uint8_t *a, int n)
378{ 438{
@@ -532,18 +592,24 @@ equal(cube_t cube1, cube_t cube2)
532bool 592bool
533issolved(cube_t cube) 593issolved(cube_t cube)
534{ 594{
535 return equal(cube, solvedcube); 595 cube_t solved;
596 setsolved(solved);
597 return equal(cube, solved);
536} 598}
537 599
538bool 600bool
539iserror(cube_t cube) 601iserror(cube_t cube)
540{ 602{
541 return equal(cube, errorcube); 603 cube_t err;
604 setzero(err);
605 return equal(cube, err);
542} 606}
543 607
544cube_t 608cube_t
545move(cube_t c, move_t m) 609move(cube_t c, move_t m)
546{ 610{
611 cube_t err;
612
547#ifdef DEBUG 613#ifdef DEBUG
548 if (!isconsistent(c)) { 614 if (!isconsistent(c)) {
549 fprintf(stderr, "move error, inconsistent cube\n"); 615 fprintf(stderr, "move error, inconsistent cube\n");
@@ -558,7 +624,8 @@ move(cube_t c, move_t m)
558#endif 624#endif
559 625
560move_error: 626move_error:
561 return errorcube; 627 setzero(err);
628 return err;
562} 629}
563 630
564cube_t 631cube_t
@@ -566,25 +633,27 @@ inverse(cube_t c)
566{ 633{
567 /* TODO: optimize for avx2 */ 634 /* TODO: optimize for avx2 */
568 uint8_t i, piece, orien; 635 uint8_t i, piece, orien;
569 cube_t ret = zerocube; 636 cube_t ret;
637
638 setzero(ret);
570 639
571#ifdef DEBUG 640#ifdef DEBUG
572 if (!isconsistent(c)) { 641 if (!isconsistent(c)) {
573 fprintf(stderr, "inverse error, inconsistent cube\n"); 642 fprintf(stderr, "inverse error, inconsistent cube\n");
574 return errorcube; 643 return ret;
575 } 644 }
576#endif 645#endif
577 646
578 for (i = 0; i < 12; i++) { 647 for (i = 0; i < 12; i++) {
579 piece = get_edge(c, i); 648 piece = get_edge(c, i);
580 orien = piece & _eobit; 649 orien = piece & _eobit;
581 set_edge(&ret, piece & _pbits, i | orien); 650 set_edge(ret, piece & _pbits, i | orien);
582 } 651 }
583 652
584 for (i = 0; i < 8; i++) { 653 for (i = 0; i < 8; i++) {
585 piece = get_corner(c, i); 654 piece = get_corner(c, i);
586 orien = ((piece << 1) | (piece >> 1)) & _cobits2; 655 orien = ((piece << 1) | (piece >> 1)) & _cobits2;
587 set_corner(&ret, piece & _pbits, i | orien); 656 set_corner(ret, piece & _pbits, i | orien);
588 } 657 }
589 658
590 return ret; 659 return ret;
@@ -595,12 +664,14 @@ compose(cube_t c1, cube_t c2)
595{ 664{
596 /* TODO: optimize for avx2 */ 665 /* TODO: optimize for avx2 */
597 uint8_t i, piece1, piece2, p, orien, aux, auy; 666 uint8_t i, piece1, piece2, p, orien, aux, auy;
598 cube_t ret = zerocube; 667 cube_t ret;
668
669 setzero(ret);
599 670
600#ifdef DEBUG 671#ifdef DEBUG
601 if (!isconsistent(c1) || !isconsistent(c2)) { 672 if (!isconsistent(c1) || !isconsistent(c2)) {
602 fprintf(stderr, "compose error, inconsistent cube\n"); 673 fprintf(stderr, "compose error, inconsistent cube\n");
603 return errorcube; 674 return ret;
604 } 675 }
605#endif 676#endif
606 677
@@ -609,7 +680,7 @@ compose(cube_t c1, cube_t c2)
609 p = piece2 & _pbits; 680 p = piece2 & _pbits;
610 piece1 = get_edge(c1, p); 681 piece1 = get_edge(c1, p);
611 orien = (piece2 ^ piece1) & _eobit; 682 orien = (piece2 ^ piece1) & _eobit;
612 set_edge(&ret, i, (piece1 & _pbits) | orien); 683 set_edge(ret, i, (piece1 & _pbits) | orien);
613 } 684 }
614 685
615 for (i = 0; i < 8; i++) { 686 for (i = 0; i < 8; i++) {
@@ -619,7 +690,7 @@ compose(cube_t c1, cube_t c2)
619 aux = (piece2 & _cobits) + (piece1 & _cobits); 690 aux = (piece2 & _cobits) + (piece1 & _cobits);
620 auy = (aux + _ctwist_cw) >> 2U; 691 auy = (aux + _ctwist_cw) >> 2U;
621 orien = (aux + auy) & _cobits2; 692 orien = (aux + auy) & _cobits2;
622 set_corner(&ret, i, (piece1 & _pbits) | orien); 693 set_corner(ret, i, (piece1 & _pbits) | orien);
623 } 694 }
624 695
625 return ret; 696 return ret;
@@ -637,7 +708,7 @@ flipallcorners(cube_t c)
637 for (i = 0; i < 8; i++) { 708 for (i = 0; i < 8; i++) {
638 piece = get_corner(c, i); 709 piece = get_corner(c, i);
639 orien = ((piece << 1) | (piece >> 1)) & _cobits2; 710 orien = ((piece << 1) | (piece >> 1)) & _cobits2;
640 set_corner(&ret, i, (piece & _pbits) | orien); 711 set_corner(ret, i, (piece & _pbits) | orien);
641 } 712 }
642 713
643 return ret; 714 return ret;
@@ -646,16 +717,17 @@ flipallcorners(cube_t c)
646cube_t 717cube_t
647transform(cube_t c, trans_t t) 718transform(cube_t c, trans_t t)
648{ 719{
649 cube_t ret; 720 cube_t ret, solved;
650 721
651#ifdef DEBUG 722#ifdef DEBUG
723 setzero(ret);
652 if (!isconsistent(c)) { 724 if (!isconsistent(c)) {
653 fprintf(stderr, "transform error, inconsistent cube\n"); 725 fprintf(stderr, "transform error, inconsistent cube\n");
654 return errorcube; 726 return ret;
655 } 727 }
656 if (t >= 48) { 728 if (t >= 48) {
657 fprintf(stderr, "transform error, unknown transformation\n"); 729 fprintf(stderr, "transform error, unknown transformation\n");
658 return errorcube; 730 return ret;
659 } 731 }
660#endif 732#endif
661 733
@@ -665,7 +737,9 @@ transform(cube_t c, trans_t t)
665#include "_trans_move_arr.c" 737#include "_trans_move_arr.c"
666#endif 738#endif
667 739
668 ret = compose(solvedcube, trans_move_cube[t]); 740 setsolved(solved);
741
742 ret = compose(solved, trans_move_cube[t]);
669 ret = compose(ret, c); 743 ret = compose(ret, c);
670 ret = compose(ret, trans_move_cube_inverse[t]); 744 ret = compose(ret, trans_move_cube_inverse[t]);
671 745

Generated with cgit - Back to sebastiano.tronto.net