diff --git a/include/CppCore.Test/Math/Util.h b/include/CppCore.Test/Math/Util.h
index 5c117e63..ab258fb3 100644
--- a/include/CppCore.Test/Math/Util.h
+++ b/include/CppCore.Test/Math/Util.h
@@ -24,7 +24,17 @@ namespace CppCore { namespace Test { namespace Math
CppCore::getbits32(0x00000011U, 0x000000FFU) == 0x00000011U &&
CppCore::getbits32(0x0000FF00U, 0x000000FFU) == 0x00000000U &&
CppCore::getbits32(0xFFFFFFFFU, 0xFFFFFFFFU) == 0xFFFFFFFFU;
- return a && b;
+ if (!a || !b)
+ return false;
+ uint32_t r[2];
+ r[1] = 0x00000000U; r[0] = 0x00000000U; if (CppCore::getbits32(r, 0, 32) != 0x00000000U) return false;
+ r[1] = 0x00000001U; r[0] = 0x80000000U; if (CppCore::getbits32(r, 31, 2) != 0x00000003U) return false;
+ r[1] = 0x0000FF01U; r[0] = 0x80FF0000U; if (CppCore::getbits32(r, 31, 2) != 0x00000003U) return false;
+ r[1] = 0x80000000U; r[0] = 0x00000000U; if (CppCore::getbits32(r, 63, 1) != 0x00000001U) return false;
+ r[1] = 0xFFFFFFFFU; r[0] = 0xFFFFFFFFU; if (CppCore::getbits32(r, 16, 32) != 0xFFFFFFFFU) return false;
+ r[1] = 0x00000000U; r[0] = 0xFFFFFFFFU; if (CppCore::getbits32(r, 0, 32) != 0xFFFFFFFFU) return false;
+ r[1] = 0xFFFFFFFFU; r[0] = 0x00000000U; if (CppCore::getbits32(r, 32, 32) != 0xFFFFFFFFU) return false;
+ return true;
}
INLINE static bool getbits64()
@@ -41,7 +51,17 @@ namespace CppCore { namespace Test { namespace Math
CppCore::getbits64(0x0000000000000011ULL, 0x00000000000000FFULL) == 0x0000000000000011ULL &&
CppCore::getbits64(0x000000000000FF00ULL, 0x00000000000000FFULL) == 0x0000000000000000ULL &&
CppCore::getbits64(0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL) == 0xFFFFFFFFFFFFFFFFULL;
- return a && b;
+ if (!a || !b)
+ return false;
+ uint64_t r[2];
+ r[1]=0x0000000000000000ULL; r[0]= 0x0000000000000000ULL; if (CppCore::getbits64(r, 0, 64) != 0x0000000000000000ULL) return false;
+ r[1]=0x0000000000000001ULL; r[0]= 0x8000000000000000ULL; if (CppCore::getbits64(r, 63, 2) != 0x0000000000000003ULL) return false;
+ r[1]=0x000000000000FF01ULL; r[0]= 0x80FF000000000000ULL; if (CppCore::getbits64(r, 63, 2) != 0x0000000000000003ULL) return false;
+ r[1]=0x8000000000000000ULL; r[0]= 0x0000000000000000ULL; if (CppCore::getbits64(r, 127, 1) != 0x0000000000000001ULL) return false;
+ r[1]=0x00000000FFFFFFFFULL; r[0]= 0xFFFFFFFF00000000ULL; if (CppCore::getbits64(r, 32, 64) != 0xFFFFFFFFFFFFFFFFULL) return false;
+ r[1]=0x0000000000000000ULL; r[0]= 0xFFFFFFFFFFFFFFFFULL; if (CppCore::getbits64(r, 0, 64) != 0xFFFFFFFFFFFFFFFFULL) return false;
+ r[1]=0xFFFFFFFFFFFFFFFFULL; r[0]= 0x0000000000000000ULL; if (CppCore::getbits64(r, 64, 64) != 0xFFFFFFFFFFFFFFFFULL) return false;
+ return true;
}
INLINE static bool setbit32()
diff --git a/include/CppCore/Math/Util.h b/include/CppCore/Math/Util.h
index c1aaf0a1..3c389552 100644
--- a/include/CppCore/Math/Util.h
+++ b/include/CppCore/Math/Util.h
@@ -105,6 +105,27 @@ namespace CppCore
#endif
}
+ ///
+ /// Extracts up to 32 bits from an integer that's a multiple of 32 bit.
+ ///
+ template
+ static INLINE uint32_t getbits32(const UINT& v, const uint32_t i, const uint32_t n)
+ {
+ static_assert(sizeof(UINT) % 4 == 0);
+ assert(i+n <= sizeof(UINT) * 8);
+ assert(n <= 32);
+ static constexpr size_t N32 = sizeof(UINT) / 4;
+ const uint32_t* p = (uint32_t*)&v;
+ const uint32_t idx = i >> 5;
+ const uint32_t off = i & 0x1F;
+ uint32_t r = p[idx];
+ if (off)
+ r = (idx+1 < N32) ? CppCore::shrd32(r, p[idx+1], off) : r >> off;
+ if (n < 32)
+ r &= (1U << n) - 1U;
+ return r;
+ }
+
///
/// Returns in lowbits the n bits starting at index i from 64-bit integer v.
/// Undefined return for i >= 64 (use i AND 0x3F to map cyclic).
@@ -132,6 +153,27 @@ namespace CppCore
#endif
}
+ ///
+ /// Extracts up to 64 bits from an integer that's a multiple of 64 bit.
+ ///
+ template
+ static INLINE uint64_t getbits64(const UINT& v, const uint32_t i, const uint32_t n)
+ {
+ static_assert(sizeof(UINT) % 8 == 0);
+ assert(i+n <= sizeof(UINT) * 8);
+ assert(n <= 64);
+ static constexpr size_t N64 = sizeof(UINT) / 8;
+ const uint64_t* p = (uint64_t*)&v;
+ const uint32_t idx = i >> 6;
+ const uint32_t off = i & 0x3F;
+ uint64_t r = p[idx];
+ if (off)
+ r = (idx+1 < N64) ? CppCore::shrd64(r, p[idx+1], off) : r >> off;
+ if (n < 64)
+ r &= (1ULL << n) - 1ULL;
+ return r;
+ }
+
///
/// Sets bits that are 1 in mask to 0 in 32-bit integer v and returns it.
/// Uses BMI1 if enabled.