arch-riscv: Fix RVV instructions vmsbf/vmsif/vmsof (#814)

This pull request has two commits, one is to fix the segmentation fault,

> arch-riscv: Fix segmentation fault in vmsbf/vmsof/vmsif
    
    This commit simplifies the conditional logic in vmsbf/vmsof/vmsif
    by removing an unnecessary variable and condition.
The updated logic checks 'this->vm' or the result of 'elem_mask(v0, i)'
    directly, which prevents a segmentation fault regardless of
    whether 'vm' is set or not.

another is to fix the incorrect output,

> arch-riscv: Add template Vector1Vs1VdMaskDeclare
    
    This commit adds a new template, Vector1Vs1VdMaskDeclare, to replace
    the use of Vector1Vs1RdMaskDeclare in Vector1Vs1VdMaskFormat.
    
The change addresses the issue with the number of indices in
srcRegIdxArr.
Only two indices are available in Vector1Vs1RdMaskDeclare, but
instructions
    that use Vector1Vs1VdMaskFormat, like 'vmsbf', require three indices
    (for vs1, vs2(old_vd), and vm) to function correctly.
    
Demonstration of incorrect output compared with spike:
[vmsbf](https://github.com/QQeg/rvv_intrinsic_testcases/tree/master/vmsbf)
```
**** REAL SIMULATION ****
src/sim/simulate.cc:199: info: Entering event queue @ 0.  Starting simulation...
Vs1 = 0 0 0 0 0 0 0 0   1 1 1 1 1 1 1 1   1 1 1 1 1 1 1 1   1 1 1 1 1 1 1 1   
Vd  = 1 1 1 1 1 1 1 1   1 1 1 1 1 1 1 1   1 1 1 1 1 1 1 1   1 1 1 1 1 1 1 1   
Exiting @ tick 23504000 because exiting with last active thread context

 ----SPIKE----
bbl loader
Vs1 = 0 0 0 0 0 0 0 0   1 1 1 1 1 1 1 1   1 1 1 1 1 1 1 1   1 1 1 1 1 1 1 1   
Vd  = 1 1 1 1 1 1 1 1   0 0 0 0 0 0 0 0   0 0 0 0 0 0 0 0   0 0 0 0 0 0 0 0
```
This commit is contained in:
Jason Lowe-Power
2024-01-29 08:28:16 -08:00
committed by GitHub
3 changed files with 22 additions and 10 deletions

View File

@@ -3146,12 +3146,11 @@ decode QUADRANT default Unknown::unknown() {
bool has_one = false;
for (uint32_t i = 0; i < (uint32_t)machInst.vl; i++) {
bool vs2_lsb = elem_mask(Vs2_vu, i);
bool do_mask = elem_mask(v0, i);
if(this->vm||(this->vm == 0&&do_mask)){
if (this->vm || elem_mask(v0, i)){
uint64_t res = 0;
if (!has_one && !vs2_lsb) {
res = 1;
} else if(!has_one && vs2_lsb) {
} else if (!has_one && vs2_lsb) {
has_one = true;
}
Vd_ub[i/8] = ASSIGN_VD_BIT(i, res);
@@ -3162,10 +3161,9 @@ decode QUADRANT default Unknown::unknown() {
bool has_one = false;
for (uint32_t i = 0; i < (uint32_t)machInst.vl; i++) {
bool vs2_lsb = elem_mask(Vs2_vu, i);
bool do_mask = elem_mask(v0, i);
if(this->vm||(this->vm == 0&&do_mask)){
if (this->vm || elem_mask(v0, i)){
uint64_t res = 0;
if(!has_one && vs2_lsb) {
if (!has_one && vs2_lsb) {
has_one = true;
res = 1;
}
@@ -3177,12 +3175,11 @@ decode QUADRANT default Unknown::unknown() {
bool has_one = false;
for (uint32_t i = 0; i < (uint32_t)machInst.vl; i++) {
bool vs2_lsb = elem_mask(Vs2_vu, i);
bool do_mask = elem_mask(v0, i);
if(this->vm||(this->vm == 0&&do_mask)){
if (this->vm || elem_mask(v0, i)){
uint64_t res = 0;
if (!has_one && !vs2_lsb) {
res = 1;
} else if(!has_one && vs2_lsb) {
} else if (!has_one && vs2_lsb) {
has_one = true;
res = 1;
}

View File

@@ -1049,7 +1049,7 @@ def format Vector1Vs1VdMaskFormat(code, category, *flags){{
},
flags)
header_output = Vector1Vs1RdMaskDeclare.subst(iop)
header_output = Vector1Vs1VdMaskDeclare.subst(iop)
decoder_output = Vector1Vs1VdMaskConstructor.subst(iop)
exec_output = Vector1Vs1VdMaskExecute.subst(iop)
decode_block = VectorMaskDecodeBlock.subst(iop)

View File

@@ -951,6 +951,21 @@ Fault
}};
def template Vector1Vs1VdMaskDeclare {{
template<typename ElemType>
class %(class_name)s : public %(base_class)s {
private:
RegId srcRegIdxArr[3];
RegId destRegIdxArr[1];
bool vm;
public:
%(class_name)s(ExtMachInst _machInst);
Fault execute(ExecContext* xc, trace::InstRecord* traceData)const override;
using %(base_class)s::generateDisassembly;
};
}};
def template Vector1Vs1VdMaskConstructor {{