RISC-V: Support ssctr/smctr extensions with frozen version 0.9.

Message ID 20240612035629.82800-1-nelson@rivosinc.com
State New
Headers
Series RISC-V: Support ssctr/smctr extensions with frozen version 0.9. |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Test passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Test 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

Nelson Chu June 12, 2024, 3:56 a.m. UTC
  https://github.com/riscv/riscv-control-transfer-records/releases/tag/v0.9.0

The privileged spec v1.10 already removed the sfence.vm instruction, and

The encoding of sfence.vm instruction is overlapped with the sctrclr
instruction of ssctr/smctr.  But since the privileged spec v1.10 already
removed the sfence.vm, and we no longer support the privileged spec v1.9.1
for now, we had to remove the sfence.vm.

bfd/
	* elfxx-riscv.c (riscv_implicit_subsets): Imply zicsr for ssctr/smctr.
	(riscv_supported_std_s_ext): Added ssctr/smctr with version 0.9.
	(riscv_multi_subset_supports): Handle INSN_CLASS for ssctr/smctr.
	(riscv_multi_subset_supports_ext): Likewise.
gas/
	* config/tc-riscv.c (enum riscv_csr_class, riscv_csr_address):
	Added and handle CSR_CLASS_SSCTR and CSR_CLASS_SMCTR.
	* testsuite/gas/riscv/attribute-14e.d: Removed since sfence.vm is no
	longer supported since privileged spec v1.10.
	* testsuite/gas/riscv/attribute-14.s: Likewise.
	* testsuite/gas/riscv/csr-version-1p10.d: Updated for ssctr/smctr CSRs.
	* testsuite/gas/riscv/csr-version-1p10.l: Likewise.
	* testsuite/gas/riscv/csr-version-1p11.d: Likewise.
	* testsuite/gas/riscv/csr-version-1p11.l: Likewise.
	* testsuite/gas/riscv/csr-version-1p12.d: Likewise.
	* testsuite/gas/riscv/csr-version-1p12.l: Likewise.
	* testsuite/gas/riscv/csr.s: Likewise.
	* testsuite/gas/riscv/csr-dw-regnums.d: Likewise.
	* testsuite/gas/riscv/csr-dw-regnums.s: Likewise.
	* testsuite/gas/riscv/march-help.l: Updated for ssctr/smctr.
	* testsuite/gas/riscv/smctr-ssctr.d: New testcase for sctr instruction.
	* testsuite/gas/riscv/smctr-ssctr.s: Likewise.
include/
	* opcode/riscv-opc.h: Added encoding macro for sctrclr, but removed
	encoding macro for sfence.vm since encoding conflict.  Added CSR
	numbers for ssctr/smctr CSRs.
	* opcode/riscv.h (enum riscv_insn_class): Added
	INSN_CLASS_SMCTR_OR_SSCTR for sctrclr.
opcodes/
	* riscv-opc.c (riscv_opcodes): Added sctrclr, but removed sfence.vm
	since encoding conflict.
---
 bfd/elfxx-riscv.c                          |  9 +++++++++
 gas/config/tc-riscv.c                      |  4 ++++
 gas/testsuite/gas/riscv/attribute-14.s     |  5 -----
 gas/testsuite/gas/riscv/attribute-14e.d    |  8 --------
 gas/testsuite/gas/riscv/csr-dw-regnums.d   |  5 +++++
 gas/testsuite/gas/riscv/csr-dw-regnums.s   |  6 ++++++
 gas/testsuite/gas/riscv/csr-version-1p10.d | 10 ++++++++++
 gas/testsuite/gas/riscv/csr-version-1p10.l | 20 ++++++++++++++++++++
 gas/testsuite/gas/riscv/csr-version-1p11.d | 10 ++++++++++
 gas/testsuite/gas/riscv/csr-version-1p11.l | 20 ++++++++++++++++++++
 gas/testsuite/gas/riscv/csr-version-1p12.d | 10 ++++++++++
 gas/testsuite/gas/riscv/csr-version-1p12.l | 20 ++++++++++++++++++++
 gas/testsuite/gas/riscv/csr.s              |  7 +++++++
 gas/testsuite/gas/riscv/march-help.l       |  2 ++
 gas/testsuite/gas/riscv/smctr-ssctr.d      | 11 +++++++++++
 gas/testsuite/gas/riscv/smctr-ssctr.s      |  1 +
 include/opcode/riscv-opc.h                 | 17 +++++++++++++++++
 include/opcode/riscv.h                     |  1 +
 opcodes/riscv-opc.c                        |  5 +++--
 19 files changed, 156 insertions(+), 15 deletions(-)
 delete mode 100644 gas/testsuite/gas/riscv/attribute-14e.d
 create mode 100644 gas/testsuite/gas/riscv/smctr-ssctr.d
 create mode 100644 gas/testsuite/gas/riscv/smctr-ssctr.s
  

