diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2025-07-24 09:00:49 +0200 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2025-07-24 10:18:07 +0200 |
| commit | 7c3701364542355c29b2e4ebc6d719ddd123c0f2 (patch) | |
| tree | 78a7aed4aea3a8f438a61ff2af4dff481767becd /src/arch/portable.h | |
| parent | 836d626e7caba9578c3440ec0484e7ff1b4cc48e (diff) | |
| download | nissy-core-7c3701364542355c29b2e4ebc6d719ddd123c0f2.tar.gz nissy-core-7c3701364542355c29b2e4ebc6d719ddd123c0f2.zip | |
Use bit trick for portable and arm popcount
Diffstat (limited to '')
| -rw-r--r-- | src/arch/portable.h | 23 |
1 files changed, 18 insertions, 5 deletions
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?) */ | ||
| 13 | STATIC_INLINE int | 12 | STATIC_INLINE int |
| 14 | popcount_u32(uint32_t x) | 13 | popcount_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 | ||
| 24 | STATIC void | 37 | STATIC void |
