Index: llvm/trunk/include/llvm/Support/MathExtras.h =================================================================== --- llvm/trunk/include/llvm/Support/MathExtras.h +++ llvm/trunk/include/llvm/Support/MathExtras.h @@ -198,6 +198,21 @@ return countTrailingZeros(Val, ZB_Undefined); } +/// \brief Create a bitmask with the N right-most bits set to 1, and all other +/// bits set to 0. Only unsigned types are allowed. +template T maskTrailingOnes(unsigned N) { + static_assert(std::is_unsigned::value, "Invalid type!"); + const unsigned Bits = CHAR_BIT * sizeof(T); + assert(N <= Bits && "Invalid bit index"); + return -T(N != 0) & (T(-1) >> (Bits - N)); +} + +/// \brief Create a bitmask with the N left-most bits set to 1, and all other +/// bits set to 0. Only unsigned types are allowed. +template T maskLeadingOnes(unsigned N) { + return ~maskTrailingOnes(CHAR_BIT * sizeof(T) - N); +} + /// \brief Get the index of the last set bit starting from the least /// significant bit. /// Index: llvm/trunk/unittests/Support/MathExtrasTest.cpp =================================================================== --- llvm/trunk/unittests/Support/MathExtrasTest.cpp +++ llvm/trunk/unittests/Support/MathExtrasTest.cpp @@ -66,6 +66,26 @@ } } +TEST(MathExtras, onesMask) { + EXPECT_EQ(0U, maskLeadingOnes(0)); + EXPECT_EQ(0U, maskTrailingOnes(0)); + EXPECT_EQ(0U, maskLeadingOnes(0)); + EXPECT_EQ(0U, maskTrailingOnes(0)); + EXPECT_EQ(0U, maskLeadingOnes(0)); + EXPECT_EQ(0U, maskTrailingOnes(0)); + EXPECT_EQ(0U, maskLeadingOnes(0)); + EXPECT_EQ(0U, maskTrailingOnes(0)); + + EXPECT_EQ(0x00000003U, maskTrailingOnes(2U)); + EXPECT_EQ(0xC0000000U, maskLeadingOnes(2U)); + + EXPECT_EQ(0x000007FFU, maskTrailingOnes(11U)); + EXPECT_EQ(0xFFE00000U, maskLeadingOnes(11U)); + + EXPECT_EQ(0xFFFFFFFFU, maskTrailingOnes(32U)); + EXPECT_EQ(0xFFFFFFFFU, maskLeadingOnes(32U)); +} + TEST(MathExtras, findFirstSet) { uint8_t Z8 = 0; uint16_t Z16 = 0;