summaryrefslogtreecommitdiffstats
path: root/import/hwpf/fapi2/include
diff options
context:
space:
mode:
authorBrian Silver <bsilver@us.ibm.com>2015-04-30 07:19:01 -0500
committerJoshua Hunsberger <jahunsbe@us.ibm.com>2017-10-23 15:51:09 -0500
commit91dccfe6bd5cf757df9178209214f7bab995f107 (patch)
tree349a7a843919785bbae52b622d12f357dbf99847 /import/hwpf/fapi2/include
parent32111e1ac3ec629eb67aabc1591217ed3156aa95 (diff)
downloadtalos-hcode-91dccfe6bd5cf757df9178209214f7bab995f107.tar.gz
talos-hcode-91dccfe6bd5cf757df9178209214f7bab995f107.zip
Extend fapi2::buffer parametric interfaces
Add fapi2::buffer<T>::clearBit(bit_to_clear) Add extract/insert(<parameters>) Change-Id: I8dc00b6da68b22cd7b346cc1da56d33b94aec5b7 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/17542 Tested-by: Jenkins Server Reviewed-by: Matt K. Light <mklight@us.ibm.com> Reviewed-by: Thi N. Tran <thi@us.ibm.com> Reviewed-by: Brian Silver <bsilver@us.ibm.com> Tested-by: Brian Silver <bsilver@us.ibm.com>
Diffstat (limited to 'import/hwpf/fapi2/include')
-rw-r--r--import/hwpf/fapi2/include/buffer.H225
1 files changed, 191 insertions, 34 deletions
diff --git a/import/hwpf/fapi2/include/buffer.H b/import/hwpf/fapi2/include/buffer.H
index 9249d0ef..2fc2438e 100644
--- a/import/hwpf/fapi2/include/buffer.H
+++ b/import/hwpf/fapi2/include/buffer.H
@@ -170,6 +170,24 @@ namespace fapi2
}
///
+ /// @brief Set a bit in the buffer
+ /// @param[in] i_bit the bit number to set.
+ /// @note 0 is left-most
+ /// @return FAPI2_RC_SUCCESS if OK
+ ///
+ inline fapi2::ReturnCode setBit(const bits_type& i_bit)
+ {
+ if (i_bit >= TT::bits_per_unit())
+ {
+ return FAPI2_RC_INVALID_PARAMETER;
+ }
+
+ iv_data |=
+ (static_cast<T>(1)) << (TT::bits_per_unit() - i_bit - 1);
+ return FAPI2_RC_SUCCESS;
+ }
+
+ ///
/// @brief Clear a bit in buffer
/// @tparam B Bit in buffer to clear.
/// @return buffer& Useful for method chaining
@@ -188,6 +206,31 @@ namespace fapi2
}
///
+ /// @brief Clear a bit in the buffer
+ /// @param[in] i_bit the bit number to clear.
+ /// @note 0 is left-most
+ /// @return FAPI2_RC_SUCCESS if OK
+ ///
+ inline fapi2::ReturnCode clearBit(const bits_type& i_bit)
+ {
+ if (i_bit >= TT::bits_per_unit())
+ {
+ return FAPI2_RC_INVALID_PARAMETER;
+ }
+
+ fapi2::buffer<T> l_scratch;
+
+ if (l_scratch.setBit(i_bit) != FAPI2_RC_SUCCESS)
+ {
+ return FAPI2_RC_INVALID_PARAMETER;
+ }
+
+ iv_data &= l_scratch.invert();
+
+ return FAPI2_RC_SUCCESS;
+ }
+
+ ///
/// @brief Write a bit in buffer to a given value
/// @tparam B Bit in buffer to write
/// @return buffer& Useful for method chaining
@@ -225,26 +268,6 @@ namespace fapi2
}
///
- /// @brief Set a bit in the buffer
- /// @param[in] i_bit the bit number to set.
- /// @note 0 is left-most
- /// @return FAPI2_RC_SUCCESS if OK
- ///
- inline fapi2::ReturnCode setBit(const bits_type& i_bit)
- {
- if (i_bit >= TT::bits_per_unit())
- {
- return FAPI2_RC_INVALID_PARAMETER;
- }
-
- // 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() - i_bit - 1);
- return FAPI2_RC_SUCCESS;
- }
-
- ///
/// @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
@@ -392,9 +415,6 @@ namespace fapi2
/// @param[in] i_datain OT value to copy into DataBuffer
/// - data is taken left aligned
/// @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 TS, bits_type L, bits_type SS = 0, typename OT>
inline buffer& insert(const OT i_datain)
@@ -440,6 +460,76 @@ namespace fapi2
}
///
+ /// @brief Copy part of a OT into the DataBuffer
+ /// @tparam OT the type of the incoming (origin) data
+ /// @param[in] i_datain OT value to copy into DataBuffer
+ /// - data is taken left aligned
+ /// @param[in] Start bit to insert into (target start)
+ /// @param[in] Length of bits to insert
+ /// @param[in] Start bit in source - defaults to bit 0
+
+ /// @return FAPI2_RC_SUCCESS if successful
+ ///
+ template<typename OT>
+ fapi2::ReturnCode insert(const OT i_datain, const bits_type i_targetStart,
+ const bits_type i_len, const bits_type i_sourceStart = 0)
+ {
+ const bits_type target_length = parameterTraits<T>::bit_length();
+ const bits_type source_length = parameterTraits<OT>::bit_length();
+
+ // Error if input data don't make sense
+ if ((i_targetStart + i_len) > target_length)
+ {
+ FAPI_ERR("insert(): (Target Start + Len) is out of bounds");
+ return FAPI2_RC_INVALID_PARAMETER;
+ }
+
+ if ((i_sourceStart + i_len) > source_length)
+ {
+ FAPI_ERR("insert(): (Source Start + Len) is out of bounds");
+ return FAPI2_RC_INVALID_PARAMETER;
+ }
+
+ if (i_targetStart >= target_length)
+ {
+ FAPI_ERR("insert(): Target Start is out of bounds");
+ return FAPI2_RC_INVALID_PARAMETER;
+ }
+
+ if (i_sourceStart >= source_length)
+ {
+ FAPI_ERR("insert(): Source Start is out of bounds");
+ return FAPI2_RC_INVALID_PARAMETER;
+ }
+
+ // Normalize the input to 2 64 bit integers and adjust the starts accordingly
+ uint64_t source = static_cast<uint64_t>(i_datain);
+ const uint64_t target = static_cast<uint64_t>(iv_data);
+
+ const bits_type source_start = parameterTraits<uint64_t>::bit_length() - (source_length - i_sourceStart);
+ const bits_type target_start = parameterTraits<uint64_t>::bit_length() - (target_length - i_targetStart);
+
+ // Get mask value for Target buffer
+ // Note: Need "& 0UL" because bit shift left for Target buffer doesn't roll off
+ uint64_t mask = ((~0UL << (parameterTraits<uint64_t>::bit_length() - i_len)) & ~0UL) >> target_start;
+
+ // Align the source to the target. Make things signed so we know which way to shift.
+ int32_t shift = source_start - target_start;
+ if (shift > 0)
+ {
+ source <<= shift;
+ }
+ else
+ {
+ shift = target_start - source_start;
+ source >>= shift;
+ }
+
+ iv_data = ((target & ~mask) | (source & mask));
+ return FAPI2_RC_SUCCESS;
+ }
+
+ ///
/// @brief Copy in a right aligned value
/// @tparam SB Start bit to insert into
/// @tparam L Length of bits to insert
@@ -448,16 +538,13 @@ namespace fapi2
/// - data is taken right aligned
/// @return buffer& Useful for method chaining
/// @note Data is assumed to be aligned on the word boundary of L
- /// @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 TS, bits_type L, typename OT>
inline buffer& insertFromRight(const OT i_datain)
{
// Error if input data don't make sense
- static_assert(L < parameterTraits<OT>::bit_length(),
- "insertFromRight(): Len >= input buffer");
+ static_assert(L <= parameterTraits<OT>::bit_length(),
+ "insertFromRight(): Len > input buffer");
static_assert(TS < parameterTraits<T>::bit_length(),
"insertFromRight(): Target Start is out of bounds");
static_assert((TS + L) <= parameterTraits<T>::bit_length(),
@@ -468,6 +555,42 @@ namespace fapi2
}
///
+ /// @brief Copy in a right aligned value
+ /// @tparam OT the type of the incoming (origin) data
+ /// @param[in] i_datain OT value to copy into DataBuffer
+ /// - data is taken right aligned
+ /// @param[in] Start bit to insert into
+ /// @param[in] Length of bits to insert
+ /// @return FAPi2_RC_SUCCESS if no error
+ /// @note Data is assumed to be aligned on the word boundary of L
+ ///
+ template<typename OT>
+ fapi2::ReturnCode insertFromRight(const OT i_datain, const bits_type i_targetStart,
+ const bits_type i_len)
+ {
+ // Error if input data don't make sense
+ if ((i_targetStart + i_len) > parameterTraits<T>::bit_length())
+ {
+ FAPI_ERR("insertFromRight(): (Target Start + Len) is out of bounds");
+ return FAPI2_RC_INVALID_PARAMETER;
+ }
+
+ if (i_targetStart >= parameterTraits<T>::bit_length())
+ {
+ FAPI_ERR("insertFromRight(): Target Start is out of bounds");
+ return FAPI2_RC_INVALID_PARAMETER;
+ }
+
+ if (i_len > parameterTraits<OT>::bit_length())
+ {
+ FAPI_ERR("insertFromRight(): Len > input buffer");
+ return FAPI2_RC_INVALID_PARAMETER;
+ }
+
+ return this->insert(i_datain, i_targetStart, i_len, parameterTraits<OT>::bit_length() - i_len);
+ }
+
+ ///
/// @brief Copy data from this buffer into an OT
/// @tparam TS Start bit to insert into (target start)
/// @tparam L Length of bits to insert
@@ -475,9 +598,6 @@ namespace fapi2
/// @tparam OT the type of the outgoing (target)
/// @param[out] o_out OT to copy into - data is placed left aligned
/// @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 TS, bits_type L, bits_type SS, typename OT>
inline buffer& extract(OT& o_out)
@@ -491,15 +611,37 @@ namespace fapi2
}
///
+ /// @brief Copy data from this buffer into an OT
+ /// @tparam OT the type of the outgoing (target)
+ /// @param[out] o_out OT to copy into - data is placed left aligned
+ /// @param[in] Start bit to insert into (target start)
+ /// @param[in] Length of bits to insert
+ /// @param[in] Start bit in source
+ /// @return FAPI2_RC_SUCCESS if ok
+ ///
+ template<typename OT>
+ fapi2::ReturnCode extract(OT& o_out, const bits_type i_targetStart,
+ const bits_type i_len, const bits_type i_sourceStart)
+ {
+ // Extraction is just an insert into o_out
+
+ buffer<OT> out(o_out);
+ if (out.insert(iv_data, i_targetStart, i_len, i_sourceStart) != FAPI2_RC_SUCCESS)
+ {
+ return FAPI2_RC_INVALID_PARAMETER;
+ }
+
+ o_out = out;
+ return FAPI2_RC_SUCCESS;
+ }
+
+ ///
/// @brief Copy data from this buffer into an OT and right justify
/// @tparam SS Start bit to insert into (source start)
/// @tparam L Length of bits to insert
/// @tparam OT the type of the outgoing (target)
/// @param[out] o_out OT to copy into - data is placed right aligned
/// @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 SS, bits_type L, typename OT>
inline buffer& extractToRight(OT& o_out)
@@ -508,6 +650,21 @@ namespace fapi2
return *this;
}
+ ///
+ /// @brief Copy data from this buffer into an OT and right justify
+ /// @tparam OT the type of the outgoing (target)
+ /// @param[out] o_out OT to copy into - data is placed right aligned
+ /// @param[in] Start bit to insert into (source start)
+ /// @param[in] Length of bits to insert
+ /// @return FAPI2_RC_SUCCESS if ok
+ ///
+ template<typename OT>
+ fapi2::ReturnCode extractToRight(OT& o_out, const bits_type i_sourceStart,
+ const bits_type i_len)
+ {
+ return extract(o_out, parameterTraits<OT>::bit_length() - i_len, i_len, i_sourceStart);
+ }
+
///@}
private:
OpenPOWER on IntegriCloud