From 44eee260db098748a9700b90e7d9741a44b4a651 Mon Sep 17 00:00:00 2001 From: Ravenwater Date: Wed, 13 Nov 2024 12:38:08 -0500 Subject: [PATCH] adding a generic find_msb() implementation for types that support bit patterns --- include/universal/utility/find_msb.hpp | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/include/universal/utility/find_msb.hpp b/include/universal/utility/find_msb.hpp index 45c8d1f7..8943ca53 100644 --- a/include/universal/utility/find_msb.hpp +++ b/include/universal/utility/find_msb.hpp @@ -17,12 +17,22 @@ namespace sw { namespace universal { //static const unsigned int bval[] = { 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4 }; +template +constexpr unsigned find_msb(const BitPatternType& x) { + constexpr unsigned nbits = x.nbits; + for (unsigned i = 0; i < nbits; ++i) { + unsigned bitIndex = nbits - 1 - i; + if (x.test(bitIndex)) return bitIndex + 1; + } + return 0; +} + /// /// find most significant bit that is set /// /// value to scan /// position of MSB that is set. LSB is defined to be at position 1, so no bits set returns 0 -inline constexpr unsigned int find_msb(unsigned int x) { +inline constexpr unsigned find_msb(unsigned int x) { // find the first non-zero bit unsigned int base = 0; if (x & 0xFFFF0000) { base += 16; x >>= 16; } @@ -41,7 +51,7 @@ inline constexpr unsigned int find_msb(unsigned int x) { /// /// value to scan /// position of MSB that is set. LSB is defined to be at position 1, so no bits set returns 0 -inline constexpr unsigned int find_msb(unsigned long x) { +inline constexpr unsigned find_msb(unsigned long x) { // find the first non-zero bit unsigned int base = 0; if (x & 0xFFFF0000) { base += 16; x >>= 16; } @@ -60,7 +70,7 @@ inline constexpr unsigned int find_msb(unsigned long x) { /// /// value to scan /// position of MSB that is set. LSB is defined to be at position 1, so no bits set returns 0 -inline constexpr unsigned int find_msb(unsigned long long x) { +inline constexpr unsigned find_msb(unsigned long long x) { // find the first non-zero bit unsigned int base = 0; if (x & 0xFFFFFFFF00000000) { base += 32; x >>= 32; } @@ -82,7 +92,7 @@ inline constexpr unsigned int find_msb(unsigned long long x) { /// /// value to scan /// position of MSB that is set. LSB is defined to be at position 1, so no bits set returns 0 -inline constexpr unsigned int find_msb(signed char x) { +inline constexpr unsigned find_msb(signed char x) { // find the first non-zero bit uint8_t tmp = uint8_t(x); unsigned int base = 0; @@ -100,7 +110,7 @@ inline constexpr unsigned int find_msb(signed char x) { /// /// value to scan /// position of MSB that is set. LSB is defined to be at position 1, so no bits set returns 0 -inline constexpr unsigned int find_msb(short x) { +inline constexpr unsigned find_msb(short x) { // find the first non-zero bit uint16_t tmp = uint16_t(x); unsigned int base = 0; @@ -119,7 +129,7 @@ inline constexpr unsigned int find_msb(short x) { /// /// value to scan /// position of MSB that is set. LSB is defined to be at position 1, so no bits set returns 0 -inline constexpr unsigned int find_msb(int x) { +inline constexpr unsigned find_msb(int x) { // find the first non-zero bit uint32_t tmp = uint32_t(x); unsigned int base = 0; @@ -139,7 +149,7 @@ inline constexpr unsigned int find_msb(int x) { /// /// value to scan /// position of MSB that is set. LSB is defined to be at position 1, so no bits set returns 0 -inline constexpr unsigned int find_msb(long x) { +inline constexpr unsigned find_msb(long x) { // find the first non-zero bit uint32_t tmp = uint32_t(x); unsigned int base = 0; @@ -160,7 +170,7 @@ inline constexpr unsigned int find_msb(long x) { /// /// value to scan /// position of MSB that is set. LSB is defined to be at position 1, so no bits set returns 0 -inline constexpr unsigned int find_msb(long long x) { +constexpr unsigned find_msb(long long x) { // find the first non-zero bit uint64_t tmp = uint64_t(x); unsigned int base = 0;