public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* Re: [PING^3][v2] RISC-V: Add SpacemiT vendor extensions xsmtvdot
@ 2026-04-04  2:10 Mark Zhuang
  2026-04-09 10:28 ` Michal Lach
  0 siblings, 1 reply; 16+ messages in thread
From: Mark Zhuang @ 2026-04-04  2:10 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 40137 bytes --]

Just checking in on the previously reviewed patch. Is there any chance it could be merged, or is there anything else needed from my side?
Thanks.





                    Mark Zhuang<zhuangqiubin@linux.spacemit.com&gt;&nbsp;On Tuesday,  Mar 17, 2026, 16:19 wrote:

Ping~





                    Mark Zhuang<zhuangqiubin@linux.spacemit.com&gt;&nbsp;在 2026年2月26日 周四 12:54 写道:

Gentle ping :)





                    Mark Zhuang<zhuangqiubin@linux.spacemit.com&gt;&nbsp;在 2026年2月13日 周五 15:33 写道:

Hi all,


I'd like to ask if there are any further review comments. If not, could someone help merge this patch? 
Thanks.





                    Mark Zhuang<zhuangqiubin@linux.spacemit.com&gt;&nbsp;在 2026年1月30日 周五 16:43 写道:

Hi Jiawei


Thanks.


&gt; I wonder if we need also need to set vlen here, otherwise LGTM.


SpacemiT currently implements K1-x60 (vlen 256), K3-x100 (vlen 256), and K3-a100 (vlen 1024), but we believe that xsmtvdot itself does not require setting a vlen limit here.





                    Jiawei<jiawei@iscas.ac.cn&gt;&nbsp;在 2026年1月28日 周三 19:16 写道:

&gt; From: Mark Zhuang <mark.zhuang@spacemit.com&gt;
&gt;
&gt; SpacemiT defines Intrinsic Matrix Extension (IME) specification [1].
&gt; SpacemiT X60 implement version 1.0 of the SpacemiT Vector Dot Product 
&gt; Extension (XsmtVdot v1.0) [2],
&gt; it is a subset of the full IME specification
&gt;
&gt; [1] 
&gt; https://github.com/spacemit-com/riscv-ime-extension-spec/releases/download/v1.0/spacemit-ime-asciidoc.pdf
&gt; [2] 
&gt; https://developer.spacemit.com/documentation?token=BWbGwbx7liGW21kq9lucSA6Vnpb#2.1
&gt;
&gt; Co-authored-by: Link <xuqian@spacemit.com&gt;
&gt; ---
&gt; &nbsp;bfd/elfxx-riscv.c&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|&nbsp; 7 +++
&gt; &nbsp;gas/NEWS&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |&nbsp; 3 +
&gt; &nbsp;gas/config/tc-riscv.c&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| 71 +++++++++++++++++++++
&gt; &nbsp;gas/doc/c-riscv.texi&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |&nbsp; 7 +++
&gt; &nbsp;gas/testsuite/gas/riscv/march-help.l&nbsp; &nbsp; &nbsp; |&nbsp; 1 +
&gt; &nbsp;gas/testsuite/gas/riscv/x-smt-vdot-fail.l |&nbsp; 3 +
&gt; &nbsp;gas/testsuite/gas/riscv/x-smt-vdot-fail.s | 46 ++++++++++++++
&gt; &nbsp;gas/testsuite/gas/riscv/x-smt-vdot.d&nbsp; &nbsp; &nbsp; | 41 +++++++++++++
&gt; &nbsp;gas/testsuite/gas/riscv/x-smt-vdot.s&nbsp; &nbsp; &nbsp; | 33 ++++++++++
&gt; &nbsp;include/opcode/riscv-opc.h&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | 75 +++++++++++++++++++++++
&gt; &nbsp;include/opcode/riscv.h&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | 10 +++
&gt; &nbsp;opcodes/riscv-dis.c&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| 33 ++++++++++
&gt; &nbsp;opcodes/riscv-opc.c&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| 45 ++++++++++++++
&gt; &nbsp;13 files changed, 375 insertions(+)
&gt; &nbsp;create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-fail.l
&gt; &nbsp;create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-fail.s
&gt; &nbsp;create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot.d
&gt; &nbsp;create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot.s
&gt;
&gt; diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
&gt; index ee962b4f6f1..ea24a68b895 100644
&gt; --- a/bfd/elfxx-riscv.c
&gt; +++ b/bfd/elfxx-riscv.c
&gt; @@ -1229,6 +1229,8 @@ static const struct riscv_implicit_subset 
&gt; riscv_implicit_subsets[] =
&gt; &nbsp; &nbsp;{"xtheadvector", "+zicsr", check_implicit_always},
&gt; &nbsp; &nbsp;{"xtheadzvamo", "+zaamo", check_implicit_always},
&gt;
&gt; +&nbsp; {"xsmtvdot", "+zve32x", check_implicit_always},

I wonder if we need also need to set vlen here, otherwise LGTM.


Thanks,

Jiawei


&gt; +
&gt; &nbsp; &nbsp;{"v", "+zve64d,+zvl128b", check_implicit_always},
&gt; &nbsp; &nbsp;{"zvfh", "+zvfhmin,+zfhmin", check_implicit_always},
&gt; &nbsp; &nbsp;{"zvfhmin", "+zve32f", check_implicit_always},
&gt; @@ -1644,6 +1646,7 @@ static const struct riscv_supported_ext 
&gt; riscv_supported_vendor_x_ext[] =
&gt; &nbsp; &nbsp;{"xmipscmov",&nbsp; &nbsp; &nbsp; &nbsp; ISA_SPEC_CLASS_DRAFT,&nbsp; &nbsp; 1, 0, 0 },
&gt; &nbsp; &nbsp;{"xmipsexectl",&nbsp; &nbsp; ISA_SPEC_CLASS_DRAFT,&nbsp; &nbsp; 1, 0, 0 },
&gt; &nbsp; &nbsp;{"xmipslsp",&nbsp; &nbsp; &nbsp; &nbsp; ISA_SPEC_CLASS_DRAFT,&nbsp; &nbsp; 1, 0, 0 },
&gt; +&nbsp; {"xsmtvdot",&nbsp; &nbsp; &nbsp; &nbsp; ISA_SPEC_CLASS_DRAFT,&nbsp; &nbsp; 1, 0, 0 },
&gt; &nbsp; &nbsp;{NULL, 0, 0, 0, 0}
&gt; &nbsp;};
&gt;
&gt; @@ -3062,6 +3065,8 @@ riscv_multi_subset_supports 
&gt; (riscv_parse_subset_t *rps,
&gt; &nbsp; &nbsp; &nbsp; &nbsp;return riscv_subset_supports (rps, "xmipsexectl");
&gt; &nbsp; &nbsp; &nbsp;case INSN_CLASS_XMIPSLSP:
&gt; &nbsp; &nbsp; &nbsp; &nbsp;return riscv_subset_supports (rps, "xmipslsp");
&gt; +&nbsp; &nbsp; case INSN_CLASS_XSMTVDOT:
&gt; +&nbsp; &nbsp; &nbsp; return riscv_subset_supports (rps, "xsmtvdot");
&gt; &nbsp; &nbsp; &nbsp;default:
&gt; &nbsp; &nbsp; &nbsp; &nbsp;rps-&gt;error_handler
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(_("internal: unreachable INSN_CLASS_*"));
&gt; @@ -3365,6 +3370,8 @@ riscv_multi_subset_supports_ext 
&gt; (riscv_parse_subset_t *rps,
&gt; &nbsp; &nbsp; &nbsp; &nbsp;return "xsfvqmaccdod";
&gt; &nbsp; &nbsp; &nbsp;case INSN_CLASS_XSFVFNRCLIPXFQF:
&gt; &nbsp; &nbsp; &nbsp; &nbsp;return "xsfvfnrclipxfqf";
&gt; +&nbsp; &nbsp; case INSN_CLASS_XSMTVDOT:
&gt; +&nbsp; &nbsp; &nbsp; return "xsmtvdot";
&gt; &nbsp; &nbsp; &nbsp;default:
&gt; &nbsp; &nbsp; &nbsp; &nbsp;rps-&gt;error_handler
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(_("internal: unreachable INSN_CLASS_*"));
&gt; diff --git a/gas/NEWS b/gas/NEWS
&gt; index e384d1135c0..123872e7c02 100644
&gt; --- a/gas/NEWS
&gt; +++ b/gas/NEWS
&gt; @@ -17,6 +17,9 @@ Changes in 2.46:
&gt; &nbsp;* Add support for RISC-V standard extensions:
&gt; &nbsp; &nbsp;sdtrig v1.0, ssstrict v1.0.
&gt;
&gt; +* Add support for RISC-V vendor extensions:
&gt; +&nbsp; SpacemiT: xsmtvdot v1.0.
&gt; +
&gt; &nbsp;* The assembler now supports generating SFrame Version 3 format.&nbsp; 
&gt; This version
&gt; &nbsp; &nbsp;supports .text &gt; 2 GiB, support for marking outermost frames, 
&gt; support for
&gt; &nbsp; &nbsp;marking signal trampolines, and support for "flexible" frames which 
&gt; have
&gt; diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
&gt; index 6bcf53832a0..25cafd83a95 100644
&gt; --- a/gas/config/tc-riscv.c
&gt; +++ b/gas/config/tc-riscv.c
&gt; @@ -1771,6 +1771,29 @@ validate_riscv_insn (const struct riscv_opcode 
&gt; *opc, int length)
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;goto unknown_validate_operand;
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;break;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; case 'p': /* Vendor-specific (SpacemiT) operands.&nbsp; */
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; switch (*++oparg)
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; {
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case 'V':
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; switch (*++oparg)
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case 'd': USE_BITS (OP_MASK_SPACEMIT_IME_VD, 
&gt; OP_SH_SPACEMIT_IME_VD); break;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case 's': USE_BITS (OP_MASK_SPACEMIT_IME_VS1, 
&gt; OP_SH_SPACEMIT_IME_VS1); break;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default:
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; goto unknown_validate_operand;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case 'w': /* Xpw&amp;S ... bits in S indicates whether 
&gt; corresponding item is permitted.&nbsp; */
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (*++oparg != '&amp;')
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; goto unknown_validate_operand;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; strtol (oparg + 1, (char **)&amp;oparg, 16);
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; oparg--;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; USE_BITS (OP_MASK_SPACEMIT_IME_WI, OP_SH_SPACEMIT_IME_WI);
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default:
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; goto unknown_validate_operand;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; }
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; break;
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;default:
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;goto unknown_validate_operand;
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}
&gt; @@ -4287,6 +4310,54 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, 
&gt; expressionS *imm_expr,
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;break;
&gt;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; case 'p': /* Vendor-specific (SpacemiT) operands.&nbsp; */
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; size_t n;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; switch (*++oparg)
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case 'V':
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; switch (*++oparg)
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case 'd':
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!reg_lookup (&amp;asarg, RCLASS_VECR, ®no))
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ((regno &amp; 0x1) != 0)
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; error.msg = _("illegal operands (vd must be even)");
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; INSERT_OPERAND (SPACEMIT_IME_VD, *ip, regno&gt;&gt;1);
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; continue;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case 's':
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!reg_lookup (&amp;asarg, RCLASS_VECR, ®no))
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ((regno &amp; 0x1) != 0)
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; error.msg = _("illegal operands (vs1 must be even)");
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; INSERT_OPERAND (SPACEMIT_IME_VS1, *ip, regno&gt;&gt;1);
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; continue;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default:
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; goto unknown_riscv_ip_operand;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case 'w': /* Xpw&amp;S ... bits in S indicates whether 
&gt; corresponding item is permitted.&nbsp; */
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (*++oparg != '&amp;')
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; goto unknown_riscv_ip_operand;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; n = strtol (oparg + 1, (char **)&amp;oparg, 16);
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; oparg--;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!arg_lookup (&amp;asarg, riscv_smt_wi, ARRAY_SIZE 
&gt; (riscv_smt_wi), ®no))
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ((n &amp; (1 << regno)) == 0)
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; INSERT_OPERAND (SPACEMIT_IME_WI, *ip, regno);
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; continue;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default:
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; goto unknown_riscv_ip_operand;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;default:
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;goto unknown_riscv_ip_operand;
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}
&gt; diff --git a/gas/doc/c-riscv.texi b/gas/doc/c-riscv.texi
&gt; index c6c4081c204..88dd1de4aea 100644
&gt; --- a/gas/doc/c-riscv.texi
&gt; +++ b/gas/doc/c-riscv.texi
&gt; @@ -918,4 +918,11 @@ The XMipsSlsp extension provides instructions 
&gt; mips.ldp, mips.lwp, mips.sdp and m
&gt;
&gt; &nbsp;It is documented in 
&gt; @url{https://mips.com/wp-content/uploads/2025/03/P8700-F_Programmers_Reference_Manual_Rev1.82_3-19-2025.pdf}.
&gt;
&gt; +@item XSmtVdot
&gt; +The XSmtVdot extension provides instructions for vector dot.
&gt; +
&gt; +SpacemiT defines Intrinsic Matrix Extension (IME) specification, 
&gt; documented in 
&gt; @url{https://github.com/spacemit-com/riscv-ime-extension-spec/releases/download/v1.0/spacemit-ime-asciidoc.pdf}.
&gt; +SpacemiT X60 implement version 1.0 of the SpacemiT Vector Dot Product 
&gt; Extension (XsmtVdot v1.0),
&gt; +it is a subset of the full IME specification, documented in 
&gt; @url{https://developer.spacemit.com/documentation?token=BWbGwbx7liGW21kq9lucSA6Vnpb#2.1}.
&gt; +
&gt; &nbsp;@end table
&gt; diff --git a/gas/testsuite/gas/riscv/march-help.l 
&gt; b/gas/testsuite/gas/riscv/march-help.l
&gt; index 0ce2f896735..6e52669e9a4 100644
&gt; --- a/gas/testsuite/gas/riscv/march-help.l
&gt; +++ b/gas/testsuite/gas/riscv/march-help.l
&gt; @@ -186,3 +186,4 @@ All available -march extensions for RISC-V:
&gt; &nbsp; &nbsp; &nbsp;xmipscmov&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1.0
&gt; &nbsp; &nbsp; &nbsp;xmipsexectl&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1.0
&gt; &nbsp; &nbsp; &nbsp;xmipslsp&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1.0
&gt; +&nbsp; &nbsp; xsmtvdot&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1.0
&gt; diff --git a/gas/testsuite/gas/riscv/x-smt-vdot-fail.l 
&gt; b/gas/testsuite/gas/riscv/x-smt-vdot-fail.l
&gt; new file mode 100644
&gt; index 00000000000..6e846b401e1
&gt; --- /dev/null
&gt; +++ b/gas/testsuite/gas/riscv/x-smt-vdot-fail.l
&gt; @@ -0,0 +1,3 @@
&gt; +#as: -march=rv64gcv_xsmtvdot
&gt; +#source: x-smt-vdot-fail.s
&gt; +#error_output: x-smt-vdot-fail.l
&gt; diff --git a/gas/testsuite/gas/riscv/x-smt-vdot-fail.s 
&gt; b/gas/testsuite/gas/riscv/x-smt-vdot-fail.s
&gt; new file mode 100644
&gt; index 00000000000..77399a7fdde
&gt; --- /dev/null
&gt; +++ b/gas/testsuite/gas/riscv/x-smt-vdot-fail.s
&gt; @@ -0,0 +1,46 @@
&gt; +target:
&gt; +&nbsp; &nbsp; smt.vmadot v1, v3, v4
&gt; +&nbsp; &nbsp; smt.vmadotu v1, v3, v4
&gt; +&nbsp; &nbsp; smt.vmadotsu v1, v3, v4
&gt; +&nbsp; &nbsp; smt.vmadotus v1, v3, v4
&gt; +&nbsp; &nbsp; smt.vmadot1u v1, v4, v5
&gt; +&nbsp; &nbsp; smt.vmadot1 v1, v4, v5
&gt; +&nbsp; &nbsp; smt.vmadot1su v1, v4, v5
&gt; +&nbsp; &nbsp; smt.vmadot1us v1, v4, v5
&gt; +&nbsp; &nbsp; smt.vmadot2u v1, v4, v5
&gt; +&nbsp; &nbsp; smt.vmadot2 v1, v4, v5
&gt; +&nbsp; &nbsp; smt.vmadot2su v1, v4, v5
&gt; +&nbsp; &nbsp; smt.vmadot2us v1, v4, v5
&gt; +&nbsp; &nbsp; smt.vmadot3u v1, v4, v5
&gt; +&nbsp; &nbsp; smt.vmadot3 v1, v4, v5
&gt; +&nbsp; &nbsp; smt.vmadot3su v1, v4, v5
&gt; +&nbsp; &nbsp; smt.vmadot3us v1, v4, v5
&gt; +&nbsp; &nbsp; smt.vmadot1u v2, v3, v5
&gt; +&nbsp; &nbsp; smt.vmadot1 v2, v3, v5
&gt; +&nbsp; &nbsp; smt.vmadot1su v2, v3, v5
&gt; +&nbsp; &nbsp; smt.vmadot1us v2, v3, v5
&gt; +&nbsp; &nbsp; smt.vmadot2u v2, v3, v5
&gt; +&nbsp; &nbsp; smt.vmadot2 v2, v3, v5
&gt; +&nbsp; &nbsp; smt.vmadot2su v2, v3, v5
&gt; +&nbsp; &nbsp; smt.vmadot2us v2, v3, v5
&gt; +&nbsp; &nbsp; smt.vmadot3u v2, v3, v5
&gt; +&nbsp; &nbsp; smt.vmadot3 v2, v3, v5
&gt; +&nbsp; &nbsp; smt.vmadot3su v2, v3, v5
&gt; +&nbsp; &nbsp; smt.vmadot3us v2, v3, v5
&gt; +&nbsp; &nbsp; smt.vmadot v2, v3, v4, i4
&gt; +&nbsp; &nbsp; smt.vmadotu v2, v3, v4, i4
&gt; +&nbsp; &nbsp; smt.vmadotsu v2, v3, v4, i4
&gt; +&nbsp; &nbsp; smt.vmadotus v2, v3, v4, i4
&gt; +&nbsp; &nbsp; smt.vmadot1u v2, v4, v5, i4
&gt; +&nbsp; &nbsp; smt.vmadot1 v2, v4, v5, i4
&gt; +&nbsp; &nbsp; smt.vmadot1su v2, v4, v5, i4
&gt; +&nbsp; &nbsp; smt.vmadot1us v2, v4, v5, i4
&gt; +&nbsp; &nbsp; smt.vmadot2u v2, v4, v5, i4
&gt; +&nbsp; &nbsp; smt.vmadot2 v2, v4, v5, i4
&gt; +&nbsp; &nbsp; smt.vmadot2su v2, v4, v5, i4
&gt; +&nbsp; &nbsp; smt.vmadot2us v2, v4, v5, i4
&gt; +&nbsp; &nbsp; smt.vmadot3u v2, v4, v5, i4
&gt; +&nbsp; &nbsp; smt.vmadot3 v2, v4, v5, i4
&gt; +&nbsp; &nbsp; smt.vmadot3su v2, v4, v5, i4
&gt; +&nbsp; &nbsp; smt.vmadot3us v2, v4, v5, i4
&gt; +
&gt; diff --git a/gas/testsuite/gas/riscv/x-smt-vdot.d 
&gt; b/gas/testsuite/gas/riscv/x-smt-vdot.d
&gt; new file mode 100644
&gt; index 00000000000..6f86236785d
&gt; --- /dev/null
&gt; +++ b/gas/testsuite/gas/riscv/x-smt-vdot.d
&gt; @@ -0,0 +1,41 @@
&gt; +#as: -march=rv64gcv_xsmtvdot
&gt; +#objdump: -dr
&gt; +
&gt; +.*:[&nbsp; &nbsp; &nbsp;]+file format .*
&gt; +
&gt; +
&gt; +Disassembly of section .text:
&gt; +
&gt; +0+000 <target&gt;:
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e241b12b[&nbsp; &nbsp; &nbsp;]+smt.vmadot[ &nbsp;]+v2,v3,v4
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e241812b[&nbsp; &nbsp; &nbsp;]+smt.vmadotu[ &nbsp;]+v2,v3,v4
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e241a12b[&nbsp; &nbsp; &nbsp;]+smt.vmadotsu[ &nbsp;]+v2,v3,v4
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e241912b[&nbsp; &nbsp; &nbsp;]+smt.vmadotus[ &nbsp;]+v2,v3,v4
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e652012b[&nbsp; &nbsp; &nbsp;]+smt.vmadot1u[ &nbsp;]+v2,v4,v5
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e652312b[&nbsp; &nbsp; &nbsp;]+smt.vmadot1[ &nbsp;]+v2,v4,v5
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e652212b[&nbsp; &nbsp; &nbsp;]+smt.vmadot1su[ &nbsp;]+v2,v4,v5
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e652112b[&nbsp; &nbsp; &nbsp;]+smt.vmadot1us[ &nbsp;]+v2,v4,v5
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e652412b[&nbsp; &nbsp; &nbsp;]+smt.vmadot2u[ &nbsp;]+v2,v4,v5
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e652712b[&nbsp; &nbsp; &nbsp;]+smt.vmadot2[ &nbsp;]+v2,v4,v5
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e652612b[&nbsp; &nbsp; &nbsp;]+smt.vmadot2su[ &nbsp;]+v2,v4,v5
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e652512b[&nbsp; &nbsp; &nbsp;]+smt.vmadot2us[ &nbsp;]+v2,v4,v5
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e652812b[&nbsp; &nbsp; &nbsp;]+smt.vmadot3u[ &nbsp;]+v2,v4,v5
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e652b12b[&nbsp; &nbsp; &nbsp;]+smt.vmadot3[ &nbsp;]+v2,v4,v5
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e652a12b[&nbsp; &nbsp; &nbsp;]+smt.vmadot3su[ &nbsp;]+v2,v4,v5
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e652912b[&nbsp; &nbsp; &nbsp;]+smt.vmadot3us[ &nbsp;]+v2,v4,v5
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e241b12b[&nbsp; &nbsp; &nbsp;]+smt.vmadot[ &nbsp;]+v2,v3,v4
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e241812b[&nbsp; &nbsp; &nbsp;]+smt.vmadotu[ &nbsp;]+v2,v3,v4
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e241a12b[&nbsp; &nbsp; &nbsp;]+smt.vmadotsu[ &nbsp;]+v2,v3,v4
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e241912b[&nbsp; &nbsp; &nbsp;]+smt.vmadotus[ &nbsp;]+v2,v3,v4
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e652012b[&nbsp; &nbsp; &nbsp;]+smt.vmadot1u[ &nbsp;]+v2,v4,v5
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e652312b[&nbsp; &nbsp; &nbsp;]+smt.vmadot1[ &nbsp;]+v2,v4,v5
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e652212b[&nbsp; &nbsp; &nbsp;]+smt.vmadot1su[ &nbsp;]+v2,v4,v5
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e652112b[&nbsp; &nbsp; &nbsp;]+smt.vmadot1us[ &nbsp;]+v2,v4,v5
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e652412b[&nbsp; &nbsp; &nbsp;]+smt.vmadot2u[ &nbsp;]+v2,v4,v5
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e652712b[&nbsp; &nbsp; &nbsp;]+smt.vmadot2[ &nbsp;]+v2,v4,v5
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e652612b[&nbsp; &nbsp; &nbsp;]+smt.vmadot2su[ &nbsp;]+v2,v4,v5
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e652512b[&nbsp; &nbsp; &nbsp;]+smt.vmadot2us[ &nbsp;]+v2,v4,v5
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e652812b[&nbsp; &nbsp; &nbsp;]+smt.vmadot3u[ &nbsp;]+v2,v4,v5
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e652b12b[&nbsp; &nbsp; &nbsp;]+smt.vmadot3[ &nbsp;]+v2,v4,v5
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e652a12b[&nbsp; &nbsp; &nbsp;]+smt.vmadot3su[ &nbsp;]+v2,v4,v5
&gt; +[&nbsp; &nbsp; &nbsp;]+[0-9a-f]+:[&nbsp; &nbsp; &nbsp;]+e652912b[&nbsp; &nbsp; &nbsp;]+smt.vmadot3us[ &nbsp;]+v2,v4,v5
&gt; diff --git a/gas/testsuite/gas/riscv/x-smt-vdot.s 
&gt; b/gas/testsuite/gas/riscv/x-smt-vdot.s
&gt; new file mode 100644
&gt; index 00000000000..a9991de4fc3
&gt; --- /dev/null
&gt; +++ b/gas/testsuite/gas/riscv/x-smt-vdot.s
&gt; @@ -0,0 +1,33 @@
&gt; +target:
&gt; +&nbsp; &nbsp; smt.vmadot v2, v3, v4
&gt; +&nbsp; &nbsp; smt.vmadotu v2, v3, v4
&gt; +&nbsp; &nbsp; smt.vmadotsu v2, v3, v4
&gt; +&nbsp; &nbsp; smt.vmadotus v2, v3, v4
&gt; +&nbsp; &nbsp; smt.vmadot1u v2, v4, v5
&gt; +&nbsp; &nbsp; smt.vmadot1 v2, v4, v5
&gt; +&nbsp; &nbsp; smt.vmadot1su v2, v4, v5
&gt; +&nbsp; &nbsp; smt.vmadot1us v2, v4, v5
&gt; +&nbsp; &nbsp; smt.vmadot2u v2, v4, v5
&gt; +&nbsp; &nbsp; smt.vmadot2 v2, v4, v5
&gt; +&nbsp; &nbsp; smt.vmadot2su v2, v4, v5
&gt; +&nbsp; &nbsp; smt.vmadot2us v2, v4, v5
&gt; +&nbsp; &nbsp; smt.vmadot3u v2, v4, v5
&gt; +&nbsp; &nbsp; smt.vmadot3 v2, v4, v5
&gt; +&nbsp; &nbsp; smt.vmadot3su v2, v4, v5
&gt; +&nbsp; &nbsp; smt.vmadot3us v2, v4, v5
&gt; +&nbsp; &nbsp; smt.vmadot v2, v3, v4, i8
&gt; +&nbsp; &nbsp; smt.vmadotu v2, v3, v4, i8
&gt; +&nbsp; &nbsp; smt.vmadotsu v2, v3, v4, i8
&gt; +&nbsp; &nbsp; smt.vmadotus v2, v3, v4, i8
&gt; +&nbsp; &nbsp; smt.vmadot1u v2, v4, v5, i8
&gt; +&nbsp; &nbsp; smt.vmadot1 v2, v4, v5, i8
&gt; +&nbsp; &nbsp; smt.vmadot1su v2, v4, v5, i8
&gt; +&nbsp; &nbsp; smt.vmadot1us v2, v4, v5, i8
&gt; +&nbsp; &nbsp; smt.vmadot2u v2, v4, v5, i8
&gt; +&nbsp; &nbsp; smt.vmadot2 v2, v4, v5, i8
&gt; +&nbsp; &nbsp; smt.vmadot2su v2, v4, v5, i8
&gt; +&nbsp; &nbsp; smt.vmadot2us v2, v4, v5, i8
&gt; +&nbsp; &nbsp; smt.vmadot3u v2, v4, v5, i8
&gt; +&nbsp; &nbsp; smt.vmadot3 v2, v4, v5, i8
&gt; +&nbsp; &nbsp; smt.vmadot3su v2, v4, v5, i8
&gt; +&nbsp; &nbsp; smt.vmadot3us v2, v4, v5, i8
&gt; diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
&gt; index 6f2775c6152..5a004622c2c 100644
&gt; --- a/include/opcode/riscv-opc.h
&gt; +++ b/include/opcode/riscv-opc.h
&gt; @@ -3852,6 +3852,81 @@
&gt; &nbsp;#define MASK_MIPS_PAUSE&nbsp; 0xffffffff
&gt; &nbsp;#define MATCH_MIPS_PREF 0x0000000b
&gt; &nbsp;#define MASK_MIPS_PREF 0xe000707f
&gt; +/* SpacemiT custom instruction.&nbsp; */
&gt; +/* Int Matrix Multiplicative Accumulation */
&gt; +#define MATCH_SMT_VMADOT_I8&nbsp; &nbsp;0xe200302b
&gt; +#define MASK_SMT_VMADOT_I8&nbsp; &nbsp; 0xfe0070ff
&gt; +#define MATCH_SMT_VMADOTU_I8&nbsp; 0xe200002b
&gt; +#define MASK_SMT_VMADOTU_I8&nbsp; &nbsp;0xfe0070ff
&gt; +#define MATCH_SMT_VMADOTSU_I8 0xe200202b
&gt; +#define MASK_SMT_VMADOTSU_I8&nbsp; 0xfe0070ff
&gt; +#define MATCH_SMT_VMADOTUS_I8 0xe200102b
&gt; +#define MASK_SMT_VMADOTUS_I8&nbsp; 0xfe0070ff
&gt; +/* Int Sliding Window Multiplicative Accumulation */
&gt; +/* Sliding Value = 1 */
&gt; +#define MATCH_SMT_VMADOT1U_I8 0xe600002b
&gt; +#define MASK_SMT_VMADOT1U_I8&nbsp; 0xfe00f0ff
&gt; +#define MATCH_SMT_VMADOT1_I8&nbsp; &nbsp; 0xe600302b
&gt; +#define MASK_SMT_VMADOT1_I8&nbsp; &nbsp; &nbsp;0xfe00f0ff
&gt; +#define MATCH_SMT_VMADOT1SU_I8&nbsp; 0xe600202b
&gt; +#define MASK_SMT_VMADOT1SU_I8&nbsp; &nbsp;0xfe00f0ff
&gt; +#define MATCH_SMT_VMADOT1US_I8&nbsp; 0xe600102b
&gt; +#define MASK_SMT_VMADOT1US_I8&nbsp; &nbsp;0xfe00f0ff
&gt; +/* Sliding Value = 2 */
&gt; +#define MATCH_SMT_VMADOT2U_I8&nbsp; &nbsp;0xe600402b
&gt; +#define MASK_SMT_VMADOT2U_I8&nbsp; &nbsp; 0xfe00f0ff
&gt; +#define MATCH_SMT_VMADOT2_I8&nbsp; &nbsp; 0xe600702b
&gt; +#define MASK_SMT_VMADOT2_I8&nbsp; &nbsp; &nbsp;0xfe00f0ff
&gt; +#define MATCH_SMT_VMADOT2SU_I8&nbsp; 0xe600602b
&gt; +#define MASK_SMT_VMADOT2SU_I8&nbsp; &nbsp;0xfe00f0ff
&gt; +#define MATCH_SMT_VMADOT2US_I8&nbsp; 0xe600502b
&gt; +#define MASK_SMT_VMADOT2US_I8&nbsp; &nbsp;0xfe00f0ff
&gt; +/* Sliding Value = 3 */
&gt; +#define MATCH_SMT_VMADOT3U_I8&nbsp; &nbsp;0xe600802b
&gt; +#define MASK_SMT_VMADOT3U_I8&nbsp; &nbsp; 0xfe00f0ff
&gt; +#define MATCH_SMT_VMADOT3_I8&nbsp; &nbsp; 0xe600b02b
&gt; +#define MASK_SMT_VMADOT3_I8&nbsp; &nbsp; &nbsp;0xfe00f0ff
&gt; +#define MATCH_SMT_VMADOT3SU_I8&nbsp; 0xe600a02b
&gt; +#define MASK_SMT_VMADOT3SU_I8&nbsp; &nbsp;0xfe00f0ff
&gt; +#define MATCH_SMT_VMADOT3US_I8&nbsp; 0xe600902b
&gt; +#define MASK_SMT_VMADOT3US_I8&nbsp; &nbsp;0xfe00f0ff
&gt; +/* Int Matrix Multiplicative Accumulation */
&gt; +#define MATCH_SMT_VMADOT&nbsp; &nbsp;0x8200302b
&gt; +#define MASK_SMT_VMADOT&nbsp; &nbsp; 0x9e0070ff
&gt; +#define MATCH_SMT_VMADOTU&nbsp; 0x8200002b
&gt; +#define MASK_SMT_VMADOTU&nbsp; &nbsp;0x9e0070ff
&gt; +#define MATCH_SMT_VMADOTSU 0x8200202b
&gt; +#define MASK_SMT_VMADOTSU&nbsp; 0x9e0070ff
&gt; +#define MATCH_SMT_VMADOTUS 0x8200102b
&gt; +#define MASK_SMT_VMADOTUS&nbsp; 0x9e0070ff
&gt; +/* Int Sliding Window Multiplicative Accumulation */
&gt; +/* Sliding Value = 1 */
&gt; +#define MATCH_SMT_VMADOT1U 0x8600002b
&gt; +#define MASK_SMT_VMADOT1U&nbsp; 0x9e00f0ff
&gt; +#define MATCH_SMT_VMADOT1&nbsp; 0x8600302b
&gt; +#define MASK_SMT_VMADOT1&nbsp; &nbsp;0x9e00f0ff
&gt; +#define MATCH_SMT_VMADOT1SU 0x8600202b
&gt; +#define MASK_SMT_VMADOT1SU 0x9e00f0ff
&gt; +#define MATCH_SMT_VMADOT1US 0x8600102b
&gt; +#define MASK_SMT_VMADOT1US 0x9e00f0ff
&gt; +/* Sliding Value = 2 */
&gt; +#define MATCH_SMT_VMADOT2U 0x8600402b
&gt; +#define MASK_SMT_VMADOT2U 0x9e00f0ff
&gt; +#define MATCH_SMT_VMADOT2 0x8600702b
&gt; +#define MASK_SMT_VMADOT2 0x9e00f0ff
&gt; +#define MATCH_SMT_VMADOT2SU 0x8600602b
&gt; +#define MASK_SMT_VMADOT2SU 0x9e00f0ff
&gt; +#define MATCH_SMT_VMADOT2US 0x8600502b
&gt; +#define MASK_SMT_VMADOT2US 0x9e00f0ff
&gt; +/* Sliding Value = 3 */
&gt; +#define MATCH_SMT_VMADOT3U 0x8600802b
&gt; +#define MASK_SMT_VMADOT3U 0x9e00f0ff
&gt; +#define MATCH_SMT_VMADOT3 0x8600b02b
&gt; +#define MASK_SMT_VMADOT3 0x9e00f0ff
&gt; +#define MATCH_SMT_VMADOT3SU 0x8600a02b
&gt; +#define MASK_SMT_VMADOT3SU 0x9e00f0ff
&gt; +#define MATCH_SMT_VMADOT3US 0x8600902b
&gt; +#define MASK_SMT_VMADOT3US 0x9e00f0ff
&gt; &nbsp;/* Unprivileged Counter/Timers CSR addresses.&nbsp; */
&gt; &nbsp;#define CSR_CYCLE 0xc00
&gt; &nbsp;#define CSR_TIME 0xc01
&gt; diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
&gt; index de105f5df8b..7a7b998b913 100644
&gt; --- a/include/opcode/riscv.h
&gt; +++ b/include/opcode/riscv.h
&gt; @@ -419,6 +419,14 @@ static inline unsigned int riscv_insn_length 
&gt; (insn_t insn)
&gt; &nbsp;#define OP_MASK_MIPS_SDP_OFFSET25&nbsp; &nbsp;0x3
&gt; &nbsp;#define OP_SH_MIPS_SDP_OFFSET25&nbsp; &nbsp; &nbsp;25
&gt;
&gt; +/* SpacemiT fields */
&gt; +#define OP_MASK_SPACEMIT_IME_VD&nbsp; &nbsp; &nbsp; &nbsp; 0xf
&gt; +#define OP_SH_SPACEMIT_IME_VD&nbsp; &nbsp; &nbsp; &nbsp; 8
&gt; +#define OP_MASK_SPACEMIT_IME_VS1&nbsp; &nbsp; 0xf
&gt; +#define OP_SH_SPACEMIT_IME_VS1&nbsp; &nbsp; &nbsp; &nbsp; 16
&gt; +#define OP_MASK_SPACEMIT_IME_WI&nbsp; &nbsp; &nbsp; &nbsp; 0x3
&gt; +#define OP_SH_SPACEMIT_IME_WI&nbsp; &nbsp; &nbsp; &nbsp; 29
&gt; +
&gt; &nbsp;/* ABI names for selected x-registers.&nbsp; */
&gt;
&gt; &nbsp;#define X_ZERO 0
&gt; @@ -606,6 +614,7 @@ enum riscv_insn_class
&gt; &nbsp; &nbsp;INSN_CLASS_XMIPSCMOV,
&gt; &nbsp; &nbsp;INSN_CLASS_XMIPSEXECTL,
&gt; &nbsp; &nbsp;INSN_CLASS_XMIPSLSP,
&gt; +&nbsp; INSN_CLASS_XSMTVDOT,
&gt; &nbsp;};
&gt;
&gt; &nbsp;/* This structure holds information for a particular instruction.&nbsp; */
&gt; @@ -726,6 +735,7 @@ extern const char * const riscv_th_vlen[4];
&gt; &nbsp;extern const char * const riscv_th_vediv[4];
&gt; &nbsp;extern const char * const riscv_fli_symval[32];
&gt; &nbsp;extern const float riscv_fli_numval[32];
&gt; +extern const char * const riscv_smt_wi[4];
&gt;
&gt; &nbsp;extern const struct riscv_opcode riscv_opcodes[];
&gt; &nbsp;extern const struct riscv_opcode riscv_insn_types[];
&gt; diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
&gt; index 03c8cf1e344..6df1441d48c 100644
&gt; --- a/opcodes/riscv-dis.c
&gt; +++ b/opcodes/riscv-dis.c
&gt; @@ -917,6 +917,39 @@ print_insn_args (const char *oparg, insn_t l, 
&gt; bfd_vma pc, disassemble_info *info
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;goto undefined_modifier;
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;break;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; case 'p': /* Vendor-specific (SpacemiT) operands.&nbsp; */
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; switch (*++oparg)
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case 'V':
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; switch (*++oparg)
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case 'd':
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print (info-&gt;stream, dis_style_register, "%s",
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; riscv_vecr_names_numeric[EXTRACT_OPERAND 
&gt; (SPACEMIT_IME_VD, l) * 2]);
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case 's':
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print (info-&gt;stream, dis_style_register, "%s",
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; riscv_vecr_names_numeric[EXTRACT_OPERAND 
&gt; (SPACEMIT_IME_VS1, l) * 2]);
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default:
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; goto undefined_modifier;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case 'w': /* Xpw&amp;S ... bits in S indicates whether 
&gt; corresponding item is permitted.&nbsp; */
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (*++oparg != '&amp;')
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; goto undefined_modifier;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; strtol (oparg + 1, (char **)&amp;oparg, 16);
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; oparg--;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print (info-&gt;stream, dis_style_register, "%s",
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; riscv_smt_wi[EXTRACT_OPERAND (SPACEMIT_IME_WI, l)]);
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default:
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; goto undefined_modifier;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&gt; +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;default:
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;goto undefined_modifier;
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}
&gt; diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
&gt; index 54887c97880..8b81dda2008 100644
&gt; --- a/opcodes/riscv-opc.c
&gt; +++ b/opcodes/riscv-opc.c
&gt; @@ -122,6 +122,12 @@ const char * const riscv_th_vediv[4] =
&gt; &nbsp; &nbsp; &nbsp;"d1", "d2", "d4", "d8"
&gt; &nbsp;};
&gt;
&gt; +/* XSmtVdot, List of int type width constants.&nbsp; */
&gt; +const char * const riscv_smt_wi[4] =
&gt; +{
&gt; +&nbsp; &nbsp; "i2", "i16", "i4", "i8"
&gt; +};
&gt; +
&gt; &nbsp;/* The FLI.[HSDQ] symbolic constants (NULL for numeric constant).&nbsp; */
&gt; &nbsp;const char * const riscv_fli_symval[32] =
&gt; &nbsp;{
&gt; @@ -3579,6 +3585,45 @@ const struct riscv_opcode riscv_opcodes[] =
&gt; &nbsp;{"mips.sdp", 0, INSN_CLASS_XMIPSLSP, "t,r,Xm^(s)", MATCH_MIPS_SDP, 
&gt; MASK_MIPS_SDP, match_opcode, 0 },
&gt; &nbsp;{"mips.swp", 0, INSN_CLASS_XMIPSLSP, "t,r,Xm&amp;(s)", MATCH_MIPS_SWP, 
&gt; MASK_MIPS_SWP, match_opcode, 0 },
&gt;
&gt; +/* SpacemiT custom instructions. */
&gt; +/* Int Matrix Multi-Accumulation */
&gt; +{"smt.vmadot",&nbsp; &nbsp;0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,Vt", 
&gt; &nbsp;MATCH_SMT_VMADOT_I8,&nbsp; &nbsp;MASK_SMT_VMADOT_I8,&nbsp; &nbsp;match_opcode, INSN_ALIAS },
&gt; +{"smt.vmadot",&nbsp; &nbsp;0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,Vt,Xpw&amp;8", 
&gt; MATCH_SMT_VMADOT,&nbsp; &nbsp; &nbsp; MASK_SMT_VMADOT, &nbsp; &nbsp; match_opcode, 0 },
&gt; +{"smt.vmadotu",&nbsp; 0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,Vt", 
&gt; &nbsp;MATCH_SMT_VMADOTU_I8,&nbsp; MASK_SMT_VMADOTU_I8,&nbsp; match_opcode, INSN_ALIAS },
&gt; +{"smt.vmadotu",&nbsp; 0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,Vt,Xpw&amp;8", 
&gt; MATCH_SMT_VMADOTU, &nbsp;MASK_SMT_VMADOTU,&nbsp; &nbsp; &nbsp;match_opcode, 0 },
&gt; +{"smt.vmadotsu", 0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,Vt", 
&gt; &nbsp;MATCH_SMT_VMADOTSU_I8, MASK_SMT_VMADOTSU_I8, match_opcode, INSN_ALIAS },
&gt; +{"smt.vmadotsu", 0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,Vt,Xpw&amp;8", 
&gt; MATCH_SMT_VMADOTSU, MASK_SMT_VMADOTSU,&nbsp; &nbsp; match_opcode, 0 },
&gt; +{"smt.vmadotus", 0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,Vt", 
&gt; &nbsp;MATCH_SMT_VMADOTUS_I8, MASK_SMT_VMADOTUS_I8, match_opcode, INSN_ALIAS },
&gt; +{"smt.vmadotus", 0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,Vt,Xpw&amp;8", 
&gt; MATCH_SMT_VMADOTUS, MASK_SMT_VMADOTUS,&nbsp; &nbsp; match_opcode, 0 },
&gt; +/* Int Sliding Window Multi-Accumulation */
&gt; +/* Sliding Value = 1 */
&gt; +{"smt.vmadot1u",&nbsp; 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt", 
&gt; &nbsp;MATCH_SMT_VMADOT1U_I8,&nbsp; MASK_SMT_VMADOT1U_I8,&nbsp; match_opcode, 
&gt; INSN_ALIAS },
&gt; +{"smt.vmadot1u",&nbsp; 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&amp;8", 
&gt; MATCH_SMT_VMADOT1U, &nbsp;MASK_SMT_VMADOT1U,&nbsp; &nbsp; &nbsp;match_opcode, 0 },
&gt; +{"smt.vmadot1",&nbsp; &nbsp;0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt", 
&gt; &nbsp;MATCH_SMT_VMADOT1_I8,&nbsp; &nbsp;MASK_SMT_VMADOT1_I8,&nbsp; &nbsp;match_opcode, 
&gt; INSN_ALIAS },
&gt; +{"smt.vmadot1",&nbsp; &nbsp;0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&amp;8", 
&gt; MATCH_SMT_VMADOT1, MASK_SMT_VMADOT1,&nbsp; &nbsp; &nbsp; match_opcode, 0 },
&gt; +{"smt.vmadot1su", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt", 
&gt; &nbsp;MATCH_SMT_VMADOT1SU_I8, MASK_SMT_VMADOT1SU_I8, match_opcode, 
&gt; INSN_ALIAS },
&gt; +{"smt.vmadot1su", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&amp;8", 
&gt; MATCH_SMT_VMADOT1SU, MASK_SMT_VMADOT1SU,&nbsp; &nbsp; match_opcode, 0 },
&gt; +{"smt.vmadot1us", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt", 
&gt; &nbsp;MATCH_SMT_VMADOT1US_I8, MASK_SMT_VMADOT1US_I8, match_opcode, 
&gt; INSN_ALIAS },
&gt; +{"smt.vmadot1us", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&amp;8", 
&gt; MATCH_SMT_VMADOT1US, MASK_SMT_VMADOT1US,&nbsp; &nbsp; match_opcode, 0 },
&gt; +/* Sliding Value = 2 */
&gt; +{"smt.vmadot2u",&nbsp; 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt", 
&gt; &nbsp;MATCH_SMT_VMADOT2U_I8,&nbsp; MASK_SMT_VMADOT2U_I8,&nbsp; match_opcode, 
&gt; INSN_ALIAS },
&gt; +{"smt.vmadot2u",&nbsp; 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&amp;8", 
&gt; MATCH_SMT_VMADOT2U, &nbsp;MASK_SMT_VMADOT2U,&nbsp; &nbsp; &nbsp;match_opcode, 0},
&gt; +{"smt.vmadot2",&nbsp; &nbsp;0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt", 
&gt; &nbsp;MATCH_SMT_VMADOT2_I8,&nbsp; &nbsp;MASK_SMT_VMADOT2_I8,&nbsp; &nbsp;match_opcode, 
&gt; INSN_ALIAS },
&gt; +{"smt.vmadot2",&nbsp; &nbsp;0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&amp;8", 
&gt; MATCH_SMT_VMADOT2, MASK_SMT_VMADOT2,&nbsp; &nbsp; &nbsp; match_opcode, 0},
&gt; +{"smt.vmadot2su", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt", 
&gt; &nbsp;MATCH_SMT_VMADOT2SU_I8, MASK_SMT_VMADOT2SU_I8, match_opcode, 
&gt; INSN_ALIAS },
&gt; +{"smt.vmadot2su", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&amp;8", 
&gt; MATCH_SMT_VMADOT2SU, MASK_SMT_VMADOT2SU,&nbsp; &nbsp; match_opcode, 0},
&gt; +{"smt.vmadot2us", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt", 
&gt; &nbsp;MATCH_SMT_VMADOT2US_I8, MASK_SMT_VMADOT2US_I8, match_opcode, 
&gt; INSN_ALIAS },
&gt; +{"smt.vmadot2us", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&amp;8", 
&gt; MATCH_SMT_VMADOT2US, MASK_SMT_VMADOT2US,&nbsp; &nbsp; match_opcode, 0},
&gt; +/* Sliding Value = 3 */
&gt; +{"smt.vmadot3u",&nbsp; 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt", 
&gt; &nbsp;MATCH_SMT_VMADOT3U_I8,&nbsp; MASK_SMT_VMADOT3U_I8,&nbsp; match_opcode, 
&gt; INSN_ALIAS },
&gt; +{"smt.vmadot3u",&nbsp; 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&amp;8", 
&gt; MATCH_SMT_VMADOT3U, &nbsp;MASK_SMT_VMADOT3U,&nbsp; &nbsp; &nbsp;match_opcode, 0},
&gt; +{"smt.vmadot3",&nbsp; &nbsp;0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt", 
&gt; &nbsp;MATCH_SMT_VMADOT3_I8,&nbsp; &nbsp;MASK_SMT_VMADOT3_I8,&nbsp; &nbsp;match_opcode, 
&gt; INSN_ALIAS },
&gt; +{"smt.vmadot3",&nbsp; &nbsp;0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&amp;8", 
&gt; MATCH_SMT_VMADOT3, MASK_SMT_VMADOT3,&nbsp; &nbsp; &nbsp; match_opcode, 0},
&gt; +{"smt.vmadot3su", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt", 
&gt; &nbsp;MATCH_SMT_VMADOT3SU_I8, MASK_SMT_VMADOT3SU_I8, match_opcode, 
&gt; INSN_ALIAS },
&gt; +{"smt.vmadot3su", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&amp;8", 
&gt; MATCH_SMT_VMADOT3SU, MASK_SMT_VMADOT3SU,&nbsp; &nbsp; match_opcode, 0},
&gt; +{"smt.vmadot3us", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt", 
&gt; &nbsp;MATCH_SMT_VMADOT3US_I8, MASK_SMT_VMADOT3US_I8, match_opcode, 
&gt; INSN_ALIAS },
&gt; +{"smt.vmadot3us", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&amp;8", 
&gt; MATCH_SMT_VMADOT3US, MASK_SMT_VMADOT3US,&nbsp; &nbsp; match_opcode, 0},
&gt; +
&gt; &nbsp;/* Terminate the list.&nbsp; */
&gt; &nbsp;{0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}
&gt; &nbsp;};
&gt;

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PING^3][v2] RISC-V: Add SpacemiT vendor extensions xsmtvdot
  2026-04-04  2:10 [PING^3][v2] RISC-V: Add SpacemiT vendor extensions xsmtvdot Mark Zhuang
@ 2026-04-09 10:28 ` Michal Lach
  2026-04-09 11:37   ` Mark Zhuang
  0 siblings, 1 reply; 16+ messages in thread
From: Michal Lach @ 2026-04-09 10:28 UTC (permalink / raw)
  To: Mark Zhuang; +Cc: binutils

Hi Mark.

I'm not a binutils maintainer, but I can see that your mails contain
HTML which might drive away interest from your patches.
Maintainers/developer who submit patches to mailing lists, may use
plain-text clients which lack HTML support, and render text as-is.

You can see that by looking at how the mailing list archive renders your
email [1].

A good guideline for submitting patches and mailing lists discussions
are outlined in Linux kernel documentation [2].

BR,
Michal Lach

[1]: https://marc.info/?l=binutils&m=177565462226049&w=2
[2]: https://www.kernel.org/doc/html/v6.9/process/email-clients.html

"Mark Zhuang" <zhuangqiubin@linux.spacemit.com> writes:

> Just checking in on the previously reviewed patch. Is there any chance it could be merged, or is there anything else needed from my
> side?
> Thanks.
>
> Mark Zhuang<zhuangqiubin@linux.spacemit.com> On Tuesday, Mar 17, 2026, 16:19 wrote:
> Ping~
>
> Mark Zhuang<zhuangqiubin@linux.spacemit.com> 在 2026年2月26日 周四 12:54 写道:
> Gentle ping :)
>
> Mark Zhuang<zhuangqiubin@linux.spacemit.com> 在 2026年2月13日 周五 15:33 写道:
> Hi all,
>
> I'd like to ask if there are any further review comments. If not, could someone help merge this patch?
> Thanks.
>
> Mark Zhuang<zhuangqiubin@linux.spacemit.com> 在 2026年1月30日 周五 16:43 写道:
> Hi Jiawei
>
> Thanks.
>
>> I wonder if we need also need to set vlen here, otherwise LGTM.
>
> SpacemiT currently implements K1-x60 (vlen 256), K3-x100 (vlen 256), and K3-a100 (vlen 1024), but we believe that xsmtvdot itself
> does not require setting a vlen limit here.
>
> Jiawei<jiawei@iscas.ac.cn> 在 2026年1月28日 周三 19:16 写道:
>> From: Mark Zhuang <mark.zhuang@spacemit.com>
>>
>> SpacemiT defines Intrinsic Matrix Extension (IME) specification [1].
>> SpacemiT X60 implement version 1.0 of the SpacemiT Vector Dot Product
>> Extension (XsmtVdot v1.0) [2],
>> it is a subset of the full IME specification
>>
>> [1]
>> https://github.com/spacemit-com/riscv-ime-extension-spec/releases/download/v1.0/spacemit-ime-asciidoc.pdf
>> [2]
>> https://developer.spacemit.com/documentation?token=BWbGwbx7liGW21kq9lucSA6Vnpb#2.1
>>
>> Co-authored-by: Link <xuqian@spacemit.com>
>> ---
>>  bfd/elfxx-riscv.c                         |  7 +++
>>  gas/NEWS                                  |  3 +
>>  gas/config/tc-riscv.c                     | 71 +++++++++++++++++++++
>>  gas/doc/c-riscv.texi                      |  7 +++
>>  gas/testsuite/gas/riscv/march-help.l      |  1 +
>>  gas/testsuite/gas/riscv/x-smt-vdot-fail.l |  3 +
>>  gas/testsuite/gas/riscv/x-smt-vdot-fail.s | 46 ++++++++++++++
>>  gas/testsuite/gas/riscv/x-smt-vdot.d      | 41 +++++++++++++
>>  gas/testsuite/gas/riscv/x-smt-vdot.s      | 33 ++++++++++
>>  include/opcode/riscv-opc.h                | 75 +++++++++++++++++++++++
>>  include/opcode/riscv.h                    | 10 +++
>>  opcodes/riscv-dis.c                       | 33 ++++++++++
>>  opcodes/riscv-opc.c                       | 45 ++++++++++++++
>>  13 files changed, 375 insertions(+)
>>  create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-fail.l
>>  create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-fail.s
>>  create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot.d
>>  create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot.s
>>
>> diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
>> index ee962b4f6f1..ea24a68b895 100644
>> --- a/bfd/elfxx-riscv.c
>> +++ b/bfd/elfxx-riscv.c
>> @@ -1229,6 +1229,8 @@ static const struct riscv_implicit_subset
>> riscv_implicit_subsets[] =
>>    {"xtheadvector", "+zicsr", check_implicit_always},
>>    {"xtheadzvamo", "+zaamo", check_implicit_always},
>>
>> +  {"xsmtvdot", "+zve32x", check_implicit_always},
>
> I wonder if we need also need to set vlen here, otherwise LGTM.
>
> Thanks,
>
> Jiawei
>
>> +
>>    {"v", "+zve64d,+zvl128b", check_implicit_always},
>>    {"zvfh", "+zvfhmin,+zfhmin", check_implicit_always},
>>    {"zvfhmin", "+zve32f", check_implicit_always},
>> @@ -1644,6 +1646,7 @@ static const struct riscv_supported_ext
>> riscv_supported_vendor_x_ext[] =
>>    {"xmipscmov",        ISA_SPEC_CLASS_DRAFT,    1, 0, 0 },
>>    {"xmipsexectl",    ISA_SPEC_CLASS_DRAFT,    1, 0, 0 },
>>    {"xmipslsp",        ISA_SPEC_CLASS_DRAFT,    1, 0, 0 },
>> +  {"xsmtvdot",        ISA_SPEC_CLASS_DRAFT,    1, 0, 0 },
>>    {NULL, 0, 0, 0, 0}
>>  };
>>
>> @@ -3062,6 +3065,8 @@ riscv_multi_subset_supports
>> (riscv_parse_subset_t *rps,
>>        return riscv_subset_supports (rps, "xmipsexectl");
>>      case INSN_CLASS_XMIPSLSP:
>>        return riscv_subset_supports (rps, "xmipslsp");
>> +    case INSN_CLASS_XSMTVDOT:
>> +      return riscv_subset_supports (rps, "xsmtvdot");
>>      default:
>>        rps->error_handler
>>          (_("internal: unreachable INSN_CLASS_*"));
>> @@ -3365,6 +3370,8 @@ riscv_multi_subset_supports_ext
>> (riscv_parse_subset_t *rps,
>>        return "xsfvqmaccdod";
>>      case INSN_CLASS_XSFVFNRCLIPXFQF:
>>        return "xsfvfnrclipxfqf";
>> +    case INSN_CLASS_XSMTVDOT:
>> +      return "xsmtvdot";
>>      default:
>>        rps->error_handler
>>          (_("internal: unreachable INSN_CLASS_*"));
>> diff --git a/gas/NEWS b/gas/NEWS
>> index e384d1135c0..123872e7c02 100644
>> --- a/gas/NEWS
>> +++ b/gas/NEWS
>> @@ -17,6 +17,9 @@ Changes in 2.46:
>>  * Add support for RISC-V standard extensions:
>>    sdtrig v1.0, ssstrict v1.0.
>>
>> +* Add support for RISC-V vendor extensions:
>> +  SpacemiT: xsmtvdot v1.0.
>> +
>>  * The assembler now supports generating SFrame Version 3 format.
>> This version
>>    supports .text > 2 GiB, support for marking outermost frames,
>> support for
>>    marking signal trampolines, and support for "flexible" frames which
>> have
>> diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
>> index 6bcf53832a0..25cafd83a95 100644
>> --- a/gas/config/tc-riscv.c
>> +++ b/gas/config/tc-riscv.c
>> @@ -1771,6 +1771,29 @@ validate_riscv_insn (const struct riscv_opcode
>> *opc, int length)
>>              goto unknown_validate_operand;
>>          }
>>          break;
>> +        case 'p': /* Vendor-specific (SpacemiT) operands.  */
>> +        switch (*++oparg)
>> +        {
>> +          case 'V':
>> +            switch (*++oparg)
>> +              {
>> +              case 'd': USE_BITS (OP_MASK_SPACEMIT_IME_VD,
>> OP_SH_SPACEMIT_IME_VD); break;
>> +              case 's': USE_BITS (OP_MASK_SPACEMIT_IME_VS1,
>> OP_SH_SPACEMIT_IME_VS1); break;
>> +              default:
>> +                goto unknown_validate_operand;
>> +              }
>> +              break;
>> +          case 'w': /* Xpw&S ... bits in S indicates whether
>> corresponding item is permitted.  */
>> +            if (*++oparg != '&')
>> +              goto unknown_validate_operand;
>> +            strtol (oparg + 1, (char **)&oparg, 16);
>> +            oparg--;
>> +            USE_BITS (OP_MASK_SPACEMIT_IME_WI, OP_SH_SPACEMIT_IME_WI);
>> +            break;
>> +          default:
>> +            goto unknown_validate_operand;
>> +        }
>> +        break;
>>          default:
>>            goto unknown_validate_operand;
>>          }
>> @@ -4287,6 +4310,54 @@ riscv_ip (char *str, struct riscv_cl_insn *ip,
>> expressionS *imm_expr,
>>              }
>>            break;
>>
>> +        case 'p': /* Vendor-specific (SpacemiT) operands.  */
>> +          {
>> +          size_t n;
>> +          switch (*++oparg)
>> +            {
>> +            case 'V':
>> +              switch (*++oparg)
>> +              {
>> +                case 'd':
>> +                  if (!reg_lookup (&asarg, RCLASS_VECR, ®no))
>> +                    break;
>> +                  if ((regno & 0x1) != 0)
>> +                  {
>> +                    error.msg = _("illegal operands (vd must be even)");
>> +                    break;
>> +                  }
>> +                  INSERT_OPERAND (SPACEMIT_IME_VD, *ip, regno>>1);
>> +                  continue;
>> +                case 's':
>> +                  if (!reg_lookup (&asarg, RCLASS_VECR, ®no))
>> +                    break;
>> +                  if ((regno & 0x1) != 0)
>> +                  {
>> +                    error.msg = _("illegal operands (vs1 must be even)");
>> +                    break;
>> +                  }
>> +                  INSERT_OPERAND (SPACEMIT_IME_VS1, *ip, regno>>1);
>> +                  continue;
>> +                default:
>> +                  goto unknown_riscv_ip_operand;
>> +              }
>> +              break;
>> +            case 'w': /* Xpw&S ... bits in S indicates whether
>> corresponding item is permitted.  */
>> +              if (*++oparg != '&')
>> +                goto unknown_riscv_ip_operand;
>> +              n = strtol (oparg + 1, (char **)&oparg, 16);
>> +              oparg--;
>> +              if (!arg_lookup (&asarg, riscv_smt_wi, ARRAY_SIZE
>> (riscv_smt_wi), ®no))
>> +                break;
>> +              if ((n & (1 << regno)) == 0)
>> +                break;
>> +              INSERT_OPERAND (SPACEMIT_IME_WI, *ip, regno);
>> +              continue;
>> +            default:
>> +              goto unknown_riscv_ip_operand;
>> +            }
>> +          }
>> +          break;
>>          default:
>>            goto unknown_riscv_ip_operand;
>>          }
>> diff --git a/gas/doc/c-riscv.texi b/gas/doc/c-riscv.texi
>> index c6c4081c204..88dd1de4aea 100644
>> --- a/gas/doc/c-riscv.texi
>> +++ b/gas/doc/c-riscv.texi
>> @@ -918,4 +918,11 @@ The XMipsSlsp extension provides instructions
>> mips.ldp, mips.lwp, mips.sdp and m
>>
>>  It is documented in
>> @url{https://mips.com/wp-content/uploads/2025/03/P8700-F_Programmers_Reference_Manual_Rev1.82_3-19-2025.pdf}.
>>
>> +@item XSmtVdot
>> +The XSmtVdot extension provides instructions for vector dot.
>> +
>> +SpacemiT defines Intrinsic Matrix Extension (IME) specification,
>> documented in
>> @url{https://github.com/spacemit-com/riscv-ime-extension-spec/releases/download/v1.0/spacemit-ime-asciidoc.pdf}.
>> +SpacemiT X60 implement version 1.0 of the SpacemiT Vector Dot Product
>> Extension (XsmtVdot v1.0),
>> +it is a subset of the full IME specification, documented in
>> @url{https://developer.spacemit.com/documentation?token=BWbGwbx7liGW21kq9lucSA6Vnpb#2.1}.
>> +
>>  @end table
>> diff --git a/gas/testsuite/gas/riscv/march-help.l
>> b/gas/testsuite/gas/riscv/march-help.l
>> index 0ce2f896735..6e52669e9a4 100644
>> --- a/gas/testsuite/gas/riscv/march-help.l
>> +++ b/gas/testsuite/gas/riscv/march-help.l
>> @@ -186,3 +186,4 @@ All available -march extensions for RISC-V:
>>      xmipscmov                               1.0
>>      xmipsexectl                             1.0
>>      xmipslsp                                1.0
>> +    xsmtvdot                                1.0
>> diff --git a/gas/testsuite/gas/riscv/x-smt-vdot-fail.l
>> b/gas/testsuite/gas/riscv/x-smt-vdot-fail.l
>> new file mode 100644
>> index 00000000000..6e846b401e1
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/x-smt-vdot-fail.l
>> @@ -0,0 +1,3 @@
>> +#as: -march=rv64gcv_xsmtvdot
>> +#source: x-smt-vdot-fail.s
>> +#error_output: x-smt-vdot-fail.l
>> diff --git a/gas/testsuite/gas/riscv/x-smt-vdot-fail.s
>> b/gas/testsuite/gas/riscv/x-smt-vdot-fail.s
>> new file mode 100644
>> index 00000000000..77399a7fdde
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/x-smt-vdot-fail.s
>> @@ -0,0 +1,46 @@
>> +target:
>> +    smt.vmadot v1, v3, v4
>> +    smt.vmadotu v1, v3, v4
>> +    smt.vmadotsu v1, v3, v4
>> +    smt.vmadotus v1, v3, v4
>> +    smt.vmadot1u v1, v4, v5
>> +    smt.vmadot1 v1, v4, v5
>> +    smt.vmadot1su v1, v4, v5
>> +    smt.vmadot1us v1, v4, v5
>> +    smt.vmadot2u v1, v4, v5
>> +    smt.vmadot2 v1, v4, v5
>> +    smt.vmadot2su v1, v4, v5
>> +    smt.vmadot2us v1, v4, v5
>> +    smt.vmadot3u v1, v4, v5
>> +    smt.vmadot3 v1, v4, v5
>> +    smt.vmadot3su v1, v4, v5
>> +    smt.vmadot3us v1, v4, v5
>> +    smt.vmadot1u v2, v3, v5
>> +    smt.vmadot1 v2, v3, v5
>> +    smt.vmadot1su v2, v3, v5
>> +    smt.vmadot1us v2, v3, v5
>> +    smt.vmadot2u v2, v3, v5
>> +    smt.vmadot2 v2, v3, v5
>> +    smt.vmadot2su v2, v3, v5
>> +    smt.vmadot2us v2, v3, v5
>> +    smt.vmadot3u v2, v3, v5
>> +    smt.vmadot3 v2, v3, v5
>> +    smt.vmadot3su v2, v3, v5
>> +    smt.vmadot3us v2, v3, v5
>> +    smt.vmadot v2, v3, v4, i4
>> +    smt.vmadotu v2, v3, v4, i4
>> +    smt.vmadotsu v2, v3, v4, i4
>> +    smt.vmadotus v2, v3, v4, i4
>> +    smt.vmadot1u v2, v4, v5, i4
>> +    smt.vmadot1 v2, v4, v5, i4
>> +    smt.vmadot1su v2, v4, v5, i4
>> +    smt.vmadot1us v2, v4, v5, i4
>> +    smt.vmadot2u v2, v4, v5, i4
>> +    smt.vmadot2 v2, v4, v5, i4
>> +    smt.vmadot2su v2, v4, v5, i4
>> +    smt.vmadot2us v2, v4, v5, i4
>> +    smt.vmadot3u v2, v4, v5, i4
>> +    smt.vmadot3 v2, v4, v5, i4
>> +    smt.vmadot3su v2, v4, v5, i4
>> +    smt.vmadot3us v2, v4, v5, i4
>> +
>> diff --git a/gas/testsuite/gas/riscv/x-smt-vdot.d
>> b/gas/testsuite/gas/riscv/x-smt-vdot.d
>> new file mode 100644
>> index 00000000000..6f86236785d
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/x-smt-vdot.d
>> @@ -0,0 +1,41 @@
>> +#as: -march=rv64gcv_xsmtvdot
>> +#objdump: -dr
>> +
>> +.*:[     ]+file format .*
>> +
>> +
>> +Disassembly of section .text:
>> +
>> +0+000 <target>:
>> +[     ]+[0-9a-f]+:[     ]+e241b12b[     ]+smt.vmadot[  ]+v2,v3,v4
>> +[     ]+[0-9a-f]+:[     ]+e241812b[     ]+smt.vmadotu[  ]+v2,v3,v4
>> +[     ]+[0-9a-f]+:[     ]+e241a12b[     ]+smt.vmadotsu[  ]+v2,v3,v4
>> +[     ]+[0-9a-f]+:[     ]+e241912b[     ]+smt.vmadotus[  ]+v2,v3,v4
>> +[     ]+[0-9a-f]+:[     ]+e652012b[     ]+smt.vmadot1u[  ]+v2,v4,v5
>> +[     ]+[0-9a-f]+:[     ]+e652312b[     ]+smt.vmadot1[  ]+v2,v4,v5
>> +[     ]+[0-9a-f]+:[     ]+e652212b[     ]+smt.vmadot1su[  ]+v2,v4,v5
>> +[     ]+[0-9a-f]+:[     ]+e652112b[     ]+smt.vmadot1us[  ]+v2,v4,v5
>> +[     ]+[0-9a-f]+:[     ]+e652412b[     ]+smt.vmadot2u[  ]+v2,v4,v5
>> +[     ]+[0-9a-f]+:[     ]+e652712b[     ]+smt.vmadot2[  ]+v2,v4,v5
>> +[     ]+[0-9a-f]+:[     ]+e652612b[     ]+smt.vmadot2su[  ]+v2,v4,v5
>> +[     ]+[0-9a-f]+:[     ]+e652512b[     ]+smt.vmadot2us[  ]+v2,v4,v5
>> +[     ]+[0-9a-f]+:[     ]+e652812b[     ]+smt.vmadot3u[  ]+v2,v4,v5
>> +[     ]+[0-9a-f]+:[     ]+e652b12b[     ]+smt.vmadot3[  ]+v2,v4,v5
>> +[     ]+[0-9a-f]+:[     ]+e652a12b[     ]+smt.vmadot3su[  ]+v2,v4,v5
>> +[     ]+[0-9a-f]+:[     ]+e652912b[     ]+smt.vmadot3us[  ]+v2,v4,v5
>> +[     ]+[0-9a-f]+:[     ]+e241b12b[     ]+smt.vmadot[  ]+v2,v3,v4
>> +[     ]+[0-9a-f]+:[     ]+e241812b[     ]+smt.vmadotu[  ]+v2,v3,v4
>> +[     ]+[0-9a-f]+:[     ]+e241a12b[     ]+smt.vmadotsu[  ]+v2,v3,v4
>> +[     ]+[0-9a-f]+:[     ]+e241912b[     ]+smt.vmadotus[  ]+v2,v3,v4
>> +[     ]+[0-9a-f]+:[     ]+e652012b[     ]+smt.vmadot1u[  ]+v2,v4,v5
>> +[     ]+[0-9a-f]+:[     ]+e652312b[     ]+smt.vmadot1[  ]+v2,v4,v5
>> +[     ]+[0-9a-f]+:[     ]+e652212b[     ]+smt.vmadot1su[  ]+v2,v4,v5
>> +[     ]+[0-9a-f]+:[     ]+e652112b[     ]+smt.vmadot1us[  ]+v2,v4,v5
>> +[     ]+[0-9a-f]+:[     ]+e652412b[     ]+smt.vmadot2u[  ]+v2,v4,v5
>> +[     ]+[0-9a-f]+:[     ]+e652712b[     ]+smt.vmadot2[  ]+v2,v4,v5
>> +[     ]+[0-9a-f]+:[     ]+e652612b[     ]+smt.vmadot2su[  ]+v2,v4,v5
>> +[     ]+[0-9a-f]+:[     ]+e652512b[     ]+smt.vmadot2us[  ]+v2,v4,v5
>> +[     ]+[0-9a-f]+:[     ]+e652812b[     ]+smt.vmadot3u[  ]+v2,v4,v5
>> +[     ]+[0-9a-f]+:[     ]+e652b12b[     ]+smt.vmadot3[  ]+v2,v4,v5
>> +[     ]+[0-9a-f]+:[     ]+e652a12b[     ]+smt.vmadot3su[  ]+v2,v4,v5
>> +[     ]+[0-9a-f]+:[     ]+e652912b[     ]+smt.vmadot3us[  ]+v2,v4,v5
>> diff --git a/gas/testsuite/gas/riscv/x-smt-vdot.s
>> b/gas/testsuite/gas/riscv/x-smt-vdot.s
>> new file mode 100644
>> index 00000000000..a9991de4fc3
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/x-smt-vdot.s
>> @@ -0,0 +1,33 @@
>> +target:
>> +    smt.vmadot v2, v3, v4
>> +    smt.vmadotu v2, v3, v4
>> +    smt.vmadotsu v2, v3, v4
>> +    smt.vmadotus v2, v3, v4
>> +    smt.vmadot1u v2, v4, v5
>> +    smt.vmadot1 v2, v4, v5
>> +    smt.vmadot1su v2, v4, v5
>> +    smt.vmadot1us v2, v4, v5
>> +    smt.vmadot2u v2, v4, v5
>> +    smt.vmadot2 v2, v4, v5
>> +    smt.vmadot2su v2, v4, v5
>> +    smt.vmadot2us v2, v4, v5
>> +    smt.vmadot3u v2, v4, v5
>> +    smt.vmadot3 v2, v4, v5
>> +    smt.vmadot3su v2, v4, v5
>> +    smt.vmadot3us v2, v4, v5
>> +    smt.vmadot v2, v3, v4, i8
>> +    smt.vmadotu v2, v3, v4, i8
>> +    smt.vmadotsu v2, v3, v4, i8
>> +    smt.vmadotus v2, v3, v4, i8
>> +    smt.vmadot1u v2, v4, v5, i8
>> +    smt.vmadot1 v2, v4, v5, i8
>> +    smt.vmadot1su v2, v4, v5, i8
>> +    smt.vmadot1us v2, v4, v5, i8
>> +    smt.vmadot2u v2, v4, v5, i8
>> +    smt.vmadot2 v2, v4, v5, i8
>> +    smt.vmadot2su v2, v4, v5, i8
>> +    smt.vmadot2us v2, v4, v5, i8
>> +    smt.vmadot3u v2, v4, v5, i8
>> +    smt.vmadot3 v2, v4, v5, i8
>> +    smt.vmadot3su v2, v4, v5, i8
>> +    smt.vmadot3us v2, v4, v5, i8
>> diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
>> index 6f2775c6152..5a004622c2c 100644
>> --- a/include/opcode/riscv-opc.h
>> +++ b/include/opcode/riscv-opc.h
>> @@ -3852,6 +3852,81 @@
>>  #define MASK_MIPS_PAUSE  0xffffffff
>>  #define MATCH_MIPS_PREF 0x0000000b
>>  #define MASK_MIPS_PREF 0xe000707f
>> +/* SpacemiT custom instruction.  */
>> +/* Int Matrix Multiplicative Accumulation */
>> +#define MATCH_SMT_VMADOT_I8   0xe200302b
>> +#define MASK_SMT_VMADOT_I8    0xfe0070ff
>> +#define MATCH_SMT_VMADOTU_I8  0xe200002b
>> +#define MASK_SMT_VMADOTU_I8   0xfe0070ff
>> +#define MATCH_SMT_VMADOTSU_I8 0xe200202b
>> +#define MASK_SMT_VMADOTSU_I8  0xfe0070ff
>> +#define MATCH_SMT_VMADOTUS_I8 0xe200102b
>> +#define MASK_SMT_VMADOTUS_I8  0xfe0070ff
>> +/* Int Sliding Window Multiplicative Accumulation */
>> +/* Sliding Value = 1 */
>> +#define MATCH_SMT_VMADOT1U_I8 0xe600002b
>> +#define MASK_SMT_VMADOT1U_I8  0xfe00f0ff
>> +#define MATCH_SMT_VMADOT1_I8    0xe600302b
>> +#define MASK_SMT_VMADOT1_I8     0xfe00f0ff
>> +#define MATCH_SMT_VMADOT1SU_I8  0xe600202b
>> +#define MASK_SMT_VMADOT1SU_I8   0xfe00f0ff
>> +#define MATCH_SMT_VMADOT1US_I8  0xe600102b
>> +#define MASK_SMT_VMADOT1US_I8   0xfe00f0ff
>> +/* Sliding Value = 2 */
>> +#define MATCH_SMT_VMADOT2U_I8   0xe600402b
>> +#define MASK_SMT_VMADOT2U_I8    0xfe00f0ff
>> +#define MATCH_SMT_VMADOT2_I8    0xe600702b
>> +#define MASK_SMT_VMADOT2_I8     0xfe00f0ff
>> +#define MATCH_SMT_VMADOT2SU_I8  0xe600602b
>> +#define MASK_SMT_VMADOT2SU_I8   0xfe00f0ff
>> +#define MATCH_SMT_VMADOT2US_I8  0xe600502b
>> +#define MASK_SMT_VMADOT2US_I8   0xfe00f0ff
>> +/* Sliding Value = 3 */
>> +#define MATCH_SMT_VMADOT3U_I8   0xe600802b
>> +#define MASK_SMT_VMADOT3U_I8    0xfe00f0ff
>> +#define MATCH_SMT_VMADOT3_I8    0xe600b02b
>> +#define MASK_SMT_VMADOT3_I8     0xfe00f0ff
>> +#define MATCH_SMT_VMADOT3SU_I8  0xe600a02b
>> +#define MASK_SMT_VMADOT3SU_I8   0xfe00f0ff
>> +#define MATCH_SMT_VMADOT3US_I8  0xe600902b
>> +#define MASK_SMT_VMADOT3US_I8   0xfe00f0ff
>> +/* Int Matrix Multiplicative Accumulation */
>> +#define MATCH_SMT_VMADOT   0x8200302b
>> +#define MASK_SMT_VMADOT    0x9e0070ff
>> +#define MATCH_SMT_VMADOTU  0x8200002b
>> +#define MASK_SMT_VMADOTU   0x9e0070ff
>> +#define MATCH_SMT_VMADOTSU 0x8200202b
>> +#define MASK_SMT_VMADOTSU  0x9e0070ff
>> +#define MATCH_SMT_VMADOTUS 0x8200102b
>> +#define MASK_SMT_VMADOTUS  0x9e0070ff
>> +/* Int Sliding Window Multiplicative Accumulation */
>> +/* Sliding Value = 1 */
>> +#define MATCH_SMT_VMADOT1U 0x8600002b
>> +#define MASK_SMT_VMADOT1U  0x9e00f0ff
>> +#define MATCH_SMT_VMADOT1  0x8600302b
>> +#define MASK_SMT_VMADOT1   0x9e00f0ff
>> +#define MATCH_SMT_VMADOT1SU 0x8600202b
>> +#define MASK_SMT_VMADOT1SU 0x9e00f0ff
>> +#define MATCH_SMT_VMADOT1US 0x8600102b
>> +#define MASK_SMT_VMADOT1US 0x9e00f0ff
>> +/* Sliding Value = 2 */
>> +#define MATCH_SMT_VMADOT2U 0x8600402b
>> +#define MASK_SMT_VMADOT2U 0x9e00f0ff
>> +#define MATCH_SMT_VMADOT2 0x8600702b
>> +#define MASK_SMT_VMADOT2 0x9e00f0ff
>> +#define MATCH_SMT_VMADOT2SU 0x8600602b
>> +#define MASK_SMT_VMADOT2SU 0x9e00f0ff
>> +#define MATCH_SMT_VMADOT2US 0x8600502b
>> +#define MASK_SMT_VMADOT2US 0x9e00f0ff
>> +/* Sliding Value = 3 */
>> +#define MATCH_SMT_VMADOT3U 0x8600802b
>> +#define MASK_SMT_VMADOT3U 0x9e00f0ff
>> +#define MATCH_SMT_VMADOT3 0x8600b02b
>> +#define MASK_SMT_VMADOT3 0x9e00f0ff
>> +#define MATCH_SMT_VMADOT3SU 0x8600a02b
>> +#define MASK_SMT_VMADOT3SU 0x9e00f0ff
>> +#define MATCH_SMT_VMADOT3US 0x8600902b
>> +#define MASK_SMT_VMADOT3US 0x9e00f0ff
>>  /* Unprivileged Counter/Timers CSR addresses.  */
>>  #define CSR_CYCLE 0xc00
>>  #define CSR_TIME 0xc01
>> diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
>> index de105f5df8b..7a7b998b913 100644
>> --- a/include/opcode/riscv.h
>> +++ b/include/opcode/riscv.h
>> @@ -419,6 +419,14 @@ static inline unsigned int riscv_insn_length
>> (insn_t insn)
>>  #define OP_MASK_MIPS_SDP_OFFSET25   0x3
>>  #define OP_SH_MIPS_SDP_OFFSET25     25
>>
>> +/* SpacemiT fields */
>> +#define OP_MASK_SPACEMIT_IME_VD        0xf
>> +#define OP_SH_SPACEMIT_IME_VD        8
>> +#define OP_MASK_SPACEMIT_IME_VS1    0xf
>> +#define OP_SH_SPACEMIT_IME_VS1        16
>> +#define OP_MASK_SPACEMIT_IME_WI        0x3
>> +#define OP_SH_SPACEMIT_IME_WI        29
>> +
>>  /* ABI names for selected x-registers.  */
>>
>>  #define X_ZERO 0
>> @@ -606,6 +614,7 @@ enum riscv_insn_class
>>    INSN_CLASS_XMIPSCMOV,
>>    INSN_CLASS_XMIPSEXECTL,
>>    INSN_CLASS_XMIPSLSP,
>> +  INSN_CLASS_XSMTVDOT,
>>  };
>>
>>  /* This structure holds information for a particular instruction.  */
>> @@ -726,6 +735,7 @@ extern const char * const riscv_th_vlen[4];
>>  extern const char * const riscv_th_vediv[4];
>>  extern const char * const riscv_fli_symval[32];
>>  extern const float riscv_fli_numval[32];
>> +extern const char * const riscv_smt_wi[4];
>>
>>  extern const struct riscv_opcode riscv_opcodes[];
>>  extern const struct riscv_opcode riscv_insn_types[];
>> diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
>> index 03c8cf1e344..6df1441d48c 100644
>> --- a/opcodes/riscv-dis.c
>> +++ b/opcodes/riscv-dis.c
>> @@ -917,6 +917,39 @@ print_insn_args (const char *oparg, insn_t l,
>> bfd_vma pc, disassemble_info *info
>>            goto undefined_modifier;
>>          }
>>            break;
>> +        case 'p': /* Vendor-specific (SpacemiT) operands.  */
>> +          {
>> +          switch (*++oparg)
>> +          {
>> +          case 'V':
>> +            switch (*++oparg)
>> +              {
>> +              case 'd':
>> +                print (info->stream, dis_style_register, "%s",
>> +                  riscv_vecr_names_numeric[EXTRACT_OPERAND
>> (SPACEMIT_IME_VD, l) * 2]);
>> +                break;
>> +              case 's':
>> +                print (info->stream, dis_style_register, "%s",
>> +                  riscv_vecr_names_numeric[EXTRACT_OPERAND
>> (SPACEMIT_IME_VS1, l) * 2]);
>> +                break;
>> +              default:
>> +                goto undefined_modifier;
>> +              }
>> +            break;
>> +          case 'w': /* Xpw&S ... bits in S indicates whether
>> corresponding item is permitted.  */
>> +            if (*++oparg != '&')
>> +              goto undefined_modifier;
>> +            strtol (oparg + 1, (char **)&oparg, 16);
>> +            oparg--;
>> +            print (info->stream, dis_style_register, "%s",
>> +                riscv_smt_wi[EXTRACT_OPERAND (SPACEMIT_IME_WI, l)]);
>> +              break;
>> +          default:
>> +            goto undefined_modifier;
>> +          }
>> +            break;
>> +          }
>> +          break;
>>          default:
>>            goto undefined_modifier;
>>          }
>> diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
>> index 54887c97880..8b81dda2008 100644
>> --- a/opcodes/riscv-opc.c
>> +++ b/opcodes/riscv-opc.c
>> @@ -122,6 +122,12 @@ const char * const riscv_th_vediv[4] =
>>      "d1", "d2", "d4", "d8"
>>  };
>>
>> +/* XSmtVdot, List of int type width constants.  */
>> +const char * const riscv_smt_wi[4] =
>> +{
>> +    "i2", "i16", "i4", "i8"
>> +};
>> +
>>  /* The FLI.[HSDQ] symbolic constants (NULL for numeric constant).  */
>>  const char * const riscv_fli_symval[32] =
>>  {
>> @@ -3579,6 +3585,45 @@ const struct riscv_opcode riscv_opcodes[] =
>>  {"mips.sdp", 0, INSN_CLASS_XMIPSLSP, "t,r,Xm^(s)", MATCH_MIPS_SDP,
>> MASK_MIPS_SDP, match_opcode, 0 },
>>  {"mips.swp", 0, INSN_CLASS_XMIPSLSP, "t,r,Xm&(s)", MATCH_MIPS_SWP,
>> MASK_MIPS_SWP, match_opcode, 0 },
>>
>> +/* SpacemiT custom instructions. */
>> +/* Int Matrix Multi-Accumulation */
>> +{"smt.vmadot",   0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,Vt",
>>  MATCH_SMT_VMADOT_I8,   MASK_SMT_VMADOT_I8,   match_opcode, INSN_ALIAS },
>> +{"smt.vmadot",   0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,Vt,Xpw&8",
>> MATCH_SMT_VMADOT,      MASK_SMT_VMADOT,     match_opcode, 0 },
>> +{"smt.vmadotu",  0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,Vt",
>>  MATCH_SMT_VMADOTU_I8,  MASK_SMT_VMADOTU_I8,  match_opcode, INSN_ALIAS },
>> +{"smt.vmadotu",  0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,Vt,Xpw&8",
>> MATCH_SMT_VMADOTU,  MASK_SMT_VMADOTU,     match_opcode, 0 },
>> +{"smt.vmadotsu", 0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,Vt",
>>  MATCH_SMT_VMADOTSU_I8, MASK_SMT_VMADOTSU_I8, match_opcode, INSN_ALIAS },
>> +{"smt.vmadotsu", 0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,Vt,Xpw&8",
>> MATCH_SMT_VMADOTSU, MASK_SMT_VMADOTSU,    match_opcode, 0 },
>> +{"smt.vmadotus", 0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,Vt",
>>  MATCH_SMT_VMADOTUS_I8, MASK_SMT_VMADOTUS_I8, match_opcode, INSN_ALIAS },
>> +{"smt.vmadotus", 0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,Vt,Xpw&8",
>> MATCH_SMT_VMADOTUS, MASK_SMT_VMADOTUS,    match_opcode, 0 },
>> +/* Int Sliding Window Multi-Accumulation */
>> +/* Sliding Value = 1 */
>> +{"smt.vmadot1u",  0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt",
>>  MATCH_SMT_VMADOT1U_I8,  MASK_SMT_VMADOT1U_I8,  match_opcode,
>> INSN_ALIAS },
>> +{"smt.vmadot1u",  0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&8",
>> MATCH_SMT_VMADOT1U,  MASK_SMT_VMADOT1U,     match_opcode, 0 },
>> +{"smt.vmadot1",   0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt",
>>  MATCH_SMT_VMADOT1_I8,   MASK_SMT_VMADOT1_I8,   match_opcode,
>> INSN_ALIAS },
>> +{"smt.vmadot1",   0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&8",
>> MATCH_SMT_VMADOT1, MASK_SMT_VMADOT1,      match_opcode, 0 },
>> +{"smt.vmadot1su", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt",
>>  MATCH_SMT_VMADOT1SU_I8, MASK_SMT_VMADOT1SU_I8, match_opcode,
>> INSN_ALIAS },
>> +{"smt.vmadot1su", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&8",
>> MATCH_SMT_VMADOT1SU, MASK_SMT_VMADOT1SU,    match_opcode, 0 },
>> +{"smt.vmadot1us", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt",
>>  MATCH_SMT_VMADOT1US_I8, MASK_SMT_VMADOT1US_I8, match_opcode,
>> INSN_ALIAS },
>> +{"smt.vmadot1us", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&8",
>> MATCH_SMT_VMADOT1US, MASK_SMT_VMADOT1US,    match_opcode, 0 },
>> +/* Sliding Value = 2 */
>> +{"smt.vmadot2u",  0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt",
>>  MATCH_SMT_VMADOT2U_I8,  MASK_SMT_VMADOT2U_I8,  match_opcode,
>> INSN_ALIAS },
>> +{"smt.vmadot2u",  0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&8",
>> MATCH_SMT_VMADOT2U,  MASK_SMT_VMADOT2U,     match_opcode, 0},
>> +{"smt.vmadot2",   0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt",
>>  MATCH_SMT_VMADOT2_I8,   MASK_SMT_VMADOT2_I8,   match_opcode,
>> INSN_ALIAS },
>> +{"smt.vmadot2",   0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&8",
>> MATCH_SMT_VMADOT2, MASK_SMT_VMADOT2,      match_opcode, 0},
>> +{"smt.vmadot2su", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt",
>>  MATCH_SMT_VMADOT2SU_I8, MASK_SMT_VMADOT2SU_I8, match_opcode,
>> INSN_ALIAS },
>> +{"smt.vmadot2su", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&8",
>> MATCH_SMT_VMADOT2SU, MASK_SMT_VMADOT2SU,    match_opcode, 0},
>> +{"smt.vmadot2us", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt",
>>  MATCH_SMT_VMADOT2US_I8, MASK_SMT_VMADOT2US_I8, match_opcode,
>> INSN_ALIAS },
>> +{"smt.vmadot2us", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&8",
>> MATCH_SMT_VMADOT2US, MASK_SMT_VMADOT2US,    match_opcode, 0},
>> +/* Sliding Value = 3 */
>> +{"smt.vmadot3u",  0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt",
>>  MATCH_SMT_VMADOT3U_I8,  MASK_SMT_VMADOT3U_I8,  match_opcode,
>> INSN_ALIAS },
>> +{"smt.vmadot3u",  0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&8",
>> MATCH_SMT_VMADOT3U,  MASK_SMT_VMADOT3U,     match_opcode, 0},
>> +{"smt.vmadot3",   0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt",
>>  MATCH_SMT_VMADOT3_I8,   MASK_SMT_VMADOT3_I8,   match_opcode,
>> INSN_ALIAS },
>> +{"smt.vmadot3",   0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&8",
>> MATCH_SMT_VMADOT3, MASK_SMT_VMADOT3,      match_opcode, 0},
>> +{"smt.vmadot3su", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt",
>>  MATCH_SMT_VMADOT3SU_I8, MASK_SMT_VMADOT3SU_I8, match_opcode,
>> INSN_ALIAS },
>> +{"smt.vmadot3su", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&8",
>> MATCH_SMT_VMADOT3SU, MASK_SMT_VMADOT3SU,    match_opcode, 0},
>> +{"smt.vmadot3us", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt",
>>  MATCH_SMT_VMADOT3US_I8, MASK_SMT_VMADOT3US_I8, match_opcode,
>> INSN_ALIAS },
>> +{"smt.vmadot3us", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&8",
>> MATCH_SMT_VMADOT3US, MASK_SMT_VMADOT3US,    match_opcode, 0},
>> +
>>  /* Terminate the list.  */
>>  {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}
>>  };
>>

--
 - Michal Lach

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PING^3][v2] RISC-V: Add SpacemiT vendor extensions xsmtvdot
  2026-04-09 10:28 ` Michal Lach
