[RFC 2/2] RISC-V: Add Zvbdota extension support
Jiawei
jiawei@iscas.ac.cn
Tue Jun 9 15:38:44 GMT 2026
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.
---
bfd/elfxx-riscv.c | 35 ++++++++++++++++++
gas/NEWS | 5 ++-
gas/config/tc-riscv.c | 37 ++++++++++++++++++-
gas/testsuite/gas/riscv/march-help.l | 5 +++
.../gas/riscv/zvbdota-operands-fail.d | 3 ++
.../gas/riscv/zvbdota-operands-fail.l | 4 ++
.../gas/riscv/zvbdota-operands-fail.s | 4 ++
.../gas/riscv/zvbdota-zvqwbdota16i.d | 11 ++++++
.../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(+), 3 deletions(-)
create mode 100644 gas/testsuite/gas/riscv/zvbdota-operands-fail.d
create mode 100644 gas/testsuite/gas/riscv/zvbdota-operands-fail.l
create mode 100644 gas/testsuite/gas/riscv/zvbdota-operands-fail.s
create mode 100644 gas/testsuite/gas/riscv/zvbdota-zvqwbdota16i.d
create mode 100644 gas/testsuite/gas/riscv/zvbdota-zvqwbdota16i.s
create mode 100644 gas/testsuite/gas/riscv/zvbdota.d
create mode 100644 gas/testsuite/gas/riscv/zvbdota.s
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 7714e5dcd49..afe7073ddb7 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1234,8 +1234,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},
@@ -1517,11 +1522,14 @@ static const struct riscv_supported_ext riscv_supported_std_z_ext[] =
{"zve64d", 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 },
@@ -1537,6 +1545,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 },
@@ -2978,8 +2988,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:
@@ -2995,6 +3011,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:
@@ -3305,8 +3328,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:
@@ -3321,6 +3350,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 ddb7983aea0..253f25a4691 100644
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,7 +1,8 @@
-*- text -*-
-* Add support for RISC-V standard extensions:
- zvqwdota8i, zvqwdota16i, zvfwdota16bf and zvfqwdota8f v1.0.
+* Add support for RISC-V extensions:
+ zvqwdota8i, zvqwdota16i, zvfwdota16bf, zvfqwdota8f, zvqwbdota8i,
+ zvqwbdota16i, zvfwbdota16bf, zvfqwbdota8f and zvfbdota32f v1.0.
Changes in 2.46:
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 42397933662..03d9efa770e 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);
@@ -2655,8 +2657,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"));
}
@@ -2682,7 +2688,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;
}
@@ -3338,6 +3344,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 51e830c021b..0550d0d605a 100644
--- a/gas/testsuite/gas/riscv/march-help.l
+++ b/gas/testsuite/gas/riscv/march-help.l
@@ -70,11 +70,14 @@ All available -march extensions for RISC-V:
zve64d 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
@@ -90,6 +93,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 359b4f64ab8..b59c85584c9 100644
--- a/include/opcode/riscv-opc.h
+++ b/include/opcode/riscv-opc.h
@@ -2560,6 +2560,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
@@ -4812,6 +4825,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 59bc09e4780..82f8fd40881 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -548,7 +548,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,
@@ -556,6 +559,9 @@ enum riscv_insn_class
INSN_CLASS_ZVKNHA_OR_ZVKNHB,
INSN_CLASS_ZVKSED,
INSN_CLASS_ZVKSH,
+ 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 6ccccd864f2..c3da5f2960e 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 3c4e4b19af5..472abb8b744 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -2233,6 +2233,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},
--
2.43.0
More information about the Binutils
mailing list