[v6,1/2] RISC-V: Add SpacemiT vendor extension xsmtvdot

Message ID 20260525082008.1219171-2-zhuangqiubin@linux.spacemit.com
State New
Headers
Series RISC-V: Add SpacemiT vendor extensions xsmtvdot and xsmtvdotii |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed

Commit Message

Mark Zhuang May 25, 2026, 8:20 a.m. UTC
  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
  

Comments

Jiawei June 3, 2026, 6:52 a.m. UTC | #1
LGTM.

在 2026/5/25 16:20, Mark Zhuang 写道:
> 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..d28744f4547 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 implements 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}
>   };

Reviewed-by: Jiawei <jiawei@iscas.ac.cn>
  
Mark Zhuang June 15, 2026, 8:19 a.m. UTC | #2
Hi Jan,

This patch series has received a Reviewed-by from Jiawei. Could you
please take a look and commit it when you have time? I'm happy to make
any further changes if needed.

Thanks,
Mark
  
Jan Beulich June 15, 2026, 8:25 a.m. UTC | #3
On 15.06.2026 10:19, Mark Zhuang wrote:
> This patch series has received a Reviewed-by from Jiawei. Could you
> please take a look and commit it when you have time? I'm happy to make
> any further changes if needed.

Hmm, no, not really. I'm not a RISC-V maintainer (adding them to Cc), and
for arch-specific new code it should imo really be them to take care.

I'm sorry, Jan
  
Mark Zhuang June 15, 2026, 9:45 a.m. UTC | #4
Hi Jan,

Thanks for the clarification -- much appreciated.

Just to be clear, I know you're not a RISC-V maintainer. I only reached out
because the RISC-V maintainers have been less active lately, and I
sincerely didn't mean to add to your workload.

I fully agree this should go through them, and will wait for their
availability to handle the patch.

Thanks again!

Best,
Mark
  
Jiawei June 17, 2026, 5:01 a.m. UTC | #5
在 2026/6/15 16:25, Jan Beulich 写道:
> On 15.06.2026 10:19, Mark Zhuang wrote:
>> This patch series has received a Reviewed-by from Jiawei. Could you
>> please take a look and commit it when you have time? I'm happy to make
>> any further changes if needed.
> Hmm, no, not really. I'm not a RISC-V maintainer (adding them to Cc), and
> for arch-specific new code it should imo really be them to take care.
>
> I'm sorry, Jan

Thanks Jan.

I agree this should be handled by the RISC-V side.

I have reviewed the series and it looks good to me. I can also help
with testing and committing it once there is approval from a RISC-V
maintainer.

Best regards,

Jiawei
  
Jeffrey Law June 22, 2026, 2:06 p.m. UTC | #6
On 6/15/2026 3:45 AM, Mark Zhuang wrote:
> Hi Jan,
>
> Thanks for the clarification -- much appreciated.
>
> Just to be clear, I know you're not a RISC-V maintainer. I only reached out
> because the RISC-V maintainers have been less active lately, and I
> sincerely didn't mean to add to your workload.
>
> I fully agree this should go through them, and will wait for their
> availability to handle the patch.
Yea.  I was just looking and it appears that at least some RISC-V 
patches that have been approved haven't been integrated.  I'll try to 
burn through that set of patches, then we can evaluate what's still 
left.  But clearly things aren't working as smoothly as they should.

jeff
  
Jeffrey Law June 22, 2026, 4:48 p.m. UTC | #7
On 5/25/2026 2:20 AM, Mark Zhuang wrote:
> 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
THanks.  I've pushed this to the trunk.

jeff
  
Mark Wielaard June 22, 2026, 9:14 p.m. UTC | #8
Hi,

On Mon, Jun 22, 2026 at 04:48:35PM +0000, Jeffrey Law via Binutils wrote:
> On 5/25/2026 2:20 AM, Mark Zhuang wrote:
> > 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
> THanks.  I've pushed this to the trunk.

This does break the build with older gcc versions (8.5.0):

../../binutils-gdb/opcodes/riscv-dis.c: In function ‘print_insn_args’:
../../binutils-gdb/opcodes/riscv-dis.c:927:9: error: a label can only be part of a statement and a declaration is not a statement
         unsigned vd = EXTRACT_OPERAND (SPACEMIT_IME_VD, l) * 2;
         ^~~~~~~~
../../binutils-gdb/opcodes/riscv-dis.c:932:9: error: a label can only be part of a statement and a declaration is not a statement
         unsigned vs = EXTRACT_OPERAND (SPACEMIT_IME_VS1, l) * 2;
         ^~~~~~~~

It wants a block after a case label when declaring new variables.

See also
https://builder.sourceware.org/buildbot/#/builders/290/builds/6952/steps/4/logs/stdio

Cheers,

Mark
  
Jeffrey Law June 23, 2026, 1:59 a.m. UTC | #9
On 6/22/2026 3:14 PM, Mark Wielaard wrote:
> WARNING: This email originated from outside of Qualcomm. Please be wary of any links or attachments, and do not enable macros.
>
> Hi,
>
> On Mon, Jun 22, 2026 at 04:48:35PM +0000, Jeffrey Law via Binutils wrote:
>> On 5/25/2026 2:20 AM, Mark Zhuang wrote:
>>> 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
>> THanks.  I've pushed this to the trunk.
> This does break the build with older gcc versions (8.5.0):
>
> ../../binutils-gdb/opcodes/riscv-dis.c: In function ‘print_insn_args’:
> ../../binutils-gdb/opcodes/riscv-dis.c:927:9: error: a label can only be part of a statement and a declaration is not a statement
>           unsigned vd = EXTRACT_OPERAND (SPACEMIT_IME_VD, l) * 2;
>           ^~~~~~~~
> ../../binutils-gdb/opcodes/riscv-dis.c:932:9: error: a label can only be part of a statement and a declaration is not a statement
>           unsigned vs = EXTRACT_OPERAND (SPACEMIT_IME_VS1, l) * 2;
>           ^~~~~~~~
>
> It wants a block after a case label when declaring new variables.
>
> See also
> https://builder.sourceware.org/buildbot/#/builders/290/builds/6952/steps/4/logs/stdio
Ugh.  gcc-8 era.   I don't recall the default C language dialect used in 
that era, but definitely old and crusty.  I think the whole block can be 
wrapped in a curly block to fix this.

jeff
  
Mark Zhuang June 23, 2026, 10:10 a.m. UTC | #10
Thank you, Jeffrey and Mark!

I have sent a fix patch to the mailing list:
https://sourceware.org/pipermail/binutils/2026-June/149757.html

Best regards,
Mark Zhuang
  
Andreas Schwab June 23, 2026, 10:32 a.m. UTC | #11
On Jun 23 2026, Jeffrey Law via Binutils wrote:

> Ugh.  gcc-8 era.   I don't recall the default C language dialect used in 
> that era, but definitely old and crusty.

You need at least C23 for that, or gcc >= 11 with GNU extensions.
  

Patch

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..d28744f4547 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 implements 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}
 };