Comments

Jan Beulich June 12, 2024, 7:10 a.m. UTC | #1
On 12.06.2024 05:56, Nelson Chu wrote:
> --- a/opcodes/riscv-opc.c
> +++ b/opcodes/riscv-opc.c
> @@ -2126,13 +2126,14 @@ const struct riscv_opcode riscv_opcodes[] =
>  {"hret",       0, INSN_CLASS_I, "",    MATCH_HRET, MASK_HRET, match_opcode, 0 },
>  {"mret",       0, INSN_CLASS_I, "",    MATCH_MRET, MASK_MRET, match_opcode, 0 },
>  {"dret",       0, INSN_CLASS_I, "",    MATCH_DRET, MASK_DRET, match_opcode, 0 },
> -{"sfence.vm",  0, INSN_CLASS_I, "",    MATCH_SFENCE_VM, MASK_SFENCE_VM | MASK_RS1, match_opcode, 0 },
> -{"sfence.vm",  0, INSN_CLASS_I, "s",   MATCH_SFENCE_VM, MASK_SFENCE_VM, match_opcode, 0 },

Shouldn't you then also drop MATCH_SFENCE_VM, MASK_SFENCE_VM, and the
DECLARE_INSN() using both?

Jan
  
Nelson Chu June 12, 2024, 7:34 a.m. UTC | #2
Yeah that makes sense, thanks.

Nelson

On Wed, Jun 12, 2024 at 3:10 PM Jan Beulich <jbeulich@suse.com> wrote:

> On 12.06.2024 05:56, Nelson Chu wrote:
> > --- a/opcodes/riscv-opc.c
> > +++ b/opcodes/riscv-opc.c
> > @@ -2126,13 +2126,14 @@ const struct riscv_opcode riscv_opcodes[] =
> >  {"hret",       0, INSN_CLASS_I, "",    MATCH_HRET, MASK_HRET,
> match_opcode, 0 },
> >  {"mret",       0, INSN_CLASS_I, "",    MATCH_MRET, MASK_MRET,
> match_opcode, 0 },
> >  {"dret",       0, INSN_CLASS_I, "",    MATCH_DRET, MASK_DRET,
> match_opcode, 0 },
> > -{"sfence.vm",  0, INSN_CLASS_I, "",    MATCH_SFENCE_VM, MASK_SFENCE_VM
> | MASK_RS1, match_opcode, 0 },
> > -{"sfence.vm",  0, INSN_CLASS_I, "s",   MATCH_SFENCE_VM, MASK_SFENCE_VM,
> match_opcode, 0 },
>
> Shouldn't you then also drop MATCH_SFENCE_VM, MASK_SFENCE_VM, and the
> DECLARE_INSN() using both?
>
> Jan
>
  

Patch

diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 297d565285c..344a165f576 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1283,6 +1283,8 @@  static struct riscv_implicit_subset riscv_implicit_subsets[] =
   {"ssstateen", "zicsr",	check_implicit_always},
   {"sstc", "zicsr",		check_implicit_always},
   {"svadu", "zicsr",		check_implicit_always},
+  {"smctr", "zicsr",	check_implicit_always},
+  {"ssctr", "zicsr",	check_implicit_always},
   {"b", "zba",		check_implicit_always},
   {"b", "zbb",		check_implicit_always},
   {"b", "zbs",		check_implicit_always},
