adds support for narrowing shifts

This commit is contained in:
2025-02-13 21:05:49 +01:00
parent af3e76cc98
commit feaff8c4a5
2 changed files with 42 additions and 0 deletions

View File

@ -65,6 +65,12 @@ template <unsigned VLEN> vmask_view read_vmask(uint8_t* V, uint16_t elem_count,
assert(mask_start + elem_count / 8 <= V + VLEN * RFS / 8);
return {mask_start, elem_count};
}
template <typename elem_t> constexpr elem_t shift_mask() {
static_assert(std::numeric_limits<elem_t>::is_integer, "shift_mask only supports integer types");
return std::numeric_limits<elem_t>::digits - 1;
}
template <typename dest_elem_t, typename src2_elem_t = dest_elem_t, typename src1_elem_t = dest_elem_t>
std::function<dest_elem_t(src2_elem_t, src1_elem_t)> get_funct(unsigned funct) {
switch(funct) {
@ -85,6 +91,16 @@ std::function<dest_elem_t(src2_elem_t, src1_elem_t)> get_funct(unsigned funct) {
return [](src2_elem_t vs2, src1_elem_t vs1) { return vs1 | vs2; };
case 0b001011: // VXOR
return [](src2_elem_t vs2, src1_elem_t vs1) { return vs1 ^ vs2; };
case 0b100101: // VSLL
return [](src2_elem_t vs2, src1_elem_t vs1) { return vs2 << (vs1 & shift_mask<src2_elem_t>()); };
case 0b101000: // VSRL
case 0b101100: // VNSRL
return [](src2_elem_t vs2, src1_elem_t vs1) { return vs2 >> (vs1 & shift_mask<src2_elem_t>()); };
case 0b101001: // VSRA
case 0b101101: // VNSRA
return [](src2_elem_t vs2, src1_elem_t vs1) {
return static_cast<typename std::make_signed_t<src2_elem_t>>(vs2) >> (vs1 & shift_mask<src2_elem_t>());
};
case 0b110001: // VWADD
case 0b110101: // VWADD.W
return [](src2_elem_t vs2, src1_elem_t vs1) {