[v6,02/15] RISC-V: Add support for the Zvbc extension
Checks
Commit Message
From: Nathan Huckleberry via Binutils <binutils@sourceware.org>
Zvbc is part of the crypto vector extensions.
This extension adds the following instructions:
- vclmul.[vv,vx]
- vclmulh.[vv,vx]
bfd/ChangeLog:
* elfxx-riscv.c (riscv_multi_subset_supports): Add instruction
class support for Zvbc.
(riscv_multi_subset_supports_ext): Likewise.
gas/ChangeLog:
* testsuite/gas/riscv/zvbc.d: New test.
* testsuite/gas/riscv/zvbc.s: New test.
include/ChangeLog:
* opcode/riscv-opc.h (MATCH_VCLMUL_VV): New.
(MASK_VCLMUL_VV): New.
(MATCH_VCLMUL_VX): New.
(MASK_VCLMUL_VX): New.
(MATCH_VCLMULH_VV): New.
(MASK_VCLMULH_VV): New.
(MATCH_VCLMULH_VX): New.
(MASK_VCLMULH_VX): New.
(DECLARE_INSN): New.
* opcode/riscv.h (enum riscv_insn_class): Add instruction class
support for Zvbc.
opcodes/ChangeLog:
* riscv-opc.c: Add Zvbc instruction.
Signed-off-by: Nathan Huckleberry <nhuck@google.com>
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
---
bfd/elfxx-riscv.c | 5 +++++
gas/testsuite/gas/riscv/zvbc.d | 16 ++++++++++++++++
gas/testsuite/gas/riscv/zvbc.s | 8 ++++++++
include/opcode/riscv-opc.h | 14 ++++++++++++++
include/opcode/riscv.h | 1 +
opcodes/riscv-opc.c | 6 ++++++
6 files changed, 50 insertions(+)
create mode 100644 gas/testsuite/gas/riscv/zvbc.d
create mode 100644 gas/testsuite/gas/riscv/zvbc.s
Comments
On 01.07.2023 07:20, Christoph Muellner wrote:
> --- a/opcodes/riscv-opc.c
> +++ b/opcodes/riscv-opc.c
> @@ -1902,6 +1902,12 @@ const struct riscv_opcode riscv_opcodes[] =
> {"vwsll.vx", 0, INSN_CLASS_ZVBB, "Vd,Vt,sVm", MATCH_VWSLL_VX, MASK_VWSLL_VX, match_opcode, 0},
> {"vwsll.vi", 0, INSN_CLASS_ZVBB, "Vd,Vt,VjVm", MATCH_VWSLL_VI, MASK_VWSLL_VI, match_opcode, 0},
>
> +/* Zvbc instructions. */
> +{"vclmul.vv", 0, INSN_CLASS_ZVBC, "Vd,Vt,VsVm", MATCH_VCLMUL_VV, MASK_VCLMUL_VV, match_opcode, 0},
> +{"vclmul.vx", 0, INSN_CLASS_ZVBC, "Vd,Vt,sVm", MATCH_VCLMUL_VX, MASK_VCLMUL_VX, match_opcode, 0},
I realize this is more a spec question than an implementation one, but
implementation might be affected by the answer to the question: What
exactly are this and ...
> +{"vclmulh.vv", 0, INSN_CLASS_ZVBC, "Vd,Vt,VsVm", MATCH_VCLMULH_VV, MASK_VCLMULH_VV, match_opcode, 0},
> +{"vclmulh.vx", 0, INSN_CLASS_ZVBC, "Vd,Vt,sVm", MATCH_VCLMULH_VX, MASK_VCLMULH_VX, match_opcode, 0},
... this insn doing in RV32 mode? There are no 64 bits to take from
the GPR, yet that's what the doc presently says. Is the value coming
from a pair of GPRs, or is it sign- or zero-extended? Or is this an
RV64-only insn? (Note how the doc explicitly describes the behavior
for vandn's scalar-source form; the only thing left to be implied
there is that truncation / sign-extension are to - I assume - element
size, but maybe that's said somewhere in more general terms.)
As a nit: The two vclmulh lines have one too many blanks, resulting
in columns to not be aligned.
Jan
On Mon, 17 Jul 2023 at 09:02, Jan Beulich <jbeulich@suse.com> wrote:
>
> On 01.07.2023 07:20, Christoph Muellner wrote:
> > --- a/opcodes/riscv-opc.c
> > +++ b/opcodes/riscv-opc.c
> > @@ -1902,6 +1902,12 @@ const struct riscv_opcode riscv_opcodes[] =
> > {"vwsll.vx", 0, INSN_CLASS_ZVBB, "Vd,Vt,sVm", MATCH_VWSLL_VX, MASK_VWSLL_VX, match_opcode, 0},
> > {"vwsll.vi", 0, INSN_CLASS_ZVBB, "Vd,Vt,VjVm", MATCH_VWSLL_VI, MASK_VWSLL_VI, match_opcode, 0},
> >
> > +/* Zvbc instructions. */
> > +{"vclmul.vv", 0, INSN_CLASS_ZVBC, "Vd,Vt,VsVm", MATCH_VCLMUL_VV, MASK_VCLMUL_VV, match_opcode, 0},
> > +{"vclmul.vx", 0, INSN_CLASS_ZVBC, "Vd,Vt,sVm", MATCH_VCLMUL_VX, MASK_VCLMUL_VX, match_opcode, 0},
>
> I realize this is more a spec question than an implementation one, but
> implementation might be affected by the answer to the question: What
> exactly are this and ...
>
> > +{"vclmulh.vv", 0, INSN_CLASS_ZVBC, "Vd,Vt,VsVm", MATCH_VCLMULH_VV, MASK_VCLMULH_VV, match_opcode, 0},
> > +{"vclmulh.vx", 0, INSN_CLASS_ZVBC, "Vd,Vt,sVm", MATCH_VCLMULH_VX, MASK_VCLMULH_VX, match_opcode, 0},
>
> ... this insn doing in RV32 mode? There are no 64 bits to take from
> the GPR, yet that's what the doc presently says. Is the value coming
> from a pair of GPRs, or is it sign- or zero-extended? Or is this an
> RV64-only insn? (Note how the doc explicitly describes the behavior
> for vandn's scalar-source form; the only thing left to be implied
> there is that truncation / sign-extension are to - I assume - element
> size, but maybe that's said somewhere in more general terms.
According to the pull-request for the SAIL model (which will in the
future be auto-generated into the specification documents and often
clarifies on parts of the specification where the English text is
ambiguous or imprecise), these are defined for RV64 only:
>
> +mapping clause encdec = RISCV_VCLMULH_VV(vm, vs1, vs2, vd) if (haveRVV() & haveZvbc() & sizeof(xlen) == 64)
> + <-> 0b001101 @ vm @ vs2 @ vs1 @ 0b010 @ vd @ 0b1010111 if (haveRVV() & haveZvbc() & sizeof(xlen) == 64)
Consequently, these should only be allowed for RV64.
Thanks for catching this!
Philipp.
>
> As a nit: The two vclmulh lines have one too many blanks, resulting
> in columns to not be aligned.
>
> Jan
+Ken Dockser
+Nicolas Brunie
I've added Ken and Nicolas (spec authors) to give an authoritative answer, and
because this looks like a valid public-review comment for the specification.
The spec indeed mentions "the 64-bit value from integer register rs1
(vector-scalar)",
which is unclear for RV32.
BR
Christoph
On Mon, Jul 17, 2023 at 9:02 AM Jan Beulich <jbeulich@suse.com> wrote:
>
> On 01.07.2023 07:20, Christoph Muellner wrote:
> > --- a/opcodes/riscv-opc.c
> > +++ b/opcodes/riscv-opc.c
> > @@ -1902,6 +1902,12 @@ const struct riscv_opcode riscv_opcodes[] =
> > {"vwsll.vx", 0, INSN_CLASS_ZVBB, "Vd,Vt,sVm", MATCH_VWSLL_VX, MASK_VWSLL_VX, match_opcode, 0},
> > {"vwsll.vi", 0, INSN_CLASS_ZVBB, "Vd,Vt,VjVm", MATCH_VWSLL_VI, MASK_VWSLL_VI, match_opcode, 0},
> >
> > +/* Zvbc instructions. */
> > +{"vclmul.vv", 0, INSN_CLASS_ZVBC, "Vd,Vt,VsVm", MATCH_VCLMUL_VV, MASK_VCLMUL_VV, match_opcode, 0},
> > +{"vclmul.vx", 0, INSN_CLASS_ZVBC, "Vd,Vt,sVm", MATCH_VCLMUL_VX, MASK_VCLMUL_VX, match_opcode, 0},
>
> I realize this is more a spec question than an implementation one, but
> implementation might be affected by the answer to the question: What
> exactly are this and ...
>
> > +{"vclmulh.vv", 0, INSN_CLASS_ZVBC, "Vd,Vt,VsVm", MATCH_VCLMULH_VV, MASK_VCLMULH_VV, match_opcode, 0},
> > +{"vclmulh.vx", 0, INSN_CLASS_ZVBC, "Vd,Vt,sVm", MATCH_VCLMULH_VX, MASK_VCLMULH_VX, match_opcode, 0},
>
> ... this insn doing in RV32 mode? There are no 64 bits to take from
> the GPR, yet that's what the doc presently says. Is the value coming
> from a pair of GPRs, or is it sign- or zero-extended? Or is this an
> RV64-only insn? (Note how the doc explicitly describes the behavior
> for vandn's scalar-source form; the only thing left to be implied
> there is that truncation / sign-extension are to - I assume - element
> size, but maybe that's said somewhere in more general terms.)
>
> As a nit: The two vclmulh lines have one too many blanks, resulting
> in columns to not be aligned.
>
> Jan
On 17.07.2023 09:11, Philipp Tomsich wrote:
> On Mon, 17 Jul 2023 at 09:02, Jan Beulich <jbeulich@suse.com> wrote:
>>
>> On 01.07.2023 07:20, Christoph Muellner wrote:
>>> --- a/opcodes/riscv-opc.c
>>> +++ b/opcodes/riscv-opc.c
>>> @@ -1902,6 +1902,12 @@ const struct riscv_opcode riscv_opcodes[] =
>>> {"vwsll.vx", 0, INSN_CLASS_ZVBB, "Vd,Vt,sVm", MATCH_VWSLL_VX, MASK_VWSLL_VX, match_opcode, 0},
>>> {"vwsll.vi", 0, INSN_CLASS_ZVBB, "Vd,Vt,VjVm", MATCH_VWSLL_VI, MASK_VWSLL_VI, match_opcode, 0},
>>>
>>> +/* Zvbc instructions. */
>>> +{"vclmul.vv", 0, INSN_CLASS_ZVBC, "Vd,Vt,VsVm", MATCH_VCLMUL_VV, MASK_VCLMUL_VV, match_opcode, 0},
>>> +{"vclmul.vx", 0, INSN_CLASS_ZVBC, "Vd,Vt,sVm", MATCH_VCLMUL_VX, MASK_VCLMUL_VX, match_opcode, 0},
>>
>> I realize this is more a spec question than an implementation one, but
>> implementation might be affected by the answer to the question: What
>> exactly are this and ...
>>
>>> +{"vclmulh.vv", 0, INSN_CLASS_ZVBC, "Vd,Vt,VsVm", MATCH_VCLMULH_VV, MASK_VCLMULH_VV, match_opcode, 0},
>>> +{"vclmulh.vx", 0, INSN_CLASS_ZVBC, "Vd,Vt,sVm", MATCH_VCLMULH_VX, MASK_VCLMULH_VX, match_opcode, 0},
>>
>> ... this insn doing in RV32 mode? There are no 64 bits to take from
>> the GPR, yet that's what the doc presently says. Is the value coming
>> from a pair of GPRs, or is it sign- or zero-extended? Or is this an
>> RV64-only insn? (Note how the doc explicitly describes the behavior
>> for vandn's scalar-source form; the only thing left to be implied
>> there is that truncation / sign-extension are to - I assume - element
>> size, but maybe that's said somewhere in more general terms.
>
>
> According to the pull-request for the SAIL model (which will in the
> future be auto-generated into the specification documents and often
> clarifies on parts of the specification where the English text is
> ambiguous or imprecise), these are defined for RV64 only:
>>
>> +mapping clause encdec = RISCV_VCLMULH_VV(vm, vs1, vs2, vd) if (haveRVV() & haveZvbc() & sizeof(xlen) == 64)
>> + <-> 0b001101 @ vm @ vs2 @ vs1 @ 0b010 @ vd @ 0b1010111 if (haveRVV() & haveZvbc() & sizeof(xlen) == 64)
>
> Consequently, these should only be allowed for RV64.
Oh, even the .vv insn is RV64 only (I had asked about the .vx one)? Plus
then why not sizeof(xlen) >= 64?
Jan
Same on the .vv:
>
> +mapping clause encdec = RISCV_VCLMULH_VV(vm, vs1, vs2, vd) if (haveRVV() & have Zvbc() & sizeof(xlen) == 64)
+ <-> 0b001101 @ vm @ vs2 @ vs1 @ 0b010 @ vd @ 0b1010111 if
(haveRVV() & have Zvbc() & sizeof(xlen) == 64)
On Mon, 17 Jul 2023 at 09:26, Jan Beulich <jbeulich@suse.com> wrote:
>
> On 17.07.2023 09:11, Philipp Tomsich wrote:
> > On Mon, 17 Jul 2023 at 09:02, Jan Beulich <jbeulich@suse.com> wrote:
> >>
> >> On 01.07.2023 07:20, Christoph Muellner wrote:
> >>> --- a/opcodes/riscv-opc.c
> >>> +++ b/opcodes/riscv-opc.c
> >>> @@ -1902,6 +1902,12 @@ const struct riscv_opcode riscv_opcodes[] =
> >>> {"vwsll.vx", 0, INSN_CLASS_ZVBB, "Vd,Vt,sVm", MATCH_VWSLL_VX, MASK_VWSLL_VX, match_opcode, 0},
> >>> {"vwsll.vi", 0, INSN_CLASS_ZVBB, "Vd,Vt,VjVm", MATCH_VWSLL_VI, MASK_VWSLL_VI, match_opcode, 0},
> >>>
> >>> +/* Zvbc instructions. */
> >>> +{"vclmul.vv", 0, INSN_CLASS_ZVBC, "Vd,Vt,VsVm", MATCH_VCLMUL_VV, MASK_VCLMUL_VV, match_opcode, 0},
> >>> +{"vclmul.vx", 0, INSN_CLASS_ZVBC, "Vd,Vt,sVm", MATCH_VCLMUL_VX, MASK_VCLMUL_VX, match_opcode, 0},
> >>
> >> I realize this is more a spec question than an implementation one, but
> >> implementation might be affected by the answer to the question: What
> >> exactly are this and ...
> >>
> >>> +{"vclmulh.vv", 0, INSN_CLASS_ZVBC, "Vd,Vt,VsVm", MATCH_VCLMULH_VV, MASK_VCLMULH_VV, match_opcode, 0},
> >>> +{"vclmulh.vx", 0, INSN_CLASS_ZVBC, "Vd,Vt,sVm", MATCH_VCLMULH_VX, MASK_VCLMULH_VX, match_opcode, 0},
> >>
> >> ... this insn doing in RV32 mode? There are no 64 bits to take from
> >> the GPR, yet that's what the doc presently says. Is the value coming
> >> from a pair of GPRs, or is it sign- or zero-extended? Or is this an
> >> RV64-only insn? (Note how the doc explicitly describes the behavior
> >> for vandn's scalar-source form; the only thing left to be implied
> >> there is that truncation / sign-extension are to - I assume - element
> >> size, but maybe that's said somewhere in more general terms.
> >
> >
> > According to the pull-request for the SAIL model (which will in the
> > future be auto-generated into the specification documents and often
> > clarifies on parts of the specification where the English text is
> > ambiguous or imprecise), these are defined for RV64 only:
> >>
> >> +mapping clause encdec = RISCV_VCLMULH_VV(vm, vs1, vs2, vd) if (haveRVV() & haveZvbc() & sizeof(xlen) == 64)
> >> + <-> 0b001101 @ vm @ vs2 @ vs1 @ 0b010 @ vd @ 0b1010111 if (haveRVV() & haveZvbc() & sizeof(xlen) == 64)
> >
> > Consequently, these should only be allowed for RV64.
>
> Oh, even the .vv insn is RV64 only (I had asked about the .vx one)? Plus
> then why not sizeof(xlen) >= 64?
>
> Jan
Hi,
This instruction is supported in RV32. The answer is in the pseudo code:
let op1 : bits (64) = if suffix =="vv" then get_velem(vs1,i)
else zext_or_truncate_to_sew(X(vs1));
The xv form of the instruction reads X(vs2) and zero-extends it to SEW=64.
When you need something other than 0s in the upper 32 bits of the vs1
operand, the vx form will not be very useful in RV32. However, the vv form
will continue to operate.
It looks like the SAIL code needs to be updated to match the spec.
Thanks,
Ken
On Mon, Jul 17, 2023 at 2:20 AM Christoph Müllner <
christoph.muellner@vrull.eu> wrote:
> +Ken Dockser
> +Nicolas Brunie
>
> I've added Ken and Nicolas (spec authors) to give an authoritative answer,
> and
> because this looks like a valid public-review comment for the
> specification.
>
> The spec indeed mentions "the 64-bit value from integer register rs1
> (vector-scalar)",
> which is unclear for RV32.
>
> BR
> Christoph
>
> On Mon, Jul 17, 2023 at 9:02 AM Jan Beulich <jbeulich@suse.com> wrote:
> >
> > On 01.07.2023 07:20, Christoph Muellner wrote:
> > > --- a/opcodes/riscv-opc.c
> > > +++ b/opcodes/riscv-opc.c
> > > @@ -1902,6 +1902,12 @@ const struct riscv_opcode riscv_opcodes[] =
> > > {"vwsll.vx", 0, INSN_CLASS_ZVBB, "Vd,Vt,sVm", MATCH_VWSLL_VX,
> MASK_VWSLL_VX, match_opcode, 0},
> > > {"vwsll.vi", 0, INSN_CLASS_ZVBB, "Vd,Vt,VjVm", MATCH_VWSLL_VI,
> MASK_VWSLL_VI, match_opcode, 0},
> > >
> > > +/* Zvbc instructions. */
> > > +{"vclmul.vv", 0, INSN_CLASS_ZVBC, "Vd,Vt,VsVm", MATCH_VCLMUL_VV,
> MASK_VCLMUL_VV, match_opcode, 0},
> > > +{"vclmul.vx", 0, INSN_CLASS_ZVBC, "Vd,Vt,sVm", MATCH_VCLMUL_VX,
> MASK_VCLMUL_VX, match_opcode, 0},
> >
> > I realize this is more a spec question than an implementation one, but
> > implementation might be affected by the answer to the question: What
> > exactly are this and ...
> >
> > > +{"vclmulh.vv", 0, INSN_CLASS_ZVBC, "Vd,Vt,VsVm", MATCH_VCLMULH_VV,
> MASK_VCLMULH_VV, match_opcode, 0},
> > > +{"vclmulh.vx", 0, INSN_CLASS_ZVBC, "Vd,Vt,sVm", MATCH_VCLMULH_VX,
> MASK_VCLMULH_VX, match_opcode, 0},
> >
> > ... this insn doing in RV32 mode? There are no 64 bits to take from
> > the GPR, yet that's what the doc presently says. Is the value coming
> > from a pair of GPRs, or is it sign- or zero-extended? Or is this an
> > RV64-only insn? (Note how the doc explicitly describes the behavior
> > for vandn's scalar-source form; the only thing left to be implied
> > there is that truncation / sign-extension are to - I assume - element
> > size, but maybe that's said somewhere in more general terms.)
> >
> > As a nit: The two vclmulh lines have one too many blanks, resulting
> > in columns to not be aligned.
> >
> > Jan
>
@@ -1263,6 +1263,7 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] =
{"zve64f", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zve64d", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zvbb", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zvbc", 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 },
@@ -2430,6 +2431,8 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
|| riscv_subset_supports (rps, "zve32f"));
case INSN_CLASS_ZVBB:
return riscv_subset_supports (rps, "zvbb");
+ case INSN_CLASS_ZVBC:
+ return riscv_subset_supports (rps, "zvbc");
case INSN_CLASS_SVINVAL:
return riscv_subset_supports (rps, "svinval");
case INSN_CLASS_H:
@@ -2620,6 +2623,8 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
return _("v' or `zve64d' or `zve64f' or `zve32f");
case INSN_CLASS_ZVBB:
return _("zvbb");
+ case INSN_CLASS_ZVBC:
+ return _("zvbc");
case INSN_CLASS_SVINVAL:
return "svinval";
case INSN_CLASS_H:
new file mode 100644
@@ -0,0 +1,16 @@
+#as: -march=rv64gc_zvbc
+#objdump: -dr
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+0+000 <.text>:
+[ ]+[0-9a-f]+:[ ]+32862257[ ]+vclmul.vv[ ]+v4,v8,v12
+[ ]+[0-9a-f]+:[ ]+30862257[ ]+vclmul.vv[ ]+v4,v8,v12,v0.t
+[ ]+[0-9a-f]+:[ ]+3285e257[ ]+vclmul.vx[ ]+v4,v8,a1
+[ ]+[0-9a-f]+:[ ]+3085e257[ ]+vclmul.vx[ ]+v4,v8,a1,v0.t
+[ ]+[0-9a-f]+:[ ]+36862257[ ]+vclmulh.vv[ ]+v4,v8,v12
+[ ]+[0-9a-f]+:[ ]+34862257[ ]+vclmulh.vv[ ]+v4,v8,v12,v0.t
+[ ]+[0-9a-f]+:[ ]+3685e257[ ]+vclmulh.vx[ ]+v4,v8,a1
+[ ]+[0-9a-f]+:[ ]+3485e257[ ]+vclmulh.vx[ ]+v4,v8,a1,v0.t
new file mode 100644
@@ -0,0 +1,8 @@
+ vclmul.vv v4, v8, v12
+ vclmul.vv v4, v8, v12, v0.t
+ vclmul.vx v4, v8, a1
+ vclmul.vx v4, v8, a1, v0.t
+ vclmulh.vv v4, v8, v12
+ vclmulh.vv v4, v8, v12, v0.t
+ vclmulh.vx v4, v8, a1
+ vclmulh.vx v4, v8, a1, v0.t
@@ -2154,6 +2154,15 @@
#define MASK_VWSLL_VV 0xfc00707f
#define MATCH_VWSLL_VX 0xd4004057
#define MASK_VWSLL_VX 0xfc00707f
+/* Zvbc instructions. */
+#define MATCH_VCLMUL_VV 0x30002057
+#define MASK_VCLMUL_VV 0xfc00707f
+#define MATCH_VCLMUL_VX 0x30006057
+#define MASK_VCLMUL_VX 0xfc00707f
+#define MATCH_VCLMULH_VV 0x34002057
+#define MASK_VCLMULH_VV 0xfc00707f
+#define MATCH_VCLMULH_VX 0x34006057
+#define MASK_VCLMULH_VX 0xfc00707f
/* Svinval instruction. */
#define MATCH_SINVAL_VMA 0x16000073
#define MASK_SINVAL_VMA 0xfe007fff
@@ -3280,6 +3289,11 @@ DECLARE_INSN(vror_vx, MATCH_VROR_VX, MASK_VROR_VX)
DECLARE_INSN(vwsll_vi, MATCH_VWSLL_VI, MASK_VWSLL_VI)
DECLARE_INSN(vwsll_vv, MATCH_VWSLL_VV, MASK_VWSLL_VV)
DECLARE_INSN(vwsll_vx, MATCH_VWSLL_VX, MASK_VWSLL_VX)
+/* Zvbc instructions. */
+DECLARE_INSN(vclmul_vv, MATCH_VCLMUL_VV, MASK_VCLMUL_VV)
+DECLARE_INSN(vclmul_vx, MATCH_VCLMUL_VX, MASK_VCLMUL_VX)
+DECLARE_INSN(vclmulh_vv, MATCH_VCLMULH_VV, MASK_VCLMULH_VV)
+DECLARE_INSN(vclmulh_vx, MATCH_VCLMULH_VX, MASK_VCLMULH_VX)
/* Vendor-specific (T-Head) XTheadBa instructions. */
DECLARE_INSN(th_addsl, MATCH_TH_ADDSL, MASK_TH_ADDSL)
/* Vendor-specific (T-Head) XTheadBb instructions. */
@@ -415,6 +415,7 @@ enum riscv_insn_class
INSN_CLASS_V,
INSN_CLASS_ZVEF,
INSN_CLASS_ZVBB,
+ INSN_CLASS_ZVBC,
INSN_CLASS_SVINVAL,
INSN_CLASS_ZICBOM,
INSN_CLASS_ZICBOP,
@@ -1902,6 +1902,12 @@ const struct riscv_opcode riscv_opcodes[] =
{"vwsll.vx", 0, INSN_CLASS_ZVBB, "Vd,Vt,sVm", MATCH_VWSLL_VX, MASK_VWSLL_VX, match_opcode, 0},
{"vwsll.vi", 0, INSN_CLASS_ZVBB, "Vd,Vt,VjVm", MATCH_VWSLL_VI, MASK_VWSLL_VI, match_opcode, 0},
+/* Zvbc instructions. */
+{"vclmul.vv", 0, INSN_CLASS_ZVBC, "Vd,Vt,VsVm", MATCH_VCLMUL_VV, MASK_VCLMUL_VV, match_opcode, 0},
+{"vclmul.vx", 0, INSN_CLASS_ZVBC, "Vd,Vt,sVm", MATCH_VCLMUL_VX, MASK_VCLMUL_VX, match_opcode, 0},
+{"vclmulh.vv", 0, INSN_CLASS_ZVBC, "Vd,Vt,VsVm", MATCH_VCLMULH_VV, MASK_VCLMULH_VV, match_opcode, 0},
+{"vclmulh.vx", 0, INSN_CLASS_ZVBC, "Vd,Vt,sVm", MATCH_VCLMULH_VX, MASK_VCLMULH_VX, match_opcode, 0},
+
/* Supervisor instructions. */
{"csrr", 0, INSN_CLASS_ZICSR, "d,E", MATCH_CSRRS, MASK_CSRRS|MASK_RS1, match_opcode, INSN_ALIAS },
{"csrw", 0, INSN_CLASS_ZICSR, "E,s", MATCH_CSRRW, MASK_CSRRW|MASK_RD, match_opcode, INSN_ALIAS },