A couple tweaks to bit twiddling utils

- Gave lfs_parity its own backup implementation.

  Since these are static inline functions, shared implementations don't
  matter as much here, so why do more work than we have to.

  Save a bit of code too:

                         code          stack          ctx
    yes-builtins:       35692           2432          640
    no-builtins before: 35996 (-0.9%)   2504 (+3.0%)  640 (+0.0%)
    no-builtins after:  35960 (-0.8%)   2504 (+3.0%)  640 (+0.0%)

  Though maybe this is an argument for these functions not being static
  inline...

- Tweaked lfs_popc for readability (the 7-digit mask was annoying me).

- Added a link to Sean Eron Anderson's Bit Twiddling Hacks page:
  https://graphics.stanford.edu/~seander/bithacks.html

  These have been published as public domain, so I don't think this is
  strictly necessary, but the page is a great resource and deserves
  mention.
This commit is contained in:
Christopher Haster
2025-04-20 16:24:09 -05:00
parent 306ca25970
commit 670b8e6732
+11 -2
View File
@@ -242,6 +242,11 @@ extern "C"
// Builtin functions, these may be replaced by more efficient
// toolchain-specific implementations. LFS_NO_BUILTINS falls back to a more
// expensive basic C implementation for debugging purposes
//
// Most of the backup implementations are based on the infamous Bit
// Twiddling Hacks compiled by Sean Eron Anderson:
// https://graphics.stanford.edu/~seander/bithacks.html
//
// Compile time min/max
#define LFS_MIN(a, b) ((a < b) ? a : b)
@@ -332,7 +337,8 @@ static inline uint32_t lfs_popc(uint32_t a) {
#else
a = a - ((a >> 1) & 0x55555555);
a = (a & 0x33333333) + ((a >> 2) & 0x33333333);
return (((a + (a >> 4)) & 0xf0f0f0f) * 0x1010101) >> 24;
a = (a + (a >> 4)) & 0x0f0f0f0f;
return (a * 0x1010101) >> 24;
#endif
}
@@ -341,7 +347,10 @@ static inline bool lfs_parity(uint32_t a) {
#if !defined(LFS_NO_BUILTINS) && (defined(__GNUC__) || defined(__CC_ARM))
return __builtin_parity(a);
#else
return lfs_popc(a) & 1;
a ^= a >> 16;
a ^= a >> 8;
a ^= a >> 4;
return (0x6996 >> (a & 0xf)) & 1;
#endif
}