From ea0387796a349c91032fbcb10f50c6ad8607b0f6 Mon Sep 17 00:00:00 2001 From: Sebastiano Tronto Date: Tue, 29 Jul 2025 12:12:43 +0200 Subject: All coordinates unsigned --- src/arch/avx2.h | 60 ++++++++++++++++++++++++++--------------------------- src/arch/common.h | 36 ++++++++++++++++---------------- src/arch/neon.h | 59 ++++++++++++++++++++++++++-------------------------- src/arch/portable.h | 32 ++++++++++++++-------------- 4 files changed, 93 insertions(+), 94 deletions(-) (limited to 'src/arch') diff --git a/src/arch/avx2.h b/src/arch/avx2.h index 7764c6b..24c8280 100644 --- a/src/arch/avx2.h +++ b/src/arch/avx2.h @@ -25,8 +25,8 @@ #define SOLVED_CUBE _mm256_set_epi64x(SOLVED_H, SOLVED_L, 0, SOLVED_L) -STATIC_INLINE int64_t permtoindex_8x8(int64_t); -STATIC_INLINE int64_t indextoperm_8x8(int64_t); +STATIC_INLINE uint64_t permtoindex_8x8(int64_t); +STATIC_INLINE int64_t indextoperm_8x8(uint64_t); STATIC_INLINE int popcount_u32(uint32_t x) @@ -144,11 +144,11 @@ inverse(cube_t c) return invertco(ret); } -STATIC_INLINE int64_t +STATIC_INLINE uint64_t coord_co(cube_t c) { cube_t co; - int64_t mem[4], ret, i, p; + uint64_t mem[4], ret, i, p; co = _mm256_and_si256(c, CO2_AVX2); _mm256_storeu_si256((__m256i *)mem, co); @@ -161,15 +161,15 @@ coord_co(cube_t c) } STATIC_INLINE cube_t -invcoord_co(int64_t coord) +invcoord_co(uint64_t coord) { - int64_t i, c, p, co, mem[4] = {0}; + uint64_t i, c, p, co, mem[4] = {0}; cube_t cube, cc; for (i = 0, p = 0, c = coord; i < 8; i++, c /= 3) { co = i == 7 ? ((3 - (p % 3)) % 3) : (c % 3); p += co; - mem[0] |= (int64_t)(i + (co << COSHIFT)) << (int64_t)(8 * i); + mem[0] |= (uint64_t)(i + (co << COSHIFT)) << (uint64_t)(8 * i); } cc = _mm256_loadu_si256((const __m256i *)mem); @@ -179,43 +179,43 @@ invcoord_co(int64_t coord) return cube; } -STATIC_INLINE int64_t +STATIC_INLINE uint64_t coord_csep(cube_t c) { cube_t cp, shifted; - int64_t mask; + int mask; cp = _mm256_and_si256(c, CP_AVX2); shifted = _mm256_slli_epi32(cp, 5); mask = _mm256_movemask_epi8(shifted); - return mask & 0x7F; + return (uint64_t)(mask & 0x7F); } -STATIC_INLINE int64_t +STATIC_INLINE uint64_t coord_cocsep(cube_t c) { - return (coord_co(c) << 7) + coord_csep(c); + return (coord_co(c) << UINT8_C(7)) + coord_csep(c); } -STATIC_INLINE int64_t +STATIC_INLINE uint64_t coord_eo(cube_t c) { cube_t eo, shifted; - int64_t mask; + int mask; eo = _mm256_and_si256(c, EO_AVX2); shifted = _mm256_slli_epi32(eo, 3); mask = _mm256_movemask_epi8(shifted); - return mask >> 17; + return (uint64_t)(mask >> 17); } -STATIC_INLINE int64_t +STATIC_INLINE uint64_t coord_esep(cube_t c) { cube_t ep; - int64_t e, mem[4], i, j, jj, k, l, ret1, ret2, bit1, bit2, is1; + uint64_t e, mem[4], i, j, jj, k, l, ret1, ret2, bit1, bit2, is1; ep = _mm256_and_si256(c, EP_AVX2); _mm256_storeu_si256((__m256i *)mem, ep); @@ -243,12 +243,12 @@ coord_esep(cube_t c) } STATIC_INLINE cube_t -invcoord_esep(int64_t esep) +invcoord_esep(uint64_t esep) { cube_t eee, ret; uint8_t mem[32] = {0}; - invcoord_esep_array(esep % 70, esep / 70, mem+16); + invcoord_esep_array(esep % UINT64_C(70), esep / UINT64_C(70), mem+16); ret = SOLVED_CUBE; eee = _mm256_loadu_si256((__m256i_u *)&mem); @@ -270,9 +270,9 @@ copy_edges(cube_t dest[static 1], cube_t src) } STATIC_INLINE void -set_eo(cube_t cube[static 1], int64_t eo) +set_eo(cube_t cube[static 1], uint64_t eo) { - int64_t eo12, eotop, eobot; + uint64_t eo12, eotop, eobot; __m256i veo; eo12 = (eo << 1) + (_mm_popcnt_u64(eo) % 2); @@ -294,17 +294,17 @@ set_eo(cube_t cube[static 1], int64_t eo) *cube = _mm256_or_si256(*cube, veo); } -STATIC_INLINE int64_t +STATIC_INLINE uint64_t permtoindex_8x8(int64_t a) { - int64_t i, c, ret; + uint64_t i, c, ret; __m64 cmp; for (i = 0, ret = 0; i < 8; i++) { cmp = _mm_set1_pi8(a & INT64_C(0xFF)); a = (a >> INT64_C(8)) | INT64_C(0x0F00000000000000); cmp = _mm_cmpgt_pi8(cmp, _mm_cvtsi64_m64(a)); - c = _mm_popcnt_u64(_mm_cvtm64_si64(cmp)) >> INT64_C(3); + c = _mm_popcnt_u64(_mm_cvtm64_si64(cmp)) >> UINT64_C(3); ret += c * factorial[7-i]; } @@ -312,10 +312,10 @@ permtoindex_8x8(int64_t a) } STATIC_INLINE int64_t -indextoperm_8x8(int64_t p) +indextoperm_8x8(uint64_t p) { int used; - int64_t c, k, i, j, ret; + uint64_t c, k, i, j, ret; for (i = 0, ret = 0, used = 0; i < 8; i++) { k = p / factorial[7-i]; @@ -332,7 +332,7 @@ indextoperm_8x8(int64_t p) return ret; } -STATIC_INLINE int64_t +STATIC_INLINE uint64_t coord_cp(cube_t cube) { cube_t cp; @@ -345,12 +345,12 @@ coord_cp(cube_t cube) } STATIC_INLINE cube_t -invcoord_cp(int64_t i) +invcoord_cp(uint64_t i) { return _mm256_set_epi64x(SOLVED_H, SOLVED_L, 0, indextoperm_8x8(i)); } -STATIC_INLINE int64_t +STATIC_INLINE uint64_t coord_epud(cube_t cube) { cube_t ep; @@ -363,7 +363,7 @@ coord_epud(cube_t cube) } STATIC_INLINE cube_t -invcoord_epud(int64_t i) +invcoord_epud(uint64_t i) { return _mm256_set_epi64x(SOLVED_H, indextoperm_8x8(i), 0, SOLVED_L); } diff --git a/src/arch/common.h b/src/arch/common.h index 3e7867d..6c62a2e 100644 --- a/src/arch/common.h +++ b/src/arch/common.h @@ -22,30 +22,30 @@ STATIC_INLINE cube_t compose_corners(cube_t, cube_t); STATIC_INLINE cube_t compose(cube_t, cube_t); STATIC_INLINE cube_t inverse(cube_t); -STATIC_INLINE int64_t coord_co(cube_t); -STATIC_INLINE cube_t invcoord_co(int64_t); -STATIC_INLINE int64_t coord_csep(cube_t); -STATIC_INLINE int64_t coord_cocsep(cube_t); -STATIC_INLINE int64_t coord_eo(cube_t); -STATIC_INLINE int64_t coord_esep(cube_t); -STATIC_INLINE cube_t invcoord_esep(int64_t); +STATIC_INLINE uint64_t coord_co(cube_t); +STATIC_INLINE cube_t invcoord_co(uint64_t); +STATIC_INLINE uint64_t coord_csep(cube_t); +STATIC_INLINE uint64_t coord_cocsep(cube_t); +STATIC_INLINE uint64_t coord_eo(cube_t); +STATIC_INLINE uint64_t coord_esep(cube_t); +STATIC_INLINE cube_t invcoord_esep(uint64_t); STATIC_INLINE void copy_corners(cube_t [static 1], cube_t); STATIC_INLINE void copy_edges(cube_t [static 1], cube_t); -STATIC_INLINE void set_eo(cube_t [static 1], int64_t); +STATIC_INLINE void set_eo(cube_t [static 1], uint64_t); -STATIC_INLINE void invcoord_esep_array(int64_t, int64_t, uint8_t[static 12]); -STATIC_INLINE cube_t invcoord_eoesep(int64_t); +STATIC_INLINE void invcoord_esep_array(uint64_t, uint64_t, uint8_t[static 12]); +STATIC_INLINE cube_t invcoord_eoesep(uint64_t); -STATIC_INLINE int64_t coord_cp(cube_t); -STATIC_INLINE cube_t invcoord_cp(int64_t); -STATIC_INLINE int64_t coord_epud(cube_t); -STATIC_INLINE cube_t invcoord_epud(int64_t); +STATIC_INLINE uint64_t coord_cp(cube_t); +STATIC_INLINE cube_t invcoord_cp(uint64_t); +STATIC_INLINE uint64_t coord_epud(cube_t); +STATIC_INLINE cube_t invcoord_epud(uint64_t); STATIC_INLINE void -invcoord_esep_array(int64_t set1, int64_t set2, uint8_t mem[static 12]) +invcoord_esep_array(uint64_t set1, uint64_t set2, uint8_t mem[static 12]) { - int64_t bit1, bit2, i, j, jj, k, l, s, v, w, is1; + uint64_t bit1, bit2, i, j, jj, k, l, s, v, w, is1; uint8_t slice[3] = {0}; for (i = 0, j = 0, k = 4, l = 4; i < 12; i++) @@ -69,10 +69,10 @@ invcoord_esep_array(int64_t set1, int64_t set2, uint8_t mem[static 12]) } STATIC_INLINE cube_t -invcoord_eoesep(int64_t i) +invcoord_eoesep(uint64_t i) { cube_t c; - int64_t esep, eo; + uint64_t esep, eo; esep = i >> INT64_C(11); eo = i % POW_2_11; diff --git a/src/arch/neon.h b/src/arch/neon.h index a378cf9..fef6220 100644 --- a/src/arch/neon.h +++ b/src/arch/neon.h @@ -29,8 +29,8 @@ STATIC_INLINE uint8x8_t compose_corners_slim(uint8x8_t, uint8x8_t); const uint8_t SOLVED_L[8] = {0, 1, 2, 3, 4, 5, 6, 7}; const uint8_t SOLVED_H[8] = {8, 9, 10, 11, 0, 0, 0}; -STATIC_INLINE int64_t permtoindex_8x8(uint8x8_t); -STATIC_INLINE uint8x8_t indextoperm_8x8(int64_t); +STATIC_INLINE uint64_t permtoindex_8x8(uint8x8_t); +STATIC_INLINE uint8x8_t indextoperm_8x8(uint64_t); STATIC_INLINE int popcount_u32(uint32_t x) @@ -215,16 +215,15 @@ inverse(cube_t cube) return ret; } -STATIC_INLINE int64_t +STATIC_INLINE uint64_t coord_co(cube_t c) { + uint64_t i, p, ret; + // Temp array to store the NEON vector uint8_t mem[8]; vst1_u8(mem, c.corner); - int i, p; - int64_t ret; - for (ret = 0, i = 0, p = 1; i < 7; i++, p *= 3) ret += p * (mem[i] >> COSHIFT); @@ -232,9 +231,9 @@ coord_co(cube_t c) } STATIC_INLINE cube_t -invcoord_co(int64_t coord) +invcoord_co(uint64_t coord) { - int64_t co, c, i, p; + uint64_t co, c, i, p; uint8_t mem[8]; cube_t cube; @@ -250,15 +249,15 @@ invcoord_co(int64_t coord) return cube; } -STATIC_INLINE int64_t +STATIC_INLINE uint64_t coord_csep(cube_t c) { + uint64_t ret, i, p; + // Temp array to store the NEON vector uint8_t mem[8]; vst1_u8(mem, c.corner); - int64_t ret = 0; - int i, p; for (ret = 0, i = 0, p = 1; i < 7; i++, p *= 2) ret += p * ((mem[i] & CSEPBIT) >> 2); @@ -266,23 +265,23 @@ coord_csep(cube_t c) return 0; } -STATIC_INLINE int64_t +STATIC_INLINE uint64_t coord_cocsep(cube_t c) { - return (coord_co(c) << 7) + coord_csep(c); + return (coord_co(c) << UINT64_C(7)) + coord_csep(c); } -STATIC_INLINE int64_t +STATIC_INLINE uint64_t coord_eo(cube_t c) { - int64_t ret = 0; - int64_t p = 1; + uint64_t ret, p; + int i; // Temp array to store the NEON vector uint8_t mem[16]; vst1q_u8(mem, c.edge); - for (int i = 1; i < 12; i++, p *= 2) + for (i = 1, ret = 0, p = 1; i < 12; i++, p *= 2) { ret += p * (mem[i] >> EOSHIFT); } @@ -290,10 +289,10 @@ coord_eo(cube_t c) return ret; } -STATIC_INLINE int64_t +STATIC_INLINE uint64_t coord_esep(cube_t c) { - int64_t i, j, jj, k, l, ret1, ret2, bit1, bit2, is1; + uint64_t i, j, jj, k, l, ret1, ret2, bit1, bit2, is1; // Temp array to store the NEON vector uint8_t mem[16]; @@ -330,7 +329,7 @@ copy_edges(cube_t dst[static 1], cube_t src) } STATIC_INLINE void -set_eo(cube_t cube[static 1], int64_t eo) +set_eo(cube_t cube[static 1], uint64_t eo) { // Temp array to store the NEON vector uint8_t mem[16]; @@ -351,12 +350,12 @@ set_eo(cube_t cube[static 1], int64_t eo) } STATIC_INLINE cube_t -invcoord_esep(int64_t esep) +invcoord_esep(uint64_t esep) { cube_t ret; uint8_t mem[16] = {0}; - invcoord_esep_array(esep % 70, esep / 70, mem); + invcoord_esep_array(esep % UINT64_C(70), esep / UINT64_C(70), mem); ret = SOLVED_CUBE; ret.edge = vld1q_u8(mem); @@ -364,10 +363,10 @@ invcoord_esep(int64_t esep) return ret; } -STATIC_INLINE int64_t +STATIC_INLINE uint64_t permtoindex_8x8(uint8x8_t a) { - int64_t i, c, ret; + uint64_t i, c, ret; uint8x8_t cmp; uint64x1_t anum; uint8_t or[8] = {0, 0, 0, 0, 0, 0, 0, 0x0F}; @@ -387,10 +386,10 @@ permtoindex_8x8(uint8x8_t a) } STATIC_INLINE uint8x8_t -indextoperm_8x8(int64_t p) +indextoperm_8x8(uint64_t p) { int used; - int64_t c, k, i, j; + uint64_t c, k, i, j; uint8_t ret[8]; for (i = 0, used = 0; i < 8; i++) { @@ -408,14 +407,14 @@ indextoperm_8x8(int64_t p) return vld1_u8(ret); } -STATIC_INLINE int64_t +STATIC_INLINE uint64_t coord_cp(cube_t cube) { return permtoindex_8x8(vand_u8(cube.corner, PBITS8_NEON)); } STATIC_INLINE cube_t -invcoord_cp(int64_t i) +invcoord_cp(uint64_t i) { return (cube_t) { .corner = indextoperm_8x8(i), @@ -423,14 +422,14 @@ invcoord_cp(int64_t i) }; } -STATIC_INLINE int64_t +STATIC_INLINE uint64_t coord_epud(cube_t cube) { return permtoindex_8x8(vand_u8(vget_low_u8(cube.edge), PBITS8_NEON)); } STATIC_INLINE cube_t -invcoord_epud(int64_t i) +invcoord_epud(uint64_t i) { return (cube_t) { .corner = vld1_u8(SOLVED_L), diff --git a/src/arch/portable.h b/src/arch/portable.h index ec992a8..5acccf2 100644 --- a/src/arch/portable.h +++ b/src/arch/portable.h @@ -154,7 +154,7 @@ inverse(cube_t cube) return ret; } -STATIC_INLINE int64_t +STATIC_INLINE uint64_t coord_co(cube_t c) { int i, p, ret; @@ -166,9 +166,9 @@ coord_co(cube_t c) } STATIC_INLINE cube_t -invcoord_co(int64_t coord) +invcoord_co(uint64_t coord) { - int64_t i, c, p; + uint64_t i, c, p; cube_t cube; cube = SOLVED_CUBE; @@ -189,11 +189,11 @@ Ignoring the last bit, we have a value up to 2^7, but not all values are possible. Encoding this as a number from 0 to C(8,4) would save about 40% of space, but we are not going to use this coordinate in large tables. */ -STATIC_INLINE int64_t +STATIC_INLINE uint64_t coord_csep(cube_t c) { int i, p; - int64_t ret; + uint64_t ret; for (ret = 0, i = 0, p = 1; i < 7; i++, p *= 2) ret += p * ((c.corner[i] & CSEPBIT) >> 2); @@ -201,17 +201,17 @@ coord_csep(cube_t c) return ret; } -STATIC_INLINE int64_t +STATIC_INLINE uint64_t coord_cocsep(cube_t c) { return (coord_co(c) << 7) + coord_csep(c); } -STATIC_INLINE int64_t +STATIC_INLINE uint64_t coord_eo(cube_t c) { int i, p; - int64_t ret; + uint64_t ret; for (ret = 0, i = 1, p = 1; i < 12; i++, p *= 2) ret += p * (c.edge[i] >> EOSHIFT); @@ -223,10 +223,10 @@ coord_eo(cube_t c) We encode the edge separation as a number from 0 to C(12,4)*C(8,4). It can be seen as the composition of two "subset index" coordinates. */ -STATIC_INLINE int64_t +STATIC_INLINE uint64_t coord_esep(cube_t c) { - int64_t i, j, jj, k, l, ret1, ret2, bit1, bit2, is1; + uint64_t i, j, jj, k, l, ret1, ret2, bit1, bit2, is1; for (i = 0, j = 0, k = 4, l = 4, ret1 = 0, ret2 = 0; i < 12; i++) { /* Simple version: @@ -256,7 +256,7 @@ coord_esep(cube_t c) } STATIC_INLINE cube_t -invcoord_esep(int64_t esep) +invcoord_esep(uint64_t esep) { cube_t ret; @@ -279,7 +279,7 @@ copy_edges(cube_t dest[static 1], cube_t src) } STATIC_INLINE void -set_eo(cube_t cube[static 1], int64_t eo) +set_eo(cube_t cube[static 1], uint64_t eo) { uint8_t i, sum, flip; @@ -291,7 +291,7 @@ set_eo(cube_t cube[static 1], int64_t eo) cube->edge[0] = (cube->edge[0] & ~EOBIT) | (EOBIT * (sum % 2)); } -STATIC_INLINE int64_t +STATIC_INLINE uint64_t coord_cp(cube_t cube) { int i; @@ -303,7 +303,7 @@ coord_cp(cube_t cube) } STATIC_INLINE cube_t -invcoord_cp(int64_t i) +invcoord_cp(uint64_t i) { uint8_t c[8]; @@ -313,7 +313,7 @@ invcoord_cp(int64_t i) 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11); } -STATIC_INLINE int64_t +STATIC_INLINE uint64_t coord_epud(cube_t cube) { int i; @@ -325,7 +325,7 @@ coord_epud(cube_t cube) } STATIC_INLINE cube_t -invcoord_epud(int64_t i) +invcoord_epud(uint64_t i) { uint8_t e[8]; -- cgit v1.3