From: Zhibo Hong <[email protected]>

The draft Zvabd extension version 0.9 provides vector integer
absolute-difference operations for image, video, and other
data-processing workloads. It introduces eight new instructions:

  - vabd.vv, vabd.vx, vabdu.vv, and vabdu.vx support SEW values from
    8 through ELEN, with SEW 64 requiring Zve64x.
  - vwabda.vv, vwabda.vx, vwabdau.vv, and vwabdau.vx support SEW 8
    and 16 and accumulate into a double-width destination.

This patch implements the extension, including instruction decoding,
TCG translation, and helper functions. This implementation targets
version 0.9, whose instruction encodings differ from version 0.7.

The specification is under review at:
https://github.com/riscv/riscv-isa-manual/pull/3279

Reviewed-by: Daniel Henrique Barboza <[email protected]>
Reviewed-by: Joel Stanley <[email protected]>
Signed-off-by: Zhibo Hong <[email protected]>
Signed-off-by: Mingliang Liu <[email protected]>
---
 disas/riscv-op.c.inc                        |  8 +++
 disas/riscv.c                               |  8 +++
 target/riscv/cpu.c                          |  1 +
 target/riscv/cpu_cfg_fields.h.inc           |  1 +
 target/riscv/helper.h                       | 26 ++++++++++
 target/riscv/insn32.decode                  | 10 ++++
 target/riscv/tcg/insn_trans/trans_rvv.c.inc | 45 +++++++++++++++++
 target/riscv/tcg/tcg-cpu.c                  |  6 +++
 target/riscv/tcg/vector_helper.c            | 56 +++++++++++++++++++++
 9 files changed, 161 insertions(+)

