blob: 3df396a2f2491beb616fb1f529f85791268130f2 [file] [log] [blame]
/*
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#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