@ 2026-04-09 11:37   ` Mark Zhuang
  2026-04-09 11:37     ` [PATCH] " Mark Zhuang
  0 siblings, 1 reply; 16+ messages in thread
From: Mark Zhuang @ 2026-04-09 11:37 UTC (permalink / raw)
  To: michal.lach
  Cc: binutils, amodra, jbeulich, nickc, palmer, andrew,
	jim.wilson.gcc, nelson.chu1990

Hi Michal,

Thank you for pointing out the HTML formatting issue. I apologize for
the confusion it may have caused.

My original patch submission was sent using git send-email,
but the subsequent PING replies were sent directly from my email client,
which inadvertently mixed in HTML formatting. When I reviewed the thread
at https://sourceware.org/pipermail/binutils/2026-April/148909.html, I
didn't notice the rendering issues, so I wasn't aware of the problem
until you mentioned it.

I'm very sorry for any inconvenience the HTML formatting may have caused.
I've now attached the clean patch below.

Best regards,
Mark Zhuang

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH] RISC-V: Add SpacemiT vendor extensions xsmtvdot
  2026-04-09 11:37   ` Mark Zhuang
@ 2026-04-09 11:37     ` Mark Zhuang
  2026-04-09 12:21       ` Jan Beulich
  0 siblings, 1 reply; 16+ messages in thread
From: Mark Zhuang @ 2026-04-09 11:37 UTC (permalink / raw)
  To: michal.lach
  Cc: binutils, amodra, jbeulich, nickc, palmer, andrew,
	jim.wilson.gcc, nelson.chu1990, Mark Zhuang, Link

From: Mark Zhuang <mark.zhuang@spacemit.com>

SpacemiT defines Intrinsic Matrix Extension (IME) specification [1].
SpacemiT X60 implement version 1.0 of the SpacemiT Vector Dot Product Extension (XsmtVdot v1.0) [2],
it is a subset of the full IME specification

[1] https://github.com/spacemit-com/riscv-ime-extension-spec/releases/download/v1.0/spacemit-ime-asciidoc.pdf
[2] https://developer.spacemit.com/documentation?token=BWbGwbx7liGW21kq9lucSA6Vnpb#2.1

Co-authored-by: Link <xuqian@spacemit.com>
---
 bfd/elfxx-riscv.c                         |  7 +++
 gas/NEWS                                  |  3 +
 gas/config/tc-riscv.c                     | 71 +++++++++++++++++++++
 gas/doc/c-riscv.texi                      |  7 +++
 gas/testsuite/gas/riscv/march-help.l      |  1 +
 gas/testsuite/gas/riscv/x-smt-vdot-fail.l |  3 +
 gas/testsuite/gas/riscv/x-smt-vdot-fail.s | 46 ++++++++++++++
 gas/testsuite/gas/riscv/x-smt-vdot.d      | 41 +++++++++++++
 gas/testsuite/gas/riscv/x-smt-vdot.s      | 33 ++++++++++
 include/opcode/riscv-opc.h                | 75 +++++++++++++++++++++++
 include/opcode/riscv.h                    | 10 +++
 opcodes/riscv-dis.c                       | 33 ++++++++++
 opcodes/riscv-opc.c                       | 45 ++++++++++++++
 13 files changed, 375 insertions(+)
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-fail.l
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-fail.s
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot.d
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot.s

diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index ee962b4f6f1..ea24a68b895 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1229,6 +1229,8 @@ static const struct riscv_implicit_subset riscv_implicit_subsets[] =
   {"xtheadvector", "+zicsr", check_implicit_always},
   {"xtheadzvamo", "+zaamo", check_implicit_always},
 
+  {"xsmtvdot", "+zve32x", check_implicit_always},
+
   {"v", "+zve64d,+zvl128b", check_implicit_always},
   {"zvfh", "+zvfhmin,+zfhmin", check_implicit_always},
   {"zvfhmin", "+zve32f", check_implicit_always},
@@ -1644,6 +1646,7 @@ static const struct riscv_supported_ext riscv_supported_vendor_x_ext[] =
   {"xmipscmov",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
   {"xmipsexectl",	ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
   {"xmipslsp",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
+  {"xsmtvdot",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
   {NULL, 0, 0, 0, 0}
 };
 
@@ -3062,6 +3065,8 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
       return riscv_subset_supports (rps, "xmipsexectl");
     case INSN_CLASS_XMIPSLSP:
       return riscv_subset_supports (rps, "xmipslsp");
+    case INSN_CLASS_XSMTVDOT:
+      return riscv_subset_supports (rps, "xsmtvdot");
     default:
       rps->error_handler
         (_("internal: unreachable INSN_CLASS_*"));
@@ -3365,6 +3370,8 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
       return "xsfvqmaccdod";
     case INSN_CLASS_XSFVFNRCLIPXFQF:
       return "xsfvfnrclipxfqf";
+    case INSN_CLASS_XSMTVDOT:
+      return "xsmtvdot";
     default:
       rps->error_handler
         (_("internal: unreachable INSN_CLASS_*"));
diff --git a/gas/NEWS b/gas/NEWS
index e384d1135c0..123872e7c02 100644
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -17,6 +17,9 @@ Changes in 2.46:
 * Add support for RISC-V standard extensions:
   sdtrig v1.0, ssstrict v1.0.
 
+* Add support for RISC-V vendor extensions:
+  SpacemiT: xsmtvdot v1.0.
+
 * The assembler now supports generating SFrame Version 3 format.  This version
   supports .text > 2 GiB, support for marking outermost frames, support for
   marking signal trampolines, and support for "flexible" frames which have
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 6bcf53832a0..25cafd83a95 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -1771,6 +1771,29 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
 		    goto unknown_validate_operand;
 		}
 		break;
+	    case 'p': /* Vendor-specific (SpacemiT) operands.  */
+		switch (*++oparg)
+		{
+		  case 'V':
+		    switch (*++oparg)
+			  {
+			  case 'd': USE_BITS (OP_MASK_SPACEMIT_IME_VD, OP_SH_SPACEMIT_IME_VD); break;
+			  case 's': USE_BITS (OP_MASK_SPACEMIT_IME_VS1, OP_SH_SPACEMIT_IME_VS1); break;
+			  default:
+			    goto unknown_validate_operand;
+			  }
+			  break;
+		  case 'w': /* Xpw&S ... bits in S indicates whether corresponding item is permitted.  */
+		    if (*++oparg != '&')
+		      goto unknown_validate_operand;
+		    strtol (oparg + 1, (char **)&oparg, 16);
+		    oparg--;
+		    USE_BITS (OP_MASK_SPACEMIT_IME_WI, OP_SH_SPACEMIT_IME_WI);
+		    break;
+		  default:
+		    goto unknown_validate_operand;
+		}
+		break;
 	    default:
 	      goto unknown_validate_operand;
 	    }
@@ -4287,6 +4310,54 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 		    }
 		  break;
 
+		case 'p': /* Vendor-specific (SpacemiT) operands.  */
+		  {
+		  size_t n;
+		  switch (*++oparg)
+		    {
+		    case 'V':
+		      switch (*++oparg)
+		      {
+			    case 'd':
+			      if (!reg_lookup (&asarg, RCLASS_VECR, &regno))
+				    break;
+			      if ((regno & 0x1) != 0)
+			      {
+				    error.msg = _("illegal operands (vd must be even)");
+				    break;
+			      }
+			      INSERT_OPERAND (SPACEMIT_IME_VD, *ip, regno>>1);
+			      continue;
+			    case 's':
+			      if (!reg_lookup (&asarg, RCLASS_VECR, &regno))
+				    break;
+			      if ((regno & 0x1) != 0)
+			      {
+				    error.msg = _("illegal operands (vs1 must be even)");
+				    break;
+			      }
+			      INSERT_OPERAND (SPACEMIT_IME_VS1, *ip, regno>>1);
+			      continue;
+			    default:
+			      goto unknown_riscv_ip_operand;
+		      }
+		      break;
+		    case 'w': /* Xpw&S ... bits in S indicates whether corresponding item is permitted.  */
+		      if (*++oparg != '&')
+			    goto unknown_riscv_ip_operand;
+		      n = strtol (oparg + 1, (char **)&oparg, 16);
+		      oparg--;
+		      if (!arg_lookup (&asarg, riscv_smt_wi, ARRAY_SIZE (riscv_smt_wi), &regno))
+			    break;
+		      if ((n & (1 << regno)) == 0)
+			    break;
+		      INSERT_OPERAND (SPACEMIT_IME_WI, *ip, regno);
+		      continue;
+		    default:
+		      goto unknown_riscv_ip_operand;
+		    }
+		  }
+		  break;
 		default:
 		  goto unknown_riscv_ip_operand;
 		}
diff --git a/gas/doc/c-riscv.texi b/gas/doc/c-riscv.texi
index c6c4081c204..88dd1de4aea 100644
--- a/gas/doc/c-riscv.texi
+++ b/gas/doc/c-riscv.texi
@@ -918,4 +918,11 @@ The XMipsSlsp extension provides instructions mips.ldp, mips.lwp, mips.sdp and m
 
 It is documented in @url{https://mips.com/wp-content/uploads/2025/03/P8700-F_Programmers_Reference_Manual_Rev1.82_3-19-2025.pdf}.
 
+@item XSmtVdot
+The XSmtVdot extension provides instructions for vector dot.
+
+SpacemiT defines Intrinsic Matrix Extension (IME) specification, documented in @url{https://github.com/spacemit-com/riscv-ime-extension-spec/releases/download/v1.0/spacemit-ime-asciidoc.pdf}.
+SpacemiT X60 implement version 1.0 of the SpacemiT Vector Dot Product Extension (XsmtVdot v1.0),
+it is a subset of the full IME specification, documented in @url{https://developer.spacemit.com/documentation?token=BWbGwbx7liGW21kq9lucSA6Vnpb#2.1}.
+
 @end table
diff --git a/gas/testsuite/gas/riscv/march-help.l b/gas/testsuite/gas/riscv/march-help.l
index 0ce2f896735..6e52669e9a4 100644
--- a/gas/testsuite/gas/riscv/march-help.l
+++ b/gas/testsuite/gas/riscv/march-help.l
@@ -186,3 +186,4 @@ All available -march extensions for RISC-V:
 	xmipscmov                               1.0
 	xmipsexectl                             1.0
 	xmipslsp                                1.0
+	xsmtvdot                                1.0
diff --git a/gas/testsuite/gas/riscv/x-smt-vdot-fail.l b/gas/testsuite/gas/riscv/x-smt-vdot-fail.l
new file mode 100644
index 00000000000..6e846b401e1
--- /dev/null
+++ b/gas/testsuite/gas/riscv/x-smt-vdot-fail.l
@@ -0,0 +1,3 @@
+#as: -march=rv64gcv_xsmtvdot
+#source: x-smt-vdot-fail.s
+#error_output: x-smt-vdot-fail.l
diff --git a/gas/testsuite/gas/riscv/x-smt-vdot-fail.s b/gas/testsuite/gas/riscv/x-smt-vdot-fail.s
new file mode 100644
index 00000000000..77399a7fdde
--- /dev/null
+++ b/gas/testsuite/gas/riscv/x-smt-vdot-fail.s
@@ -0,0 +1,46 @@
+target:
+	smt.vmadot v1, v3, v4
+	smt.vmadotu v1, v3, v4
+	smt.vmadotsu v1, v3, v4
+	smt.vmadotus v1, v3, v4
+	smt.vmadot1u v1, v4, v5
+	smt.vmadot1 v1, v4, v5
+	smt.vmadot1su v1, v4, v5
+	smt.vmadot1us v1, v4, v5
+	smt.vmadot2u v1, v4, v5
+	smt.vmadot2 v1, v4, v5
+	smt.vmadot2su v1, v4, v5
+	smt.vmadot2us v1, v4, v5
+	smt.vmadot3u v1, v4, v5
+	smt.vmadot3 v1, v4, v5
+	smt.vmadot3su v1, v4, v5
+	smt.vmadot3us v1, v4, v5
+	smt.vmadot1u v2, v3, v5
+	smt.vmadot1 v2, v3, v5
+	smt.vmadot1su v2, v3, v5
+	smt.vmadot1us v2, v3, v5
+	smt.vmadot2u v2, v3, v5
+	smt.vmadot2 v2, v3, v5
+	smt.vmadot2su v2, v3, v5
+	smt.vmadot2us v2, v3, v5
+	smt.vmadot3u v2, v3, v5
+	smt.vmadot3 v2, v3, v5
+	smt.vmadot3su v2, v3, v5
+	smt.vmadot3us v2, v3, v5
+	smt.vmadot v2, v3, v4, i4
+	smt.vmadotu v2, v3, v4, i4
+	smt.vmadotsu v2, v3, v4, i4
+	smt.vmadotus v2, v3, v4, i4
+	smt.vmadot1u v2, v4, v5, i4
+	smt.vmadot1 v2, v4, v5, i4
+	smt.vmadot1su v2, v4, v5, i4
+	smt.vmadot1us v2, v4, v5, i4
+	smt.vmadot2u v2, v4, v5, i4
+	smt.vmadot2 v2, v4, v5, i4
+	smt.vmadot2su v2, v4, v5, i4
+	smt.vmadot2us v2, v4, v5, i4
+	smt.vmadot3u v2, v4, v5, i4
+	smt.vmadot3 v2, v4, v5, i4
+	smt.vmadot3su v2, v4, v5, i4
+	smt.vmadot3us v2, v4, v5, i4
+
diff --git a/gas/testsuite/gas/riscv/x-smt-vdot.d b/gas/testsuite/gas/riscv/x-smt-vdot.d
new file mode 100644
index 00000000000..6f86236785d
--- /dev/null
+++ b/gas/testsuite/gas/riscv/x-smt-vdot.d
@@ -0,0 +1,41 @@
+#as: -march=rv64gcv_xsmtvdot
+#objdump: -dr
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+e241b12b[ 	]+smt.vmadot[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e241812b[ 	]+smt.vmadotu[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e241a12b[ 	]+smt.vmadotsu[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e241912b[ 	]+smt.vmadotus[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e652012b[ 	]+smt.vmadot1u[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652312b[ 	]+smt.vmadot1[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652212b[ 	]+smt.vmadot1su[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652112b[ 	]+smt.vmadot1us[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652412b[ 	]+smt.vmadot2u[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652712b[ 	]+smt.vmadot2[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652612b[ 	]+smt.vmadot2su[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652512b[ 	]+smt.vmadot2us[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652812b[ 	]+smt.vmadot3u[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652b12b[ 	]+smt.vmadot3[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652a12b[ 	]+smt.vmadot3su[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652912b[ 	]+smt.vmadot3us[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e241b12b[ 	]+smt.vmadot[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e241812b[ 	]+smt.vmadotu[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e241a12b[ 	]+smt.vmadotsu[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e241912b[ 	]+smt.vmadotus[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e652012b[ 	]+smt.vmadot1u[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652312b[ 	]+smt.vmadot1[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652212b[ 	]+smt.vmadot1su[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652112b[ 	]+smt.vmadot1us[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652412b[ 	]+smt.vmadot2u[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652712b[ 	]+smt.vmadot2[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652612b[ 	]+smt.vmadot2su[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652512b[ 	]+smt.vmadot2us[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652812b[ 	]+smt.vmadot3u[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652b12b[ 	]+smt.vmadot3[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652a12b[ 	]+smt.vmadot3su[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652912b[ 	]+smt.vmadot3us[ 	]+v2,v4,v5
diff --git a/gas/testsuite/gas/riscv/x-smt-vdot.s b/gas/testsuite/gas/riscv/x-smt-vdot.s
new file mode 100644
index 00000000000..a9991de4fc3
--- /dev/null
+++ b/gas/testsuite/gas/riscv/x-smt-vdot.s
@@ -0,0 +1,33 @@
+target:
+	smt.vmadot v2, v3, v4
+	smt.vmadotu v2, v3, v4
+	smt.vmadotsu v2, v3, v4
+	smt.vmadotus v2, v3, v4
+	smt.vmadot1u v2, v4, v5
+	smt.vmadot1 v2, v4, v5
+	smt.vmadot1su v2, v4, v5
+	smt.vmadot1us v2, v4, v5
+	smt.vmadot2u v2, v4, v5
+	smt.vmadot2 v2, v4, v5
+	smt.vmadot2su v2, v4, v5
+	smt.vmadot2us v2, v4, v5
+	smt.vmadot3u v2, v4, v5
+	smt.vmadot3 v2, v4, v5
+	smt.vmadot3su v2, v4, v5
+	smt.vmadot3us v2, v4, v5
+	smt.vmadot v2, v3, v4, i8
+	smt.vmadotu v2, v3, v4, i8
+	smt.vmadotsu v2, v3, v4, i8
+	smt.vmadotus v2, v3, v4, i8
+	smt.vmadot1u v2, v4, v5, i8
+	smt.vmadot1 v2, v4, v5, i8
+	smt.vmadot1su v2, v4, v5, i8
+	smt.vmadot1us v2, v4, v5, i8
+	smt.vmadot2u v2, v4, v5, i8
+	smt.vmadot2 v2, v4, v5, i8
+	smt.vmadot2su v2, v4, v5, i8
+	smt.vmadot2us v2, v4, v5, i8
+	smt.vmadot3u v2, v4, v5, i8
+	smt.vmadot3 v2, v4, v5, i8
+	smt.vmadot3su v2, v4, v5, i8
+	smt.vmadot3us v2, v4, v5, i8
diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
index 6f2775c6152..5a004622c2c 100644
--- a/include/opcode/riscv-opc.h
+++ b/include/opcode/riscv-opc.h
@@ -3852,6 +3852,81 @@
 #define MASK_MIPS_PAUSE  0xffffffff
 #define MATCH_MIPS_PREF 0x0000000b
 #define MASK_MIPS_PREF 0xe000707f
+/* SpacemiT custom instruction.  */
+/* Int Matrix Multiplicative Accumulation */
+#define MATCH_SMT_VMADOT_I8   0xe200302b
+#define MASK_SMT_VMADOT_I8    0xfe0070ff
+#define MATCH_SMT_VMADOTU_I8  0xe200002b
+#define MASK_SMT_VMADOTU_I8   0xfe0070ff
+#define MATCH_SMT_VMADOTSU_I8 0xe200202b
+#define MASK_SMT_VMADOTSU_I8  0xfe0070ff
+#define MATCH_SMT_VMADOTUS_I8 0xe200102b
+#define MASK_SMT_VMADOTUS_I8  0xfe0070ff
+/* Int Sliding Window Multiplicative Accumulation */
+/* Sliding Value = 1 */
+#define MATCH_SMT_VMADOT1U_I8 0xe600002b
+#define MASK_SMT_VMADOT1U_I8  0xfe00f0ff
+#define MATCH_SMT_VMADOT1_I8    0xe600302b
+#define MASK_SMT_VMADOT1_I8     0xfe00f0ff
+#define MATCH_SMT_VMADOT1SU_I8  0xe600202b
+#define MASK_SMT_VMADOT1SU_I8   0xfe00f0ff
+#define MATCH_SMT_VMADOT1US_I8  0xe600102b
+#define MASK_SMT_VMADOT1US_I8   0xfe00f0ff
+/* Sliding Value = 2 */
+#define MATCH_SMT_VMADOT2U_I8   0xe600402b
+#define MASK_SMT_VMADOT2U_I8    0xfe00f0ff
+#define MATCH_SMT_VMADOT2_I8    0xe600702b
+#define MASK_SMT_VMADOT2_I8     0xfe00f0ff
+#define MATCH_SMT_VMADOT2SU_I8  0xe600602b
+#define MASK_SMT_VMADOT2SU_I8   0xfe00f0ff
+#define MATCH_SMT_VMADOT2US_I8  0xe600502b
+#define MASK_SMT_VMADOT2US_I8   0xfe00f0ff
+/* Sliding Value = 3 */
+#define MATCH_SMT_VMADOT3U_I8   0xe600802b
+#define MASK_SMT_VMADOT3U_I8    0xfe00f0ff
+#define MATCH_SMT_VMADOT3_I8    0xe600b02b
+#define MASK_SMT_VMADOT3_I8     0xfe00f0ff
+#define MATCH_SMT_VMADOT3SU_I8  0xe600a02b
+#define MASK_SMT_VMADOT3SU_I8   0xfe00f0ff
+#define MATCH_SMT_VMADOT3US_I8  0xe600902b
+#define MASK_SMT_VMADOT3US_I8   0xfe00f0ff
+/* Int Matrix Multiplicative Accumulation */
+#define MATCH_SMT_VMADOT   0x8200302b
+#define MASK_SMT_VMADOT    0x9e0070ff
+#define MATCH_SMT_VMADOTU  0x8200002b
+#define MASK_SMT_VMADOTU   0x9e0070ff
+#define MATCH_SMT_VMADOTSU 0x8200202b
+#define MASK_SMT_VMADOTSU  0x9e0070ff
+#define MATCH_SMT_VMADOTUS 0x8200102b
+#define MASK_SMT_VMADOTUS  0x9e0070ff
+/* Int Sliding Window Multiplicative Accumulation */
+/* Sliding Value = 1 */
+#define MATCH_SMT_VMADOT1U 0x8600002b
+#define MASK_SMT_VMADOT1U  0x9e00f0ff
+#define MATCH_SMT_VMADOT1  0x8600302b
+#define MASK_SMT_VMADOT1   0x9e00f0ff
+#define MATCH_SMT_VMADOT1SU 0x8600202b
+#define MASK_SMT_VMADOT1SU 0x9e00f0ff
+#define MATCH_SMT_VMADOT1US 0x8600102b
+#define MASK_SMT_VMADOT1US 0x9e00f0ff
+/* Sliding Value = 2 */
+#define MATCH_SMT_VMADOT2U 0x8600402b
+#define MASK_SMT_VMADOT2U 0x9e00f0ff
+#define MATCH_SMT_VMADOT2 0x8600702b
+#define MASK_SMT_VMADOT2 0x9e00f0ff
+#define MATCH_SMT_VMADOT2SU 0x8600602b
+#define MASK_SMT_VMADOT2SU 0x9e00f0ff
+#define MATCH_SMT_VMADOT2US 0x8600502b
+#define MASK_SMT_VMADOT2US 0x9e00f0ff
+/* Sliding Value = 3 */
+#define MATCH_SMT_VMADOT3U 0x8600802b
+#define MASK_SMT_VMADOT3U 0x9e00f0ff
+#define MATCH_SMT_VMADOT3 0x8600b02b
+#define MASK_SMT_VMADOT3 0x9e00f0ff
+#define MATCH_SMT_VMADOT3SU 0x8600a02b
+#define MASK_SMT_VMADOT3SU 0x9e00f0ff
+#define MATCH_SMT_VMADOT3US 0x8600902b
+#define MASK_SMT_VMADOT3US 0x9e00f0ff
 /* Unprivileged Counter/Timers CSR addresses.  */
 #define CSR_CYCLE 0xc00
 #define CSR_TIME 0xc01
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index de105f5df8b..7a7b998b913 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -419,6 +419,14 @@ static inline unsigned int riscv_insn_length (insn_t insn)
 #define OP_MASK_MIPS_SDP_OFFSET25   0x3
 #define OP_SH_MIPS_SDP_OFFSET25     25
 
+/* SpacemiT fields */
+#define OP_MASK_SPACEMIT_IME_VD		0xf
+#define OP_SH_SPACEMIT_IME_VD		8
+#define OP_MASK_SPACEMIT_IME_VS1	0xf
+#define OP_SH_SPACEMIT_IME_VS1		16
+#define OP_MASK_SPACEMIT_IME_WI		0x3
+#define OP_SH_SPACEMIT_IME_WI		29
+
 /* ABI names for selected x-registers.  */
 
 #define X_ZERO 0
@@ -606,6 +614,7 @@ enum riscv_insn_class
   INSN_CLASS_XMIPSCMOV,
   INSN_CLASS_XMIPSEXECTL,
   INSN_CLASS_XMIPSLSP,
+  INSN_CLASS_XSMTVDOT,
 };
 
 /* This structure holds information for a particular instruction.  */
@@ -726,6 +735,7 @@ extern const char * const riscv_th_vlen[4];
 extern const char * const riscv_th_vediv[4];
 extern const char * const riscv_fli_symval[32];
 extern const float riscv_fli_numval[32];
+extern const char * const riscv_smt_wi[4];
 
 extern const struct riscv_opcode riscv_opcodes[];
 extern const struct riscv_opcode riscv_insn_types[];
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index 03c8cf1e344..6df1441d48c 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -917,6 +917,39 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 		  goto undefined_modifier;
 		}
 	      break;
+	    case 'p': /* Vendor-specific (SpacemiT) operands.  */
+		  {
+	      switch (*++oparg)
+		  {
+		  case 'V':
+		    switch (*++oparg)
+		      {
+		      case 'd':
+			    print (info->stream, dis_style_register,  "%s",
+			      riscv_vecr_names_numeric[EXTRACT_OPERAND (SPACEMIT_IME_VD, l) * 2]);
+			    break;
+		      case 's':
+			    print (info->stream, dis_style_register,  "%s",
+			      riscv_vecr_names_numeric[EXTRACT_OPERAND (SPACEMIT_IME_VS1, l) * 2]);
+			    break;
+		      default:
+			    goto undefined_modifier;
+		      }
+		    break;
+		  case 'w': /* Xpw&S ... bits in S indicates whether corresponding item is permitted.  */
+			if (*++oparg != '&')
+			  goto undefined_modifier;
+			strtol (oparg + 1, (char **)&oparg, 16);
+		    oparg--;
+			print (info->stream, dis_style_register, "%s",
+				riscv_smt_wi[EXTRACT_OPERAND (SPACEMIT_IME_WI, l)]);
+			  break;
+		  default:
+		    goto undefined_modifier;
+		  }
+			break;
+		  }
+	      break;
 	    default:
 	      goto undefined_modifier;
 	    }
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 54887c97880..8b81dda2008 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -122,6 +122,12 @@ const char * const riscv_th_vediv[4] =
     "d1", "d2", "d4", "d8"
 };
 
+/* XSmtVdot, List of int type width constants.  */
+const char * const riscv_smt_wi[4] =
+{
+    "i2", "i16", "i4", "i8"
+};
+
 /* The FLI.[HSDQ] symbolic constants (NULL for numeric constant).  */
 const char * const riscv_fli_symval[32] =
 {
@@ -3579,6 +3585,45 @@ const struct riscv_opcode riscv_opcodes[] =
 {"mips.sdp", 0, INSN_CLASS_XMIPSLSP, "t,r,Xm^(s)", MATCH_MIPS_SDP, MASK_MIPS_SDP, match_opcode, 0 },
 {"mips.swp", 0, INSN_CLASS_XMIPSLSP, "t,r,Xm&(s)", MATCH_MIPS_SWP, MASK_MIPS_SWP, match_opcode, 0 },
 
+/* SpacemiT custom instructions. */
+/* Int Matrix Multi-Accumulation */
+{"smt.vmadot",   0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,Vt",       MATCH_SMT_VMADOT_I8,   MASK_SMT_VMADOT_I8,   match_opcode, INSN_ALIAS },
+{"smt.vmadot",   0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,Vt,Xpw&8", MATCH_SMT_VMADOT,      MASK_SMT_VMADOT,      match_opcode, 0 },
+{"smt.vmadotu",  0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,Vt",       MATCH_SMT_VMADOTU_I8,  MASK_SMT_VMADOTU_I8,  match_opcode, INSN_ALIAS },
+{"smt.vmadotu",  0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,Vt,Xpw&8", MATCH_SMT_VMADOTU,     MASK_SMT_VMADOTU,     match_opcode, 0 },
+{"smt.vmadotsu", 0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,Vt",       MATCH_SMT_VMADOTSU_I8, MASK_SMT_VMADOTSU_I8, match_opcode, INSN_ALIAS },
+{"smt.vmadotsu", 0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,Vt,Xpw&8", MATCH_SMT_VMADOTSU,    MASK_SMT_VMADOTSU,    match_opcode, 0 },
+{"smt.vmadotus", 0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,Vt",       MATCH_SMT_VMADOTUS_I8, MASK_SMT_VMADOTUS_I8, match_opcode, INSN_ALIAS },
+{"smt.vmadotus", 0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,Vt,Xpw&8", MATCH_SMT_VMADOTUS,    MASK_SMT_VMADOTUS,    match_opcode, 0 },
+/* Int Sliding Window Multi-Accumulation */
+/* Sliding Value = 1 */
+{"smt.vmadot1u",  0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt",       MATCH_SMT_VMADOT1U_I8,  MASK_SMT_VMADOT1U_I8,  match_opcode, INSN_ALIAS },
+{"smt.vmadot1u",  0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&8", MATCH_SMT_VMADOT1U,     MASK_SMT_VMADOT1U,     match_opcode, 0 },
+{"smt.vmadot1",   0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt",       MATCH_SMT_VMADOT1_I8,   MASK_SMT_VMADOT1_I8,   match_opcode, INSN_ALIAS },
+{"smt.vmadot1",   0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&8", MATCH_SMT_VMADOT1,      MASK_SMT_VMADOT1,      match_opcode, 0 },
+{"smt.vmadot1su", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt",       MATCH_SMT_VMADOT1SU_I8, MASK_SMT_VMADOT1SU_I8, match_opcode, INSN_ALIAS },
+{"smt.vmadot1su", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&8", MATCH_SMT_VMADOT1SU,    MASK_SMT_VMADOT1SU,    match_opcode, 0 },
+{"smt.vmadot1us", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt",       MATCH_SMT_VMADOT1US_I8, MASK_SMT_VMADOT1US_I8, match_opcode, INSN_ALIAS },
+{"smt.vmadot1us", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&8", MATCH_SMT_VMADOT1US,    MASK_SMT_VMADOT1US,    match_opcode, 0 },
+/* Sliding Value = 2 */
+{"smt.vmadot2u",  0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt",       MATCH_SMT_VMADOT2U_I8,  MASK_SMT_VMADOT2U_I8,  match_opcode, INSN_ALIAS },
+{"smt.vmadot2u",  0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&8", MATCH_SMT_VMADOT2U,     MASK_SMT_VMADOT2U,     match_opcode, 0},
+{"smt.vmadot2",   0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt",       MATCH_SMT_VMADOT2_I8,   MASK_SMT_VMADOT2_I8,   match_opcode, INSN_ALIAS },
+{"smt.vmadot2",   0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&8", MATCH_SMT_VMADOT2,      MASK_SMT_VMADOT2,      match_opcode, 0},
+{"smt.vmadot2su", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt",       MATCH_SMT_VMADOT2SU_I8, MASK_SMT_VMADOT2SU_I8, match_opcode, INSN_ALIAS },
+{"smt.vmadot2su", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&8", MATCH_SMT_VMADOT2SU,    MASK_SMT_VMADOT2SU,    match_opcode, 0},
+{"smt.vmadot2us", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt",       MATCH_SMT_VMADOT2US_I8, MASK_SMT_VMADOT2US_I8, match_opcode, INSN_ALIAS },
+{"smt.vmadot2us", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&8", MATCH_SMT_VMADOT2US,    MASK_SMT_VMADOT2US,    match_opcode, 0},
+/* Sliding Value = 3 */
+{"smt.vmadot3u",  0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt",       MATCH_SMT_VMADOT3U_I8,  MASK_SMT_VMADOT3U_I8,  match_opcode, INSN_ALIAS },
+{"smt.vmadot3u",  0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&8", MATCH_SMT_VMADOT3U,     MASK_SMT_VMADOT3U,     match_opcode, 0},
+{"smt.vmadot3",   0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt",       MATCH_SMT_VMADOT3_I8,   MASK_SMT_VMADOT3_I8,   match_opcode, INSN_ALIAS },
+{"smt.vmadot3",   0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&8", MATCH_SMT_VMADOT3,      MASK_SMT_VMADOT3,      match_opcode, 0},
+{"smt.vmadot3su", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt",       MATCH_SMT_VMADOT3SU_I8, MASK_SMT_VMADOT3SU_I8, match_opcode, INSN_ALIAS },
+{"smt.vmadot3su", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&8", MATCH_SMT_VMADOT3SU,    MASK_SMT_VMADOT3SU,    match_opcode, 0},
+{"smt.vmadot3us", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt",       MATCH_SMT_VMADOT3US_I8, MASK_SMT_VMADOT3US_I8, match_opcode, INSN_ALIAS },
+{"smt.vmadot3us", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,Vt,Xpw&8", MATCH_SMT_VMADOT3US,    MASK_SMT_VMADOT3US,    match_opcode, 0},
+
 /* Terminate the list.  */
 {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}
 };
-- 
2.34.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] RISC-V: Add SpacemiT vendor extensions xsmtvdot
  2026-04-09 11:37     ` [PATCH] " Mark Zhuang
