From 3bfe3ce5eec998dd1fb8ab4f44542abc6f6df60b Mon Sep 17 00:00:00 2001 From: Zhibo Hong Date: Thu, 13 Nov 2025 21:08:54 +0800 Subject: [PATCH] Add Zvabd extension. --- README.md | 1 + disasm/disasm.cc | 8 +++++++ disasm/isa_parser.cc | 2 ++ riscv/insns/vabd_vv.h | 9 +++++++ riscv/insns/vabdu_vv.h | 9 +++++++ riscv/insns/vabs_v.h | 8 +++++++ riscv/insns/vwabda_vv.h | 10 ++++++++ riscv/insns/vwabdau_vv.h | 10 ++++++++ riscv/isa_parser.h | 1 + riscv/riscv.mk.in | 8 +++++++ riscv/v_ext_macros.h | 52 ++++++++++++++++++++++++++++++++++++++++ 11 files changed, 118 insertions(+) create mode 100644 riscv/insns/vabd_vv.h create mode 100644 riscv/insns/vabdu_vv.h create mode 100644 riscv/insns/vabs_v.h create mode 100644 riscv/insns/vwabda_vv.h create mode 100644 riscv/insns/vwabdau_vv.h diff --git a/README.md b/README.md index 0639d727..47676100 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,7 @@ Spike supports the following RISC-V ISA features: - Zfbfmin extension, v0.6 - Zvfbfmin extension, v0.6 - Zvfbfwma extension, v0.6 + - Zvabd extension, v0.7 - Zvbb extension, v1.0 - Zvbc extension, v1.0 - Zvkg extension, v1.0 diff --git a/disasm/disasm.cc b/disasm/disasm.cc index 63468ce9..37dfb2c5 100644 --- a/disasm/disasm.cc +++ b/disasm/disasm.cc @@ -2175,6 +2175,14 @@ void disassembler_t::add_instructions(const isa_parser_t* isa, bool strict) DEFINE_R1TYPE(sm3p1); } + if (ext_enabled(EXT_ZVABD)) { + DEFINE_VECTOR_V(vabs_v); + DEFINE_VECTOR_VV(vabd_vv); + DEFINE_VECTOR_VV(vabdu_vv); + DEFINE_VECTOR_MULTIPLYADD_VV(vwabda_vv); + DEFINE_VECTOR_MULTIPLYADD_VV(vwabdau_vv); + } + if (ext_enabled(EXT_ZVBB)) { #define DEFINE_VECTOR_VIU_ZIMM6(code) \ add_vector_viu_z6_insn(this, #code, match_##code, mask_##code) diff --git a/disasm/isa_parser.cc b/disasm/isa_parser.cc index 448b4684..32151744 100644 --- a/disasm/isa_parser.cc +++ b/disasm/isa_parser.cc @@ -244,6 +244,8 @@ void isa_parser_t::add_extension(const std::string& ext_str, const char* str) extension_table[EXT_ZCLSD] = true; extension_table[EXT_ZCA] = true; extension_table[EXT_ZILSD] = true; + } else if (ext_str == "zvabd") { + extension_table[EXT_ZVABD] = true; } else if (ext_str == "zvkb") { extension_table[EXT_ZVKB] = true; } else if (ext_str == "zvbb") { diff --git a/riscv/insns/vabd_vv.h b/riscv/insns/vabd_vv.h new file mode 100644 index 00000000..ea4797f8 --- /dev/null +++ b/riscv/insns/vabd_vv.h @@ -0,0 +1,9 @@ +// vabd.vv vd, vs1, vs2, vm + +require_zvabd; +require(P.VU.vsew <= e16); + +VI_VV_LOOP +({ + vd = DO_ABD(vs1, vs2); +}) diff --git a/riscv/insns/vabdu_vv.h b/riscv/insns/vabdu_vv.h new file mode 100644 index 00000000..183ba334 --- /dev/null +++ b/riscv/insns/vabdu_vv.h @@ -0,0 +1,9 @@ +// vabdu.vv vd, vs1, vs2, vm + +require_zvabd; +require(P.VU.vsew <= e16); + +VI_VV_ULOOP +({ + vd = DO_ABD(vs1, vs2); +}) diff --git a/riscv/insns/vabs_v.h b/riscv/insns/vabs_v.h new file mode 100644 index 00000000..f175eb04 --- /dev/null +++ b/riscv/insns/vabs_v.h @@ -0,0 +1,8 @@ +// vabs.v vd, vs2, vm + +require_zvabd; + +VI_V_LOOP +({ + vd = vs2 > 0 ? vs2 : -vs2; +}) diff --git a/riscv/insns/vwabda_vv.h b/riscv/insns/vwabda_vv.h new file mode 100644 index 00000000..ef8face0 --- /dev/null +++ b/riscv/insns/vwabda_vv.h @@ -0,0 +1,10 @@ +// vwabda.vv vd, vs2, vs1, vm + +require_zvabd; +require(P.VU.vsew <= e16); +VI_CHECK_DSS(true); + +VI_VV_LOOP_WIDEN +({ + VI_WIDE_OP_MACRO_AND_ASSIGN(vs2, vs1, vd_w, DO_ABD, int); +}) diff --git a/riscv/insns/vwabdau_vv.h b/riscv/insns/vwabdau_vv.h new file mode 100644 index 00000000..fd662543 --- /dev/null +++ b/riscv/insns/vwabdau_vv.h @@ -0,0 +1,10 @@ +// vwabdau.vv vd, vs2, vs1, vm + +require_zvabd; +require(P.VU.vsew <= e16); +VI_CHECK_DSS(true); + +VI_VV_LOOP_WIDEN +({ + VI_WIDE_OP_MACRO_AND_ASSIGN(vs2, vs1, vd_w, DO_ABD, uint); +}) diff --git a/riscv/isa_parser.h b/riscv/isa_parser.h index 2fc0f3aa..ed669831 100644 --- a/riscv/isa_parser.h +++ b/riscv/isa_parser.h @@ -66,6 +66,7 @@ typedef enum { EXT_ZICOND, EXT_ZIHPM, EXT_ZILSD, + EXT_ZVABD, EXT_ZVBB, EXT_ZVKB, EXT_ZVBC, diff --git a/riscv/riscv.mk.in b/riscv/riscv.mk.in index ae87a4d7..3a6bd3a1 100644 --- a/riscv/riscv.mk.in +++ b/riscv/riscv.mk.in @@ -1136,6 +1136,13 @@ riscv_insn_ext_zvk = \ $(riscv_insn_ext_zvksed) \ $(riscv_insn_ext_zvksh) \ +riscv_insn_ext_zvabd = \ + vabs_v \ + vabd_vv \ + vabdu_vv \ + vwabda_vv \ + vwabdau_vv \ + riscv_insn_list = \ $(riscv_insn_ext_i) \ $(riscv_insn_ext_c) \ @@ -1166,6 +1173,7 @@ riscv_insn_list = \ $(riscv_insn_ext_zvk) \ $(riscv_insn_ext_zvbdot) \ $(riscv_insn_ext_zvldot) \ + $(riscv_insn_ext_zvabd) \ $(riscv_insn_priv) \ $(riscv_insn_smrnmi) \ $(riscv_insn_svinval) \ diff --git a/riscv/v_ext_macros.h b/riscv/v_ext_macros.h index e96fc122..b30cd215 100644 --- a/riscv/v_ext_macros.h +++ b/riscv/v_ext_macros.h @@ -72,6 +72,12 @@ static inline bool is_overlapped_widen(const int astart, int asize, #define require_zvfbfa_or_zvfhmin \ require_extension(P.VU.altfmt ? EXT_ZVFBFA : EXT_ZVFHMIN); \ +#define require_zvabd \ + do { \ + require_vector(true); \ + require_extension(EXT_ZVABD); \ + } while (0) + #define VI_NARROW_CHECK_COMMON(factor) \ require_vector(true); \ require(P.VU.vflmul <= (8 / factor)); \ @@ -353,6 +359,10 @@ static inline bool is_overlapped_widen(const int astart, int asize, type_sew_t::type vs1 = P.VU.elt::type>(rs1_num, i); \ type_sew_t::type UNUSED vs2 = P.VU.elt::type>(rs2_num, i); +#define V_PARAMS(x) \ + type_sew_t::type &vd = P.VU.elt::type>(rd_num, i, true); \ + type_sew_t::type vs2 = P.VU.elt::type>(rs2_num, i); + #define VX_PARAMS(x) \ type_sew_t::type UNUSED &vd = P.VU.elt::type>(rd_num, i, true); \ type_sew_t::type rs1 = (type_sew_t::type)RS1; \ @@ -723,6 +733,24 @@ static inline bool is_overlapped_widen(const int astart, int asize, } \ VI_LOOP_END +#define VI_V_LOOP(BODY) \ + VI_CHECK_SSS(false) \ + VI_LOOP_BASE \ + if (sew == e8) { \ + V_PARAMS(e8); \ + BODY; \ + } else if (sew == e16) { \ + V_PARAMS(e16); \ + BODY; \ + } else if (sew == e32) { \ + V_PARAMS(e32); \ + BODY; \ + } else if (sew == e64) { \ + V_PARAMS(e64); \ + BODY; \ + } \ + VI_LOOP_END + #define VI_VX_ULOOP(BODY) \ VI_CHECK_SSS(false) \ VI_LOOP_BASE \ @@ -974,6 +1002,28 @@ static inline bool is_overlapped_widen(const int astart, int asize, break; \ } +#define VI_WIDE_OP_MACRO_AND_ASSIGN(var0, var1, var2, op, sign) \ + switch (P.VU.vsew) { \ + case e8: { \ + sign##16_t UNUSED vd_w = P.VU.elt(rd_num, i); \ + P.VU.elt(rd_num, i, true) = \ + op((sign##16_t)(sign##8_t)var0, (sign##16_t)(sign##8_t)var1) + var2; \ + } \ + break; \ + case e16: { \ + sign##32_t UNUSED vd_w = P.VU.elt(rd_num, i); \ + P.VU.elt(rd_num, i, true) = \ + op((sign##32_t)(sign##16_t)var0, (sign##32_t)(sign##16_t)var1) + var2; \ + } \ + break; \ + default: { \ + sign##64_t UNUSED vd_w = P.VU.elt(rd_num, i); \ + P.VU.elt(rd_num, i, true) = \ + op((sign##64_t)(sign##32_t)var0, (sign##64_t)(sign##32_t)var1) + var2; \ + } \ + break; \ + } + #define VI_WIDE_OP_AND_ASSIGN_MIX(var0, var1, var2, op0, op1, sign_d, sign_1, sign_2) \ switch (P.VU.vsew) { \ case e8: { \ @@ -2238,4 +2288,6 @@ c_t generic_dot_product(const std::vector& a, const std::vector& b, c_ #define P_SET_OV(ov) \ if (ov) P.VU.vxsat->write(1); +#define DO_ABD(N, M) ((N) > (M) ? (N) - (M) : (M) - (N)) + #endif