aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arch/avx2.h88
-rw-r--r--src/core/cube.h6
2 files changed, 32 insertions, 62 deletions
diff --git a/src/arch/avx2.h b/src/arch/avx2.h
index 4682e33..ad4ee0d 100644
--- a/src/arch/avx2.h
+++ b/src/arch/avx2.h
@@ -1,10 +1,16 @@
1#define CO2_AVX2 _mm256_set_epi64x(0, 0, 0, INT64_C(0x6060606060606060)) 1#define CO2_AVX2 _mm256_set_epi64x(0, 0, 0, INT64_C(0x6060606060606060))
2#define COCW_AVX2 _mm256_set_epi64x(0, 0, 0, INT64_C(0x2020202020202020)) 2#define COCW_AVX2 _mm256_set_epi64x(0, 0, 0, INT64_C(0x2020202020202020))
3#define CP_AVX2 _mm256_set_epi64x(0, 0, 0, INT64_C(0x0707070707070707)) 3#define CP_AVX2 _mm256_set_epi64x(0, 0, 0, INT64_C(0x0707070707070707))
4#define EP_AVX2 \ 4#define EP_AVX2 _mm256_set_epi64x(\
5 _mm256_set_epi64x(INT64_C(0x0F0F0F0F), INT64_C(0x0F0F0F0F0F0F0F0F), 0, 0) 5 INT64_C(0x0F0F0F0F), INT64_C(0x0F0F0F0F0F0F0F0F), 0, 0)
6#define EO_AVX2 \ 6#define EO_AVX2 _mm256_set_epi64x(\
7 _mm256_set_epi64x(INT64_C(0x10101010), INT64_C(0x1010101010101010), 0, 0) 7 INT64_C(0x10101010), INT64_C(0x1010101010101010), 0, 0)
8#define ORIENT_AVX2 _mm256_set_epi64x(INT64_C(0x10101010), \
9 INT64_C(0x1010101010101010), 0, INT64_C(0x6060606060606060))
10#define USED_AVX2 _mm256_set_epi64x(INT64_C(0x00000000FFFFFFFF), \
11 INT64_C(0xFFFFFFFFFFFFFFFF), 0, INT64_C(0xFFFFFFFFFFFFFFFF))
12#define CARRY_AVX2 _mm256_set_epi64x(INT64_C(0x20202020), \
13 INT64_C(0x2020202020202020), 0, INT64_C(0x6060606060606060))
8 14
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) \
@@ -61,76 +67,36 @@ invertco(cube_t c)
61} 67}
62 68
63STATIC_INLINE cube_t 69STATIC_INLINE cube_t
64compose_epcpeo(cube_t c1, cube_t c2)
65{
66 cube_t b, s, eo2;
67
68 /* Permute and clean unused bits */
69 s = _mm256_shuffle_epi8(c1, c2);
70 b = _mm256_set_epi8(
71 ~0, ~0, ~0, ~0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
72 ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, 0, 0, 0, 0, 0, 0, 0, 0
73 );
74 s = _mm256_andnot_si256(b, s);
75
76 /* Change EO */
77 eo2 = _mm256_and_si256(c2, EO_AVX2);
78 s = _mm256_xor_si256(s, eo2);
79
80 return s;
81}
82
83STATIC_INLINE cube_t
84compose_edges(cube_t c1, cube_t c2) 70compose_edges(cube_t c1, cube_t c2)
85{ 71{
86 return compose_epcpeo(c1, c2); 72 return compose(c1, c2);
87} 73}
88 74
89STATIC_INLINE cube_t 75STATIC_INLINE cube_t
90compose_corners(cube_t c1, cube_t c2) 76compose_corners(cube_t c1, cube_t c2)
91{ 77{
92 /*
93 * We do a full compose. Minor optimizations are possible, like
94 * saving one instruction by not doing EO, but it should not
95 * be significant.
96 */
97 return compose(c1, c2); 78 return compose(c1, c2);
98} 79}
99 80
100STATIC_INLINE cube_t 81STATIC_INLINE cube_t
101compose(cube_t c1, cube_t c2) 82compose(cube_t c1, cube_t c2)
102{ 83{
103 cube_t s, co1, co2, aux, auy1, auy2, auz1, auz2; 84 /*
104 85 * Method taken from Andrew Skalski's vcube (thanks to Arhan Chaudhary
105 s = compose_epcpeo(c1, c2); 86 * for pointing this out)
106 87 */
107 /* Change CO */ 88 cube_t ss, so, su;
108 co1 = _mm256_and_si256(s, CO2_AVX2);
109 co2 = _mm256_and_si256(c2, CO2_AVX2);
110 aux = _mm256_add_epi8(co1, co2);
111 auy1 = _mm256_add_epi8(aux, COCW_AVX2);
112 auy2 = _mm256_srli_epi32(auy1, 2);
113 auz1 = _mm256_add_epi8(aux, auy2);
114 auz2 = _mm256_and_si256(auz1, CO2_AVX2);
115
116 /* Put together */
117 s = _mm256_andnot_si256(CO2_AVX2, s);
118 s = _mm256_or_si256(s, auz2);
119
120 return s;
121}
122 89
123STATIC_INLINE cube_t 90 /* Permute */
124cleanaftershuffle(cube_t c) 91 ss = _mm256_shuffle_epi8(c1, c2);
125{
126 __m256i b;
127 92
128 b = _mm256_set_epi8( 93 /* Orient */
129 ~0, ~0, ~0, ~0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94 so = _mm256_and_si256(c2, ORIENT_AVX2);
130 ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, 0, 0, 0, 0, 0, 0, 0, 0 95 ss = _mm256_add_epi8(ss, so);
131 ); 96 su = _mm256_sub_epi8(ss, CARRY_AVX2);
97 ss = _mm256_min_epu8(ss, su);
132 98
133 return _mm256_andnot_si256(b, c); 99 return _mm256_and_si256(ss, USED_AVX2);
134} 100}
135 101
136STATIC_INLINE cube_t 102STATIC_INLINE cube_t
@@ -163,11 +129,11 @@ inverse(cube_t c)
163 vi = _mm256_shuffle_epi8(vi, vi); 129 vi = _mm256_shuffle_epi8(vi, vi);
164 vi = _mm256_shuffle_epi8(vi, c); 130 vi = _mm256_shuffle_epi8(vi, c);
165 131
166 vo = _mm256_and_si256(c, _mm256_or_si256(EO_AVX2, CO2_AVX2)); 132 vo = _mm256_and_si256(c, ORIENT_AVX2);
167 vo = _mm256_shuffle_epi8(vo, vi); 133 vo = _mm256_shuffle_epi8(vo, vi);
168 vp = _mm256_andnot_si256(_mm256_or_si256(EO_AVX2, CO2_AVX2), vi); 134 vp = _mm256_andnot_si256(ORIENT_AVX2, vi);
169 ret = _mm256_or_si256(vp, vo); 135 ret = _mm256_or_si256(vp, vo);
170 ret = cleanaftershuffle(ret); 136 ret = _mm256_and_si256(ret, USED_AVX2);
171 137
172 return invertco(ret); 138 return invertco(ret);
173} 139}
diff --git a/src/core/cube.h b/src/core/cube.h
index 3dd3ccb..ce8a6b8 100644
--- a/src/core/cube.h
+++ b/src/core/cube.h
@@ -109,9 +109,13 @@ issolvable(cube_t cube)
109 return true; 109 return true;
110 110
111issolvable_parity: 111issolvable_parity:
112 LOG("There is parity\n");
113 return false;
112issolvable_eo: 114issolvable_eo:
115 LOG("EO is not solvable\n");
116 return false;
113issolvable_co: 117issolvable_co:
114 /* We used to do more logging here, hence the 3 different labels */ 118 LOG("CO is not solvable\n");
115 return false; 119 return false;
116} 120}
117 121

Generated with cgit - Back to sebastiano.tronto.net