@ 2026-04-09 12:21       ` Jan Beulich
  2026-04-10 10:00         ` [PATCH v3 0/1] " Mark Zhuang
  0 siblings, 1 reply; 16+ messages in thread
From: Jan Beulich @ 2026-04-09 12:21 UTC (permalink / raw)
  To: Mark Zhuang
  Cc: binutils, amodra, nickc, palmer, andrew, jim.wilson.gcc,
	nelson.chu1990, Mark Zhuang, Link, michal.lach

On 09.04.2026 13:37, Mark Zhuang wrote:
> --- a/gas/NEWS
> +++ b/gas/NEWS
> @@ -17,6 +17,9 @@ Changes in 2.46:
>  * Add support for RISC-V standard extensions:
>    sdtrig v1.0, ssstrict v1.0.
>  
> +* Add support for RISC-V vendor extensions:
> +  SpacemiT: xsmtvdot v1.0.
> +
>  * The assembler now supports generating SFrame Version 3 format.  This version
>    supports .text > 2 GiB, support for marking outermost frames, support for
>    marking signal trampolines, and support for "flexible" frames which have

This clearly is in need of adjustment. 2.46 has already gone out.

> --- a/gas/config/tc-riscv.c
> +++ b/gas/config/tc-riscv.c
> @@ -1771,6 +1771,29 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
>  		    goto unknown_validate_operand;
>  		}
>  		break;
> +	    case 'p': /* Vendor-specific (SpacemiT) operands.  */
> +		switch (*++oparg)
> +		{
> +		  case 'V':
> +		    switch (*++oparg)
> +			  {
> +			  case 'd': USE_BITS (OP_MASK_SPACEMIT_IME_VD, OP_SH_SPACEMIT_IME_VD); break;
> +			  case 's': USE_BITS (OP_MASK_SPACEMIT_IME_VS1, OP_SH_SPACEMIT_IME_VS1); break;
> +			  default:
> +			    goto unknown_validate_operand;
> +			  }
> +			  break;
> +		  case 'w': /* Xpw&S ... bits in S indicates whether corresponding item is permitted.  */
> +		    if (*++oparg != '&')
> +		      goto unknown_validate_operand;
> +		    strtol (oparg + 1, (char **)&oparg, 16);
> +		    oparg--;
> +		    USE_BITS (OP_MASK_SPACEMIT_IME_WI, OP_SH_SPACEMIT_IME_WI);
> +		    break;
> +		  default:
> +		    goto unknown_validate_operand;
> +		}
> +		break;
>  	    default:
>  	      goto unknown_validate_operand;
>  	    }

