From 670b8e673259694349c87805b413f716c173d31d Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Sun, 20 Apr 2025 16:24:09 -0500 Subject: [PATCH] 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. --- lfs_util.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/lfs_util.h b/lfs_util.h index b46eaff3..544724a8 100644 --- a/lfs_util.h +++ b/lfs_util.h @@ -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 }