[binutils-gdb] RISC-V: Add Zvbdota extension support
Jeff Law via Binutils-cvs <[email protected]> Tue, 30 Jun 2026 13:55:36 +0000 (GMT)
| Newsgroups | gmane.comp.gnu.binutils.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=794f538c3e57e3f55a6224a7206fdb0ea7815a82 commit 794f538c3e57e3f55a6224a7206fdb0ea7815a82 Author: Jiawei <[email protected]> Date: Tue Jun 30 07:55:11 2026 -0600 RISC-V: Add Zvbdota extension support This patch supports the RISC-V Zvbdota family of batched dot-product extensions [1]. Compared to the non-batched Zvdota family, Zvbdota computes up to eight dot products at a time. These instructions use an EMUL=8 `vs2` vector register group and a scaled-by-8 `ci` immediate encoded in `vs2[2:0]`. This patch adds assembler/disassembler support for those additional operand constraints. The Zvbdota extension family includes the following extensions: * Zvqwbdota8i: batched dot product of 8-bit integers with 32-bit accumulation. * Zvqwbdota16i: batched dot product of 16-bit integers with 64-bit accumulation. * Zvfwbdota16bf: batched dot product of bfloat16 floating-point numbers with 32-bit accumulation. * Zvfqwbdota8f: batched dot product of 8-bit floating-point numbers with 32-bit accumulation. * Zvfbdota32f: batched dot product of 32-bit single-precision floating-point numbers with 32-bit accumulation. [1] https://github.com/riscv/riscv-isa-manual/blob/zvbdot/src/zvdota.adoc bfd/ChangeLog: * elfxx-riscv.c (riscv_implicit_subsets): New implies. (riscv_supported_std_z_ext): New extensions. (riscv_multi_subset_supports): Ditto. (riscv_multi_subset_supports_ext): Ditto. gas/ChangeLog: * NEWS: Add zvqwbdota8i, zvqwbdota16i, zvfwbdota16bf, zvfqwbdota8f and zvfbdota32f extensions. * config/tc-riscv.c (validate_riscv_insn): Add Zvbdota operand type 'q' and 'r' bits validation. (riscv_vtype_altfmt_supported): Add Zvbdota extensions. (my_getVsetvliExpression): Update altfmt error message. (riscv_ip): Add 'q' operand for VS2 EMUL=8 alignment check and 'r' operand for ci immediate. * testsuite/gas/riscv/march-help.l: Ditto. * testsuite/gas/riscv/zvbdota.d: New test. * testsuite/gas/riscv/zvbdota.s: Ditto. * testsuite/gas/riscv/zvbdota-operands-fail.d: Ditto. * testsuite/gas/riscv/zvbdota-operands-fail.l: Ditto. * testsuite/gas/riscv/zvbdota-operands-fail.s: Ditto. * testsuite/gas/riscv/zvbdota-zvqwbdota16i.d: Ditto. * testsuite/gas/riscv/zvbdota-zvqwbdota16i.s: Ditto. include/ChangeLog: * opcode/riscv-opc.h (MATCH_VQWBDOTAU_VV, MASK_VQWBDOTAU_VV): New encoding. (MATCH_VQWBDOTAS_VV, MASK_VQWBDOTAS_VV): Ditto. (MATCH_VFWBDOTA_VV, MASK_VFWBDOTA_VV): Ditto. (MATCH_VFQWBDOTA_VV, MASK_VFQWBDOTA_VV): Ditto. (MATCH_VFQWBDOTA_ALT_VV, MASK_VFQWBDOTA_ALT_VV): Ditto. (MATCH_VFBDOTA_VV, MASK_VFBDOTA_VV): Ditto. (DECLARE_INSN): New declarations. * opcode/riscv.h (enum riscv_insn_class): New extension classes. opcodes/ChangeLog: * riscv-dis.c (print_insn_args): Add 'q' and 'r' operand types for Zvbdota. * riscv-opc.c (riscv_opcodes): New instructions. Diff: --- bfd/elfxx-riscv.c | 35 +++++++++++++++++++++++ gas/NEWS | 4 ++- gas/config/tc-riscv.c | 37 ++++++++++++++++++++++++- gas/testsuite/gas/riscv/march-help.l | 5 ++++ gas/testsuite/gas/riscv/zvbdota-operands-fail.d | 3 ++ gas/testsuite/gas/riscv/zvbdota-operands-fail.l | 4 +++ gas/testsuite/gas/riscv/zvbdota-operands-fail.s | 4 +++ gas/testsuite/gas/riscv/zvbdota-zvqwbdota16i.d | 11 ++++++++ gas/testsuite/gas/riscv/zvbdota-zvqwbdota16i.s | 3 ++ gas/testsuite/gas/riscv/zvbdota.d | 23 +++++++++++++++ gas/testsuite/gas/riscv/zvbdota.s | 15 ++++++++++ include/opcode/riscv-opc.h | 20 +++++++++++++ include/opcode/riscv.h | 6 ++++ opcodes/riscv-dis.c | 11 ++++++++ opcodes/riscv-opc.c | 8 ++++++ 15 files changed, 187 insertions(+), 2 deletions(-) diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c index 44bdb5f2a99..e1639cbc2cb 100644 --- a/bfd/elfxx-riscv.c +++ b/bfd/elfxx-riscv.c @@ -1239,8 +1239,13 @@ static const struct riscv_implicit_subset riscv_implicit_subsets[] = {"zvfhmin", "+zve32f", check_implicit_always}, {"zvfbfwma", "+zve32f,+zfbfmin", check_implicit_always}, {"zvfbfmin", "+zve32f", check_implicit_always}, + {"zvfbdota32f", "+zve32f", check_implicit_always}, + {"zvfqwbdota8f", "+zve32f", check_implicit_always}, {"zvfqwdota8f", "+zve32f", check_implicit_always}, + {"zvfwbdota16bf", "+zve32f", check_implicit_always}, {"zvfwdota16bf", "+zve32f", check_implicit_always}, + {"zvqwbdota8i", "+zve32x", check_implicit_always}, + {"zvqwbdota16i", "+zve64x", check_implicit_always}, {"zvqwdota8i", "+zve32x", check_implicit_always}, {"zvqwdota16i", "+zve64x", check_implicit_always}, {"zve64d", "+d,+zve64f", check_implicit_always}, @@ -1524,11 +1529,14 @@ static const struct riscv_supported_ext riscv_supported_std_z_ext[] = {"zvabd", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zvbb", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zvbc", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zvfbdota32f", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zvfbfmin", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zvfbfwma", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zvfh", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zvfhmin", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zvfqwbdota8f", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zvfqwdota8f", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zvfwbdota16bf", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zvfwdota16bf", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zvkb", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zvkg", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, @@ -1544,6 +1552,8 @@ static const struct riscv_supported_ext riscv_supported_std_z_ext[] = {"zvksg", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zvksc", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zvkt", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zvqwbdota8i", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zvqwbdota16i", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zvqwdota8i", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zvqwdota16i", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zvl32b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, @@ -2993,8 +3003,14 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps, return riscv_subset_supports (rps, "zvfbfmin"); case INSN_CLASS_ZVFBFWMA: return riscv_subset_supports (rps, "zvfbfwma"); + case INSN_CLASS_ZVFBDOTA32F: + return riscv_subset_supports (rps, "zvfbdota32f"); + case INSN_CLASS_ZVFQWBDOTA8F: + return riscv_subset_supports (rps, "zvfqwbdota8f"); case INSN_CLASS_ZVFQWDOTA8F: return riscv_subset_supports (rps, "zvfqwdota8f"); + case INSN_CLASS_ZVFWBDOTA16BF: + return riscv_subset_supports (rps, "zvfwbdota16bf"); case INSN_CLASS_ZVFWDOTA16BF: return riscv_subset_supports (rps, "zvfwdota16bf"); case INSN_CLASS_ZVKB: @@ -3010,6 +3026,13 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps, return riscv_subset_supports (rps, "zvksed"); case INSN_CLASS_ZVKSH: return riscv_subset_supports (rps, "zvksh"); + case INSN_CLASS_ZVQWBDOTA8I: + return riscv_subset_supports (rps, "zvqwbdota8i"); + case INSN_CLASS_ZVQWBDOTA16I: + return riscv_subset_supports (rps, "zvqwbdota16i"); + case INSN_CLASS_ZVQWBDOTA8I_OR_ZVQWBDOTA16I: + return (riscv_subset_supports (rps, "zvqwbdota8i") + || riscv_subset_supports (rps, "zvqwbdota16i")); case INSN_CLASS_ZVQWDOTA8I: return riscv_subset_supports (rps, "zvqwdota8i"); case INSN_CLASS_ZVQWDOTA16I: @@ -3331,8 +3354,14 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps, return "zvfbfmin"; case INSN_CLASS_ZVFBFWMA: return "zvfbfwma"; + case INSN_CLASS_ZVFBDOTA32F: + return "zvfbdota32f"; + case INSN_CLASS_ZVFQWBDOTA8F: + return "zvfqwbdota8f"; case INSN_CLASS_ZVFQWDOTA8F: return "zvfqwdota8f"; + case INSN_CLASS_ZVFWBDOTA16BF: + return "zvfwbdota16bf"; case INSN_CLASS_ZVFWDOTA16BF: return "zvfwdota16bf"; case INSN_CLASS_ZVKB: @@ -3347,6 +3376,12 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps, return _("zvksed"); case INSN_CLASS_ZVKSH: return _("zvksh"); + case INSN_CLASS_ZVQWBDOTA8I: + return "zvqwbdota8i"; + case INSN_CLASS_ZVQWBDOTA16I: + return "zvqwbdota16i"; + case INSN_CLASS_ZVQWBDOTA8I_OR_ZVQWBDOTA16I: + return _("zvqwbdota8i' or `zvqwbdota16i"); case INSN_CLASS_ZVQWDOTA8I: return "zvqwdota8i"; case INSN_CLASS_ZVQWDOTA16I: diff --git a/gas/NEWS b/gas/NEWS index c3e254689e0..b36bcb5cf3d 100644 --- a/gas/NEWS +++ b/gas/NEWS @@ -7,7 +7,9 @@ * Add support for RISC-V standard extensions: zalasr v1.0, svrsw60t59b v1.0, zvabd v1.0, smpmpmt v1.0, - zvqwdota8i, zvqwdota16i, zvfwdota16bf and zvfqwdota8f v1.0. + zvqwdota8i, zvqwdota16i, zvfwdota16bf and zvfqwdota8f v1.0, + zvqwbdota8i, zvqwbdota16i, zvfwbdota16bf, zvfqwbdota8f and + zvfbdota32f v1.0. * Add support for RISC-V vendor extensions: SpacemiT: xsmtvdot v1.0, xsmtvdotii v1.0. diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c index 53cc234cde4..0f3283cbb96 100644 --- a/gas/config/tc-riscv.c +++ b/gas/config/tc-riscv.c @@ -1568,6 +1568,8 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length) case 'e': USE_BITS (OP_MASK_VWD, OP_SH_VWD); break; case 's': USE_BITS (OP_MASK_VS1, OP_SH_VS1); break; case 't': USE_BITS (OP_MASK_VS2, OP_SH_VS2); break; + case 'q': USE_BITS (0x3, OP_SH_VS2 + 3); break; + case 'r': USE_BITS (0x7, OP_SH_VS2); break; case 'u': USE_BITS (OP_MASK_VS1, OP_SH_VS1); USE_BITS (OP_MASK_VS2, OP_SH_VS2); break; case 'v': USE_BITS (OP_MASK_VD, OP_SH_VD); @@ -2697,8 +2699,12 @@ riscv_vtype_altfmt_supported (void) { return (riscv_subset_supports (&riscv_rps_as, "zvfbfa") || riscv_subset_supports (&riscv_rps_as, "zvfofp8min") + || riscv_subset_supports (&riscv_rps_as, "zvfqwbdota8f") || riscv_subset_supports (&riscv_rps_as, "zvfqwdota8f") + || riscv_subset_supports (&riscv_rps_as, "zvfwbdota16bf") || riscv_subset_supports (&riscv_rps_as, "zvfwdota16bf") + || riscv_subset_supports (&riscv_rps_as, "zvqwbdota8i") + || riscv_subset_supports (&riscv_rps_as, "zvqwbdota16i") || riscv_subset_supports (&riscv_rps_as, "zvqwdota8i") || riscv_subset_supports (&riscv_rps_as, "zvqwdota16i")); } @@ -2720,7 +2726,7 @@ my_getVsetvliExpression (expressionS *ep, char *str) as_bad (_("multiple vsew constants")); if (!riscv_vtype_altfmt_supported ()) as_bad (_("symbolic vtype altfmt requires `zvfbfa', " - "`zvfofp8min' or a `zvdota' extension")); + "`zvfofp8min' or an altfmt dot-product extension")); altfmt_value = 1 << OP_SH_VTYPE_ALTFMT; vsew_found = true; } @@ -3376,6 +3382,35 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr, INSERT_OPERAND (VS2, *ip, regno); continue; + case 'q': /* Zvbdota VS2 group base. */ + if (!reg_lookup (&asarg, RCLASS_VECR, ®no)) + break; + if (regno & 0x7) + as_bad (_("vector register must be aligned to an " + "EMUL=8 group")); + INSERT_BITS (ip->insn_opcode, regno & 0x18, 0x18, + OP_SH_VS2); + continue; + + case 'r': /* Zvbdota ci immediate in VS2. */ + { + offsetT ci; + + my_getExpression (imm_expr, asarg, force_reloc); + check_absolute_expr (ip, imm_expr, false); + ci = imm_expr->X_add_number; + if (ci < 0 || ci > 56 || (ci & 0x7)) + { + as_bad (_("bad value for Zvbdota ci immediate field, " + "value must be a multiple of 8 in 0..56")); + ci = 0; + } + INSERT_BITS (ip->insn_opcode, ci / 8, 0x7, OP_SH_VS2); + imm_expr->X_op = O_absent; + asarg = expr_parse_end; + continue; + } + case 'u': /* VS1 == VS2 */ if (!reg_lookup (&asarg, RCLASS_VECR, ®no)) break; diff --git a/gas/testsuite/gas/riscv/march-help.l b/gas/testsuite/gas/riscv/march-help.l index 2b5efe808d6..142369b6b1d 100644 --- a/gas/testsuite/gas/riscv/march-help.l +++ b/gas/testsuite/gas/riscv/march-help.l @@ -72,11 +72,14 @@ All available -march extensions for RISC-V: zvabd 1.0 zvbb 1.0 zvbc 1.0 + zvfbdota32f 1.0 zvfbfmin 1.0 zvfbfwma 1.0 zvfh 1.0 zvfhmin 1.0 + zvfqwbdota8f 1.0 zvfqwdota8f 1.0 + zvfwbdota16bf 1.0 zvfwdota16bf 1.0 zvkb 1.0 zvkg 1.0 @@ -92,6 +95,8 @@ All available -march extensions for RISC-V: zvksg 1.0 zvksc 1.0 zvkt 1.0 + zvqwbdota8i 1.0 + zvqwbdota16i 1.0 zvqwdota8i 1.0 zvqwdota16i 1.0 zvl32b 1.0 diff --git a/gas/testsuite/gas/riscv/zvbdota-operands-fail.d b/gas/testsuite/gas/riscv/zvbdota-operands-fail.d new file mode 100644 index 00000000000..32028f6bb8c --- /dev/null +++ b/gas/testsuite/gas/riscv/zvbdota-operands-fail.d @@ -0,0 +1,3 @@ +#as: -march=rv64gc_zvqwbdota8i +#source: zvbdota-operands-fail.s +#error_output: zvbdota-operands-fail.l diff --git a/gas/testsuite/gas/riscv/zvbdota-operands-fail.l b/gas/testsuite/gas/riscv/zvbdota-operands-fail.l new file mode 100644 index 00000000000..6ba8dfca2e8 --- /dev/null +++ b/gas/testsuite/gas/riscv/zvbdota-operands-fail.l @@ -0,0 +1,4 @@ +.*: Assembler messages: +.*: Error: vector register must be aligned to an EMUL=8 group +.*: Error: bad value for Zvbdota ci immediate field, value must be a multiple of 8 in 0..56 +.*: Error: bad value for Zvbdota ci immediate field, value must be a multiple of 8 in 0..56 diff --git a/gas/testsuite/gas/riscv/zvbdota-operands-fail.s b/gas/testsuite/gas/riscv/zvbdota-operands-fail.s new file mode 100644 index 00000000000..0709892db8d --- /dev/null +++ b/gas/testsuite/gas/riscv/zvbdota-operands-fail.s @@ -0,0 +1,4 @@ +target: + vqwbdotas.vv v16, v9, v31, 0 + vqwbdotas.vv v16, v8, v31, 4 + vqwbdotas.vv v16, v8, v31, 64 diff --git a/gas/testsuite/gas/riscv/zvbdota-zvqwbdota16i.d b/gas/testsuite/gas/riscv/zvbdota-zvqwbdota16i.d new file mode 100644 index 00000000000..349cd81f759 --- /dev/null +++ b/gas/testsuite/gas/riscv/zvbdota-zvqwbdota16i.d @@ -0,0 +1,11 @@ +#as: -march=rv64gc_zvqwbdota16i +#objdump: -dr + +.*:[ ]+file format .* + + +Disassembly of section .text: + +0+000 <target>: +[ ]+[0-9a-f]+:[ ]+ba8f8877[ ]+vqwbdotau.vv[ ]+v16,v8,v31,0 +[ ]+[0-9a-f]+:[ ]+be9f8877[ ]+vqwbdotas.vv[ ]+v16,v8,v31,8 diff --git a/gas/testsuite/gas/riscv/zvbdota-zvqwbdota16i.s b/gas/testsuite/gas/riscv/zvbdota-zvqwbdota16i.s new file mode 100644 index 00000000000..1a5bb4ef4bc --- /dev/null +++ b/gas/testsuite/gas/riscv/zvbdota-zvqwbdota16i.s @@ -0,0 +1,3 @@ +target: + vqwbdotau.vv v16, v8, v31, 0 + vqwbdotas.vv v16, v8, v31, 8 diff --git a/gas/testsuite/gas/riscv/zvbdota.d b/gas/testsuite/gas/riscv/zvbdota.d new file mode 100644 index 00000000000..63fa13853fa --- /dev/null +++ b/gas/testsuite/gas/riscv/zvbdota.d @@ -0,0 +1,23 @@ +#as: -march=rv64gc_zvqwbdota8i_zvqwbdota16i_zvfwbdota16bf_zvfqwbdota8f_zvfbdota32f +#objdump: -dr + +.*:[ ]+file format .* + + +Disassembly of section .text: + +0+000 <target>: +[ ]+[0-9a-f]+:[ ]+ba8f8877[ ]+vqwbdotau.vv[ ]+v16,v8,v31,0 +[ ]+[0-9a-f]+:[ ]+ba9f8877[ ]+vqwbdotau.vv[ ]+v16,v8,v31,8 +[ ]+[0-9a-f]+:[ ]+be8f8877[ ]+vqwbdotas.vv[ ]+v16,v8,v31,0 +[ ]+[0-9a-f]+:[ ]+be9f8877[ ]+vqwbdotas.vv[ ]+v16,v8,v31,8 +[ ]+[0-9a-f]+:[ ]+b28f9877[ ]+vfwbdota.vv[ ]+v16,v8,v31,0 +[ ]+[0-9a-f]+:[ ]+b29f9877[ ]+vfwbdota.vv[ ]+v16,v8,v31,8 +[ ]+[0-9a-f]+:[ ]+ba8f9877[ ]+vfqwbdota.vv[ ]+v16,v8,v31,0 +[ ]+[0-9a-f]+:[ ]+ba9f9877[ ]+vfqwbdota.vv[ ]+v16,v8,v31,8 +[ ]+[0-9a-f]+:[ ]+be8f9877[ ]+vfqwbdota.alt.vv[ ]+v16,v8,v31,0 +[ ]+[0-9a-f]+:[ ]+be9f9877[ ]+vfqwbdota.alt.vv[ ]+v16,v8,v31,8 +[ ]+[0-9a-f]+:[ ]+ae8f9877[ ]+vfbdota.vv[ ]+v16,v8,v31,0 +[ ]+[0-9a-f]+:[ ]+ae9f9877[ ]+vfbdota.vv[ ]+v16,v8,v31,8 +[ ]+[0-9a-f]+:[ ]+bc8f8877[ ]+vqwbdotas.vv[ ]+v16,v8,v31,0,v0.t +[ ]+[0-9a-f]+:[ ]+b89f9877[ ]+vfqwbdota.vv[ ]+v16,v8,v31,8,v0.t diff --git a/gas/testsuite/gas/riscv/zvbdota.s b/gas/testsuite/gas/riscv/zvbdota.s new file mode 100644 index 00000000000..c87975a4cc9 --- /dev/null +++ b/gas/testsuite/gas/riscv/zvbdota.s @@ -0,0 +1,15 @@ +target: + vqwbdotau.vv v16, v8, v31, 0 + vqwbdotau.vv v16, v8, v31, 8 + vqwbdotas.vv v16, v8, v31, 0 + vqwbdotas.vv v16, v8, v31, 8 + vfwbdota.vv v16, v8, v31, 0 + vfwbdota.vv v16, v8, v31, 8 + vfqwbdota.vv v16, v8, v31, 0 + vfqwbdota.vv v16, v8, v31, 8 + vfqwbdota.alt.vv v16, v8, v31, 0 + vfqwbdota.alt.vv v16, v8, v31, 8 + vfbdota.vv v16, v8, v31, 0 + vfbdota.vv v16, v8, v31, 8 + vqwbdotas.vv v16, v8, v31, 0, v0.t + vfqwbdota.vv v16, v8, v31, 8, v0.t diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h index 812f24c083c..6846655aeed 100644 --- a/include/opcode/riscv-opc.h +++ b/include/opcode/riscv-opc.h @@ -2588,6 +2588,19 @@ #define MASK_VFQWDOTA_VV 0xfc00707f #define MATCH_VFQWDOTA_ALT_VV 0x9c001077 #define MASK_VFQWDOTA_ALT_VV 0xfc00707f +/* Zvbdota instructions. */ +#define MATCH_VQWBDOTAU_VV 0xb8000077 +#define MASK_VQWBDOTAU_VV 0xfc00707f +#define MATCH_VQWBDOTAS_VV 0xbc000077 +#define MASK_VQWBDOTAS_VV 0xfc00707f +#define MATCH_VFWBDOTA_VV 0xb0001077 +#define MASK_VFWBDOTA_VV 0xfc00707f +#define MATCH_VFQWBDOTA_VV 0xb8001077 +#define MASK_VFQWBDOTA_VV 0xfc00707f +#define MATCH_VFQWBDOTA_ALT_VV 0xbc001077 +#define MASK_VFQWBDOTA_ALT_VV 0xfc00707f +#define MATCH_VFBDOTA_VV 0xac001077 +#define MASK_VFBDOTA_VV 0xfc00707f /* Vendor-specific (CORE-V) Xcvmac instructions. */ #define MATCH_CV_MAC 0x9000302b #define MASK_CV_MAC 0xfe00707f @@ -4919,6 +4932,13 @@ DECLARE_INSN(vqwdotas_vv, MATCH_VQWDOTAS_VV, MASK_VQWDOTAS_VV) DECLARE_INSN(vfwdota_vv, MATCH_VFWDOTA_VV, MASK_VFWDOTA_VV) DECLARE_INSN(vfqwdota_vv, MATCH_VFQWDOTA_VV, MASK_VFQWDOTA_VV) DECLARE_INSN(vfqwdota_alt_vv, MATCH_VFQWDOTA_ALT_VV, MASK_VFQWDOTA_ALT_VV) +/* Zvbdota instructions. */ +DECLARE_INSN(vqwbdotau_vv, MATCH_VQWBDOTAU_VV, MASK_VQWBDOTAU_VV) +DECLARE_INSN(vqwbdotas_vv, MATCH_VQWBDOTAS_VV, MASK_VQWBDOTAS_VV) +DECLARE_INSN(vfwbdota_vv, MATCH_VFWBDOTA_VV, MASK_VFWBDOTA_VV) +DECLARE_INSN(vfqwbdota_vv, MATCH_VFQWBDOTA_VV, MASK_VFQWBDOTA_VV) +DECLARE_INSN(vfqwbdota_alt_vv, MATCH_VFQWBDOTA_ALT_VV, MASK_VFQWBDOTA_ALT_VV) +DECLARE_INSN(vfbdota_vv, MATCH_VFBDOTA_VV, MASK_VFBDOTA_VV) /* Zvbb/Zvkb instructions. */ DECLARE_INSN(vandn_vv, MATCH_VANDN_VV, MASK_VANDN_VV) DECLARE_INSN(vandn_vx, MATCH_VANDN_VX, MASK_VANDN_VX) diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h index 45b6c7979db..f500b877ca6 100644 --- a/include/opcode/riscv.h +++ b/include/opcode/riscv.h @@ -562,7 +562,10 @@ enum riscv_insn_class INSN_CLASS_ZVBC, INSN_CLASS_ZVFBFMIN, INSN_CLASS_ZVFBFWMA, + INSN_CLASS_ZVFBDOTA32F, + INSN_CLASS_ZVFQWBDOTA8F, INSN_CLASS_ZVFQWDOTA8F, + INSN_CLASS_ZVFWBDOTA16BF, INSN_CLASS_ZVFWDOTA16BF, INSN_CLASS_ZVKB, INSN_CLASS_ZVKG, @@ -571,6 +574,9 @@ enum riscv_insn_class INSN_CLASS_ZVKSED, INSN_CLASS_ZVKSH, INSN_CLASS_ZVABD, + INSN_CLASS_ZVQWBDOTA8I, + INSN_CLASS_ZVQWBDOTA16I, + INSN_CLASS_ZVQWBDOTA8I_OR_ZVQWBDOTA16I, INSN_CLASS_ZVQWDOTA8I, INSN_CLASS_ZVQWDOTA16I, INSN_CLASS_ZVQWDOTA8I_OR_ZVQWDOTA16I, diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c index 86dbdb18456..724c8b90b12 100644 --- a/opcodes/riscv-dis.c +++ b/opcodes/riscv-dis.c @@ -440,6 +440,17 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info print (info->stream, dis_style_register, "%s", riscv_vecr_names_numeric[EXTRACT_OPERAND (VS2, l)]); break; + case 'q': + { + unsigned int vs2 = EXTRACT_OPERAND (VS2, l); + print (info->stream, dis_style_register, "%s", + riscv_vecr_names_numeric[vs2 & 0x18]); + } + break; + case 'r': + print (info->stream, dis_style_immediate, "%u", + (unsigned int) (EXTRACT_OPERAND (VS2, l) & 0x7) * 8); + break; case '0': print (info->stream, dis_style_register, "%s", riscv_vecr_names_numeric[0]); diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c index cfec774ecdb..cd1e2910307 100644 --- a/opcodes/riscv-opc.c +++ b/opcodes/riscv-opc.c @@ -2257,6 +2257,14 @@ const struct riscv_opcode riscv_opcodes[] = {"vfqwdota.vv", 0, INSN_CLASS_ZVFQWDOTA8F, "Vd,Vt,VsVm", MATCH_VFQWDOTA_VV, MASK_VFQWDOTA_VV, match_opcode, 0}, {"vfqwdota.alt.vv", 0, INSN_CLASS_ZVFQWDOTA8F, "Vd,Vt,VsVm", MATCH_VFQWDOTA_ALT_VV, MASK_VFQWDOTA_ALT_VV, match_opcode, 0}, +/* Zvbdota instructions. */ +{"vqwbdotau.vv", 0, INSN_CLASS_ZVQWBDOTA8I_OR_ZVQWBDOTA16I, "Vd,Vq,Vs,VrVm", MATCH_VQWBDOTAU_VV, MASK_VQWBDOTAU_VV, match_opcode, 0}, +{"vqwbdotas.vv", 0, INSN_CLASS_ZVQWBDOTA8I_OR_ZVQWBDOTA16I, "Vd,Vq,Vs,VrVm", MATCH_VQWBDOTAS_VV, MASK_VQWBDOTAS_VV, match_opcode, 0}, +{"vfwbdota.vv", 0, INSN_CLASS_ZVFWBDOTA16BF, "Vd,Vq,Vs,VrVm", MATCH_VFWBDOTA_VV, MASK_VFWBDOTA_VV, match_opcode, 0}, +{"vfqwbdota.vv", 0, INSN_CLASS_ZVFQWBDOTA8F, "Vd,Vq,Vs,VrVm", MATCH_VFQWBDOTA_VV, MASK_VFQWBDOTA_VV, match_opcode, 0}, +{"vfqwbdota.alt.vv", 0, INSN_CLASS_ZVFQWBDOTA8F, "Vd,Vq,Vs,VrVm", MATCH_VFQWBDOTA_ALT_VV, MASK_VFQWBDOTA_ALT_VV, match_opcode, 0}, +{"vfbdota.vv", 0, INSN_CLASS_ZVFBDOTA32F, "Vd,Vq,Vs,VrVm", MATCH_VFBDOTA_VV, MASK_VFBDOTA_VV, match_opcode, 0}, + /* Zvbb/Zvkb instructions. */ {"vandn.vv", 0, INSN_CLASS_ZVKB, "Vd,Vt,VsVm", MATCH_VANDN_VV, MASK_VANDN_VV, match_opcode, 0}, {"vandn.vx", 0, INSN_CLASS_ZVKB, "Vd,Vt,sVm", MATCH_VANDN_VX, MASK_VANDN_VX, match_opcode, 0},