summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Silver <bsilver@us.ibm.com>2015-03-13 10:50:16 -0500
committerDerk Rembold <rembold@de.ibm.com>2015-09-03 07:21:42 -0500
commit91cc641a78c379d9b6b0d5c270866429d36e6c16 (patch)
treec80adfa2988186857924da0585b2106725db7b1b
parent54281ef813168b16b41a084e4f70dbab462da2ce (diff)
downloadtalos-sbe-91cc641a78c379d9b6b0d5c270866429d36e6c16.tar.gz
talos-sbe-91cc641a78c379d9b6b0d5c270866429d36e6c16.zip
Buffer, targeting updates
Update target types for ex, l2/l3 Add variable_buffer resize Update, fix, variable_buffer insert/extract variable_buffer array constructor -Wall clean up Refactor buffer::insert, bit_lengths Change-Id: I2bbec294f275a80c33917dc2df2f8b8220f6d8d6 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/16359 Reviewed-by: Matt K. Light <mklight@us.ibm.com> Reviewed-by: MATTHEW A. PLOETZ <maploetz@us.ibm.com> Reviewed-by: Brian Silver <bsilver@us.ibm.com> Tested-by: Brian Silver <bsilver@us.ibm.com> Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/20126 Tested-by: Jenkins Server Reviewed-by: Derk Rembold <rembold@de.ibm.com>
-rw-r--r--import/hwpf/fapi2/include/buffer.H82
-rw-r--r--import/hwpf/fapi2/include/buffer_base.H48
-rw-r--r--import/hwpf/fapi2/include/buffer_parameters.H19
-rw-r--r--import/hwpf/fapi2/include/buffer_traits.H13
-rw-r--r--import/hwpf/fapi2/include/error_info.H3
-rw-r--r--import/hwpf/fapi2/include/ffdc.H2
-rw-r--r--import/hwpf/fapi2/include/return_code.H2
-rw-r--r--import/hwpf/fapi2/include/target.H2
-rw-r--r--import/hwpf/fapi2/include/target_types.H9
-rw-r--r--import/hwpf/fapi2/include/variable_buffer.H316
10 files changed, 373 insertions, 123 deletions
diff --git a/import/hwpf/fapi2/include/buffer.H b/import/hwpf/fapi2/include/buffer.H
index 9f072039..e0b6ec8c 100644
--- a/import/hwpf/fapi2/include/buffer.H
+++ b/import/hwpf/fapi2/include/buffer.H
@@ -108,11 +108,11 @@ namespace fapi2
inline buffer& setBit(void)
{
static_assert((B >= 0) &&
- (B < bufferTraits<T>::bits_per_unit), "failed range check");
+ (B < bufferTraits<T>::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
- this->iv_data |= (static_cast<T>(1)) << (bufferTraits<T>::bits_per_unit - B - 1);
+ this->iv_data |= (static_cast<T>(1)) << (bufferTraits<T>::bits_per_unit() - B - 1);
return *this;
}
@@ -128,7 +128,7 @@ namespace fapi2
inline buffer& clearBit(void)
{
static_assert((B >= 0) &&
- (B < bufferTraits<T>::bits_per_unit), "failed range check");
+ (B < bufferTraits<T>::bits_per_unit()), "failed range check");
this->iv_data &= buffer<T>().setBit<B>().invert();
return *this;
@@ -146,7 +146,7 @@ namespace fapi2
inline buffer& flipBit(void)
{
static_assert((B >= 0) &&
- (B < bufferTraits<T>::bits_per_unit), "failed range check");
+ (B < bufferTraits<T>::bits_per_unit()), "failed range check");
this->iv_data ^= buffer<T>().setBit<B>();
return *this;
@@ -160,7 +160,7 @@ namespace fapi2
///
inline fapi2::ReturnCode setBit(const bits_type& i_bit)
{
- if (i_bit >= bufferTraits<T>::bits_per_unit)
+ if (i_bit >= bufferTraits<T>::bits_per_unit())
{
return FAPI2_RC_INVALID_PARAMETER;
}
@@ -168,7 +168,7 @@ namespace fapi2
// Force iv_data to be dependent on the template type to force
// its look up in the second phase
this->iv_data |=
- (static_cast<T>(1)) << (bufferTraits<T>::bits_per_unit - i_bit - 1);
+ (static_cast<T>(1)) << (bufferTraits<T>::bits_per_unit() - i_bit - 1);
return FAPI2_RC_SUCCESS;
}
@@ -280,7 +280,7 @@ namespace fapi2
/// @brief Copy part of a OT into the DataBuffer
/// @tparam TS Start bit to insert into (target start)
/// @tparam L Length of bits to insert
- /// @tparam SS Start bit in source
+ /// @tparam SS Start bit in source - defaults to bit 0
/// @tparam OT the type of the incoming (origin) data
/// @param[in] i_datain OT value to copy into DataBuffer
/// - data is taken left aligned
@@ -288,11 +288,11 @@ namespace fapi2
/// 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>
+ template<bits_type TS, bits_type L, bits_type SS = 0, typename OT>
inline void insert(const OT i_datain)
{
- const bits_type target_length = parameterTraits<T>::bit_length;
- const bits_type source_length = parameterTraits<OT>::bit_length;
+ 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
static_assert((TS + L) <= target_length,
@@ -304,48 +304,30 @@ namespace fapi2
static_assert(SS < source_length,
"insert(): Source Start is out of bounds");
- // Get mask value for Target buffer
- // Note: Need "& ((T)-1) because bit shift left for Target buffer doesn't roll off
- T mask =((T(~0) << (target_length - L)) & T(~0)) >> TS;
+ // 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>(this->iv_data);
- // Calculate the equivalent position of the input Source start for the size of the Target buffer.
+ const bits_type source_start = parameterTraits<uint64_t>::bit_length() - (source_length - SS);
+ const bits_type target_start = parameterTraits<uint64_t>::bit_length() - (target_length - TS);
- // Assume OT is smaller (sizeof(T) > sizeof(OT))
- uint64_t sourceShift = abs(TS - ((target_length - source_length) + SS));
- uint64_t sourceAlign = T(i_datain) << sourceShift;
+ // 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() - L)) & ~0UL) >> target_start;
- if (sizeof(T) == sizeof(OT))
+ // 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)
{
- sourceShift = abs(SS - TS);
- sourceAlign = (SS > TS) ? ((T)i_datain) << sourceShift : ((T)i_datain) >> sourceShift;
+ source <<= shift;
}
-
- if (sizeof(T) < sizeof(OT))
+ else
{
- sourceShift = source_length - target_length;
- if (SS <= sourceShift)
- {
- sourceShift = sourceShift + TS - SS;
- sourceAlign = ((OT)i_datain) >> sourceShift;
- }
-
- // (SS > sourceShift)
- else
- {
- if (sourceShift > TS)
- {
- sourceShift = SS - sourceShift - TS;
- sourceAlign = OT(i_datain) << sourceShift;
- }
- else
- {
- sourceShift = SS - sourceShift;
- sourceAlign = (sourceShift < TS) ? OT(i_datain) >> sourceShift : OT(i_datain);
- }
- }
+ shift = target_start - source_start;
+ source >>= shift;
}
- this->iv_data = (this->iv_data & ~mask) | (sourceAlign & mask);
+ this->iv_data = ((target & ~mask) | (source & mask));
return;
}
@@ -365,14 +347,14 @@ namespace fapi2
inline void insertFromRight(const OT i_datain)
{
// Error if input data don't make sense
- static_assert(L < parameterTraits<OT>::bit_length,
+ static_assert(L < parameterTraits<OT>::bit_length(),
"insertFromRight(): Len >= input buffer");
- static_assert(TS < parameterTraits<T>::bit_length,
+ static_assert(TS < parameterTraits<T>::bit_length(),
"insertFromRight(): Target Start is out of bounds");
- static_assert((TS + L) <= parameterTraits<T>::bit_length,
+ static_assert((TS + L) <= parameterTraits<T>::bit_length(),
"InsertFromRight(): (Target Start + Len) is out of bounds");
- this->insert<TS, L, parameterTraits<OT>::bit_length - L>(i_datain);
+ this->insert<TS, L, parameterTraits<OT>::bit_length() - L>(i_datain);
return;
}
@@ -411,12 +393,12 @@ namespace fapi2
template<bits_type SS, bits_type L, typename OT>
inline void extractToRight(OT& o_out)
{
- extract<parameterTraits<OT>::bit_length - L, L, SS>(o_out);
+ extract<parameterTraits<OT>::bit_length() - L, L, SS>(o_out);
return;
}
///@}
};
-};
+}
#endif
diff --git a/import/hwpf/fapi2/include/buffer_base.H b/import/hwpf/fapi2/include/buffer_base.H
index a6e8c4ad..849e9e79 100644
--- a/import/hwpf/fapi2/include/buffer_base.H
+++ b/import/hwpf/fapi2/include/buffer_base.H
@@ -289,6 +289,17 @@ namespace fapi2
protected:
///
+ /// @brief Get the actual bit length of the buffer
+ /// @return The bit length of the buffer.
+ /// @note This is needed by variable_buffer, which is why it's here
+ ///
+ uint32_t bit_length(void)
+ { return TT::bit_length(iv_data); }
+
+ uint32_t bit_length(void) const
+ { return TT::bit_length(iv_data); }
+
+ ///
/// @brief Variable buffer constructor
/// @param[in] i_value number of *bits* (sizeof(container_units) * 8)
/// needed. Meaningless for integral types and thus protected.
@@ -300,7 +311,7 @@ namespace fapi2
/// @param[in] i_value an initializer list to initialize the container.
/// Meaningless for integral types and thus protected
///
- buffer_base(std::initializer_list<unit_type> i_value);
+ buffer_base(const std::initializer_list<unit_type>& i_value);
///
/// @brief Clear the buffer
@@ -308,23 +319,46 @@ namespace fapi2
inline void clear(void)
{ TT::clear(iv_data); }
+ ///@cond
+ ///
+ /// @brief Return the size of the internal vector given a desired bit size
+ /// @param[in] The size in bits
+ /// @return The size in units.
+ ///
+ inline bits_type _vector_size(const bits_type& bits_size)
+ {
+ // If we fit in one unit, we allocate one unit.
+ if (bits_size < parameterTraits<unit_type>::bit_length())
+ {
+ return 1;
+ }
+
+ // Otherwise, the number of units is calculates - add one if
+ // we cross the unit boundary.
+ else
+ {
+ bits_type my_size = bits_type(bits_size / 8 / sizeof(unit_type));
+ my_size += (bits_size % parameterTraits<unit_type>::bit_length() == 0) ? 0 : 1;
+ return my_size;
+ }
+ }
+ ///@endcond
+
/// The contents of the buffer
T iv_data;
};
template <typename T, typename TT>
inline buffer_base<T, TT>::buffer_base(bits_type i_value):
- iv_data( std::max(bits_type(1),
- bits_type(i_value / 8 / sizeof(bits_type))))
- {
- }
+ iv_data(_vector_size(i_value))
+ {}
template <typename T, typename TT>
- inline buffer_base<T, TT>::buffer_base(std::initializer_list<unit_type> i_value):
+ inline buffer_base<T, TT>::buffer_base(const std::initializer_list<unit_type>& i_value):
iv_data(i_value)
{
}
-};
+}
diff --git a/import/hwpf/fapi2/include/buffer_parameters.H b/import/hwpf/fapi2/include/buffer_parameters.H
index 3dc41b26..1ad9ba43 100644
--- a/import/hwpf/fapi2/include/buffer_parameters.H
+++ b/import/hwpf/fapi2/include/buffer_parameters.H
@@ -41,12 +41,17 @@ namespace fapi2
class parameterTraits
{
public:
- enum
- {
- mask = T(~0),
- bit_length = sizeof(T) * 8,
- byte_length = sizeof(T),
- };
+ // Why constexpr functions? Enums are hard to do math on, and
+ // static const doesn't work without -O1 (or greater.) That might
+ // be a bug in g++ but this works just the same.
+ constexpr static uint32_t mask(void)
+ { return T(~0); }
+
+ constexpr static uint32_t byte_length(void)
+ { return sizeof(T); }
+
+ constexpr static uint32_t bit_length(void)
+ { return sizeof(T) * 8; }
template<typename U>
inline static void write_element(void* i_data, T i_value, uint32_t i_offset)
@@ -60,6 +65,6 @@ namespace fapi2
}
};
/// @endcond
-};
+}
#endif
diff --git a/import/hwpf/fapi2/include/buffer_traits.H b/import/hwpf/fapi2/include/buffer_traits.H
index 5fa9f0b7..cf4df1be 100644
--- a/import/hwpf/fapi2/include/buffer_traits.H
+++ b/import/hwpf/fapi2/include/buffer_traits.H
@@ -43,7 +43,10 @@ namespace fapi2
{
/// @cond
/// Types representing a container of bits. Used to create
- /// variable_buffer.
+ /// variable_buffer. container_unit must remain 32-bits
+ /// for now - there will be a lot of code to change if it
+ /// changes. There are assertions helping to enforce this
+ /// in places in the code.
typedef uint32_t container_unit;
typedef std::vector<container_unit> bits_container;
@@ -137,7 +140,8 @@ namespace fapi2
typedef B bits_type;
typedef T unit_type;
- enum { bits_per_unit = sizeof(unit_type) * 8 };
+ constexpr static uint32_t bits_per_unit(void)
+ { return sizeof(unit_type) * 8; }
};
//
@@ -222,10 +226,11 @@ namespace fapi2
typedef uint32_t bits_type;
typedef container_unit unit_type;
- enum { bits_per_unit = sizeof(unit_type) * 8 };
+ constexpr static uint32_t bits_per_unit(void)
+ { return sizeof(unit_type) * 8; }
};
/// @endcond
-};
+}
diff --git a/import/hwpf/fapi2/include/error_info.H b/import/hwpf/fapi2/include/error_info.H
index b28ab011..30f82998 100644
--- a/import/hwpf/fapi2/include/error_info.H
+++ b/import/hwpf/fapi2/include/error_info.H
@@ -53,7 +53,7 @@ namespace fapi2
{}
operator const void*() const { return iv_value.first; }
- operator const uint8_t() const
+ operator uint8_t() const
{ return *(reinterpret_cast<const uint8_t*>(iv_value.first)); }
int16_t size(void) const { return iv_value.second; }
@@ -219,6 +219,7 @@ namespace fapi2
{
static_assert(std::is_pointer<T>::value,
"pointer passed to getErrorInfoFfdcSize");
+ return 0;
}
///
diff --git a/import/hwpf/fapi2/include/ffdc.H b/import/hwpf/fapi2/include/ffdc.H
index fd79d92e..a0cdd6f2 100644
--- a/import/hwpf/fapi2/include/ffdc.H
+++ b/import/hwpf/fapi2/include/ffdc.H
@@ -187,5 +187,5 @@ namespace fapi2
std::shared_ptr<ErrorInfo> iv_info;
};
-};
+}
#endif // FAPI2_FFDC_H_
diff --git a/import/hwpf/fapi2/include/return_code.H b/import/hwpf/fapi2/include/return_code.H
index 0442ca89..348180cb 100644
--- a/import/hwpf/fapi2/include/return_code.H
+++ b/import/hwpf/fapi2/include/return_code.H
@@ -175,6 +175,6 @@ namespace fapi2
extern thread_local uint64_t pib_error_mask; /// the pib mask
extern thread_local uint64_t operational_state; /// the operational mode
-};
+}
#endif
diff --git a/import/hwpf/fapi2/include/target.H b/import/hwpf/fapi2/include/target.H
index 1add61d6..5946e3cf 100644
--- a/import/hwpf/fapi2/include/target.H
+++ b/import/hwpf/fapi2/include/target.H
@@ -332,6 +332,6 @@ namespace fapi2
{ return (K & T) != 0; }
-};
+}
#endif
diff --git a/import/hwpf/fapi2/include/target_types.H b/import/hwpf/fapi2/include/target_types.H
index f4cfd931..5cee0141 100644
--- a/import/hwpf/fapi2/include/target_types.H
+++ b/import/hwpf/fapi2/include/target_types.H
@@ -48,14 +48,14 @@ namespace fapi2
TARGET_TYPE_DIMM = 0x00000002, ///< DIMM type
TARGET_TYPE_PROC_CHIP = 0x00000004, ///< Processor type
TARGET_TYPE_MEMBUF_CHIP = 0x00000008, ///< Membuf type
- TARGET_TYPE_EX = 0x00000010, ///< Ex type
+ TARGET_TYPE_EX = 0x00000010, ///< EX - 2x Core, L2, L3 - can be deconfigured
TARGET_TYPE_MBA = 0x00000020, ///< MBA type
TARGET_TYPE_MCS = 0x00000040, ///< MCS type
TARGET_TYPE_XBUS = 0x00000080, ///< XBUS type
TARGET_TYPE_ABUS = 0x00000100, ///< ABUS type
TARGET_TYPE_L4 = 0x00000200, ///< L4 type
- TARGET_TYPE_CORE = 0x00000400, ///< Core type
- TARGET_TYPE_EQ = 0x00000800, ///< EQ type
+ TARGET_TYPE_CORE = 0x00000400, ///< Core - 4x threads(?) - can be deconfigured
+ TARGET_TYPE_EQ = 0x00000800, ///< EQ - 4x core, 2x L2, 2x L3 - can be deconfigured
TARGET_TYPE_MCA = 0x00001000, ///< MCA type
TARGET_TYPE_MCBIST = 0x00002000, ///< MCBIST type
TARGET_TYPE_MIA = 0x00004000, ///< MIA type
@@ -68,7 +68,6 @@ namespace fapi2
TARGET_TYPE_PERV = 0x00200000, ///< Pervasive type
TARGET_TYPE_PEC = 0x00400000, ///< PEC type
TARGET_TYPE_PHB = 0x00800000, ///< PHB type
- TARGET_TYPE_EL = 0x01000000, ///< L3/L2 Caches
TARGET_TYPE_ALL = 0xFFFFFFFF, ///< Any/All types
@@ -100,6 +99,6 @@ namespace fapi2
static const uint8_t count = 0;
};
/// @endcond
-};
+}
#endif
diff --git a/import/hwpf/fapi2/include/variable_buffer.H b/import/hwpf/fapi2/include/variable_buffer.H
index a1280830..95183b32 100644
--- a/import/hwpf/fapi2/include/variable_buffer.H
+++ b/import/hwpf/fapi2/include/variable_buffer.H
@@ -73,26 +73,27 @@ namespace fapi2
/// @param[in] i_target_start_bit The starting bit position in this
/// @param[in] i_length The length, in bits, the user wants copied.
///
- template<typename unit_type, typename bits_type>
+ template<typename unit_type, typename bits_type, typename output_type>
inline fapi2::ReturnCode _insert(const unit_type* i_source,
bits_type i_source_length,
- unit_type* i_target,
+ output_type* i_target,
bits_type i_target_length,
bits_type i_source_start_bit,
bits_type i_target_start_bit,
bits_type i_length)
{
- const bits_type bits_per_unit = fapi2::parameterTraits<unit_type>::bit_length;
+ const bits_type bits_per_input_unit = parameterTraits<unit_type>::bit_length();
+ const bits_type bits_per_output_unit =parameterTraits<output_type>::bit_length();
- // tartgetStart is defaulted to the sizeof(target) - (sizeof(source) - i_source_start_bit)
+ // targetStart is defaulted to the sizeof(target) - (sizeof(source) - i_source_start_bit)
// which makes this act like insert from right
- if (i_target_start_bit == ~0)
+ if (i_target_start_bit == static_cast<bits_type>(~0))
{
i_target_start_bit = (i_target_length - (i_source_length - i_source_start_bit));
}
// len defaults to (sizeof(OT) * 8) - i_source_start_bit
- if (i_length == ~0)
+ if (i_length == static_cast<bits_type>(~0))
{
i_length = i_source_length - i_source_start_bit;
}
@@ -106,17 +107,17 @@ namespace fapi2
do
{
- const bits_type src_idx = i_source_start_bit / bits_per_unit;
- const bits_type trg_idx = i_target_start_bit / bits_per_unit;
+ const bits_type src_idx = i_source_start_bit / bits_per_input_unit;
+ const bits_type trg_idx = i_target_start_bit / bits_per_output_unit;
// "slop" = unaligned bits
- const bits_type src_slop = i_source_start_bit % bits_per_unit;
- const bits_type trg_slop = i_target_start_bit % bits_per_unit;
+ const bits_type src_slop = i_source_start_bit % bits_per_input_unit;
+ const bits_type trg_slop = i_target_start_bit % bits_per_output_unit;
// "cnt" = largest number of bits to be moved each pass
- bits_type cnt = std::min(i_length, bits_per_unit);
- cnt = std::min(cnt, bits_per_unit - src_slop);
- cnt = std::min(cnt, bits_per_unit - trg_slop);
+ bits_type cnt = std::min(i_length, bits_per_input_unit);
+ cnt = std::min(cnt, bits_per_input_unit - src_slop);
+ cnt = std::min(cnt, bits_per_output_unit - trg_slop);
// generate the source mask only once
bits_type mask = fast_mask32(src_slop, cnt);
@@ -127,9 +128,6 @@ namespace fapi2
// "shift" = amount of shifting needed for target alignment
int32_t shift = trg_slop - src_slop;
- // ideally (i << -1) would yield (i >> 1), but it
- // doesn't, so we need an extra branch here
-
if (shift < 0)
{
src_bits <<= -shift;
@@ -143,6 +141,7 @@ namespace fapi2
// clear source '0' bits in the target
i_target[trg_idx] &= ~mask;
+
// set source '1' bits in the target
i_target[trg_idx] |= src_bits;
@@ -150,6 +149,7 @@ namespace fapi2
i_target_start_bit += cnt;
i_length -= cnt;
+
} while (0 < i_length);
return fapi2::FAPI2_RC_SUCCESS;
@@ -182,9 +182,47 @@ namespace fapi2
///
/// @brief Variable buffer list constructor
/// @param[in] i_value an initializer list to initialize the container.
+ /// @warning Input data is assumed to be right-aligned and must be 32 bits
///
variable_buffer(const std::initializer_list<unit_type>& i_value);
+ ///
+ /// @brief Variable buffer copy constructor
+ /// @param[in] i_buffer the buffer to copy from
+ ///
+ variable_buffer(const variable_buffer& i_buffer):
+ buffer_base()
+ {
+ iv_perceived_bit_length = i_buffer.iv_perceived_bit_length;
+ iv_data = i_buffer.iv_data;
+ }
+
+ ///
+ /// @brief Variable buffer move constructor
+ /// @param[in] i_buffer the buffer to move
+ ///
+ variable_buffer(variable_buffer&& i_buffer):
+ buffer_base()
+ {
+ iv_perceived_bit_length = i_buffer.iv_perceived_bit_length;
+ i_buffer.iv_perceived_bit_length = 0;
+ iv_data = std::move(i_buffer.iv_data);
+ }
+
+ ///
+ /// @brief Variable buffer array constructor
+ /// @param[in] i_value a uint32_t array to initialize the container.
+ /// @param[in] i_length the length of the array in 32-bit words
+ /// @param[in] i_bit_length the length of the resulting buffer in bits.
+ /// @warning This assumes the underlying container of a variable_buffer
+ /// is a uint32_t - which it is.
+ /// @note To use this constructor given an ecmdDataBuffer, you would
+ /// ecmd.memCopyOut( buffer, ... );
+ /// variable_buffer( buffer, ecmd.getCapacity(), ecmd.getBitLength());
+ ///
+ variable_buffer(const uint32_t* i_value, const uint32_t i_length,
+ const uint32_t i_bit_length);
+
/// @name Bit/Word Manipulation Functions
///@{
@@ -226,8 +264,8 @@ namespace fapi2
}
iv_data[index] |=
- unit_type(1) << (bits_per_unit - 1) -
- (i_bit - (index * bits_per_unit));
+ unit_type(1) << ((bits_per_unit - 1) -
+ (i_bit - (index * bits_per_unit)));
return FAPI2_RC_SUCCESS;
}
@@ -319,9 +357,28 @@ namespace fapi2
/// @name Buffer Manipulation Functions
///@{
- // Note: Many (all?) of these are not needed and the compiler complains
- // as the cast to T yields a better operator. There are here mainly for
- // documenation purposes.
+ ///
+ /// @brief move operator=()
+ /// @note To use: new_buffer = std::move(old_buffer). old_buffer will be
+ /// destroyed and no copy will be made (moved)
+ ///
+ variable_buffer& operator=(variable_buffer&& other)
+ {
+ iv_perceived_bit_length = other.iv_perceived_bit_length;
+ other.iv_perceived_bit_length = 0;
+ iv_data = std::move(other.iv_data);
+ return *this;
+ }
+
+ ///
+ /// @brief operator=()
+ ///
+ variable_buffer& operator=(const variable_buffer& other)
+ {
+ iv_perceived_bit_length = other.iv_perceived_bit_length;
+ iv_data = other.iv_data;
+ return *this;
+ }
///
/// @brief operator>>()
@@ -339,10 +396,37 @@ namespace fapi2
///
/// @brief operator+()
+ /// @param[in] A variable_buffer to append to this
///
-#ifdef DOXYGEN
- variable_buffer<T>& operator+(const T& rhs);
-#endif
+ variable_buffer& operator+(const variable_buffer& rhs)
+ {
+ iv_perceived_bit_length += rhs.iv_perceived_bit_length;
+ iv_data.insert(iv_data.end(), rhs.iv_data.begin(), rhs.iv_data.end());
+ return *this;
+ }
+
+ ///
+ /// @brief operator+()
+ /// @param[in] A number of bits to add to this buffer
+ ///
+ variable_buffer& operator+(const bits_type& rhs)
+ {
+ if (rhs != 0)
+ {
+ iv_perceived_bit_length += rhs;
+ iv_data.resize(_vector_size(iv_perceived_bit_length));
+ }
+ return *this;
+ }
+
+ ///
+ /// @brief resize()
+ /// @param[in] Desired resulting size of the buffer, in bits
+ ///
+ variable_buffer& resize(const bits_type& rhs)
+ {
+ return operator+(rhs - iv_perceived_bit_length);
+ }
///
/// @brief operator+=()
@@ -389,22 +473,22 @@ namespace fapi2
///
/// @brief operator!=()
///
-#ifdef DOXYGEN
- bool operator!=(const T& rhs) const;
-#endif
+ bool operator!=(const variable_buffer& rhs) const
+ { return ! operator==(rhs); }
///
/// @brief operator==()
/// @return true if and only if lhs == rhs
///
- inline bool operator==(const fapi2::bits_container& rhs) const
+ inline bool operator==(const fapi2::variable_buffer& rhs) const
{
- if (&iv_data == &rhs)
+ if (&iv_data == &rhs.iv_data)
{
return true;
}
- return iv_data == rhs;
+ return (iv_data == rhs.iv_data) &&
+ (iv_perceived_bit_length == rhs.iv_perceived_bit_length);
}
///
@@ -466,7 +550,7 @@ namespace fapi2
private:
// Just shorthand ...
static const bits_type bits_per_unit =
- bufferTraits<bits_container>::bits_per_unit;
+ bufferTraits<bits_container>::bits_per_unit();
// The number of bits the user asked for. The actual size of the
// container might be larger.
@@ -517,7 +601,17 @@ namespace fapi2
"code currently needs unit_type to be a unit32_t");
}
+ inline variable_buffer::
+ variable_buffer(const uint32_t* i_value, const uint32_t i_length,
+ const uint32_t i_bit_length):
+ iv_perceived_bit_length(i_bit_length)
+ {
+ static_assert(std::is_same<unit_type, uint32_t>::value,
+ "code currently needs unit_type to be a unit32_t");
+ // Copy the array in to our vector.
+ iv_data.insert(iv_data.end(), i_value, &i_value[i_length]);
+ }
/// @cond
//
@@ -529,7 +623,30 @@ namespace fapi2
bits_type i_len,
bits_type i_sourceStart)
{
- return _insert((unit_type*)(&i_source), parameterTraits<OT>::bit_length,
+ // _insert likes 32-bit sources. So lets make our source 32 bits.
+ uint32_t l_source = static_cast<uint32_t>(i_source);
+ bits_type l_sourceStart = i_sourceStart +
+ parameterTraits<uint32_t>::bit_length() - parameterTraits<OT>::bit_length();
+
+ return _insert(&l_source, parameterTraits<uint32_t>::bit_length(),
+ &(iv_data[0]), getBitLength(),
+ l_sourceStart, i_targetStart, i_len);
+ }
+
+ //
+ // If the source is 64-bits, treat that as 2x32
+ template<>
+ inline fapi2::ReturnCode variable_buffer::insert(const uint64_t& i_source,
+ bits_type i_targetStart,
+ bits_type i_len,
+ bits_type i_sourceStart)
+ {
+ // _insert wants 32 bit chunks, so lets turn our uint64_t into a
+ // uint32_t array (of 64 bits in length). Looks like a 64 bit variable_buffer.
+ uint32_t l_source[2] = {static_cast<uint32_t>((i_source & 0xFFFFFFFF00000000) >> 32),
+ static_cast<uint32_t>((i_source & 0x00000000FFFFFFFF))};
+
+ return _insert(l_source, parameterTraits<uint64_t>::bit_length(),
&(iv_data[0]), getBitLength(),
i_sourceStart, i_targetStart, i_len);
}
@@ -544,7 +661,8 @@ namespace fapi2
bits_type i_len,
bits_type i_sourceStart)
{
- return _insert((unit_type*)&(i_data()[0]), i_data.getBitLength(),
+ return _insert(reinterpret_cast<const unit_type*>(&(i_data()[0])),
+ i_data.getBitLength(),
&(iv_data[0]), getBitLength(),
i_sourceStart, i_targetStart, i_len);
}
@@ -558,7 +676,7 @@ namespace fapi2
bits_type i_targetStart,
bits_type i_len)
{
- _insertFromRight(i_data, parameterTraits<OT>::bit_length, i_targetStart, i_len);
+ return _insertFromRight(i_data, parameterTraits<OT>::bit_length(), i_targetStart, i_len);
}
//
@@ -571,7 +689,7 @@ namespace fapi2
bits_type i_len)
{
const bits_type bit_length_of_source = i_data.getBitLength();
- _insertFromRight(i_data, bit_length_of_source, i_targetStart, i_len);
+ return _insertFromRight(i_data, bit_length_of_source, i_targetStart, i_len);
}
@@ -586,19 +704,125 @@ namespace fapi2
bits_type i_start,
bits_type i_len) const
{
- // Needed to trick the compiler into matching the template below
- const bits_type max_length = parameterTraits<OT>::bit_length;
+ // If thy didn't pass an i_len, assume they want all the data
+ // which will fit.
+ if (i_len == static_cast<bits_type>(~0))
+ {
+ i_len = std::min(getBitLength(), parameterTraits<OT>::bit_length());
+ }
+
+ // _insert likes 32-bit targets. So lets make our target 32 bits.
+ uint32_t l_data = static_cast<uint32_t>(i_data);
+
+ ReturnCode rc;
+ if ((rc = _insert((container_unit*)&iv_data[0], getBitLength(),
+ &l_data, parameterTraits<uint32_t>::bit_length(),
+ i_start, 0U, i_len)) != FAPI2_RC_SUCCESS)
+ {
+ return rc;
+ }
+
+ // Shift back to the original bit width.
+ i_data = l_data >> (parameterTraits<uint32_t>::bit_length() - parameterTraits<OT>::bit_length());
+ return FAPI2_RC_SUCCESS;
+ }
+ template<>
+ inline fapi2::ReturnCode variable_buffer::extract(
+ uint64_t& i_data,
+ bits_type i_start,
+ bits_type i_len) const
+ {
// If thy didn't pass an i_len, assume they want all the data
// which will fit.
- if (i_len == ~0)
+ if ((i_len == static_cast<bits_type>(~0)) ||
+ (i_len > parameterTraits<uint64_t>::bit_length()))
{
- i_len = max_length;
+ i_len = std::min(getBitLength(), parameterTraits<uint64_t>::bit_length());
}
- return _insert((container_unit*)&iv_data[0], getBitLength(),
- &i_data, max_length,
- i_start, 0U, i_len);
+ // _insert wants 32 bit chunks, so lets turn our uint64_t into a
+ // uint32_t array (of 64 bits in length). Looks like a 64 bit variable_buffer.
+ uint32_t l_data[2] = {static_cast<uint32_t>((i_data & 0xFFFFFFFF00000000) >> 32),
+ static_cast<uint32_t>((i_data & 0x00000000FFFFFFFF))};
+
+ ReturnCode rc;
+ if ((rc = _insert((container_unit*)&iv_data[0], getBitLength(),
+ l_data, parameterTraits<uint64_t>::bit_length(),
+ i_start, 0U, i_len)) != FAPI2_RC_SUCCESS)
+ {
+ return rc;
+ }
+
+ i_data = static_cast<uint64_t>(l_data[0]) << 32;
+ i_data |= l_data[1];
+
+ return FAPI2_RC_SUCCESS;
+ }
+
+ //
+ // Generic extractToRight. Extract is an insert with the arguments reversed.
+ //
+ template<typename OT>
+ inline fapi2::ReturnCode variable_buffer::extractToRight(
+ OT& i_data,
+ bits_type i_start,
+ bits_type i_len) const
+ {
+ // If thy didn't pass an i_len, assume they want all the data
+ // which will fit.
+ if ((i_len == static_cast<bits_type>(~0)) ||
+ (i_len > parameterTraits<OT>::bit_length()))
+ {
+ i_len = std::min(getBitLength(), parameterTraits<OT>::bit_length());
+ }
+
+ // _insert likes 32-bit targets. So lets make our target 32 bits.
+ uint32_t l_data = static_cast<uint32_t>(i_data);
+
+ ReturnCode rc;
+ if ((rc = _insert(reinterpret_cast<const container_unit*>(&iv_data[0]), getBitLength(),
+ &l_data, parameterTraits<uint32_t>::bit_length(),
+ i_start, parameterTraits<uint32_t>::bit_length() - i_len, i_len)) != FAPI2_RC_SUCCESS)
+ {
+ return rc;
+ }
+
+ i_data = l_data;
+ return FAPI2_RC_SUCCESS;
+ }
+
+ template<>
+ inline fapi2::ReturnCode variable_buffer::extractToRight(
+ uint64_t& i_data,
+ bits_type i_start,
+ bits_type i_len) const
+ {
+ // If thy didn't pass an i_len, assume they want all the data
+ // which will fit.
+ if ((i_len == static_cast<bits_type>(~0)) ||
+ (i_len > parameterTraits<uint64_t>::bit_length()))
+ {
+ i_len = std::min(getBitLength(), parameterTraits<uint64_t>::bit_length());
+ }
+
+ // _insert wants 32 bit chunks, so lets turn our uint64_t into a
+ // uint32_t array (of 64 bits in length).
+ uint32_t l_data[2] = {static_cast<uint32_t>((i_data & 0xFFFFFFFF00000000) >> 32),
+ static_cast<uint32_t>((i_data & 0x00000000FFFFFFFF))};
+
+ ReturnCode rc;
+ if ((rc = _insert(reinterpret_cast<const container_unit*>(&iv_data[0]), getBitLength(),
+ l_data, parameterTraits<uint64_t>::bit_length(),
+ i_start, parameterTraits<uint64_t>::bit_length() - i_len, i_len)) != FAPI2_RC_SUCCESS)
+ {
+ return rc;
+ }
+
+ i_data = static_cast<uint64_t>(l_data[0]) << 32;
+ i_data |= l_data[1];
+
+ return FAPI2_RC_SUCCESS;
}
//
@@ -612,11 +836,11 @@ namespace fapi2
{
// If thy didn't pass an i_len, assume they want all the data
// which will fit.
- if (i_len == ~0)
+ if (i_len == static_cast<bits_type>(~0))
{
i_len = i_data.getBitLength();
}
- return _insert((container_unit*)&iv_data[0], getBitLength(),
+ return _insert(reinterpret_cast<const container_unit*>(&iv_data[0]), getBitLength(),
&(i_data()[0]), i_data.getBitLength(),
i_start, 0U, i_len);
}
@@ -632,7 +856,7 @@ namespace fapi2
{
// If they didn't pass in a length, assume they want all the i_data
// which will fit.
- if( i_len == ~0 )
+ if( i_len == static_cast<bits_type>(~0) )
{
// The longest the length can be is the length of the data
// This is the miniumum of the length of the data or the
@@ -657,7 +881,7 @@ namespace fapi2
bits_type i_offset);
#endif
/// @endcond
-};
+}
#endif
OpenPOWER on IntegriCloud