There look to be issues with indentation and line length throughout here. And
more further down, including in disassembler code.

> --- a/opcodes/riscv-opc.c
> +++ b/opcodes/riscv-opc.c
> @@ -122,6 +122,12 @@ const char * const riscv_th_vediv[4] =
>      "d1", "d2", "d4", "d8"
>  };
>  
> +/* XSmtVdot, List of int type width constants.  */
> +const char * const riscv_smt_wi[4] =
> +{
> +    "i2", "i16", "i4", "i8"
> +};

Do you really need to use arg_lookup() for these, and hence do you really need
this table (requiring more space for the pointers than for the actual strings
pointed to)?

> @@ -3579,6 +3585,45 @@ const struct riscv_opcode riscv_opcodes[] =
>  {"mips.sdp", 0, INSN_CLASS_XMIPSLSP, "t,r,Xm^(s)", MATCH_MIPS_SDP, MASK_MIPS_SDP, match_opcode, 0 },
>  {"mips.swp", 0, INSN_CLASS_XMIPSLSP, "t,r,Xm&(s)", MATCH_MIPS_SWP, MASK_MIPS_SWP, match_opcode, 0 },
>  
> +/* SpacemiT custom instructions. */
> +/* Int Matrix Multi-Accumulation */
> +{"smt.vmadot",   0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,Vt",       MATCH_SMT_VMADOT_I8,   MASK_SMT_VMADOT_I8,   match_opcode, INSN_ALIAS },
> +{"smt.vmadot",   0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,Vt,Xpw&8", MATCH_SMT_VMADOT,      MASK_SMT_VMADOT,      match_opcode, 0 },

Rather than having two entries each, can't you handle to Xpw&8 operand as an
optional one, like is done for Vm (and I'm soon to submit a patch to do the
same for floating point rounding mode operands)? We shouldn't grow this ever
growing table more than necessary, imo.

Jan

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v3 0/1] RISC-V: Add SpacemiT vendor extensions xsmtvdot
  2026-04-09 12:21       ` Jan Beulich
@ 2026-04-10 10:00         ` Mark Zhuang
  2026-04-10 10:00           ` [PATCH v3 1/1] " Mark Zhuang
  0 siblings, 1 reply; 16+ messages in thread
From: Mark Zhuang @ 2026-04-10 10:00 UTC (permalink / raw)
  To: binutils; +Cc: jbeulich, nelson.chu1990

From: Mark Zhuang <mark.zhuang@spacemit.com>

Thanks Jan for the helpful review, the suggestions really improved things.

Changes in v3:
  - Fix gas/NEWS placement
  - Fix indentation, line length and comment style issues.
  - Drop riscv_smt_wi table, parse width specifiers inline.
  - Make Xpw&8 an optional operand, remove INSN_ALIAS duplicates.

Mark Zhuang (1):
  RISC-V: Add SpacemiT vendor extensions xsmtvdot

 bfd/elfxx-riscv.c                         |   7 ++
 gas/NEWS                                  |   3 +
 gas/config/tc-riscv.c                     | 106 ++++++++++++++++++++++
 gas/doc/c-riscv.texi                      |   7 ++
 gas/testsuite/gas/riscv/march-help.l      |   1 +
 gas/testsuite/gas/riscv/x-smt-vdot-fail.l |   3 +
 gas/testsuite/gas/riscv/x-smt-vdot-fail.s |  46 ++++++++++
 gas/testsuite/gas/riscv/x-smt-vdot.d      |  41 +++++++++
 gas/testsuite/gas/riscv/x-smt-vdot.s      |  33 +++++++
 include/opcode/riscv-opc.h                |  38 ++++++++
 include/opcode/riscv.h                    |   9 ++
 opcodes/riscv-dis.c                       |  59 ++++++++++++
 opcodes/riscv-opc.c                       |  23 +++++
 13 files changed, 376 insertions(+)
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-fail.l
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-fail.s
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot.d
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot.s

-- 
2.34.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v3 1/1] RISC-V: Add SpacemiT vendor extensions xsmtvdot
  2026-04-10 10:00         ` [PATCH v3 0/1] " Mark Zhuang
@ 2026-04-10 10:00           ` Mark Zhuang
  2026-04-10 10:25             ` Jan Beulich
  0 siblings, 1 reply; 16+ messages in thread
From: Mark Zhuang @ 2026-04-10 10:00 UTC (permalink / raw)
  To: binutils; +Cc: jbeulich, nelson.chu1990

From: Mark Zhuang <mark.zhuang@spacemit.com>

SpacemiT defines Intrinsic Matrix Extension (IME) specification [1].
SpacemiT X60 implement version 1.0 of the SpacemiT Vector Dot Product Extension (XsmtVdot v1.0) [2],
it is a subset of the full IME specification

[1] https://github.com/spacemit-com/riscv-ime-extension-spec/releases/download/v1.0/spacemit-ime-asciidoc.pdf
[2] https://github.com/spacemit-com/docs-chip/blob/main/en/key_stone/k1/k1_docs/k1_ds.md#spacemit-x60-risc-v-core

Co-authored-by: Link <xuqian@spacemit.com>
---
 bfd/elfxx-riscv.c                         |   7 ++
 gas/NEWS                                  |   3 +
 gas/config/tc-riscv.c                     | 106 ++++++++++++++++++++++
 gas/doc/c-riscv.texi                      |   7 ++
 gas/testsuite/gas/riscv/march-help.l      |   1 +
 gas/testsuite/gas/riscv/x-smt-vdot-fail.l |   3 +
 gas/testsuite/gas/riscv/x-smt-vdot-fail.s |  46 ++++++++++
 gas/testsuite/gas/riscv/x-smt-vdot.d      |  41 +++++++++
 gas/testsuite/gas/riscv/x-smt-vdot.s      |  33 +++++++
 include/opcode/riscv-opc.h                |  38 ++++++++
 include/opcode/riscv.h                    |   9 ++
 opcodes/riscv-dis.c                       |  59 ++++++++++++
 opcodes/riscv-opc.c                       |  23 +++++
 13 files changed, 376 insertions(+)
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-fail.l
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-fail.s
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot.d
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot.s

diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 83134f81c96..5fdbc1698af 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1229,6 +1229,8 @@ static const struct riscv_implicit_subset riscv_implicit_subsets[] =
   {"xtheadvector", "+zicsr", check_implicit_always},
   {"xtheadzvamo", "+zaamo", check_implicit_always},
 
+  {"xsmtvdot", "+zve32x", check_implicit_always},
+
   {"v", "+zve64d,+zvl128b", check_implicit_always},
   {"zvfh", "+zvfhmin,+zfhmin", check_implicit_always},
   {"zvfhmin", "+zve32f", check_implicit_always},
@@ -1644,6 +1646,7 @@ static const struct riscv_supported_ext riscv_supported_vendor_x_ext[] =
   {"xmipscmov",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
   {"xmipsexectl",	ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
   {"xmipslsp",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
+  {"xsmtvdot",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
   {NULL, 0, 0, 0, 0}
 };
 
@@ -3062,6 +3065,8 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
       return riscv_subset_supports (rps, "xmipsexectl");
     case INSN_CLASS_XMIPSLSP:
       return riscv_subset_supports (rps, "xmipslsp");
+    case INSN_CLASS_XSMTVDOT:
+      return riscv_subset_supports (rps, "xsmtvdot");
     default:
       rps->error_handler
         (_("internal: unreachable INSN_CLASS_*"));
@@ -3365,6 +3370,8 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
       return "xsfvqmaccdod";
     case INSN_CLASS_XSFVFNRCLIPXFQF:
       return "xsfvfnrclipxfqf";
+    case INSN_CLASS_XSMTVDOT:
+      return "xsmtvdot";
     default:
       rps->error_handler
         (_("internal: unreachable INSN_CLASS_*"));
diff --git a/gas/NEWS b/gas/NEWS
index e384d1135c0..e47d55b05dc 100644
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,5 +1,8 @@
 -*- text -*-
 
+* Add support for RISC-V vendor extensions:
+  SpacemiT: xsmtvdot v1.0.
+
 Changes in 2.46:
 
 * Add support for AMD Zen6 processor.
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index b00b530b0bd..9476b141111 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -1770,6 +1770,35 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
 		    goto unknown_validate_operand;
 		}
 		break;
+	    case 'p': /* Vendor-specific (SpacemiT) operands.  */
+	      switch (*++oparg)
+		{
+		case 'V':
+		  switch (*++oparg)
+		    {
+		    case 'd':
+		      USE_BITS (OP_MASK_SPACEMIT_IME_VD, OP_SH_SPACEMIT_IME_VD);
+		      break;
+		    case 's':
+		      USE_BITS (OP_MASK_SPACEMIT_IME_VS1, OP_SH_SPACEMIT_IME_VS1);
+		      break;
+		    default:
+		      goto unknown_validate_operand;
+		    }
+		  break;
+		case 'w':
+		  /* Xpw&S ... bits in S indicates whether corresponding
+		     item is permitted.  */
+		  if (*++oparg != '&')
+		    goto unknown_validate_operand;
+		  strtol (oparg + 1, (char **)&oparg, 16);
+		  oparg--;
+		  USE_BITS (OP_MASK_SPACEMIT_IME_WI, OP_SH_SPACEMIT_IME_WI);
+		  break;
+		default:
+		  goto unknown_validate_operand;
+		}
+	      break;
 	    default:
 	      goto unknown_validate_operand;
 	    }
@@ -4286,6 +4315,83 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 		    }
 		  break;
 
+		case 'p': /* Vendor-specific (SpacemiT) operands.  */
+		  switch (*++oparg)
+		    {
+		    case 'V':
+		      switch (*++oparg)
+			{
+			case 'd':
+			  if (!reg_lookup (&asarg, RCLASS_VECR, &regno))
+			    break;
+			  if ((regno & 0x1) != 0)
+			    {
+			      error.msg = _("illegal operands (vd must be even)");
+			      break;
+			    }
+			  INSERT_OPERAND (SPACEMIT_IME_VD, *ip, regno>>1);
+			  continue;
+			case 's':
+			  if (!reg_lookup (&asarg, RCLASS_VECR, &regno))
+			    break;
+			  if ((regno & 0x1) != 0)
+			    {
+			      error.msg = _("illegal operands (vs1 must be even)");
+			      break;
+			    }
+			  INSERT_OPERAND (SPACEMIT_IME_VS1, *ip, regno>>1);
+			  continue;
+			default:
+			  goto unknown_riscv_ip_operand;
+			}
+		      break;
+		    case 'w':
+		      /* Xpw&S ... bits in S indicates whether
+			 corresponding item is permitted.  */
+		      if (*++oparg != '&')
+			goto unknown_riscv_ip_operand;
+		      size_t n = strtol (oparg + 1, (char **)&oparg, 16);
+		      oparg--;
+		      /* Optional operand: if not present, default to i8.  */
+		      if (*asarg == '\0')
+			regno = 3;
+		      else if (*asarg == ',')
+			{
+			  asarg++;
+			  /* Parse width specifier inline.  */
+			  if (strncmp (asarg, "i2", 2) == 0)
+			    {
+			      regno = 0;
+			      asarg += 2;
+			    }
+			  else if (strncmp (asarg, "i16", 3) == 0)
+			    {
+			      regno = 1;
+			      asarg += 3;
+			    }
+			  else if (strncmp (asarg, "i4", 2) == 0)
+			    {
+			      regno = 2;
+			      asarg += 2;
+			    }
+			  else if (strncmp (asarg, "i8", 2) == 0)
+			    {
+			      regno = 3;
+			      asarg += 2;
+			    }
+			  else
+			    break;
+			}
+		      else
+			goto unknown_riscv_ip_operand;
+		      if ((n & (1 << regno)) == 0)
+			goto unknown_riscv_ip_operand;
+		      INSERT_OPERAND (SPACEMIT_IME_WI, *ip, regno);
+		      continue;
+		    default:
+		      goto unknown_riscv_ip_operand;
+		    }
+		  break;
 		default:
 		  goto unknown_riscv_ip_operand;
 		}
