diff options
Diffstat (limited to 'src/arch')
| -rw-r--r-- | src/arch/neon.h | 13 | ||||
| -rw-r--r-- | src/arch/portable.h | 23 |
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?) */ | ||
| 34 | STATIC_INLINE int | 33 | STATIC_INLINE int |
| 35 | popcount_u32(uint32_t x) | 34 | popcount_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 | ||
| 45 | STATIC void | 46 | STATIC 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?) */ | ||
| 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 |
