blob: e4475a50a115a64868c4af5dc36d4ad19c03d6b9 [file] [log] [blame]
#ifndef SOFTRVV_INTERNAL_H
#define SOFTRVV_INTERNAL_H
#include <bit>
#include <tuple>
namespace softrvv {
template <typename T>
inline std::tuple<int, int>get_element_and_pos(unsigned int index) {
// bw_required is the number of bits required to store the value
const unsigned int bw_required = std::__bit_width(sizeof(T)* 8);
const unsigned int shift = bw_required - 1;
// shift is the number of bits required to store the value minus 1
// Example for T is int32_t:
// 32 requires 6 bits to store, the shift required to divide by 32 is 5 (6 - 1)
// Shift of the index is equivalent to a divide
unsigned int element_idx = index >> shift;
// Masked lowers bits are equivalent to remainder
unsigned int element_pos = index & ~(element_idx << shift);
return std::make_tuple(element_idx, element_pos);
}
template <typename T>
inline void set_bit_in_dest_mask(unsigned int index, T *dest, bool set_bit) {
unsigned int element_idx;
unsigned int element_pos;
std::tie(element_idx, element_pos) = get_element_and_pos<T>(index);
T *dest_eptr = dest + element_idx;
if (set_bit) {
// Set the target bit
*dest_eptr |= (1 << element_pos);
} else {
// Clear the target bit
*dest_eptr &= ~(1 << element_pos);
}
}
} // namespace softrvv
#endif // SOFTRVV_INTERNAL_H