diff --git a/lib/bit_ops_test.cc b/lib/bit_ops_test.cc index 81adfbdc..67f33eb8 100644 --- a/lib/bit_ops_test.cc +++ b/lib/bit_ops_test.cc @@ -41,3 +41,31 @@ TEST(BitFieldGetTest, SelectMidway) { uint32_t expected = prjxray::bit_field_get(0xFFCCBBAA, 18, 8); EXPECT_EQ(static_cast(0x4BB), expected); } + +TEST(BitFieldSetTest, WriteOneBit) { + uint32_t actual = prjxray::bit_field_set( + static_cast(0x0), 23, 23, + static_cast(0x1)); + EXPECT_EQ(actual, static_cast(0x800000)); +} + +TEST(BitFieldSetTest, WriteOneBitWithOutOfRangeValue) { + uint32_t actual = prjxray::bit_field_set( + static_cast(0x0), 23, 23, + static_cast(0x3)); + EXPECT_EQ(actual, static_cast(0x800000)); +} + +TEST(BitFieldSetTest, WriteMultipleBits) { + uint32_t actual = prjxray::bit_field_set( + static_cast(0x0), 18, 8, + static_cast(0x123)); + EXPECT_EQ(actual, static_cast(0x12300)); +} + +TEST(BitFieldSetTest, WriteMultipleBitsWithOutOfRangeValue) { + uint32_t actual = prjxray::bit_field_set( + static_cast(0x0), 18, 8, + static_cast(0x1234)); + EXPECT_EQ(actual, static_cast(0x23400)); +} diff --git a/lib/include/prjxray/bit_ops.h b/lib/include/prjxray/bit_ops.h index ac779b4e..5979e2b5 100644 --- a/lib/include/prjxray/bit_ops.h +++ b/lib/include/prjxray/bit_ops.h @@ -4,7 +4,7 @@ namespace prjxray { template -constexpr UInt bit_mask(int bit) { +constexpr UInt bit_mask(const int bit) { return (static_cast(1) << bit); } @@ -19,7 +19,7 @@ constexpr UInt bit_all_ones() { } template -constexpr UInt bit_mask_range(int top_bit, int bottom_bit) { +constexpr UInt bit_mask_range(const int top_bit, const int bottom_bit) { return ((bit_all_ones() >> (bit_sizeof() - 1 - top_bit)) & (bit_all_ones() - bit_mask(bottom_bit) + static_cast(1))); @@ -27,10 +27,19 @@ constexpr UInt bit_mask_range(int top_bit, int bottom_bit) { template -constexpr UInt bit_field_get(UInt value, int top_bit, int bottom_bit) { +constexpr UInt bit_field_get(UInt value, const int top_bit, const int bottom_bit) { return (value & bit_mask_range(top_bit, bottom_bit)) >> bottom_bit; } +template +constexpr UInt bit_field_set(const UInt reg_value, + const int top_bit, const int bottom_bit, + const UInt field_value) { + return ((reg_value & ~bit_mask_range(top_bit, bottom_bit)) | + ((static_cast(field_value) << bottom_bit) & + bit_mask_range(top_bit, bottom_bit))); +} + } // namespace prjxray #endif // PRJXRAY_LIB_BIT_OPS_H