aboutsummaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2025-07-24 09:00:49 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2025-07-24 10:18:07 +0200
commit7c3701364542355c29b2e4ebc6d719ddd123c0f2 (patch)
tree78a7aed4aea3a8f438a61ff2af4dff481767becd /src/arch
parent836d626e7caba9578c3440ec0484e7ff1b4cc48e (diff)
downloadnissy-core-7c3701364542355c29b2e4ebc6d719ddd123c0f2.tar.gz
nissy-core-7c3701364542355c29b2e4ebc6d719ddd123c0f2.zip
Use bit trick for portable and arm popcount
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/neon.h13
-rw-r--r--src/arch/portable.h23
2 files changed, 25 insertions, 11 deletions
diff --git a/src/arch/neon.h b/src/arch/neon.h
index 6261c9a..1fb1c82 100644
--- a/src/arch/neon.h
+++ b/src/arch/neon.h
@@ -30,16 +30,17 @@ STATIC_INLINE uint8x8_t compose_corners_slim(uint8x8_t, uint8x8_t);
30#define SOLVED_CUBE STATIC_CUBE( \ 30#define SOLVED_CUBE STATIC_CUBE( \
31 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) 31 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
32 32
33/* TODO: optimize this (use intrinsics?) */
34STATIC_INLINE int 33STATIC_INLINE int
35popcount_u32(uint32_t x) 34popcount_u32(uint32_t x)
36{ 35{
37 int ret; 36 /* Same as the portable version */
37 x -= (x >> UINT32_C(1)) & UINT32_C(0x55555555);
38 x = (x & UINT32_C(0x33333333)) +
39 ((x >> UINT32_C(2)) & UINT32_C(0x33333333));
40 x = (x + (x >> UINT32_C(4))) & UINT32_C(0x0F0F0F0F);
41 x = (x * UINT32_C(0x01010101)) >> UINT32_C(24);
38 42
39 for (ret = 0; x != 0; x >>= 1) 43 return (int)x;
40 ret += x & 1;
41
42 return ret;
43} 44}
44 45
45STATIC void 46STATIC void
diff --git a/src/arch/portable.h b/src/arch/portable.h
index 56d3074..bd67c18 100644
--- a/src/arch/portable.h
+++ b/src/arch/portable.h
@@ -9,16 +9,29 @@
9#define SOLVED_CUBE STATIC_CUBE( \ 9#define SOLVED_CUBE STATIC_CUBE( \
10 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) 10 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
11 11
12/* TODO: optimize this (use bit tricks?) */
13STATIC_INLINE int 12STATIC_INLINE int
14popcount_u32(uint32_t x) 13popcount_u32(uint32_t x)
15{ 14{
16 int ret; 15 /*
16 Bit trick: accumulate in pairs of bits, quads of bits and so on,
17 until the final result is the sum of all bits.
17 18
18 for (ret = 0; x != 0; x >>= 1) 19 x = (x & 0x55555555) + ((x >> 1) & 0x55555555);
19 ret += x & 1; 20 x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
21 x = (x & 0x0F0F0F0F) + ((x >> 4) & 0x0F0F0F0F);
22 x = (x & 0x00FF00FF) + ((x >> 8) & 0x00FF00FF);
23 x = (x & 0x0000FFFF) + ((x >> 16) & 0x0000FFFF);
20 24
21 return ret; 25 The actual method we use is a small optimization of the one above.
26 */
27
28 x -= (x >> UINT32_C(1)) & UINT32_C(0x55555555);
29 x = (x & UINT32_C(0x33333333)) +
30 ((x >> UINT32_C(2)) & UINT32_C(0x33333333));
31 x = (x + (x >> UINT32_C(4))) & UINT32_C(0x0F0F0F0F);
32 x = (x * UINT32_C(0x01010101)) >> UINT32_C(24);
33
34 return (int)x;
22} 35}
23 36
24STATIC void 37STATIC void

Generated with cgit - Back to sebastiano.tronto.net