From be469405df134f3b9a13020b64873acf1226453f Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Sun, 28 Jan 2024 15:41:50 +0000 Subject: [PATCH] Bitmath: Add utility functions for calculating bit masks Add tests --- src/core/bitmath_func.hpp | 29 +++++++++++++++++++++++++++++ src/tests/bitmath_func.cpp | 19 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/src/core/bitmath_func.hpp b/src/core/bitmath_func.hpp index 12bd02138d..9d3b91a883 100644 --- a/src/core/bitmath_func.hpp +++ b/src/core/bitmath_func.hpp @@ -187,6 +187,35 @@ inline T ToggleBit(T &x, const uint8_t y) return x = (T)(x ^ ((T)1U << y)); } +/** + * Return a bit mask of count bits starting at start. + * + * @param start The start bit + * @param count The number of bits + * @pre start + count < sizeof(T) * 8 + * @return The bit mask + */ +template +constexpr T GetBitMaskSC(const uint8_t start, const uint8_t count) +{ + typename std::make_unsigned::type mask = 1; + return (T)(((mask << count) - 1) << start); +} + +/** + * Return a bit mask of bits from first to last (inclusive). + * + * @param first The first bit + * @param last The last bits (inclusive) + * @pre first <= last && last < sizeof(T) * 8 + * @return The bit mask + */ +template +constexpr T GetBitMaskFL(const uint8_t first, const uint8_t last) +{ + return GetBitMaskSC(first, 1 + last - first); +} + /** * Search the first set bit in a value. * When no bit is set, it returns 0. diff --git a/src/tests/bitmath_func.cpp b/src/tests/bitmath_func.cpp index 8aaf3eae09..7b2fb9c21c 100644 --- a/src/tests/bitmath_func.cpp +++ b/src/tests/bitmath_func.cpp @@ -68,3 +68,22 @@ TEST_CASE("SetBitIterator tests") CHECK(test_case(INT32_MIN, { 31 })); CHECK(test_case(INT64_MIN, { 63 })); } + +TEST_CASE("GetBitMaskSC tests") +{ + CHECK(GetBitMaskSC(4, 4) == 0xF0); + CHECK(GetBitMaskSC(28, 4) == 0xF0000000); + CHECK(GetBitMaskSC(7, 1) == 0x80); + CHECK(GetBitMaskSC(0, 1) == 1); + CHECK(GetBitMaskSC(0, 0) == 0); + CHECK(GetBitMaskSC(7, 0) == 0); +} + +TEST_CASE("GetBitMaskFL tests") +{ + CHECK(GetBitMaskFL(4, 7) == 0xF0); + CHECK(GetBitMaskFL(28, 31) == 0xF0000000); + CHECK(GetBitMaskFL(7, 7) == 0x80); + CHECK(GetBitMaskFL(0, 0) == 1); + CHECK(GetBitMaskFL(3, 4) == 0x18); +}