diff --git a/disas/riscv-op.c.inc b/disas/riscv-op.c.inc
index 1d334e4857..07b56f5d52 100644
--- a/disas/riscv-op.c.inc
+++ b/disas/riscv-op.c.inc
@@ -490,6 +490,10 @@ OP(vaadd_vv, "vaadd.vv", rv_codec_v_r, 
rv_fmt_vd_vs2_vs1_vm)
 OP(vaadd_vx, "vaadd.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm)
 OP(vaaddu_vv, "vaaddu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm)
 OP(vaaddu_vx, "vaaddu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm)
+OP(vabd_vv, "vabd.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm)
+OP(vabd_vx, "vabd.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm)
+OP(vabdu_vv, "vabdu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm)
+OP(vabdu_vx, "vabdu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm)
 OP(vadc_vim, "vadc.vim", rv_codec_v_i, rv_fmt_vd_vs2_imm_vl)
 OP(vadc_vvm, "vadc.vvm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vl)
 OP(vadc_vxm, "vadc.vxm", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vl)
@@ -861,6 +865,10 @@ OP(vsuxei16_v, "vsuxei16.v", rv_codec_v_r, 
rv_fmt_ldst_vd_rs1_vs2_vm)
 OP(vsuxei32_v, "vsuxei32.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm)
 OP(vsuxei64_v, "vsuxei64.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm)
 OP(vsuxei8_v, "vsuxei8.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm)
+OP(vwabda_vv, "vwabda.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm)
+OP(vwabda_vx, "vwabda.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm)
+OP(vwabdau_vv, "vwabdau.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm)
+OP(vwabdau_vx, "vwabdau.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm)
 OP(vwadd_vv, "vwadd.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm)
 OP(vwadd_vx, "vwadd.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm)
 OP(vwadd_wv, "vwadd.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm)
diff --git a/disas/riscv.c b/disas/riscv.c
index e85dbac035..b0102e47bc 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -2024,6 +2024,8 @@ static const rv_opcode_data *decode_inst_opcode(rv_decode 
*dec, rv_isa isa)
                 case 48: return &op_vwredsumu_vs;
                 case 49: return &op_vwredsum_vs;
                 case 53: return &op_vwsll_vv;
+                case 61: return &op_vwabda_vv;
+                case 62: return &op_vwabdau_vv;
                 }
                 break;
             case 1:
@@ -2166,6 +2168,8 @@ static const rv_opcode_data *decode_inst_opcode(rv_decode 
*dec, rv_isa isa)
                         break;
                     }
                     break;
+                case 21: return &op_vabd_vv;
+                case 22: return &op_vabdu_vv;
                 case 23:
                     if ((inst >> 25) & 1) {
                         return &op_vcompress_vm;
@@ -2351,6 +2355,8 @@ static const rv_opcode_data *decode_inst_opcode(rv_decode 
*dec, rv_isa isa)
                 case 46: return &op_vnclipu_wx;
                 case 47: return &op_vnclip_wx;
                 case 53: return &op_vwsll_vx;
+                case 61: return &op_vwabda_vx;
+                case 62: return &op_vwabdau_vx;
                 }
                 break;
             case 5:
@@ -2427,6 +2433,8 @@ static const rv_opcode_data *decode_inst_opcode(rv_decode 
*dec, rv_isa isa)
                         }
                     }
                     break;
+                case 21: return &op_vabd_vx;
+                case 22: return &op_vabdu_vx;
                 case 32: return &op_vdivu_vx;
                 case 33: return &op_vdiv_vx;
                 case 34: return &op_vremu_vx;
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index da4c1a090b..e08cb2f356 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -220,6 +220,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
     ISA_EXT_DATA_ENTRY(zksh, PRIV_VERSION_1_12_0, ext_zksh),
     ISA_EXT_DATA_ENTRY(zkt, PRIV_VERSION_1_12_0, ext_zkt),
     ISA_EXT_DATA_ENTRY(ztso, PRIV_VERSION_1_12_0, ext_ztso),
+    ISA_EXPERIMENTAL_EXT_DATA_ENTRY(zvabd, PRIV_VERSION_1_13_0, ext_zvabd),
     ISA_EXT_DATA_ENTRY(zvbb, PRIV_VERSION_1_12_0, ext_zvbb),
     ISA_EXT_DATA_ENTRY(zvbc, PRIV_VERSION_1_12_0, ext_zvbc),
     ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f),
diff --git a/target/riscv/cpu_cfg_fields.h.inc 
b/target/riscv/cpu_cfg_fields.h.inc
index f91c780299..6f567612fa 100644
--- a/target/riscv/cpu_cfg_fields.h.inc
+++ b/target/riscv/cpu_cfg_fields.h.inc
@@ -83,6 +83,7 @@ BOOL_FIELD(ext_zve32x)
 BOOL_FIELD(ext_zve64f)
 BOOL_FIELD(ext_zve64d)
 BOOL_FIELD(ext_zve64x)
+BOOL_FIELD(ext_zvabd)
 BOOL_FIELD(ext_zvbb)
 BOOL_FIELD(ext_zvbc)
 BOOL_FIELD(ext_zvkb)
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index aab92bf132..b7acb6fdc9 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1350,6 +1350,32 @@ DEF_HELPER_5(vsm4k_vi, void, ptr, ptr, i32, env, i32)
 DEF_HELPER_4(vsm4r_vv, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vsm4r_vs, void, ptr, ptr, env, i32)
 
+/* Zvabd Extension */
+DEF_HELPER_6(vabd_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vabd_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vabd_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vabd_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vabd_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vabd_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vabd_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vabd_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vabdu_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vabdu_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vabdu_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vabdu_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vabdu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vabdu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vabdu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vabdu_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vwabda_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vwabda_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vwabda_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vwabda_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vwabdau_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vwabdau_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vwabdau_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vwabdau_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+
 /* CFI (zicfiss) helpers */
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_1(ssamoswap_disabled, void, env)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index aa02dae3c9..288ce8a554 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -1086,3 +1086,13 @@ sb_aqrl  00111 . . ..... ..... 000 ..... 0101111 @atom_st
 sh_aqrl  00111 . . ..... ..... 001 ..... 0101111 @atom_st
 sw_aqrl  00111 . . ..... ..... 010 ..... 0101111 @atom_st
 sd_aqrl  00111 . . ..... ..... 011 ..... 0101111 @atom_st
+
+# *** Zvabd Extension ***
+vabd_vv       010101 . ..... ..... 010 ..... 1010111 @r_vm
+vabd_vx       010101 . ..... ..... 110 ..... 1010111 @r_vm
+vabdu_vv      010110 . ..... ..... 010 ..... 1010111 @r_vm
+vabdu_vx      010110 . ..... ..... 110 ..... 1010111 @r_vm
+vwabda_vv     111101 . ..... ..... 000 ..... 1010111 @r_vm
+vwabda_vx     111101 . ..... ..... 100 ..... 1010111 @r_vm
+vwabdau_vv    111110 . ..... ..... 000 ..... 1010111 @r_vm
+vwabdau_vx    111110 . ..... ..... 100 ..... 1010111 @r_vm
diff --git a/target/riscv/tcg/insn_trans/trans_rvv.c.inc 
b/target/riscv/tcg/insn_trans/trans_rvv.c.inc
index a22e2cae6c..14ef961607 100644
--- a/target/riscv/tcg/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/tcg/insn_trans/trans_rvv.c.inc
@@ -4091,3 +4091,48 @@ GEN_INT_EXT_TRANS(vzext_vf8, 3, 2)
 GEN_INT_EXT_TRANS(vsext_vf2, 1, 3)
 GEN_INT_EXT_TRANS(vsext_vf4, 2, 4)
 GEN_INT_EXT_TRANS(vsext_vf8, 3, 5)
+
+/* Zvabd Extension */
+#define GEN_ABD_CHECK(NAME, CHECK_FN, MAX_SEW)                       \
+static bool NAME(DisasContext *s, arg_rmrr *a)                       \
+{                                                                    \
+    return CHECK_FN(s, a) && s->cfg_ptr->ext_zvabd &&                \
+           s->sew <= MAX_SEW &&                                      \
+           (s->sew != MO_64 || s->cfg_ptr->ext_zve64x);              \
+}
+GEN_ABD_CHECK(vabd_vv_check, opivv_check, MO_64)
+GEN_ABD_CHECK(vabd_vx_check, opivx_check, MO_64)
+GEN_ABD_CHECK(vwabd_vv_check, opivv_overwrite_widen_check, MO_16)
+GEN_ABD_CHECK(vwabd_vx_check, opivx_overwrite_widen_check, MO_16)
+
+GEN_OPIVV_TRANS(vabd_vv, vabd_vv_check)
+GEN_OPIVX_TRANS(vabd_vx, vabd_vx_check)
+GEN_OPIVV_TRANS(vabdu_vv, vabd_vv_check)
+GEN_OPIVX_TRANS(vabdu_vx, vabd_vx_check)
+
+#define GEN_ABD_OPIVV_WIDEN_TRANS(NAME, CHECK)                          \
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a)                  \
+{                                                                       \
+    static gen_helper_gvec_4_ptr * const fns[2] = {                     \
+        gen_helper_##NAME##_b, gen_helper_##NAME##_h,                   \
+    };                                                                  \
+    return s->sew <= MO_16 && do_opivv_widen(s, a, fns[s->sew], CHECK); \
+}
+
+#define GEN_ABD_OPIVX_WIDEN_TRANS(NAME, CHECK)                          \
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a)                  \
+{                                                                       \
+    if (CHECK(s, a)) {                                                  \
+        static gen_helper_opivx * const fns[2] = {                      \
+            gen_helper_##NAME##_b, gen_helper_##NAME##_h,               \
+        };                                                              \
+        return opivx_trans(a->rd, a->rs1, a->rs2, a->vm,                \
+                           fns[s->sew], s);                             \
+    }                                                                   \
+    return false;                                                       \
+}
+
+GEN_ABD_OPIVV_WIDEN_TRANS(vwabda_vv, vwabd_vv_check)
+GEN_ABD_OPIVX_WIDEN_TRANS(vwabda_vx, vwabd_vx_check)
+GEN_ABD_OPIVV_WIDEN_TRANS(vwabdau_vv, vwabd_vv_check)
+GEN_ABD_OPIVX_WIDEN_TRANS(vwabdau_vx, vwabd_vx_check)
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index b68160af83..be2332083c 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -731,6 +731,12 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, 
Error **errp)
         return;
     }
 
+    if ((cpu->cfg.ext_zvabd) && !cpu->cfg.ext_zve32x) {
+        error_setg(errp,
+                   "Zvabd extensions require V or Zve* extensions");
+        return;
+    }
+
     if (cpu->cfg.ext_zicntr && !cpu->cfg.ext_zicsr) {
         if (cpu_cfg_ext_is_user_set(cpu, CPU_CFG_OFFSET(ext_zicntr))) {
             error_setg(errp, "zicntr requires zicsr");
diff --git a/target/riscv/tcg/vector_helper.c b/target/riscv/tcg/vector_helper.c
index 0d1e4e0964..917a48b510 100644
--- a/target/riscv/tcg/vector_helper.c
+++ b/target/riscv/tcg/vector_helper.c
@@ -5911,3 +5911,59 @@ GEN_VEXT_INT_EXT(vsext_vf2_d, int64_t, int32_t, H8, H4)
 GEN_VEXT_INT_EXT(vsext_vf4_w, int32_t, int8_t,  H4, H1)
 GEN_VEXT_INT_EXT(vsext_vf4_d, int64_t, int16_t, H8, H2)
 GEN_VEXT_INT_EXT(vsext_vf8_d, int64_t, int8_t,  H8, H1)
+
+/* Zvabd Extension */
+#define DO_ABD(N, M)  (N > M ? N - M : M - N)
+#define DO_ABDACC(N, M, D) (DO_ABD(N, M) + D)
+
+RVVCALL(OPIVV2, vabd_vv_b, OP_SSS_B, H1, H1, H1, DO_ABD)
+RVVCALL(OPIVV2, vabd_vv_h, OP_SSS_H, H2, H2, H2, DO_ABD)
+RVVCALL(OPIVV2, vabd_vv_w, OP_SSS_W, H4, H4, H4, DO_ABD)
+RVVCALL(OPIVV2, vabd_vv_d, OP_SSS_D, H8, H8, H8, DO_ABD)
+RVVCALL(OPIVX2, vabd_vx_b, OP_SSS_B, H1, H1, DO_ABD)
+RVVCALL(OPIVX2, vabd_vx_h, OP_SSS_H, H2, H2, DO_ABD)
+RVVCALL(OPIVX2, vabd_vx_w, OP_SSS_W, H4, H4, DO_ABD)
+RVVCALL(OPIVX2, vabd_vx_d, OP_SSS_D, H8, H8, DO_ABD)
+RVVCALL(OPIVV2, vabdu_vv_b, OP_UUU_B, H1, H1, H1, DO_ABD)
+RVVCALL(OPIVV2, vabdu_vv_h, OP_UUU_H, H2, H2, H2, DO_ABD)
+RVVCALL(OPIVV2, vabdu_vv_w, OP_UUU_W, H4, H4, H4, DO_ABD)
+RVVCALL(OPIVV2, vabdu_vv_d, OP_UUU_D, H8, H8, H8, DO_ABD)
+RVVCALL(OPIVX2, vabdu_vx_b, OP_UUU_B, H1, H1, DO_ABD)
+RVVCALL(OPIVX2, vabdu_vx_h, OP_UUU_H, H2, H2, DO_ABD)
+RVVCALL(OPIVX2, vabdu_vx_w, OP_UUU_W, H4, H4, DO_ABD)
+RVVCALL(OPIVX2, vabdu_vx_d, OP_UUU_D, H8, H8, DO_ABD)
+
+RVVCALL(OPIVV3, vwabda_vv_b, WOP_SSS_B, H2, H1, H1, DO_ABDACC)
+RVVCALL(OPIVV3, vwabda_vv_h, WOP_SSS_H, H4, H2, H2, DO_ABDACC)
+RVVCALL(OPIVX3, vwabda_vx_b, WOP_SSS_B, H2, H1, DO_ABDACC)
+RVVCALL(OPIVX3, vwabda_vx_h, WOP_SSS_H, H4, H2, DO_ABDACC)
+RVVCALL(OPIVV3, vwabdau_vv_b, WOP_UUU_B, H2, H1, H1, DO_ABDACC)
+RVVCALL(OPIVV3, vwabdau_vv_h, WOP_UUU_H, H4, H2, H2, DO_ABDACC)
+RVVCALL(OPIVX3, vwabdau_vx_b, WOP_UUU_B, H2, H1, DO_ABDACC)
+RVVCALL(OPIVX3, vwabdau_vx_h, WOP_UUU_H, H4, H2, DO_ABDACC)
+
+GEN_VEXT_VV(vabd_vv_b, 1)
+GEN_VEXT_VV(vabd_vv_h, 2)
+GEN_VEXT_VV(vabd_vv_w, 4)
+GEN_VEXT_VV(vabd_vv_d, 8)
+GEN_VEXT_VX(vabd_vx_b, 1)
+GEN_VEXT_VX(vabd_vx_h, 2)
+GEN_VEXT_VX(vabd_vx_w, 4)
+GEN_VEXT_VX(vabd_vx_d, 8)
+GEN_VEXT_VV(vabdu_vv_b, 1)
+GEN_VEXT_VV(vabdu_vv_h, 2)
+GEN_VEXT_VV(vabdu_vv_w, 4)
+GEN_VEXT_VV(vabdu_vv_d, 8)
+GEN_VEXT_VX(vabdu_vx_b, 1)
+GEN_VEXT_VX(vabdu_vx_h, 2)
+GEN_VEXT_VX(vabdu_vx_w, 4)
+GEN_VEXT_VX(vabdu_vx_d, 8)
+
+GEN_VEXT_VV(vwabda_vv_b, 2)
+GEN_VEXT_VV(vwabda_vv_h, 4)
+GEN_VEXT_VX(vwabda_vx_b, 2)
+GEN_VEXT_VX(vwabda_vx_h, 4)
+GEN_VEXT_VV(vwabdau_vv_b, 2)
+GEN_VEXT_VV(vwabdau_vv_h, 4)
+GEN_VEXT_VX(vwabdau_vx_b, 2)
+GEN_VEXT_VX(vwabdau_vx_h, 4)
-- 
2.39.5

Reply via email to