vwabdau.vx

Vector Widening Unsigned Integer Absolute Difference and Accumulate with Scalar

This instruction is defined by:

Encoding

svg

Synopsis

Computes the element-wise absolute difference of unsigned integer operands from vector register vs2 and scalar register xs1, and accumulates the results into the 2*SEW-bit elements of vd. The scalar is sign-extended or truncated to SEW before being interpreted as an unsigned value.

Reserved when SEW is neither 8 nor 16.

Access

M HS U VS VU

Always

Always

Always

Always

Always

Decode Variables

Bits<1> vm = $encoding[25];
Bits<5> vs2 = $encoding[24:20];
Bits<5> xs1 = $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;
}
Bits<64> scalar = $signed(X[xs1]);
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 + state.sew - 1;
  U32 dst_start = i * sew2;
  U32 dst_end = dst_start + sew2 - 1;
  if (vm == 1'b1 || V[0][i:i] == 1'b1) {
    if (V[vs2][src_end:src_start] >= scalar[state.sew - 1:0]) {
      V[vd][dst_end:dst_start] = V[vd][dst_end:dst_start] + (V[vs2][src_end:src_start] - scalar[state.sew - 1:0]);
    } else {
      V[vd][dst_end:dst_start] = V[vd][dst_end:dst_start] + (scalar[state.sew - 1:0] - 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;
}
Bits<64> scalar = $signed(X[xs1]);
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 + state.sew - 1;
  U32 dst_start = i * sew2;
  U32 dst_end = dst_start + sew2 - 1;
  if (vm == 1'b1 || V[0][i:i] == 1'b1) {
    if (V[vs2][src_end:src_start] >= scalar[state.sew - 1:0]) {
      V[vd][dst_end:dst_start] = V[vd][dst_end:dst_start] + (V[vs2][src_end:src_start] - scalar[state.sew - 1:0]);
    } else {
      V[vd][dst_end:dst_start] = V[vd][dst_end:dst_start] + (scalar[state.sew - 1:0] - V[vs2][src_end:src_start]);
    }
  }
}
CSR[vstart].VALUE = 0;

Exceptions

This instruction may result in the following synchronous exceptions:

  • IllegalInstruction