From 967c97bb59dfa37d4423684c7357e660ad1e3bbf Mon Sep 17 00:00:00 2001 From: Maria Matejka Date: Tue, 12 Mar 2024 21:08:29 +0100 Subject: [PATCH] Bitops: bitflip function to flip order of bits in 32b numbers --- lib/bitops.c | 18 ++++++++++++++++++ lib/bitops.h | 2 ++ lib/bitops_test.c | 26 ++++++++++++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/lib/bitops.c b/lib/bitops.c index efb8710e..4b6fee4a 100644 --- a/lib/bitops.c +++ b/lib/bitops.c @@ -68,3 +68,21 @@ u32_log2(u32 v) return r; } + +/** + * u32_bitflip - flips bits in number. + * @n: number + * + * This function flips bits in the given number such that MSB becomes LSB and vice versa. + */ + +u32 +u32_bitflip(u32 n) +{ + n = ((n & 0xffff0000) >> 16) | ((n & 0x0000ffff) << 16); + n = ((n & 0xff00ff00) >> 8) | ((n & 0x00ff00ff) << 8); + n = ((n & 0xf0f0f0f0) >> 4) | ((n & 0x0f0f0f0f) << 4); + n = ((n & 0xcccccccc) >> 2) | ((n & 0x33333333) << 2); + n = ((n & 0xaaaaaaaa) >> 1) | ((n & 0x55555555) << 1); + return n; +} diff --git a/lib/bitops.h b/lib/bitops.h index 0beda2a3..1db89f0b 100644 --- a/lib/bitops.h +++ b/lib/bitops.h @@ -25,6 +25,8 @@ uint u32_masklen(u32 x); u32 u32_log2(u32 v); +u32 u32_bitflip(u32 n); + static inline u32 u32_hash(u32 v) { return v * 2902958171u; } static inline u8 u32_popcount(u32 v) { return __builtin_popcount(v); } diff --git a/lib/bitops_test.c b/lib/bitops_test.c index f816b9d1..db2bdc03 100644 --- a/lib/bitops_test.c +++ b/lib/bitops_test.c @@ -110,6 +110,31 @@ t_log2(void) return 1; } +static void +check_bitflip(u32 n) +{ + u32 rot = u32_bitflip(n); + for (int i = 0; i < 16; i++) + { + bt_assert(!((n >> i) & 1) == !((rot << i) & 0x80000000)); + bt_assert(!((rot >> i) & 1) == !((n << i) & 0x80000000)); + } +} + +static int +t_bitflip(void) +{ + u32 i; + + for (i = 0; i < MAX_NUM; i++) + { + check_bitflip(i); + check_bitflip((u32) bt_random()); + } + + return 1; +} + int main(int argc, char *argv[]) { @@ -118,6 +143,7 @@ main(int argc, char *argv[]) bt_test_suite(t_mkmask, "u32_mkmask()"); bt_test_suite(t_masklen, "u32_masklen()"); bt_test_suite(t_log2, "u32_log2()"); + bt_test_suite(t_bitflip, "u32_bitflip()"); return bt_exit_value(); }