From 7cd4c1f12fa3d812e8dd1d4018752378ab2e796c Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Sun, 20 Apr 2025 17:13:14 -0500 Subject: [PATCH] Adopted shift-table hack for lfsr_tag_mask This is based off the parity impl in Sean Eron Anderson's Bit Twiddling Hacks, who attributes the idea to Mathew Hendry. Basically the idea is to encode a small lookup table in an integer, and extract using a shift + mask: .-- LFSR_TAG_MASK0 .|-- LFSR_TAG_MASK2 .||-- LFSR_TAG_MASK8 .|||-- LFSR_TAG_MASK12 vvvv 0x0fff & (-1U << ((0xc820 >> (4*((tag >> 12) & 0x3))) & 0xf)) '--.-' ^ '--------.--------' key mask gcc complains w/o this mask bits Saves a bit of code at the cost of some stack. I guess because GCC is trying to avoid multiple constant pool lookups? This may just be compiler noise: code stack ctx before: 35692 2432 640 after: 35688 (-0.0%) 2440 (+0.3%) 640 (+0.0%) --- lfs.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lfs.c b/lfs.c index a7b44623..1f1ac8be 100644 --- a/lfs.c +++ b/lfs.c @@ -1255,12 +1255,8 @@ static inline bool lfsr_tag_ismask12(lfsr_tag_t tag) { return ((tag >> 12) & 0x3) == 3; } -static const uint16_t lfsr_tag_masktable[4] = { - 0x0fff, 0x0ffc, 0x0f00, 0x0000 -}; - static inline lfsr_tag_t lfsr_tag_mask(lfsr_tag_t tag) { - return lfsr_tag_masktable[(tag >> 12) & 0x3]; + return 0x0fff & (-1U << ((0xc820 >> (4*((tag >> 12) & 0x3))) & 0xf)); } // alt operations