diff --git a/gas/doc/c-riscv.texi b/gas/doc/c-riscv.texi
index c6c4081c204..d928f76c014 100644
--- a/gas/doc/c-riscv.texi
+++ b/gas/doc/c-riscv.texi
@@ -918,4 +918,11 @@ The XMipsSlsp extension provides instructions mips.ldp, mips.lwp, mips.sdp and m
 
 It is documented in @url{https://mips.com/wp-content/uploads/2025/03/P8700-F_Programmers_Reference_Manual_Rev1.82_3-19-2025.pdf}.
 
+@item XSmtVdot
+The XSmtVdot extension provides instructions for vector dot.
+
+SpacemiT defines Intrinsic Matrix Extension (IME) specification, documented in @url{https://github.com/spacemit-com/riscv-ime-extension-spec/releases/download/v1.0/spacemit-ime-asciidoc.pdf}.
+SpacemiT X60 implement version 1.0 of the SpacemiT Vector Dot Product Extension (XsmtVdot v1.0),
+it is a subset of the full IME specification, documented in @url{https://github.com/spacemit-com/docs-chip/blob/main/en/key_stone/k1/k1_docs/k1_ds.md#spacemit-x60-risc-v-core}.
+
 @end table
diff --git a/gas/testsuite/gas/riscv/march-help.l b/gas/testsuite/gas/riscv/march-help.l
index 0ce2f896735..6e52669e9a4 100644
--- a/gas/testsuite/gas/riscv/march-help.l
+++ b/gas/testsuite/gas/riscv/march-help.l
@@ -186,3 +186,4 @@ All available -march extensions for RISC-V:
 	xmipscmov                               1.0
 	xmipsexectl                             1.0
 	xmipslsp                                1.0
+	xsmtvdot                                1.0
diff --git a/gas/testsuite/gas/riscv/x-smt-vdot-fail.l b/gas/testsuite/gas/riscv/x-smt-vdot-fail.l
new file mode 100644
index 00000000000..6e846b401e1
--- /dev/null
+++ b/gas/testsuite/gas/riscv/x-smt-vdot-fail.l
@@ -0,0 +1,3 @@
+#as: -march=rv64gcv_xsmtvdot
+#source: x-smt-vdot-fail.s
+#error_output: x-smt-vdot-fail.l
diff --git a/gas/testsuite/gas/riscv/x-smt-vdot-fail.s b/gas/testsuite/gas/riscv/x-smt-vdot-fail.s
new file mode 100644
index 00000000000..77399a7fdde
--- /dev/null
+++ b/gas/testsuite/gas/riscv/x-smt-vdot-fail.s
@@ -0,0 +1,46 @@
+target:
+	smt.vmadot v1, v3, v4
+	smt.vmadotu v1, v3, v4
+	smt.vmadotsu v1, v3, v4
+	smt.vmadotus v1, v3, v4
+	smt.vmadot1u v1, v4, v5
+	smt.vmadot1 v1, v4, v5
+	smt.vmadot1su v1, v4, v5
+	smt.vmadot1us v1, v4, v5
+	smt.vmadot2u v1, v4, v5
+	smt.vmadot2 v1, v4, v5
+	smt.vmadot2su v1, v4, v5
+	smt.vmadot2us v1, v4, v5
+	smt.vmadot3u v1, v4, v5
+	smt.vmadot3 v1, v4, v5
+	smt.vmadot3su v1, v4, v5
+	smt.vmadot3us v1, v4, v5
+	smt.vmadot1u v2, v3, v5
+	smt.vmadot1 v2, v3, v5
+	smt.vmadot1su v2, v3, v5
+	smt.vmadot1us v2, v3, v5
+	smt.vmadot2u v2, v3, v5
+	smt.vmadot2 v2, v3, v5
+	smt.vmadot2su v2, v3, v5
+	smt.vmadot2us v2, v3, v5
+	smt.vmadot3u v2, v3, v5
+	smt.vmadot3 v2, v3, v5
+	smt.vmadot3su v2, v3, v5
+	smt.vmadot3us v2, v3, v5
+	smt.vmadot v2, v3, v4, i4
+	smt.vmadotu v2, v3, v4, i4
+	smt.vmadotsu v2, v3, v4, i4
+	smt.vmadotus v2, v3, v4, i4
+	smt.vmadot1u v2, v4, v5, i4
+	smt.vmadot1 v2, v4, v5, i4
+	smt.vmadot1su v2, v4, v5, i4
+	smt.vmadot1us v2, v4, v5, i4
+	smt.vmadot2u v2, v4, v5, i4
+	smt.vmadot2 v2, v4, v5, i4
+	smt.vmadot2su v2, v4, v5, i4
+	smt.vmadot2us v2, v4, v5, i4
+	smt.vmadot3u v2, v4, v5, i4
+	smt.vmadot3 v2, v4, v5, i4
+	smt.vmadot3su v2, v4, v5, i4
+	smt.vmadot3us v2, v4, v5, i4
+
diff --git a/gas/testsuite/gas/riscv/x-smt-vdot.d b/gas/testsuite/gas/riscv/x-smt-vdot.d
new file mode 100644
index 00000000000..6f86236785d
--- /dev/null
+++ b/gas/testsuite/gas/riscv/x-smt-vdot.d
@@ -0,0 +1,41 @@
+#as: -march=rv64gcv_xsmtvdot
+#objdump: -dr
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+e241b12b[ 	]+smt.vmadot[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e241812b[ 	]+smt.vmadotu[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e241a12b[ 	]+smt.vmadotsu[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e241912b[ 	]+smt.vmadotus[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e652012b[ 	]+smt.vmadot1u[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652312b[ 	]+smt.vmadot1[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652212b[ 	]+smt.vmadot1su[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652112b[ 	]+smt.vmadot1us[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652412b[ 	]+smt.vmadot2u[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652712b[ 	]+smt.vmadot2[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652612b[ 	]+smt.vmadot2su[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652512b[ 	]+smt.vmadot2us[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652812b[ 	]+smt.vmadot3u[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652b12b[ 	]+smt.vmadot3[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652a12b[ 	]+smt.vmadot3su[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652912b[ 	]+smt.vmadot3us[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e241b12b[ 	]+smt.vmadot[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e241812b[ 	]+smt.vmadotu[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e241a12b[ 	]+smt.vmadotsu[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e241912b[ 	]+smt.vmadotus[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e652012b[ 	]+smt.vmadot1u[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652312b[ 	]+smt.vmadot1[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652212b[ 	]+smt.vmadot1su[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652112b[ 	]+smt.vmadot1us[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652412b[ 	]+smt.vmadot2u[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652712b[ 	]+smt.vmadot2[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652612b[ 	]+smt.vmadot2su[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652512b[ 	]+smt.vmadot2us[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652812b[ 	]+smt.vmadot3u[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652b12b[ 	]+smt.vmadot3[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652a12b[ 	]+smt.vmadot3su[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652912b[ 	]+smt.vmadot3us[ 	]+v2,v4,v5
diff --git a/gas/testsuite/gas/riscv/x-smt-vdot.s b/gas/testsuite/gas/riscv/x-smt-vdot.s
new file mode 100644
index 00000000000..a9991de4fc3
--- /dev/null
+++ b/gas/testsuite/gas/riscv/x-smt-vdot.s
@@ -0,0 +1,33 @@
+target:
+	smt.vmadot v2, v3, v4
+	smt.vmadotu v2, v3, v4
+	smt.vmadotsu v2, v3, v4
+	smt.vmadotus v2, v3, v4
+	smt.vmadot1u v2, v4, v5
+	smt.vmadot1 v2, v4, v5
+	smt.vmadot1su v2, v4, v5
+	smt.vmadot1us v2, v4, v5
+	smt.vmadot2u v2, v4, v5
+	smt.vmadot2 v2, v4, v5
+	smt.vmadot2su v2, v4, v5
+	smt.vmadot2us v2, v4, v5
+	smt.vmadot3u v2, v4, v5
+	smt.vmadot3 v2, v4, v5
+	smt.vmadot3su v2, v4, v5
+	smt.vmadot3us v2, v4, v5
+	smt.vmadot v2, v3, v4, i8
+	smt.vmadotu v2, v3, v4, i8
+	smt.vmadotsu v2, v3, v4, i8
+	smt.vmadotus v2, v3, v4, i8
+	smt.vmadot1u v2, v4, v5, i8
+	smt.vmadot1 v2, v4, v5, i8
+	smt.vmadot1su v2, v4, v5, i8
+	smt.vmadot1us v2, v4, v5, i8
+	smt.vmadot2u v2, v4, v5, i8
+	smt.vmadot2 v2, v4, v5, i8
+	smt.vmadot2su v2, v4, v5, i8
+	smt.vmadot2us v2, v4, v5, i8
+	smt.vmadot3u v2, v4, v5, i8
+	smt.vmadot3 v2, v4, v5, i8
+	smt.vmadot3su v2, v4, v5, i8
+	smt.vmadot3us v2, v4, v5, i8
diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
index 6f2775c6152..31b7e7a06a7 100644
--- a/include/opcode/riscv-opc.h
+++ b/include/opcode/riscv-opc.h
@@ -3852,6 +3852,44 @@
 #define MASK_MIPS_PAUSE  0xffffffff
 #define MATCH_MIPS_PREF 0x0000000b
 #define MASK_MIPS_PREF 0xe000707f
+/* SpacemiT custom instruction.  */
+/* Int Matrix Multiplicative Accumulation.  */
+#define MATCH_SMT_VMADOT   0x8200302b
+#define MASK_SMT_VMADOT    0x9e0070ff
+#define MATCH_SMT_VMADOTU  0x8200002b
+#define MASK_SMT_VMADOTU   0x9e0070ff
+#define MATCH_SMT_VMADOTSU 0x8200202b
+#define MASK_SMT_VMADOTSU  0x9e0070ff
+#define MATCH_SMT_VMADOTUS 0x8200102b
+#define MASK_SMT_VMADOTUS  0x9e0070ff
+/* Int Sliding Window Multiplicative Accumulation.  */
+/* Sliding Value = 1.  */
+#define MATCH_SMT_VMADOT1U 0x8600002b
+#define MASK_SMT_VMADOT1U  0x9e00f0ff
+#define MATCH_SMT_VMADOT1  0x8600302b
+#define MASK_SMT_VMADOT1   0x9e00f0ff
+#define MATCH_SMT_VMADOT1SU 0x8600202b
+#define MASK_SMT_VMADOT1SU 0x9e00f0ff
+#define MATCH_SMT_VMADOT1US 0x8600102b
+#define MASK_SMT_VMADOT1US 0x9e00f0ff
+/* Sliding Value = 2.  */
+#define MATCH_SMT_VMADOT2U 0x8600402b
+#define MASK_SMT_VMADOT2U 0x9e00f0ff
+#define MATCH_SMT_VMADOT2 0x8600702b
+#define MASK_SMT_VMADOT2 0x9e00f0ff
+#define MATCH_SMT_VMADOT2SU 0x8600602b
+#define MASK_SMT_VMADOT2SU 0x9e00f0ff
+#define MATCH_SMT_VMADOT2US 0x8600502b
+#define MASK_SMT_VMADOT2US 0x9e00f0ff
+/* Sliding Value = 3.  */
+#define MATCH_SMT_VMADOT3U 0x8600802b
+#define MASK_SMT_VMADOT3U 0x9e00f0ff
+#define MATCH_SMT_VMADOT3 0x8600b02b
+#define MASK_SMT_VMADOT3 0x9e00f0ff
+#define MATCH_SMT_VMADOT3SU 0x8600a02b
+#define MASK_SMT_VMADOT3SU 0x9e00f0ff
+#define MATCH_SMT_VMADOT3US 0x8600902b
+#define MASK_SMT_VMADOT3US 0x9e00f0ff
 /* Unprivileged Counter/Timers CSR addresses.  */
 #define CSR_CYCLE 0xc00
 #define CSR_TIME 0xc01
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index de105f5df8b..3a32abfcf3c 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -419,6 +419,14 @@ static inline unsigned int riscv_insn_length (insn_t insn)
 #define OP_MASK_MIPS_SDP_OFFSET25   0x3
 #define OP_SH_MIPS_SDP_OFFSET25     25
 
+/* SpacemiT fields.  */
+#define OP_MASK_SPACEMIT_IME_VD		0xf
+#define OP_SH_SPACEMIT_IME_VD		8
+#define OP_MASK_SPACEMIT_IME_VS1	0xf
+#define OP_SH_SPACEMIT_IME_VS1		16
+#define OP_MASK_SPACEMIT_IME_WI		0x3
+#define OP_SH_SPACEMIT_IME_WI		29
+
 /* ABI names for selected x-registers.  */
 
 #define X_ZERO 0
@@ -606,6 +614,7 @@ enum riscv_insn_class
   INSN_CLASS_XMIPSCMOV,
   INSN_CLASS_XMIPSEXECTL,
   INSN_CLASS_XMIPSLSP,
+  INSN_CLASS_XSMTVDOT,
 };
 
 /* This structure holds information for a particular instruction.  */
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index eda802ff420..45cec2cc07a 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -917,6 +917,65 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 		  goto undefined_modifier;
 		}
 	      break;
+	    case 'p': /* Vendor-specific (SpacemiT) operands.  */
+	      {
+		switch (*++oparg)
+		  {
+		  case 'V':
+		    switch (*++oparg)
+		      {
+		      case 'd':
+			unsigned vd = EXTRACT_OPERAND (SPACEMIT_IME_VD, l) * 2;
+			print (info->stream, dis_style_register, "%s",
+			       riscv_vecr_names_numeric[vd]);
+			break;
+		      case 's':
+			unsigned vs = EXTRACT_OPERAND (SPACEMIT_IME_VS1, l) * 2;
+			print (info->stream, dis_style_register, "%s",
+			       riscv_vecr_names_numeric[vs]);
+			break;
+		      default:
+			goto undefined_modifier;
+		      }
+		    break;
+		  case 'w':
+		    /* Xpw&S ... bits in S indicates whether corresponding
+		       item is permitted.  */
+		    if (*++oparg != '&')
+		      goto undefined_modifier;
+		    strtol (oparg + 1, (char **)&oparg, 16);
+		    oparg--;
+		    unsigned wi = EXTRACT_OPERAND (SPACEMIT_IME_WI, l);
+		    /* Only print if not the default value (i8 = 3).  */
+		    if (wi != 3)
+		      {
+			print (info->stream, dis_style_text, ",");
+			switch (wi)
+			  {
+			  case 0:
+			    print (info->stream, dis_style_text, "i2");
+			    break;
+			  case 1:
+			    print (info->stream, dis_style_text, "i16");
+			    break;
+			  case 2:
+			    print (info->stream, dis_style_text, "i4");
+			    break;
+			  case 3:
+			    print (info->stream, dis_style_text, "i8");
+			    break;
+			  default:
+			    print (info->stream, dis_style_immediate, "%u", wi);
+			      break;
+			  }
+		      }
+		    break;
+		  default:
+		    goto undefined_modifier;
+		  }
+		break;
+	      }
+	      break;
 	    default:
 	      goto undefined_modifier;
 	    }
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 54887c97880..ed2d7e4c4a0 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -3579,6 +3579,29 @@ const struct riscv_opcode riscv_opcodes[] =
 {"mips.sdp", 0, INSN_CLASS_XMIPSLSP, "t,r,Xm^(s)", MATCH_MIPS_SDP, MASK_MIPS_SDP, match_opcode, 0 },
 {"mips.swp", 0, INSN_CLASS_XMIPSLSP, "t,r,Xm&(s)", MATCH_MIPS_SWP, MASK_MIPS_SWP, match_opcode, 0 },
 
+/* SpacemiT custom instructions.  */
+/* Int Matrix Multi-Accumulation.  */
+{"smt.vmadot",   0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,VtXpw&8", MATCH_SMT_VMADOT, MASK_SMT_VMADOT, match_opcode, 0 },
+{"smt.vmadotu",  0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,VtXpw&8", MATCH_SMT_VMADOTU, MASK_SMT_VMADOTU, match_opcode, 0 },
+{"smt.vmadotsu", 0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,VtXpw&8", MATCH_SMT_VMADOTSU, MASK_SMT_VMADOTSU, match_opcode, 0 },
+{"smt.vmadotus", 0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,VtXpw&8", MATCH_SMT_VMADOTUS, MASK_SMT_VMADOTUS, match_opcode, 0 },
+/* Int Sliding Window Multi-Accumulation.  */
+/* Sliding Value = 1.  */
+{"smt.vmadot1u",  0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw&8", MATCH_SMT_VMADOT1U, MASK_SMT_VMADOT1U, match_opcode, 0 },
+{"smt.vmadot1",   0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw&8", MATCH_SMT_VMADOT1, MASK_SMT_VMADOT1, match_opcode, 0 },
+{"smt.vmadot1su", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw&8", MATCH_SMT_VMADOT1SU, MASK_SMT_VMADOT1SU, match_opcode, 0 },
+{"smt.vmadot1us", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw&8", MATCH_SMT_VMADOT1US, MASK_SMT_VMADOT1US, match_opcode, 0 },
+/* Sliding Value = 2.  */
+{"smt.vmadot2u",  0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw&8", MATCH_SMT_VMADOT2U, MASK_SMT_VMADOT2U, match_opcode, 0 },
+{"smt.vmadot2",   0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw&8", MATCH_SMT_VMADOT2, MASK_SMT_VMADOT2, match_opcode, 0 },
+{"smt.vmadot2su", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw&8", MATCH_SMT_VMADOT2SU, MASK_SMT_VMADOT2SU, match_opcode, 0 },
+{"smt.vmadot2us", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw&8", MATCH_SMT_VMADOT2US, MASK_SMT_VMADOT2US, match_opcode, 0 },
+/* Sliding Value = 3.  */
+{"smt.vmadot3u",  0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw&8", MATCH_SMT_VMADOT3U, MASK_SMT_VMADOT3U, match_opcode, 0 },
+{"smt.vmadot3",   0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw&8", MATCH_SMT_VMADOT3, MASK_SMT_VMADOT3, match_opcode, 0 },
+{"smt.vmadot3su", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw&8", MATCH_SMT_VMADOT3SU, MASK_SMT_VMADOT3SU, match_opcode, 0 },
+{"smt.vmadot3us", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw&8", MATCH_SMT_VMADOT3US, MASK_SMT_VMADOT3US, match_opcode, 0 },
+
 /* Terminate the list.  */
 {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}
 };
-- 
2.34.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v3 1/1] RISC-V: Add SpacemiT vendor extensions xsmtvdot
  2026-04-10 10:00           ` [PATCH v3 1/1] " Mark Zhuang
@ 2026-04-10 10:25             ` Jan Beulich
  2026-04-10 15:11               ` [PATCH v4 0/1] " Mark Zhuang
  0 siblings, 1 reply; 16+ messages in thread
From: Jan Beulich @ 2026-04-10 10:25 UTC (permalink / raw)
  To: Mark Zhuang; +Cc: nelson.chu1990, binutils

On 10.04.2026 12:00, Mark Zhuang wrote:
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/x-smt-vdot-fail.l
> @@ -0,0 +1,3 @@
> +#as: -march=rv64gcv_xsmtvdot
> +#source: x-smt-vdot-fail.s
> +#error_output: x-smt-vdot-fail.l

Doesn't this file need to be named x-smt-vdot-fail.d, for the test to be
executed at all? And isn't the real x-smt-vdot-fail.l missing?

> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/x-smt-vdot.s
> @@ -0,0 +1,33 @@
> +target:
> +	smt.vmadot v2, v3, v4
> +	smt.vmadotu v2, v3, v4
> +	smt.vmadotsu v2, v3, v4
> +	smt.vmadotus v2, v3, v4
> +	smt.vmadot1u v2, v4, v5
> +	smt.vmadot1 v2, v4, v5
> +	smt.vmadot1su v2, v4, v5
> +	smt.vmadot1us v2, v4, v5
> +	smt.vmadot2u v2, v4, v5
> +	smt.vmadot2 v2, v4, v5
> +	smt.vmadot2su v2, v4, v5
> +	smt.vmadot2us v2, v4, v5
> +	smt.vmadot3u v2, v4, v5
> +	smt.vmadot3 v2, v4, v5
> +	smt.vmadot3su v2, v4, v5
> +	smt.vmadot3us v2, v4, v5
> +	smt.vmadot v2, v3, v4, i8
> +	smt.vmadotu v2, v3, v4, i8
> +	smt.vmadotsu v2, v3, v4, i8
> +	smt.vmadotus v2, v3, v4, i8
> +	smt.vmadot1u v2, v4, v5, i8
> +	smt.vmadot1 v2, v4, v5, i8
> +	smt.vmadot1su v2, v4, v5, i8
> +	smt.vmadot1us v2, v4, v5, i8
> +	smt.vmadot2u v2, v4, v5, i8
> +	smt.vmadot2 v2, v4, v5, i8
> +	smt.vmadot2su v2, v4, v5, i8
> +	smt.vmadot2us v2, v4, v5, i8
> +	smt.vmadot3u v2, v4, v5, i8
> +	smt.vmadot3 v2, v4, v5, i8
> +	smt.vmadot3su v2, v4, v5, i8
> +	smt.vmadot3us v2, v4, v5, i8

Only i8 being tested? (And no invalid i<N> in the -fail test?)

> --- a/opcodes/riscv-dis.c
> +++ b/opcodes/riscv-dis.c
> @@ -917,6 +917,65 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
>  		  goto undefined_modifier;
>  		}
>  	      break;
> +	    case 'p': /* Vendor-specific (SpacemiT) operands.  */
> +	      {
> +		switch (*++oparg)
> +		  {
> +		  case 'V':
> +		    switch (*++oparg)
> +		      {
> +		      case 'd':
> +			unsigned vd = EXTRACT_OPERAND (SPACEMIT_IME_VD, l) * 2;
> +			print (info->stream, dis_style_register, "%s",
> +			       riscv_vecr_names_numeric[vd]);
> +			break;
> +		      case 's':
> +			unsigned vs = EXTRACT_OPERAND (SPACEMIT_IME_VS1, l) * 2;
> +			print (info->stream, dis_style_register, "%s",
> +			       riscv_vecr_names_numeric[vs]);
> +			break;
> +		      default:
> +			goto undefined_modifier;
> +		      }
> +		    break;
> +		  case 'w':
> +		    /* Xpw&S ... bits in S indicates whether corresponding
> +		       item is permitted.  */
> +		    if (*++oparg != '&')
> +		      goto undefined_modifier;
> +		    strtol (oparg + 1, (char **)&oparg, 16);
> +		    oparg--;
> +		    unsigned wi = EXTRACT_OPERAND (SPACEMIT_IME_WI, l);
> +		    /* Only print if not the default value (i8 = 3).  */
> +		    if (wi != 3)

In a situation like this, with already pretty deep indentation, can I talk
you into using

		    if (wi == 3)
		      break;

instead?

> +		      {
> +			print (info->stream, dis_style_text, ",");
> +			switch (wi)
> +			  {
> +			  case 0:
> +			    print (info->stream, dis_style_text, "i2");
> +			    break;
> +			  case 1:
> +			    print (info->stream, dis_style_text, "i16");
> +			    break;
> +			  case 2:
> +			    print (info->stream, dis_style_text, "i4");
> +			    break;
> +			  case 3:
> +			    print (info->stream, dis_style_text, "i8");
> +			    break;
> +			  default:
> +			    print (info->stream, dis_style_immediate, "%u", wi);
> +			      break;
> +			  }
> +		      }

The scope here then can go away, and indentation can be reduced by 2 levels.

The last of the "break" also looks mis-indented, but the question is
whether the default: case is needed at all. wi can't take any value other
than 0...3.

Jan

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v4 0/1] RISC-V: Add SpacemiT vendor extensions xsmtvdot
  2026-04-10 10:25             ` Jan Beulich
@ 2026-04-10 15:11               ` Mark Zhuang
  2026-04-10 15:11                 ` [PATCH v4 1/1] " Mark Zhuang
  2026-04-16  6:28                 ` [PATCH v4 0/1] RISC-V: Add SpacemiT vendor extensions xsmtvdot Jan Beulich
  0 siblings, 2 replies; 16+ messages in thread
From: Mark Zhuang @ 2026-04-10 15:11 UTC (permalink / raw)
  To: binutils; +Cc: jbeulich, nelson.chu1990

From: Mark Zhuang <mark.zhuang@spacemit.com>

On 10.04.2026 12:25, Jan Beulich wrote:
> Doesn't this file need to be named x-smt-vdot-fail.d, for the test to be
> executed at all? And isn't the real x-smt-vdot-fail.l missing?

I apologize for not catching this before sending. v4 fix it. Thanks.

> Only i8 being tested? (And no invalid i<N> in the -fail test?)

For the SpacemiT K1 chip (X60 core), only i8 is currently implemented
in hardware, so only i8 being tested. In the v4 update, the fail test
has been extended to include invalid i<N>

Although the K1 hardware only supports i8, we retain handling for
i2, i4, and i16 in the patch because the upcoming SpacemiT K3 chip
will utilize them, allowing for code reuse.
We are currently preparing the documentation and patches for K3.

> In a situation like this, with already pretty deep indentation, can I talk
> you into using
>
>             if (wi == 3)
>               break;
>
> instead?
>
> The scope here then can go away, and indentation can be reduced by 2 levels.
>
> The last of the "break" also looks mis-indented, but the question is
> whether the default: case is needed at all. wi can't take any value other
> than 0...3.

Done. v4 use early break and if/else-if chain to make code cleaner.

Mark Zhuang (1):
  RISC-V: Add SpacemiT vendor extensions xsmtvdot

 bfd/elfxx-riscv.c                         |   7 ++
 gas/NEWS                                  |   3 +
 gas/config/tc-riscv.c                     | 108 ++++++++++++++++++++++
 gas/doc/c-riscv.texi                      |   7 ++
 gas/testsuite/gas/riscv/march-help.l      |   1 +
 gas/testsuite/gas/riscv/x-smt-vdot-fail.d |   3 +
 gas/testsuite/gas/riscv/x-smt-vdot-fail.l |  77 +++++++++++++++
 gas/testsuite/gas/riscv/x-smt-vdot-fail.s |  78 ++++++++++++++++
 gas/testsuite/gas/riscv/x-smt-vdot.d      |  41 ++++++++
 gas/testsuite/gas/riscv/x-smt-vdot.s      |  33 +++++++
 include/opcode/riscv-opc.h                |  38 ++++++++
 include/opcode/riscv.h                    |   9 ++
 opcodes/riscv-dis.c                       |  43 +++++++++
 opcodes/riscv-opc.c                       |  23 +++++
 14 files changed, 471 insertions(+)
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-fail.d
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-fail.l
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-fail.s
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot.d
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot.s

-- 
2.34.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v4 1/1] RISC-V: Add SpacemiT vendor extensions xsmtvdot
  2026-04-10 15:11               ` [PATCH v4 0/1] " Mark Zhuang
@ 2026-04-10 15:11                 ` Mark Zhuang
  2026-04-16  6:34                   ` Jan Beulich
  2026-04-16  8:49                   ` Andreas Schwab
  2026-04-16  6:28                 ` [PATCH v4 0/1] RISC-V: Add SpacemiT vendor extensions xsmtvdot Jan Beulich
  1 sibling, 2 replies; 16+ messages in thread
From: Mark Zhuang @ 2026-04-10 15:11 UTC (permalink / raw)
  To: binutils; +Cc: jbeulich, nelson.chu1990

From: Mark Zhuang <mark.zhuang@spacemit.com>

SpacemiT defines Intrinsic Matrix Extension (IME) specification [1].
SpacemiT X60 implement version 1.0 of the SpacemiT Vector Dot Product Extension (XsmtVdot v1.0) [2],
it is a subset of the full IME specification

[1] https://github.com/spacemit-com/riscv-ime-extension-spec/releases/download/v1.0/spacemit-ime-asciidoc.pdf
[2] https://github.com/spacemit-com/docs-chip/blob/main/en/key_stone/k1/k1_docs/k1_ds.md#spacemit-x60-risc-v-core

Co-authored-by: Link <xuqian@spacemit.com>
---
 bfd/elfxx-riscv.c                         |   7 ++
 gas/NEWS                                  |   3 +
 gas/config/tc-riscv.c                     | 108 ++++++++++++++++++++++
 gas/doc/c-riscv.texi                      |   7 ++
 gas/testsuite/gas/riscv/march-help.l      |   1 +
 gas/testsuite/gas/riscv/x-smt-vdot-fail.d |   3 +
 gas/testsuite/gas/riscv/x-smt-vdot-fail.l |  77 +++++++++++++++
 gas/testsuite/gas/riscv/x-smt-vdot-fail.s |  78 ++++++++++++++++
 gas/testsuite/gas/riscv/x-smt-vdot.d      |  41 ++++++++
 gas/testsuite/gas/riscv/x-smt-vdot.s      |  33 +++++++
 include/opcode/riscv-opc.h                |  38 ++++++++
 include/opcode/riscv.h                    |   9 ++
 opcodes/riscv-dis.c                       |  43 +++++++++
 opcodes/riscv-opc.c                       |  23 +++++
 14 files changed, 471 insertions(+)
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-fail.d
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-fail.l
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-fail.s
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot.d
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot.s

diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 83134f81c96..5fdbc1698af 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1229,6 +1229,8 @@ static const struct riscv_implicit_subset riscv_implicit_subsets[] =
   {"xtheadvector", "+zicsr", check_implicit_always},
   {"xtheadzvamo", "+zaamo", check_implicit_always},
 
+  {"xsmtvdot", "+zve32x", check_implicit_always},
+
   {"v", "+zve64d,+zvl128b", check_implicit_always},
   {"zvfh", "+zvfhmin,+zfhmin", check_implicit_always},
   {"zvfhmin", "+zve32f", check_implicit_always},
@@ -1644,6 +1646,7 @@ static const struct riscv_supported_ext riscv_supported_vendor_x_ext[] =
   {"xmipscmov",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
   {"xmipsexectl",	ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
   {"xmipslsp",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
+  {"xsmtvdot",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
   {NULL, 0, 0, 0, 0}
 };
 
@@ -3062,6 +3065,8 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
       return riscv_subset_supports (rps, "xmipsexectl");
     case INSN_CLASS_XMIPSLSP:
       return riscv_subset_supports (rps, "xmipslsp");
+    case INSN_CLASS_XSMTVDOT:
+      return riscv_subset_supports (rps, "xsmtvdot");
     default:
       rps->error_handler
         (_("internal: unreachable INSN_CLASS_*"));
@@ -3365,6 +3370,8 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
       return "xsfvqmaccdod";
     case INSN_CLASS_XSFVFNRCLIPXFQF:
       return "xsfvfnrclipxfqf";
+    case INSN_CLASS_XSMTVDOT:
+      return "xsmtvdot";
     default:
       rps->error_handler
         (_("internal: unreachable INSN_CLASS_*"));
diff --git a/gas/NEWS b/gas/NEWS
index e384d1135c0..e47d55b05dc 100644
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,5 +1,8 @@
 -*- text -*-
 
+* Add support for RISC-V vendor extensions:
+  SpacemiT: xsmtvdot v1.0.
+
 Changes in 2.46:
 
 * Add support for AMD Zen6 processor.
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index b00b530b0bd..273f6370fee 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -1770,6 +1770,35 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
 		    goto unknown_validate_operand;
 		}
 		break;
+	    case 'p': /* Vendor-specific (SpacemiT) operands.  */
+	      switch (*++oparg)
+		{
+		case 'V':
+		  switch (*++oparg)
+		    {
+		    case 'd':
+		      USE_BITS (OP_MASK_SPACEMIT_IME_VD, OP_SH_SPACEMIT_IME_VD);
+		      break;
+		    case 's':
+		      USE_BITS (OP_MASK_SPACEMIT_IME_VS1, OP_SH_SPACEMIT_IME_VS1);
+		      break;
+		    default:
+		      goto unknown_validate_operand;
+		    }
+		  break;
+		case 'w':
+		  /* Xpw&S ... bits in S indicates whether corresponding
+		     item is permitted.  */
+		  if (*++oparg != '&')
+		    goto unknown_validate_operand;
+		  strtol (oparg + 1, (char **)&oparg, 16);
+		  oparg--;
+		  USE_BITS (OP_MASK_SPACEMIT_IME_WI, OP_SH_SPACEMIT_IME_WI);
+		  break;
+		default:
+		  goto unknown_validate_operand;
+		}
+	      break;
 	    default:
 	      goto unknown_validate_operand;
 	    }
@@ -4286,6 +4315,85 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 		    }
 		  break;
 
+		case 'p': /* Vendor-specific (SpacemiT) operands.  */
+		  switch (*++oparg)
+		    {
+		    case 'V':
+		      switch (*++oparg)
+			{
+			case 'd':
+			  if (!reg_lookup (&asarg, RCLASS_VECR, &regno))
+			    break;
+			  if ((regno & 0x1) != 0)
+			    {
+			      error.msg = _("illegal operands (vd must be even)");
+			      break;
+			    }
+			  INSERT_OPERAND (SPACEMIT_IME_VD, *ip, regno>>1);
+			  continue;
+			case 's':
+			  if (!reg_lookup (&asarg, RCLASS_VECR, &regno))
+			    break;
+			  if ((regno & 0x1) != 0)
+			    {
+			      error.msg = _("illegal operands (vs1 must be even)");
+			      break;
+			    }
+			  INSERT_OPERAND (SPACEMIT_IME_VS1, *ip, regno>>1);
+			  continue;
+			default:
+			  goto unknown_riscv_ip_operand;
+			}
+		      break;
+		    case 'w':
+		      /* Xpw&S ... bits in S indicates whether
+			 corresponding item is permitted.  */
+		      if (*++oparg != '&')
+			goto unknown_riscv_ip_operand;
+		      size_t n = strtol (oparg + 1, (char **)&oparg, 16);
+		      oparg--;
+		      /* Optional operand: if not present, default to i8.  */
+		      if (*asarg == '\0')
+			regno = 3;
+		      else if (*asarg == ',')
+			{
+			  asarg++;
+			  if (strncmp (asarg, "i2", 2) == 0)
+			    {
+			      regno = 0;
+			      asarg += 2;
+			    }
+			  else if (strncmp (asarg, "i16", 3) == 0)
+			    {
+			      regno = 1;
+			      asarg += 3;
+			    }
+			  else if (strncmp (asarg, "i4", 2) == 0)
+			    {
+			      regno = 2;
+			      asarg += 2;
+			    }
+			  else if (strncmp (asarg, "i8", 2) == 0)
+			    {
+			      regno = 3;
+			      asarg += 2;
+			    }
+			  else
+			    break;
+			}
+		      else
+			goto unknown_riscv_ip_operand;
+		      if ((n & (1 << regno)) == 0)
+			{
+			  error.msg = _("illegal operands (invalid data type)");
+			  break;
+			}
+		      INSERT_OPERAND (SPACEMIT_IME_WI, *ip, regno);
+		      continue;
+		    default:
+		      goto unknown_riscv_ip_operand;
+		    }
+		  break;
 		default:
 		  goto unknown_riscv_ip_operand;
 		}
diff --git a/gas/doc/c-riscv.texi b/gas/doc/c-riscv.texi
index c6c4081c204..d928f76c014 100644
--- a/gas/doc/c-riscv.texi
+++ b/gas/doc/c-riscv.texi
@@ -918,4 +918,11 @@ The XMipsSlsp extension provides instructions mips.ldp, mips.lwp, mips.sdp and m
 
 It is documented in @url{https://mips.com/wp-content/uploads/2025/03/P8700-F_Programmers_Reference_Manual_Rev1.82_3-19-2025.pdf}.
 
+@item XSmtVdot
+The XSmtVdot extension provides instructions for vector dot.
+
+SpacemiT defines Intrinsic Matrix Extension (IME) specification, documented in @url{https://github.com/spacemit-com/riscv-ime-extension-spec/releases/download/v1.0/spacemit-ime-asciidoc.pdf}.
+SpacemiT X60 implement version 1.0 of the SpacemiT Vector Dot Product Extension (XsmtVdot v1.0),
+it is a subset of the full IME specification, documented in @url{https://github.com/spacemit-com/docs-chip/blob/main/en/key_stone/k1/k1_docs/k1_ds.md#spacemit-x60-risc-v-core}.
+
 @end table
diff --git a/gas/testsuite/gas/riscv/march-help.l b/gas/testsuite/gas/riscv/march-help.l
index 0ce2f896735..6e52669e9a4 100644
--- a/gas/testsuite/gas/riscv/march-help.l
+++ b/gas/testsuite/gas/riscv/march-help.l
@@ -186,3 +186,4 @@ All available -march extensions for RISC-V:
 	xmipscmov                               1.0
 	xmipsexectl                             1.0
 	xmipslsp                                1.0
+	xsmtvdot                                1.0
diff --git a/gas/testsuite/gas/riscv/x-smt-vdot-fail.d b/gas/testsuite/gas/riscv/x-smt-vdot-fail.d
new file mode 100644
index 00000000000..6e846b401e1
--- /dev/null
+++ b/gas/testsuite/gas/riscv/x-smt-vdot-fail.d
@@ -0,0 +1,3 @@
+#as: -march=rv64gcv_xsmtvdot
+#source: x-smt-vdot-fail.s
+#error_output: x-smt-vdot-fail.l
diff --git a/gas/testsuite/gas/riscv/x-smt-vdot-fail.l b/gas/testsuite/gas/riscv/x-smt-vdot-fail.l
new file mode 100644
index 00000000000..3172fd36e27
--- /dev/null
+++ b/gas/testsuite/gas/riscv/x-smt-vdot-fail.l
@@ -0,0 +1,77 @@
+.*: Assembler messages:
+.*:2: Error: illegal operands \(vd must be even\) `smt.vmadot v1,v3,v4'
+.*:3: Error: illegal operands \(vd must be even\) `smt.vmadotu v1,v3,v4'
+.*:4: Error: illegal operands \(vd must be even\) `smt.vmadotsu v1,v3,v4'
+.*:5: Error: illegal operands \(vd must be even\) `smt.vmadotus v1,v3,v4'
+.*:6: Error: illegal operands \(vd must be even\) `smt.vmadot1u v1,v4,v5'
+.*:7: Error: illegal operands \(vd must be even\) `smt.vmadot1 v1,v4,v5'
+.*:8: Error: illegal operands \(vd must be even\) `smt.vmadot1su v1,v4,v5'
+.*:9: Error: illegal operands \(vd must be even\) `smt.vmadot1us v1,v4,v5'
+.*:10: Error: illegal operands \(vd must be even\) `smt.vmadot2u v1,v4,v5'
+.*:11: Error: illegal operands \(vd must be even\) `smt.vmadot2 v1,v4,v5'
+.*:12: Error: illegal operands \(vd must be even\) `smt.vmadot2su v1,v4,v5'
+.*:13: Error: illegal operands \(vd must be even\) `smt.vmadot2us v1,v4,v5'
+.*:14: Error: illegal operands \(vd must be even\) `smt.vmadot3u v1,v4,v5'
+.*:15: Error: illegal operands \(vd must be even\) `smt.vmadot3 v1,v4,v5'
+.*:16: Error: illegal operands \(vd must be even\) `smt.vmadot3su v1,v4,v5'
+.*:17: Error: illegal operands \(vd must be even\) `smt.vmadot3us v1,v4,v5'
+.*:18: Error: illegal operands \(vs1 must be even\) `smt.vmadot1u v2,v3,v5'
+.*:19: Error: illegal operands \(vs1 must be even\) `smt.vmadot1 v2,v3,v5'
+.*:20: Error: illegal operands \(vs1 must be even\) `smt.vmadot1su v2,v3,v5'
+.*:21: Error: illegal operands \(vs1 must be even\) `smt.vmadot1us v2,v3,v5'
+.*:22: Error: illegal operands \(vs1 must be even\) `smt.vmadot2u v2,v3,v5'
+.*:23: Error: illegal operands \(vs1 must be even\) `smt.vmadot2 v2,v3,v5'
+.*:24: Error: illegal operands \(vs1 must be even\) `smt.vmadot2su v2,v3,v5'
+.*:25: Error: illegal operands \(vs1 must be even\) `smt.vmadot2us v2,v3,v5'
+.*:26: Error: illegal operands \(vs1 must be even\) `smt.vmadot3u v2,v3,v5'
+.*:27: Error: illegal operands \(vs1 must be even\) `smt.vmadot3 v2,v3,v5'
+.*:28: Error: illegal operands \(vs1 must be even\) `smt.vmadot3su v2,v3,v5'
+.*:29: Error: illegal operands \(vs1 must be even\) `smt.vmadot3us v2,v3,v5'
+.*:30: Error: illegal operands \(invalid data type\) `smt.vmadot v2,v3,v4,i2'
+.*:31: Error: illegal operands \(invalid data type\) `smt.vmadotu v2,v3,v4,i2'
+.*:32: Error: illegal operands \(invalid data type\) `smt.vmadotsu v2,v3,v4,i2'
+.*:33: Error: illegal operands \(invalid data type\) `smt.vmadotus v2,v3,v4,i2'
+.*:34: Error: illegal operands \(invalid data type\) `smt.vmadot1u v2,v4,v5,i2'
+.*:35: Error: illegal operands \(invalid data type\) `smt.vmadot1 v2,v4,v5,i2'
+.*:36: Error: illegal operands \(invalid data type\) `smt.vmadot1su v2,v4,v5,i2'
+.*:37: Error: illegal operands \(invalid data type\) `smt.vmadot1us v2,v4,v5,i2'
+.*:38: Error: illegal operands \(invalid data type\) `smt.vmadot2u v2,v4,v5,i2'
+.*:39: Error: illegal operands \(invalid data type\) `smt.vmadot2 v2,v4,v5,i2'
+.*:40: Error: illegal operands \(invalid data type\) `smt.vmadot2su v2,v4,v5,i2'
+.*:41: Error: illegal operands \(invalid data type\) `smt.vmadot2us v2,v4,v5,i2'
+.*:42: Error: illegal operands \(invalid data type\) `smt.vmadot3u v2,v4,v5,i2'
+.*:43: Error: illegal operands \(invalid data type\) `smt.vmadot3 v2,v4,v5,i2'
+.*:44: Error: illegal operands \(invalid data type\) `smt.vmadot3su v2,v4,v5,i2'
+.*:45: Error: illegal operands \(invalid data type\) `smt.vmadot3us v2,v4,v5,i2'
+.*:46: Error: illegal operands \(invalid data type\) `smt.vmadot v2,v3,v4,i4'
+.*:47: Error: illegal operands \(invalid data type\) `smt.vmadotu v2,v3,v4,i4'
+.*:48: Error: illegal operands \(invalid data type\) `smt.vmadotsu v2,v3,v4,i4'
+.*:49: Error: illegal operands \(invalid data type\) `smt.vmadotus v2,v3,v4,i4'
+.*:50: Error: illegal operands \(invalid data type\) `smt.vmadot1u v2,v4,v5,i4'
+.*:51: Error: illegal operands \(invalid data type\) `smt.vmadot1 v2,v4,v5,i4'
+.*:52: Error: illegal operands \(invalid data type\) `smt.vmadot1su v2,v4,v5,i4'
+.*:53: Error: illegal operands \(invalid data type\) `smt.vmadot1us v2,v4,v5,i4'
+.*:54: Error: illegal operands \(invalid data type\) `smt.vmadot2u v2,v4,v5,i4'
+.*:55: Error: illegal operands \(invalid data type\) `smt.vmadot2 v2,v4,v5,i4'
+.*:56: Error: illegal operands \(invalid data type\) `smt.vmadot2su v2,v4,v5,i4'
+.*:57: Error: illegal operands \(invalid data type\) `smt.vmadot2us v2,v4,v5,i4'
+.*:58: Error: illegal operands \(invalid data type\) `smt.vmadot3u v2,v4,v5,i4'
+.*:59: Error: illegal operands \(invalid data type\) `smt.vmadot3 v2,v4,v5,i4'
+.*:60: Error: illegal operands \(invalid data type\) `smt.vmadot3su v2,v4,v5,i4'
+.*:61: Error: illegal operands \(invalid data type\) `smt.vmadot3us v2,v4,v5,i4'
+.*:62: Error: illegal operands \(invalid data type\) `smt.vmadot v2,v3,v4,i16'
+.*:63: Error: illegal operands \(invalid data type\) `smt.vmadotu v2,v3,v4,i16'
+.*:64: Error: illegal operands \(invalid data type\) `smt.vmadotsu v2,v3,v4,i16'
+.*:65: Error: illegal operands \(invalid data type\) `smt.vmadotus v2,v3,v4,i16'
+.*:66: Error: illegal operands \(invalid data type\) `smt.vmadot1u v2,v4,v5,i16'
+.*:67: Error: illegal operands \(invalid data type\) `smt.vmadot1 v2,v4,v5,i16'
+.*:68: Error: illegal operands \(invalid data type\) `smt.vmadot1su v2,v4,v5,i16'
+.*:69: Error: illegal operands \(invalid data type\) `smt.vmadot1us v2,v4,v5,i16'
+.*:70: Error: illegal operands \(invalid data type\) `smt.vmadot2u v2,v4,v5,i16'
+.*:71: Error: illegal operands \(invalid data type\) `smt.vmadot2 v2,v4,v5,i16'
+.*:72: Error: illegal operands \(invalid data type\) `smt.vmadot2su v2,v4,v5,i16'
+.*:73: Error: illegal operands \(invalid data type\) `smt.vmadot2us v2,v4,v5,i16'
+.*:74: Error: illegal operands \(invalid data type\) `smt.vmadot3u v2,v4,v5,i16'
+.*:75: Error: illegal operands \(invalid data type\) `smt.vmadot3 v2,v4,v5,i16'
+.*:76: Error: illegal operands \(invalid data type\) `smt.vmadot3su v2,v4,v5,i16'
+.*:77: Error: illegal operands \(invalid data type\) `smt.vmadot3us v2,v4,v5,i16'
diff --git a/gas/testsuite/gas/riscv/x-smt-vdot-fail.s b/gas/testsuite/gas/riscv/x-smt-vdot-fail.s
new file mode 100644
index 00000000000..22a480711ce
--- /dev/null
+++ b/gas/testsuite/gas/riscv/x-smt-vdot-fail.s
@@ -0,0 +1,78 @@
+target:
+	smt.vmadot v1, v3, v4
+	smt.vmadotu v1, v3, v4
+	smt.vmadotsu v1, v3, v4
+	smt.vmadotus v1, v3, v4
+	smt.vmadot1u v1, v4, v5
+	smt.vmadot1 v1, v4, v5
+	smt.vmadot1su v1, v4, v5
+	smt.vmadot1us v1, v4, v5
+	smt.vmadot2u v1, v4, v5
+	smt.vmadot2 v1, v4, v5
+	smt.vmadot2su v1, v4, v5
+	smt.vmadot2us v1, v4, v5
+	smt.vmadot3u v1, v4, v5
+	smt.vmadot3 v1, v4, v5
+	smt.vmadot3su v1, v4, v5
+	smt.vmadot3us v1, v4, v5
+	smt.vmadot1u v2, v3, v5
+	smt.vmadot1 v2, v3, v5
+	smt.vmadot1su v2, v3, v5
+	smt.vmadot1us v2, v3, v5
+	smt.vmadot2u v2, v3, v5
+	smt.vmadot2 v2, v3, v5
+	smt.vmadot2su v2, v3, v5
+	smt.vmadot2us v2, v3, v5
+	smt.vmadot3u v2, v3, v5
+	smt.vmadot3 v2, v3, v5
+	smt.vmadot3su v2, v3, v5
+	smt.vmadot3us v2, v3, v5
+	smt.vmadot v2, v3, v4, i2
+	smt.vmadotu v2, v3, v4, i2
+	smt.vmadotsu v2, v3, v4, i2
+	smt.vmadotus v2, v3, v4, i2
+	smt.vmadot1u v2, v4, v5, i2
+	smt.vmadot1 v2, v4, v5, i2
+	smt.vmadot1su v2, v4, v5, i2
+	smt.vmadot1us v2, v4, v5, i2
+	smt.vmadot2u v2, v4, v5, i2
+	smt.vmadot2 v2, v4, v5, i2
+	smt.vmadot2su v2, v4, v5, i2
+	smt.vmadot2us v2, v4, v5, i2
+	smt.vmadot3u v2, v4, v5, i2
+	smt.vmadot3 v2, v4, v5, i2
+	smt.vmadot3su v2, v4, v5, i2
+	smt.vmadot3us v2, v4, v5, i2
+	smt.vmadot v2, v3, v4, i4
+	smt.vmadotu v2, v3, v4, i4
+	smt.vmadotsu v2, v3, v4, i4
+	smt.vmadotus v2, v3, v4, i4
+	smt.vmadot1u v2, v4, v5, i4
+	smt.vmadot1 v2, v4, v5, i4
+	smt.vmadot1su v2, v4, v5, i4
+	smt.vmadot1us v2, v4, v5, i4
+	smt.vmadot2u v2, v4, v5, i4
+	smt.vmadot2 v2, v4, v5, i4
+	smt.vmadot2su v2, v4, v5, i4
+	smt.vmadot2us v2, v4, v5, i4
+	smt.vmadot3u v2, v4, v5, i4
+	smt.vmadot3 v2, v4, v5, i4
+	smt.vmadot3su v2, v4, v5, i4
+	smt.vmadot3us v2, v4, v5, i4
+	smt.vmadot v2, v3, v4, i16
+	smt.vmadotu v2, v3, v4, i16
+	smt.vmadotsu v2, v3, v4, i16
+	smt.vmadotus v2, v3, v4, i16
+	smt.vmadot1u v2, v4, v5, i16
+	smt.vmadot1 v2, v4, v5, i16
+	smt.vmadot1su v2, v4, v5, i16
+	smt.vmadot1us v2, v4, v5, i16
+	smt.vmadot2u v2, v4, v5, i16
+	smt.vmadot2 v2, v4, v5, i16
+	smt.vmadot2su v2, v4, v5, i16
+	smt.vmadot2us v2, v4, v5, i16
+	smt.vmadot3u v2, v4, v5, i16
+	smt.vmadot3 v2, v4, v5, i16
+	smt.vmadot3su v2, v4, v5, i16
+	smt.vmadot3us v2, v4, v5, i16
+
diff --git a/gas/testsuite/gas/riscv/x-smt-vdot.d b/gas/testsuite/gas/riscv/x-smt-vdot.d
new file mode 100644
index 00000000000..6f86236785d
--- /dev/null
+++ b/gas/testsuite/gas/riscv/x-smt-vdot.d
@@ -0,0 +1,41 @@
+#as: -march=rv64gcv_xsmtvdot
+#objdump: -dr
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+e241b12b[ 	]+smt.vmadot[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e241812b[ 	]+smt.vmadotu[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e241a12b[ 	]+smt.vmadotsu[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e241912b[ 	]+smt.vmadotus[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e652012b[ 	]+smt.vmadot1u[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652312b[ 	]+smt.vmadot1[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652212b[ 	]+smt.vmadot1su[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652112b[ 	]+smt.vmadot1us[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652412b[ 	]+smt.vmadot2u[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652712b[ 	]+smt.vmadot2[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652612b[ 	]+smt.vmadot2su[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652512b[ 	]+smt.vmadot2us[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652812b[ 	]+smt.vmadot3u[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652b12b[ 	]+smt.vmadot3[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652a12b[ 	]+smt.vmadot3su[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652912b[ 	]+smt.vmadot3us[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e241b12b[ 	]+smt.vmadot[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e241812b[ 	]+smt.vmadotu[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e241a12b[ 	]+smt.vmadotsu[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e241912b[ 	]+smt.vmadotus[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e652012b[ 	]+smt.vmadot1u[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652312b[ 	]+smt.vmadot1[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652212b[ 	]+smt.vmadot1su[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652112b[ 	]+smt.vmadot1us[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652412b[ 	]+smt.vmadot2u[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652712b[ 	]+smt.vmadot2[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652612b[ 	]+smt.vmadot2su[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652512b[ 	]+smt.vmadot2us[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652812b[ 	]+smt.vmadot3u[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652b12b[ 	]+smt.vmadot3[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652a12b[ 	]+smt.vmadot3su[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652912b[ 	]+smt.vmadot3us[ 	]+v2,v4,v5
diff --git a/gas/testsuite/gas/riscv/x-smt-vdot.s b/gas/testsuite/gas/riscv/x-smt-vdot.s
new file mode 100644
index 00000000000..a9991de4fc3
--- /dev/null
+++ b/gas/testsuite/gas/riscv/x-smt-vdot.s
@@ -0,0 +1,33 @@
+target:
+	smt.vmadot v2, v3, v4
+	smt.vmadotu v2, v3, v4
+	smt.vmadotsu v2, v3, v4
+	smt.vmadotus v2, v3, v4
+	smt.vmadot1u v2, v4, v5
+	smt.vmadot1 v2, v4, v5
+	smt.vmadot1su v2, v4, v5
+	smt.vmadot1us v2, v4, v5
+	smt.vmadot2u v2, v4, v5
+	smt.vmadot2 v2, v4, v5
+	smt.vmadot2su v2, v4, v5
+	smt.vmadot2us v2, v4, v5
+	smt.vmadot3u v2, v4, v5
+	smt.vmadot3 v2, v4, v5
+	smt.vmadot3su v2, v4, v5
+	smt.vmadot3us v2, v4, v5
+	smt.vmadot v2, v3, v4, i8
+	smt.vmadotu v2, v3, v4, i8
+	smt.vmadotsu v2, v3, v4, i8
+	smt.vmadotus v2, v3, v4, i8
+	smt.vmadot1u v2, v4, v5, i8
+	smt.vmadot1 v2, v4, v5, i8
+	smt.vmadot1su v2, v4, v5, i8
+	smt.vmadot1us v2, v4, v5, i8
+	smt.vmadot2u v2, v4, v5, i8
+	smt.vmadot2 v2, v4, v5, i8
+	smt.vmadot2su v2, v4, v5, i8
+	smt.vmadot2us v2, v4, v5, i8
+	smt.vmadot3u v2, v4, v5, i8
+	smt.vmadot3 v2, v4, v5, i8
+	smt.vmadot3su v2, v4, v5, i8
+	smt.vmadot3us v2, v4, v5, i8
diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
index 6f2775c6152..31b7e7a06a7 100644
--- a/include/opcode/riscv-opc.h
+++ b/include/opcode/riscv-opc.h
@@ -3852,6 +3852,44 @@
 #define MASK_MIPS_PAUSE  0xffffffff
 #define MATCH_MIPS_PREF 0x0000000b
 #define MASK_MIPS_PREF 0xe000707f
+/* SpacemiT custom instruction.  */
+/* Int Matrix Multiplicative Accumulation.  */
+#define MATCH_SMT_VMADOT   0x8200302b
+#define MASK_SMT_VMADOT    0x9e0070ff
+#define MATCH_SMT_VMADOTU  0x8200002b
+#define MASK_SMT_VMADOTU   0x9e0070ff
+#define MATCH_SMT_VMADOTSU 0x8200202b
+#define MASK_SMT_VMADOTSU  0x9e0070ff
+#define MATCH_SMT_VMADOTUS 0x8200102b
+#define MASK_SMT_VMADOTUS  0x9e0070ff
+/* Int Sliding Window Multiplicative Accumulation.  */
+/* Sliding Value = 1.  */
+#define MATCH_SMT_VMADOT1U 0x8600002b
+#define MASK_SMT_VMADOT1U  0x9e00f0ff
+#define MATCH_SMT_VMADOT1  0x8600302b
+#define MASK_SMT_VMADOT1   0x9e00f0ff
+#define MATCH_SMT_VMADOT1SU 0x8600202b
+#define MASK_SMT_VMADOT1SU 0x9e00f0ff
+#define MATCH_SMT_VMADOT1US 0x8600102b
+#define MASK_SMT_VMADOT1US 0x9e00f0ff
+/* Sliding Value = 2.  */
+#define MATCH_SMT_VMADOT2U 0x8600402b
+#define MASK_SMT_VMADOT2U 0x9e00f0ff
+#define MATCH_SMT_VMADOT2 0x8600702b
+#define MASK_SMT_VMADOT2 0x9e00f0ff
+#define MATCH_SMT_VMADOT2SU 0x8600602b
+#define MASK_SMT_VMADOT2SU 0x9e00f0ff
+#define MATCH_SMT_VMADOT2US 0x8600502b
+#define MASK_SMT_VMADOT2US 0x9e00f0ff
+/* Sliding Value = 3.  */
+#define MATCH_SMT_VMADOT3U 0x8600802b
+#define MASK_SMT_VMADOT3U 0x9e00f0ff
+#define MATCH_SMT_VMADOT3 0x8600b02b
+#define MASK_SMT_VMADOT3 0x9e00f0ff
+#define MATCH_SMT_VMADOT3SU 0x8600a02b
+#define MASK_SMT_VMADOT3SU 0x9e00f0ff
+#define MATCH_SMT_VMADOT3US 0x8600902b
+#define MASK_SMT_VMADOT3US 0x9e00f0ff
 /* Unprivileged Counter/Timers CSR addresses.  */
 #define CSR_CYCLE 0xc00
 #define CSR_TIME 0xc01
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index de105f5df8b..3a32abfcf3c 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -419,6 +419,14 @@ static inline unsigned int riscv_insn_length (insn_t insn)
 #define OP_MASK_MIPS_SDP_OFFSET25   0x3
 #define OP_SH_MIPS_SDP_OFFSET25     25
 
+/* SpacemiT fields.  */
+#define OP_MASK_SPACEMIT_IME_VD		0xf
+#define OP_SH_SPACEMIT_IME_VD		8
+#define OP_MASK_SPACEMIT_IME_VS1	0xf
+#define OP_SH_SPACEMIT_IME_VS1		16
+#define OP_MASK_SPACEMIT_IME_WI		0x3
+#define OP_SH_SPACEMIT_IME_WI		29
+
 /* ABI names for selected x-registers.  */
 
 #define X_ZERO 0
@@ -606,6 +614,7 @@ enum riscv_insn_class
   INSN_CLASS_XMIPSCMOV,
   INSN_CLASS_XMIPSEXECTL,
   INSN_CLASS_XMIPSLSP,
+  INSN_CLASS_XSMTVDOT,
 };
 
 /* This structure holds information for a particular instruction.  */
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index eda802ff420..fc25364d293 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -917,6 +917,49 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 		  goto undefined_modifier;
 		}
 	      break;
+	    case 'p': /* Vendor-specific (SpacemiT) operands.  */
+	      switch (*++oparg)
+		{
+		case 'V':
+		  switch (*++oparg)
+		    {
+		    case 'd':
+		      unsigned vd = EXTRACT_OPERAND (SPACEMIT_IME_VD, l) * 2;
+		      print (info->stream, dis_style_register, "%s",
+			     riscv_vecr_names_numeric[vd]);
+		      break;
+		    case 's':
+		      unsigned vs = EXTRACT_OPERAND (SPACEMIT_IME_VS1, l) * 2;
+		      print (info->stream, dis_style_register, "%s",
+			     riscv_vecr_names_numeric[vs]);
+		      break;
+		    default:
+		      goto undefined_modifier;
+		    }
+		  break;
+		case 'w':
+		  /* Xpw&S ... bits in S indicates whether corresponding
+		     item is permitted.  */
+		  if (*++oparg != '&')
+		    goto undefined_modifier;
+		  strtol (oparg + 1, (char **)&oparg, 16);
+		  oparg--;
+		  unsigned wi = EXTRACT_OPERAND (SPACEMIT_IME_WI, l);
+		  /* Only print if not the default value (i8 = 3).  */
+		  if (wi == 3)
+		    break;
+		  print (info->stream, dis_style_text, ",");
+		  if (wi == 0)
+		    print (info->stream, dis_style_text, "i2");
+		  else if (wi == 1)
+		    print (info->stream, dis_style_text, "i16");
+		  else if (wi == 2)
+		    print (info->stream, dis_style_text, "i4");
+		  break;
+		default:
+		  goto undefined_modifier;
+		}
+	      break;
 	    default:
 	      goto undefined_modifier;
 	    }
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 54887c97880..ed2d7e4c4a0 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -3579,6 +3579,29 @@ const struct riscv_opcode riscv_opcodes[] =
 {"mips.sdp", 0, INSN_CLASS_XMIPSLSP, "t,r,Xm^(s)", MATCH_MIPS_SDP, MASK_MIPS_SDP, match_opcode, 0 },
 {"mips.swp", 0, INSN_CLASS_XMIPSLSP, "t,r,Xm&(s)", MATCH_MIPS_SWP, MASK_MIPS_SWP, match_opcode, 0 },
 
+/* SpacemiT custom instructions.  */
+/* Int Matrix Multi-Accumulation.  */
+{"smt.vmadot",   0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,VtXpw&8", MATCH_SMT_VMADOT, MASK_SMT_VMADOT, match_opcode, 0 },
+{"smt.vmadotu",  0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,VtXpw&8", MATCH_SMT_VMADOTU, MASK_SMT_VMADOTU, match_opcode, 0 },
+{"smt.vmadotsu", 0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,VtXpw&8", MATCH_SMT_VMADOTSU, MASK_SMT_VMADOTSU, match_opcode, 0 },
+{"smt.vmadotus", 0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,VtXpw&8", MATCH_SMT_VMADOTUS, MASK_SMT_VMADOTUS, match_opcode, 0 },
+/* Int Sliding Window Multi-Accumulation.  */
+/* Sliding Value = 1.  */
+{"smt.vmadot1u",  0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw&8", MATCH_SMT_VMADOT1U, MASK_SMT_VMADOT1U, match_opcode, 0 },
+{"smt.vmadot1",   0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw&8", MATCH_SMT_VMADOT1, MASK_SMT_VMADOT1, match_opcode, 0 },
+{"smt.vmadot1su", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw&8", MATCH_SMT_VMADOT1SU, MASK_SMT_VMADOT1SU, match_opcode, 0 },
+{"smt.vmadot1us", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw&8", MATCH_SMT_VMADOT1US, MASK_SMT_VMADOT1US, match_opcode, 0 },
+/* Sliding Value = 2.  */
+{"smt.vmadot2u",  0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw&8", MATCH_SMT_VMADOT2U, MASK_SMT_VMADOT2U, match_opcode, 0 },
+{"smt.vmadot2",   0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw&8", MATCH_SMT_VMADOT2, MASK_SMT_VMADOT2, match_opcode, 0 },
+{"smt.vmadot2su", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw&8", MATCH_SMT_VMADOT2SU, MASK_SMT_VMADOT2SU, match_opcode, 0 },
+{"smt.vmadot2us", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw&8", MATCH_SMT_VMADOT2US, MASK_SMT_VMADOT2US, match_opcode, 0 },
+/* Sliding Value = 3.  */
+{"smt.vmadot3u",  0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw&8", MATCH_SMT_VMADOT3U, MASK_SMT_VMADOT3U, match_opcode, 0 },
+{"smt.vmadot3",   0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw&8", MATCH_SMT_VMADOT3, MASK_SMT_VMADOT3, match_opcode, 0 },
+{"smt.vmadot3su", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw&8", MATCH_SMT_VMADOT3SU, MASK_SMT_VMADOT3SU, match_opcode, 0 },
+{"smt.vmadot3us", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw&8", MATCH_SMT_VMADOT3US, MASK_SMT_VMADOT3US, match_opcode, 0 },
+
 /* Terminate the list.  */
 {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}
 };
-- 
2.34.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v4 0/1] RISC-V: Add SpacemiT vendor extensions xsmtvdot
  2026-04-10 15:11               ` [PATCH v4 0/1] " Mark Zhuang
  2026-04-10 15:11                 ` [PATCH v4 1/1] " Mark Zhuang
@ 2026-04-16  6:28                 ` Jan Beulich
  1 sibling, 0 replies; 16+ messages in thread
From: Jan Beulich @ 2026-04-16  6:28 UTC (permalink / raw)
  To: Mark Zhuang; +Cc: nelson.chu1990, binutils

On 10.04.2026 17:11, Mark Zhuang wrote:
> From: Mark Zhuang <mark.zhuang@spacemit.com>
> 
> On 10.04.2026 12:25, Jan Beulich wrote:
>> Doesn't this file need to be named x-smt-vdot-fail.d, for the test to be
>> executed at all? And isn't the real x-smt-vdot-fail.l missing?
> 
> I apologize for not catching this before sending. v4 fix it. Thanks.
> 
>> Only i8 being tested? (And no invalid i<N> in the -fail test?)
> 
> For the SpacemiT K1 chip (X60 core), only i8 is currently implemented
> in hardware, so only i8 being tested. In the v4 update, the fail test
> has been extended to include invalid i<N>

Hmm, depends on how you look at it. Something like "i3" isn't tested for
example.

> Although the K1 hardware only supports i8, we retain handling for
> i2, i4, and i16 in the patch because the upcoming SpacemiT K3 chip
> will utilize them, allowing for code reuse.
> We are currently preparing the documentation and patches for K3.

I'm not a RISC-V maintainer, but if you ask me: Please have testing for
what you implement. That may either mean to drop the handling of "i2",
"i4", and "i16", or properly add support. (I'll comment on that part of
the patch itself, too.)

Jan

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v4 1/1] RISC-V: Add SpacemiT vendor extensions xsmtvdot
  2026-04-10 15:11                 ` [PATCH v4 1/1] " Mark Zhuang
@ 2026-04-16  6:34                   ` Jan Beulich
  2026-04-16  8:49                   ` Andreas Schwab
  1 sibling, 0 replies; 16+ messages in thread
From: Jan Beulich @ 2026-04-16  6:34 UTC (permalink / raw)
  To: Mark Zhuang; +Cc: nelson.chu1990, binutils

On 10.04.2026 17:11, Mark Zhuang wrote:
> @@ -4286,6 +4315,85 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
>  		    }
>  		  break;
>  
> +		case 'p': /* Vendor-specific (SpacemiT) operands.  */
> +		  switch (*++oparg)
> +		    {
> +		    case 'V':
> +		      switch (*++oparg)
> +			{
> +			case 'd':
> +			  if (!reg_lookup (&asarg, RCLASS_VECR, &regno))
> +			    break;
> +			  if ((regno & 0x1) != 0)
> +			    {
> +			      error.msg = _("illegal operands (vd must be even)");
> +			      break;
> +			    }
> +			  INSERT_OPERAND (SPACEMIT_IME_VD, *ip, regno>>1);
> +			  continue;
> +			case 's':
> +			  if (!reg_lookup (&asarg, RCLASS_VECR, &regno))
> +			    break;
> +			  if ((regno & 0x1) != 0)
> +			    {
> +			      error.msg = _("illegal operands (vs1 must be even)");
> +			      break;
> +			    }
> +			  INSERT_OPERAND (SPACEMIT_IME_VS1, *ip, regno>>1);
> +			  continue;
> +			default:
> +			  goto unknown_riscv_ip_operand;
> +			}
> +		      break;
> +		    case 'w':
> +		      /* Xpw&S ... bits in S indicates whether
> +			 corresponding item is permitted.  */
> +		      if (*++oparg != '&')
> +			goto unknown_riscv_ip_operand;
> +		      size_t n = strtol (oparg + 1, (char **)&oparg, 16);
> +		      oparg--;
> +		      /* Optional operand: if not present, default to i8.  */
> +		      if (*asarg == '\0')
> +			regno = 3;
> +		      else if (*asarg == ',')
> +			{
> +			  asarg++;
> +			  if (strncmp (asarg, "i2", 2) == 0)
> +			    {
> +			      regno = 0;
> +			      asarg += 2;
> +			    }
> +			  else if (strncmp (asarg, "i16", 3) == 0)
> +			    {
> +			      regno = 1;
> +			      asarg += 3;
> +			    }
> +			  else if (strncmp (asarg, "i4", 2) == 0)
> +			    {
> +			      regno = 2;
> +			      asarg += 2;
> +			    }
> +			  else if (strncmp (asarg, "i8", 2) == 0)
> +			    {
> +			      regno = 3;
> +			      asarg += 2;
> +			    }
> +			  else
> +			    break;
> +			}
> +		      else
> +			goto unknown_riscv_ip_operand;
> +		      if ((n & (1 << regno)) == 0)

I will admit that I didn't try to find this aspectr in the spec, but the
above looks pretty implausible. The mapping from "i<N>" to regno isn't
a regular transformation. What does <N> stand for? Why would the regno-
th bit need to be clear? IOW why would "i2" require "&4" in the opcode
pattern, or "i16" require "&2", when "i8" requires "&8"? How do the two
numbers fit together?

Jan

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v4 1/1] RISC-V: Add SpacemiT vendor extensions xsmtvdot
  2026-04-10 15:11                 ` [PATCH v4 1/1] " Mark Zhuang
  2026-04-16  6:34                   ` Jan Beulich
@ 2026-04-16  8:49                   ` Andreas Schwab
  2026-05-03 14:33                     ` [PATCH v5 0/2] RISC-V: Add SpacemiT IME vendor extensions (xsmtvdot, xsmtvdotii) Mark Zhuang
  1 sibling, 1 reply; 16+ messages in thread
From: Andreas Schwab @ 2026-04-16  8:49 UTC (permalink / raw)
  To: Mark Zhuang; +Cc: binutils, jbeulich, nelson.chu1990

On Apr 10 2026, Mark Zhuang wrote:

> +		    case 'w':
> +		      /* Xpw&S ... bits in S indicates whether
> +			 corresponding item is permitted.  */
> +		      if (*++oparg != '&')
> +			goto unknown_riscv_ip_operand;
> +		      size_t n = strtol (oparg + 1, (char **)&oparg, 16);
> +		      oparg--;
> +		      /* Optional operand: if not present, default to i8.  */
> +		      if (*asarg == '\0')
> +			regno = 3;
> +		      else if (*asarg == ',')
> +			{
> +			  asarg++;
> +			  if (strncmp (asarg, "i2", 2) == 0)
> +			    {
> +			      regno = 0;
> +			      asarg += 2;
> +			    }
> +			  else if (strncmp (asarg, "i16", 3) == 0)
> +			    {
> +			      regno = 1;
> +			      asarg += 3;
> +			    }
> +			  else if (strncmp (asarg, "i4", 2) == 0)
> +			    {
> +			      regno = 2;
> +			      asarg += 2;
> +			    }
> +			  else if (strncmp (asarg, "i8", 2) == 0)
> +			    {
> +			      regno = 3;
> +			      asarg += 2;
> +			    }
> +			  else
> +			    break;

That does not appear to diagnose an invalid operand.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v5 0/2] RISC-V: Add SpacemiT IME vendor extensions (xsmtvdot, xsmtvdotii)
  2026-04-16  8:49                   ` Andreas Schwab
@ 2026-05-03 14:33                     ` Mark Zhuang
  2026-05-03 14:33                       ` [PATCH v5 1/2] RISC-V: Add SpacemiT vendor extension xsmtvdot Mark Zhuang
  2026-05-03 14:33                       ` [PATCH v5 2/2] RISC-V: Add SpacemiT vendor extension xsmtvdotii Mark Zhuang
  0 siblings, 2 replies; 16+ messages in thread
From: Mark Zhuang @ 2026-05-03 14:33 UTC (permalink / raw)
  To: binutils; +Cc: jbeulich, schwab

From: Mark Zhuang <mark.zhuang@spacemit.com>

This series adds support for two SpacemiT vendor extensions implementing
subsets of the SpacemiT Intrinsic Matrix Extension (IME) specification:

  - XsmtVdot v1.0: Vector Dot Product Extension, implemented by SpacemiT X60
  - XsmtVdotII v1.0: Vector Dot Product II Extension, implemented by
    SpacemiT A100

Thanks to Jan and Andreas Schwab for reviewing.

Changes since v4:
1. Simplify code: replace the Xpw&S hex-bitmask operand with direct
   operand matching, and remove unused i2 and i16 variants.
2. Add more test coverage.
3. Handle the unmatched operand branch with a proper error.
4. Add a new patch to support the xsmtvdotii extension.  When v1 was
   submitted five months ago, the xsmtvdotii spec was not yet ready.
   Now that the SpacemiT K3 documentation has been published, we are
   including it in this series.

Mark Zhuang (2):
  RISC-V: Add SpacemiT vendor extension xsmtvdot
  RISC-V: Add SpacemiT vendor extension xsmtvdotii

 bfd/elfxx-riscv.c                            |  18 ++
 gas/NEWS                                     |   3 +
 gas/config/tc-riscv.c                        | 183 +++++++++++++++++++
 gas/doc/c-riscv.texi                         |  16 ++
 gas/testsuite/gas/riscv/march-help.l         |   2 +
 gas/testsuite/gas/riscv/x-smt-vdot-fail.d    |   3 +
 gas/testsuite/gas/riscv/x-smt-vdot-fail.l    |  73 ++++++++
 gas/testsuite/gas/riscv/x-smt-vdot-fail.s    |  50 +++++
 gas/testsuite/gas/riscv/x-smt-vdot-ii-fail.d |   3 +
 gas/testsuite/gas/riscv/x-smt-vdot-ii-fail.l |  99 ++++++++++
 gas/testsuite/gas/riscv/x-smt-vdot-ii-fail.s | 118 ++++++++++++
 gas/testsuite/gas/riscv/x-smt-vdot-ii.d      |  69 +++++++
 gas/testsuite/gas/riscv/x-smt-vdot-ii.s      |  73 ++++++++
 gas/testsuite/gas/riscv/x-smt-vdot.d         |  41 +++++
 gas/testsuite/gas/riscv/x-smt-vdot.s         |  33 ++++
 include/opcode/riscv-opc.h                   |  79 ++++++++
 include/opcode/riscv.h                       |  16 ++
 opcodes/riscv-dis.c                          |  69 +++++++
 opcodes/riscv-opc.c                          |  58 ++++++
 19 files changed, 1006 insertions(+)
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-fail.d
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-fail.l
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-fail.s
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-ii-fail.d
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-ii-fail.l
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-ii-fail.s
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-ii.d
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-ii.s
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot.d
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot.s

-- 
2.34.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v5 1/2] RISC-V: Add SpacemiT vendor extension xsmtvdot
  2026-05-03 14:33                     ` [PATCH v5 0/2] RISC-V: Add SpacemiT IME vendor extensions (xsmtvdot, xsmtvdotii) Mark Zhuang
@ 2026-05-03 14:33                       ` Mark Zhuang
  2026-05-03 14:33                       ` [PATCH v5 2/2] RISC-V: Add SpacemiT vendor extension xsmtvdotii Mark Zhuang
  1 sibling, 0 replies; 16+ messages in thread
From: Mark Zhuang @ 2026-05-03 14:33 UTC (permalink / raw)
  To: binutils; +Cc: jbeulich, schwab

From: Mark Zhuang <mark.zhuang@spacemit.com>

SpacemiT defines Intrinsic Matrix Extension (IME) specification [1].
SpacemiT X60 implements version 1.0 of the SpacemiT Vector Dot Product
Extension (XsmtVdot v1.0) [2], a subset of the full IME specification.

[1] https://github.com/spacemit-com/riscv-ime-extension-spec/releases/download/v1.0/spacemit-ime-asciidoc.pdf
[2] https://github.com/spacemit-com/docs-ai/blob/main/en/architecture/ime_extension.md
---
 bfd/elfxx-riscv.c                         |  7 ++
 gas/NEWS                                  |  3 +
 gas/config/tc-riscv.c                     | 81 +++++++++++++++++++++++
 gas/doc/c-riscv.texi                      |  8 +++
 gas/testsuite/gas/riscv/march-help.l      |  1 +
 gas/testsuite/gas/riscv/x-smt-vdot-fail.d |  3 +
 gas/testsuite/gas/riscv/x-smt-vdot-fail.l | 73 ++++++++++++++++++++
 gas/testsuite/gas/riscv/x-smt-vdot-fail.s | 50 ++++++++++++++
 gas/testsuite/gas/riscv/x-smt-vdot.d      | 41 ++++++++++++
 gas/testsuite/gas/riscv/x-smt-vdot.s      | 33 +++++++++
 include/opcode/riscv-opc.h                | 38 +++++++++++
 include/opcode/riscv.h                    |  9 +++
 opcodes/riscv-dis.c                       | 33 +++++++++
 opcodes/riscv-opc.c                       | 23 +++++++
 14 files changed, 403 insertions(+)
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-fail.d
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-fail.l
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-fail.s
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot.d
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot.s

diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 83134f81c96..5fdbc1698af 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1229,6 +1229,8 @@ static const struct riscv_implicit_subset riscv_implicit_subsets[] =
   {"xtheadvector", "+zicsr", check_implicit_always},
   {"xtheadzvamo", "+zaamo", check_implicit_always},
 
+  {"xsmtvdot", "+zve32x", check_implicit_always},
+
   {"v", "+zve64d,+zvl128b", check_implicit_always},
   {"zvfh", "+zvfhmin,+zfhmin", check_implicit_always},
   {"zvfhmin", "+zve32f", check_implicit_always},
@@ -1644,6 +1646,7 @@ static const struct riscv_supported_ext riscv_supported_vendor_x_ext[] =
   {"xmipscmov",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
   {"xmipsexectl",	ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
   {"xmipslsp",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
+  {"xsmtvdot",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
   {NULL, 0, 0, 0, 0}
 };
 
@@ -3062,6 +3065,8 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
       return riscv_subset_supports (rps, "xmipsexectl");
     case INSN_CLASS_XMIPSLSP:
       return riscv_subset_supports (rps, "xmipslsp");
+    case INSN_CLASS_XSMTVDOT:
+      return riscv_subset_supports (rps, "xsmtvdot");
     default:
       rps->error_handler
         (_("internal: unreachable INSN_CLASS_*"));
@@ -3365,6 +3370,8 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
       return "xsfvqmaccdod";
     case INSN_CLASS_XSFVFNRCLIPXFQF:
       return "xsfvfnrclipxfqf";
+    case INSN_CLASS_XSMTVDOT:
+      return "xsmtvdot";
     default:
       rps->error_handler
         (_("internal: unreachable INSN_CLASS_*"));
diff --git a/gas/NEWS b/gas/NEWS
index e384d1135c0..e47d55b05dc 100644
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,5 +1,8 @@
 -*- text -*-
 
+* Add support for RISC-V vendor extensions:
+  SpacemiT: xsmtvdot v1.0.
+
 Changes in 2.46:
 
 * Add support for AMD Zen6 processor.
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index b00b530b0bd..9c062ad3521 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -1770,6 +1770,30 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
 		    goto unknown_validate_operand;
 		}
 		break;
+	    case 'p': /* Vendor-specific (SpacemiT) operands.  */
+	      switch (*++oparg)
+		{
+		case 'V':
+		  switch (*++oparg)
+		    {
+		    case 'd':
+		      USE_BITS (OP_MASK_SPACEMIT_IME_VD, OP_SH_SPACEMIT_IME_VD);
+		      break;
+		    case 's':
+		      USE_BITS (OP_MASK_SPACEMIT_IME_VS1,
+				OP_SH_SPACEMIT_IME_VS1);
+		      break;
+		    default:
+		      goto unknown_validate_operand;
+		    }
+		  break;
+		case 'w':
+		  USE_BITS (OP_MASK_SPACEMIT_IME_WI, OP_SH_SPACEMIT_IME_WI);
+		  break;
+		default:
+		  goto unknown_validate_operand;
+		}
+	      break;
 	    default:
 	      goto unknown_validate_operand;
 	    }
@@ -4286,6 +4310,63 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 		    }
 		  break;
 
+		case 'p': /* Vendor-specific (SpacemiT) operands.  */
+		  switch (*++oparg)
+		    {
+		    case 'V':
+		      switch (*++oparg)
+			{
+			case 'd':
+			  if (!reg_lookup (&asarg, RCLASS_VECR, &regno))
+			    break;
+			  if ((regno & 0x1) != 0)
+			    {
+			      error.msg
+				= _("illegal operands (vd must be even)");
+			      error.missing_ext = NULL;
+			      goto out;
+			    }
+			  INSERT_OPERAND (SPACEMIT_IME_VD, *ip, regno>>1);
+			  continue;
+			case 's':
+			  if (!reg_lookup (&asarg, RCLASS_VECR, &regno))
+			    break;
+			  if ((regno & 0x1) != 0)
+			    {
+			      error.msg
+				= _("illegal operands (vs1 must be even)");
+			      error.missing_ext = NULL;
+			      goto out;
+			    }
+			  INSERT_OPERAND (SPACEMIT_IME_VS1, *ip, regno>>1);
+			  continue;
+			default:
+			  goto unknown_riscv_ip_operand;
+			}
+		      break;
+		    case 'w':
+		      /* Xpw: optional data-width suffix, i8 only (WI=3).
+			 If omitted, defaults to i8.  */
+		      if (*asarg == ',')
+			{
+			  if (strcmp (asarg + 1, "i8") != 0)
+			    {
+			      error.msg
+				= _("illegal operands (invalid data type)");
+			      error.missing_ext = NULL;
+			      goto out;
+			    }
+			  asarg += 3;
+			}
+		      else if (*asarg != '\0')
+			goto unknown_riscv_ip_operand;
+		      regno = 3;
+		      INSERT_OPERAND (SPACEMIT_IME_WI, *ip, regno);
+		      continue;
+		    default:
+		      goto unknown_riscv_ip_operand;
+		    }
+		  break;
 		default:
 		  goto unknown_riscv_ip_operand;
 		}
diff --git a/gas/doc/c-riscv.texi b/gas/doc/c-riscv.texi
index c6c4081c204..0b1a4265843 100644
--- a/gas/doc/c-riscv.texi
+++ b/gas/doc/c-riscv.texi
@@ -918,4 +918,12 @@ The XMipsSlsp extension provides instructions mips.ldp, mips.lwp, mips.sdp and m
 
 It is documented in @url{https://mips.com/wp-content/uploads/2025/03/P8700-F_Programmers_Reference_Manual_Rev1.82_3-19-2025.pdf}.
 
+@item XSmtVdot
+The XSmtVdot extension provides instructions for vector dot.
+
+SpacemiT defines Intrinsic Matrix Extension (IME) specification,
+documented in @url{https://github.com/spacemit-com/riscv-ime-extension-spec/releases/download/v1.0/spacemit-ime-asciidoc.pdf}.
+SpacemiT X60 implement version 1.0 of the SpacemiT Vector Dot Product Extension (XsmtVdot v1.0), a subset of the full IME specification,
+documented in @url{https://github.com/spacemit-com/docs-ai/blob/main/en/architecture/ime_extension.md}.
+
 @end table
diff --git a/gas/testsuite/gas/riscv/march-help.l b/gas/testsuite/gas/riscv/march-help.l
index 0ce2f896735..6e52669e9a4 100644
--- a/gas/testsuite/gas/riscv/march-help.l
+++ b/gas/testsuite/gas/riscv/march-help.l
@@ -186,3 +186,4 @@ All available -march extensions for RISC-V:
 	xmipscmov                               1.0
 	xmipsexectl                             1.0
 	xmipslsp                                1.0
+	xsmtvdot                                1.0
diff --git a/gas/testsuite/gas/riscv/x-smt-vdot-fail.d b/gas/testsuite/gas/riscv/x-smt-vdot-fail.d
new file mode 100644
index 00000000000..bf8fb0f87ac
--- /dev/null
+++ b/gas/testsuite/gas/riscv/x-smt-vdot-fail.d
@@ -0,0 +1,3 @@
+#as: -march=rv64gcv_xsmtvdot -I$srcdir/$subdir/
+#source: x-smt-vdot-fail.s
+#error_output: x-smt-vdot-fail.l
diff --git a/gas/testsuite/gas/riscv/x-smt-vdot-fail.l b/gas/testsuite/gas/riscv/x-smt-vdot-fail.l
new file mode 100644
index 00000000000..77511d45296
--- /dev/null
+++ b/gas/testsuite/gas/riscv/x-smt-vdot-fail.l
@@ -0,0 +1,73 @@
+.*: Assembler messages:
+.*:3: Error: illegal operands \(vd must be even\) `smt.vmadot v1,v3,v4'
+.*:4: Error: illegal operands \(vd must be even\) `smt.vmadotu v1,v3,v4'
+.*:5: Error: illegal operands \(vd must be even\) `smt.vmadotsu v1,v3,v4'
+.*:6: Error: illegal operands \(vd must be even\) `smt.vmadotus v1,v3,v4'
+.*:7: Error: illegal operands \(vd must be even\) `smt.vmadot1u v1,v4,v5'
+.*:8: Error: illegal operands \(vd must be even\) `smt.vmadot1 v1,v4,v5'
+.*:9: Error: illegal operands \(vd must be even\) `smt.vmadot1su v1,v4,v5'
+.*:10: Error: illegal operands \(vd must be even\) `smt.vmadot1us v1,v4,v5'
+.*:11: Error: illegal operands \(vd must be even\) `smt.vmadot2u v1,v4,v5'
+.*:12: Error: illegal operands \(vd must be even\) `smt.vmadot2 v1,v4,v5'
+.*:13: Error: illegal operands \(vd must be even\) `smt.vmadot2su v1,v4,v5'
+.*:14: Error: illegal operands \(vd must be even\) `smt.vmadot2us v1,v4,v5'
+.*:15: Error: illegal operands \(vd must be even\) `smt.vmadot3u v1,v4,v5'
+.*:16: Error: illegal operands \(vd must be even\) `smt.vmadot3 v1,v4,v5'
+.*:17: Error: illegal operands \(vd must be even\) `smt.vmadot3su v1,v4,v5'
+.*:18: Error: illegal operands \(vd must be even\) `smt.vmadot3us v1,v4,v5'
+.*:20: Error: illegal operands \(vs1 must be even\) `smt.vmadot1u v2,v3,v5'
+.*:21: Error: illegal operands \(vs1 must be even\) `smt.vmadot1 v2,v3,v5'
+.*:22: Error: illegal operands \(vs1 must be even\) `smt.vmadot1su v2,v3,v5'
+.*:23: Error: illegal operands \(vs1 must be even\) `smt.vmadot1us v2,v3,v5'
+.*:24: Error: illegal operands \(vs1 must be even\) `smt.vmadot2u v2,v3,v5'
+.*:25: Error: illegal operands \(vs1 must be even\) `smt.vmadot2 v2,v3,v5'
+.*:26: Error: illegal operands \(vs1 must be even\) `smt.vmadot2su v2,v3,v5'
+.*:27: Error: illegal operands \(vs1 must be even\) `smt.vmadot2us v2,v3,v5'
+.*:28: Error: illegal operands \(vs1 must be even\) `smt.vmadot3u v2,v3,v5'
+.*:29: Error: illegal operands \(vs1 must be even\) `smt.vmadot3 v2,v3,v5'
+.*:30: Error: illegal operands \(vs1 must be even\) `smt.vmadot3su v2,v3,v5'
+.*:31: Error: illegal operands \(vs1 must be even\) `smt.vmadot3us v2,v3,v5'
+.*:33: Error: illegal operands \(invalid data type\) `smt.vmadot v2,v3,v4,i1'
+.*:34: Error: illegal operands \(invalid data type\) `smt.vmadot v2,v3,v4,i2'
+.*:35: Error: illegal operands \(invalid data type\) `smt.vmadot v2,v3,v4,i3'
+.*:36: Error: illegal operands \(invalid data type\) `smt.vmadot v2,v3,v4,i4'
+.*:37: Error: illegal operands \(invalid data type\) `smt.vmadot v2,v3,v4,i5'
+.*:38: Error: illegal operands \(invalid data type\) `smt.vmadot v2,v3,v4,i7'
+.*:39: Error: illegal operands \(invalid data type\) `smt.vmadot v2,v3,v4,i16'
+.*:40: Error: illegal operands \(invalid data type\) `smt.vmadot v2,v3,v4,i32'
+.*:41: Error: illegal operands \(invalid data type\) `smt.vmadot v2,v3,v4,i64'
+.*:42: Error: illegal operands \(invalid data type\) `smt.vmadot1u v2,v4,v5,i2'
+.*:43: Error: illegal operands \(invalid data type\) `smt.vmadot2u v2,v4,v5,i4'
+.*:44: Error: illegal operands \(invalid data type\) `smt.vmadot3u v2,v4,v5,i16'
+.*:2: Error: unrecognized opcode `smt.vmadot v2,v3,v4', extension `xsmtvdot' required
+.*:3: Error: unrecognized opcode `smt.vmadotu v2,v3,v4', extension `xsmtvdot' required
+.*:4: Error: unrecognized opcode `smt.vmadotsu v2,v3,v4', extension `xsmtvdot' required
+.*:5: Error: unrecognized opcode `smt.vmadotus v2,v3,v4', extension `xsmtvdot' required
+.*:6: Error: unrecognized opcode `smt.vmadot1u v2,v4,v5', extension `xsmtvdot' required
+.*:7: Error: unrecognized opcode `smt.vmadot1 v2,v4,v5', extension `xsmtvdot' required
+.*:8: Error: unrecognized opcode `smt.vmadot1su v2,v4,v5', extension `xsmtvdot' required
+.*:9: Error: unrecognized opcode `smt.vmadot1us v2,v4,v5', extension `xsmtvdot' required
+.*:10: Error: unrecognized opcode `smt.vmadot2u v2,v4,v5', extension `xsmtvdot' required
+.*:11: Error: unrecognized opcode `smt.vmadot2 v2,v4,v5', extension `xsmtvdot' required
+.*:12: Error: unrecognized opcode `smt.vmadot2su v2,v4,v5', extension `xsmtvdot' required
+.*:13: Error: unrecognized opcode `smt.vmadot2us v2,v4,v5', extension `xsmtvdot' required
+.*:14: Error: unrecognized opcode `smt.vmadot3u v2,v4,v5', extension `xsmtvdot' required
+.*:15: Error: unrecognized opcode `smt.vmadot3 v2,v4,v5', extension `xsmtvdot' required
+.*:16: Error: unrecognized opcode `smt.vmadot3su v2,v4,v5', extension `xsmtvdot' required
+.*:17: Error: unrecognized opcode `smt.vmadot3us v2,v4,v5', extension `xsmtvdot' required
+.*:18: Error: unrecognized opcode `smt.vmadot v2,v3,v4,i8', extension `xsmtvdot' required
+.*:19: Error: unrecognized opcode `smt.vmadotu v2,v3,v4,i8', extension `xsmtvdot' required
+.*:20: Error: unrecognized opcode `smt.vmadotsu v2,v3,v4,i8', extension `xsmtvdot' required
+.*:21: Error: unrecognized opcode `smt.vmadotus v2,v3,v4,i8', extension `xsmtvdot' required
+.*:22: Error: unrecognized opcode `smt.vmadot1u v2,v4,v5,i8', extension `xsmtvdot' required
+.*:23: Error: unrecognized opcode `smt.vmadot1 v2,v4,v5,i8', extension `xsmtvdot' required
+.*:24: Error: unrecognized opcode `smt.vmadot1su v2,v4,v5,i8', extension `xsmtvdot' required
+.*:25: Error: unrecognized opcode `smt.vmadot1us v2,v4,v5,i8', extension `xsmtvdot' required
+.*:26: Error: unrecognized opcode `smt.vmadot2u v2,v4,v5,i8', extension `xsmtvdot' required
+.*:27: Error: unrecognized opcode `smt.vmadot2 v2,v4,v5,i8', extension `xsmtvdot' required
+.*:28: Error: unrecognized opcode `smt.vmadot2su v2,v4,v5,i8', extension `xsmtvdot' required
+.*:29: Error: unrecognized opcode `smt.vmadot2us v2,v4,v5,i8', extension `xsmtvdot' required
+.*:30: Error: unrecognized opcode `smt.vmadot3u v2,v4,v5,i8', extension `xsmtvdot' required
+.*:31: Error: unrecognized opcode `smt.vmadot3 v2,v4,v5,i8', extension `xsmtvdot' required
+.*:32: Error: unrecognized opcode `smt.vmadot3su v2,v4,v5,i8', extension `xsmtvdot' required
+.*:33: Error: unrecognized opcode `smt.vmadot3us v2,v4,v5,i8', extension `xsmtvdot' required
diff --git a/gas/testsuite/gas/riscv/x-smt-vdot-fail.s b/gas/testsuite/gas/riscv/x-smt-vdot-fail.s
new file mode 100644
index 00000000000..af33b693e54
--- /dev/null
+++ b/gas/testsuite/gas/riscv/x-smt-vdot-fail.s
@@ -0,0 +1,50 @@
+target:
+	# vmadot/vmadot1/2/3: vd must be even
+	smt.vmadot v1, v3, v4
+	smt.vmadotu v1, v3, v4
+	smt.vmadotsu v1, v3, v4
+	smt.vmadotus v1, v3, v4
+	smt.vmadot1u v1, v4, v5
+	smt.vmadot1 v1, v4, v5
+	smt.vmadot1su v1, v4, v5
+	smt.vmadot1us v1, v4, v5
+	smt.vmadot2u v1, v4, v5
+	smt.vmadot2 v1, v4, v5
+	smt.vmadot2su v1, v4, v5
+	smt.vmadot2us v1, v4, v5
+	smt.vmadot3u v1, v4, v5
+	smt.vmadot3 v1, v4, v5
+	smt.vmadot3su v1, v4, v5
+	smt.vmadot3us v1, v4, v5
+	# vmadot1/2/3: vs1 must be even
+	smt.vmadot1u v2, v3, v5
+	smt.vmadot1 v2, v3, v5
+	smt.vmadot1su v2, v3, v5
+	smt.vmadot1us v2, v3, v5
+	smt.vmadot2u v2, v3, v5
+	smt.vmadot2 v2, v3, v5
+	smt.vmadot2su v2, v3, v5
+	smt.vmadot2us v2, v3, v5
+	smt.vmadot3u v2, v3, v5
+	smt.vmadot3 v2, v3, v5
+	smt.vmadot3su v2, v3, v5
+	smt.vmadot3us v2, v3, v5
+	# vmadot/vmadot1/2/3: invalid data type
+	smt.vmadot v2, v3, v4, i1
+	smt.vmadot v2, v3, v4, i2
+	smt.vmadot v2, v3, v4, i3
+	smt.vmadot v2, v3, v4, i4
+	smt.vmadot v2, v3, v4, i5
+	smt.vmadot v2, v3, v4, i7
+	smt.vmadot v2, v3, v4, i16
+	smt.vmadot v2, v3, v4, i32
+	smt.vmadot v2, v3, v4, i64
+	smt.vmadot1u v2, v4, v5, i2
+	smt.vmadot2u v2, v4, v5, i4
+	smt.vmadot3u v2, v4, v5, i16
+
+	# xsmtvdot - extension required
+	.option push
+	.option arch, rv64gcv
+	.include "x-smt-vdot.s"
+	.option pop
diff --git a/gas/testsuite/gas/riscv/x-smt-vdot.d b/gas/testsuite/gas/riscv/x-smt-vdot.d
new file mode 100644
index 00000000000..6f86236785d
--- /dev/null
+++ b/gas/testsuite/gas/riscv/x-smt-vdot.d
@@ -0,0 +1,41 @@
+#as: -march=rv64gcv_xsmtvdot
+#objdump: -dr
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+e241b12b[ 	]+smt.vmadot[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e241812b[ 	]+smt.vmadotu[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e241a12b[ 	]+smt.vmadotsu[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e241912b[ 	]+smt.vmadotus[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e652012b[ 	]+smt.vmadot1u[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652312b[ 	]+smt.vmadot1[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652212b[ 	]+smt.vmadot1su[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652112b[ 	]+smt.vmadot1us[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652412b[ 	]+smt.vmadot2u[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652712b[ 	]+smt.vmadot2[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652612b[ 	]+smt.vmadot2su[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652512b[ 	]+smt.vmadot2us[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652812b[ 	]+smt.vmadot3u[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652b12b[ 	]+smt.vmadot3[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652a12b[ 	]+smt.vmadot3su[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652912b[ 	]+smt.vmadot3us[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e241b12b[ 	]+smt.vmadot[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e241812b[ 	]+smt.vmadotu[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e241a12b[ 	]+smt.vmadotsu[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e241912b[ 	]+smt.vmadotus[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e652012b[ 	]+smt.vmadot1u[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652312b[ 	]+smt.vmadot1[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652212b[ 	]+smt.vmadot1su[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652112b[ 	]+smt.vmadot1us[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652412b[ 	]+smt.vmadot2u[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652712b[ 	]+smt.vmadot2[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652612b[ 	]+smt.vmadot2su[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652512b[ 	]+smt.vmadot2us[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652812b[ 	]+smt.vmadot3u[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652b12b[ 	]+smt.vmadot3[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652a12b[ 	]+smt.vmadot3su[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652912b[ 	]+smt.vmadot3us[ 	]+v2,v4,v5
diff --git a/gas/testsuite/gas/riscv/x-smt-vdot.s b/gas/testsuite/gas/riscv/x-smt-vdot.s
new file mode 100644
index 00000000000..a9991de4fc3
--- /dev/null
+++ b/gas/testsuite/gas/riscv/x-smt-vdot.s
@@ -0,0 +1,33 @@
+target:
+	smt.vmadot v2, v3, v4
+	smt.vmadotu v2, v3, v4
+	smt.vmadotsu v2, v3, v4
+	smt.vmadotus v2, v3, v4
+	smt.vmadot1u v2, v4, v5
+	smt.vmadot1 v2, v4, v5
+	smt.vmadot1su v2, v4, v5
+	smt.vmadot1us v2, v4, v5
+	smt.vmadot2u v2, v4, v5
+	smt.vmadot2 v2, v4, v5
+	smt.vmadot2su v2, v4, v5
+	smt.vmadot2us v2, v4, v5
+	smt.vmadot3u v2, v4, v5
+	smt.vmadot3 v2, v4, v5
+	smt.vmadot3su v2, v4, v5
+	smt.vmadot3us v2, v4, v5
+	smt.vmadot v2, v3, v4, i8
+	smt.vmadotu v2, v3, v4, i8
+	smt.vmadotsu v2, v3, v4, i8
+	smt.vmadotus v2, v3, v4, i8
+	smt.vmadot1u v2, v4, v5, i8
+	smt.vmadot1 v2, v4, v5, i8
+	smt.vmadot1su v2, v4, v5, i8
+	smt.vmadot1us v2, v4, v5, i8
+	smt.vmadot2u v2, v4, v5, i8
+	smt.vmadot2 v2, v4, v5, i8
+	smt.vmadot2su v2, v4, v5, i8
+	smt.vmadot2us v2, v4, v5, i8
+	smt.vmadot3u v2, v4, v5, i8
+	smt.vmadot3 v2, v4, v5, i8
+	smt.vmadot3su v2, v4, v5, i8
+	smt.vmadot3us v2, v4, v5, i8
diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
index 6f2775c6152..31b7e7a06a7 100644
--- a/include/opcode/riscv-opc.h
+++ b/include/opcode/riscv-opc.h
@@ -3852,6 +3852,44 @@
 #define MASK_MIPS_PAUSE  0xffffffff
 #define MATCH_MIPS_PREF 0x0000000b
 #define MASK_MIPS_PREF 0xe000707f
+/* SpacemiT custom instruction.  */
+/* Int Matrix Multiplicative Accumulation.  */
+#define MATCH_SMT_VMADOT   0x8200302b
+#define MASK_SMT_VMADOT    0x9e0070ff
+#define MATCH_SMT_VMADOTU  0x8200002b
+#define MASK_SMT_VMADOTU   0x9e0070ff
+#define MATCH_SMT_VMADOTSU 0x8200202b
+#define MASK_SMT_VMADOTSU  0x9e0070ff
+#define MATCH_SMT_VMADOTUS 0x8200102b
+#define MASK_SMT_VMADOTUS  0x9e0070ff
+/* Int Sliding Window Multiplicative Accumulation.  */
+/* Sliding Value = 1.  */
+#define MATCH_SMT_VMADOT1U 0x8600002b
+#define MASK_SMT_VMADOT1U  0x9e00f0ff
+#define MATCH_SMT_VMADOT1  0x8600302b
+#define MASK_SMT_VMADOT1   0x9e00f0ff
+#define MATCH_SMT_VMADOT1SU 0x8600202b
+#define MASK_SMT_VMADOT1SU 0x9e00f0ff
+#define MATCH_SMT_VMADOT1US 0x8600102b
+#define MASK_SMT_VMADOT1US 0x9e00f0ff
+/* Sliding Value = 2.  */
+#define MATCH_SMT_VMADOT2U 0x8600402b
+#define MASK_SMT_VMADOT2U 0x9e00f0ff
+#define MATCH_SMT_VMADOT2 0x8600702b
+#define MASK_SMT_VMADOT2 0x9e00f0ff
+#define MATCH_SMT_VMADOT2SU 0x8600602b
+#define MASK_SMT_VMADOT2SU 0x9e00f0ff
+#define MATCH_SMT_VMADOT2US 0x8600502b
+#define MASK_SMT_VMADOT2US 0x9e00f0ff
+/* Sliding Value = 3.  */
+#define MATCH_SMT_VMADOT3U 0x8600802b
+#define MASK_SMT_VMADOT3U 0x9e00f0ff
+#define MATCH_SMT_VMADOT3 0x8600b02b
+#define MASK_SMT_VMADOT3 0x9e00f0ff
+#define MATCH_SMT_VMADOT3SU 0x8600a02b
+#define MASK_SMT_VMADOT3SU 0x9e00f0ff
+#define MATCH_SMT_VMADOT3US 0x8600902b
+#define MASK_SMT_VMADOT3US 0x9e00f0ff
 /* Unprivileged Counter/Timers CSR addresses.  */
 #define CSR_CYCLE 0xc00
 #define CSR_TIME 0xc01
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index de105f5df8b..3a32abfcf3c 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -419,6 +419,14 @@ static inline unsigned int riscv_insn_length (insn_t insn)
 #define OP_MASK_MIPS_SDP_OFFSET25   0x3
 #define OP_SH_MIPS_SDP_OFFSET25     25
 
+/* SpacemiT fields.  */
+#define OP_MASK_SPACEMIT_IME_VD		0xf
+#define OP_SH_SPACEMIT_IME_VD		8
+#define OP_MASK_SPACEMIT_IME_VS1	0xf
+#define OP_SH_SPACEMIT_IME_VS1		16
+#define OP_MASK_SPACEMIT_IME_WI		0x3
+#define OP_SH_SPACEMIT_IME_WI		29
+
 /* ABI names for selected x-registers.  */
 
 #define X_ZERO 0
@@ -606,6 +614,7 @@ enum riscv_insn_class
   INSN_CLASS_XMIPSCMOV,
   INSN_CLASS_XMIPSEXECTL,
   INSN_CLASS_XMIPSLSP,
+  INSN_CLASS_XSMTVDOT,
 };
 
 /* This structure holds information for a particular instruction.  */
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index eda802ff420..93d41343772 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -917,6 +917,39 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 		  goto undefined_modifier;
 		}
 	      break;
+	    case 'p': /* Vendor-specific (SpacemiT) operands.  */
+	      switch (*++oparg)
+		{
+		case 'V':
+		  switch (*++oparg)
+		    {
+		    case 'd':
+		      unsigned vd = EXTRACT_OPERAND (SPACEMIT_IME_VD, l) * 2;
+		      print (info->stream, dis_style_register, "%s",
+			     riscv_vecr_names_numeric[vd]);
+		      break;
+		    case 's':
+		      unsigned vs = EXTRACT_OPERAND (SPACEMIT_IME_VS1, l) * 2;
+		      print (info->stream, dis_style_register, "%s",
+			     riscv_vecr_names_numeric[vs]);
+		      break;
+		    default:
+		      goto undefined_modifier;
+		    }
+		  break;
+		case 'w':
+		  /* Xpw: optional data-width suffix, i8 only.  WI==3 (i8)
+		     is the default and is omitted from the output.  */
+		  {
+		    unsigned wi = EXTRACT_OPERAND (SPACEMIT_IME_WI, l);
+		    if (wi != 3)
+		      goto undefined_modifier;
+		  }
+		  break;
+		default:
+		  goto undefined_modifier;
+		}
+	      break;
 	    default:
 	      goto undefined_modifier;
 	    }
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 54887c97880..417918bb6f6 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -3579,6 +3579,29 @@ const struct riscv_opcode riscv_opcodes[] =
 {"mips.sdp", 0, INSN_CLASS_XMIPSLSP, "t,r,Xm^(s)", MATCH_MIPS_SDP, MASK_MIPS_SDP, match_opcode, 0 },
 {"mips.swp", 0, INSN_CLASS_XMIPSLSP, "t,r,Xm&(s)", MATCH_MIPS_SWP, MASK_MIPS_SWP, match_opcode, 0 },
 
+/* SpacemiT custom instructions.  */
+/* Int Matrix Multi-Accumulation.  */
+{"smt.vmadot",   0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,VtXpw", MATCH_SMT_VMADOT, MASK_SMT_VMADOT, match_opcode, 0 },
+{"smt.vmadotu",  0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,VtXpw", MATCH_SMT_VMADOTU, MASK_SMT_VMADOTU, match_opcode, 0 },
+{"smt.vmadotsu", 0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,VtXpw", MATCH_SMT_VMADOTSU, MASK_SMT_VMADOTSU, match_opcode, 0 },
+{"smt.vmadotus", 0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,VtXpw", MATCH_SMT_VMADOTUS, MASK_SMT_VMADOTUS, match_opcode, 0 },
+/* Int Sliding Window Multi-Accumulation.  */
+/* Sliding Value = 1.  */
+{"smt.vmadot1u",  0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT1U, MASK_SMT_VMADOT1U, match_opcode, 0 },
+{"smt.vmadot1",   0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT1, MASK_SMT_VMADOT1, match_opcode, 0 },
+{"smt.vmadot1su", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT1SU, MASK_SMT_VMADOT1SU, match_opcode, 0 },
+{"smt.vmadot1us", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT1US, MASK_SMT_VMADOT1US, match_opcode, 0 },
+/* Sliding Value = 2.  */
+{"smt.vmadot2u",  0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT2U, MASK_SMT_VMADOT2U, match_opcode, 0 },
+{"smt.vmadot2",   0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT2, MASK_SMT_VMADOT2, match_opcode, 0 },
+{"smt.vmadot2su", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT2SU, MASK_SMT_VMADOT2SU, match_opcode, 0 },
+{"smt.vmadot2us", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT2US, MASK_SMT_VMADOT2US, match_opcode, 0 },
+/* Sliding Value = 3.  */
+{"smt.vmadot3u",  0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT3U, MASK_SMT_VMADOT3U, match_opcode, 0 },
+{"smt.vmadot3",   0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT3, MASK_SMT_VMADOT3, match_opcode, 0 },
+{"smt.vmadot3su", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT3SU, MASK_SMT_VMADOT3SU, match_opcode, 0 },
+{"smt.vmadot3us", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT3US, MASK_SMT_VMADOT3US, match_opcode, 0 },
+
 /* Terminate the list.  */
 {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}
 };
-- 
2.34.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v5 2/2] RISC-V: Add SpacemiT vendor extension xsmtvdotii
  2026-05-03 14:33                     ` [PATCH v5 0/2] RISC-V: Add SpacemiT IME vendor extensions (xsmtvdot, xsmtvdotii) Mark Zhuang
  2026-05-03 14:33                       ` [PATCH v5 1/2] RISC-V: Add SpacemiT vendor extension xsmtvdot Mark Zhuang
@ 2026-05-03 14:33                       ` Mark Zhuang
  1 sibling, 0 replies; 16+ messages in thread
From: Mark Zhuang @ 2026-05-03 14:33 UTC (permalink / raw)
  To: binutils; +Cc: jbeulich, schwab

From: Mark Zhuang <mark.zhuang@spacemit.com>

SpacemiT defines Intrinsic Matrix Extension (IME) specification [1].
SpacemiT A100 implements version 1.0 of the SpacemiT Vector Dot Product
II Extension (XsmtVdotII v1.0) [2], a subset of the full IME specification.

[1] https://github.com/spacemit-com/riscv-ime-extension-spec/releases/download/v1.0/spacemit-ime-asciidoc.pdf
[2] https://github.com/spacemit-com/docs-ai/blob/main/en/architecture/ime_extension.md
---
 bfd/elfxx-riscv.c                            |  11 ++
 gas/NEWS                                     |   2 +-
 gas/config/tc-riscv.c                        | 102 ++++++++++++++++
 gas/doc/c-riscv.texi                         |   8 ++
 gas/testsuite/gas/riscv/march-help.l         |   1 +
 gas/testsuite/gas/riscv/x-smt-vdot-fail.l    |  64 +++++-----
 gas/testsuite/gas/riscv/x-smt-vdot-ii-fail.d |   3 +
 gas/testsuite/gas/riscv/x-smt-vdot-ii-fail.l |  99 ++++++++++++++++
 gas/testsuite/gas/riscv/x-smt-vdot-ii-fail.s | 118 +++++++++++++++++++
 gas/testsuite/gas/riscv/x-smt-vdot-ii.d      |  69 +++++++++++
 gas/testsuite/gas/riscv/x-smt-vdot-ii.s      |  73 ++++++++++++
 include/opcode/riscv-opc.h                   |  41 +++++++
 include/opcode/riscv.h                       |   7 ++
 opcodes/riscv-dis.c                          |  36 ++++++
 opcodes/riscv-opc.c                          |  67 ++++++++---
 15 files changed, 652 insertions(+), 49 deletions(-)
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-ii-fail.d
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-ii-fail.l
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-ii-fail.s
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-ii.d
 create mode 100644 gas/testsuite/gas/riscv/x-smt-vdot-ii.s

diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 5fdbc1698af..d54c4abafd7 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1230,6 +1230,7 @@ static const struct riscv_implicit_subset riscv_implicit_subsets[] =
   {"xtheadzvamo", "+zaamo", check_implicit_always},
 
   {"xsmtvdot", "+zve32x", check_implicit_always},
+  {"xsmtvdotii", "+xsmtvdot", check_implicit_always},
 
   {"v", "+zve64d,+zvl128b", check_implicit_always},
   {"zvfh", "+zvfhmin,+zfhmin", check_implicit_always},
@@ -1647,6 +1648,7 @@ static const struct riscv_supported_ext riscv_supported_vendor_x_ext[] =
   {"xmipsexectl",	ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
   {"xmipslsp",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
   {"xsmtvdot",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
+  {"xsmtvdotii",	ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
   {NULL, 0, 0, 0, 0}
 };
 
@@ -3067,6 +3069,11 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
       return riscv_subset_supports (rps, "xmipslsp");
     case INSN_CLASS_XSMTVDOT:
       return riscv_subset_supports (rps, "xsmtvdot");
+    case INSN_CLASS_XSMTVDOTII:
+      return riscv_subset_supports (rps, "xsmtvdotii");
+    case INSN_CLASS_XSMTVDOT_OR_XSMTVDOTII:
+      return (riscv_subset_supports (rps, "xsmtvdot")
+	      || riscv_subset_supports (rps, "xsmtvdotii"));
     default:
       rps->error_handler
         (_("internal: unreachable INSN_CLASS_*"));
@@ -3372,6 +3379,10 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
       return "xsfvfnrclipxfqf";
     case INSN_CLASS_XSMTVDOT:
       return "xsmtvdot";
+    case INSN_CLASS_XSMTVDOTII:
+      return "xsmtvdotii";
+    case INSN_CLASS_XSMTVDOT_OR_XSMTVDOTII:
+      return _("xsmtvdot' or `xsmtvdotii");
     default:
       rps->error_handler
         (_("internal: unreachable INSN_CLASS_*"));
diff --git a/gas/NEWS b/gas/NEWS
index e47d55b05dc..2d86f0c1719 100644
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,7 +1,7 @@
 -*- text -*-
 
 * Add support for RISC-V vendor extensions:
-  SpacemiT: xsmtvdot v1.0.
+  SpacemiT: xsmtvdot v1.0, xsmtvdotii v1.0.
 
 Changes in 2.46:
 
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 9c062ad3521..841f227e931 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -1771,6 +1771,8 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
 		}
 		break;
 	    case 'p': /* Vendor-specific (SpacemiT) operands.  */
+	      size_t n;
+	      size_t s;
 	      switch (*++oparg)
 		{
 		case 'V':
@@ -1783,11 +1785,29 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
 		      USE_BITS (OP_MASK_SPACEMIT_IME_VS1,
 				OP_SH_SPACEMIT_IME_VS1);
 		      break;
+		    case 'm':
+		      USE_BITS (OP_MASK_SPACEMIT_IME_VMASK,
+				OP_SH_SPACEMIT_IME_VMASK);
+		      break;
 		    default:
 		      goto unknown_validate_operand;
 		    }
 		  break;
+		case 'u': /* Integer immediate, 'XpuN@S' ...
+			     N-bit unsigned immediate at bit S.  */
+		  n = strtol (oparg + 1, (char **)&oparg, 10);
+		  if (*oparg != '@')
+		    goto unknown_validate_operand;
+		  s = strtol (oparg + 1, (char **)&oparg, 10);
+		  oparg--;
+		  USE_IMM (n, s);
+		  break;
+		case 'n':
+		case 'b':
+		  used_bits |= ENCODE_SPACEMIT_IME_UIMM2_SP (-1U);
+		  break;
 		case 'w':
+		case 'x':
 		  USE_BITS (OP_MASK_SPACEMIT_IME_WI, OP_SH_SPACEMIT_IME_WI);
 		  break;
 		default:
@@ -4311,6 +4331,8 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 		  break;
 
 		case 'p': /* Vendor-specific (SpacemiT) operands.  */
+		  size_t n;
+		  size_t s;
 		  switch (*++oparg)
 		    {
 		    case 'V':
@@ -4340,10 +4362,66 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 			    }
 			  INSERT_OPERAND (SPACEMIT_IME_VS1, *ip, regno>>1);
 			  continue;
+			case 'm':
+			  if (!reg_lookup (&asarg, RCLASS_VECR, &regno))
+			    break;
+			  if (regno >= 2)
+			    {
+			      error.msg
+				= _("illegal operands (mask must be v0/v1)");
+			      error.missing_ext = NULL;
+			      goto out;
+			    }
+			  INSERT_OPERAND (SPACEMIT_IME_VMASK, *ip, regno);
+			  continue;
 			default:
 			  goto unknown_riscv_ip_operand;
 			}
 		      break;
+		    case 'u': /* Integer immediate, 'XpuN@S' ...
+				 N-bit unsigned immediate at bit S.  */
+		      n = strtol (oparg + 1, (char **)&oparg, 10);
+		      if (*oparg != '@')
+			goto unknown_riscv_ip_operand;
+		      s = strtol (oparg + 1, (char **)&oparg, 10);
+		      oparg--;
+		      my_getExpression (imm_expr, asarg, force_reloc);
+		      check_absolute_expr (ip, imm_expr, false);
+		      if (!VALIDATE_U_IMM (imm_expr->X_add_number, n))
+			as_bad (_("improper immediate value (%"PRIu64")"),
+				imm_expr->X_add_number);
+		      INSERT_IMM (n, s, *ip, imm_expr->X_add_number);
+		      imm_expr->X_op = O_absent;
+		      asarg = expr_parse_end;
+		      continue;
+		    case 'n': /* Xpn: stride (0-1), paired with Xpx.  */
+		      my_getExpression (imm_expr, asarg, force_reloc);
+		      check_absolute_expr (ip, imm_expr, false);
+		      if (imm_expr->X_add_number < 0
+			  || imm_expr->X_add_number >= 2)
+			break;
+		      ip->insn_opcode
+			|= ENCODE_SPACEMIT_IME_UIMM2_SP
+			     (imm_expr->X_add_number);
+		      imm_expr->X_op = O_absent;
+		      asarg = expr_parse_end;
+		      continue;
+		    case 'b': /* Xpb: stride (0-3), paired with Xpw.  */
+		      my_getExpression (imm_expr, asarg, force_reloc);
+		      check_absolute_expr (ip, imm_expr, false);
+		      if (imm_expr->X_add_number < 0
+			  || imm_expr->X_add_number >= 4)
+			{
+			  as_bad (_("bad value for stride field,"
+				    " value must be 0..3"));
+			  break;
+			}
+		      ip->insn_opcode
+			|= ENCODE_SPACEMIT_IME_UIMM2_SP
+			     (imm_expr->X_add_number);
+		      imm_expr->X_op = O_absent;
+		      asarg = expr_parse_end;
+		      continue;
 		    case 'w':
 		      /* Xpw: optional data-width suffix, i8 only (WI=3).
 			 If omitted, defaults to i8.  */
@@ -4363,6 +4441,30 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 		      regno = 3;
 		      INSERT_OPERAND (SPACEMIT_IME_WI, *ip, regno);
 		      continue;
+		    case 'x':
+		      /* Xpx: optional data-width suffix, i4 or i8 (WI=2/3).
+			 If omitted, defaults to i8.  */
+		      if (*asarg == ',')
+			{
+			  if (strcmp (asarg + 1, "i4") == 0)
+			    regno = 2;
+			  else if (strcmp (asarg + 1, "i8") == 0)
+			    regno = 3;
+			  else
+			    {
+			      error.msg
+				= _("illegal operands (invalid data type)");
+			      error.missing_ext = NULL;
+			      goto out;
+			    }
+			  asarg += 3;
+			}
+		      else if (*asarg != '\0')
+			goto unknown_riscv_ip_operand;
+		      else
+			regno = 3;
+		      INSERT_OPERAND (SPACEMIT_IME_WI, *ip, regno);
+		      continue;
 		    default:
 		      goto unknown_riscv_ip_operand;
 		    }
diff --git a/gas/doc/c-riscv.texi b/gas/doc/c-riscv.texi
index 0b1a4265843..0cd21c8d157 100644
--- a/gas/doc/c-riscv.texi
+++ b/gas/doc/c-riscv.texi
@@ -926,4 +926,12 @@ documented in @url{https://github.com/spacemit-com/riscv-ime-extension-spec/rele
 SpacemiT X60 implement version 1.0 of the SpacemiT Vector Dot Product Extension (XsmtVdot v1.0), a subset of the full IME specification,
 documented in @url{https://github.com/spacemit-com/docs-ai/blob/main/en/architecture/ime_extension.md}.
 
+@item XSmtVdotII
+The XSmtVdotII extension provides instructions for vector dot.
+
+SpacemiT defines Intrinsic Matrix Extension (IME) specification,
+documented in @url{https://github.com/spacemit-com/riscv-ime-extension-spec/releases/download/v1.0/spacemit-ime-asciidoc.pdf}.
+SpacemiT A100 implement version 1.0 of the SpacemiT Vector Dot Product II Extension (XsmtVdotII v1.0), a subset of the full IME specification,
+documented in @url{https://github.com/spacemit-com/docs-ai/blob/main/en/architecture/ime_extension.md}.
+
 @end table
diff --git a/gas/testsuite/gas/riscv/march-help.l b/gas/testsuite/gas/riscv/march-help.l
index 6e52669e9a4..d70d1cf2bb6 100644
--- a/gas/testsuite/gas/riscv/march-help.l
+++ b/gas/testsuite/gas/riscv/march-help.l
@@ -187,3 +187,4 @@ All available -march extensions for RISC-V:
 	xmipsexectl                             1.0
 	xmipslsp                                1.0
 	xsmtvdot                                1.0
+	xsmtvdotii                              1.0
diff --git a/gas/testsuite/gas/riscv/x-smt-vdot-fail.l b/gas/testsuite/gas/riscv/x-smt-vdot-fail.l
index 77511d45296..56c7185d2a5 100644
--- a/gas/testsuite/gas/riscv/x-smt-vdot-fail.l
+++ b/gas/testsuite/gas/riscv/x-smt-vdot-fail.l
@@ -39,35 +39,35 @@
 .*:42: Error: illegal operands \(invalid data type\) `smt.vmadot1u v2,v4,v5,i2'
 .*:43: Error: illegal operands \(invalid data type\) `smt.vmadot2u v2,v4,v5,i4'
 .*:44: Error: illegal operands \(invalid data type\) `smt.vmadot3u v2,v4,v5,i16'
-.*:2: Error: unrecognized opcode `smt.vmadot v2,v3,v4', extension `xsmtvdot' required
-.*:3: Error: unrecognized opcode `smt.vmadotu v2,v3,v4', extension `xsmtvdot' required
-.*:4: Error: unrecognized opcode `smt.vmadotsu v2,v3,v4', extension `xsmtvdot' required
-.*:5: Error: unrecognized opcode `smt.vmadotus v2,v3,v4', extension `xsmtvdot' required
-.*:6: Error: unrecognized opcode `smt.vmadot1u v2,v4,v5', extension `xsmtvdot' required
-.*:7: Error: unrecognized opcode `smt.vmadot1 v2,v4,v5', extension `xsmtvdot' required
-.*:8: Error: unrecognized opcode `smt.vmadot1su v2,v4,v5', extension `xsmtvdot' required
-.*:9: Error: unrecognized opcode `smt.vmadot1us v2,v4,v5', extension `xsmtvdot' required
-.*:10: Error: unrecognized opcode `smt.vmadot2u v2,v4,v5', extension `xsmtvdot' required
-.*:11: Error: unrecognized opcode `smt.vmadot2 v2,v4,v5', extension `xsmtvdot' required
-.*:12: Error: unrecognized opcode `smt.vmadot2su v2,v4,v5', extension `xsmtvdot' required
-.*:13: Error: unrecognized opcode `smt.vmadot2us v2,v4,v5', extension `xsmtvdot' required
-.*:14: Error: unrecognized opcode `smt.vmadot3u v2,v4,v5', extension `xsmtvdot' required
-.*:15: Error: unrecognized opcode `smt.vmadot3 v2,v4,v5', extension `xsmtvdot' required
-.*:16: Error: unrecognized opcode `smt.vmadot3su v2,v4,v5', extension `xsmtvdot' required
-.*:17: Error: unrecognized opcode `smt.vmadot3us v2,v4,v5', extension `xsmtvdot' required
-.*:18: Error: unrecognized opcode `smt.vmadot v2,v3,v4,i8', extension `xsmtvdot' required
-.*:19: Error: unrecognized opcode `smt.vmadotu v2,v3,v4,i8', extension `xsmtvdot' required
-.*:20: Error: unrecognized opcode `smt.vmadotsu v2,v3,v4,i8', extension `xsmtvdot' required
-.*:21: Error: unrecognized opcode `smt.vmadotus v2,v3,v4,i8', extension `xsmtvdot' required
-.*:22: Error: unrecognized opcode `smt.vmadot1u v2,v4,v5,i8', extension `xsmtvdot' required
-.*:23: Error: unrecognized opcode `smt.vmadot1 v2,v4,v5,i8', extension `xsmtvdot' required
-.*:24: Error: unrecognized opcode `smt.vmadot1su v2,v4,v5,i8', extension `xsmtvdot' required
-.*:25: Error: unrecognized opcode `smt.vmadot1us v2,v4,v5,i8', extension `xsmtvdot' required
-.*:26: Error: unrecognized opcode `smt.vmadot2u v2,v4,v5,i8', extension `xsmtvdot' required
-.*:27: Error: unrecognized opcode `smt.vmadot2 v2,v4,v5,i8', extension `xsmtvdot' required
-.*:28: Error: unrecognized opcode `smt.vmadot2su v2,v4,v5,i8', extension `xsmtvdot' required
-.*:29: Error: unrecognized opcode `smt.vmadot2us v2,v4,v5,i8', extension `xsmtvdot' required
-.*:30: Error: unrecognized opcode `smt.vmadot3u v2,v4,v5,i8', extension `xsmtvdot' required
-.*:31: Error: unrecognized opcode `smt.vmadot3 v2,v4,v5,i8', extension `xsmtvdot' required
-.*:32: Error: unrecognized opcode `smt.vmadot3su v2,v4,v5,i8', extension `xsmtvdot' required
-.*:33: Error: unrecognized opcode `smt.vmadot3us v2,v4,v5,i8', extension `xsmtvdot' required
+.*:2: Error: unrecognized opcode `smt.vmadot v2,v3,v4', extension `xsmtvdot' or `xsmtvdotii' required
+.*:3: Error: unrecognized opcode `smt.vmadotu v2,v3,v4', extension `xsmtvdot' or `xsmtvdotii' required
+.*:4: Error: unrecognized opcode `smt.vmadotsu v2,v3,v4', extension `xsmtvdot' or `xsmtvdotii' required
+.*:5: Error: unrecognized opcode `smt.vmadotus v2,v3,v4', extension `xsmtvdot' or `xsmtvdotii' required
+.*:6: Error: unrecognized opcode `smt.vmadot1u v2,v4,v5', extension `xsmtvdot' or `xsmtvdotii' required
+.*:7: Error: unrecognized opcode `smt.vmadot1 v2,v4,v5', extension `xsmtvdot' or `xsmtvdotii' required
+.*:8: Error: unrecognized opcode `smt.vmadot1su v2,v4,v5', extension `xsmtvdot' or `xsmtvdotii' required
+.*:9: Error: unrecognized opcode `smt.vmadot1us v2,v4,v5', extension `xsmtvdot' or `xsmtvdotii' required
+.*:10: Error: unrecognized opcode `smt.vmadot2u v2,v4,v5', extension `xsmtvdot' or `xsmtvdotii' required
+.*:11: Error: unrecognized opcode `smt.vmadot2 v2,v4,v5', extension `xsmtvdot' or `xsmtvdotii' required
+.*:12: Error: unrecognized opcode `smt.vmadot2su v2,v4,v5', extension `xsmtvdot' or `xsmtvdotii' required
+.*:13: Error: unrecognized opcode `smt.vmadot2us v2,v4,v5', extension `xsmtvdot' or `xsmtvdotii' required
+.*:14: Error: unrecognized opcode `smt.vmadot3u v2,v4,v5', extension `xsmtvdot' or `xsmtvdotii' required
+.*:15: Error: unrecognized opcode `smt.vmadot3 v2,v4,v5', extension `xsmtvdot' or `xsmtvdotii' required
+.*:16: Error: unrecognized opcode `smt.vmadot3su v2,v4,v5', extension `xsmtvdot' or `xsmtvdotii' required
+.*:17: Error: unrecognized opcode `smt.vmadot3us v2,v4,v5', extension `xsmtvdot' or `xsmtvdotii' required
+.*:18: Error: unrecognized opcode `smt.vmadot v2,v3,v4,i8', extension `xsmtvdot' or `xsmtvdotii' required
+.*:19: Error: unrecognized opcode `smt.vmadotu v2,v3,v4,i8', extension `xsmtvdot' or `xsmtvdotii' required
+.*:20: Error: unrecognized opcode `smt.vmadotsu v2,v3,v4,i8', extension `xsmtvdot' or `xsmtvdotii' required
+.*:21: Error: unrecognized opcode `smt.vmadotus v2,v3,v4,i8', extension `xsmtvdot' or `xsmtvdotii' required
+.*:22: Error: unrecognized opcode `smt.vmadot1u v2,v4,v5,i8', extension `xsmtvdot' or `xsmtvdotii' required
+.*:23: Error: unrecognized opcode `smt.vmadot1 v2,v4,v5,i8', extension `xsmtvdot' or `xsmtvdotii' required
+.*:24: Error: unrecognized opcode `smt.vmadot1su v2,v4,v5,i8', extension `xsmtvdot' or `xsmtvdotii' required
+.*:25: Error: unrecognized opcode `smt.vmadot1us v2,v4,v5,i8', extension `xsmtvdot' or `xsmtvdotii' required
+.*:26: Error: unrecognized opcode `smt.vmadot2u v2,v4,v5,i8', extension `xsmtvdot' or `xsmtvdotii' required
+.*:27: Error: unrecognized opcode `smt.vmadot2 v2,v4,v5,i8', extension `xsmtvdot' or `xsmtvdotii' required
+.*:28: Error: unrecognized opcode `smt.vmadot2su v2,v4,v5,i8', extension `xsmtvdot' or `xsmtvdotii' required
+.*:29: Error: unrecognized opcode `smt.vmadot2us v2,v4,v5,i8', extension `xsmtvdot' or `xsmtvdotii' required
+.*:30: Error: unrecognized opcode `smt.vmadot3u v2,v4,v5,i8', extension `xsmtvdot' or `xsmtvdotii' required
+.*:31: Error: unrecognized opcode `smt.vmadot3 v2,v4,v5,i8', extension `xsmtvdot' or `xsmtvdotii' required
+.*:32: Error: unrecognized opcode `smt.vmadot3su v2,v4,v5,i8', extension `xsmtvdot' or `xsmtvdotii' required
+.*:33: Error: unrecognized opcode `smt.vmadot3us v2,v4,v5,i8', extension `xsmtvdot' or `xsmtvdotii' required
diff --git a/gas/testsuite/gas/riscv/x-smt-vdot-ii-fail.d b/gas/testsuite/gas/riscv/x-smt-vdot-ii-fail.d
new file mode 100644
index 00000000000..4b5944511b0
--- /dev/null
+++ b/gas/testsuite/gas/riscv/x-smt-vdot-ii-fail.d
@@ -0,0 +1,3 @@
+#as: -march=rv64gcv_xsmtvdotii
+#source: x-smt-vdot-ii-fail.s
+#error_output: x-smt-vdot-ii-fail.l
diff --git a/gas/testsuite/gas/riscv/x-smt-vdot-ii-fail.l b/gas/testsuite/gas/riscv/x-smt-vdot-ii-fail.l
new file mode 100644
index 00000000000..3bc22641173
--- /dev/null
+++ b/gas/testsuite/gas/riscv/x-smt-vdot-ii-fail.l
@@ -0,0 +1,99 @@
+.*: Assembler messages:
+.*:3: Error: illegal operands \(vd must be even\) `smt.vmadot v1,v3,v4'
+.*:4: Error: illegal operands \(vd must be even\) `smt.vmadotu v1,v3,v4'
+.*:5: Error: illegal operands \(vd must be even\) `smt.vmadotsu v1,v3,v4'
+.*:6: Error: illegal operands \(vd must be even\) `smt.vmadotus v1,v3,v4'
+.*:7: Error: illegal operands \(vd must be even\) `smt.vmadot1u v1,v4,v5'
+.*:8: Error: illegal operands \(vd must be even\) `smt.vmadot1 v1,v4,v5'
+.*:9: Error: illegal operands \(vd must be even\) `smt.vmadot1su v1,v4,v5'
+.*:10: Error: illegal operands \(vd must be even\) `smt.vmadot1us v1,v4,v5'
+.*:11: Error: illegal operands \(vd must be even\) `smt.vmadot2u v1,v4,v5'
+.*:12: Error: illegal operands \(vd must be even\) `smt.vmadot2 v1,v4,v5'
+.*:13: Error: illegal operands \(vd must be even\) `smt.vmadot2su v1,v4,v5'
+.*:14: Error: illegal operands \(vd must be even\) `smt.vmadot2us v1,v4,v5'
+.*:15: Error: illegal operands \(vd must be even\) `smt.vmadot3u v1,v4,v5'
+.*:16: Error: illegal operands \(vd must be even\) `smt.vmadot3 v1,v4,v5'
+.*:17: Error: illegal operands \(vd must be even\) `smt.vmadot3su v1,v4,v5'
+.*:18: Error: illegal operands \(vd must be even\) `smt.vmadot3us v1,v4,v5'
+.*:20: Error: illegal operands \(vs1 must be even\) `smt.vmadot1u v2,v3,v5'
+.*:21: Error: illegal operands \(vs1 must be even\) `smt.vmadot1 v2,v3,v5'
+.*:22: Error: illegal operands \(vs1 must be even\) `smt.vmadot1su v2,v3,v5'
+.*:23: Error: illegal operands \(vs1 must be even\) `smt.vmadot1us v2,v3,v5'
+.*:24: Error: illegal operands \(vs1 must be even\) `smt.vmadot2u v2,v3,v5'
+.*:25: Error: illegal operands \(vs1 must be even\) `smt.vmadot2 v2,v3,v5'
+.*:26: Error: illegal operands \(vs1 must be even\) `smt.vmadot2su v2,v3,v5'
+.*:27: Error: illegal operands \(vs1 must be even\) `smt.vmadot2us v2,v3,v5'
+.*:28: Error: illegal operands \(vs1 must be even\) `smt.vmadot3u v2,v3,v5'
+.*:29: Error: illegal operands \(vs1 must be even\) `smt.vmadot3 v2,v3,v5'
+.*:30: Error: illegal operands \(vs1 must be even\) `smt.vmadot3su v2,v3,v5'
+.*:31: Error: illegal operands \(vs1 must be even\) `smt.vmadot3us v2,v3,v5'
+.*:33: Error: illegal operands \(invalid data type\) `smt.vmadot1u v2,v4,v5,i4'
+.*:34: Error: illegal operands \(invalid data type\) `smt.vmadot1 v2,v4,v5,i4'
+.*:35: Error: illegal operands \(invalid data type\) `smt.vmadot1su v2,v4,v5,i4'
+.*:36: Error: illegal operands \(invalid data type\) `smt.vmadot1us v2,v4,v5,i4'
+.*:37: Error: illegal operands \(invalid data type\) `smt.vmadot2u v2,v4,v5,i4'
+.*:38: Error: illegal operands \(invalid data type\) `smt.vmadot2 v2,v4,v5,i4'
+.*:39: Error: illegal operands \(invalid data type\) `smt.vmadot2su v2,v4,v5,i4'
+.*:40: Error: illegal operands \(invalid data type\) `smt.vmadot2us v2,v4,v5,i4'
+.*:41: Error: illegal operands \(invalid data type\) `smt.vmadot3u v2,v4,v5,i4'
+.*:42: Error: illegal operands \(invalid data type\) `smt.vmadot3 v2,v4,v5,i4'
+.*:43: Error: illegal operands \(invalid data type\) `smt.vmadot3su v2,v4,v5,i4'
+.*:44: Error: illegal operands \(invalid data type\) `smt.vmadot3us v2,v4,v5,i4'
+.*:46: Error: illegal operands \(invalid data type\) `smt.vmadot v2,v3,v4,i1'
+.*:47: Error: illegal operands \(invalid data type\) `smt.vmadot v2,v3,v4,i2'
+.*:48: Error: illegal operands \(invalid data type\) `smt.vmadot v2,v3,v4,i3'
+.*:49: Error: illegal operands \(invalid data type\) `smt.vmadot v2,v3,v4,i5'
+.*:50: Error: illegal operands \(invalid data type\) `smt.vmadot v2,v3,v4,i7'
+.*:51: Error: illegal operands \(invalid data type\) `smt.vmadot v2,v3,v4,i16'
+.*:52: Error: illegal operands \(invalid data type\) `smt.vmadot v2,v3,v4,i32'
+.*:53: Error: illegal operands \(invalid data type\) `smt.vmadot v2,v3,v4,i64'
+.*:54: Error: illegal operands \(invalid data type\) `smt.vmadot v2,v3,v4,i40'
+.*:55: Error: illegal operands \(invalid data type\) `smt.vmadot1u v2,v4,v5,i2'
+.*:56: Error: illegal operands \(invalid data type\) `smt.vmadot2u v2,v4,v5,i16'
+.*:57: Error: illegal operands \(invalid data type\) `smt.vmadot3u v2,v4,v5,i32'
+.*:60: Error: illegal operands \(vd must be even\) `smt.vmadotu.sp v1,v4,v5,v0,0,i8'
+.*:61: Error: illegal operands \(vs1 must be even\) `smt.vmadotu.sp v2,v3,v5,v0,0,i8'
+.*:63: Error: illegal operands \(mask must be v0/v1\) `smt.vmadotu.sp v2,v4,v5,v2,0,i8'
+.*:65: Error: illegal operands \(invalid data type\) `smt.vmadotu.sp v2,v4,v5,v0,2,i4'
+.*:66: Error: illegal operands \(invalid data type\) `smt.vmadotu.sp v2,v4,v5,v0,3,i4'
+.*:68: Error: bad value for stride field, value must be 0\.\.3
+.*:68: Error: illegal operands `smt.vmadotu.sp v2,v4,v5,v0,4,i8'
+.*:70: Error: illegal operands \(mask must be v0/v1\) `smt.vmadotu.hp v2,v3,v4,v2,0,i4'
+.*:72: Error: improper immediate value \(8\)
+.*:74: Error: illegal operands \(vd must be even\) `smt.vfwmadot v1,v3,v4'
+.*:75: Error: illegal operands \(vd must be even\) `smt.vfwmadot1 v1,v4,v5'
+.*:76: Error: illegal operands \(vd must be even\) `smt.vfwmadot2 v1,v4,v5'
+.*:77: Error: illegal operands \(vd must be even\) `smt.vfwmadot3 v1,v4,v5'
+.*:79: Error: illegal operands \(vs1 must be even\) `smt.vfwmadot1 v2,v3,v5'
+.*:80: Error: illegal operands \(vs1 must be even\) `smt.vfwmadot2 v2,v3,v5'
+.*:81: Error: illegal operands \(vs1 must be even\) `smt.vfwmadot3 v2,v3,v5'
+.*:83: Error: improper immediate value \(4\)
+.*:84: Error: improper immediate value \(4\)
+.*:85: Error: improper immediate value \(4\)
+.*:86: Error: improper immediate value \(4\)
+.*:88: Error: illegal operands \(vd must be even\) `smt.vpack.vv v1,v3,v4,0'
+.*:89: Error: improper immediate value \(4\)
+.*:90: Error: illegal operands \(vd must be even\) `smt.vupack.vv v1,v3,v4,0'
+.*:91: Error: improper immediate value \(4\)
+.*:96: Error: illegal operands \(invalid data type\) \`smt\.vmadot v2,v3,v4,i4'
+.*:97: Error: illegal operands \(invalid data type\) \`smt\.vmadotu v2,v3,v4,i4'
+.*:98: Error: illegal operands \(invalid data type\) \`smt\.vmadotsu v2,v3,v4,i4'
+.*:99: Error: illegal operands \(invalid data type\) \`smt\.vmadotus v2,v3,v4,i4'
+.*:100: Error: unrecognized opcode \`smt\.vmadotu\.sp v2,v4,v5,v0,0,i4', extension \`xsmtvdotii' required
+.*:101: Error: unrecognized opcode \`smt\.vmadot\.sp v2,v4,v5,v0,0,i4', extension \`xsmtvdotii' required
+.*:102: Error: unrecognized opcode \`smt\.vmadotsu\.sp v2,v4,v5,v0,0,i4', extension \`xsmtvdotii' required
+.*:103: Error: unrecognized opcode \`smt\.vmadotus\.sp v2,v4,v5,v0,0,i4', extension \`xsmtvdotii' required
+.*:104: Error: unrecognized opcode \`smt\.vmadotu\.hp v2,v3,v4,v0,0,i4', extension \`xsmtvdotii' required
+.*:105: Error: unrecognized opcode \`smt\.vmadot\.hp v2,v3,v4,v0,0,i4', extension \`xsmtvdotii' required
+.*:106: Error: unrecognized opcode \`smt\.vmadotsu\.hp v2,v3,v4,v0,0,i4', extension \`xsmtvdotii' required
+.*:107: Error: unrecognized opcode \`smt\.vmadotus\.hp v2,v3,v4,v0,0,i4', extension \`xsmtvdotii' required
+.*:108: Error: unrecognized opcode \`smt\.vfwmadot v2,v3,v4', extension \`xsmtvdotii' required
+.*:109: Error: unrecognized opcode \`smt\.vfwmadot1 v2,v4,v5', extension \`xsmtvdotii' required
+.*:110: Error: unrecognized opcode \`smt\.vfwmadot2 v2,v4,v5', extension \`xsmtvdotii' required
+.*:111: Error: unrecognized opcode \`smt\.vfwmadot3 v2,v4,v5', extension \`xsmtvdotii' required
+.*:112: Error: unrecognized opcode \`smt\.vnpack\.vv v2,v3,v4,0', extension \`xsmtvdotii' required
+.*:113: Error: unrecognized opcode \`smt\.vnspack\.vv v2,v3,v4,0', extension \`xsmtvdotii' required
+.*:114: Error: unrecognized opcode \`smt\.vnpack4\.vv v2,v3,v4,0', extension \`xsmtvdotii' required
+.*:115: Error: unrecognized opcode \`smt\.vnspack4\.vv v2,v3,v4,0', extension \`xsmtvdotii' required
+.*:116: Error: unrecognized opcode \`smt\.vpack\.vv v2,v3,v4,0', extension \`xsmtvdotii' required
+.*:117: Error: unrecognized opcode \`smt\.vupack\.vv v2,v3,v4,0', extension \`xsmtvdotii' required
diff --git a/gas/testsuite/gas/riscv/x-smt-vdot-ii-fail.s b/gas/testsuite/gas/riscv/x-smt-vdot-ii-fail.s
new file mode 100644
index 00000000000..9b8877270a5
--- /dev/null
+++ b/gas/testsuite/gas/riscv/x-smt-vdot-ii-fail.s
@@ -0,0 +1,118 @@
+target:
+	# vmadot/vmadot1/2/3: vd must be even
+	smt.vmadot v1, v3, v4
+	smt.vmadotu v1, v3, v4
+	smt.vmadotsu v1, v3, v4
+	smt.vmadotus v1, v3, v4
+	smt.vmadot1u v1, v4, v5
+	smt.vmadot1 v1, v4, v5
+	smt.vmadot1su v1, v4, v5
+	smt.vmadot1us v1, v4, v5
+	smt.vmadot2u v1, v4, v5
+	smt.vmadot2 v1, v4, v5
+	smt.vmadot2su v1, v4, v5
+	smt.vmadot2us v1, v4, v5
+	smt.vmadot3u v1, v4, v5
+	smt.vmadot3 v1, v4, v5
+	smt.vmadot3su v1, v4, v5
+	smt.vmadot3us v1, v4, v5
+	# vmadot1/2/3: vs1 must be even
+	smt.vmadot1u v2, v3, v5
+	smt.vmadot1 v2, v3, v5
+	smt.vmadot1su v2, v3, v5
+	smt.vmadot1us v2, v3, v5
+	smt.vmadot2u v2, v3, v5
+	smt.vmadot2 v2, v3, v5
+	smt.vmadot2su v2, v3, v5
+	smt.vmadot2us v2, v3, v5
+	smt.vmadot3u v2, v3, v5
+	smt.vmadot3 v2, v3, v5
+	smt.vmadot3su v2, v3, v5
+	smt.vmadot3us v2, v3, v5
+	# vmadot1/2/3: i4 invalid (only i8 valid via Xpw)
+	smt.vmadot1u v2, v4, v5, i4
+	smt.vmadot1 v2, v4, v5, i4
+	smt.vmadot1su v2, v4, v5, i4
+	smt.vmadot1us v2, v4, v5, i4
+	smt.vmadot2u v2, v4, v5, i4
+	smt.vmadot2 v2, v4, v5, i4
+	smt.vmadot2su v2, v4, v5, i4
+	smt.vmadot2us v2, v4, v5, i4
+	smt.vmadot3u v2, v4, v5, i4
+	smt.vmadot3 v2, v4, v5, i4
+	smt.vmadot3su v2, v4, v5, i4
+	smt.vmadot3us v2, v4, v5, i4
+	# vmadot/vmadot1/2/3: invalid data type
+	smt.vmadot v2, v3, v4, i1
+	smt.vmadot v2, v3, v4, i2
+	smt.vmadot v2, v3, v4, i3
+	smt.vmadot v2, v3, v4, i5
+	smt.vmadot v2, v3, v4, i7
+	smt.vmadot v2, v3, v4, i16
+	smt.vmadot v2, v3, v4, i32
+	smt.vmadot v2, v3, v4, i64
+	smt.vmadot v2, v3, v4, i40
+	smt.vmadot1u v2, v4, v5, i2
+	smt.vmadot2u v2, v4, v5, i16
+	smt.vmadot3u v2, v4, v5, i32
+
+	# vmadot.sp: vd/vs1 must be even
+	smt.vmadotu.sp v1, v4, v5, v0, 0, i8
+	smt.vmadotu.sp v2, v3, v5, v0, 0, i8
+	# vmadot.sp: mask must be v0/v1
+	smt.vmadotu.sp v2, v4, v5, v2, 0, i8
+	# vmadot.sp: i4 only valid with stride 0/1
+	smt.vmadotu.sp v2, v4, v5, v0, 2, i4
+	smt.vmadotu.sp v2, v4, v5, v0, 3, i4
+	# vmadot.sp: stride >= 4 out of range
+	smt.vmadotu.sp v2, v4, v5, v0, 4, i8
+	# vmadot.hp: mask must be v0/v1
+	smt.vmadotu.hp v2, v3, v4, v2, 0, i4
+	# vmadot.hp: stride >= 8 out of range
+	smt.vmadotu.hp v2, v3, v4, v0, 8, i4
+	# vfwmadot: vd must be even
+	smt.vfwmadot v1, v3, v4
+	smt.vfwmadot1 v1, v4, v5
+	smt.vfwmadot2 v1, v4, v5
+	smt.vfwmadot3 v1, v4, v5
+	# vfwmadot1/2/3: vs1 must be even
+	smt.vfwmadot1 v2, v3, v5
+	smt.vfwmadot2 v2, v3, v5
+	smt.vfwmadot3 v2, v3, v5
+	# vnpack/vnspack/vnpack4/vnspack4: imm2 out of range
+	smt.vnpack.vv v2, v3, v4, 4
+	smt.vnspack.vv v2, v3, v4, 4
+	smt.vnpack4.vv v2, v3, v4, 4
+	smt.vnspack4.vv v2, v3, v4, 4
+	# vpack/vupack: vd must be even, imm2 out of range
+	smt.vpack.vv v1, v3, v4, 0
+	smt.vpack.vv v2, v3, v4, 4
+	smt.vupack.vv v1, v3, v4, 0
+	smt.vupack.vv v2, v3, v4, 4
+
+	# xsmtvdotii - extension required (xsmtvdotii-only insns need xsmtvdotii)
+	.option push
+	.option arch, rv64gcv_xsmtvdot
+	smt.vmadot v2, v3, v4, i4
+	smt.vmadotu v2, v3, v4, i4
+	smt.vmadotsu v2, v3, v4, i4
+	smt.vmadotus v2, v3, v4, i4
+	smt.vmadotu.sp v2, v4, v5, v0, 0, i4
+	smt.vmadot.sp v2, v4, v5, v0, 0, i4
+	smt.vmadotsu.sp v2, v4, v5, v0, 0, i4
+	smt.vmadotus.sp v2, v4, v5, v0, 0, i4
+	smt.vmadotu.hp v2, v3, v4, v0, 0, i4
+	smt.vmadot.hp v2, v3, v4, v0, 0, i4
+	smt.vmadotsu.hp v2, v3, v4, v0, 0, i4
+	smt.vmadotus.hp v2, v3, v4, v0, 0, i4
+	smt.vfwmadot v2, v3, v4
+	smt.vfwmadot1 v2, v4, v5
+	smt.vfwmadot2 v2, v4, v5
+	smt.vfwmadot3 v2, v4, v5
+	smt.vnpack.vv v2, v3, v4, 0
+	smt.vnspack.vv v2, v3, v4, 0
+	smt.vnpack4.vv v2, v3, v4, 0
+	smt.vnspack4.vv v2, v3, v4, 0
+	smt.vpack.vv v2, v3, v4, 0
+	smt.vupack.vv v2, v3, v4, 0
+	.option pop
diff --git a/gas/testsuite/gas/riscv/x-smt-vdot-ii.d b/gas/testsuite/gas/riscv/x-smt-vdot-ii.d
new file mode 100644
index 00000000000..7eb161644fa
--- /dev/null
+++ b/gas/testsuite/gas/riscv/x-smt-vdot-ii.d
@@ -0,0 +1,69 @@
+#as: -march=rv64gcv_xsmtvdotii
+#objdump: -dr
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+c241b12b[ 	]+smt.vmadot[ 	]+v2,v3,v4,i4
+[ 	]+[0-9a-f]+:[ 	]+c241812b[ 	]+smt.vmadotu[ 	]+v2,v3,v4,i4
+[ 	]+[0-9a-f]+:[ 	]+c241a12b[ 	]+smt.vmadotsu[ 	]+v2,v3,v4,i4
+[ 	]+[0-9a-f]+:[ 	]+c241912b[ 	]+smt.vmadotus[ 	]+v2,v3,v4,i4
+[ 	]+[0-9a-f]+:[ 	]+e241b12b[ 	]+smt.vmadot[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e241812b[ 	]+smt.vmadotu[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e241a12b[ 	]+smt.vmadotsu[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e241912b[ 	]+smt.vmadotus[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e241b12b[ 	]+smt.vmadot[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e241812b[ 	]+smt.vmadotu[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e241a12b[ 	]+smt.vmadotsu[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e241912b[ 	]+smt.vmadotus[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+e652012b[ 	]+smt.vmadot1u[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652312b[ 	]+smt.vmadot1[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652212b[ 	]+smt.vmadot1su[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652112b[ 	]+smt.vmadot1us[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652412b[ 	]+smt.vmadot2u[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652712b[ 	]+smt.vmadot2[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652612b[ 	]+smt.vmadot2su[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652512b[ 	]+smt.vmadot2us[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652812b[ 	]+smt.vmadot3u[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652b12b[ 	]+smt.vmadot3[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652a12b[ 	]+smt.vmadot3su[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+e652912b[ 	]+smt.vmadot3us[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+c852012b[ 	]+smt.vmadotu.sp[ 	]+v2,v4,v5,v0,0,i4
+[ 	]+[0-9a-f]+:[ 	]+c85201ab[ 	]+smt.vmadotu.sp[ 	]+v2,v4,v5,v0,1,i4
+[ 	]+[0-9a-f]+:[ 	]+c852312b[ 	]+smt.vmadot.sp[ 	]+v2,v4,v5,v0,0,i4
+[ 	]+[0-9a-f]+:[ 	]+c852212b[ 	]+smt.vmadotsu.sp[ 	]+v2,v4,v5,v0,0,i4
+[ 	]+[0-9a-f]+:[ 	]+c852112b[ 	]+smt.vmadotus.sp[ 	]+v2,v4,v5,v0,0,i4
+[ 	]+[0-9a-f]+:[ 	]+e852012b[ 	]+smt.vmadotu.sp[ 	]+v2,v4,v5,v0,0
+[ 	]+[0-9a-f]+:[ 	]+e85201ab[ 	]+smt.vmadotu.sp[ 	]+v2,v4,v5,v0,1
+[ 	]+[0-9a-f]+:[ 	]+e852312b[ 	]+smt.vmadot.sp[ 	]+v2,v4,v5,v0,0
+[ 	]+[0-9a-f]+:[ 	]+e852212b[ 	]+smt.vmadotsu.sp[ 	]+v2,v4,v5,v0,0
+[ 	]+[0-9a-f]+:[ 	]+e852112b[ 	]+smt.vmadotus.sp[ 	]+v2,v4,v5,v0,0
+[ 	]+[0-9a-f]+:[ 	]+e852812b[ 	]+smt.vmadotu.sp[ 	]+v2,v4,v5,v0,2
+[ 	]+[0-9a-f]+:[ 	]+e85281ab[ 	]+smt.vmadotu.sp[ 	]+v2,v4,v5,v0,3
+[ 	]+[0-9a-f]+:[ 	]+e852b12b[ 	]+smt.vmadot.sp[ 	]+v2,v4,v5,v0,2
+[ 	]+[0-9a-f]+:[ 	]+e852a12b[ 	]+smt.vmadotsu.sp[ 	]+v2,v4,v5,v0,2
+[ 	]+[0-9a-f]+:[ 	]+e852912b[ 	]+smt.vmadotus.sp[ 	]+v2,v4,v5,v0,2
+[ 	]+[0-9a-f]+:[ 	]+ea52812b[ 	]+smt.vmadotu.sp[ 	]+v2,v4,v5,v1,2
+[ 	]+[0-9a-f]+:[ 	]+ea52b12b[ 	]+smt.vmadot.sp[ 	]+v2,v4,v5,v1,2
+[ 	]+[0-9a-f]+:[ 	]+cc41812b[ 	]+smt.vmadotu.hp[ 	]+v2,v3,v4,v0,0,i4
+[ 	]+[0-9a-f]+:[ 	]+cc41912b[ 	]+smt.vmadotu.hp[ 	]+v2,v3,v4,v0,1,i4
+[ 	]+[0-9a-f]+:[ 	]+ec41812b[ 	]+smt.vmadotu.hp[ 	]+v2,v3,v4,v0,0
+[ 	]+[0-9a-f]+:[ 	]+d041812b[ 	]+smt.vmadot.hp[ 	]+v2,v3,v4,v0,0,i4
+[ 	]+[0-9a-f]+:[ 	]+d441812b[ 	]+smt.vmadotsu.hp[ 	]+v2,v3,v4,v0,0,i4
+[ 	]+[0-9a-f]+:[ 	]+d841812b[ 	]+smt.vmadotus.hp[ 	]+v2,v3,v4,v0,0,i4
+[ 	]+[0-9a-f]+:[ 	]+ce41812b[ 	]+smt.vmadotu.hp[ 	]+v2,v3,v4,v1,0,i4
+[ 	]+[0-9a-f]+:[ 	]+9e41c12b[ 	]+smt.vfwmadot[ 	]+v2,v3,v4
+[ 	]+[0-9a-f]+:[ 	]+9e52512b[ 	]+smt.vfwmadot1[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+9e52612b[ 	]+smt.vfwmadot2[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+9e52712b[ 	]+smt.vfwmadot3[ 	]+v2,v4,v5
+[ 	]+[0-9a-f]+:[ 	]+6241812b[ 	]+smt.vnpack.vv[ 	]+v2,v3,v4,0
+[ 	]+[0-9a-f]+:[ 	]+6241912b[ 	]+smt.vnpack.vv[ 	]+v2,v3,v4,1
+[ 	]+[0-9a-f]+:[ 	]+6241c12b[ 	]+smt.vnspack.vv[ 	]+v2,v3,v4,0
+[ 	]+[0-9a-f]+:[ 	]+4241812b[ 	]+smt.vnpack4.vv[ 	]+v2,v3,v4,0
+[ 	]+[0-9a-f]+:[ 	]+4241c12b[ 	]+smt.vnspack4.vv[ 	]+v2,v3,v4,0
+[ 	]+[0-9a-f]+:[ 	]+6641812b[ 	]+smt.vpack.vv[ 	]+v2,v3,v4,0
+[ 	]+[0-9a-f]+:[ 	]+6641912b[ 	]+smt.vpack.vv[ 	]+v2,v3,v4,1
+[ 	]+[0-9a-f]+:[ 	]+6641c12b[ 	]+smt.vupack.vv[ 	]+v2,v3,v4,0
diff --git a/gas/testsuite/gas/riscv/x-smt-vdot-ii.s b/gas/testsuite/gas/riscv/x-smt-vdot-ii.s
new file mode 100644
index 00000000000..d80e07c49b9
--- /dev/null
+++ b/gas/testsuite/gas/riscv/x-smt-vdot-ii.s
@@ -0,0 +1,73 @@
+target:
+	# vmadot (xsmtvdotii only: i4 dtype)
+	smt.vmadot v2, v3, v4, i4
+	smt.vmadotu v2, v3, v4, i4
+	smt.vmadotsu v2, v3, v4, i4
+	smt.vmadotus v2, v3, v4, i4
+	# vmadot default (i8)
+	smt.vmadot v2, v3, v4
+	smt.vmadotu v2, v3, v4
+	smt.vmadotsu v2, v3, v4
+	smt.vmadotus v2, v3, v4
+	# vmadot explicit i8
+	smt.vmadot v2, v3, v4, i8
+	smt.vmadotu v2, v3, v4, i8
+	smt.vmadotsu v2, v3, v4, i8
+	smt.vmadotus v2, v3, v4, i8
+	# vmadot1/2/3 (shared with xsmtvdot, i8 only)
+	smt.vmadot1u v2, v4, v5
+	smt.vmadot1 v2, v4, v5
+	smt.vmadot1su v2, v4, v5
+	smt.vmadot1us v2, v4, v5
+	smt.vmadot2u v2, v4, v5
+	smt.vmadot2 v2, v4, v5
+	smt.vmadot2su v2, v4, v5
+	smt.vmadot2us v2, v4, v5
+	smt.vmadot3u v2, v4, v5
+	smt.vmadot3 v2, v4, v5
+	smt.vmadot3su v2, v4, v5
+	smt.vmadot3us v2, v4, v5
+	# vmadot.sp with Xp9 stride (0/1) and i4
+	smt.vmadotu.sp v2, v4, v5, v0, 0, i4
+	smt.vmadotu.sp v2, v4, v5, v0, 1, i4
+	smt.vmadot.sp v2, v4, v5, v0, 0, i4
+	smt.vmadotsu.sp v2, v4, v5, v0, 0, i4
+	smt.vmadotus.sp v2, v4, v5, v0, 0, i4
+	# vmadot.sp with Xp9 stride (0/1) and i8 (default)
+	smt.vmadotu.sp v2, v4, v5, v0, 0, i8
+	smt.vmadotu.sp v2, v4, v5, v0, 1, i8
+	smt.vmadot.sp v2, v4, v5, v0, 0, i8
+	smt.vmadotsu.sp v2, v4, v5, v0, 0, i8
+	smt.vmadotus.sp v2, v4, v5, v0, 0, i8
+	# vmadot.sp with Xpk stride (2/3) and i8
+	smt.vmadotu.sp v2, v4, v5, v0, 2, i8
+	smt.vmadotu.sp v2, v4, v5, v0, 3, i8
+	smt.vmadot.sp v2, v4, v5, v0, 2, i8
+	smt.vmadotsu.sp v2, v4, v5, v0, 2, i8
+	smt.vmadotus.sp v2, v4, v5, v0, 2, i8
+	# vmadot.sp with mask v1
+	smt.vmadotu.sp v2, v4, v5, v1, 2, i8
+	smt.vmadot.sp v2, v4, v5, v1, 2, i8
+	# vmadot.hp
+	smt.vmadotu.hp v2, v3, v4, v0, 0, i4
+	smt.vmadotu.hp v2, v3, v4, v0, 1, i4
+	smt.vmadotu.hp v2, v3, v4, v0, 0, i8
+	smt.vmadot.hp v2, v3, v4, v0, 0, i4
+	smt.vmadotsu.hp v2, v3, v4, v0, 0, i4
+	smt.vmadotus.hp v2, v3, v4, v0, 0, i4
+	smt.vmadotu.hp v2, v3, v4, v1, 0, i4
+	# vfwmadot
+	smt.vfwmadot v2, v3, v4
+	smt.vfwmadot1 v2, v4, v5
+	smt.vfwmadot2 v2, v4, v5
+	smt.vfwmadot3 v2, v4, v5
+	# vnpack/vnspack/vnpack4/vnspack4
+	smt.vnpack.vv v2, v3, v4, 0
+	smt.vnpack.vv v2, v3, v4, 1
+	smt.vnspack.vv v2, v3, v4, 0
+	smt.vnpack4.vv v2, v3, v4, 0
+	smt.vnspack4.vv v2, v3, v4, 0
+	# vpack/vupack
+	smt.vpack.vv v2, v3, v4, 0
+	smt.vpack.vv v2, v3, v4, 1
+	smt.vupack.vv v2, v3, v4, 0
diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
index 31b7e7a06a7..cc090670458 100644
--- a/include/opcode/riscv-opc.h
+++ b/include/opcode/riscv-opc.h
@@ -3890,6 +3890,47 @@
 #define MASK_SMT_VMADOT3SU 0x9e00f0ff
 #define MATCH_SMT_VMADOT3US 0x8600902b
 #define MASK_SMT_VMADOT3US 0x9e00f0ff
+/* Int Sparse Matrix Multi-Accumulation.  */
+#define MATCH_SMT_VMADOT_SP 0x8800302b
+#define MASK_SMT_VMADOT_SP 0x9c00707f
+#define MATCH_SMT_VMADOTSU_SP 0x8800202b
+#define MASK_SMT_VMADOTSU_SP 0x9c00707f
+#define MATCH_SMT_VMADOTU_SP 0x8800002b
+#define MASK_SMT_VMADOTU_SP 0x9c00707f
+#define MATCH_SMT_VMADOTUS_SP 0x8800102b
+#define MASK_SMT_VMADOTUS_SP 0x9c00707f
+/* Shaping High-Precision Matrix Multiplication Accumulation.  */
+#define MATCH_SMT_VMADOTU_HP 0x8c00002b
+#define MASK_SMT_VMADOTU_HP  0x9c00007f
+#define MATCH_SMT_VMADOT_HP  0x9000002b
+#define MASK_SMT_VMADOT_HP   0x9c00007f
+#define MATCH_SMT_VMADOTSU_HP 0x9400002b
+#define MASK_SMT_VMADOTSU_HP 0x9c00007f
+#define MATCH_SMT_VMADOTUS_HP 0x9800002b
+#define MASK_SMT_VMADOTUS_HP 0x9c00007f
+/* Floating-Point Expansion Matrix Multi-Accumulation.  */
+#define MATCH_SMT_VFWMADOT 0x9e00402b
+#define MASK_SMT_VFWMADOT 0xfe0070ff
+/* Floating-Point Sliding Window Expansion Multi-Accumulation.  */
+#define MATCH_SMT_VFWMADOT1 0x9e00502b
+#define MASK_SMT_VFWMADOT1  0xfe00f0ff
+#define MATCH_SMT_VFWMADOT2 0x9e00602b
+#define MASK_SMT_VFWMADOT2 0xfe00f0ff
+#define MATCH_SMT_VFWMADOT3 0x9e00702b
+#define MASK_SMT_VFWMADOT3 0xfe00f0ff
+/* Element Indentation Assembly.  */
+#define MATCH_SMT_VNPACK_VV 0x6200002b
+#define MASK_SMT_VNPACK_VV 0xfe00407f
+#define MATCH_SMT_VNSPACK_VV 0x6200402b
+#define MASK_SMT_VNSPACK_VV 0xfe00407f
+#define MATCH_SMT_VNPACK4_VV 0x4200002b
+#define MASK_SMT_VNPACK4_VV 0xfe00407f
+#define MATCH_SMT_VNSPACK4_VV 0x4200402b
+#define MASK_SMT_VNSPACK4_VV 0xfe00407f
+#define MATCH_SMT_VPACK_VV 0x6600002b
+#define MASK_SMT_VPACK_VV 0xfe0040ff
+#define MATCH_SMT_VUPACK_VV 0x6600402b
+#define MASK_SMT_VUPACK_VV 0xfe0040ff
 /* Unprivileged Counter/Timers CSR addresses.  */
 #define CSR_CYCLE 0xc00
 #define CSR_TIME 0xc01
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index 3a32abfcf3c..9c3979a7056 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -141,6 +141,9 @@ static inline unsigned int riscv_insn_length (insn_t insn)
   ((RV_X(x, 25, 2) << 5) | (RV_X(x, 9, 3) << 2))
 #define EXTRACT_MIPS_SDP_IMM(x) \
   ((RV_X(x, 25, 2) << 5) | (RV_X(x, 10, 2) << 3))
+/* Vendor-specific (SPACEMIT) encode macros.  */
+#define ENCODE_SPACEMIT_IME_UIMM2_SP(x) \
+  ((RV_X (x, 0, 1) << 7) | (RV_X (x, 1, 1) << 15))
 
 #define ENCODE_ITYPE_IMM(x) \
   (RV_X(x, 0, 12) << 20)
@@ -426,6 +429,8 @@ static inline unsigned int riscv_insn_length (insn_t insn)
 #define OP_SH_SPACEMIT_IME_VS1		16
 #define OP_MASK_SPACEMIT_IME_WI		0x3
 #define OP_SH_SPACEMIT_IME_WI		29
+#define OP_MASK_SPACEMIT_IME_VMASK	0x1
+#define OP_SH_SPACEMIT_IME_VMASK	25
 
 /* ABI names for selected x-registers.  */
 
@@ -615,6 +620,8 @@ enum riscv_insn_class
   INSN_CLASS_XMIPSEXECTL,
   INSN_CLASS_XMIPSLSP,
   INSN_CLASS_XSMTVDOT,
+  INSN_CLASS_XSMTVDOTII,
+  INSN_CLASS_XSMTVDOT_OR_XSMTVDOTII,
 };
 
 /* This structure holds information for a particular instruction.  */
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index 93d41343772..3d71666e703 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -933,10 +933,35 @@ 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[vs]);
 		      break;
+		    case 'm':
+		      {
+			unsigned vm = EXTRACT_OPERAND (SPACEMIT_IME_VMASK, l);
+			print (info->stream, dis_style_register, "%s",
+			       riscv_vecr_names_numeric[vm]);
+		      }
+		      break;
 		    default:
 		      goto undefined_modifier;
 		    }
 		  break;
+		case 'n': /* Xpn/Xpb: uimm2 stride, encoded across bits 7,15.  */
+		case 'b':
+		  {
+		    unsigned sp = ((l >> 7) & 1) | (((l >> 15) & 1) << 1);
+		    print (info->stream, dis_style_immediate, "%u", sp);
+		  }
+		  break;
+		case 'u': /* XpuN@S: N-bit unsigned immediate at bit S.  */
+		  {
+		    long n = strtol (oparg + 1, (char **)&oparg, 10);
+		    if (*oparg != '@')
+		      goto undefined_modifier;
+		    long s = strtol (oparg + 1, (char **)&oparg, 10);
+		    oparg--;
+		    unsigned val = (l >> s) & ((1U << n) - 1);
+		    print (info->stream, dis_style_immediate, "%u", val);
+		  }
+		  break;
 		case 'w':
 		  /* Xpw: optional data-width suffix, i8 only.  WI==3 (i8)
 		     is the default and is omitted from the output.  */
@@ -946,6 +971,17 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 		      goto undefined_modifier;
 		  }
 		  break;
+		case 'x':
+		  /* Xpx: optional data-width suffix, i4 or i8.  WI==3 (i8)
+		     is the default and is omitted from the output.  */
+		  {
+		    unsigned wi = EXTRACT_OPERAND (SPACEMIT_IME_WI, l);
+		    if (wi == 2)
+		      print (info->stream, dis_style_text, ",i4");
+		    else if (wi != 3)
+		      print (info->stream, dis_style_text, ",i8");
+		  }
+		  break;
 		default:
 		  goto undefined_modifier;
 		}
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 417918bb6f6..680a1f0610e 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -3581,26 +3581,61 @@ const struct riscv_opcode riscv_opcodes[] =
 
 /* SpacemiT custom instructions.  */
 /* Int Matrix Multi-Accumulation.  */
-{"smt.vmadot",   0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,VtXpw", MATCH_SMT_VMADOT, MASK_SMT_VMADOT, match_opcode, 0 },
-{"smt.vmadotu",  0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,VtXpw", MATCH_SMT_VMADOTU, MASK_SMT_VMADOTU, match_opcode, 0 },
-{"smt.vmadotsu", 0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,VtXpw", MATCH_SMT_VMADOTSU, MASK_SMT_VMADOTSU, match_opcode, 0 },
-{"smt.vmadotus", 0, INSN_CLASS_XSMTVDOT, "XpVd,Vs,VtXpw", MATCH_SMT_VMADOTUS, MASK_SMT_VMADOTUS, match_opcode, 0 },
+{"smt.vmadot",   0, INSN_CLASS_XSMTVDOTII, "XpVd,Vs,VtXpx", MATCH_SMT_VMADOT, MASK_SMT_VMADOT, match_opcode, 0 },
+{"smt.vmadot",   0, INSN_CLASS_XSMTVDOT_OR_XSMTVDOTII, "XpVd,Vs,VtXpw", MATCH_SMT_VMADOT, MASK_SMT_VMADOT, match_opcode, 0 },
+{"smt.vmadotu",  0, INSN_CLASS_XSMTVDOTII, "XpVd,Vs,VtXpx", MATCH_SMT_VMADOTU, MASK_SMT_VMADOTU, match_opcode, 0 },
+{"smt.vmadotu",  0, INSN_CLASS_XSMTVDOT_OR_XSMTVDOTII, "XpVd,Vs,VtXpw", MATCH_SMT_VMADOTU, MASK_SMT_VMADOTU, match_opcode, 0 },
+{"smt.vmadotsu", 0, INSN_CLASS_XSMTVDOTII, "XpVd,Vs,VtXpx", MATCH_SMT_VMADOTSU, MASK_SMT_VMADOTSU, match_opcode, 0 },
+{"smt.vmadotsu", 0, INSN_CLASS_XSMTVDOT_OR_XSMTVDOTII, "XpVd,Vs,VtXpw", MATCH_SMT_VMADOTSU, MASK_SMT_VMADOTSU, match_opcode, 0 },
+{"smt.vmadotus", 0, INSN_CLASS_XSMTVDOTII, "XpVd,Vs,VtXpx", MATCH_SMT_VMADOTUS, MASK_SMT_VMADOTUS, match_opcode, 0 },
+{"smt.vmadotus", 0, INSN_CLASS_XSMTVDOT_OR_XSMTVDOTII, "XpVd,Vs,VtXpw", MATCH_SMT_VMADOTUS, MASK_SMT_VMADOTUS, match_opcode, 0 },
 /* Int Sliding Window Multi-Accumulation.  */
 /* Sliding Value = 1.  */
-{"smt.vmadot1u",  0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT1U, MASK_SMT_VMADOT1U, match_opcode, 0 },
-{"smt.vmadot1",   0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT1, MASK_SMT_VMADOT1, match_opcode, 0 },
-{"smt.vmadot1su", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT1SU, MASK_SMT_VMADOT1SU, match_opcode, 0 },
-{"smt.vmadot1us", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT1US, MASK_SMT_VMADOT1US, match_opcode, 0 },
+{"smt.vmadot1u",  0, INSN_CLASS_XSMTVDOT_OR_XSMTVDOTII, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT1U, MASK_SMT_VMADOT1U, match_opcode, 0 },
+{"smt.vmadot1",   0, INSN_CLASS_XSMTVDOT_OR_XSMTVDOTII, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT1, MASK_SMT_VMADOT1, match_opcode, 0 },
+{"smt.vmadot1su", 0, INSN_CLASS_XSMTVDOT_OR_XSMTVDOTII, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT1SU, MASK_SMT_VMADOT1SU, match_opcode, 0 },
+{"smt.vmadot1us", 0, INSN_CLASS_XSMTVDOT_OR_XSMTVDOTII, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT1US, MASK_SMT_VMADOT1US, match_opcode, 0 },
 /* Sliding Value = 2.  */
-{"smt.vmadot2u",  0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT2U, MASK_SMT_VMADOT2U, match_opcode, 0 },
-{"smt.vmadot2",   0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT2, MASK_SMT_VMADOT2, match_opcode, 0 },
-{"smt.vmadot2su", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT2SU, MASK_SMT_VMADOT2SU, match_opcode, 0 },
-{"smt.vmadot2us", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT2US, MASK_SMT_VMADOT2US, match_opcode, 0 },
+{"smt.vmadot2u",  0, INSN_CLASS_XSMTVDOT_OR_XSMTVDOTII, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT2U, MASK_SMT_VMADOT2U, match_opcode, 0 },
+{"smt.vmadot2",   0, INSN_CLASS_XSMTVDOT_OR_XSMTVDOTII, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT2, MASK_SMT_VMADOT2, match_opcode, 0 },
+{"smt.vmadot2su", 0, INSN_CLASS_XSMTVDOT_OR_XSMTVDOTII, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT2SU, MASK_SMT_VMADOT2SU, match_opcode, 0 },
+{"smt.vmadot2us", 0, INSN_CLASS_XSMTVDOT_OR_XSMTVDOTII, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT2US, MASK_SMT_VMADOT2US, match_opcode, 0 },
 /* Sliding Value = 3.  */
-{"smt.vmadot3u",  0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT3U, MASK_SMT_VMADOT3U, match_opcode, 0 },
-{"smt.vmadot3",   0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT3, MASK_SMT_VMADOT3, match_opcode, 0 },
-{"smt.vmadot3su", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT3SU, MASK_SMT_VMADOT3SU, match_opcode, 0 },
-{"smt.vmadot3us", 0, INSN_CLASS_XSMTVDOT, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT3US, MASK_SMT_VMADOT3US, match_opcode, 0 },
+{"smt.vmadot3u",  0, INSN_CLASS_XSMTVDOT_OR_XSMTVDOTII, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT3U, MASK_SMT_VMADOT3U, match_opcode, 0 },
+{"smt.vmadot3",   0, INSN_CLASS_XSMTVDOT_OR_XSMTVDOTII, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT3, MASK_SMT_VMADOT3, match_opcode, 0 },
+{"smt.vmadot3su", 0, INSN_CLASS_XSMTVDOT_OR_XSMTVDOTII, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT3SU, MASK_SMT_VMADOT3SU, match_opcode, 0 },
+{"smt.vmadot3us", 0, INSN_CLASS_XSMTVDOT_OR_XSMTVDOTII, "XpVd,XpVs,VtXpw", MATCH_SMT_VMADOT3US, MASK_SMT_VMADOT3US, match_opcode, 0 },
+/* Int Sparse Matrix Multi-Accumulation.
+   Each mnemonic has two entries: Xpb (stride 0-3) paired with Xpw (i8)
+   listed first so the disassembler picks it for round-trip correctness,
+   then Xpn (stride 0-1) paired with Xpx (i4/i8) as the assembler
+   fallback for the narrower stride + i4 form.  */
+{"smt.vmadotu.sp",  0, INSN_CLASS_XSMTVDOTII, "XpVd,XpVs,Vt,XpVm,XpnXpx", MATCH_SMT_VMADOTU_SP,  MASK_SMT_VMADOTU_SP,  match_opcode, 0 },
+{"smt.vmadotu.sp",  0, INSN_CLASS_XSMTVDOTII, "XpVd,XpVs,Vt,XpVm,XpbXpw", MATCH_SMT_VMADOTU_SP,  MASK_SMT_VMADOTU_SP,  match_opcode, 0 },
+{"smt.vmadot.sp",   0, INSN_CLASS_XSMTVDOTII, "XpVd,XpVs,Vt,XpVm,XpnXpx", MATCH_SMT_VMADOT_SP,   MASK_SMT_VMADOT_SP,   match_opcode, 0 },
+{"smt.vmadot.sp",   0, INSN_CLASS_XSMTVDOTII, "XpVd,XpVs,Vt,XpVm,XpbXpw", MATCH_SMT_VMADOT_SP,   MASK_SMT_VMADOT_SP,   match_opcode, 0 },
+{"smt.vmadotsu.sp", 0, INSN_CLASS_XSMTVDOTII, "XpVd,XpVs,Vt,XpVm,XpnXpx", MATCH_SMT_VMADOTSU_SP, MASK_SMT_VMADOTSU_SP, match_opcode, 0 },
+{"smt.vmadotsu.sp", 0, INSN_CLASS_XSMTVDOTII, "XpVd,XpVs,Vt,XpVm,XpbXpw", MATCH_SMT_VMADOTSU_SP, MASK_SMT_VMADOTSU_SP, match_opcode, 0 },
+{"smt.vmadotus.sp", 0, INSN_CLASS_XSMTVDOTII, "XpVd,XpVs,Vt,XpVm,XpnXpx", MATCH_SMT_VMADOTUS_SP, MASK_SMT_VMADOTUS_SP, match_opcode, 0 },
+{"smt.vmadotus.sp", 0, INSN_CLASS_XSMTVDOTII, "XpVd,XpVs,Vt,XpVm,XpbXpw", MATCH_SMT_VMADOTUS_SP, MASK_SMT_VMADOTUS_SP, match_opcode, 0 },
+/* Shaping High-Precision Matrix Multiplication Accumulation.  */
+{"smt.vmadotu.hp",  0, INSN_CLASS_XSMTVDOTII, "Vd,Vs,Vt,XpVm,Xpu3@12Xpx", MATCH_SMT_VMADOTU_HP,  MASK_SMT_VMADOTU_HP,  match_opcode, 0 },
+{"smt.vmadot.hp",   0, INSN_CLASS_XSMTVDOTII, "Vd,Vs,Vt,XpVm,Xpu3@12Xpx", MATCH_SMT_VMADOT_HP,   MASK_SMT_VMADOT_HP,   match_opcode, 0 },
+{"smt.vmadotsu.hp", 0, INSN_CLASS_XSMTVDOTII, "Vd,Vs,Vt,XpVm,Xpu3@12Xpx", MATCH_SMT_VMADOTSU_HP, MASK_SMT_VMADOTSU_HP, match_opcode, 0 },
+{"smt.vmadotus.hp", 0, INSN_CLASS_XSMTVDOTII, "Vd,Vs,Vt,XpVm,Xpu3@12Xpx", MATCH_SMT_VMADOTUS_HP, MASK_SMT_VMADOTUS_HP, match_opcode, 0 },
+/* Floating-Point Expansion Matrix Multi-Accumulation.  */
+{"smt.vfwmadot", 0, INSN_CLASS_XSMTVDOTII, "XpVd,Vs,Vt", MATCH_SMT_VFWMADOT, MASK_SMT_VFWMADOT, match_opcode, 0 },
+/* Floating-Point Sliding Window Expansion Multi-Accumulation.  */
+{"smt.vfwmadot1", 0, INSN_CLASS_XSMTVDOTII, "XpVd,XpVs,Vt", MATCH_SMT_VFWMADOT1, MASK_SMT_VFWMADOT1, match_opcode, 0 },
+{"smt.vfwmadot2", 0, INSN_CLASS_XSMTVDOTII, "XpVd,XpVs,Vt", MATCH_SMT_VFWMADOT2, MASK_SMT_VFWMADOT2, match_opcode, 0 },
+{"smt.vfwmadot3", 0, INSN_CLASS_XSMTVDOTII, "XpVd,XpVs,Vt", MATCH_SMT_VFWMADOT3, MASK_SMT_VFWMADOT3, match_opcode, 0 },
+/* Element Indentation Assembly.  */
+{"smt.vnpack.vv", 0, INSN_CLASS_XSMTVDOTII, "Vd,Vs,Vt,Xpu2@12", MATCH_SMT_VNPACK_VV, MASK_SMT_VNPACK_VV, match_opcode, 0 },
+{"smt.vnspack.vv", 0, INSN_CLASS_XSMTVDOTII, "Vd,Vs,Vt,Xpu2@12", MATCH_SMT_VNSPACK_VV, MASK_SMT_VNSPACK_VV, match_opcode, 0 },
+{"smt.vnpack4.vv", 0, INSN_CLASS_XSMTVDOTII, "Vd,Vs,Vt,Xpu2@12", MATCH_SMT_VNPACK4_VV, MASK_SMT_VNPACK4_VV, match_opcode, 0 },
+{"smt.vnspack4.vv", 0, INSN_CLASS_XSMTVDOTII, "Vd,Vs,Vt,Xpu2@12", MATCH_SMT_VNSPACK4_VV, MASK_SMT_VNSPACK4_VV, match_opcode, 0 },
+{"smt.vpack.vv", 0, INSN_CLASS_XSMTVDOTII, "XpVd,Vs,Vt,Xpu2@12", MATCH_SMT_VPACK_VV, MASK_SMT_VPACK_VV, match_opcode, 0 },
+{"smt.vupack.vv", 0, INSN_CLASS_XSMTVDOTII, "XpVd,Vs,Vt,Xpu2@12", MATCH_SMT_VUPACK_VV, MASK_SMT_VUPACK_VV, match_opcode, 0 },
 
 /* Terminate the list.  */
 {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}
-- 
2.34.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2026-05-03 14:34 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-04-04  2:10 [PING^3][v2] RISC-V: Add SpacemiT vendor extensions xsmtvdot Mark Zhuang
2026-04-09 10:28 ` Michal Lach
2026-04-09 11:37   ` Mark Zhuang
2026-04-09 11:37     ` [PATCH] " Mark Zhuang
2026-04-09 12:21       ` Jan Beulich
2026-04-10 10:00         ` [PATCH v3 0/1] " Mark Zhuang
2026-04-10 10:00           ` [PATCH v3 1/1] " Mark Zhuang
2026-04-10 10:25             ` Jan Beulich
2026-04-10 15:11               ` [PATCH v4 0/1] " Mark Zhuang
2026-04-10 15:11                 ` [PATCH v4 1/1] " Mark Zhuang
2026-04-16  6:34                   ` Jan Beulich
2026-04-16  8:49                   ` Andreas Schwab
2026-05-03 14:33                     ` [PATCH v5 0/2] RISC-V: Add SpacemiT IME vendor extensions (xsmtvdot, xsmtvdotii) Mark Zhuang
2026-05-03 14:33                       ` [PATCH v5 1/2] RISC-V: Add SpacemiT vendor extension xsmtvdot Mark Zhuang
2026-05-03 14:33                       ` [PATCH v5 2/2] RISC-V: Add SpacemiT vendor extension xsmtvdotii Mark Zhuang
2026-04-16  6:28                 ` [PATCH v4 0/1] RISC-V: Add SpacemiT vendor extensions xsmtvdot Jan Beulich

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).