[1/2] RISC-V: Add Zvdota extension classes

Message ID 20260630033438.143289-1-jiawei@iscas.ac.cn
State New
Headers
Series [1/2] RISC-V: Add Zvdota extension classes |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 fail Patch failed to apply
linaro-tcwg-bot/tcwg_binutils_build--master-arm fail Patch failed to apply

Commit Message

Jiawei June 30, 2026, 3:34 a.m. UTC
  This patch adds assembler/disassembler support for the RISC-V Zvdota family of extensions [1], which compute a dot product between two vector register groups.

The Zvdota extension family includes the following extensions:

Zvqwdota8i: dot product of 8-bit integers with 32-bit accumulation.
Zvqwdota16i: dot product of 16-bit integers with 64-bit accumulation.
Zvfwdota16bf: dot product of bfloat16 floating-point numbers with 32-bit accumulation.
Zvfqwdota8f: dot product of 8-bit floating-point numbers with 32-bit accumulation.

Zvdota also uses the vtype alternative format bit, altfmt, which is bit 8 of the vtype CSR. This patch adds symbolic e8alt and e16alt vsew constants for vsetvli/vsetivli so that assembly code can select the alternative element formats required by these dot-product instructions.

[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 zvqwdota8i, zvqwdota16i, zvfwdota16bf and
	zvfqwdota8f extensions.
	* config/tc-riscv.c (riscv_vsew_altfmt): New vsew altfmt
	constants array for e8alt and e16alt.
	(riscv_vtype_altfmt_supported): New function.
	(my_getVsetvliExpression): Ditto.
	* testsuite/gas/riscv/march-help.l: New test.
	* testsuite/gas/riscv/vector-vtype-altfmt.d: Ditto.
	* testsuite/gas/riscv/vector-vtype-altfmt.s: Ditto.
	* testsuite/gas/riscv/zvdota.d: Ditto.
	* testsuite/gas/riscv/zvdota.s: Ditto.

include/ChangeLog:

	* opcode/riscv-opc.h (MATCH_VQWDOTAU_VV, MASK_VQWDOTAU_VV): New encoding.
	(MATCH_VQWDOTAS_VV, MASK_VQWDOTAS_VV): Ditto.
	(MATCH_VFWDOTA_VV, MASK_VFWDOTA_VV): Ditto.
	(MATCH_VFQWDOTA_VV, MASK_VFQWDOTA_VV): Ditto.
	(MATCH_VFQWDOTA_ALT_VV, MASK_VFQWDOTA_ALT_VV): Ditto.
	(DECLARE_INSN): New declarations.
	* opcode/riscv.h (OP_MASK_VTYPE_ALTFMT, OP_SH_VTYPE_ALTFMT): New vtype altfmt.
	(enum riscv_insn_class): New extension classes.

opcodes/ChangeLog:

	* riscv-dis.c (print_insn_args): Add altfmt support.
	* riscv-opc.c (riscv_opcodes): New instructions.
---
 bfd/elfxx-riscv.c                             | 29 +++++++++++++++++
 gas/NEWS                                      |  3 +-
 gas/config/tc-riscv.c                         | 32 +++++++++++++++++--
 gas/testsuite/gas/riscv/march-help.l          |  4 +++
 gas/testsuite/gas/riscv/vector-vtype-altfmt.d | 15 +++++++++
 gas/testsuite/gas/riscv/vector-vtype-altfmt.s |  7 ++++
 gas/testsuite/gas/riscv/zvdota.d              | 19 +++++++++++
 gas/testsuite/gas/riscv/zvdota.s              | 11 +++++++
 include/opcode/riscv-opc.h                    | 17 ++++++++++
 include/opcode/riscv.h                        |  8 +++++
 opcodes/riscv-dis.c                           | 10 ++++--
 opcodes/riscv-opc.c                           | 13 ++++++++
 12 files changed, 162 insertions(+), 6 deletions(-)
 create mode 100644 gas/testsuite/gas/riscv/vector-vtype-altfmt.d
 create mode 100644 gas/testsuite/gas/riscv/vector-vtype-altfmt.s
 create mode 100644 gas/testsuite/gas/riscv/zvdota.d
 create mode 100644 gas/testsuite/gas/riscv/zvdota.s
  

Comments

Jeffrey Law June 30, 2026, 1:56 p.m. UTC | #1
On 6/29/2026 9:34 PM, Jiawei wrote:
> This patch adds assembler/disassembler support for the RISC-V Zvdota family of extensions [1], which compute a dot product between two vector register groups.
>
> The Zvdota extension family includes the following extensions:
>
> Zvqwdota8i: dot product of 8-bit integers with 32-bit accumulation.
> Zvqwdota16i: dot product of 16-bit integers with 64-bit accumulation.
> Zvfwdota16bf: dot product of bfloat16 floating-point numbers with 32-bit accumulation.
> Zvfqwdota8f: dot product of 8-bit floating-point numbers with 32-bit accumulation.
>
> Zvdota also uses the vtype alternative format bit, altfmt, which is bit 8 of the vtype CSR. This patch adds symbolic e8alt and e16alt vsew constants for vsetvli/vsetivli so that assembly code can select the alternative element formats required by these dot-product instructions.
>
> [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 zvqwdota8i, zvqwdota16i, zvfwdota16bf and
> 	zvfqwdota8f extensions.
> 	* config/tc-riscv.c (riscv_vsew_altfmt): New vsew altfmt
> 	constants array for e8alt and e16alt.
> 	(riscv_vtype_altfmt_supported): New function.
> 	(my_getVsetvliExpression): Ditto.
> 	* testsuite/gas/riscv/march-help.l: New test.
> 	* testsuite/gas/riscv/vector-vtype-altfmt.d: Ditto.
> 	* testsuite/gas/riscv/vector-vtype-altfmt.s: Ditto.
> 	* testsuite/gas/riscv/zvdota.d: Ditto.
> 	* testsuite/gas/riscv/zvdota.s: Ditto.
>
> include/ChangeLog:
>
> 	* opcode/riscv-opc.h (MATCH_VQWDOTAU_VV, MASK_VQWDOTAU_VV): New encoding.
> 	(MATCH_VQWDOTAS_VV, MASK_VQWDOTAS_VV): Ditto.
> 	(MATCH_VFWDOTA_VV, MASK_VFWDOTA_VV): Ditto.
> 	(MATCH_VFQWDOTA_VV, MASK_VFQWDOTA_VV): Ditto.
> 	(MATCH_VFQWDOTA_ALT_VV, MASK_VFQWDOTA_ALT_VV): Ditto.
> 	(DECLARE_INSN): New declarations.
> 	* opcode/riscv.h (OP_MASK_VTYPE_ALTFMT, OP_SH_VTYPE_ALTFMT): New vtype altfmt.
> 	(enum riscv_insn_class): New extension classes.
>
> opcodes/ChangeLog:
>
> 	* riscv-dis.c (print_insn_args): Add altfmt support.
> 	* riscv-opc.c (riscv_opcodes): New instructions.
THanks!  I've pushed both patches in this series to the trunk.

jeff
  

Patch

diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 961c44a9206..44bdb5f2a99 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1239,6 +1239,10 @@  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},
+  {"zvfqwdota8f", "+zve32f", check_implicit_always},
+  {"zvfwdota16bf", "+zve32f", check_implicit_always},
+  {"zvqwdota8i", "+zve32x", check_implicit_always},
+  {"zvqwdota16i", "+zve64x", check_implicit_always},
   {"zve64d", "+d,+zve64f", check_implicit_always},
   {"zve64f", "+zve32f,+zve64x,+zvl64b", check_implicit_always},
   {"zve32f", "+f,+zve32x,+zvl32b", check_implicit_always},
@@ -1524,6 +1528,8 @@  static const struct riscv_supported_ext riscv_supported_std_z_ext[] =
   {"zvfbfwma",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
   {"zvfh",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
   {"zvfhmin",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
+  {"zvfqwdota8f",	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 },
   {"zvkn",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
@@ -1538,6 +1544,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 },
+  {"zvqwdota8i",	ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
+  {"zvqwdota16i",	ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
   {"zvl32b",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
   {"zvl64b",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
   {"zvl128b",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
@@ -2985,6 +2993,10 @@  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_ZVFQWDOTA8F:
+      return riscv_subset_supports (rps, "zvfqwdota8f");
+    case INSN_CLASS_ZVFWDOTA16BF:
+      return riscv_subset_supports (rps, "zvfwdota16bf");
     case INSN_CLASS_ZVKB:
       return riscv_subset_supports (rps, "zvkb");
     case INSN_CLASS_ZVKG:
@@ -2998,6 +3010,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_ZVQWDOTA8I:
+      return riscv_subset_supports (rps, "zvqwdota8i");
+    case INSN_CLASS_ZVQWDOTA16I:
+      return riscv_subset_supports (rps, "zvqwdota16i");
+    case INSN_CLASS_ZVQWDOTA8I_OR_ZVQWDOTA16I:
+      return (riscv_subset_supports (rps, "zvqwdota8i")
+	      || riscv_subset_supports (rps, "zvqwdota16i"));
     case INSN_CLASS_ZCB:
       return riscv_subset_supports (rps, "zcb");
     case INSN_CLASS_ZCB_AND_ZBB:
@@ -3312,6 +3331,10 @@  riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
       return "zvfbfmin";
     case INSN_CLASS_ZVFBFWMA:
       return "zvfbfwma";
+    case INSN_CLASS_ZVFQWDOTA8F:
+      return "zvfqwdota8f";
+    case INSN_CLASS_ZVFWDOTA16BF:
+      return "zvfwdota16bf";
     case INSN_CLASS_ZVKB:
       return _("zvkb");
     case INSN_CLASS_ZVKG:
@@ -3324,6 +3347,12 @@  riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
       return _("zvksed");
     case INSN_CLASS_ZVKSH:
       return _("zvksh");
+    case INSN_CLASS_ZVQWDOTA8I:
+      return "zvqwdota8i";
+    case INSN_CLASS_ZVQWDOTA16I:
+      return "zvqwdota16i";
+    case INSN_CLASS_ZVQWDOTA8I_OR_ZVQWDOTA16I:
+      return _("zvqwdota8i' or `zvqwdota16i");
     case INSN_CLASS_ZCB:
       return "zcb";
     case INSN_CLASS_ZCB_AND_ZBA:
diff --git a/gas/NEWS b/gas/NEWS
index 4c55a544f25..c3e254689e0 100644
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -6,7 +6,8 @@ 
   and will be removed in a future release.
 
 * Add support for RISC-V standard extensions:
-  zalasr v1.0, svrsw60t59b v1.0, zvabd v1.0, smpmpmt v1.0.
+  zalasr v1.0, svrsw60t59b v1.0, zvabd v1.0, smpmpmt v1.0,
+  zvqwdota8i, zvqwdota16i, zvfwdota16bf and zvfqwdota8f 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 28875e77ff0..53cc234cde4 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -2692,15 +2692,40 @@  my_getOpcodeExpression (expressionS *ep, bfd_reloc_code_real_type *reloc,
    On exit, EXPR_PARSE_END points to the first character after the
    expression.  */
 
+static bool
+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, "zvfqwdota8f")
+	  || riscv_subset_supports (&riscv_rps_as, "zvfwdota16bf")
+	  || riscv_subset_supports (&riscv_rps_as, "zvqwdota8i")
+	  || riscv_subset_supports (&riscv_rps_as, "zvqwdota16i"));
+}
+
 static void
 my_getVsetvliExpression (expressionS *ep, char *str)
 {
   unsigned int vsew_value = 0, vlmul_value = 0;
-  unsigned int vta_value = 0, vma_value = 0;
+  unsigned int vta_value = 0, vma_value = 0, altfmt_value = 0;
   bool vsew_found = false, vlmul_found = false;
   bool vta_found = false, vma_found = false;
 
-  if (arg_lookup (&str, riscv_vsew, ARRAY_SIZE (riscv_vsew), &vsew_value))
+  if (arg_lookup (&str, riscv_vsew_altfmt,
+		  ARRAY_SIZE (riscv_vsew_altfmt), &vsew_value))
+    {
+      if (*str == ',')
+	++str;
+      if (vsew_found)
+	as_bad (_("multiple vsew constants"));
+      if (!riscv_vtype_altfmt_supported ())
+	as_bad (_("symbolic vtype altfmt requires `zvfbfa', "
+		  "`zvfofp8min' or a `zvdota' extension"));
+      altfmt_value = 1 << OP_SH_VTYPE_ALTFMT;
+      vsew_found = true;
+    }
+  if (!vsew_found
+      && arg_lookup (&str, riscv_vsew, ARRAY_SIZE (riscv_vsew), &vsew_value))
     {
       if (*str == ',')
 	++str;
@@ -2739,7 +2764,8 @@  my_getVsetvliExpression (expressionS *ep, char *str)
       ep->X_add_number = (vlmul_value << OP_SH_VLMUL)
 			 | (vsew_value << OP_SH_VSEW)
 			 | (vta_value << OP_SH_VTA)
-			 | (vma_value << OP_SH_VMA);
+			 | (vma_value << OP_SH_VMA)
+			 | altfmt_value;
       expr_parse_end = str;
     }
   else
diff --git a/gas/testsuite/gas/riscv/march-help.l b/gas/testsuite/gas/riscv/march-help.l
index db6a86bc287..2b5efe808d6 100644
--- a/gas/testsuite/gas/riscv/march-help.l
+++ b/gas/testsuite/gas/riscv/march-help.l
@@ -76,6 +76,8 @@  All available -march extensions for RISC-V:
 	zvfbfwma                                1.0
 	zvfh                                    1.0
 	zvfhmin                                 1.0
+	zvfqwdota8f                             1.0
+	zvfwdota16bf                            1.0
 	zvkb                                    1.0
 	zvkg                                    1.0
 	zvkn                                    1.0
@@ -90,6 +92,8 @@  All available -march extensions for RISC-V:
 	zvksg                                   1.0
 	zvksc                                   1.0
 	zvkt                                    1.0
+	zvqwdota8i                              1.0
+	zvqwdota16i                             1.0
 	zvl32b                                  1.0
 	zvl64b                                  1.0
 	zvl128b                                 1.0
diff --git a/gas/testsuite/gas/riscv/vector-vtype-altfmt.d b/gas/testsuite/gas/riscv/vector-vtype-altfmt.d
new file mode 100644
index 00000000000..398f7682a91
--- /dev/null
+++ b/gas/testsuite/gas/riscv/vector-vtype-altfmt.d
@@ -0,0 +1,15 @@ 
+#as: -march=rv64gc_zvfqwdota8f
+#objdump: -dr
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+10707057[ 	]+vsetvli[ 	]+zero,zero,e8alt,mf2,tu,mu
+[ 	]+[0-9a-f]+:[ 	]+10707057[ 	]+vsetvli[ 	]+zero,zero,e8alt,mf2,tu,mu
+[ 	]+[0-9a-f]+:[ 	]+10707057[ 	]+vsetvli[ 	]+zero,zero,e8alt,mf2,tu,mu
+[ 	]+[0-9a-f]+:[ 	]+10f07057[ 	]+vsetvli[ 	]+zero,zero,e16alt,mf2,tu,mu
+[ 	]+[0-9a-f]+:[ 	]+10f07057[ 	]+vsetvli[ 	]+zero,zero,e16alt,mf2,tu,mu
+[ 	]+[0-9a-f]+:[ 	]+10f07057[ 	]+vsetvli[ 	]+zero,zero,e16alt,mf2,tu,mu
diff --git a/gas/testsuite/gas/riscv/vector-vtype-altfmt.s b/gas/testsuite/gas/riscv/vector-vtype-altfmt.s
new file mode 100644
index 00000000000..de8418236f1
--- /dev/null
+++ b/gas/testsuite/gas/riscv/vector-vtype-altfmt.s
@@ -0,0 +1,7 @@ 
+target:
+	vsetvli zero, zero, e8alt, mf2, tu, mu
+	vsetvli zero, zero, e8alt, mf2, tu, mu
+	vsetvli zero, zero, e8alt, mf2, tu, mu
+	vsetvli zero, zero, e16alt, mf2, tu, mu
+	vsetvli zero, zero, e16alt, mf2, tu, mu
+	vsetvli zero, zero, e16alt, mf2, tu, mu
diff --git a/gas/testsuite/gas/riscv/zvdota.d b/gas/testsuite/gas/riscv/zvdota.d
new file mode 100644
index 00000000000..8d133255993
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zvdota.d
@@ -0,0 +1,19 @@ 
+#as: -march=rv64gc_zvqwdota8i_zvqwdota16i_zvfwdota16bf_zvfqwdota8f
+#objdump: -dr
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+9a8f8877[ 	]+vqwdotau.vv[ 	]+v16,v8,v31
+[ 	]+[0-9a-f]+:[ 	]+9e8f8877[ 	]+vqwdotas.vv[ 	]+v16,v8,v31
+[ 	]+[0-9a-f]+:[ 	]+928f9877[ 	]+vfwdota.vv[ 	]+v16,v8,v31
+[ 	]+[0-9a-f]+:[ 	]+9a8f9877[ 	]+vfqwdota.vv[ 	]+v16,v8,v31
+[ 	]+[0-9a-f]+:[ 	]+9e8f9877[ 	]+vfqwdota.alt.vv[ 	]+v16,v8,v31
+[ 	]+[0-9a-f]+:[ 	]+988f8877[ 	]+vqwdotau.vv[ 	]+v16,v8,v31
+[ 	]+[0-9a-f]+:[ 	]+9c8f8877[ 	]+vqwdotas.vv[ 	]+v16,v8,v31
+[ 	]+[0-9a-f]+:[ 	]+928f9877[ 	]+vfwdota.vv[ 	]+v16,v8,v31
+[ 	]+[0-9a-f]+:[ 	]+980f9877[ 	]+vfqwdota.vv[ 	]+v16,v0,v31,v0.t
+[ 	]+[0-9a-f]+:[ 	]+9c0f9877[ 	]+vfqwdota.alt.vv[ 	]+v16,v0,v31,v0.t
diff --git a/gas/testsuite/gas/riscv/zvdota.s b/gas/testsuite/gas/riscv/zvdota.s
new file mode 100644
index 00000000000..a40453faf82
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zvdota.s
@@ -0,0 +1,11 @@ 
+target:
+	vqwdotau.vv v16, v8, v31
+	vqwdotas.vv v16, v8, v31
+	vfwdota.vv v16, v8, v31
+	vfqwdota.vv v16, v8, v31
+	vfqwdota.alt.vv v16, v8, v31
+	vqwdotau.vv v16, v8, v31, v0.t
+	vqwdotas.vv v16, v8, v31, v0.t
+	vfwdota.vv v16, v8, v31, v0.t
+	vfqwdota.vv v16, v0, v31, v0.t
+	vfqwdota.alt.vv v16, v0, v31, v0.t
diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
index eebf8f2a435..812f24c083c 100644
--- a/include/opcode/riscv-opc.h
+++ b/include/opcode/riscv-opc.h
@@ -2577,6 +2577,17 @@ 
 #define MASK_VFWMACCBF16_VF 0xfc00707f
 #define MATCH_VFWMACCBF16_VV 0xec001057
 #define MASK_VFWMACCBF16_VV 0xfc00707f
+/* Zvdota instructions.  */
+#define MATCH_VQWDOTAU_VV 0x98000077
+#define MASK_VQWDOTAU_VV 0xfc00707f
+#define MATCH_VQWDOTAS_VV 0x9c000077
+#define MASK_VQWDOTAS_VV 0xfc00707f
+#define MATCH_VFWDOTA_VV 0x90001077
+#define MASK_VFWDOTA_VV 0xfc00707f
+#define MATCH_VFQWDOTA_VV 0x98001077
+#define MASK_VFQWDOTA_VV 0xfc00707f
+#define MATCH_VFQWDOTA_ALT_VV 0x9c001077
+#define MASK_VFQWDOTA_ALT_VV 0xfc00707f
 /* Vendor-specific (CORE-V) Xcvmac instructions.  */
 #define MATCH_CV_MAC       0x9000302b
 #define MASK_CV_MAC        0xfe00707f
@@ -4902,6 +4913,12 @@  DECLARE_INSN(VFWCVTBF16_F_F_V, MATCH_VFWCVTBF16_F_F_V, MASK_VFWCVTBF16_F_F_V)
 /* Zvfbfwma instructions.  */
 DECLARE_INSN(VFWMACCBF16_VF, MATCH_VFWMACCBF16_VF, MASK_VFWMACCBF16_VF)
 DECLARE_INSN(VFWMACCBF16_VV, MATCH_VFWMACCBF16_VV, MASK_VFWMACCBF16_VV)
+/* Zvdota instructions.  */
+DECLARE_INSN(vqwdotau_vv, MATCH_VQWDOTAU_VV, MASK_VQWDOTAU_VV)
+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)
 /* 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 b4587976ea2..45b6c7979db 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -374,6 +374,8 @@  static inline unsigned int riscv_insn_length (insn_t insn)
 #define OP_SH_VTA		6
 #define OP_MASK_VMA		0x1
 #define OP_SH_VMA		7
+#define OP_MASK_VTYPE_ALTFMT	0x1
+#define OP_SH_VTYPE_ALTFMT	8
 #define OP_MASK_VWD		0x1
 #define OP_SH_VWD		26
 
@@ -560,6 +562,8 @@  enum riscv_insn_class
   INSN_CLASS_ZVBC,
   INSN_CLASS_ZVFBFMIN,
   INSN_CLASS_ZVFBFWMA,
+  INSN_CLASS_ZVFQWDOTA8F,
+  INSN_CLASS_ZVFWDOTA16BF,
   INSN_CLASS_ZVKB,
   INSN_CLASS_ZVKG,
   INSN_CLASS_ZVKNED,
@@ -567,6 +571,9 @@  enum riscv_insn_class
   INSN_CLASS_ZVKSED,
   INSN_CLASS_ZVKSH,
   INSN_CLASS_ZVABD,
+  INSN_CLASS_ZVQWDOTA8I,
+  INSN_CLASS_ZVQWDOTA16I,
+  INSN_CLASS_ZVQWDOTA8I_OR_ZVQWDOTA16I,
   INSN_CLASS_ZICFISS,
   INSN_CLASS_ZICFISS_AND_ZCMOP,
   INSN_CLASS_ZICFILP,
@@ -737,6 +744,7 @@  extern const char * const riscv_pred_succ[16];
 extern const char riscv_vecr_names_numeric[NVECR][NRC];
 extern const char riscv_vecm_names_numeric[NVECM][NRC];
 extern const char * const riscv_vsew[8];
+extern const char * const riscv_vsew_altfmt[2];
 extern const char * const riscv_vlmul[8];
 extern const char * const riscv_vta[2];
 extern const char * const riscv_vma[2];
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index edb9ce04778..86dbdb18456 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -453,17 +453,23 @@  print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 		unsigned int imm_vsew = EXTRACT_OPERAND (VSEW, imm);
 		unsigned int imm_vta = EXTRACT_OPERAND (VTA, imm);
 		unsigned int imm_vma = EXTRACT_OPERAND (VMA, imm);
-		unsigned int imm_vtype_res = (imm >> 8);
+		unsigned int imm_vtype_altfmt
+		  = EXTRACT_OPERAND (VTYPE_ALTFMT, imm);
+		unsigned int imm_vtype_res = (imm >> 9);
 
 		if (imm_vsew < ARRAY_SIZE (riscv_vsew)
 		    && imm_vlmul < ARRAY_SIZE (riscv_vlmul)
 		    && imm_vta < ARRAY_SIZE (riscv_vta)
 		    && imm_vma < ARRAY_SIZE (riscv_vma)
 		    && !imm_vtype_res
+		    && (imm_vtype_altfmt == 0
+			|| imm_vsew < ARRAY_SIZE (riscv_vsew_altfmt))
 		    && riscv_vsew[imm_vsew] != NULL
 		    && riscv_vlmul[imm_vlmul] != NULL)
 		  print (info->stream, dis_style_text, "%s,%s,%s,%s",
-			 riscv_vsew[imm_vsew],
+			 imm_vtype_altfmt
+			 ? riscv_vsew_altfmt[imm_vsew]
+			 : riscv_vsew[imm_vsew],
 			 riscv_vlmul[imm_vlmul], riscv_vta[imm_vta],
 			 riscv_vma[imm_vma]);
 		else
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 589495ac6c7..cfec774ecdb 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -93,6 +93,12 @@  const char * const riscv_vsew[8] =
   "e8", "e16", "e32", "e64", NULL, NULL, NULL, NULL
 };
 
+/* The vsetvli/vsetivli vsew altfmt constants.  */
+const char * const riscv_vsew_altfmt[2] =
+{
+  "e8alt", "e16alt"
+};
+
 /* The vsetvli vlmul constants.  */
 const char * const riscv_vlmul[8] =
 {
@@ -2244,6 +2250,13 @@  const struct riscv_opcode riscv_opcodes[] =
 {"vfwmaccbf16.vf",  0, INSN_CLASS_ZVFBFWMA, "Vd,S,VtVm",  MATCH_VFWMACCBF16_VF, MASK_VFWMACCBF16_VF, match_opcode, 0},
 {"vfwmaccbf16.vv",  0, INSN_CLASS_ZVFBFWMA, "Vd,Vs,VtVm", MATCH_VFWMACCBF16_VV, MASK_VFWMACCBF16_VV, match_opcode, 0},
 
+/* Zvdota instructions.  */
+{"vqwdotau.vv", 0, INSN_CLASS_ZVQWDOTA8I_OR_ZVQWDOTA16I, "Vd,Vt,VsVm", MATCH_VQWDOTAU_VV, MASK_VQWDOTAU_VV, match_opcode, 0},
+{"vqwdotas.vv", 0, INSN_CLASS_ZVQWDOTA8I_OR_ZVQWDOTA16I, "Vd,Vt,VsVm", MATCH_VQWDOTAS_VV, MASK_VQWDOTAS_VV, match_opcode, 0},
+{"vfwdota.vv",  0, INSN_CLASS_ZVFWDOTA16BF, "Vd,Vt,VsVm", MATCH_VFWDOTA_VV, MASK_VFWDOTA_VV, match_opcode, 0},
+{"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},
+
 /* 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},