2#include "libmicroemu/internal/utils/traits.h"
3#include "libmicroemu/types.h"
11template <
typename T>
class BitManip {
14 std::is_same<T, u64>::value ||
15 std::is_same<T, u32>::value ||
16 std::is_same<T, u16>::value ||
17 std::is_same<T, u8>::value,
18 "BitManip only works for u32, u16 and u8");
35 template <T alignment>
static constexpr T
AlignDown(
const T &address) {
38 return address & ~(alignment - 1U);
55 template <T alignment>
static constexpr T
AlignUp(
const T &address) {
56 if (alignment == 0U) {
59 return (address + (alignment - 1U)) & ~(alignment - 1U);
68 return static_cast<T
>(
static_cast<T
>(1U) << bit);
77 template <
unsigned last_bit,
unsigned first_bit>
static constexpr T
GenerateBitMask() {
79 if constexpr (last_bit ==
sizeof(T) * 8U - 1U) {
80 T
constexpr msk = ~static_cast<T>(0U);
81 return static_cast<T
>(msk << first_bit);
83 auto constexpr shift_range = last_bit - first_bit + 1U;
84 T
constexpr one =
static_cast<T
>(1U);
85 T
constexpr msk = (one << shift_range) - one;
86 return static_cast<T
>(msk << first_bit);
97 if (last_bit ==
sizeof(T) * 8U - 1U) {
98 T
constexpr msk = ~static_cast<T>(0U);
99 return static_cast<T
>(msk << first_bit);
101 auto shift_range = last_bit - first_bit + 1U;
102 T
constexpr one =
static_cast<T
>(1U);
103 T msk = (one << shift_range) - one;
104 return static_cast<T
>(msk << first_bit);
114 template <
unsigned bit>
static constexpr T
IsolateBit(
const T &value) {
115 return (value & (
static_cast<T
>(1U) << bit)) >> bit;
124 template <
unsigned bit>
static constexpr bool IsBitSet(
const T &value) {
125 return (value & (
static_cast<T
>(1U) << bit)) != 0;
135 template <
unsigned last_bit,
unsigned first_bit>
152 template <
typename U>
static U
ExtractType(T value, u32 start_byte) {
153 assert(start_byte >= 0U && start_byte <= (
sizeof(T) - 1U));
154 auto bitpos = start_byte * 8U;
155 auto constexpr bitmask =
GenerateBitMask<
sizeof(U) * 8U - 1U, 0U>() - 1U;
156 return static_cast<U
>((value >> bitpos) & bitmask);
167 template <
typename U>
static T
InsertType(T value, u32 start_byte, U insert_val) {
168 assert(start_byte >= 0U && start_byte <= (
sizeof(T) - 1U));
169 auto start_pos = start_byte * 8U;
170 auto end_pos = start_pos +
sizeof(U) * 8 - 1U;
173 auto shifted_bits =
static_cast<T
>(insert_val) << start_pos;
174 return (value & (~mask)) | (shifted_bits & mask);
186 template <
unsigned r2_last_bit,
unsigned r2_first_bit,
unsigned r1_last_bit,
187 unsigned r1_first_bit>
190 (r2_first_bit - r1_last_bit + r1_first_bit - 1U)) +
200 template <
typename U>
static inline U
ZeroExtend(
const T &value) {
201 static_assert(std::is_same<U, u32>::value || std::is_same<U, u16>::value ||
202 std::is_same<U, u8>::value,
203 "ZeroExtend only works for u32, u16 and u8");
204 return static_cast<U
>(value);
214 template <
typename U,
unsigned top_bit>
static inline U
SignExtend(
const T &value) {
215 static_assert(std::is_same<U, u32>::value || std::is_same<U, u16>::value ||
216 std::is_same<U, u8>::value,
217 "ZeroExtend only works for u32, u16 and u8");
218 T s = (value >> top_bit) & 0x1U;
220 U value_u =
static_cast<U
>(value);
222 value_u = value_u | bitmask;
224 value_u = value_u & ~bitmask;
235 return value ==
static_cast<T
>(0U) ?
static_cast<T
>(1U) :
static_cast<T
>(0U);
263 while ((x & 1) == 0) {
270 static T CountLeadingZeros(
const T &value) {
312 ~BitManip() =
delete;
318 BitManip(
const BitManip &r_src) =
delete;
324 BitManip &operator=(
const BitManip &r_src) =
delete;
330 BitManip(BitManip &&r_src) =
delete;
336 BitManip &operator=(BitManip &&r_src) =
delete;
Definition bit_manip.h:11
static U ZeroExtend(const T &value)
Takes a value of type T and converts it to type U by extending the missing bits with 0.
Definition bit_manip.h:200
static T LowestBitSet(const T &value)
Finds the position of the lowest bit set in the given value.
Definition bit_manip.h:257
static constexpr T GenerateBitMask()
Generates a mask for the bit 'bit'.
Definition bit_manip.h:67
static constexpr T ExtractBits2R(const T &value)
Extracts bits from value in 2 bit regions and concatenates them.
Definition bit_manip.h:188
static constexpr bool IsBitSet(const T &value)
Checks if the given bit "bit" is set in the value.
Definition bit_manip.h:124
static U SignExtend(const T &value)
Takes a value of type T and converts it to type U by extending the given top bit.
Definition bit_manip.h:214
static constexpr T AlignUp(const T &address)
Aligns the given address up to the nearest multiple of the specified alignment.
Definition bit_manip.h:55
static constexpr T ExtractBits1R(const T &value)
Extracts bits from value in the region [last_bit:first_bit].
Definition bit_manip.h:136
static U ExtractType(T value, u32 start_byte)
Extracts bits from an value and returns the result as the specified type.
Definition bit_manip.h:152
static T IsZeroBit(const T &value)
Checks if the given value is zero.
Definition bit_manip.h:234
static constexpr T AlignDown(const T &address)
Aligns the given address down to the nearest multiple of the specified alignment.
Definition bit_manip.h:35
static constexpr T GenerateBitMask()
Generates a mask of 1 bits in the region [last_bit:first_bit].
Definition bit_manip.h:77
static T BitCount(const T &value)
Counts the number of bits set in the given value.
Definition bit_manip.h:243
static constexpr T GenerateBitMask(unsigned last_bit, unsigned first_bit)
Generates a mask of 1 bits in the region [last_bit:first_bit].
Definition bit_manip.h:96
static T InsertType(T value, u32 start_byte, U insert_val)
Inserts bits of a shorter type into a value at the specified byte position.
Definition bit_manip.h:167
static constexpr T IsolateBit(const T &value)
Isolates the given bit "bit" in the value.
Definition bit_manip.h:114
The libmicroemu::internal namespace contains all classes and functions of libmicroemu which are priva...
Definition bkpt_flags.h:6