vwabda.vv
Vector Widening Signed Integer Absolute Difference and Accumulate, Overwrite Addend
This instruction is defined by:
Synopsis
Computes the element-wise absolute difference of two signed integer SEW-bit source operands vs1 and vs2, and accumulates the results into the elements of a 2*SEW-bit operand vd.
Reserved when SEW is neither 8 nor 16.
Decode Variables
Bits<1> vm = $encoding[25];
Bits<5> vs2 = $encoding[24:20];
Bits<5> vs1 = $encoding[19:15];
Bits<5> vd = $encoding[11:7];
Execution
-
Pruned, XLEN == 64
-
Original
VectorState state = vector_state();
if (state.sew != 8 && state.sew != 16) {
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
}
VectorLmulType lmul_type = state.lmul_type;
XReg vlen = 17'128;
XReg vlmax;
if (lmul_type == VectorLmulType::Multiply) {
vlmax = (64'128 << state.log2_lmul) >> state.log2_sew;
} else {
vlmax = (64'128 >> state.log2_lmul) >> state.log2_sew;
}
U32 sew2 = state.sew + state.sew;
for (U32 i = CSR[vstart].VALUE; i < CSR[vl].VALUE; i) {
U32 src_start = i * state.sew;
U32 src_end = src_start pass:[+] state.sew - 1;
U32 dst_start = i * sew2;
U32 dst_end = dst_start pass:[+] sew2 - 1;
if pass:[(]vm == 1'b1 || V[0][i:i] == 1'b1) {
if pass:[(]$signed(V[vs2][src_end:src_start]) >= $signed(++V[vs1][src_end:src_start])) {
V[vd][dst_end:dst_start] = V[vd][dst_end:dst_start] + (V[vs2][src_end:src_start] - V[vs1][src_end:src_start]);
} else {
V[vd][dst_end:dst_start] = V[vd][dst_end:dst_start] + (V[vs1][src_end:src_start] - V[vs2][src_end:src_start]);
}
}
}
CSR[vstart].VALUE = 0;
VectorState state = vector_state();
if (state.sew != 8 && state.sew != 16) {
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
}
VectorLmulType lmul_type = state.lmul_type;
XReg vlen = VLEN;
XReg vlmax;
if (lmul_type == VectorLmulType::Multiply) {
vlmax = (vlen << state.log2_lmul) >> state.log2_sew;
} else {
vlmax = (vlen >> state.log2_lmul) >> state.log2_sew;
}
U32 sew2 = state.sew + state.sew;
for (U32 i = CSR[vstart].VALUE; i < CSR[vl].VALUE; i) {
U32 src_start = i * state.sew;
U32 src_end = src_start pass:[+] state.sew - 1;
U32 dst_start = i * sew2;
U32 dst_end = dst_start pass:[+] sew2 - 1;
if pass:[(]vm == 1'b1 || V[0][i:i] == 1'b1) {
if pass:[(]$signed(V[vs2][src_end:src_start]) >= $signed(++V[vs1][src_end:src_start])) {
V[vd][dst_end:dst_start] = V[vd][dst_end:dst_start] + (V[vs2][src_end:src_start] - V[vs1][src_end:src_start]);
} else {
V[vd][dst_end:dst_start] = V[vd][dst_end:dst_start] + (V[vs1][src_end:src_start] - V[vs2][src_end:src_start]);
}
}
}
CSR[vstart].VALUE = 0;