@@ -1442,11 +1444,13 @@  static struct riscv_supported_ext riscv_supported_std_s_ext[] =
   {"smaia",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
   {"smcsrind",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
   {"smcntrpmf",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
+  {"smctr",		ISA_SPEC_CLASS_DRAFT,		0, 9, 0 },
   {"smepmp",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
   {"smstateen",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
   {"ssaia",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
   {"sscsrind",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
   {"sscofpmf",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
+  {"ssctr",		ISA_SPEC_CLASS_DRAFT,		0, 9, 0 },
   {"ssstateen",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
   {"sstc",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
   {"svadu",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
@@ -2686,6 +2690,9 @@  riscv_multi_subset_supports (riscv_parse_subset_t *rps,
 	      && riscv_subset_supports (rps, "zmmul"));
     case INSN_CLASS_ZCMP:
       return riscv_subset_supports (rps, "zcmp");
+    case INSN_CLASS_SMCTR_OR_SSCTR:
+      return (riscv_subset_supports (rps, "smctr")
+	      || riscv_subset_supports (rps, "ssctr"));
     case INSN_CLASS_SVINVAL:
       return riscv_subset_supports (rps, "svinval");
     case INSN_CLASS_H:
@@ -2956,6 +2963,8 @@  riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
       return _("zcb' and `zmmul', or `zcb' and `m");
     case INSN_CLASS_ZCMP:
       return "zcmp";
+    case INSN_CLASS_SMCTR_OR_SSCTR:
+      return _("smctr' or `ssctr");
     case INSN_CLASS_SVINVAL:
       return "svinval";
     case INSN_CLASS_H:
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index e0083702fbd..7aba60ba323 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -83,6 +83,7 @@  enum riscv_csr_class
   CSR_CLASS_SMCNTRPMF_32,	/* Smcntrpmf, rv32 only */
   CSR_CLASS_SMSTATEEN,		/* Smstateen only */
   CSR_CLASS_SMSTATEEN_32,	/* Smstateen RV32 only */
+  CSR_CLASS_SMCTR,		/* Smctr */
   CSR_CLASS_SSAIA,		/* Ssaia */
   CSR_CLASS_SSAIA_AND_H,	/* Ssaia with H */
   CSR_CLASS_SSAIA_32,		/* Ssaia, rv32 only */
@@ -100,6 +101,7 @@  enum riscv_csr_class
   CSR_CLASS_SSTC_AND_H,		/* Sstc only (with H) */
   CSR_CLASS_SSTC_32,		/* Sstc RV32 only */
   CSR_CLASS_SSTC_AND_H_32,	/* Sstc RV32 only (with H) */
+  CSR_CLASS_SSCTR,		/* Ssctr */
   CSR_CLASS_XTHEADVECTOR,	/* xtheadvector only */
 };
 
@@ -1084,6 +1086,7 @@  riscv_csr_address (const char *csr_name,
     case CSR_CLASS_SMSTATEEN:
       extension = "smstateen";
       break;
+    case CSR_CLASS_SMCTR: extension = "smctr"; break;
     case CSR_CLASS_SSAIA:
     case CSR_CLASS_SSAIA_AND_H:
     case CSR_CLASS_SSAIA_32:
@@ -1129,6 +1132,7 @@  riscv_csr_address (const char *csr_name,
 		      || csr_class == CSR_CLASS_SSTC_AND_H_32);
       extension = "sstc";
       break;
+    case CSR_CLASS_SSCTR: extension = "ssctr"; break;
     case CSR_CLASS_DEBUG:
       break;
     case CSR_CLASS_XTHEADVECTOR:
diff --git a/gas/testsuite/gas/riscv/attribute-14.s b/gas/testsuite/gas/riscv/attribute-14.s
index ddda6b996f8..dcca2d8671d 100644
--- a/gas/testsuite/gas/riscv/attribute-14.s
+++ b/gas/testsuite/gas/riscv/attribute-14.s
@@ -12,8 +12,3 @@ 
 .ifdef priv_insn_d
 	sfence.vma
 .endif
-
-	# Obselete priv instruction.
-.ifdef priv_insn_e
-	sfence.vm
-.endif
diff --git a/gas/testsuite/gas/riscv/attribute-14e.d b/gas/testsuite/gas/riscv/attribute-14e.d
deleted file mode 100644
index 47fdc2e2df9..00000000000
--- a/gas/testsuite/gas/riscv/attribute-14e.d
+++ /dev/null
@@ -1,8 +0,0 @@ 
-#as: -march-attr --defsym priv_insn_e=1
-#readelf: -A
-#source: attribute-14.s
-Attribute Section: riscv
-File Attributes
-  Tag_RISCV_arch: [a-zA-Z0-9_\"].*
-  Tag_RISCV_priv_spec: [0-9_\"].*
-#...
diff --git a/gas/testsuite/gas/riscv/csr-dw-regnums.d b/gas/testsuite/gas/riscv/csr-dw-regnums.d
index 2d85996ad5c..a1d1147188d 100644
--- a/gas/testsuite/gas/riscv/csr-dw-regnums.d
+++ b/gas/testsuite/gas/riscv/csr-dw-regnums.d
@@ -403,6 +403,11 @@  Contents of the .* section:
   DW_CFA_offset_extended_sf: r4445 \(stimecmph\) at cfa\+1396
   DW_CFA_offset_extended_sf: r4685 \(vstimecmp\) at cfa\+2356
   DW_CFA_offset_extended_sf: r4701 \(vstimecmph\) at cfa\+2420
+  DW_CFA_offset_extended_sf: r4430 \(sctrctl\) at cfa\+1336
+  DW_CFA_offset_extended_sf: r4431 \(sctrstatus\) at cfa\+1340
+  DW_CFA_offset_extended_sf: r4447 \(sctrdepth\) at cfa\+1404
+  DW_CFA_offset_extended_sf: r4686 \(vsctrctl\) at cfa\+2360
+  DW_CFA_offset_extended_sf: r4942 \(mctrctl\) at cfa\+3384
   DW_CFA_offset_extended: r4096 \(ustatus\) at cfa\+0
   DW_CFA_offset_extended_sf: r4100 \(uie\) at cfa\+16
   DW_CFA_offset_extended_sf: r4101 \(utvec\) at cfa\+20
diff --git a/gas/testsuite/gas/riscv/csr-dw-regnums.s b/gas/testsuite/gas/riscv/csr-dw-regnums.s
index a4cf56dd799..7b9d663cea2 100644
--- a/gas/testsuite/gas/riscv/csr-dw-regnums.s
+++ b/gas/testsuite/gas/riscv/csr-dw-regnums.s
@@ -405,6 +405,12 @@  _start:
 	.cfi_offset stimecmph, 1396
 	.cfi_offset vstimecmp, 2356
 	.cfi_offset vstimecmph, 2420
+	# Ssctr/Smctr extension
+	.cfi_offset sctrctl, 1336
+	.cfi_offset sctrstatus, 1340
+	.cfi_offset sctrdepth, 1404
+	.cfi_offset vsctrctl, 2360
+	.cfi_offset mctrctl, 3384
 	# dropped
 	.cfi_offset ustatus, 0
 	.cfi_offset uie, 16
diff --git a/gas/testsuite/gas/riscv/csr-version-1p10.d b/gas/testsuite/gas/riscv/csr-version-1p10.d
index 5165f4bea0d..0121e7b9240 100644
--- a/gas/testsuite/gas/riscv/csr-version-1p10.d
+++ b/gas/testsuite/gas/riscv/csr-version-1p10.d
@@ -823,6 +823,16 @@  Disassembly of section .text:
 [ 	]+[0-9a-f]+:[ 	]+24d59073[ 	]+csrw[ 	]+vstimecmp,a1
 [ 	]+[0-9a-f]+:[ 	]+25d02573[ 	]+csrr[ 	]+a0,vstimecmph
 [ 	]+[0-9a-f]+:[ 	]+25d59073[ 	]+csrw[ 	]+vstimecmph,a1
+[ 	]+[0-9a-f]+:[ 	]+14e02573[ 	]+csrr[ 	]+a0,sctrctl
+[ 	]+[0-9a-f]+:[ 	]+14e59073[ 	]+csrw[ 	]+sctrctl,a1
+[ 	]+[0-9a-f]+:[ 	]+14f02573[ 	]+csrr[ 	]+a0,sctrstatus
+[ 	]+[0-9a-f]+:[ 	]+14f59073[ 	]+csrw[ 	]+sctrstatus,a1
+[ 	]+[0-9a-f]+:[ 	]+15f02573[ 	]+csrr[ 	]+a0,sctrdepth
+[ 	]+[0-9a-f]+:[ 	]+15f59073[ 	]+csrw[ 	]+sctrdepth,a1
+[ 	]+[0-9a-f]+:[ 	]+24e02573[ 	]+csrr[ 	]+a0,vsctrctl
+[ 	]+[0-9a-f]+:[ 	]+24e59073[ 	]+csrw[ 	]+vsctrctl,a1
+[ 	]+[0-9a-f]+:[ 	]+34e02573[ 	]+csrr[ 	]+a0,mctrctl
+[ 	]+[0-9a-f]+:[ 	]+34e59073[ 	]+csrw[ 	]+mctrctl,a1
 [ 	]+[0-9a-f]+:[ 	]+00002573[ 	]+csrr[ 	]+a0,ustatus
 [ 	]+[0-9a-f]+:[ 	]+00059073[ 	]+csrw[ 	]+ustatus,a1
 [ 	]+[0-9a-f]+:[ 	]+00402573[ 	]+csrr[ 	]+a0,uie
diff --git a/gas/testsuite/gas/riscv/csr-version-1p10.l b/gas/testsuite/gas/riscv/csr-version-1p10.l
index 17a8bb638e8..f36dc10b3d4 100644
--- a/gas/testsuite/gas/riscv/csr-version-1p10.l
+++ b/gas/testsuite/gas/riscv/csr-version-1p10.l
@@ -1623,6 +1623,26 @@ 
 .*Info: macro .*
 .*Warning: invalid CSR `vstimecmph', needs `sstc' extension
 .*Info: macro .*
+.*Warning: invalid CSR `sctrctl', needs `ssctr' extension
+.*Info: macro .*
+.*Warning: invalid CSR `sctrctl', needs `ssctr' extension
+.*Info: macro .*
+.*Warning: invalid CSR `sctrstatus', needs `ssctr' extension
+.*Info: macro .*
+.*Warning: invalid CSR `sctrstatus', needs `ssctr' extension
+.*Info: macro .*
+.*Warning: invalid CSR `sctrdepth', needs `ssctr' extension
+.*Info: macro .*
+.*Warning: invalid CSR `sctrdepth', needs `ssctr' extension
+.*Info: macro .*
+.*Warning: invalid CSR `vsctrctl', needs `ssctr' extension
+.*Info: macro .*
+.*Warning: invalid CSR `vsctrctl', needs `ssctr' extension
+.*Info: macro .*
+.*Warning: invalid CSR `mctrctl', needs `smctr' extension
+.*Info: macro .*
+.*Warning: invalid CSR `mctrctl', needs `smctr' extension
+.*Info: macro .*
 .*Warning: invalid CSR `fflags', needs `f' extension
 .*Info: macro .*
 .*Warning: invalid CSR `fflags', needs `f' extension
diff --git a/gas/testsuite/gas/riscv/csr-version-1p11.d b/gas/testsuite/gas/riscv/csr-version-1p11.d
index 1cb5a917f1a..5e3ed10c5a5 100644
--- a/gas/testsuite/gas/riscv/csr-version-1p11.d
+++ b/gas/testsuite/gas/riscv/csr-version-1p11.d
@@ -823,6 +823,16 @@  Disassembly of section .text:
 [ 	]+[0-9a-f]+:[ 	]+24d59073[ 	]+csrw[ 	]+vstimecmp,a1
 [ 	]+[0-9a-f]+:[ 	]+25d02573[ 	]+csrr[ 	]+a0,vstimecmph
 [ 	]+[0-9a-f]+:[ 	]+25d59073[ 	]+csrw[ 	]+vstimecmph,a1
+[ 	]+[0-9a-f]+:[ 	]+14e02573[ 	]+csrr[ 	]+a0,sctrctl
+[ 	]+[0-9a-f]+:[ 	]+14e59073[ 	]+csrw[ 	]+sctrctl,a1
+[ 	]+[0-9a-f]+:[ 	]+14f02573[ 	]+csrr[ 	]+a0,sctrstatus
+[ 	]+[0-9a-f]+:[ 	]+14f59073[ 	]+csrw[ 	]+sctrstatus,a1
+[ 	]+[0-9a-f]+:[ 	]+15f02573[ 	]+csrr[ 	]+a0,sctrdepth
+[ 	]+[0-9a-f]+:[ 	]+15f59073[ 	]+csrw[ 	]+sctrdepth,a1
+[ 	]+[0-9a-f]+:[ 	]+24e02573[ 	]+csrr[ 	]+a0,vsctrctl
+[ 	]+[0-9a-f]+:[ 	]+24e59073[ 	]+csrw[ 	]+vsctrctl,a1
+[ 	]+[0-9a-f]+:[ 	]+34e02573[ 	]+csrr[ 	]+a0,mctrctl
+[ 	]+[0-9a-f]+:[ 	]+34e59073[ 	]+csrw[ 	]+mctrctl,a1
 [ 	]+[0-9a-f]+:[ 	]+00002573[ 	]+csrr[ 	]+a0,ustatus
 [ 	]+[0-9a-f]+:[ 	]+00059073[ 	]+csrw[ 	]+ustatus,a1
 [ 	]+[0-9a-f]+:[ 	]+00402573[ 	]+csrr[ 	]+a0,uie
diff --git a/gas/testsuite/gas/riscv/csr-version-1p11.l b/gas/testsuite/gas/riscv/csr-version-1p11.l
index 8b797e8893e..511c7722f13 100644
--- a/gas/testsuite/gas/riscv/csr-version-1p11.l
+++ b/gas/testsuite/gas/riscv/csr-version-1p11.l
@@ -1619,6 +1619,26 @@ 
 .*Info: macro .*
 .*Warning: invalid CSR `vstimecmph', needs `sstc' extension
 .*Info: macro .*
+.*Warning: invalid CSR `sctrctl', needs `ssctr' extension
+.*Info: macro .*
+.*Warning: invalid CSR `sctrctl', needs `ssctr' extension
+.*Info: macro .*
+.*Warning: invalid CSR `sctrstatus', needs `ssctr' extension
+.*Info: macro .*
+.*Warning: invalid CSR `sctrstatus', needs `ssctr' extension
+.*Info: macro .*
+.*Warning: invalid CSR `sctrdepth', needs `ssctr' extension
+.*Info: macro .*
+.*Warning: invalid CSR `sctrdepth', needs `ssctr' extension
+.*Info: macro .*
+.*Warning: invalid CSR `vsctrctl', needs `ssctr' extension
+.*Info: macro .*
+.*Warning: invalid CSR `vsctrctl', needs `ssctr' extension
+.*Info: macro .*
+.*Warning: invalid CSR `mctrctl', needs `smctr' extension
+.*Info: macro .*
+.*Warning: invalid CSR `mctrctl', needs `smctr' extension
+.*Info: macro .*
 .*Warning: invalid CSR `fflags', needs `f' extension
 .*Info: macro .*
 .*Warning: invalid CSR `fflags', needs `f' extension
diff --git a/gas/testsuite/gas/riscv/csr-version-1p12.d b/gas/testsuite/gas/riscv/csr-version-1p12.d
index ac88d9370f8..5136e6d01f7 100644
--- a/gas/testsuite/gas/riscv/csr-version-1p12.d
+++ b/gas/testsuite/gas/riscv/csr-version-1p12.d
@@ -823,6 +823,16 @@  Disassembly of section .text:
 [ 	]+[0-9a-f]+:[ 	]+24d59073[ 	]+csrw[ 	]+vstimecmp,a1
 [ 	]+[0-9a-f]+:[ 	]+25d02573[ 	]+csrr[ 	]+a0,vstimecmph
 [ 	]+[0-9a-f]+:[ 	]+25d59073[ 	]+csrw[ 	]+vstimecmph,a1
+[ 	]+[0-9a-f]+:[ 	]+14e02573[ 	]+csrr[ 	]+a0,sctrctl
+[ 	]+[0-9a-f]+:[ 	]+14e59073[ 	]+csrw[ 	]+sctrctl,a1
+[ 	]+[0-9a-f]+:[ 	]+14f02573[ 	]+csrr[ 	]+a0,sctrstatus
+[ 	]+[0-9a-f]+:[ 	]+14f59073[ 	]+csrw[ 	]+sctrstatus,a1
+[ 	]+[0-9a-f]+:[ 	]+15f02573[ 	]+csrr[ 	]+a0,sctrdepth
+[ 	]+[0-9a-f]+:[ 	]+15f59073[ 	]+csrw[ 	]+sctrdepth,a1
+[ 	]+[0-9a-f]+:[ 	]+24e02573[ 	]+csrr[ 	]+a0,vsctrctl
+[ 	]+[0-9a-f]+:[ 	]+24e59073[ 	]+csrw[ 	]+vsctrctl,a1
+[ 	]+[0-9a-f]+:[ 	]+34e02573[ 	]+csrr[ 	]+a0,mctrctl
+[ 	]+[0-9a-f]+:[ 	]+34e59073[ 	]+csrw[ 	]+mctrctl,a1
 [ 	]+[0-9a-f]+:[ 	]+00002573[ 	]+csrr[ 	]+a0,0x0
 [ 	]+[0-9a-f]+:[ 	]+00059073[ 	]+csrw[ 	]+0x0,a1
 [ 	]+[0-9a-f]+:[ 	]+00402573[ 	]+csrr[ 	]+a0,0x4
diff --git a/gas/testsuite/gas/riscv/csr-version-1p12.l b/gas/testsuite/gas/riscv/csr-version-1p12.l
index 81a7aba25c8..64c1976a5c0 100644
--- a/gas/testsuite/gas/riscv/csr-version-1p12.l
+++ b/gas/testsuite/gas/riscv/csr-version-1p12.l
@@ -1343,6 +1343,26 @@ 
 .*Info: macro .*
 .*Warning: invalid CSR `vstimecmph', needs `sstc' extension
 .*Info: macro .*
+.*Warning: invalid CSR `sctrctl', needs `ssctr' extension
+.*Info: macro .*
+.*Warning: invalid CSR `sctrctl', needs `ssctr' extension
+.*Info: macro .*
+.*Warning: invalid CSR `sctrstatus', needs `ssctr' extension
+.*Info: macro .*
+.*Warning: invalid CSR `sctrstatus', needs `ssctr' extension
+.*Info: macro .*
+.*Warning: invalid CSR `sctrdepth', needs `ssctr' extension
+.*Info: macro .*
+.*Warning: invalid CSR `sctrdepth', needs `ssctr' extension
+.*Info: macro .*
+.*Warning: invalid CSR `vsctrctl', needs `ssctr' extension
+.*Info: macro .*
+.*Warning: invalid CSR `vsctrctl', needs `ssctr' extension
+.*Info: macro .*
+.*Warning: invalid CSR `mctrctl', needs `smctr' extension
+.*Info: macro .*
+.*Warning: invalid CSR `mctrctl', needs `smctr' extension
+.*Info: macro .*
 .*Warning: invalid CSR `ustatus' for the privileged spec `1.12'
 .*Info: macro .*
 .*Warning: invalid CSR `ustatus' for the privileged spec `1.12'
diff --git a/gas/testsuite/gas/riscv/csr.s b/gas/testsuite/gas/riscv/csr.s
index 378caef35b0..8b5e4d1cbbd 100644
--- a/gas/testsuite/gas/riscv/csr.s
+++ b/gas/testsuite/gas/riscv/csr.s
@@ -464,6 +464,13 @@ 
 	csr vstimecmp
 	csr vstimecmph
 
+	# Smctr/Ssctr
+	csr sctrctl
+	csr sctrstatus
+	csr sctrdepth
+	csr vsctrctl
+	csr mctrctl
+
 	# Supported in previous priv spec, but dropped now
 
 	csr ustatus		# 0x0   in 1.10, dropped in 1.12
diff --git a/gas/testsuite/gas/riscv/march-help.l b/gas/testsuite/gas/riscv/march-help.l
index d2b98383e80..64f9c8aaa02 100644
--- a/gas/testsuite/gas/riscv/march-help.l
+++ b/gas/testsuite/gas/riscv/march-help.l
@@ -97,11 +97,13 @@  All available -march extensions for RISC-V:
 	smaia                                   1.0
 	smcsrind                                1.0
 	smcntrpmf                               1.0
+	smctr                                   0.9
 	smepmp                                  1.0
 	smstateen                               1.0
 	ssaia                                   1.0
 	sscsrind                                1.0
 	sscofpmf                                1.0
+	ssctr                                   0.9
 	ssstateen                               1.0
 	sstc                                    1.0
 	svadu                                   1.0
diff --git a/gas/testsuite/gas/riscv/smctr-ssctr.d b/gas/testsuite/gas/riscv/smctr-ssctr.d
new file mode 100644
index 00000000000..ead1f2337b8
--- /dev/null
+++ b/gas/testsuite/gas/riscv/smctr-ssctr.d
@@ -0,0 +1,11 @@ 
+#as: -march=rv32i_smctr_ssctr
+#source: smctr-ssctr.s
+#objdump: -d
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <.text>:
+[ 	]+0:[ 	]+10400073[ 	]+sctrclr
diff --git a/gas/testsuite/gas/riscv/smctr-ssctr.s b/gas/testsuite/gas/riscv/smctr-ssctr.s
new file mode 100644
index 00000000000..08cfab4ac8d
--- /dev/null
+++ b/gas/testsuite/gas/riscv/smctr-ssctr.s
@@ -0,0 +1 @@ 
+	sctrclr
diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
index 511895eca2b..f1b58ee058b 100644
--- a/include/opcode/riscv-opc.h
+++ b/include/opcode/riscv-opc.h
@@ -2280,6 +2280,9 @@ 
 #define MASK_CM_POPRET 0xff03
 #define MATCH_CM_POPRETZ 0xbc02
 #define MASK_CM_POPRETZ 0xff03
+/* Smctr/Ssctr instruction.  */
+#define MATCH_SCTRCLR 0x10400073
+#define MASK_SCTRCLR 0xffffffff
 /* Svinval instruction.  */
 #define MATCH_SINVAL_VMA 0x16000073
 #define MASK_SINVAL_VMA 0xfe007fff
@@ -3572,6 +3575,12 @@ 
 #define CSR_STIMECMPH 0x15d
 #define CSR_VSTIMECMP 0x24d
 #define CSR_VSTIMECMPH 0x25d
+/* Smctr/Ssctr CSR addresses.  */
+#define CSR_SCTRCTL 0x14e
+#define CSR_SCTRSTATUS 0x14f
+#define CSR_SCTRDEPTH 0x15f
+#define CSR_VSCTRCTL 0x24e
+#define CSR_MCTRCTL 0x34e
 /* Unprivileged Floating-Point CSR addresses.  */
 #define CSR_FFLAGS 0x1
 #define CSR_FRM 0x2
@@ -4076,6 +4085,8 @@  DECLARE_INSN(cm_push, MATCH_CM_PUSH, MASK_CM_PUSH)
 DECLARE_INSN(cm_pop, MATCH_CM_POP, MASK_CM_POP)
 DECLARE_INSN(cm_popret, MATCH_CM_POPRET, MASK_CM_POPRET)
 DECLARE_INSN(cm_popretz, MATCH_CM_POPRETZ, MASK_CM_POPRETZ)
+/* Smctr/Ssctr instruction.  */
+DECLARE_INSN(sctrclr, MATCH_SCTRCLR, MASK_SCTRCLR)
 /* Vendor-specific (T-Head) XTheadBa instructions.  */
 DECLARE_INSN(th_addsl, MATCH_TH_ADDSL, MASK_TH_ADDSL)
 /* Vendor-specific (T-Head) XTheadBb instructions.  */
@@ -4612,6 +4623,12 @@  DECLARE_CSR(stimecmp, CSR_STIMECMP, CSR_CLASS_SSTC, PRIV_SPEC_CLASS_NONE, PRIV_S
 DECLARE_CSR(stimecmph, CSR_STIMECMPH, CSR_CLASS_SSTC_32, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
 DECLARE_CSR(vstimecmp, CSR_VSTIMECMP, CSR_CLASS_SSTC_AND_H, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
 DECLARE_CSR(vstimecmph, CSR_VSTIMECMPH, CSR_CLASS_SSTC_AND_H_32, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+/* Smctr/Ssctr CSRs.  */
+DECLARE_CSR(mctrctl, CSR_MCTRCTL, CSR_CLASS_SMCTR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(sctrctl, CSR_SCTRCTL, CSR_CLASS_SSCTR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(sctrstatus, CSR_SCTRSTATUS, CSR_CLASS_SSCTR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(sctrdepth, CSR_SCTRDEPTH, CSR_CLASS_SSCTR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(vsctrctl, CSR_VSCTRCTL, CSR_CLASS_SSCTR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
 /* Dropped CSRs.  */
 DECLARE_CSR(ustatus, CSR_USTATUS, CSR_CLASS_I, PRIV_SPEC_CLASS_1P10, PRIV_SPEC_CLASS_1P12)
 DECLARE_CSR(uie, CSR_UIE, CSR_CLASS_I, PRIV_SPEC_CLASS_1P10, PRIV_SPEC_CLASS_1P12)
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index 33df56d13af..f40b8425dbe 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -487,6 +487,7 @@  enum riscv_insn_class
   INSN_CLASS_ZCB_AND_ZBB,
   INSN_CLASS_ZCB_AND_ZMMUL,
   INSN_CLASS_ZCMP,
+  INSN_CLASS_SMCTR_OR_SSCTR,
   INSN_CLASS_SVINVAL,
   INSN_CLASS_ZICBOM,
   INSN_CLASS_ZICBOP,
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index ff08bd595c0..106c32776e1 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -2126,13 +2126,14 @@  const struct riscv_opcode riscv_opcodes[] =
 {"hret",       0, INSN_CLASS_I, "",    MATCH_HRET, MASK_HRET, match_opcode, 0 },
 {"mret",       0, INSN_CLASS_I, "",    MATCH_MRET, MASK_MRET, match_opcode, 0 },
 {"dret",       0, INSN_CLASS_I, "",    MATCH_DRET, MASK_DRET, match_opcode, 0 },
-{"sfence.vm",  0, INSN_CLASS_I, "",    MATCH_SFENCE_VM, MASK_SFENCE_VM | MASK_RS1, match_opcode, 0 },
-{"sfence.vm",  0, INSN_CLASS_I, "s",   MATCH_SFENCE_VM, MASK_SFENCE_VM, match_opcode, 0 },
 {"sfence.vma", 0, INSN_CLASS_I, "",    MATCH_SFENCE_VMA, MASK_SFENCE_VMA|MASK_RS1|MASK_RS2, match_opcode, INSN_ALIAS },
 {"sfence.vma", 0, INSN_CLASS_I, "s",   MATCH_SFENCE_VMA, MASK_SFENCE_VMA|MASK_RS2, match_opcode, INSN_ALIAS },
 {"sfence.vma", 0, INSN_CLASS_I, "s,t", MATCH_SFENCE_VMA, MASK_SFENCE_VMA, match_opcode, 0 },
 {"wfi",        0, INSN_CLASS_I, "",    MATCH_WFI, MASK_WFI, match_opcode, 0 },
 
+/* Smctr/Ssctr instruction.  */
+{"sctrclr", 0, INSN_CLASS_SMCTR_OR_SSCTR, "", MATCH_SCTRCLR, MASK_SCTRCLR, match_opcode, 0 },
+
 /* Svinval instructions.  */
 {"sinval.vma",      0, INSN_CLASS_SVINVAL, "s,t", MATCH_SINVAL_VMA, MASK_SINVAL_VMA, match_opcode, 0 },
 {"sfence.w.inval",  0, INSN_CLASS_SVINVAL, "",    MATCH_SFENCE_W_INVAL, MASK_SFENCE_W_INVAL, match_opcode, 0 },