adds gather instructions

This commit is contained in:
Eyck-Alexander Jentzsch 2025-02-21 17:29:57 +01:00
parent a26505cb5c
commit 877cad27ba
3 changed files with 85 additions and 1 deletions

View File

@ -622,6 +622,48 @@ if(vector != null) {%>
throw new std::runtime_error("Unsupported sew bit value");
}
}
void vector_vector_gather(uint8_t* V, uint64_t vl, uint64_t vstart, softvector::vtype_t vtype, bool vm, uint8_t vd, uint8_t vs2, uint8_t vs1, uint8_t sew_val){
switch(sew_val){
case 0b000:
return softvector::vector_vector_gather<${vlen}, uint8_t>(V, vl, vstart, vtype, vm, vd, vs2, vs1);
case 0b001:
return softvector::vector_vector_gather<${vlen}, uint16_t>(V, vl, vstart, vtype, vm, vd, vs2, vs1);
case 0b010:
return softvector::vector_vector_gather<${vlen}, uint32_t>(V, vl, vstart, vtype, vm, vd, vs2, vs1);
case 0b011:
return softvector::vector_vector_gather<${vlen}, uint64_t>(V, vl, vstart, vtype, vm, vd, vs2, vs1);
default:
throw new std::runtime_error("Unsupported sew bit value");
}
}
void vector_vector_gatherei16(uint8_t* V, uint64_t vl, uint64_t vstart, softvector::vtype_t vtype, bool vm, uint8_t vd, uint8_t vs2, uint8_t vs1, uint8_t sew_val){
switch(sew_val){
case 0b000:
return softvector::vector_vector_gather<${vlen}, uint8_t, uint16_t>(V, vl, vstart, vtype, vm, vd, vs2, vs1);
case 0b001:
return softvector::vector_vector_gather<${vlen}, uint16_t, uint16_t>(V, vl, vstart, vtype, vm, vd, vs2, vs1);
case 0b010:
return softvector::vector_vector_gather<${vlen}, uint32_t, uint16_t>(V, vl, vstart, vtype, vm, vd, vs2, vs1);
case 0b011:
return softvector::vector_vector_gather<${vlen}, uint64_t, uint16_t>(V, vl, vstart, vtype, vm, vd, vs2, vs1);
default:
throw new std::runtime_error("Unsupported sew bit value");
}
}
void vector_imm_gather(uint8_t* V, uint64_t vl, uint64_t vstart, softvector::vtype_t vtype, bool vm, uint8_t vd, uint8_t vs2, uint64_t imm, uint8_t sew_val){
switch(sew_val){
case 0b000:
return softvector::vector_imm_gather<${vlen}, uint8_t>(V, vl, vstart, vtype, vm, vd, vs2, imm);
case 0b001:
return softvector::vector_imm_gather<${vlen}, uint16_t>(V, vl, vstart, vtype, vm, vd, vs2, imm);
case 0b010:
return softvector::vector_imm_gather<${vlen}, uint32_t>(V, vl, vstart, vtype, vm, vd, vs2, imm);
case 0b011:
return softvector::vector_imm_gather<${vlen}, uint64_t>(V, vl, vstart, vtype, vm, vd, vs2, imm);
default:
throw new std::runtime_error("Unsupported sew bit value");
}
}
<%}%>
uint64_t fetch_count{0};
uint64_t tval{0};

View File

@ -115,7 +115,10 @@ template <unsigned VLEN, typename src_elem_t>
void vector_slide1up(uint8_t* V, uint64_t vl, uint64_t vstart, vtype_t vtype, bool vm, unsigned vd, unsigned vs2, int64_t imm);
template <unsigned VLEN, typename src_elem_t>
void vector_slide1down(uint8_t* V, uint64_t vl, uint64_t vstart, vtype_t vtype, bool vm, unsigned vd, unsigned vs2, int64_t imm);
template <unsigned VLEN, typename dest_elem_t, typename scr_elem_t = dest_elem_t>
void vector_vector_gather(uint8_t* V, uint64_t vl, uint64_t vstart, vtype_t vtype, bool vm, unsigned vd, unsigned vs2, unsigned vs1);
template <unsigned VLEN, typename scr_elem_t>
void vector_imm_gather(uint8_t* V, uint64_t vl, uint64_t vstart, vtype_t vtype, bool vm, unsigned vd, unsigned vs2, uint64_t imm);
} // namespace softvector
#include "vm/vector_functions.hpp"
#endif /* _VM_VECTOR_FUNCTIONS_H_ */

View File

@ -1068,4 +1068,43 @@ void vector_slide1down(uint8_t* V, uint64_t vl, uint64_t vstart, vtype_t vtype,
vd_view[0] = vtype.vma() ? vd_view[0] : vd_view[0];
}
}
template <unsigned VLEN, typename dest_elem_t, typename scr_elem_t>
void vector_vector_gather(uint8_t* V, uint64_t vl, uint64_t vstart, vtype_t vtype, bool vm, unsigned vd, unsigned vs2, unsigned vs1) {
uint64_t vlmax = VLEN * vtype.lmul() / vtype.sew();
vmask_view mask_reg = read_vmask<VLEN>(V, vlmax);
auto vs1_view = get_vreg<VLEN, scr_elem_t>(V, vs1, vlmax);
auto vs2_view = get_vreg<VLEN, dest_elem_t>(V, vs2, vlmax);
auto vd_view = get_vreg<VLEN, dest_elem_t>(V, vd, vlmax);
for(unsigned idx = vstart; idx < std::min(vlmax, vl); idx++) {
bool mask_active = vm ? 1 : mask_reg[idx];
if(mask_active) {
vd_view[idx] = (vs1_view[idx] >= vlmax) ? 0 : vs2_view[vs1_view[idx]];
} else {
vd_view[idx] = vtype.vma() ? vd_view[idx] : vd_view[idx];
}
}
for(unsigned idx = vl; idx < vlmax; idx++) {
vd_view[idx] = vtype.vta() ? vd_view[idx] : vd_view[idx];
}
return;
}
template <unsigned VLEN, typename scr_elem_t>
void vector_imm_gather(uint8_t* V, uint64_t vl, uint64_t vstart, vtype_t vtype, bool vm, unsigned vd, unsigned vs2, uint64_t imm) {
uint64_t vlmax = VLEN * vtype.lmul() / vtype.sew();
vmask_view mask_reg = read_vmask<VLEN>(V, vlmax);
auto vs2_view = get_vreg<VLEN, scr_elem_t>(V, vs2, vlmax);
auto vd_view = get_vreg<VLEN, scr_elem_t>(V, vd, vlmax);
for(unsigned idx = vstart; idx < std::min(vlmax, vl); idx++) {
bool mask_active = vm ? 1 : mask_reg[idx];
if(mask_active) {
vd_view[idx] = (imm >= vlmax) ? 0 : vs2_view[imm];
} else {
vd_view[idx] = vtype.vma() ? vd_view[idx] : vd_view[idx];
}
}
for(unsigned idx = vl; idx < vlmax; idx++) {
vd_view[idx] = vtype.vta() ? vd_view[idx] : vd_view[idx];
}
return;
}
} // namespace softvector