diff options
author | Brian Silver <bsilver@us.ibm.com> | 2015-05-12 09:04:36 -0500 |
---|---|---|
committer | Joshua Hunsberger <jahunsbe@us.ibm.com> | 2017-10-23 15:51:12 -0500 |
commit | 48d7054b5251a34758a0db919bd892cb2406a79b (patch) | |
tree | 9fe2718ec5884b3f794c271f7273da87cf1f20bb /import/hwpf | |
parent | 69e6a1833869ea81c85989bcac33f173496bdd0d (diff) | |
download | talos-hcode-48d7054b5251a34758a0db919bd892cb2406a79b.tar.gz talos-hcode-48d7054b5251a34758a0db919bd892cb2406a79b.zip |
Add support for ranges of bits in bit operators
Change-Id: Ifb8d66983379a9f113bfe315a671738d703da8d2
Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/17716
Tested-by: Jenkins Server
Reviewed-by: Matt K. Light <mklight@us.ibm.com>
Reviewed-by: Bilicon Patil <bilpatil@in.ibm.com>
Reviewed-by: Brian Silver <bsilver@us.ibm.com>
Diffstat (limited to 'import/hwpf')
-rw-r--r-- | import/hwpf/fapi2/include/buffer.H | 56 |
1 files changed, 32 insertions, 24 deletions
diff --git a/import/hwpf/fapi2/include/buffer.H b/import/hwpf/fapi2/include/buffer.H index abc28dd9..8d20b71c 100644 --- a/import/hwpf/fapi2/include/buffer.H +++ b/import/hwpf/fapi2/include/buffer.H @@ -153,74 +153,79 @@ namespace fapi2 /// /// @brief Templated setBit for integral types /// @tparam B the bit number to set. + /// @tparam C the count of bits to set, defaults to 1 /// @return buffer& Useful for method chaining /// @note 0 is left-most /// @note Example: fapi2::buffer<uint64_t>().setBit<3>(); /// - template< bits_type B > + template< bits_type B, bits_type C = 1 > inline buffer& setBit(void) { static_assert((B >= 0) && - (B < TT::bits_per_unit()), "failed range check"); + ((B + C - 1) < TT::bits_per_unit()), "failed range check"); - // Force iv_data to be dependent on the template type to force - // its look up in the second phase - iv_data |= (static_cast<T>(1)) << (TT::bits_per_unit() - B - 1); + // This would be a candidate for a fast_mask (see variable_buffer) but + // we'd need tables for all the integral types which maybe we need to + // do ... + iv_data |= (T(~0) >> (TT::bits_per_unit() - C)) << (TT::bits_per_unit() - B - C); return *this; } /// /// @brief Set a bit in the buffer /// @param[in] i_bit the bit number to set. + /// @param[in] i_count the count of bits to set, defaults to 1 /// @note 0 is left-most /// @return FAPI2_RC_SUCCESS if OK /// - inline fapi2::ReturnCode setBit(const bits_type& i_bit) + inline fapi2::ReturnCode setBit(const bits_type& i_bit, const bits_type& i_count = 1) { - if (i_bit >= TT::bits_per_unit()) + if ((i_count + i_bit - 1) >= TT::bits_per_unit()) { return FAPI2_RC_INVALID_PARAMETER; } - iv_data |= - (static_cast<T>(1)) << (TT::bits_per_unit() - i_bit - 1); + iv_data |= (T(~0) >> (TT::bits_per_unit() - i_count)) << (TT::bits_per_unit() - i_bit - i_count); + return FAPI2_RC_SUCCESS; } /// /// @brief Clear a bit in buffer /// @tparam B Bit in buffer to clear. + /// @tparam C the count of bits to clear, defaults to 1 /// @return buffer& Useful for method chaining /// @note Asserting that all the parameters are known at /// compile time so this can be templated only. If that is not /// the case we can add a function parameter version. /// - template< bits_type B > + template< bits_type B, bits_type C = 1> inline buffer& clearBit(void) { static_assert((B >= 0) && - (B < TT::bits_per_unit()), "failed range check"); + ((B + C - 1)< TT::bits_per_unit()), "failed range check"); - iv_data &= buffer<T>().setBit<B>().invert(); + iv_data &= buffer<T>().setBit<B, C>().invert(); return *this; } /// /// @brief Clear a bit in the buffer /// @param[in] i_bit the bit number to clear. + /// @param[in] i_count the count of bits to clear, defaults to 1 /// @note 0 is left-most /// @return FAPI2_RC_SUCCESS if OK /// - inline fapi2::ReturnCode clearBit(const bits_type& i_bit) + inline fapi2::ReturnCode clearBit(const bits_type& i_bit, const bits_type& i_count = 1) { - if (i_bit >= TT::bits_per_unit()) + if ((i_count + i_bit - 1) >= TT::bits_per_unit()) { return FAPI2_RC_INVALID_PARAMETER; } fapi2::buffer<T> l_scratch; - if (l_scratch.setBit(i_bit) != FAPI2_RC_SUCCESS) + if (l_scratch.setBit(i_bit, i_count) != FAPI2_RC_SUCCESS) { return FAPI2_RC_INVALID_PARAMETER; } @@ -233,18 +238,19 @@ namespace fapi2 /// /// @brief Write a bit in buffer to a given value /// @tparam B Bit in buffer to write + /// @tparam C the count of bits to write, defaults to 1 /// @return buffer& Useful for method chaining /// @note Asserting that all the parameters are known at /// compile time so this can be templated only. If that is not /// the case we can add a function parameter version. /// - template< bits_type B > + template< bits_type B, bits_type C = 1 > inline buffer& writeBit(const bool i_value) { static_assert((B >= 0) && - (B < TT::bits_per_unit()), "failed range check"); + ((B + C - 1)< TT::bits_per_unit()), "failed range check"); - (i_value == 0) ? clearBit<B>() : setBit<B>(); + (i_value == 0) ? clearBit<B, C>() : setBit<B, C>(); return *this; } @@ -252,30 +258,32 @@ namespace fapi2 /// /// @brief Invert bit /// @tparam B Bit in buffer to invert. + /// @tparam C the count of bits to flip, defaults to 1 /// @return buffer& Useful for method chaining /// @note Asserting that all the parameters are known at /// compile time so this can be templated only. If that is not /// the case we can add a function parameter version. /// - template< bits_type B > + template< bits_type B, bits_type C = 1 > inline buffer& flipBit(void) { static_assert((B >= 0) && - (B < TT::bits_per_unit()), "failed range check"); + ((B + C - 1) < TT::bits_per_unit()), "failed range check"); - iv_data ^= buffer<T>().setBit<B>(); + iv_data ^= buffer<T>().setBit<B, C>(); return *this; } /// /// @brief Get the value of a bit in the buffer /// @tparam B Bit in buffer to get. - /// @return true if bit is on, false if bit is off + /// @tparam C the count of bits to get, defaults to 1 + /// @return true if *any* bit is on, false if *every* bit is off /// - template< bits_type B > + template< bits_type B, bits_type C = 1> inline bool getBit(void) const { - return buffer<T>().setBit<B>() & iv_data; + return buffer<T>().setBit<B, C>() & iv_data; } /// |