public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] RISC-V/t-head: Add CSRs and opcodes of the T-HEAD XUANTIE CPUs
@ 2022-07-28 22:04 Palmer Dabbelt
  2022-07-29  0:28 ` Kito Cheng
  0 siblings, 1 reply; 4+ messages in thread
From: Palmer Dabbelt @ 2022-07-28 22:04 UTC (permalink / raw)
  To: binutils

From: Lifang Xia <lifang_xia@c-sky.com>

Add CSRs and opcodes of the XUANTIE CPUs, extensions named "theadc",
"xtheade" and "xtheadse".

bfd/ChangeLog

	* cpu-riscv.h (riscv_spec_class) <VENDOR_SPEC_CLASS_THEAD>: New
	value.
	* elfxx-riscv.c (riscv_supported_custom_ext): New table.
	(riscv_all_supported_ext): Add riscv_supported_custom_ext.
	(riscv_recognized_prefixed_ext): Update comment.
	(riscv_get_default_ext_version): Add the t-head extensions.
	(riscv_multi_subset_supports): Likewise.
	(riscv_multi_subset_supports_ext): Likewise.

gas/ChangeLog

	* config/tc-riscv.c (riscv_csr_class) <CSR_CLASS_THEAD>: New
	value.
	(riscv_csr_address): Add CSR_CLASS_THEAD.
	(validate_riscv_insn): Add the XI and XS formats.
	(riscv_ip): Likewise.

gas/testsuite/ChangeLog

	* gas/riscv/thead-csr-list.d: New test.
	* gas/riscv/theadc-ext.d: Likewise.
	* gas/riscv/theadc-ext.s: Likewise.
	* gas/riscv/theade-ext.d: Likewise.
	* gas/riscv/theade-ext.s: Likewise.

include/ChangeLog

	* opcode/iscv-opc-thead.h: New file.

opcodes/ChangeLog

	* riscv-dis.c (print_insn_args): Support XI and XS formats.
	* riscv-opc.c (match_thead_rd1_rd2_neq_rs1): New function.
	(riscv_opcodes): Add the t-thead extensions.
---
I cherry-picked this off Nelson's integration branch at sourceware, and
then went through it a bit to avoid the dependencies on the experimental
extension handling (and also just some cleanups).  This should be
functionally the same as what was originally posted, aside from having
the "th." prefix on instructions and the "th_" prefix on CSRs.

This passes the tests, but I don't currently have any other way to
verify it.
---
 bfd/cpu-riscv.h                          |   3 +
 bfd/elfxx-riscv.c                        |  43 +-
 gas/config/tc-riscv.c                    |  85 ++++
 gas/testsuite/gas/riscv/thead-csr-list.d | 107 +++++
 gas/testsuite/gas/riscv/thead-csr-list.s |  98 ++++
 gas/testsuite/gas/riscv/theadc-ext.d     | 112 +++++
 gas/testsuite/gas/riscv/theadc-ext.s     | 115 +++++
 gas/testsuite/gas/riscv/theade-ext.d     |  62 +++
 gas/testsuite/gas/riscv/theade-ext.s     |  66 +++
 include/opcode/riscv-opc-thead.h         | 571 +++++++++++++++++++++++
 include/opcode/riscv-opc.h               |   2 +
 include/opcode/riscv.h                   |  21 +
 opcodes/riscv-dis.c                      |  24 +
 opcodes/riscv-opc.c                      | 124 +++++
 14 files changed, 1428 insertions(+), 5 deletions(-)
 create mode 100644 gas/testsuite/gas/riscv/thead-csr-list.d
 create mode 100644 gas/testsuite/gas/riscv/thead-csr-list.s
 create mode 100644 gas/testsuite/gas/riscv/theadc-ext.d
 create mode 100644 gas/testsuite/gas/riscv/theadc-ext.s
 create mode 100644 gas/testsuite/gas/riscv/theade-ext.d
 create mode 100644 gas/testsuite/gas/riscv/theade-ext.s
 create mode 100644 include/opcode/riscv-opc-thead.h

diff --git a/bfd/cpu-riscv.h b/bfd/cpu-riscv.h
index ff037d127e2..3e0839fec3c 100644
--- a/bfd/cpu-riscv.h
+++ b/bfd/cpu-riscv.h
@@ -34,6 +34,9 @@ enum riscv_spec_class
   PRIV_SPEC_CLASS_1P11,
   PRIV_SPEC_CLASS_1P12,
   PRIV_SPEC_CLASS_DRAFT,
+
+  /* Vendor spec for T_HEAD XuanTie.  */
+  VENDOR_SPEC_CLASS_THEAD,
 };
 
 struct riscv_spec
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 0b2021f5cc7..2af0917381e 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1245,12 +1245,21 @@ static struct riscv_supported_ext riscv_supported_std_zxm_ext[] =
   {NULL, 0, 0, 0, 0}
 };
 
+static struct riscv_supported_ext riscv_supported_custom_ext[] =
+{
+  {"xtheadc",		VENDOR_SPEC_CLASS_THEAD,	2, 0, 0 },
+  {"xtheade",		VENDOR_SPEC_CLASS_THEAD,	2, 0, 0 },
+  {"xtheadse",		VENDOR_SPEC_CLASS_THEAD,	2, 0, 0 },
+  {NULL, 0, 0, 0, 0}
+};
+
 const struct riscv_supported_ext *riscv_all_supported_ext[] =
 {
   riscv_supported_std_ext,
   riscv_supported_std_z_ext,
   riscv_supported_std_s_ext,
   riscv_supported_std_zxm_ext,
+  riscv_supported_custom_ext,
   NULL
 };
 
@@ -1331,7 +1340,8 @@ riscv_recognized_prefixed_ext (const char *ext)
   case RV_ISA_CLASS_S:
     return riscv_known_prefixed_ext (ext, riscv_supported_std_s_ext);
   case RV_ISA_CLASS_X:
-    /* Only the single x is unrecognized.  */
+    /* For compatibility this pretends to support any X extension except the
+       single letter "x". */
     if (strcmp (ext, "x") != 0)
       return true;
   default:
@@ -1504,10 +1514,9 @@ riscv_get_default_ext_version (enum riscv_spec_class *default_isa_spec,
   switch (class)
     {
     case RV_ISA_CLASS_ZXM: table = riscv_supported_std_zxm_ext; break;
-    case RV_ISA_CLASS_Z: table = riscv_supported_std_z_ext; break;
-    case RV_ISA_CLASS_S: table = riscv_supported_std_s_ext; break;
-    case RV_ISA_CLASS_X:
-      break;
+    case RV_ISA_CLASS_Z: table = riscv_supported_std_z_ext;     break;
+    case RV_ISA_CLASS_S: table = riscv_supported_std_s_ext;     break;
+    case RV_ISA_CLASS_X: table = riscv_supported_custom_ext;    break;
     default:
       table = riscv_supported_std_ext;
     }
@@ -1517,6 +1526,7 @@ riscv_get_default_ext_version (enum riscv_spec_class *default_isa_spec,
     {
       if (strcmp (table[i].name, name) == 0
 	  && (table[i].isa_spec_class == ISA_SPEC_CLASS_DRAFT
+	      || table[i].isa_spec_class == VENDOR_SPEC_CLASS_THEAD
 	      || table[i].isa_spec_class == *default_isa_spec))
 	{
 	  *major_version = table[i].major_version;
@@ -2402,6 +2412,19 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
       return riscv_subset_supports (rps, "svinval");
     case INSN_CLASS_H:
       return riscv_subset_supports (rps, "h");
+    case INSN_CLASS_THEAD_C:
+      return riscv_subset_supports (rps, "xtheadc");
+    case INSN_CLASS_THEAD_E:
+      return riscv_subset_supports (rps, "xtheade");
+    case INSN_CLASS_THEAD_SE:
+      return riscv_subset_supports (rps, "xtheadse");
+    case INSN_CLASS_THEAD_C_OR_E:
+      return (riscv_subset_supports (rps, "xtheadc")
+	      || riscv_subset_supports (rps, "xtheade"));
+    case INSN_CLASS_THEAD_C_OR_E_OR_SE:
+      return (riscv_subset_supports (rps, "xtheadc")
+	      || riscv_subset_supports (rps, "xtheade")
+	      || riscv_subset_supports (rps, "xtheadse"));
     default:
       rps->error_handler
         (_("internal: unreachable INSN_CLASS_*"));
@@ -2527,6 +2550,16 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
       return "svinval";
     case INSN_CLASS_H:
       return _("h");
+    case INSN_CLASS_THEAD_C:
+      return "xtheadc";
+    case INSN_CLASS_THEAD_E:
+      return "xtheade";
+    case INSN_CLASS_THEAD_SE:
+      return "xtheadse";
+    case INSN_CLASS_THEAD_C_OR_E:
+      return _("xtheadc' or `xtheade");
+    case INSN_CLASS_THEAD_C_OR_E_OR_SE:
+      return _("xtheadc' or `xtheade' or `xtheadse");
     default:
       rps->error_handler
         (_("internal: unreachable INSN_CLASS_*"));
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 291d07f6d8f..8a473d4b3fe 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -78,6 +78,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_THEAD,		/* vendor CSR for T-HEAD */
 };
 
 /* This structure holds all restricted conditions for a CSR.  */
@@ -965,6 +966,9 @@ riscv_csr_address (const char *csr_name,
       break;
     case CSR_CLASS_DEBUG:
       break;
+    case CSR_CLASS_THEAD:
+      extension = "xthead";
+      break;
     default:
       as_bad (_("internal: bad RISC-V CSR class (0x%x)"), csr_class);
     }
@@ -1253,6 +1257,30 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
 		goto unknown_validate_operand;
 	    }
 	  break;
+	case 'X': /* Opcode for custom instructions.  */
+	  {
+	    int nbit, at, n;
+	    if (sscanf(oparg, "XI%d@%d%n", &nbit, &at, &n) == 2)
+	      {
+		used_bits |= ENCODE_VENDOR_THEAD_IMM ((1ULL << nbit) - 1,
+						      nbit, at);
+		oparg += n - 1;
+	      }
+	    else if (sscanf(oparg, "XS%d@%d%n", &nbit, &at, &n) == 2)
+	      {
+		used_bits |= ENCODE_VENDOR_THEAD_SIGN_IMM ((1ULL << nbit) - 1,
+							   nbit, at);
+		oparg += n - 1;
+	      }
+	    else
+	      {
+		as_bad (_("internal: bad X opcode type `%s'"),
+			oparg);
+		return false;
+	      }
+	  }
+	  break;
+
 	default:
 	unknown_validate_operand:
 	  as_bad (_("internal: bad RISC-V opcode "
@@ -3265,6 +3293,63 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 	      asarg = expr_end;
 	      continue;
 
+	    case 'X': /* Vendor-specific.  */
+	      {
+		int nbit, at, n;
+		if (sscanf(oparg, "XI%d@%d%n", &nbit, &at, &n) == 2)
+		  {
+		    my_getExpression (imm_expr, asarg);
+		    if (imm_expr->X_op != O_constant)
+		      {
+			as_bad (_("non-constant operand"));
+			break;
+		      }
+
+		    if (!VALID_VENDOR_THEAD_IMM (imm_expr->X_add_number, nbit, at))
+		      {
+			as_bad (_("invalid immediate"));
+			break;
+		      }
+
+		    ip->insn_opcode |=
+		      ENCODE_VENDOR_THEAD_IMM (imm_expr->X_add_number, nbit, at);
+		    asarg = expr_end;
+		    imm_expr->X_op = O_absent;
+		    oparg += n - 1;
+		    continue;
+		  }
+		else if (sscanf(oparg, "XS%d@%d%n", &nbit, &at, &n) == 2)
+		  {
+		    my_getExpression (imm_expr, asarg);
+		    if (imm_expr->X_op != O_constant)
+		      {
+			as_bad (_("non-constant operand"));
+			break;
+		      }
+
+		    if (!VALID_VENDOR_THEAD_SIGN_IMM (imm_expr->X_add_number, nbit, at))
+		      {
+			as_bad (_("invalid immediate"));
+			break;
+		      }
+
+		    ip->insn_opcode |=
+		      ENCODE_VENDOR_THEAD_SIGN_IMM (imm_expr->X_add_number, nbit, at);
+		    asarg = expr_end;
+		    imm_expr->X_op = O_absent;
+		    oparg += n - 1;
+		    continue;
+		  }
+
+		else
+		  {
+		    as_fatal (_("internal: unknown X argument type `%s'"),
+			      opargStart);
+		    break;
+		  }
+		continue;
+	      }
+
 	    default:
 	    unknown_riscv_ip_operand:
 	      as_fatal (_("internal: unknown argument type `%s'"),
diff --git a/gas/testsuite/gas/riscv/thead-csr-list.d b/gas/testsuite/gas/riscv/thead-csr-list.d
new file mode 100644
index 00000000000..08bda4d24ea
--- /dev/null
+++ b/gas/testsuite/gas/riscv/thead-csr-list.d
@@ -0,0 +1,107 @@
+#as: -march=rv64gcxtheadc
+#objdump: -dr
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0000000000000000 <.text>:
+   0:	7c002573          	csrr	a0,th_mxstatus
+   4:	7c102573          	csrr	a0,th_mhcr
+   8:	7c202573          	csrr	a0,th_mcor
+   c:	7c302573          	csrr	a0,th_mccr2
+  10:	7c402573          	csrr	a0,th_mcer2
+  14:	7c502573          	csrr	a0,th_mhint
+  18:	7c602573          	csrr	a0,th_mrmr
+  1c:	7c702573          	csrr	a0,th_mrvbr
+  20:	7c802573          	csrr	a0,th_mcer
+  24:	7c902573          	csrr	a0,th_mcounterwen
+  28:	7ca02573          	csrr	a0,th_mcounterinten
+  2c:	7cb02573          	csrr	a0,th_mcounterof
+  30:	7cc02573          	csrr	a0,th_mhint2
+  34:	7cd02573          	csrr	a0,th_mhint3
+  38:	7e002573          	csrr	a0,th_mraddr
+  3c:	7e102573          	csrr	a0,th_mexstatus
+  40:	7e202573          	csrr	a0,th_mnmicause
+  44:	7e302573          	csrr	a0,th_mnmipc
+  48:	7f002573          	csrr	a0,th_mhpmcr
+  4c:	7f102573          	csrr	a0,th_mhpmsr
+  50:	7f202573          	csrr	a0,th_mhpmer
+  54:	7f302573          	csrr	a0,th_msmpr
+  58:	7f402573          	csrr	a0,th_mteecfg
+  5c:	7d102573          	csrr	a0,th_usp
+  60:	7d202573          	csrr	a0,th_mcins
+  64:	7d302573          	csrr	a0,th_mcindex
+  68:	7d402573          	csrr	a0,th_mcdata0
+  6c:	7d502573          	csrr	a0,th_mcdata1
+  70:	7d602573          	csrr	a0,th_meicr
+  74:	7d702573          	csrr	a0,th_meicr2
+  78:	be002573          	csrr	a0,th_mebr
+  7c:	be102573          	csrr	a0,th_nt_mstatus
+  80:	be302573          	csrr	a0,th_nt_mtvec
+  84:	be202573          	csrr	a0,th_nt_mie
+  88:	be402573          	csrr	a0,th_nt_mtvt
+  8c:	be502573          	csrr	a0,th_nt_mepc
+  90:	be602573          	csrr	a0,th_nt_mcause
+  94:	be702573          	csrr	a0,th_nt_mip
+  98:	be802573          	csrr	a0,th_nt_mintstate
+  9c:	be902573          	csrr	a0,th_nt_mxstatus
+  a0:	bea02573          	csrr	a0,th_nt_mebr
+  a4:	beb02573          	csrr	a0,th_nt_msp
+  a8:	bec02573          	csrr	a0,th_t_usp
+  ac:	bed02573          	csrr	a0,th_t_mdcr
+  b0:	bee02573          	csrr	a0,th_t_mpcr
+  b4:	bef02573          	csrr	a0,th_pmpteecfg
+  b8:	fc002573          	csrr	a0,th_mcpuid
+  bc:	fc102573          	csrr	a0,th_mapbaddr
+  c0:	fc202573          	csrr	a0,th_mwmsr
+  c4:	80002573          	csrr	a0,th_fxcr
+  c8:	9c002573          	csrr	a0,th_smir
+  cc:	9c102573          	csrr	a0,th_smel
+  d0:	9c202573          	csrr	a0,th_smeh
+  d4:	9c302573          	csrr	a0,th_smcir
+  d8:	5c002573          	csrr	a0,th_sxstatus
+  dc:	5c102573          	csrr	a0,th_shcr
+  e0:	5c202573          	csrr	a0,th_scer2
+  e4:	5c302573          	csrr	a0,th_scer
+  e8:	5c402573          	csrr	a0,th_scounterinten
+  ec:	5c502573          	csrr	a0,th_scounterof
+  f0:	5c602573          	csrr	a0,th_shint
+  f4:	5c702573          	csrr	a0,th_shint2
+  f8:	5c802573          	csrr	a0,th_shpminhibit
+  fc:	5c902573          	csrr	a0,th_shpmcr
+ 100:	5ca02573          	csrr	a0,th_shpmsr
+ 104:	5cb02573          	csrr	a0,th_shpmer
+ 108:	5e002573          	csrr	a0,th_scycle
+ 10c:	5e102573          	csrr	a0,th_shpmcounter1
+ 110:	5e202573          	csrr	a0,th_shpmcounter2
+ 114:	5e302573          	csrr	a0,th_shpmcounter3
+ 118:	5e402573          	csrr	a0,th_shpmcounter4
+ 11c:	5e502573          	csrr	a0,th_shpmcounter5
+ 120:	5e602573          	csrr	a0,th_shpmcounter6
+ 124:	5e702573          	csrr	a0,th_shpmcounter7
+ 128:	5e802573          	csrr	a0,th_shpmcounter8
+ 12c:	5e902573          	csrr	a0,th_shpmcounter9
+ 130:	5ea02573          	csrr	a0,th_shpmcounter10
+ 134:	5eb02573          	csrr	a0,th_shpmcounter11
+ 138:	5ec02573          	csrr	a0,th_shpmcounter12
+ 13c:	5ed02573          	csrr	a0,th_shpmcounter13
+ 140:	5ee02573          	csrr	a0,th_shpmcounter14
+ 144:	5ef02573          	csrr	a0,th_shpmcounter15
+ 148:	5f002573          	csrr	a0,th_shpmcounter16
+ 14c:	5f102573          	csrr	a0,th_shpmcounter17
+ 150:	5f202573          	csrr	a0,th_shpmcounter18
+ 154:	5f302573          	csrr	a0,th_shpmcounter19
+ 158:	5f402573          	csrr	a0,th_shpmcounter20
+ 15c:	5f502573          	csrr	a0,th_shpmcounter21
+ 160:	5f602573          	csrr	a0,th_shpmcounter22
+ 164:	5f702573          	csrr	a0,th_shpmcounter23
+ 168:	5f802573          	csrr	a0,th_shpmcounter24
+ 16c:	5f902573          	csrr	a0,th_shpmcounter25
+ 170:	5fa02573          	csrr	a0,th_shpmcounter26
+ 174:	5fb02573          	csrr	a0,th_shpmcounter27
+ 178:	5fc02573          	csrr	a0,th_shpmcounter28
+ 17c:	5fd02573          	csrr	a0,th_shpmcounter29
+ 180:	5fe02573          	csrr	a0,th_shpmcounter30
+ 184:	5ff02573          	csrr	a0,th_shpmcounter31
diff --git a/gas/testsuite/gas/riscv/thead-csr-list.s b/gas/testsuite/gas/riscv/thead-csr-list.s
new file mode 100644
index 00000000000..0784179683d
--- /dev/null
+++ b/gas/testsuite/gas/riscv/thead-csr-list.s
@@ -0,0 +1,98 @@
+csrr a0, th_mxstatus
+csrr a0, th_mhcr
+csrr a0, th_mcor
+csrr a0, th_mccr2
+csrr a0, th_mcer2
+csrr a0, th_mhint
+csrr a0, th_mrmr
+csrr a0, th_mrvbr
+csrr a0, th_mcer
+csrr a0, th_mcounterwen
+csrr a0, th_mcounterinten
+csrr a0, th_mcounterof
+csrr a0, th_mhint2
+csrr a0, th_mhint3
+csrr a0, th_mraddr
+csrr a0, th_mexstatus
+csrr a0, th_mnmicause
+csrr a0, th_mnmipc
+csrr a0, th_mhpmcr
+csrr a0, th_mhpmsr
+csrr a0, th_mhpmer
+csrr a0, th_msmpr
+csrr a0, th_mteecfg
+csrr a0, th_usp
+csrr a0, th_mcins
+csrr a0, th_mcindex
+csrr a0, th_mcdata0
+csrr a0, th_mcdata1
+csrr a0, th_meicr
+csrr a0, th_meicr2
+csrr a0, th_mebr
+csrr a0, th_nt_mstatus
+csrr a0, th_nt_mtvec
+csrr a0, th_nt_mie
+csrr a0, th_nt_mtvt
+csrr a0, th_nt_mepc
+csrr a0, th_nt_mcause
+csrr a0, th_nt_mip
+csrr a0, th_nt_mintstate
+csrr a0, th_nt_mxstatus
+csrr a0, th_nt_mebr
+csrr a0, th_nt_msp
+csrr a0, th_t_usp
+csrr a0, th_t_mdcr
+csrr a0, th_t_mpcr
+csrr a0, th_pmpteecfg
+csrr a0, th_mcpuid
+csrr a0, th_mapbaddr
+csrr a0, th_mwmsr
+csrr a0, th_fxcr
+csrr a0, th_smir
+csrr a0, th_smel
+csrr a0, th_smeh
+csrr a0, th_smcir
+csrr a0, th_sxstatus
+csrr a0, th_shcr
+csrr a0, th_scer2
+csrr a0, th_scer
+csrr a0, th_scounterinten
+csrr a0, th_scounterof
+csrr a0, th_shint
+csrr a0, th_shint2
+csrr a0, th_shpminhibit
+csrr a0, th_shpmcr
+csrr a0, th_shpmsr
+csrr a0, th_shpmer
+csrr a0, th_scycle
+csrr a0, th_shpmcounter1
+csrr a0, th_shpmcounter2
+csrr a0, th_shpmcounter3
+csrr a0, th_shpmcounter4
+csrr a0, th_shpmcounter5
+csrr a0, th_shpmcounter6
+csrr a0, th_shpmcounter7
+csrr a0, th_shpmcounter8
+csrr a0, th_shpmcounter9
+csrr a0, th_shpmcounter10
+csrr a0, th_shpmcounter11
+csrr a0, th_shpmcounter12
+csrr a0, th_shpmcounter13
+csrr a0, th_shpmcounter14
+csrr a0, th_shpmcounter15
+csrr a0, th_shpmcounter16
+csrr a0, th_shpmcounter17
+csrr a0, th_shpmcounter18
+csrr a0, th_shpmcounter19
+csrr a0, th_shpmcounter20
+csrr a0, th_shpmcounter21
+csrr a0, th_shpmcounter22
+csrr a0, th_shpmcounter23
+csrr a0, th_shpmcounter24
+csrr a0, th_shpmcounter25
+csrr a0, th_shpmcounter26
+csrr a0, th_shpmcounter27
+csrr a0, th_shpmcounter28
+csrr a0, th_shpmcounter29
+csrr a0, th_shpmcounter30
+csrr a0, th_shpmcounter31
diff --git a/gas/testsuite/gas/riscv/theadc-ext.d b/gas/testsuite/gas/riscv/theadc-ext.d
new file mode 100644
index 00000000000..b697f1b1c86
--- /dev/null
+++ b/gas/testsuite/gas/riscv/theadc-ext.d
@@ -0,0 +1,112 @@
+#as: -march=rv64gcxtheadc
+#objdump: -dr
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0000000000000000 <.text>:
+   0:	cff01073          	csrw	0xcff,zero
+   4:	0010000b          	th.dcache.call
+   8:	0030000b          	th.dcache.ciall
+   c:	02b5000b          	th.dcache.cipa	a0
+  10:	0235000b          	th.dcache.cisw	a0
+  14:	0275000b          	th.dcache.civa	a0
+  18:	0295000b          	th.dcache.cpa	a0
+  1c:	0285000b          	th.dcache.cpal1	a0
+  20:	0255000b          	th.dcache.cva	a0
+  24:	0245000b          	th.dcache.cval1	a0
+  28:	02a5000b          	th.dcache.ipa	a0
+  2c:	0225000b          	th.dcache.isw	a0
+  30:	0265000b          	th.dcache.iva	a0
+  34:	0020000b          	th.dcache.iall
+  38:	0215000b          	th.dcache.csw	a0
+  3c:	0100000b          	th.icache.iall
+  40:	0110000b          	th.icache.ialls
+  44:	0305000b          	th.icache.iva	a0
+  48:	0385000b          	th.icache.ipa	a0
+  4c:	0160000b          	th.l2cache.iall
+  50:	0150000b          	th.l2cache.call
+  54:	0170000b          	th.l2cache.ciall
+  58:	04b5000b          	th.sfence.vmas	a0,a1
+  5c:	0180000b          	th.sync
+  60:	01a0000b          	th.sync.i
+  64:	0190000b          	th.sync.s
+  68:	01b0000b          	th.sync.is
+  6c:	02c5950b          	th.addsl	a0,a1,a2,1
+  70:	20c5950b          	th.mula	a0,a1,a2
+  74:	22c5950b          	th.muls	a0,a1,a2
+  78:	24c5950b          	th.mulaw	a0,a1,a2
+  7c:	26c5950b          	th.mulsw	a0,a1,a2
+  80:	28c5950b          	th.mulah	a0,a1,a2
+  84:	2ac5950b          	th.mulsh	a0,a1,a2
+  88:	1105950b          	th.srri	a0,a1,16
+  8c:	1505950b          	th.srriw	a0,a1,16
+  90:	40c5950b          	th.mveqz	a0,a1,a2
+  94:	42c5950b          	th.mvnez	a0,a1,a2
+  98:	8905950b          	th.tst	a0,a1,16
+  9c:	8005950b          	th.tstnbz	a0,a1
+  a0:	4105a50b          	th.ext	a0,a1,16,16
+  a4:	4105b50b          	th.extu	a0,a1,16,16
+  a8:	8605950b          	th.ff1	a0,a1
+  ac:	8405950b          	th.ff0	a0,a1
+  b0:	8205950b          	th.rev	a0,a1
+  b4:	9005950b          	th.revw	a0,a1
+  b8:	62b5600b          	th.flrd	ft0,a0,a1,1
+  bc:	42b5600b          	th.flrw	ft0,a0,a1,1
+  c0:	72b5600b          	th.flurd	ft0,a0,a1,1
+  c4:	52b5600b          	th.flurw	ft0,a0,a1,1
+  c8:	02c5c50b          	th.lrb	a0,a1,a2,1
+  cc:	22c5c50b          	th.lrh	a0,a1,a2,1
+  d0:	42c5c50b          	th.lrw	a0,a1,a2,1
+  d4:	62c5c50b          	th.lrd	a0,a1,a2,1
+  d8:	82c5c50b          	th.lrbu	a0,a1,a2,1
+  dc:	a2c5c50b          	th.lrhu	a0,a1,a2,1
+  e0:	c2c5c50b          	th.lrwu	a0,a1,a2,1
+  e4:	12c5c50b          	th.lurb	a0,a1,a2,1
+  e8:	32c5c50b          	th.lurh	a0,a1,a2,1
+  ec:	52c5c50b          	th.lurw	a0,a1,a2,1
+  f0:	72c5c50b          	th.lurd	a0,a1,a2,1
+  f4:	92c5c50b          	th.lurbu	a0,a1,a2,1
+  f8:	b2c5c50b          	th.lurhu	a0,a1,a2,1
+  fc:	d2c5c50b          	th.lurwu	a0,a1,a2,1
+ 100:	1af5c50b          	th.lbia	a0,\(a1\),15,1
+ 104:	0af5c50b          	th.lbib	a0,\(a1\),15,1
+ 108:	3af5c50b          	th.lhia	a0,\(a1\),15,1
+ 10c:	2af5c50b          	th.lhib	a0,\(a1\),15,1
+ 110:	5af5c50b          	th.lwia	a0,\(a1\),15,1
+ 114:	4af5c50b          	th.lwib	a0,\(a1\),15,1
+ 118:	7af5c50b          	th.ldia	a0,\(a1\),15,1
+ 11c:	6af5c50b          	th.ldib	a0,\(a1\),15,1
+ 120:	9af5c50b          	th.lbuia	a0,\(a1\),15,1
+ 124:	8af5c50b          	th.lbuib	a0,\(a1\),15,1
+ 128:	baf5c50b          	th.lhuia	a0,\(a1\),15,1
+ 12c:	aaf5c50b          	th.lhuib	a0,\(a1\),15,1
+ 130:	daf5c50b          	th.lwuia	a0,\(a1\),15,1
+ 134:	caf5c50b          	th.lwuib	a0,\(a1\),15,1
+ 138:	fab6450b          	th.ldd	a0,a1,\(a2\),1
+ 13c:	e2b6450b          	th.lwd	a0,a1,\(a2\),1
+ 140:	f2b6450b          	th.lwud	a0,a1,\(a2\),1
+ 144:	62b5700b          	th.fsrd	ft0,a0,a1,1
+ 148:	42b5700b          	th.fsrw	ft0,a0,a1,1
+ 14c:	72b5700b          	th.fsurd	ft0,a0,a1,1
+ 150:	52b5700b          	th.fsurw	ft0,a0,a1,1
+ 154:	02c5d50b          	th.srb	a0,a1,a2,1
+ 158:	22c5d50b          	th.srh	a0,a1,a2,1
+ 15c:	42c5d50b          	th.srw	a0,a1,a2,1
+ 160:	62c5d50b          	th.srd	a0,a1,a2,1
+ 164:	12c5d50b          	th.surb	a0,a1,a2,1
+ 168:	32c5d50b          	th.surh	a0,a1,a2,1
+ 16c:	52c5d50b          	th.surw	a0,a1,a2,1
+ 170:	72c5d50b          	th.surd	a0,a1,a2,1
+ 174:	1af5d50b          	th.sbia	a0,\(a1\),15,1
+ 178:	0af5d50b          	th.sbib	a0,\(a1\),15,1
+ 17c:	3af5d50b          	th.shia	a0,\(a1\),15,1
+ 180:	2af5d50b          	th.shib	a0,\(a1\),15,1
+ 184:	5ac5d50b          	th.swia	a0,\(a1\),12,1
+ 188:	4af5d50b          	th.swib	a0,\(a1\),15,1
+ 18c:	7af5d50b          	th.sdia	a0,\(a1\),15,1
+ 190:	6af5d50b          	th.sdib	a0,\(a1\),15,1
+ 194:	fab6550b          	th.sdd	a0,a1,\(a2\),1
+ 198:	e2b6550b          	th.swd	a0,a1,\(a2\),1
diff --git a/gas/testsuite/gas/riscv/theadc-ext.s b/gas/testsuite/gas/riscv/theadc-ext.s
new file mode 100644
index 00000000000..fda4319863b
--- /dev/null
+++ b/gas/testsuite/gas/riscv/theadc-ext.s
@@ -0,0 +1,115 @@
+.text
+
+th.wsc
+
+# cache ext
+th.dcache.call
+th.dcache.ciall
+th.dcache.cipa a0
+th.dcache.cisw a0
+th.dcache.civa a0
+th.dcache.cpa a0
+th.dcache.cpal1 a0
+th.dcache.cva a0
+th.dcache.cval1 a0
+th.dcache.ipa a0
+th.dcache.isw a0
+th.dcache.iva a0
+th.dcache.iall
+th.dcache.csw a0
+th.icache.iall
+th.icache.ialls
+th.icache.iva a0
+th.icache.ipa a0
+th.l2cache.iall
+th.l2cache.call
+th.l2cache.ciall
+
+# sync ext
+th.sfence.vmas       a0, a1
+th.sync
+th.sync.i
+th.sync.s
+th.sync.is
+
+# calc ext
+th.addsl             a0, a1, a2, 1
+th.mula              a0, a1, a2
+th.muls              a0, a1, a2
+th.mulaw             a0, a1, a2
+th.mulsw             a0, a1, a2
+th.mulah             a0, a1, a2
+th.mulsh             a0, a1, a2
+th.srri              a0, a1, 16
+th.srriw             a0, a1, 16
+th.mveqz             a0, a1, a2
+th.mvnez             a0, a1, a2
+
+# bit ext
+th.tst               a0, a1, 16
+th.tstnbz            a0, a1
+th.ext               a0, a1, 16, 16
+th.extu              a0, a1, 16, 16
+th.ff1               a0, a1
+th.ff0               a0, a1
+th.rev               a0, a1
+th.revw       a0, a1
+
+# load/store ext
+th.flrd       f0, a0, a1, 1
+th.flrw       f0, a0, a1, 1
+th.flurd      f0, a0, a1, 1
+th.flurw      f0, a0, a1, 1
+th.lrb               a0, a1, a2, 1
+th.lrh               a0, a1, a2, 1
+th.lrw               a0, a1, a2, 1
+th.lrd               a0, a1, a2, 1
+th.lrbu              a0, a1, a2, 1
+th.lrhu              a0, a1, a2, 1
+th.lrwu              a0, a1, a2, 1
+th.lurb              a0, a1, a2, 1
+th.lurh              a0, a1, a2, 1
+th.lurw              a0, a1, a2, 1
+th.lurd              a0, a1, a2, 1
+th.lurbu             a0, a1, a2, 1
+th.lurhu             a0, a1, a2, 1
+th.lurwu             a0, a1, a2, 1
+th.lbia       a0, (a1), 15, 1
+th.lbib       a0, (a1), 15, 1
+th.lhia       a0, (a1), 15, 1
+th.lhib       a0, (a1), 15, 1
+th.lwia       a0, (a1), 15, 1
+th.lwib       a0, (a1), 15, 1
+th.ldia       a0, (a1), 15, 1
+th.ldib       a0, (a1), 15, 1
+th.lbuia      a0, (a1), 15, 1
+th.lbuib      a0, (a1), 15, 1
+th.lhuia      a0, (a1), 15, 1
+th.lhuib      a0, (a1), 15, 1
+th.lwuia      a0, (a1), 15, 1
+th.lwuib      a0, (a1), 15, 1
+th.ldd               a0, a1, (a2), 1
+th.lwd               a0, a1, (a2), 1
+th.lwud              a0, a1, (a2), 1
+th.fsrd       f0, a0, a1, 1
+th.fsrw       f0, a0, a1, 1
+th.fsurd      f0, a0, a1, 1
+th.fsurw      f0, a0, a1, 1
+th.srb               a0, a1, a2, 1
+th.srh               a0, a1, a2, 1
+th.srw               a0, a1, a2, 1
+th.srd               a0, a1, a2, 1
+th.surb              a0, a1, a2, 1
+th.surh              a0, a1, a2, 1
+th.surw              a0, a1, a2, 1
+th.surd              a0, a1, a2, 1
+th.sbia              a0, (a1), 15, 1
+th.sbib              a0, (a1), 15, 1
+th.shia              a0, (a1), 15, 1
+th.shib              a0, (a1), 15, 1
+th.swia              a0, (a1), 12, 1
+th.swib              a0, (a1), 15, 1
+th.sdia              a0, (a1), 15, 1
+th.sdib              a0, (a1), 15, 1
+th.sdd               a0, a1, (a2), 1
+th.swd               a0, a1, (a2), 1
diff --git a/gas/testsuite/gas/riscv/theade-ext.d b/gas/testsuite/gas/riscv/theade-ext.d
new file mode 100644
index 00000000000..ff4234d323e
--- /dev/null
+++ b/gas/testsuite/gas/riscv/theade-ext.d
@@ -0,0 +1,62 @@
+#as: -march=rv32gcxtheade
+#objdump: -dr
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+00000000 <.text>:
+[       ]+[0-9a-f]+:\s+cff01073          	csrw	0xcff,zero
+[       ]+[0-9a-f]+:\s+02a5000b          	th.dcache.ipa	a0
+[       ]+[0-9a-f]+:\s+0295000b          	th.dcache.cpa	a0
+[       ]+[0-9a-f]+:\s+02b5000b          	th.dcache.cipa	a0
+[       ]+[0-9a-f]+:\s+0225000b          	th.dcache.isw	a0
+[       ]+[0-9a-f]+:\s+0215000b          	th.dcache.csw	a0
+[       ]+[0-9a-f]+:\s+0235000b          	th.dcache.cisw	a0
+[       ]+[0-9a-f]+:\s+0020000b          	th.dcache.iall
+[       ]+[0-9a-f]+:\s+0010000b          	th.dcache.call
+[       ]+[0-9a-f]+:\s+0030000b          	th.dcache.ciall
+[       ]+[0-9a-f]+:\s+0100000b          	th.icache.iall
+[       ]+[0-9a-f]+:\s+0385000b          	th.icache.ipa	a0
+[       ]+[0-9a-f]+:\s+0180000b          	th.sync
+[       ]+[0-9a-f]+:\s+01a0000b          	th.sync.i
+[       ]+[0-9a-f]+:\s+02c5950b          	th.addsl	a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+1105950b          	th.srri	a0,a1,16
+[       ]+[0-9a-f]+:\s+20c5950b          	th.mula	a0,a1,a2
+[       ]+[0-9a-f]+:\s+28c5950b          	th.mulah	a0,a1,a2
+[       ]+[0-9a-f]+:\s+22c5950b          	th.muls	a0,a1,a2
+[       ]+[0-9a-f]+:\s+2ac5950b          	th.mulsh	a0,a1,a2
+[       ]+[0-9a-f]+:\s+40c5950b          	th.mveqz	a0,a1,a2
+[       ]+[0-9a-f]+:\s+42c5950b          	th.mvnez	a0,a1,a2
+[       ]+[0-9a-f]+:\s+4105a50b          	th.ext	a0,a1,16,16
+[       ]+[0-9a-f]+:\s+4105b50b          	th.extu	a0,a1,16,16
+[       ]+[0-9a-f]+:\s+8605950b          	th.ff1	a0,a1
+[       ]+[0-9a-f]+:\s+8405950b          	th.ff0	a0,a1
+[       ]+[0-9a-f]+:\s+8205950b          	th.rev	a0,a1
+[       ]+[0-9a-f]+:\s+8905950b          	th.tst	a0,a1,16
+[       ]+[0-9a-f]+:\s+8005950b          	th.tstnbz	a0,a1
+[       ]+[0-9a-f]+:\s+02c5c50b          	th.lrb	a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+22c5c50b          	th.lrh	a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+42c5c50b          	th.lrw	a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+82c5c50b          	th.lrbu	a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+a2c5c50b          	th.lrhu	a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+1af5c50b          	th.lbia	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+0af5c50b          	th.lbib	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+3af5c50b          	th.lhia	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+2af5c50b          	th.lhib	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+5af5c50b          	th.lwia	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+4af5c50b          	th.lwib	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+02c5d50b          	th.srb	a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+22c5d50b          	th.srh	a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+42c5d50b          	th.srw	a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+1af5d50b          	th.sbia	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+0af5d50b          	th.sbib	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+3af5d50b          	th.shia	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+2af5d50b          	th.shib	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+5ac5d50b          	th.swia	a0,\(a1\),12,1
+[       ]+[0-9a-f]+:\s+4af5d50b          	th.swib	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+c000150b          	th.fmv.x.hw	a0,ft0
+[       ]+[0-9a-f]+:\s+a005100b          	th.fmv.hw.x	ft0,a0
+[       ]+[0-9a-f]+:\s+0040000b          	th.ipush
+[       ]+[0-9a-f]+:\s+0050000b          	th.ipop
diff --git a/gas/testsuite/gas/riscv/theade-ext.s b/gas/testsuite/gas/riscv/theade-ext.s
new file mode 100644
index 00000000000..a56385802b1
--- /dev/null
+++ b/gas/testsuite/gas/riscv/theade-ext.s
@@ -0,0 +1,66 @@
+.text
+
+th.wsc
+
+# cache ext
+th.dcache.ipa a0
+th.dcache.cpa a0
+th.dcache.cipa a0
+th.dcache.isw a0
+th.dcache.csw a0
+th.dcache.cisw a0
+th.dcache.iall
+th.dcache.call
+th.dcache.ciall
+th.icache.iall
+th.icache.ipa a0
+
+# sync ext
+th.sync
+th.sync.i
+
+# calc ext
+th.addsl             a0, a1, a2, 1
+th.srri              a0, a1, 16
+th.mula              a0, a1, a2
+th.mulah             a0, a1, a2
+th.muls              a0, a1, a2
+th.mulsh             a0, a1, a2
+th.mveqz             a0, a1, a2
+th.mvnez             a0, a1, a2
+
+# bit ext
+th.ext               a0, a1, 16, 16
+th.extu              a0, a1, 16, 16
+th.ff1               a0, a1
+th.ff0               a0, a1
+th.rev               a0, a1
+th.tst               a0, a1, 16
+th.tstnbz            a0, a1
+
+# load/store ext
+th.lrb               a0, a1, a2, 1
+th.lrh               a0, a1, a2, 1
+th.lrw               a0, a1, a2, 1
+th.lrbu              a0, a1, a2, 1
+th.lrhu              a0, a1, a2, 1
+th.lbia       a0, (a1), 15, 1
+th.lbib       a0, (a1), 15, 1
+th.lhia       a0, (a1), 15, 1
+th.lhib       a0, (a1), 15, 1
+th.lwia       a0, (a1), 15, 1
+th.lwib       a0, (a1), 15, 1
+th.srb               a0, a1, a2, 1
+th.srh               a0, a1, a2, 1
+th.srw               a0, a1, a2, 1
+th.sbia              a0, (a1), 15, 1
+th.sbib              a0, (a1), 15, 1
+th.shia              a0, (a1), 15, 1
+th.shib              a0, (a1), 15, 1
+th.swia              a0, (a1), 12, 1
+th.swib              a0, (a1), 15, 1
+
+th.fmv.x.hw   a0, f0
+th.fmv.hw.x   f0, a0
+th.ipush
+th.ipop
diff --git a/include/opcode/riscv-opc-thead.h b/include/opcode/riscv-opc-thead.h
new file mode 100644
index 00000000000..98935f6b2b0
--- /dev/null
+++ b/include/opcode/riscv-opc-thead.h
@@ -0,0 +1,571 @@
+/* riscv-opcextended.h.  RISC-V extended instruction opcode.
+   Copyright (C) 2021 Free Software Foundation, Inc.
+
+   This file is part of GDB, GAS, and the GNU binutils.
+
+   GDB, GAS, and the GNU binutils are free software; you can redistribute
+   them and/or modify them under the terms of the GNU General Public
+   License as published by the Free Software Foundation; either version
+   3, or (at your option) any later version.
+
+   GDB, GAS, and the GNU binutils are distributed in the hope that they
+   will be useful, but WITHOUT ANY WARRANTY; without even the implied
+   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+   the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; see the file COPYING3. If not,
+   see <http://www.gnu.org/licenses/>.  */
+
+#ifndef __RISCV_OPC_THEAD__
+#define __RISCV_OPC_THEAD__
+/* Opcodes for T-HEAD.  */
+#define MATCH_DCACHE_CALL	0x0010000b
+#define MASK_DCACHE_CALL	0xffffffff
+#define MATCH_DCACHE_IALL	0x0020000b
+#define MASK_DCACHE_IALL	0xffffffff
+#define MATCH_DCACHE_CSW	0x0210000b
+#define MASK_DCACHE_CSW		0xfff07fff
+#define MATCH_DCACHE_ISW	0x0220000b
+#define MASK_DCACHE_ISW		0xfff07fff
+#define MATCH_DCACHE_CIALL	0x0030000b
+#define MASK_DCACHE_CIALL	0xffffffff
+#define MATCH_DCACHE_CISW	0x0230000b
+#define MASK_DCACHE_CISW	0xfff07fff
+#define MATCH_DCACHE_CVAL1	0x0240000b
+#define MASK_DCACHE_CVAL1	0xfff07fff
+#define MATCH_DCACHE_CVA	0x0250000b
+#define MASK_DCACHE_CVA		0xfff07fff
+#define MATCH_DCACHE_IVA	0x0260000b
+#define MASK_DCACHE_IVA		0xfff07fff
+#define MATCH_DCACHE_CIVA	0x0270000b
+#define MASK_DCACHE_CIVA	0xfff07fff
+#define MATCH_DCACHE_CPAL1	0x0280000b
+#define MASK_DCACHE_CPAL1	0xfff07fff
+#define MATCH_DCACHE_CPA	0x0290000b
+#define MASK_DCACHE_CPA		0xfff07fff
+#define MATCH_DCACHE_IPA	0x02a0000b
+#define MASK_DCACHE_IPA		0xfff07fff
+#define MATCH_DCACHE_CIPA	0x02b0000b
+#define MASK_DCACHE_CIPA	0xfff07fff
+#define MATCH_ICACHE_IALL	0x0100000b
+#define MASK_ICACHE_IALL	0xffffffff
+#define MATCH_ICACHE_IALLS	0x0110000b
+#define MASK_ICACHE_IALLS	0xffffffff
+#define MATCH_ICACHE_IVA	0x0300000b
+#define MASK_ICACHE_IVA		0xfff07fff
+#define MATCH_ICACHE_IPA	0x0380000b
+#define MASK_ICACHE_IPA		0xfff07fff
+#define MATCH_L2CACHE_CALL	0x0150000b
+#define MASK_L2CACHE_CALL	0xffffffff
+#define MATCH_L2CACHE_IALL	0x0160000b
+#define MASK_L2CACHE_IALL	0xffffffff
+#define MATCH_L2CACHE_CIALL	0x0170000b
+#define MASK_L2CACHE_CIALL	0xffffffff
+#define MATCH_SYNC		0x0180000b
+#define MASK_SYNC		0xffffffff
+#define MATCH_SYNC_S		0x0190000b
+#define MASK_SYNC_S		0xffffffff
+#define MATCH_SYNC_I		0x01a0000b
+#define MASK_SYNC_I		0xffffffff
+#define MATCH_SYNC_IS		0x01b0000b
+#define MASK_SYNC_IS		0xffffffff
+#define MATCH_SFENCE_VMAS	0x0400000b
+#define MASK_SFENCE_VMAS	0xfe007fff
+#define MATCH_TSTNBZ		0x8000100b
+#define MASK_TSTNBZ		0xfff0707f
+#define MATCH_MVEQZ		0x4000100b
+#define MASK_MVEQZ		0xfe00707f
+#define MATCH_MVNEZ		0x4200100b
+#define MASK_MVNEZ		0xfe00707f
+#define MATCH_MULA		0x2000100b
+#define MASK_MULA		0xfe00707f
+#define MATCH_MULS		0x2200100b
+#define MASK_MULS		0xfe00707f
+#define MATCH_MULAW		0x2400100b
+#define MASK_MULAW		0xfe00707f
+#define MATCH_MULSW		0x2600100b
+#define MASK_MULSW		0xfe00707f
+#define MATCH_MULAH		0x2800100b
+#define MASK_MULAH		0xfe00707f
+#define MATCH_MULSH		0x2a00100b
+#define MASK_MULSH		0xfe00707f
+#define MATCH_EXT		0x0000200b
+#define MASK_EXT		0x0000707f
+#define MATCH_EXTU		0x0000300b
+#define MASK_EXTU		0x0000707f
+#define MATCH_LRB		0x0000400b
+#define MASK_LRB		0xf800707f
+#define MATCH_LRH		0x2000400b
+#define MASK_LRH		0xf800707f
+#define MATCH_LRW		0x4000400b
+#define MASK_LRW		0xf800707f
+#define MATCH_LRD		0x6000400b
+#define MASK_LRD		0xf800707f
+#define MATCH_LRBU		0x8000400b
+#define MASK_LRBU		0xf800707f
+#define MATCH_LRHU		0xa000400b
+#define MASK_LRHU		0xf800707f
+#define MATCH_LRWU		0xc000400b
+#define MASK_LRWU		0xf800707f
+#define MATCH_LURB		0x1000400b
+#define MASK_LURB		0xf800707f
+#define MATCH_LURH		0x3000400b
+#define MASK_LURH		0xf800707f
+#define MATCH_LURW		0x5000400b
+#define MASK_LURW		0xf800707f
+#define MATCH_LURD		0x7000400b
+#define MASK_LURD		0xf800707f
+#define MATCH_LURBU		0x9000400b
+#define MASK_LURBU		0xf800707f
+#define MATCH_LURHU		0xb000400b
+#define MASK_LURHU		0xf800707f
+#define MATCH_LURWU		0xd000400b
+#define MASK_LURWU		0xf800707f
+#define MATCH_REV		0x8200100b
+#define MASK_REV		0xfff0707f
+#define MATCH_FF0		0x8400100b
+#define MASK_FF0		0xfff0707f
+#define MATCH_FF1		0x8600100b
+#define MASK_FF1		0xfff0707f
+#define MATCH_SRB		0x0000500b
+#define MASK_SRB		0xf800707f
+#define MATCH_SRH		0x2000500b
+#define MASK_SRH		0xf800707f
+#define MATCH_SRW		0x4000500b
+#define MASK_SRW		0xf800707f
+#define MATCH_SRD		0x6000500b
+#define MASK_SRD		0xf800707f
+#define MATCH_SURB		0x1000500b
+#define MASK_SURB		0xf800707f
+#define MATCH_SURH		0x3000500b
+#define MASK_SURH		0xf800707f
+#define MATCH_SURW		0x5000500b
+#define MASK_SURW		0xf800707f
+#define MATCH_SURD		0x7000500b
+#define MASK_SURD		0xf800707f
+#define MATCH_TST		0x8800100b
+#define MASK_TST		0xfc00707f
+#define MATCH_SRRIW		0x1400100b
+#define MASK_SRRIW		0xfe00707f
+#define MATCH_SRRI		0x1000100b
+#define MASK_SRRI		0xfc00707f
+#define MATCH_ADDSL		0x0000100b
+#define MASK_ADDSL		0xf800707f
+#define MATCH_SWD		0xe000500b
+#define MASK_SWD		0xf800707f
+#define MATCH_SDD		0xf800500b
+#define MASK_SDD		0xf800707f
+#define MATCH_SDIA		0x7800500b
+#define MASK_SDIA		0xf800707f
+#define MATCH_SDIB		0x6800500b
+#define MASK_SDIB		0xf800707f
+#define MATCH_SWIA		0x5800500b
+#define MASK_SWIA		0xf800707f
+#define MATCH_SWIB		0x4800500b
+#define MASK_SWIB		0xf800707f
+#define MATCH_SHIB		0x2800500b
+#define MASK_SHIB		0xf800707f
+#define MATCH_SHIA		0x3800500b
+#define MASK_SHIA		0xf800707f
+#define MATCH_SBIA		0x1800500b
+#define MASK_SBIA		0xf800707f
+#define MATCH_SBIB		0x0800500b
+#define MASK_SBIB		0xf800707f
+#define MATCH_LWUD		0xf000400b
+#define MASK_LWUD		0xf800707f
+#define MATCH_LWD		0xe000400b
+#define MASK_LWD		0xf800707f
+#define MATCH_LDD		0xf800400b
+#define MASK_LDD		0xf800707f
+#define MATCH_LWUIA		0xd800400b
+#define MASK_LWUIA		0xf800707f
+#define MATCH_LWUIB		0xc800400b
+#define MASK_LWUIB		0xf800707f
+#define MATCH_LHUIA		0xb800400b
+#define MASK_LHUIA		0xf800707f
+#define MATCH_LHUIB		0xa800400b
+#define MASK_LHUIB		0xf800707f
+#define MATCH_LBUIA		0x9800400b
+#define MASK_LBUIA		0xf800707f
+#define MATCH_LBUIB		0x8800400b
+#define MASK_LBUIB		0xf800707f
+#define MATCH_LDIA		0x7800400b
+#define MASK_LDIA		0xf800707f
+#define MATCH_LDIB		0x6800400b
+#define MASK_LDIB		0xf800707f
+#define MATCH_LWIA		0x5800400b
+#define MASK_LWIA		0xf800707f
+#define MATCH_LWIB		0x4800400b
+#define MASK_LWIB		0xf800707f
+#define MATCH_LHIA		0x3800400b
+#define MASK_LHIA		0xf800707f
+#define MATCH_LHIB		0x2800400b
+#define MASK_LHIB		0xf800707f
+#define MATCH_LBIA		0x1800400b
+#define MASK_LBIA		0xf800707f
+#define MATCH_LBIB		0x0800400b
+#define MASK_LBIB		0xf800707f
+#define MATCH_REVW		0x9000100b
+#define MASK_REVW		0xfff0707f
+#define MATCH_FSURD		0x7000700b
+#define MASK_FSURD		0xf800707f
+#define MATCH_FSURW		0x5000700b
+#define MASK_FSURW		0xf800707f
+#define MATCH_FSRD		0x6000700b
+#define MASK_FSRD		0xf800707f
+#define MATCH_FSRW		0x4000700b
+#define MASK_FSRW		0xf800707f
+#define MATCH_FLURD		0x7000600b
+#define MASK_FLURD		0xf800707f
+#define MATCH_FLURW		0x5000600b
+#define MASK_FLURW		0xf800707f
+#define MATCH_FLRD		0x6000600b
+#define MASK_FLRD		0xf800707f
+#define MATCH_FLRW		0x4000600b
+#define MASK_FLRW		0xf800707f
+#define MATCH_IPUSH		0x0040000b
+#define MASK_IPUSH		0xffffffff
+#define MATCH_IPOP		0x0050000b
+#define MASK_IPOP		0xffffffff
+/* T-HEAD security.  */
+#define MATCH_WSC		0xcff01073
+#define MASK_WSC 		0xffffffff
+/* T-HEAD Float for rv32.  */
+#define MATCH_FMV_X_HW		0xc000100b
+#define MASK_FMV_X_HW 		0xfff0707f
+#define MATCH_FMV_HW_X		0xa000100b
+#define MASK_FMV_HW_X 		0xfff0707f
+#endif /* __RISCV_OPC_THEAD__ */
+#ifdef DECLARE_INSN
+DECLARE_INSN(th_wsc, MATCH_WSC, MASK_WSC)
+DECLARE_INSN(th_dcache_giall, MATCH_DCACHE_IALL, MASK_DCACHE_IALL)
+DECLARE_INSN(th_dcache_gcall, MATCH_DCACHE_CALL, MASK_DCACHE_CALL)
+DECLARE_INSN(th_dcache_gciall, MATCH_DCACHE_CIALL, MASK_DCACHE_CIALL)
+DECLARE_INSN(th_dcache_gisw, MATCH_DCACHE_ISW, MASK_DCACHE_ISW)
+DECLARE_INSN(th_dcache_gcsw, MATCH_DCACHE_CSW, MASK_DCACHE_CSW)
+DECLARE_INSN(th_dcache_gcisw, MATCH_DCACHE_CISW, MASK_DCACHE_CISW)
+DECLARE_INSN(th_dcache_giva, MATCH_DCACHE_IVA, MASK_DCACHE_IVA)
+DECLARE_INSN(th_dcache_gcva, MATCH_DCACHE_CVA, MASK_DCACHE_CVA)
+DECLARE_INSN(th_dcache_gcval1, MATCH_DCACHE_CVAL1, MASK_DCACHE_CVAL1)
+DECLARE_INSN(th_dcache_gciva, MATCH_DCACHE_CIVA, MASK_DCACHE_CIVA)
+DECLARE_INSN(th_dcache_gipa, MATCH_DCACHE_IPA, MASK_DCACHE_IPA)
+DECLARE_INSN(th_dcache_gcpa, MATCH_DCACHE_CPA, MASK_DCACHE_CPA)
+DECLARE_INSN(th_dcache_gcpal1, MATCH_DCACHE_CPAL1, MASK_DCACHE_CPAL1)
+DECLARE_INSN(th_dcache_gcipa, MATCH_DCACHE_CIPA, MASK_DCACHE_CIPA)
+DECLARE_INSN(th_icache_giall, MATCH_ICACHE_IALL, MASK_ICACHE_IALL)
+DECLARE_INSN(th_icache_gialls, MATCH_ICACHE_IALLS, MASK_ICACHE_IALLS)
+DECLARE_INSN(th_icache_giva, MATCH_ICACHE_IVA, MASK_ICACHE_IVA)
+DECLARE_INSN(th_icache_gipa, MATCH_ICACHE_IPA, MASK_ICACHE_IPA)
+DECLARE_INSN(th_l2cache_giall, MATCH_L2CACHE_IALL, MASK_L2CACHE_IALL)
+DECLARE_INSN(th_l2cache_gcall, MATCH_L2CACHE_CALL, MASK_L2CACHE_CALL)
+DECLARE_INSN(th_l2cache_gciall, MATCH_L2CACHE_CIALL, MASK_L2CACHE_CIALL)
+DECLARE_INSN(th_sync, MATCH_SYNC, MASK_SYNC)
+DECLARE_INSN(th_sync_gi, MATCH_SYNC_I, MASK_SYNC_I)
+DECLARE_INSN(th_sync_gs, MATCH_SYNC_S, MASK_SYNC_S)
+DECLARE_INSN(th_sync_gis, MATCH_SYNC_IS, MASK_SYNC_IS)
+DECLARE_INSN(th_tstnbz, MATCH_TSTNBZ, MASK_TSTNBZ)
+DECLARE_INSN(th_mula, MATCH_MULA, MASK_MULA)
+DECLARE_INSN(th_muls, MATCH_MULS, MASK_MULS)
+DECLARE_INSN(th_mulah, MATCH_MULAH, MASK_MULAH)
+DECLARE_INSN(th_mulsh, MATCH_MULSH, MASK_MULSH)
+DECLARE_INSN(th_sfence_vmas, MATCH_SFENCE_VMAS, MASK_SFENCE_VMAS)
+DECLARE_INSN(th_mveqz, MATCH_MVEQZ, MASK_MVEQZ)
+DECLARE_INSN(th_mvnez, MATCH_MVNEZ, MASK_MVNEZ)
+DECLARE_INSN(th_mulaw, MATCH_MULAW, MASK_MULAW)
+DECLARE_INSN(th_mulsw, MATCH_MULSW, MASK_MULSW)
+DECLARE_INSN(th_ext, MATCH_EXT, MASK_EXT)
+DECLARE_INSN(th_extu, MATCH_EXTU, MASK_EXTU)
+DECLARE_INSN(th_ff1, MATCH_FF1, MASK_FF1)
+DECLARE_INSN(th_ff0, MATCH_FF0, MASK_FF1)
+DECLARE_INSN(th_rev, MATCH_REV, MASK_REV)
+DECLARE_INSN(th_lrb, MATCH_LRB, MASK_LRB)
+DECLARE_INSN(th_lrbu, MATCH_LRBU, MASK_LRBU)
+DECLARE_INSN(th_lrh, MATCH_LRH, MASK_LRH)
+DECLARE_INSN(th_lrhu, MATCH_LRHU, MASK_LRHU)
+DECLARE_INSN(th_lrw, MATCH_LRW, MASK_LRW)
+DECLARE_INSN(th_lrwu, MATCH_LRWU, MASK_LRWU)
+DECLARE_INSN(th_srb, MATCH_SRB, MASK_SRB)
+DECLARE_INSN(th_srh, MATCH_SRH, MASK_SRH)
+DECLARE_INSN(th_srw, MATCH_SRW, MASK_SRW)
+DECLARE_INSN(th_lrd, MATCH_LRD, MASK_LRD)
+DECLARE_INSN(th_srd, MATCH_SRD, MASK_SRD)
+DECLARE_INSN(th_lurb, MATCH_LURB, MASK_LURB)
+DECLARE_INSN(th_lurbu, MATCH_LURBU, MASK_LURBU)
+DECLARE_INSN(th_lurh, MATCH_LURH, MASK_LURH)
+DECLARE_INSN(th_lurhu, MATCH_LURHU, MASK_LURHU)
+DECLARE_INSN(th_lurw, MATCH_LURW, MASK_LURW)
+DECLARE_INSN(th_lurwu, MATCH_LURWU, MASK_LURWU)
+DECLARE_INSN(th_lurd, MATCH_LURD, MASK_LURD)
+DECLARE_INSN(th_surb, MATCH_SURB, MASK_SURB)
+DECLARE_INSN(th_surh, MATCH_SURH, MASK_SURH)
+DECLARE_INSN(th_surw, MATCH_SURW, MASK_SURW)
+DECLARE_INSN(th_surd, MATCH_SURD, MASK_SURD)
+DECLARE_INSN(th_tst, MATCH_TST, MASK_TST)
+DECLARE_INSN(th_srriw, MATCH_SRRIW, MASK_SRRIW)
+DECLARE_INSN(th_srri, MATCH_SRRI, MASK_SRRI)
+DECLARE_INSN(th_addsl, MATCH_ADDSL, MASK_ADDSL)
+DECLARE_INSN(th_lwd, MATCH_LWD, MASK_LWD)
+DECLARE_INSN(th_ldd, MATCH_LDD, MASK_LDD)
+DECLARE_INSN(th_swd, MATCH_SWD, MASK_SWD)
+DECLARE_INSN(th_sdd, MATCH_SDD, MASK_SDD)
+DECLARE_INSN(th_sdia, MATCH_SDIA, MASK_SDIA)
+DECLARE_INSN(th_sdib, MATCH_SDIB, MASK_SDIB)
+DECLARE_INSN(th_lwud, MATCH_LWUD, MASK_LWUD)
+DECLARE_INSN(th_swia, MATCH_SWIA, MASK_SWIA)
+DECLARE_INSN(th_swib, MATCH_SWIB, MASK_SWIB)
+DECLARE_INSN(th_shia, MATCH_SHIA, MASK_SHIA)
+DECLARE_INSN(th_shib, MATCH_SHIB, MASK_SHIB)
+DECLARE_INSN(th_sbia, MATCH_SBIA, MASK_SBIA)
+DECLARE_INSN(th_sbib, MATCH_SBIB, MASK_SBIB)
+DECLARE_INSN(th_lwuia, MATCH_LWUIA, MASK_LWUIA)
+DECLARE_INSN(th_lwuib, MATCH_LWUIB, MASK_LWUIB)
+DECLARE_INSN(th_lhuia, MATCH_LHUIA, MASK_LHUIA)
+DECLARE_INSN(th_lhuib, MATCH_LHUIB, MASK_LHUIB)
+DECLARE_INSN(th_lbuia, MATCH_LBUIA, MASK_LBUIA)
+DECLARE_INSN(th_lbuib, MATCH_LBUIB, MASK_LBUIB)
+DECLARE_INSN(th_ldia, MATCH_LDIA, MASK_LDIA)
+DECLARE_INSN(th_ldib, MATCH_LDIB, MASK_LDIB)
+DECLARE_INSN(th_lwia, MATCH_LWIA, MASK_LWIA)
+DECLARE_INSN(th_lwib, MATCH_LWIB, MASK_LWIB)
+DECLARE_INSN(th_lhia, MATCH_LHIA, MASK_LHIA)
+DECLARE_INSN(th_lhib, MATCH_LHIB, MASK_LHIB)
+DECLARE_INSN(th_lbia, MATCH_LBIA, MASK_LBIA)
+DECLARE_INSN(th_lbib, MATCH_LBIB, MASK_LBIB)
+DECLARE_INSN(th_fsurd, MATCH_FSURD, MASK_FSURD)
+DECLARE_INSN(th_revw, MATCH_REVW, MASK_REVW)
+DECLARE_INSN(th_fsurw, MATCH_FSURW, MASK_FSURW)
+DECLARE_INSN(th_flurd, MATCH_FLURD, MASK_FLURD)
+DECLARE_INSN(th_flurw, MATCH_FLURW, MASK_FLURW)
+DECLARE_INSN(th_fsrd, MATCH_FSRD, MASK_FSRD)
+DECLARE_INSN(th_fsrw, MATCH_FSRW, MASK_FSRW)
+DECLARE_INSN(th_flrd, MATCH_FLRD, MASK_FLRD)
+DECLARE_INSN(th_flrw, MATCH_FLRW, MASK_FLRW)
+DECLARE_INSN(th_ipush, MATCH_IPUSH, MASK_IPUSH)
+DECLARE_INSN(th_ipop, MATCH_IPOP, MASK_IPOP)
+DECLARE_INSN(th_fmv_x_hw, MATCH_FMV_X_HW, MASK_FMV_X_HW)
+DECLARE_INSN(th_fmv_hw_x, MATCH_FMV_HW_X, MASK_FMV_HW_X)
+#endif /* DECLARE_INSN */
+#ifdef DECLARE_CSR
+/* T-HEAD M mode CSR.  */
+#define CSR_THEAD_MXSTATUS 0x7c0
+#define CSR_THEAD_MHCR 0x7c1
+#define CSR_THEAD_MCOR 0x7c2
+#define CSR_THEAD_MCCR2 0x7c3
+#define CSR_THEAD_MCER2 0x7c4
+#define CSR_THEAD_MHINT 0x7c5
+#define CSR_THEAD_MRMR 0x7c6
+#define CSR_THEAD_MRVBR 0x7c7
+#define CSR_THEAD_MCER 0x7c8
+#define CSR_THEAD_MCOUNTERWEN 0x7c9
+#define CSR_THEAD_MCOUNTERINTEN 0x7ca
+#define CSR_THEAD_MCOUNTEROF 0x7cb
+#define CSR_THEAD_MHINT2 0x7cc
+#define CSR_THEAD_MHINT3 0x7cd
+#define CSR_THEAD_MRADDR 0x7e0
+#define CSR_THEAD_MEXSTATUS 0x7e1
+#define CSR_THEAD_MNMICAUSE 0x7e2
+#define CSR_THEAD_MNMIPC 0x7e3
+#define CSR_THEAD_MHPMCR 0x7f0
+#define CSR_THEAD_MHPMSR 0x7f1
+#define CSR_THEAD_MHPMER 0x7f2
+#define CSR_THEAD_MSMPR 0x7f3
+#define CSR_THEAD_MTEECFG 0x7f4
+#define CSR_THEAD_MZONEID 0x7f5
+#define CSR_THEAD_ML2CPID 0x7f6
+#define CSR_THEAD_ML2WP 0x7f7
+#define CSR_THEAD_MDTCMCR 0x7f8
+#define CSR_THEAD_USP 0x7d1
+#define CSR_THEAD_MCINS 0x7d2
+#define CSR_THEAD_MCINDEX 0x7d3
+#define CSR_THEAD_MCDATA0 0x7d4
+#define CSR_THEAD_MCDATA1 0x7d5
+#define CSR_THEAD_MEICR 0x7d6
+#define CSR_THEAD_MEICR2 0x7d7
+#define CSR_THEAD_MBEADDR 0x7d8
+#define CSR_THEAD_MCPUID 0xfc0
+#define CSR_THEAD_MAPBADDR 0xfc1
+#define CSR_THEAD_MWMSR 0xfc2
+#define CSR_THEAD_MHALTCAUSE 0xfe0
+#define CSR_THEAD_MDBGINFO 0xfe1
+#define CSR_THEAD_MPCFIFO 0xfe2
+/* T-HEAD S mode CSR.  */
+#define CSR_THEAD_SXSTATUS 0x5c0
+#define CSR_THEAD_SHCR 0x5c1
+#define CSR_THEAD_SCER2 0x5c2
+#define CSR_THEAD_SCER 0x5c3
+#define CSR_THEAD_SCOUNTERINTEN 0x5c4
+#define CSR_THEAD_SCOUNTEROF 0x5c5
+#define CSR_THEAD_SHINT 0x5c6
+#define CSR_THEAD_SHINT2 0x5c7
+#define CSR_THEAD_SHPMINHIBIT 0x5c8
+#define CSR_THEAD_SHPMCR 0x5c9
+#define CSR_THEAD_SHPMSR 0x5ca
+#define CSR_THEAD_SHPMER 0x5cb
+#define CSR_THEAD_SL2CPID 0x5cc
+#define CSR_THEAD_SL2WP 0x5cd
+#define CSR_THEAD_SBEADDR 0x5d0
+#define CSR_THEAD_SCYCLE 0x5e0
+#define CSR_THEAD_SHPMCOUNTER1 0x5e1
+#define CSR_THEAD_SHPMCOUNTER2 0x5e2
+#define CSR_THEAD_SHPMCOUNTER3 0x5e3
+#define CSR_THEAD_SHPMCOUNTER4 0x5e4
+#define CSR_THEAD_SHPMCOUNTER5 0x5e5
+#define CSR_THEAD_SHPMCOUNTER6 0x5e6
+#define CSR_THEAD_SHPMCOUNTER7 0x5e7
+#define CSR_THEAD_SHPMCOUNTER8 0x5e8
+#define CSR_THEAD_SHPMCOUNTER9 0x5e9
+#define CSR_THEAD_SHPMCOUNTER10 0x5ea
+#define CSR_THEAD_SHPMCOUNTER11 0x5eb
+#define CSR_THEAD_SHPMCOUNTER12 0x5ec
+#define CSR_THEAD_SHPMCOUNTER13 0x5ed
+#define CSR_THEAD_SHPMCOUNTER14 0x5ee
+#define CSR_THEAD_SHPMCOUNTER15 0x5ef
+#define CSR_THEAD_SHPMCOUNTER16 0x5f0
+#define CSR_THEAD_SHPMCOUNTER17 0x5f1
+#define CSR_THEAD_SHPMCOUNTER18 0x5f2
+#define CSR_THEAD_SHPMCOUNTER19 0x5f3
+#define CSR_THEAD_SHPMCOUNTER20 0x5f4
+#define CSR_THEAD_SHPMCOUNTER21 0x5f5
+#define CSR_THEAD_SHPMCOUNTER22 0x5f6
+#define CSR_THEAD_SHPMCOUNTER23 0x5f7
+#define CSR_THEAD_SHPMCOUNTER24 0x5f8
+#define CSR_THEAD_SHPMCOUNTER25 0x5f9
+#define CSR_THEAD_SHPMCOUNTER26 0x5fa
+#define CSR_THEAD_SHPMCOUNTER27 0x5fb
+#define CSR_THEAD_SHPMCOUNTER28 0x5fc
+#define CSR_THEAD_SHPMCOUNTER29 0x5fd
+#define CSR_THEAD_SHPMCOUNTER30 0x5fe
+#define CSR_THEAD_SHPMCOUNTER31 0x5ff
+/* T-HEAD U mode CSR.  */
+#define CSR_THEAD_FXCR 0x800
+/* T-HEAD MMU extentions.  */
+#define CSR_THEAD_SMIR 0x9c0
+#define CSR_THEAD_SMEL 0x9c1
+#define CSR_THEAD_SMEH 0x9c2
+#define CSR_THEAD_SMCIR 0x9c3
+/* T-HEAD Security CSR(May be dropped).  */
+#define CSR_THEAD_MEBR 0xbe0
+#define CSR_THEAD_NT_MSTATUS 0xbe1
+#define CSR_THEAD_NT_MIE 0xbe2
+#define CSR_THEAD_NT_MTVEC 0xbe3
+#define CSR_THEAD_NT_MTVT 0xbe4
+#define CSR_THEAD_NT_MEPC 0xbe5
+#define CSR_THEAD_NT_MCAUSE 0xbe6
+#define CSR_THEAD_NT_MIP 0xbe7
+#define CSR_THEAD_NT_MINTSTATE 0xbe8
+#define CSR_THEAD_NT_MXSTATUS 0xbe9
+#define CSR_THEAD_NT_MEBR 0xbea
+#define CSR_THEAD_NT_MSP 0xbeb
+#define CSR_THEAD_T_USP 0xbec
+#define CSR_THEAD_T_MDCR 0xbed
+#define CSR_THEAD_T_MPCR 0xbee
+#define CSR_THEAD_PMPTEECFG 0xbef
+/* T-HEAD extentions.  */
+DECLARE_CSR(th_mxstatus, CSR_THEAD_MXSTATUS, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mhcr, CSR_THEAD_MHCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mcor, CSR_THEAD_MCOR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mccr2, CSR_THEAD_MCCR2, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mcer2, CSR_THEAD_MCER2, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mhint, CSR_THEAD_MHINT, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mrmr, CSR_THEAD_MRMR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mrvbr, CSR_THEAD_MRVBR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mcer, CSR_THEAD_MCER, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mcounterwen, CSR_THEAD_MCOUNTERWEN, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mcounterinten, CSR_THEAD_MCOUNTERINTEN, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mcounterof, CSR_THEAD_MCOUNTEROF, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mhint2, CSR_THEAD_MHINT2, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mhint3, CSR_THEAD_MHINT3, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mraddr, CSR_THEAD_MRADDR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mexstatus, CSR_THEAD_MEXSTATUS, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mnmicause, CSR_THEAD_MNMICAUSE, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mnmipc, CSR_THEAD_MNMIPC, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mhpmcr, CSR_THEAD_MHPMCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mhpmsr, CSR_THEAD_MHPMSR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mhpmer, CSR_THEAD_MHPMER, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_msmpr, CSR_THEAD_MSMPR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mteecfg, CSR_THEAD_MTEECFG, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mzoneid, CSR_THEAD_MZONEID, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_ml2cpid, CSR_THEAD_ML2CPID, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_ml2wp, CSR_THEAD_ML2WP, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mdtcmcr, CSR_THEAD_MDTCMCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_usp, CSR_THEAD_USP, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mcins, CSR_THEAD_MCINS, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mcindex, CSR_THEAD_MCINDEX, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mcdata0, CSR_THEAD_MCDATA0, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mcdata1, CSR_THEAD_MCDATA1, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_meicr, CSR_THEAD_MEICR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_meicr2, CSR_THEAD_MEICR2, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mbeaddr, CSR_THEAD_MBEADDR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mebr, CSR_THEAD_MEBR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_nt_mstatus, CSR_THEAD_NT_MSTATUS, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_nt_mtvec, CSR_THEAD_NT_MTVEC, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_nt_mie, CSR_THEAD_NT_MIE, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_nt_mtvt, CSR_THEAD_NT_MTVT, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_nt_mepc, CSR_THEAD_NT_MEPC, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_nt_mcause, CSR_THEAD_NT_MCAUSE, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_nt_mip, CSR_THEAD_NT_MIP, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_nt_mintstate, CSR_THEAD_NT_MINTSTATE, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_nt_mxstatus, CSR_THEAD_NT_MXSTATUS, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_nt_mebr, CSR_THEAD_NT_MEBR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_nt_msp, CSR_THEAD_NT_MSP, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_t_usp, CSR_THEAD_T_USP, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_t_mdcr, CSR_THEAD_T_MDCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_t_mpcr, CSR_THEAD_T_MPCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_pmpteecfg, CSR_THEAD_PMPTEECFG, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mcpuid, CSR_THEAD_MCPUID, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mapbaddr, CSR_THEAD_MAPBADDR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_mwmsr, CSR_THEAD_MWMSR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_fxcr, CSR_THEAD_FXCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_smir, CSR_THEAD_SMIR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_smel, CSR_THEAD_SMEL, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_smeh, CSR_THEAD_SMEH, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_smcir, CSR_THEAD_SMCIR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_sxstatus, CSR_THEAD_SXSTATUS, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shcr, CSR_THEAD_SHCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_scer2, CSR_THEAD_SCER2, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_scer, CSR_THEAD_SCER, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_scounterinten , CSR_THEAD_SCOUNTERINTEN, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_scounterof, CSR_THEAD_SCOUNTEROF, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shint, CSR_THEAD_SHINT, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shint2, CSR_THEAD_SHINT2, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpminhibit, CSR_THEAD_SHPMINHIBIT, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcr, CSR_THEAD_SHPMCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmsr, CSR_THEAD_SHPMSR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmer, CSR_THEAD_SHPMER, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_sl2cpid, CSR_THEAD_SL2CPID, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_sl2wp, CSR_THEAD_SL2WP, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_sbeaddr, CSR_THEAD_SBEADDR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_scycle, CSR_THEAD_SCYCLE, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcounter1, CSR_THEAD_SHPMCOUNTER1, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcounter2, CSR_THEAD_SHPMCOUNTER2, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcounter3, CSR_THEAD_SHPMCOUNTER3, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcounter4, CSR_THEAD_SHPMCOUNTER4, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcounter5, CSR_THEAD_SHPMCOUNTER5, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcounter6, CSR_THEAD_SHPMCOUNTER6, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcounter7, CSR_THEAD_SHPMCOUNTER7, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcounter8, CSR_THEAD_SHPMCOUNTER8, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcounter9, CSR_THEAD_SHPMCOUNTER9, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcounter10, CSR_THEAD_SHPMCOUNTER10, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcounter11, CSR_THEAD_SHPMCOUNTER11, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcounter12, CSR_THEAD_SHPMCOUNTER12, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcounter13, CSR_THEAD_SHPMCOUNTER13, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcounter14, CSR_THEAD_SHPMCOUNTER14, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcounter15, CSR_THEAD_SHPMCOUNTER15, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcounter16, CSR_THEAD_SHPMCOUNTER16, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcounter17, CSR_THEAD_SHPMCOUNTER17, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcounter18, CSR_THEAD_SHPMCOUNTER18, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcounter19, CSR_THEAD_SHPMCOUNTER19, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcounter20, CSR_THEAD_SHPMCOUNTER20, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcounter21, CSR_THEAD_SHPMCOUNTER21, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcounter22, CSR_THEAD_SHPMCOUNTER22, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcounter23, CSR_THEAD_SHPMCOUNTER23, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcounter24, CSR_THEAD_SHPMCOUNTER24, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcounter25, CSR_THEAD_SHPMCOUNTER25, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcounter26, CSR_THEAD_SHPMCOUNTER26, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcounter27, CSR_THEAD_SHPMCOUNTER27, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcounter28, CSR_THEAD_SHPMCOUNTER28, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcounter29, CSR_THEAD_SHPMCOUNTER29, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcounter30, CSR_THEAD_SHPMCOUNTER30, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(th_shpmcounter31, CSR_THEAD_SHPMCOUNTER31, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+#endif /* DECLARE_CSR */
diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
index 88b8d7ff595..f755d0e0643 100644
--- a/include/opcode/riscv-opc.h
+++ b/include/opcode/riscv-opc.h
@@ -3276,3 +3276,5 @@ DECLARE_CSR_ALIAS(tmexttrigger, CSR_TDATA1, CSR_CLASS_DEBUG, PRIV_SPEC_CLASS_NON
 DECLARE_CSR_ALIAS(textra32, CSR_TDATA3, CSR_CLASS_DEBUG, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
 DECLARE_CSR_ALIAS(textra64, CSR_TDATA3, CSR_CLASS_DEBUG, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
 #endif /* DECLARE_CSR_ALIAS */
+
+#include "riscv-opc-thead.h"
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index b115e338a05..eff93641bae 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -397,6 +397,11 @@ enum riscv_insn_class
   INSN_CLASS_ZICBOP,
   INSN_CLASS_ZICBOZ,
   INSN_CLASS_H,
+  INSN_CLASS_THEAD_C,
+  INSN_CLASS_THEAD_E,
+  INSN_CLASS_THEAD_SE,
+  INSN_CLASS_THEAD_C_OR_E,
+  INSN_CLASS_THEAD_C_OR_E_OR_SE,
 };
 
 /* This structure holds information for a particular instruction.  */
@@ -531,4 +536,20 @@ extern const char * const riscv_vma[2];
 extern const struct riscv_opcode riscv_opcodes[];
 extern const struct riscv_opcode riscv_insn_types[];
 
+/* T-HEAD IMM Encoding.  */
+#define EXTRACT_VENDOR_THEAD_IMM(x,nbit,at) \
+  (RV_X(x, at, nbit))
+#define EXTRACT_VENDOR_THEAD_SIGN_IMM(x,nbit,at) \
+  (RV_X(x, at, nbit) | ((-(RV_X(x, (at+nbit-1),1))) << (nbit)))
+
+#define ENCODE_VENDOR_THEAD_IMM(x,nbit,at) \
+  (RV_X(x, 0, nbit) << at)
+#define ENCODE_VENDOR_THEAD_SIGN_IMM(x,nbit,at) \
+  (RV_X(x, 0, nbit) << at)
+
+#define VALID_VENDOR_THEAD_IMM(x,nbit,at) \
+  (EXTRACT_VENDOR_THEAD_IMM(ENCODE_VENDOR_THEAD_IMM(x,nbit,at),nbit,at) == (x))
+#define VALID_VENDOR_THEAD_SIGN_IMM(x,nbit,at) \
+  (EXTRACT_VENDOR_THEAD_SIGN_IMM(ENCODE_VENDOR_THEAD_SIGN_IMM(x,nbit,at),nbit,at) == (x))
+
 #endif /* _RISCV_H_ */
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index 164fd209dbd..43646cc0731 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -554,6 +554,30 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 	  print (info->stream, dis_style_text, "%d", rs1);
 	  break;
 
+	case 'X':
+	  {
+	    int nbit, at, n;
+	    if (sscanf(oparg, "XI%d@%d%n", &nbit, &at, &n) == 2)
+	      {
+		int value = EXTRACT_BITS (l, (1 << nbit) - 1, at);
+		print (info->stream, dis_style_immediate, "%d", value);
+		oparg += n - 1;
+	      }
+	    else if (sscanf(oparg, "XS%d@%d%n", &nbit, &at, &n) == 2)
+	      {
+		int value = EXTRACT_BITS (l, (1 << nbit) - 1, at);
+		print (info->stream, dis_style_immediate, "%d", value);
+		oparg += n - 1;
+	      }
+	    else
+	      {
+		print (info->stream, dis_style_text,
+		       _("# internal error, unknown X modifier %s"),
+		       oparg);
+	      }
+	  }
+	  break;
+
 	default:
 	  /* xgettext:c-format */
 	  print (info->stream, dis_style_text,
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 2f9945aa930..0e9a2f597c2 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -266,6 +266,17 @@ match_vd_eq_vs1_eq_vs2 (const struct riscv_opcode *op,
   return match_opcode (op, insn) && vd == vs1 && vs1 == vs2;
 }
 
+static int
+match_thead_rd1_rd2_neq_rs1(const struct riscv_opcode *op,
+			    insn_t insn)
+{
+  int rd1 = (insn & MASK_RD) >> OP_SH_RD;
+  int rd2 = (insn & MASK_RS2) >> OP_SH_RS2;
+  int rs1 = (insn & MASK_RS1) >> OP_SH_RS1;
+
+  return match_opcode (op, insn) && rd1 != rs1 && rd2 != rs1;
+}
+
 const struct riscv_opcode riscv_opcodes[] =
 {
 /* name, xlen, isa, operands, match, mask, match_func, pinfo.  */
@@ -1825,6 +1836,119 @@ const struct riscv_opcode riscv_opcodes[] =
 {"hsv.w",       0, INSN_CLASS_H, "t,0(s)", MATCH_HSV_W, MASK_HSV_W, match_opcode, INSN_DREF|INSN_4_BYTE },
 {"hsv.d",      64, INSN_CLASS_H, "t,0(s)", MATCH_HSV_D, MASK_HSV_D, match_opcode, INSN_DREF|INSN_8_BYTE },
 
+/* The vendor extension opcodes for T-HEAD.  */
+{"th.wsc",             0, INSN_CLASS_THEAD_C_OR_E,   "",  MATCH_WSC, MASK_WSC, match_opcode, 0},
+{"th.dcache.iall",     0, INSN_CLASS_THEAD_C_OR_E,   "",  MATCH_DCACHE_IALL, MASK_DCACHE_IALL, match_opcode, 0},
+{"th.dcache.call",     0, INSN_CLASS_THEAD_C_OR_E,   "",  MATCH_DCACHE_CALL, MASK_DCACHE_CALL, match_opcode, 0},
+{"th.dcache.ciall",    0, INSN_CLASS_THEAD_C_OR_E,   "",  MATCH_DCACHE_CIALL, MASK_DCACHE_CIALL, match_opcode, 0},
+{"th.dcache.isw",      0, INSN_CLASS_THEAD_C_OR_E,   "s",     MATCH_DCACHE_ISW, MASK_DCACHE_ISW, match_opcode, 0},
+{"th.dcache.csw",      0, INSN_CLASS_THEAD_C_OR_E,   "s",     MATCH_DCACHE_CSW, MASK_DCACHE_CSW, match_opcode, 0},
+{"th.dcache.cisw",     0, INSN_CLASS_THEAD_C_OR_E,   "s",     MATCH_DCACHE_CISW, MASK_DCACHE_CISW, match_opcode, 0},
+{"th.dcache.iva",      0, INSN_CLASS_THEAD_C,   "s",     MATCH_DCACHE_IVA, MASK_DCACHE_IVA, match_opcode, 0},
+{"th.dcache.cva",      0, INSN_CLASS_THEAD_C,   "s",     MATCH_DCACHE_CVA, MASK_DCACHE_CVA, match_opcode, 0},
+{"th.dcache.cval1",    0, INSN_CLASS_THEAD_C,   "s",     MATCH_DCACHE_CVAL1, MASK_DCACHE_CVAL1, match_opcode, 0},
+{"th.dcache.civa",     0, INSN_CLASS_THEAD_C,   "s",     MATCH_DCACHE_CIVA, MASK_DCACHE_CIVA, match_opcode, 0},
+{"th.dcache.ipa",      0, INSN_CLASS_THEAD_C_OR_E,   "s",     MATCH_DCACHE_IPA, MASK_DCACHE_IPA, match_opcode, 0},
+{"th.dcache.cpa",      0, INSN_CLASS_THEAD_C_OR_E,   "s",     MATCH_DCACHE_CPA, MASK_DCACHE_CPA, match_opcode, 0},
+{"th.dcache.cpal1",    0, INSN_CLASS_THEAD_C,   "s",     MATCH_DCACHE_CPAL1, MASK_DCACHE_CPAL1, match_opcode, 0},
+{"th.dcache.cipa",     0, INSN_CLASS_THEAD_C_OR_E,   "s",     MATCH_DCACHE_CIPA, MASK_DCACHE_CIPA, match_opcode, 0},
+{"th.icache.iall",     0, INSN_CLASS_THEAD_C_OR_E_OR_SE,   "",      MATCH_ICACHE_IALL, MASK_ICACHE_IALL, match_opcode, 0},
+{"th.icache.iall",     0, INSN_CLASS_THEAD_SE,   "",      MATCH_ICACHE_IALL, MASK_ICACHE_IALL, match_opcode, INSN_ALIAS},
+{"th.icache.ialls",    0, INSN_CLASS_THEAD_C,   "",      MATCH_ICACHE_IALLS, MASK_ICACHE_IALLS, match_opcode, 0},
+{"th.icache.iva",      0, INSN_CLASS_THEAD_C,   "s",     MATCH_ICACHE_IVA, MASK_ICACHE_IVA, match_opcode, 0},
+{"th.icache.ipa",      0, INSN_CLASS_THEAD_C_OR_E,   "s",     MATCH_ICACHE_IPA, MASK_ICACHE_IPA, match_opcode, 0},
+{"th.l2cache.iall",    0, INSN_CLASS_THEAD_C,   "",      MATCH_L2CACHE_IALL, MASK_L2CACHE_IALL, match_opcode, 0},
+{"th.l2cache.call",    0, INSN_CLASS_THEAD_C,   "",      MATCH_L2CACHE_CALL, MASK_L2CACHE_CALL, match_opcode, 0},
+{"th.l2cache.ciall",   0, INSN_CLASS_THEAD_C_OR_E,   "",      MATCH_L2CACHE_CIALL, MASK_L2CACHE_CIALL, match_opcode, 0},
+{"th.sync",            0, INSN_CLASS_THEAD_C_OR_E,   "",      MATCH_SYNC, MASK_SYNC, match_opcode, 0},
+{"th.sync.i",          0, INSN_CLASS_THEAD_C_OR_E,   "",      MATCH_SYNC_I, MASK_SYNC_I, match_opcode, 0},
+{"th.sync.s",          0, INSN_CLASS_THEAD_C,   "",      MATCH_SYNC_S, MASK_SYNC_S, match_opcode, 0},
+{"th.sync.is",         0, INSN_CLASS_THEAD_C,   "",      MATCH_SYNC_IS, MASK_SYNC_IS, match_opcode, 0},
+{"th.tstnbz",          0, INSN_CLASS_THEAD_C_OR_E,   "d,s",     MATCH_TSTNBZ, MASK_TSTNBZ, match_opcode, 0},
+{"th.mula",            0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MULA, MASK_MULA, match_opcode, 0},
+{"th.muls",            0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MULS, MASK_MULS, match_opcode, 0},
+{"th.mulah",           0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MULAH, MASK_MULAH, match_opcode, 0},
+{"th.mulsh",           0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MULSH, MASK_MULSH, match_opcode, 0},
+{"th.sfence.vmas",     0, INSN_CLASS_THEAD_C,   "s,t",      MATCH_SFENCE_VMAS, MASK_SFENCE_VMAS, match_opcode, 0},
+{"th.mveqz",           0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MVEQZ, MASK_MVEQZ, match_opcode, 0},
+{"th.mvnez",           0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MVNEZ, MASK_MVNEZ, match_opcode, 0},
+{"th.mulaw",           0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MULAW, MASK_MULAW, match_opcode, 0},
+{"th.mulsw",           0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MULSW, MASK_MULSW, match_opcode, 0},
+{"th.ext",             64, INSN_CLASS_THEAD_C,  "d,s,XI6@26,XI6@20",   MATCH_EXT, MASK_EXT, match_opcode, 0 },
+{"th.ext",             32, INSN_CLASS_THEAD_E,  "d,s,XI5@26,XI5@20",   MATCH_EXT, (MASK_EXT | (1U<<25) | (1U<<31)), match_opcode, 0 },
+{"th.extu",            64, INSN_CLASS_THEAD_C,  "d,s,XI6@26,XI6@20",   MATCH_EXTU, MASK_EXTU, match_opcode, 0 },
+{"th.extu",            32, INSN_CLASS_THEAD_E,  "d,s,XI5@26,XI5@20",   MATCH_EXTU, (MASK_EXTU | (1U<<25) | (1U<<31)), match_opcode, 0 },
+{"th.ff1",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s",   MATCH_FF1, MASK_FF1, match_opcode, 0},
+{"th.ff0",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s",   MATCH_FF0, MASK_FF1, match_opcode, 0},
+{"th.rev",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s",   MATCH_REV, MASK_REV, match_opcode, 0},
+{"th.lrb",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_LRB, MASK_LRB, match_opcode, 0 },
+{"th.lrbu",            0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_LRBU, MASK_LRBU, match_opcode, 0 },
+{"th.lrh",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_LRH, MASK_LRH, match_opcode, 0 },
+{"th.lrhu",            0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_LRHU, MASK_LRHU, match_opcode, 0 },
+{"th.lrw",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_LRW, MASK_LRW, match_opcode, 0 },
+{"th.lrwu",            0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_LRWU, MASK_LRWU, match_opcode, 0 },
+{"th.srb",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_SRB, MASK_SRB, match_opcode, 0 },
+{"th.srh",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_SRH, MASK_SRH, match_opcode, 0 },
+{"th.srw",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_SRW, MASK_SRW, match_opcode, 0 },
+{"th.lrd",             0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LRD, MASK_LRD, match_opcode, 0 },
+{"th.srd",             0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_SRD, MASK_SRD, match_opcode, 0 },
+{"th.lurb",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LURB, MASK_LURB, match_opcode, 0 },
+{"th.lurbu",           0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LURBU, MASK_LURBU, match_opcode, 0 },
+{"th.lurh",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LURH, MASK_LURH, match_opcode, 0 },
+{"th.lurhu",           0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LURHU, MASK_LURHU, match_opcode, 0 },
+{"th.lurw",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LURW, MASK_LURW, match_opcode, 0 },
+{"th.lurwu",           0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LURWU, MASK_LURWU, match_opcode, 0 },
+{"th.lurd",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LURD, MASK_LURD, match_opcode, 0 },
+{"th.surb",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_SURB, MASK_SURB, match_opcode, 0 },
+{"th.surh",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_SURH, MASK_SURH, match_opcode, 0 },
+{"th.surw",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_SURW, MASK_SURW, match_opcode, 0 },
+{"th.surd",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_SURD, MASK_SURD, match_opcode, 0 },
+{"th.tst",             64, INSN_CLASS_THEAD_C,  "d,s,XI6@20",   MATCH_TST, MASK_TST, match_opcode, 0 },
+{"th.tst",             32, INSN_CLASS_THEAD_E,   "d,s,XI5@20",   MATCH_TST, (MASK_TST | (1U << 25)), match_opcode, INSN_ALIAS},
+{"th.srriw",           0, INSN_CLASS_THEAD_C,   "d,s,XI5@20",   MATCH_SRRIW, MASK_SRRIW, match_opcode, 0 },
+{"th.srri",            0, INSN_CLASS_THEAD_C_OR_E,   "d,s,XI6@20",   MATCH_SRRI, MASK_SRRI, match_opcode, 0 },
+{"th.addsl",           0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25", MATCH_ADDSL, MASK_ADDSL, match_opcode, 0 },
+{"th.lwd",             0, INSN_CLASS_THEAD_C,   "d,t,(s),XI2@25", MATCH_LWD, MASK_LWD, match_thead_rd1_rd2_neq_rs1, 0 },
+{"th.ldd",             0, INSN_CLASS_THEAD_C,   "d,t,(s),XI2@25", MATCH_LDD, MASK_LDD, match_thead_rd1_rd2_neq_rs1, 0 },
+{"th.swd",             0, INSN_CLASS_THEAD_C,   "d,t,(s),XI2@25", MATCH_SWD, MASK_SWD, match_opcode, 0 },
+{"th.sdd",             0, INSN_CLASS_THEAD_C,   "d,t,(s),XI2@25", MATCH_SDD, MASK_SDD, match_opcode, 0 },
+{"th.sdia",            0, INSN_CLASS_THEAD_C,   "d,(s),XS5@20,XI2@25", MATCH_SDIA, MASK_SDIA, match_opcode, 0 },
+{"th.sdib",            0, INSN_CLASS_THEAD_C,   "d,(s),XS5@20,XI2@25", MATCH_SDIB, MASK_SDIB, match_opcode, 0 },
+{"th.lwud",            0, INSN_CLASS_THEAD_C,   "d,t,(s),XI2@25", MATCH_LWUD, MASK_LWUD, match_thead_rd1_rd2_neq_rs1, 0 },
+{"th.swia",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_SWIA, MASK_SWIA, match_opcode, 0},
+{"th.swib",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_SWIB, MASK_SWIB, match_opcode, 0},
+{"th.shia",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_SHIA, MASK_SHIA, match_opcode, 0},
+{"th.shib",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_SHIB, MASK_SHIB, match_opcode, 0},
+{"th.sbia",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_SBIA, MASK_SBIA, match_opcode, 0},
+{"th.sbib",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_SBIB, MASK_SBIB, match_opcode, 0},
+{"th.lwuia",           0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LWUIA, MASK_LWUIA, match_opcode, 0},
+{"th.lwuib",           0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LWUIB, MASK_LWUIB, match_opcode, 0},
+{"th.lhuia",           0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LHUIA, MASK_LHUIA, match_opcode, 0},
+{"th.lhuib",           0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LHUIB, MASK_LHUIB, match_opcode, 0},
+{"th.lbuia",           0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LBUIA, MASK_LBUIA, match_opcode, 0},
+{"th.lbuib",           0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LBUIB, MASK_LBUIB, match_opcode, 0},
+{"th.ldia",            0, INSN_CLASS_THEAD_C,   "d,(s),XS5@20,XI2@25", MATCH_LDIA, MASK_LDIA, match_opcode, 0},
+{"th.ldib",            0, INSN_CLASS_THEAD_C,   "d,(s),XS5@20,XI2@25", MATCH_LDIB, MASK_LDIB, match_opcode, 0},
+{"th.lwia",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LWIA, MASK_LWIA, match_opcode, 0},
+{"th.lwib",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LWIB, MASK_LWIB, match_opcode, 0},
+{"th.lhia",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LHIA, MASK_LHIA, match_opcode, 0},
+{"th.lhib",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LHIB, MASK_LHIB, match_opcode, 0},
+{"th.lbia",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LBIA, MASK_LBIA, match_opcode, 0},
+{"th.lbib",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LBIB, MASK_LBIB, match_opcode, 0},
+{"th.fsurd",           0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FSURD, MASK_FSURD, match_opcode, 0},
+{"th.revw",            0, INSN_CLASS_THEAD_C,   "d,s", MATCH_REVW, MASK_REVW, match_opcode, 0},
+{"th.fsurw",           0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FSURW, MASK_FSURW, match_opcode, 0},
+{"th.flurd",           0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FLURD, MASK_FLURD, match_opcode, 0},
+{"th.flurw",           0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FLURW, MASK_FLURW, match_opcode, 0},
+{"th.fsrd",            0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FSRD, MASK_FSRD, match_opcode, 0},
+{"th.fsrw",            0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FSRW, MASK_FSRW, match_opcode, 0},
+{"th.flrd",            0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FLRD, MASK_FLRD, match_opcode, 0},
+{"th.flrw",            0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FLRW, MASK_FLRW, match_opcode, 0},
+{"th.ipush",           0, INSN_CLASS_THEAD_E,   "",  MATCH_IPUSH, MASK_IPUSH, match_opcode, 0},
+{"th.ipop",            0, INSN_CLASS_THEAD_E,   "",  MATCH_IPOP, MASK_IPOP, match_opcode, 0},
+{"th.fmv.x.hw",        32, INSN_CLASS_THEAD_E,  "d,S",  MATCH_FMV_X_HW, MASK_FMV_X_HW, match_opcode, 0},
+{"th.fmv.hw.x",        32, INSN_CLASS_THEAD_E,  "D,s",  MATCH_FMV_HW_X, MASK_FMV_HW_X, match_opcode, 0},
+
 /* Terminate the list.  */
 {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}
 };
-- 
2.34.1


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

* Re: [PATCH] RISC-V/t-head: Add CSRs and opcodes of the T-HEAD XUANTIE CPUs
  2022-07-28 22:04 [PATCH] RISC-V/t-head: Add CSRs and opcodes of the T-HEAD XUANTIE CPUs Palmer Dabbelt
@ 2022-07-29  0:28 ` Kito Cheng
  2022-07-29  8:43   ` Jojo R
  2022-07-29  9:19   ` Lifang Xia
  0 siblings, 2 replies; 4+ messages in thread
From: Kito Cheng @ 2022-07-29  0:28 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: Binutils, Christoph Muellner, Jojo R, Lifang Xia

Hi Palmer

They are trying to reorg the structure of their extensions as I know,
so the extension name might be obsolete now?

https://github.com/riscv-non-isa/riscv-toolchain-conventions/pull/19

Hi Jojo, Li-Fan:

Could you confirm that?

Thanks

On Fri, Jul 29, 2022 at 6:08 AM Palmer Dabbelt <palmer@rivosinc.com> wrote:
>
> From: Lifang Xia <lifang_xia@c-sky.com>
>
> Add CSRs and opcodes of the XUANTIE CPUs, extensions named "theadc",
> "xtheade" and "xtheadse".
>
> bfd/ChangeLog
>
>         * cpu-riscv.h (riscv_spec_class) <VENDOR_SPEC_CLASS_THEAD>: New
>         value.
>         * elfxx-riscv.c (riscv_supported_custom_ext): New table.
>         (riscv_all_supported_ext): Add riscv_supported_custom_ext.
>         (riscv_recognized_prefixed_ext): Update comment.
>         (riscv_get_default_ext_version): Add the t-head extensions.
>         (riscv_multi_subset_supports): Likewise.
>         (riscv_multi_subset_supports_ext): Likewise.
>
> gas/ChangeLog
>
>         * config/tc-riscv.c (riscv_csr_class) <CSR_CLASS_THEAD>: New
>         value.
>         (riscv_csr_address): Add CSR_CLASS_THEAD.
>         (validate_riscv_insn): Add the XI and XS formats.
>         (riscv_ip): Likewise.
>
> gas/testsuite/ChangeLog
>
>         * gas/riscv/thead-csr-list.d: New test.
>         * gas/riscv/theadc-ext.d: Likewise.
>         * gas/riscv/theadc-ext.s: Likewise.
>         * gas/riscv/theade-ext.d: Likewise.
>         * gas/riscv/theade-ext.s: Likewise.
>
> include/ChangeLog
>
>         * opcode/iscv-opc-thead.h: New file.
>
> opcodes/ChangeLog
>
>         * riscv-dis.c (print_insn_args): Support XI and XS formats.
>         * riscv-opc.c (match_thead_rd1_rd2_neq_rs1): New function.
>         (riscv_opcodes): Add the t-thead extensions.
> ---
> I cherry-picked this off Nelson's integration branch at sourceware, and
> then went through it a bit to avoid the dependencies on the experimental
> extension handling (and also just some cleanups).  This should be
> functionally the same as what was originally posted, aside from having
> the "th." prefix on instructions and the "th_" prefix on CSRs.
>
> This passes the tests, but I don't currently have any other way to
> verify it.
> ---
>  bfd/cpu-riscv.h                          |   3 +
>  bfd/elfxx-riscv.c                        |  43 +-
>  gas/config/tc-riscv.c                    |  85 ++++
>  gas/testsuite/gas/riscv/thead-csr-list.d | 107 +++++
>  gas/testsuite/gas/riscv/thead-csr-list.s |  98 ++++
>  gas/testsuite/gas/riscv/theadc-ext.d     | 112 +++++
>  gas/testsuite/gas/riscv/theadc-ext.s     | 115 +++++
>  gas/testsuite/gas/riscv/theade-ext.d     |  62 +++
>  gas/testsuite/gas/riscv/theade-ext.s     |  66 +++
>  include/opcode/riscv-opc-thead.h         | 571 +++++++++++++++++++++++
>  include/opcode/riscv-opc.h               |   2 +
>  include/opcode/riscv.h                   |  21 +
>  opcodes/riscv-dis.c                      |  24 +
>  opcodes/riscv-opc.c                      | 124 +++++
>  14 files changed, 1428 insertions(+), 5 deletions(-)
>  create mode 100644 gas/testsuite/gas/riscv/thead-csr-list.d
>  create mode 100644 gas/testsuite/gas/riscv/thead-csr-list.s
>  create mode 100644 gas/testsuite/gas/riscv/theadc-ext.d
>  create mode 100644 gas/testsuite/gas/riscv/theadc-ext.s
>  create mode 100644 gas/testsuite/gas/riscv/theade-ext.d
>  create mode 100644 gas/testsuite/gas/riscv/theade-ext.s
>  create mode 100644 include/opcode/riscv-opc-thead.h
>
> diff --git a/bfd/cpu-riscv.h b/bfd/cpu-riscv.h
> index ff037d127e2..3e0839fec3c 100644
> --- a/bfd/cpu-riscv.h
> +++ b/bfd/cpu-riscv.h
> @@ -34,6 +34,9 @@ enum riscv_spec_class
>    PRIV_SPEC_CLASS_1P11,
>    PRIV_SPEC_CLASS_1P12,
>    PRIV_SPEC_CLASS_DRAFT,
> +
> +  /* Vendor spec for T_HEAD XuanTie.  */
> +  VENDOR_SPEC_CLASS_THEAD,
>  };
>
>  struct riscv_spec
> diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
> index 0b2021f5cc7..2af0917381e 100644
> --- a/bfd/elfxx-riscv.c
> +++ b/bfd/elfxx-riscv.c
> @@ -1245,12 +1245,21 @@ static struct riscv_supported_ext riscv_supported_std_zxm_ext[] =
>    {NULL, 0, 0, 0, 0}
>  };
>
> +static struct riscv_supported_ext riscv_supported_custom_ext[] =
> +{
> +  {"xtheadc",          VENDOR_SPEC_CLASS_THEAD,        2, 0, 0 },
> +  {"xtheade",          VENDOR_SPEC_CLASS_THEAD,        2, 0, 0 },
> +  {"xtheadse",         VENDOR_SPEC_CLASS_THEAD,        2, 0, 0 },
> +  {NULL, 0, 0, 0, 0}
> +};
> +
>  const struct riscv_supported_ext *riscv_all_supported_ext[] =
>  {
>    riscv_supported_std_ext,
>    riscv_supported_std_z_ext,
>    riscv_supported_std_s_ext,
>    riscv_supported_std_zxm_ext,
> +  riscv_supported_custom_ext,
>    NULL
>  };
>
> @@ -1331,7 +1340,8 @@ riscv_recognized_prefixed_ext (const char *ext)
>    case RV_ISA_CLASS_S:
>      return riscv_known_prefixed_ext (ext, riscv_supported_std_s_ext);
>    case RV_ISA_CLASS_X:
> -    /* Only the single x is unrecognized.  */
> +    /* For compatibility this pretends to support any X extension except the
> +       single letter "x". */
>      if (strcmp (ext, "x") != 0)
>        return true;
>    default:
> @@ -1504,10 +1514,9 @@ riscv_get_default_ext_version (enum riscv_spec_class *default_isa_spec,
>    switch (class)
>      {
>      case RV_ISA_CLASS_ZXM: table = riscv_supported_std_zxm_ext; break;
> -    case RV_ISA_CLASS_Z: table = riscv_supported_std_z_ext; break;
> -    case RV_ISA_CLASS_S: table = riscv_supported_std_s_ext; break;
> -    case RV_ISA_CLASS_X:
> -      break;
> +    case RV_ISA_CLASS_Z: table = riscv_supported_std_z_ext;     break;
> +    case RV_ISA_CLASS_S: table = riscv_supported_std_s_ext;     break;
> +    case RV_ISA_CLASS_X: table = riscv_supported_custom_ext;    break;
>      default:
>        table = riscv_supported_std_ext;
>      }
> @@ -1517,6 +1526,7 @@ riscv_get_default_ext_version (enum riscv_spec_class *default_isa_spec,
>      {
>        if (strcmp (table[i].name, name) == 0
>           && (table[i].isa_spec_class == ISA_SPEC_CLASS_DRAFT
> +             || table[i].isa_spec_class == VENDOR_SPEC_CLASS_THEAD
>               || table[i].isa_spec_class == *default_isa_spec))
>         {
>           *major_version = table[i].major_version;
> @@ -2402,6 +2412,19 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
>        return riscv_subset_supports (rps, "svinval");
>      case INSN_CLASS_H:
>        return riscv_subset_supports (rps, "h");
> +    case INSN_CLASS_THEAD_C:
> +      return riscv_subset_supports (rps, "xtheadc");
> +    case INSN_CLASS_THEAD_E:
> +      return riscv_subset_supports (rps, "xtheade");
> +    case INSN_CLASS_THEAD_SE:
> +      return riscv_subset_supports (rps, "xtheadse");
> +    case INSN_CLASS_THEAD_C_OR_E:
> +      return (riscv_subset_supports (rps, "xtheadc")
> +             || riscv_subset_supports (rps, "xtheade"));
> +    case INSN_CLASS_THEAD_C_OR_E_OR_SE:
> +      return (riscv_subset_supports (rps, "xtheadc")
> +             || riscv_subset_supports (rps, "xtheade")
> +             || riscv_subset_supports (rps, "xtheadse"));
>      default:
>        rps->error_handler
>          (_("internal: unreachable INSN_CLASS_*"));
> @@ -2527,6 +2550,16 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
>        return "svinval";
>      case INSN_CLASS_H:
>        return _("h");
> +    case INSN_CLASS_THEAD_C:
> +      return "xtheadc";
> +    case INSN_CLASS_THEAD_E:
> +      return "xtheade";
> +    case INSN_CLASS_THEAD_SE:
> +      return "xtheadse";
> +    case INSN_CLASS_THEAD_C_OR_E:
> +      return _("xtheadc' or `xtheade");
> +    case INSN_CLASS_THEAD_C_OR_E_OR_SE:
> +      return _("xtheadc' or `xtheade' or `xtheadse");
>      default:
>        rps->error_handler
>          (_("internal: unreachable INSN_CLASS_*"));
> diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
> index 291d07f6d8f..8a473d4b3fe 100644
> --- a/gas/config/tc-riscv.c
> +++ b/gas/config/tc-riscv.c
> @@ -78,6 +78,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_THEAD,             /* vendor CSR for T-HEAD */
>  };
>
>  /* This structure holds all restricted conditions for a CSR.  */
> @@ -965,6 +966,9 @@ riscv_csr_address (const char *csr_name,
>        break;
>      case CSR_CLASS_DEBUG:
>        break;
> +    case CSR_CLASS_THEAD:
> +      extension = "xthead";
> +      break;
>      default:
>        as_bad (_("internal: bad RISC-V CSR class (0x%x)"), csr_class);
>      }
> @@ -1253,6 +1257,30 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
>                 goto unknown_validate_operand;
>             }
>           break;
> +       case 'X': /* Opcode for custom instructions.  */
> +         {
> +           int nbit, at, n;
> +           if (sscanf(oparg, "XI%d@%d%n", &nbit, &at, &n) == 2)
> +             {
> +               used_bits |= ENCODE_VENDOR_THEAD_IMM ((1ULL << nbit) - 1,
> +                                                     nbit, at);
> +               oparg += n - 1;
> +             }
> +           else if (sscanf(oparg, "XS%d@%d%n", &nbit, &at, &n) == 2)
> +             {
> +               used_bits |= ENCODE_VENDOR_THEAD_SIGN_IMM ((1ULL << nbit) - 1,
> +                                                          nbit, at);
> +               oparg += n - 1;
> +             }
> +           else
> +             {
> +               as_bad (_("internal: bad X opcode type `%s'"),
> +                       oparg);
> +               return false;
> +             }
> +         }
> +         break;
> +
>         default:
>         unknown_validate_operand:
>           as_bad (_("internal: bad RISC-V opcode "
> @@ -3265,6 +3293,63 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
>               asarg = expr_end;
>               continue;
>
> +           case 'X': /* Vendor-specific.  */
> +             {
> +               int nbit, at, n;
> +               if (sscanf(oparg, "XI%d@%d%n", &nbit, &at, &n) == 2)
> +                 {
> +                   my_getExpression (imm_expr, asarg);
> +                   if (imm_expr->X_op != O_constant)
> +                     {
> +                       as_bad (_("non-constant operand"));
> +                       break;
> +                     }
> +
> +                   if (!VALID_VENDOR_THEAD_IMM (imm_expr->X_add_number, nbit, at))
> +                     {
> +                       as_bad (_("invalid immediate"));
> +                       break;
> +                     }
> +
> +                   ip->insn_opcode |=
> +                     ENCODE_VENDOR_THEAD_IMM (imm_expr->X_add_number, nbit, at);
> +                   asarg = expr_end;
> +                   imm_expr->X_op = O_absent;
> +                   oparg += n - 1;
> +                   continue;
> +                 }
> +               else if (sscanf(oparg, "XS%d@%d%n", &nbit, &at, &n) == 2)
> +                 {
> +                   my_getExpression (imm_expr, asarg);
> +                   if (imm_expr->X_op != O_constant)
> +                     {
> +                       as_bad (_("non-constant operand"));
> +                       break;
> +                     }
> +
> +                   if (!VALID_VENDOR_THEAD_SIGN_IMM (imm_expr->X_add_number, nbit, at))
> +                     {
> +                       as_bad (_("invalid immediate"));
> +                       break;
> +                     }
> +
> +                   ip->insn_opcode |=
> +                     ENCODE_VENDOR_THEAD_SIGN_IMM (imm_expr->X_add_number, nbit, at);
> +                   asarg = expr_end;
> +                   imm_expr->X_op = O_absent;
> +                   oparg += n - 1;
> +                   continue;
> +                 }
> +
> +               else
> +                 {
> +                   as_fatal (_("internal: unknown X argument type `%s'"),
> +                             opargStart);
> +                   break;
> +                 }
> +               continue;
> +             }
> +
>             default:
>             unknown_riscv_ip_operand:
>               as_fatal (_("internal: unknown argument type `%s'"),
> diff --git a/gas/testsuite/gas/riscv/thead-csr-list.d b/gas/testsuite/gas/riscv/thead-csr-list.d
> new file mode 100644
> index 00000000000..08bda4d24ea
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/thead-csr-list.d
> @@ -0,0 +1,107 @@
> +#as: -march=rv64gcxtheadc
> +#objdump: -dr
> +
> +.*:[   ]+file format .*
> +
> +
> +Disassembly of section .text:
> +
> +0000000000000000 <.text>:
> +   0:  7c002573                csrr    a0,th_mxstatus
> +   4:  7c102573                csrr    a0,th_mhcr
> +   8:  7c202573                csrr    a0,th_mcor
> +   c:  7c302573                csrr    a0,th_mccr2
> +  10:  7c402573                csrr    a0,th_mcer2
> +  14:  7c502573                csrr    a0,th_mhint
> +  18:  7c602573                csrr    a0,th_mrmr
> +  1c:  7c702573                csrr    a0,th_mrvbr
> +  20:  7c802573                csrr    a0,th_mcer
> +  24:  7c902573                csrr    a0,th_mcounterwen
> +  28:  7ca02573                csrr    a0,th_mcounterinten
> +  2c:  7cb02573                csrr    a0,th_mcounterof
> +  30:  7cc02573                csrr    a0,th_mhint2
> +  34:  7cd02573                csrr    a0,th_mhint3
> +  38:  7e002573                csrr    a0,th_mraddr
> +  3c:  7e102573                csrr    a0,th_mexstatus
> +  40:  7e202573                csrr    a0,th_mnmicause
> +  44:  7e302573                csrr    a0,th_mnmipc
> +  48:  7f002573                csrr    a0,th_mhpmcr
> +  4c:  7f102573                csrr    a0,th_mhpmsr
> +  50:  7f202573                csrr    a0,th_mhpmer
> +  54:  7f302573                csrr    a0,th_msmpr
> +  58:  7f402573                csrr    a0,th_mteecfg
> +  5c:  7d102573                csrr    a0,th_usp
> +  60:  7d202573                csrr    a0,th_mcins
> +  64:  7d302573                csrr    a0,th_mcindex
> +  68:  7d402573                csrr    a0,th_mcdata0
> +  6c:  7d502573                csrr    a0,th_mcdata1
> +  70:  7d602573                csrr    a0,th_meicr
> +  74:  7d702573                csrr    a0,th_meicr2
> +  78:  be002573                csrr    a0,th_mebr
> +  7c:  be102573                csrr    a0,th_nt_mstatus
> +  80:  be302573                csrr    a0,th_nt_mtvec
> +  84:  be202573                csrr    a0,th_nt_mie
> +  88:  be402573                csrr    a0,th_nt_mtvt
> +  8c:  be502573                csrr    a0,th_nt_mepc
> +  90:  be602573                csrr    a0,th_nt_mcause
> +  94:  be702573                csrr    a0,th_nt_mip
> +  98:  be802573                csrr    a0,th_nt_mintstate
> +  9c:  be902573                csrr    a0,th_nt_mxstatus
> +  a0:  bea02573                csrr    a0,th_nt_mebr
> +  a4:  beb02573                csrr    a0,th_nt_msp
> +  a8:  bec02573                csrr    a0,th_t_usp
> +  ac:  bed02573                csrr    a0,th_t_mdcr
> +  b0:  bee02573                csrr    a0,th_t_mpcr
> +  b4:  bef02573                csrr    a0,th_pmpteecfg
> +  b8:  fc002573                csrr    a0,th_mcpuid
> +  bc:  fc102573                csrr    a0,th_mapbaddr
> +  c0:  fc202573                csrr    a0,th_mwmsr
> +  c4:  80002573                csrr    a0,th_fxcr
> +  c8:  9c002573                csrr    a0,th_smir
> +  cc:  9c102573                csrr    a0,th_smel
> +  d0:  9c202573                csrr    a0,th_smeh
> +  d4:  9c302573                csrr    a0,th_smcir
> +  d8:  5c002573                csrr    a0,th_sxstatus
> +  dc:  5c102573                csrr    a0,th_shcr
> +  e0:  5c202573                csrr    a0,th_scer2
> +  e4:  5c302573                csrr    a0,th_scer
> +  e8:  5c402573                csrr    a0,th_scounterinten
> +  ec:  5c502573                csrr    a0,th_scounterof
> +  f0:  5c602573                csrr    a0,th_shint
> +  f4:  5c702573                csrr    a0,th_shint2
> +  f8:  5c802573                csrr    a0,th_shpminhibit
> +  fc:  5c902573                csrr    a0,th_shpmcr
> + 100:  5ca02573                csrr    a0,th_shpmsr
> + 104:  5cb02573                csrr    a0,th_shpmer
> + 108:  5e002573                csrr    a0,th_scycle
> + 10c:  5e102573                csrr    a0,th_shpmcounter1
> + 110:  5e202573                csrr    a0,th_shpmcounter2
> + 114:  5e302573                csrr    a0,th_shpmcounter3
> + 118:  5e402573                csrr    a0,th_shpmcounter4
> + 11c:  5e502573                csrr    a0,th_shpmcounter5
> + 120:  5e602573                csrr    a0,th_shpmcounter6
> + 124:  5e702573                csrr    a0,th_shpmcounter7
> + 128:  5e802573                csrr    a0,th_shpmcounter8
> + 12c:  5e902573                csrr    a0,th_shpmcounter9
> + 130:  5ea02573                csrr    a0,th_shpmcounter10
> + 134:  5eb02573                csrr    a0,th_shpmcounter11
> + 138:  5ec02573                csrr    a0,th_shpmcounter12
> + 13c:  5ed02573                csrr    a0,th_shpmcounter13
> + 140:  5ee02573                csrr    a0,th_shpmcounter14
> + 144:  5ef02573                csrr    a0,th_shpmcounter15
> + 148:  5f002573                csrr    a0,th_shpmcounter16
> + 14c:  5f102573                csrr    a0,th_shpmcounter17
> + 150:  5f202573                csrr    a0,th_shpmcounter18
> + 154:  5f302573                csrr    a0,th_shpmcounter19
> + 158:  5f402573                csrr    a0,th_shpmcounter20
> + 15c:  5f502573                csrr    a0,th_shpmcounter21
> + 160:  5f602573                csrr    a0,th_shpmcounter22
> + 164:  5f702573                csrr    a0,th_shpmcounter23
> + 168:  5f802573                csrr    a0,th_shpmcounter24
> + 16c:  5f902573                csrr    a0,th_shpmcounter25
> + 170:  5fa02573                csrr    a0,th_shpmcounter26
> + 174:  5fb02573                csrr    a0,th_shpmcounter27
> + 178:  5fc02573                csrr    a0,th_shpmcounter28
> + 17c:  5fd02573                csrr    a0,th_shpmcounter29
> + 180:  5fe02573                csrr    a0,th_shpmcounter30
> + 184:  5ff02573                csrr    a0,th_shpmcounter31
> diff --git a/gas/testsuite/gas/riscv/thead-csr-list.s b/gas/testsuite/gas/riscv/thead-csr-list.s
> new file mode 100644
> index 00000000000..0784179683d
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/thead-csr-list.s
> @@ -0,0 +1,98 @@
> +csrr a0, th_mxstatus
> +csrr a0, th_mhcr
> +csrr a0, th_mcor
> +csrr a0, th_mccr2
> +csrr a0, th_mcer2
> +csrr a0, th_mhint
> +csrr a0, th_mrmr
> +csrr a0, th_mrvbr
> +csrr a0, th_mcer
> +csrr a0, th_mcounterwen
> +csrr a0, th_mcounterinten
> +csrr a0, th_mcounterof
> +csrr a0, th_mhint2
> +csrr a0, th_mhint3
> +csrr a0, th_mraddr
> +csrr a0, th_mexstatus
> +csrr a0, th_mnmicause
> +csrr a0, th_mnmipc
> +csrr a0, th_mhpmcr
> +csrr a0, th_mhpmsr
> +csrr a0, th_mhpmer
> +csrr a0, th_msmpr
> +csrr a0, th_mteecfg
> +csrr a0, th_usp
> +csrr a0, th_mcins
> +csrr a0, th_mcindex
> +csrr a0, th_mcdata0
> +csrr a0, th_mcdata1
> +csrr a0, th_meicr
> +csrr a0, th_meicr2
> +csrr a0, th_mebr
> +csrr a0, th_nt_mstatus
> +csrr a0, th_nt_mtvec
> +csrr a0, th_nt_mie
> +csrr a0, th_nt_mtvt
> +csrr a0, th_nt_mepc
> +csrr a0, th_nt_mcause
> +csrr a0, th_nt_mip
> +csrr a0, th_nt_mintstate
> +csrr a0, th_nt_mxstatus
> +csrr a0, th_nt_mebr
> +csrr a0, th_nt_msp
> +csrr a0, th_t_usp
> +csrr a0, th_t_mdcr
> +csrr a0, th_t_mpcr
> +csrr a0, th_pmpteecfg
> +csrr a0, th_mcpuid
> +csrr a0, th_mapbaddr
> +csrr a0, th_mwmsr
> +csrr a0, th_fxcr
> +csrr a0, th_smir
> +csrr a0, th_smel
> +csrr a0, th_smeh
> +csrr a0, th_smcir
> +csrr a0, th_sxstatus
> +csrr a0, th_shcr
> +csrr a0, th_scer2
> +csrr a0, th_scer
> +csrr a0, th_scounterinten
> +csrr a0, th_scounterof
> +csrr a0, th_shint
> +csrr a0, th_shint2
> +csrr a0, th_shpminhibit
> +csrr a0, th_shpmcr
> +csrr a0, th_shpmsr
> +csrr a0, th_shpmer
> +csrr a0, th_scycle
> +csrr a0, th_shpmcounter1
> +csrr a0, th_shpmcounter2
> +csrr a0, th_shpmcounter3
> +csrr a0, th_shpmcounter4
> +csrr a0, th_shpmcounter5
> +csrr a0, th_shpmcounter6
> +csrr a0, th_shpmcounter7
> +csrr a0, th_shpmcounter8
> +csrr a0, th_shpmcounter9
> +csrr a0, th_shpmcounter10
> +csrr a0, th_shpmcounter11
> +csrr a0, th_shpmcounter12
> +csrr a0, th_shpmcounter13
> +csrr a0, th_shpmcounter14
> +csrr a0, th_shpmcounter15
> +csrr a0, th_shpmcounter16
> +csrr a0, th_shpmcounter17
> +csrr a0, th_shpmcounter18
> +csrr a0, th_shpmcounter19
> +csrr a0, th_shpmcounter20
> +csrr a0, th_shpmcounter21
> +csrr a0, th_shpmcounter22
> +csrr a0, th_shpmcounter23
> +csrr a0, th_shpmcounter24
> +csrr a0, th_shpmcounter25
> +csrr a0, th_shpmcounter26
> +csrr a0, th_shpmcounter27
> +csrr a0, th_shpmcounter28
> +csrr a0, th_shpmcounter29
> +csrr a0, th_shpmcounter30
> +csrr a0, th_shpmcounter31
> diff --git a/gas/testsuite/gas/riscv/theadc-ext.d b/gas/testsuite/gas/riscv/theadc-ext.d
> new file mode 100644
> index 00000000000..b697f1b1c86
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/theadc-ext.d
> @@ -0,0 +1,112 @@
> +#as: -march=rv64gcxtheadc
> +#objdump: -dr
> +
> +.*:[   ]+file format .*
> +
> +
> +Disassembly of section .text:
> +
> +0000000000000000 <.text>:
> +   0:  cff01073                csrw    0xcff,zero
> +   4:  0010000b                th.dcache.call
> +   8:  0030000b                th.dcache.ciall
> +   c:  02b5000b                th.dcache.cipa  a0
> +  10:  0235000b                th.dcache.cisw  a0
> +  14:  0275000b                th.dcache.civa  a0
> +  18:  0295000b                th.dcache.cpa   a0
> +  1c:  0285000b                th.dcache.cpal1 a0
> +  20:  0255000b                th.dcache.cva   a0
> +  24:  0245000b                th.dcache.cval1 a0
> +  28:  02a5000b                th.dcache.ipa   a0
> +  2c:  0225000b                th.dcache.isw   a0
> +  30:  0265000b                th.dcache.iva   a0
> +  34:  0020000b                th.dcache.iall
> +  38:  0215000b                th.dcache.csw   a0
> +  3c:  0100000b                th.icache.iall
> +  40:  0110000b                th.icache.ialls
> +  44:  0305000b                th.icache.iva   a0
> +  48:  0385000b                th.icache.ipa   a0
> +  4c:  0160000b                th.l2cache.iall
> +  50:  0150000b                th.l2cache.call
> +  54:  0170000b                th.l2cache.ciall
> +  58:  04b5000b                th.sfence.vmas  a0,a1
> +  5c:  0180000b                th.sync
> +  60:  01a0000b                th.sync.i
> +  64:  0190000b                th.sync.s
> +  68:  01b0000b                th.sync.is
> +  6c:  02c5950b                th.addsl        a0,a1,a2,1
> +  70:  20c5950b                th.mula a0,a1,a2
> +  74:  22c5950b                th.muls a0,a1,a2
> +  78:  24c5950b                th.mulaw        a0,a1,a2
> +  7c:  26c5950b                th.mulsw        a0,a1,a2
> +  80:  28c5950b                th.mulah        a0,a1,a2
> +  84:  2ac5950b                th.mulsh        a0,a1,a2
> +  88:  1105950b                th.srri a0,a1,16
> +  8c:  1505950b                th.srriw        a0,a1,16
> +  90:  40c5950b                th.mveqz        a0,a1,a2
> +  94:  42c5950b                th.mvnez        a0,a1,a2
> +  98:  8905950b                th.tst  a0,a1,16
> +  9c:  8005950b                th.tstnbz       a0,a1
> +  a0:  4105a50b                th.ext  a0,a1,16,16
> +  a4:  4105b50b                th.extu a0,a1,16,16
> +  a8:  8605950b                th.ff1  a0,a1
> +  ac:  8405950b                th.ff0  a0,a1
> +  b0:  8205950b                th.rev  a0,a1
> +  b4:  9005950b                th.revw a0,a1
> +  b8:  62b5600b                th.flrd ft0,a0,a1,1
> +  bc:  42b5600b                th.flrw ft0,a0,a1,1
> +  c0:  72b5600b                th.flurd        ft0,a0,a1,1
> +  c4:  52b5600b                th.flurw        ft0,a0,a1,1
> +  c8:  02c5c50b                th.lrb  a0,a1,a2,1
> +  cc:  22c5c50b                th.lrh  a0,a1,a2,1
> +  d0:  42c5c50b                th.lrw  a0,a1,a2,1
> +  d4:  62c5c50b                th.lrd  a0,a1,a2,1
> +  d8:  82c5c50b                th.lrbu a0,a1,a2,1
> +  dc:  a2c5c50b                th.lrhu a0,a1,a2,1
> +  e0:  c2c5c50b                th.lrwu a0,a1,a2,1
> +  e4:  12c5c50b                th.lurb a0,a1,a2,1
> +  e8:  32c5c50b                th.lurh a0,a1,a2,1
> +  ec:  52c5c50b                th.lurw a0,a1,a2,1
> +  f0:  72c5c50b                th.lurd a0,a1,a2,1
> +  f4:  92c5c50b                th.lurbu        a0,a1,a2,1
> +  f8:  b2c5c50b                th.lurhu        a0,a1,a2,1
> +  fc:  d2c5c50b                th.lurwu        a0,a1,a2,1
> + 100:  1af5c50b                th.lbia a0,\(a1\),15,1
> + 104:  0af5c50b                th.lbib a0,\(a1\),15,1
> + 108:  3af5c50b                th.lhia a0,\(a1\),15,1
> + 10c:  2af5c50b                th.lhib a0,\(a1\),15,1
> + 110:  5af5c50b                th.lwia a0,\(a1\),15,1
> + 114:  4af5c50b                th.lwib a0,\(a1\),15,1
> + 118:  7af5c50b                th.ldia a0,\(a1\),15,1
> + 11c:  6af5c50b                th.ldib a0,\(a1\),15,1
> + 120:  9af5c50b                th.lbuia        a0,\(a1\),15,1
> + 124:  8af5c50b                th.lbuib        a0,\(a1\),15,1
> + 128:  baf5c50b                th.lhuia        a0,\(a1\),15,1
> + 12c:  aaf5c50b                th.lhuib        a0,\(a1\),15,1
> + 130:  daf5c50b                th.lwuia        a0,\(a1\),15,1
> + 134:  caf5c50b                th.lwuib        a0,\(a1\),15,1
> + 138:  fab6450b                th.ldd  a0,a1,\(a2\),1
> + 13c:  e2b6450b                th.lwd  a0,a1,\(a2\),1
> + 140:  f2b6450b                th.lwud a0,a1,\(a2\),1
> + 144:  62b5700b                th.fsrd ft0,a0,a1,1
> + 148:  42b5700b                th.fsrw ft0,a0,a1,1
> + 14c:  72b5700b                th.fsurd        ft0,a0,a1,1
> + 150:  52b5700b                th.fsurw        ft0,a0,a1,1
> + 154:  02c5d50b                th.srb  a0,a1,a2,1
> + 158:  22c5d50b                th.srh  a0,a1,a2,1
> + 15c:  42c5d50b                th.srw  a0,a1,a2,1
> + 160:  62c5d50b                th.srd  a0,a1,a2,1
> + 164:  12c5d50b                th.surb a0,a1,a2,1
> + 168:  32c5d50b                th.surh a0,a1,a2,1
> + 16c:  52c5d50b                th.surw a0,a1,a2,1
> + 170:  72c5d50b                th.surd a0,a1,a2,1
> + 174:  1af5d50b                th.sbia a0,\(a1\),15,1
> + 178:  0af5d50b                th.sbib a0,\(a1\),15,1
> + 17c:  3af5d50b                th.shia a0,\(a1\),15,1
> + 180:  2af5d50b                th.shib a0,\(a1\),15,1
> + 184:  5ac5d50b                th.swia a0,\(a1\),12,1
> + 188:  4af5d50b                th.swib a0,\(a1\),15,1
> + 18c:  7af5d50b                th.sdia a0,\(a1\),15,1
> + 190:  6af5d50b                th.sdib a0,\(a1\),15,1
> + 194:  fab6550b                th.sdd  a0,a1,\(a2\),1
> + 198:  e2b6550b                th.swd  a0,a1,\(a2\),1
> diff --git a/gas/testsuite/gas/riscv/theadc-ext.s b/gas/testsuite/gas/riscv/theadc-ext.s
> new file mode 100644
> index 00000000000..fda4319863b
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/theadc-ext.s
> @@ -0,0 +1,115 @@
> +.text
> +
> +th.wsc
> +
> +# cache ext
> +th.dcache.call
> +th.dcache.ciall
> +th.dcache.cipa a0
> +th.dcache.cisw a0
> +th.dcache.civa a0
> +th.dcache.cpa a0
> +th.dcache.cpal1 a0
> +th.dcache.cva a0
> +th.dcache.cval1 a0
> +th.dcache.ipa a0
> +th.dcache.isw a0
> +th.dcache.iva a0
> +th.dcache.iall
> +th.dcache.csw a0
> +th.icache.iall
> +th.icache.ialls
> +th.icache.iva a0
> +th.icache.ipa a0
> +th.l2cache.iall
> +th.l2cache.call
> +th.l2cache.ciall
> +
> +# sync ext
> +th.sfence.vmas       a0, a1
> +th.sync
> +th.sync.i
> +th.sync.s
> +th.sync.is
> +
> +# calc ext
> +th.addsl             a0, a1, a2, 1
> +th.mula              a0, a1, a2
> +th.muls              a0, a1, a2
> +th.mulaw             a0, a1, a2
> +th.mulsw             a0, a1, a2
> +th.mulah             a0, a1, a2
> +th.mulsh             a0, a1, a2
> +th.srri              a0, a1, 16
> +th.srriw             a0, a1, 16
> +th.mveqz             a0, a1, a2
> +th.mvnez             a0, a1, a2
> +
> +# bit ext
> +th.tst               a0, a1, 16
> +th.tstnbz            a0, a1
> +th.ext               a0, a1, 16, 16
> +th.extu              a0, a1, 16, 16
> +th.ff1               a0, a1
> +th.ff0               a0, a1
> +th.rev               a0, a1
> +th.revw       a0, a1
> +
> +# load/store ext
> +th.flrd       f0, a0, a1, 1
> +th.flrw       f0, a0, a1, 1
> +th.flurd      f0, a0, a1, 1
> +th.flurw      f0, a0, a1, 1
> +th.lrb               a0, a1, a2, 1
> +th.lrh               a0, a1, a2, 1
> +th.lrw               a0, a1, a2, 1
> +th.lrd               a0, a1, a2, 1
> +th.lrbu              a0, a1, a2, 1
> +th.lrhu              a0, a1, a2, 1
> +th.lrwu              a0, a1, a2, 1
> +th.lurb              a0, a1, a2, 1
> +th.lurh              a0, a1, a2, 1
> +th.lurw              a0, a1, a2, 1
> +th.lurd              a0, a1, a2, 1
> +th.lurbu             a0, a1, a2, 1
> +th.lurhu             a0, a1, a2, 1
> +th.lurwu             a0, a1, a2, 1
> +th.lbia       a0, (a1), 15, 1
> +th.lbib       a0, (a1), 15, 1
> +th.lhia       a0, (a1), 15, 1
> +th.lhib       a0, (a1), 15, 1
> +th.lwia       a0, (a1), 15, 1
> +th.lwib       a0, (a1), 15, 1
> +th.ldia       a0, (a1), 15, 1
> +th.ldib       a0, (a1), 15, 1
> +th.lbuia      a0, (a1), 15, 1
> +th.lbuib      a0, (a1), 15, 1
> +th.lhuia      a0, (a1), 15, 1
> +th.lhuib      a0, (a1), 15, 1
> +th.lwuia      a0, (a1), 15, 1
> +th.lwuib      a0, (a1), 15, 1
> +th.ldd               a0, a1, (a2), 1
> +th.lwd               a0, a1, (a2), 1
> +th.lwud              a0, a1, (a2), 1
> +th.fsrd       f0, a0, a1, 1
> +th.fsrw       f0, a0, a1, 1
> +th.fsurd      f0, a0, a1, 1
> +th.fsurw      f0, a0, a1, 1
> +th.srb               a0, a1, a2, 1
> +th.srh               a0, a1, a2, 1
> +th.srw               a0, a1, a2, 1
> +th.srd               a0, a1, a2, 1
> +th.surb              a0, a1, a2, 1
> +th.surh              a0, a1, a2, 1
> +th.surw              a0, a1, a2, 1
> +th.surd              a0, a1, a2, 1
> +th.sbia              a0, (a1), 15, 1
> +th.sbib              a0, (a1), 15, 1
> +th.shia              a0, (a1), 15, 1
> +th.shib              a0, (a1), 15, 1
> +th.swia              a0, (a1), 12, 1
> +th.swib              a0, (a1), 15, 1
> +th.sdia              a0, (a1), 15, 1
> +th.sdib              a0, (a1), 15, 1
> +th.sdd               a0, a1, (a2), 1
> +th.swd               a0, a1, (a2), 1
> diff --git a/gas/testsuite/gas/riscv/theade-ext.d b/gas/testsuite/gas/riscv/theade-ext.d
> new file mode 100644
> index 00000000000..ff4234d323e
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/theade-ext.d
> @@ -0,0 +1,62 @@
> +#as: -march=rv32gcxtheade
> +#objdump: -dr
> +
> +.*:[   ]+file format .*
> +
> +
> +Disassembly of section .text:
> +
> +00000000 <.text>:
> +[       ]+[0-9a-f]+:\s+cff01073                csrw    0xcff,zero
> +[       ]+[0-9a-f]+:\s+02a5000b                th.dcache.ipa   a0
> +[       ]+[0-9a-f]+:\s+0295000b                th.dcache.cpa   a0
> +[       ]+[0-9a-f]+:\s+02b5000b                th.dcache.cipa  a0
> +[       ]+[0-9a-f]+:\s+0225000b                th.dcache.isw   a0
> +[       ]+[0-9a-f]+:\s+0215000b                th.dcache.csw   a0
> +[       ]+[0-9a-f]+:\s+0235000b                th.dcache.cisw  a0
> +[       ]+[0-9a-f]+:\s+0020000b                th.dcache.iall
> +[       ]+[0-9a-f]+:\s+0010000b                th.dcache.call
> +[       ]+[0-9a-f]+:\s+0030000b                th.dcache.ciall
> +[       ]+[0-9a-f]+:\s+0100000b                th.icache.iall
> +[       ]+[0-9a-f]+:\s+0385000b                th.icache.ipa   a0
> +[       ]+[0-9a-f]+:\s+0180000b                th.sync
> +[       ]+[0-9a-f]+:\s+01a0000b                th.sync.i
> +[       ]+[0-9a-f]+:\s+02c5950b                th.addsl        a0,a1,a2,1
> +[       ]+[0-9a-f]+:\s+1105950b                th.srri a0,a1,16
> +[       ]+[0-9a-f]+:\s+20c5950b                th.mula a0,a1,a2
> +[       ]+[0-9a-f]+:\s+28c5950b                th.mulah        a0,a1,a2
> +[       ]+[0-9a-f]+:\s+22c5950b                th.muls a0,a1,a2
> +[       ]+[0-9a-f]+:\s+2ac5950b                th.mulsh        a0,a1,a2
> +[       ]+[0-9a-f]+:\s+40c5950b                th.mveqz        a0,a1,a2
> +[       ]+[0-9a-f]+:\s+42c5950b                th.mvnez        a0,a1,a2
> +[       ]+[0-9a-f]+:\s+4105a50b                th.ext  a0,a1,16,16
> +[       ]+[0-9a-f]+:\s+4105b50b                th.extu a0,a1,16,16
> +[       ]+[0-9a-f]+:\s+8605950b                th.ff1  a0,a1
> +[       ]+[0-9a-f]+:\s+8405950b                th.ff0  a0,a1
> +[       ]+[0-9a-f]+:\s+8205950b                th.rev  a0,a1
> +[       ]+[0-9a-f]+:\s+8905950b                th.tst  a0,a1,16
> +[       ]+[0-9a-f]+:\s+8005950b                th.tstnbz       a0,a1
> +[       ]+[0-9a-f]+:\s+02c5c50b                th.lrb  a0,a1,a2,1
> +[       ]+[0-9a-f]+:\s+22c5c50b                th.lrh  a0,a1,a2,1
> +[       ]+[0-9a-f]+:\s+42c5c50b                th.lrw  a0,a1,a2,1
> +[       ]+[0-9a-f]+:\s+82c5c50b                th.lrbu a0,a1,a2,1
> +[       ]+[0-9a-f]+:\s+a2c5c50b                th.lrhu a0,a1,a2,1
> +[       ]+[0-9a-f]+:\s+1af5c50b                th.lbia a0,\(a1\),15,1
> +[       ]+[0-9a-f]+:\s+0af5c50b                th.lbib a0,\(a1\),15,1
> +[       ]+[0-9a-f]+:\s+3af5c50b                th.lhia a0,\(a1\),15,1
> +[       ]+[0-9a-f]+:\s+2af5c50b                th.lhib a0,\(a1\),15,1
> +[       ]+[0-9a-f]+:\s+5af5c50b                th.lwia a0,\(a1\),15,1
> +[       ]+[0-9a-f]+:\s+4af5c50b                th.lwib a0,\(a1\),15,1
> +[       ]+[0-9a-f]+:\s+02c5d50b                th.srb  a0,a1,a2,1
> +[       ]+[0-9a-f]+:\s+22c5d50b                th.srh  a0,a1,a2,1
> +[       ]+[0-9a-f]+:\s+42c5d50b                th.srw  a0,a1,a2,1
> +[       ]+[0-9a-f]+:\s+1af5d50b                th.sbia a0,\(a1\),15,1
> +[       ]+[0-9a-f]+:\s+0af5d50b                th.sbib a0,\(a1\),15,1
> +[       ]+[0-9a-f]+:\s+3af5d50b                th.shia a0,\(a1\),15,1
> +[       ]+[0-9a-f]+:\s+2af5d50b                th.shib a0,\(a1\),15,1
> +[       ]+[0-9a-f]+:\s+5ac5d50b                th.swia a0,\(a1\),12,1
> +[       ]+[0-9a-f]+:\s+4af5d50b                th.swib a0,\(a1\),15,1
> +[       ]+[0-9a-f]+:\s+c000150b                th.fmv.x.hw     a0,ft0
> +[       ]+[0-9a-f]+:\s+a005100b                th.fmv.hw.x     ft0,a0
> +[       ]+[0-9a-f]+:\s+0040000b                th.ipush
> +[       ]+[0-9a-f]+:\s+0050000b                th.ipop
> diff --git a/gas/testsuite/gas/riscv/theade-ext.s b/gas/testsuite/gas/riscv/theade-ext.s
> new file mode 100644
> index 00000000000..a56385802b1
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/theade-ext.s
> @@ -0,0 +1,66 @@
> +.text
> +
> +th.wsc
> +
> +# cache ext
> +th.dcache.ipa a0
> +th.dcache.cpa a0
> +th.dcache.cipa a0
> +th.dcache.isw a0
> +th.dcache.csw a0
> +th.dcache.cisw a0
> +th.dcache.iall
> +th.dcache.call
> +th.dcache.ciall
> +th.icache.iall
> +th.icache.ipa a0
> +
> +# sync ext
> +th.sync
> +th.sync.i
> +
> +# calc ext
> +th.addsl             a0, a1, a2, 1
> +th.srri              a0, a1, 16
> +th.mula              a0, a1, a2
> +th.mulah             a0, a1, a2
> +th.muls              a0, a1, a2
> +th.mulsh             a0, a1, a2
> +th.mveqz             a0, a1, a2
> +th.mvnez             a0, a1, a2
> +
> +# bit ext
> +th.ext               a0, a1, 16, 16
> +th.extu              a0, a1, 16, 16
> +th.ff1               a0, a1
> +th.ff0               a0, a1
> +th.rev               a0, a1
> +th.tst               a0, a1, 16
> +th.tstnbz            a0, a1
> +
> +# load/store ext
> +th.lrb               a0, a1, a2, 1
> +th.lrh               a0, a1, a2, 1
> +th.lrw               a0, a1, a2, 1
> +th.lrbu              a0, a1, a2, 1
> +th.lrhu              a0, a1, a2, 1
> +th.lbia       a0, (a1), 15, 1
> +th.lbib       a0, (a1), 15, 1
> +th.lhia       a0, (a1), 15, 1
> +th.lhib       a0, (a1), 15, 1
> +th.lwia       a0, (a1), 15, 1
> +th.lwib       a0, (a1), 15, 1
> +th.srb               a0, a1, a2, 1
> +th.srh               a0, a1, a2, 1
> +th.srw               a0, a1, a2, 1
> +th.sbia              a0, (a1), 15, 1
> +th.sbib              a0, (a1), 15, 1
> +th.shia              a0, (a1), 15, 1
> +th.shib              a0, (a1), 15, 1
> +th.swia              a0, (a1), 12, 1
> +th.swib              a0, (a1), 15, 1
> +
> +th.fmv.x.hw   a0, f0
> +th.fmv.hw.x   f0, a0
> +th.ipush
> +th.ipop
> diff --git a/include/opcode/riscv-opc-thead.h b/include/opcode/riscv-opc-thead.h
> new file mode 100644
> index 00000000000..98935f6b2b0
> --- /dev/null
> +++ b/include/opcode/riscv-opc-thead.h
> @@ -0,0 +1,571 @@
> +/* riscv-opcextended.h.  RISC-V extended instruction opcode.
> +   Copyright (C) 2021 Free Software Foundation, Inc.
> +
> +   This file is part of GDB, GAS, and the GNU binutils.
> +
> +   GDB, GAS, and the GNU binutils are free software; you can redistribute
> +   them and/or modify them under the terms of the GNU General Public
> +   License as published by the Free Software Foundation; either version
> +   3, or (at your option) any later version.
> +
> +   GDB, GAS, and the GNU binutils are distributed in the hope that they
> +   will be useful, but WITHOUT ANY WARRANTY; without even the implied
> +   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
> +   the GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program; see the file COPYING3. If not,
> +   see <http://www.gnu.org/licenses/>.  */
> +
> +#ifndef __RISCV_OPC_THEAD__
> +#define __RISCV_OPC_THEAD__
> +/* Opcodes for T-HEAD.  */
> +#define MATCH_DCACHE_CALL      0x0010000b
> +#define MASK_DCACHE_CALL       0xffffffff
> +#define MATCH_DCACHE_IALL      0x0020000b
> +#define MASK_DCACHE_IALL       0xffffffff
> +#define MATCH_DCACHE_CSW       0x0210000b
> +#define MASK_DCACHE_CSW                0xfff07fff
> +#define MATCH_DCACHE_ISW       0x0220000b
> +#define MASK_DCACHE_ISW                0xfff07fff
> +#define MATCH_DCACHE_CIALL     0x0030000b
> +#define MASK_DCACHE_CIALL      0xffffffff
> +#define MATCH_DCACHE_CISW      0x0230000b
> +#define MASK_DCACHE_CISW       0xfff07fff
> +#define MATCH_DCACHE_CVAL1     0x0240000b
> +#define MASK_DCACHE_CVAL1      0xfff07fff
> +#define MATCH_DCACHE_CVA       0x0250000b
> +#define MASK_DCACHE_CVA                0xfff07fff
> +#define MATCH_DCACHE_IVA       0x0260000b
> +#define MASK_DCACHE_IVA                0xfff07fff
> +#define MATCH_DCACHE_CIVA      0x0270000b
> +#define MASK_DCACHE_CIVA       0xfff07fff
> +#define MATCH_DCACHE_CPAL1     0x0280000b
> +#define MASK_DCACHE_CPAL1      0xfff07fff
> +#define MATCH_DCACHE_CPA       0x0290000b
> +#define MASK_DCACHE_CPA                0xfff07fff
> +#define MATCH_DCACHE_IPA       0x02a0000b
> +#define MASK_DCACHE_IPA                0xfff07fff
> +#define MATCH_DCACHE_CIPA      0x02b0000b
> +#define MASK_DCACHE_CIPA       0xfff07fff
> +#define MATCH_ICACHE_IALL      0x0100000b
> +#define MASK_ICACHE_IALL       0xffffffff
> +#define MATCH_ICACHE_IALLS     0x0110000b
> +#define MASK_ICACHE_IALLS      0xffffffff
> +#define MATCH_ICACHE_IVA       0x0300000b
> +#define MASK_ICACHE_IVA                0xfff07fff
> +#define MATCH_ICACHE_IPA       0x0380000b
> +#define MASK_ICACHE_IPA                0xfff07fff
> +#define MATCH_L2CACHE_CALL     0x0150000b
> +#define MASK_L2CACHE_CALL      0xffffffff
> +#define MATCH_L2CACHE_IALL     0x0160000b
> +#define MASK_L2CACHE_IALL      0xffffffff
> +#define MATCH_L2CACHE_CIALL    0x0170000b
> +#define MASK_L2CACHE_CIALL     0xffffffff
> +#define MATCH_SYNC             0x0180000b
> +#define MASK_SYNC              0xffffffff
> +#define MATCH_SYNC_S           0x0190000b
> +#define MASK_SYNC_S            0xffffffff
> +#define MATCH_SYNC_I           0x01a0000b
> +#define MASK_SYNC_I            0xffffffff
> +#define MATCH_SYNC_IS          0x01b0000b
> +#define MASK_SYNC_IS           0xffffffff
> +#define MATCH_SFENCE_VMAS      0x0400000b
> +#define MASK_SFENCE_VMAS       0xfe007fff
> +#define MATCH_TSTNBZ           0x8000100b
> +#define MASK_TSTNBZ            0xfff0707f
> +#define MATCH_MVEQZ            0x4000100b
> +#define MASK_MVEQZ             0xfe00707f
> +#define MATCH_MVNEZ            0x4200100b
> +#define MASK_MVNEZ             0xfe00707f
> +#define MATCH_MULA             0x2000100b
> +#define MASK_MULA              0xfe00707f
> +#define MATCH_MULS             0x2200100b
> +#define MASK_MULS              0xfe00707f
> +#define MATCH_MULAW            0x2400100b
> +#define MASK_MULAW             0xfe00707f
> +#define MATCH_MULSW            0x2600100b
> +#define MASK_MULSW             0xfe00707f
> +#define MATCH_MULAH            0x2800100b
> +#define MASK_MULAH             0xfe00707f
> +#define MATCH_MULSH            0x2a00100b
> +#define MASK_MULSH             0xfe00707f
> +#define MATCH_EXT              0x0000200b
> +#define MASK_EXT               0x0000707f
> +#define MATCH_EXTU             0x0000300b
> +#define MASK_EXTU              0x0000707f
> +#define MATCH_LRB              0x0000400b
> +#define MASK_LRB               0xf800707f
> +#define MATCH_LRH              0x2000400b
> +#define MASK_LRH               0xf800707f
> +#define MATCH_LRW              0x4000400b
> +#define MASK_LRW               0xf800707f
> +#define MATCH_LRD              0x6000400b
> +#define MASK_LRD               0xf800707f
> +#define MATCH_LRBU             0x8000400b
> +#define MASK_LRBU              0xf800707f
> +#define MATCH_LRHU             0xa000400b
> +#define MASK_LRHU              0xf800707f
> +#define MATCH_LRWU             0xc000400b
> +#define MASK_LRWU              0xf800707f
> +#define MATCH_LURB             0x1000400b
> +#define MASK_LURB              0xf800707f
> +#define MATCH_LURH             0x3000400b
> +#define MASK_LURH              0xf800707f
> +#define MATCH_LURW             0x5000400b
> +#define MASK_LURW              0xf800707f
> +#define MATCH_LURD             0x7000400b
> +#define MASK_LURD              0xf800707f
> +#define MATCH_LURBU            0x9000400b
> +#define MASK_LURBU             0xf800707f
> +#define MATCH_LURHU            0xb000400b
> +#define MASK_LURHU             0xf800707f
> +#define MATCH_LURWU            0xd000400b
> +#define MASK_LURWU             0xf800707f
> +#define MATCH_REV              0x8200100b
> +#define MASK_REV               0xfff0707f
> +#define MATCH_FF0              0x8400100b
> +#define MASK_FF0               0xfff0707f
> +#define MATCH_FF1              0x8600100b
> +#define MASK_FF1               0xfff0707f
> +#define MATCH_SRB              0x0000500b
> +#define MASK_SRB               0xf800707f
> +#define MATCH_SRH              0x2000500b
> +#define MASK_SRH               0xf800707f
> +#define MATCH_SRW              0x4000500b
> +#define MASK_SRW               0xf800707f
> +#define MATCH_SRD              0x6000500b
> +#define MASK_SRD               0xf800707f
> +#define MATCH_SURB             0x1000500b
> +#define MASK_SURB              0xf800707f
> +#define MATCH_SURH             0x3000500b
> +#define MASK_SURH              0xf800707f
> +#define MATCH_SURW             0x5000500b
> +#define MASK_SURW              0xf800707f
> +#define MATCH_SURD             0x7000500b
> +#define MASK_SURD              0xf800707f
> +#define MATCH_TST              0x8800100b
> +#define MASK_TST               0xfc00707f
> +#define MATCH_SRRIW            0x1400100b
> +#define MASK_SRRIW             0xfe00707f
> +#define MATCH_SRRI             0x1000100b
> +#define MASK_SRRI              0xfc00707f
> +#define MATCH_ADDSL            0x0000100b
> +#define MASK_ADDSL             0xf800707f
> +#define MATCH_SWD              0xe000500b
> +#define MASK_SWD               0xf800707f
> +#define MATCH_SDD              0xf800500b
> +#define MASK_SDD               0xf800707f
> +#define MATCH_SDIA             0x7800500b
> +#define MASK_SDIA              0xf800707f
> +#define MATCH_SDIB             0x6800500b
> +#define MASK_SDIB              0xf800707f
> +#define MATCH_SWIA             0x5800500b
> +#define MASK_SWIA              0xf800707f
> +#define MATCH_SWIB             0x4800500b
> +#define MASK_SWIB              0xf800707f
> +#define MATCH_SHIB             0x2800500b
> +#define MASK_SHIB              0xf800707f
> +#define MATCH_SHIA             0x3800500b
> +#define MASK_SHIA              0xf800707f
> +#define MATCH_SBIA             0x1800500b
> +#define MASK_SBIA              0xf800707f
> +#define MATCH_SBIB             0x0800500b
> +#define MASK_SBIB              0xf800707f
> +#define MATCH_LWUD             0xf000400b
> +#define MASK_LWUD              0xf800707f
> +#define MATCH_LWD              0xe000400b
> +#define MASK_LWD               0xf800707f
> +#define MATCH_LDD              0xf800400b
> +#define MASK_LDD               0xf800707f
> +#define MATCH_LWUIA            0xd800400b
> +#define MASK_LWUIA             0xf800707f
> +#define MATCH_LWUIB            0xc800400b
> +#define MASK_LWUIB             0xf800707f
> +#define MATCH_LHUIA            0xb800400b
> +#define MASK_LHUIA             0xf800707f
> +#define MATCH_LHUIB            0xa800400b
> +#define MASK_LHUIB             0xf800707f
> +#define MATCH_LBUIA            0x9800400b
> +#define MASK_LBUIA             0xf800707f
> +#define MATCH_LBUIB            0x8800400b
> +#define MASK_LBUIB             0xf800707f
> +#define MATCH_LDIA             0x7800400b
> +#define MASK_LDIA              0xf800707f
> +#define MATCH_LDIB             0x6800400b
> +#define MASK_LDIB              0xf800707f
> +#define MATCH_LWIA             0x5800400b
> +#define MASK_LWIA              0xf800707f
> +#define MATCH_LWIB             0x4800400b
> +#define MASK_LWIB              0xf800707f
> +#define MATCH_LHIA             0x3800400b
> +#define MASK_LHIA              0xf800707f
> +#define MATCH_LHIB             0x2800400b
> +#define MASK_LHIB              0xf800707f
> +#define MATCH_LBIA             0x1800400b
> +#define MASK_LBIA              0xf800707f
> +#define MATCH_LBIB             0x0800400b
> +#define MASK_LBIB              0xf800707f
> +#define MATCH_REVW             0x9000100b
> +#define MASK_REVW              0xfff0707f
> +#define MATCH_FSURD            0x7000700b
> +#define MASK_FSURD             0xf800707f
> +#define MATCH_FSURW            0x5000700b
> +#define MASK_FSURW             0xf800707f
> +#define MATCH_FSRD             0x6000700b
> +#define MASK_FSRD              0xf800707f
> +#define MATCH_FSRW             0x4000700b
> +#define MASK_FSRW              0xf800707f
> +#define MATCH_FLURD            0x7000600b
> +#define MASK_FLURD             0xf800707f
> +#define MATCH_FLURW            0x5000600b
> +#define MASK_FLURW             0xf800707f
> +#define MATCH_FLRD             0x6000600b
> +#define MASK_FLRD              0xf800707f
> +#define MATCH_FLRW             0x4000600b
> +#define MASK_FLRW              0xf800707f
> +#define MATCH_IPUSH            0x0040000b
> +#define MASK_IPUSH             0xffffffff
> +#define MATCH_IPOP             0x0050000b
> +#define MASK_IPOP              0xffffffff
> +/* T-HEAD security.  */
> +#define MATCH_WSC              0xcff01073
> +#define MASK_WSC               0xffffffff
> +/* T-HEAD Float for rv32.  */
> +#define MATCH_FMV_X_HW         0xc000100b
> +#define MASK_FMV_X_HW          0xfff0707f
> +#define MATCH_FMV_HW_X         0xa000100b
> +#define MASK_FMV_HW_X          0xfff0707f
> +#endif /* __RISCV_OPC_THEAD__ */
> +#ifdef DECLARE_INSN
> +DECLARE_INSN(th_wsc, MATCH_WSC, MASK_WSC)
> +DECLARE_INSN(th_dcache_giall, MATCH_DCACHE_IALL, MASK_DCACHE_IALL)
> +DECLARE_INSN(th_dcache_gcall, MATCH_DCACHE_CALL, MASK_DCACHE_CALL)
> +DECLARE_INSN(th_dcache_gciall, MATCH_DCACHE_CIALL, MASK_DCACHE_CIALL)
> +DECLARE_INSN(th_dcache_gisw, MATCH_DCACHE_ISW, MASK_DCACHE_ISW)
> +DECLARE_INSN(th_dcache_gcsw, MATCH_DCACHE_CSW, MASK_DCACHE_CSW)
> +DECLARE_INSN(th_dcache_gcisw, MATCH_DCACHE_CISW, MASK_DCACHE_CISW)
> +DECLARE_INSN(th_dcache_giva, MATCH_DCACHE_IVA, MASK_DCACHE_IVA)
> +DECLARE_INSN(th_dcache_gcva, MATCH_DCACHE_CVA, MASK_DCACHE_CVA)
> +DECLARE_INSN(th_dcache_gcval1, MATCH_DCACHE_CVAL1, MASK_DCACHE_CVAL1)
> +DECLARE_INSN(th_dcache_gciva, MATCH_DCACHE_CIVA, MASK_DCACHE_CIVA)
> +DECLARE_INSN(th_dcache_gipa, MATCH_DCACHE_IPA, MASK_DCACHE_IPA)
> +DECLARE_INSN(th_dcache_gcpa, MATCH_DCACHE_CPA, MASK_DCACHE_CPA)
> +DECLARE_INSN(th_dcache_gcpal1, MATCH_DCACHE_CPAL1, MASK_DCACHE_CPAL1)
> +DECLARE_INSN(th_dcache_gcipa, MATCH_DCACHE_CIPA, MASK_DCACHE_CIPA)
> +DECLARE_INSN(th_icache_giall, MATCH_ICACHE_IALL, MASK_ICACHE_IALL)
> +DECLARE_INSN(th_icache_gialls, MATCH_ICACHE_IALLS, MASK_ICACHE_IALLS)
> +DECLARE_INSN(th_icache_giva, MATCH_ICACHE_IVA, MASK_ICACHE_IVA)
> +DECLARE_INSN(th_icache_gipa, MATCH_ICACHE_IPA, MASK_ICACHE_IPA)
> +DECLARE_INSN(th_l2cache_giall, MATCH_L2CACHE_IALL, MASK_L2CACHE_IALL)
> +DECLARE_INSN(th_l2cache_gcall, MATCH_L2CACHE_CALL, MASK_L2CACHE_CALL)
> +DECLARE_INSN(th_l2cache_gciall, MATCH_L2CACHE_CIALL, MASK_L2CACHE_CIALL)
> +DECLARE_INSN(th_sync, MATCH_SYNC, MASK_SYNC)
> +DECLARE_INSN(th_sync_gi, MATCH_SYNC_I, MASK_SYNC_I)
> +DECLARE_INSN(th_sync_gs, MATCH_SYNC_S, MASK_SYNC_S)
> +DECLARE_INSN(th_sync_gis, MATCH_SYNC_IS, MASK_SYNC_IS)
> +DECLARE_INSN(th_tstnbz, MATCH_TSTNBZ, MASK_TSTNBZ)
> +DECLARE_INSN(th_mula, MATCH_MULA, MASK_MULA)
> +DECLARE_INSN(th_muls, MATCH_MULS, MASK_MULS)
> +DECLARE_INSN(th_mulah, MATCH_MULAH, MASK_MULAH)
> +DECLARE_INSN(th_mulsh, MATCH_MULSH, MASK_MULSH)
> +DECLARE_INSN(th_sfence_vmas, MATCH_SFENCE_VMAS, MASK_SFENCE_VMAS)
> +DECLARE_INSN(th_mveqz, MATCH_MVEQZ, MASK_MVEQZ)
> +DECLARE_INSN(th_mvnez, MATCH_MVNEZ, MASK_MVNEZ)
> +DECLARE_INSN(th_mulaw, MATCH_MULAW, MASK_MULAW)
> +DECLARE_INSN(th_mulsw, MATCH_MULSW, MASK_MULSW)
> +DECLARE_INSN(th_ext, MATCH_EXT, MASK_EXT)
> +DECLARE_INSN(th_extu, MATCH_EXTU, MASK_EXTU)
> +DECLARE_INSN(th_ff1, MATCH_FF1, MASK_FF1)
> +DECLARE_INSN(th_ff0, MATCH_FF0, MASK_FF1)
> +DECLARE_INSN(th_rev, MATCH_REV, MASK_REV)
> +DECLARE_INSN(th_lrb, MATCH_LRB, MASK_LRB)
> +DECLARE_INSN(th_lrbu, MATCH_LRBU, MASK_LRBU)
> +DECLARE_INSN(th_lrh, MATCH_LRH, MASK_LRH)
> +DECLARE_INSN(th_lrhu, MATCH_LRHU, MASK_LRHU)
> +DECLARE_INSN(th_lrw, MATCH_LRW, MASK_LRW)
> +DECLARE_INSN(th_lrwu, MATCH_LRWU, MASK_LRWU)
> +DECLARE_INSN(th_srb, MATCH_SRB, MASK_SRB)
> +DECLARE_INSN(th_srh, MATCH_SRH, MASK_SRH)
> +DECLARE_INSN(th_srw, MATCH_SRW, MASK_SRW)
> +DECLARE_INSN(th_lrd, MATCH_LRD, MASK_LRD)
> +DECLARE_INSN(th_srd, MATCH_SRD, MASK_SRD)
> +DECLARE_INSN(th_lurb, MATCH_LURB, MASK_LURB)
> +DECLARE_INSN(th_lurbu, MATCH_LURBU, MASK_LURBU)
> +DECLARE_INSN(th_lurh, MATCH_LURH, MASK_LURH)
> +DECLARE_INSN(th_lurhu, MATCH_LURHU, MASK_LURHU)
> +DECLARE_INSN(th_lurw, MATCH_LURW, MASK_LURW)
> +DECLARE_INSN(th_lurwu, MATCH_LURWU, MASK_LURWU)
> +DECLARE_INSN(th_lurd, MATCH_LURD, MASK_LURD)
> +DECLARE_INSN(th_surb, MATCH_SURB, MASK_SURB)
> +DECLARE_INSN(th_surh, MATCH_SURH, MASK_SURH)
> +DECLARE_INSN(th_surw, MATCH_SURW, MASK_SURW)
> +DECLARE_INSN(th_surd, MATCH_SURD, MASK_SURD)
> +DECLARE_INSN(th_tst, MATCH_TST, MASK_TST)
> +DECLARE_INSN(th_srriw, MATCH_SRRIW, MASK_SRRIW)
> +DECLARE_INSN(th_srri, MATCH_SRRI, MASK_SRRI)
> +DECLARE_INSN(th_addsl, MATCH_ADDSL, MASK_ADDSL)
> +DECLARE_INSN(th_lwd, MATCH_LWD, MASK_LWD)
> +DECLARE_INSN(th_ldd, MATCH_LDD, MASK_LDD)
> +DECLARE_INSN(th_swd, MATCH_SWD, MASK_SWD)
> +DECLARE_INSN(th_sdd, MATCH_SDD, MASK_SDD)
> +DECLARE_INSN(th_sdia, MATCH_SDIA, MASK_SDIA)
> +DECLARE_INSN(th_sdib, MATCH_SDIB, MASK_SDIB)
> +DECLARE_INSN(th_lwud, MATCH_LWUD, MASK_LWUD)
> +DECLARE_INSN(th_swia, MATCH_SWIA, MASK_SWIA)
> +DECLARE_INSN(th_swib, MATCH_SWIB, MASK_SWIB)
> +DECLARE_INSN(th_shia, MATCH_SHIA, MASK_SHIA)
> +DECLARE_INSN(th_shib, MATCH_SHIB, MASK_SHIB)
> +DECLARE_INSN(th_sbia, MATCH_SBIA, MASK_SBIA)
> +DECLARE_INSN(th_sbib, MATCH_SBIB, MASK_SBIB)
> +DECLARE_INSN(th_lwuia, MATCH_LWUIA, MASK_LWUIA)
> +DECLARE_INSN(th_lwuib, MATCH_LWUIB, MASK_LWUIB)
> +DECLARE_INSN(th_lhuia, MATCH_LHUIA, MASK_LHUIA)
> +DECLARE_INSN(th_lhuib, MATCH_LHUIB, MASK_LHUIB)
> +DECLARE_INSN(th_lbuia, MATCH_LBUIA, MASK_LBUIA)
> +DECLARE_INSN(th_lbuib, MATCH_LBUIB, MASK_LBUIB)
> +DECLARE_INSN(th_ldia, MATCH_LDIA, MASK_LDIA)
> +DECLARE_INSN(th_ldib, MATCH_LDIB, MASK_LDIB)
> +DECLARE_INSN(th_lwia, MATCH_LWIA, MASK_LWIA)
> +DECLARE_INSN(th_lwib, MATCH_LWIB, MASK_LWIB)
> +DECLARE_INSN(th_lhia, MATCH_LHIA, MASK_LHIA)
> +DECLARE_INSN(th_lhib, MATCH_LHIB, MASK_LHIB)
> +DECLARE_INSN(th_lbia, MATCH_LBIA, MASK_LBIA)
> +DECLARE_INSN(th_lbib, MATCH_LBIB, MASK_LBIB)
> +DECLARE_INSN(th_fsurd, MATCH_FSURD, MASK_FSURD)
> +DECLARE_INSN(th_revw, MATCH_REVW, MASK_REVW)
> +DECLARE_INSN(th_fsurw, MATCH_FSURW, MASK_FSURW)
> +DECLARE_INSN(th_flurd, MATCH_FLURD, MASK_FLURD)
> +DECLARE_INSN(th_flurw, MATCH_FLURW, MASK_FLURW)
> +DECLARE_INSN(th_fsrd, MATCH_FSRD, MASK_FSRD)
> +DECLARE_INSN(th_fsrw, MATCH_FSRW, MASK_FSRW)
> +DECLARE_INSN(th_flrd, MATCH_FLRD, MASK_FLRD)
> +DECLARE_INSN(th_flrw, MATCH_FLRW, MASK_FLRW)
> +DECLARE_INSN(th_ipush, MATCH_IPUSH, MASK_IPUSH)
> +DECLARE_INSN(th_ipop, MATCH_IPOP, MASK_IPOP)
> +DECLARE_INSN(th_fmv_x_hw, MATCH_FMV_X_HW, MASK_FMV_X_HW)
> +DECLARE_INSN(th_fmv_hw_x, MATCH_FMV_HW_X, MASK_FMV_HW_X)
> +#endif /* DECLARE_INSN */
> +#ifdef DECLARE_CSR
> +/* T-HEAD M mode CSR.  */
> +#define CSR_THEAD_MXSTATUS 0x7c0
> +#define CSR_THEAD_MHCR 0x7c1
> +#define CSR_THEAD_MCOR 0x7c2
> +#define CSR_THEAD_MCCR2 0x7c3
> +#define CSR_THEAD_MCER2 0x7c4
> +#define CSR_THEAD_MHINT 0x7c5
> +#define CSR_THEAD_MRMR 0x7c6
> +#define CSR_THEAD_MRVBR 0x7c7
> +#define CSR_THEAD_MCER 0x7c8
> +#define CSR_THEAD_MCOUNTERWEN 0x7c9
> +#define CSR_THEAD_MCOUNTERINTEN 0x7ca
> +#define CSR_THEAD_MCOUNTEROF 0x7cb
> +#define CSR_THEAD_MHINT2 0x7cc
> +#define CSR_THEAD_MHINT3 0x7cd
> +#define CSR_THEAD_MRADDR 0x7e0
> +#define CSR_THEAD_MEXSTATUS 0x7e1
> +#define CSR_THEAD_MNMICAUSE 0x7e2
> +#define CSR_THEAD_MNMIPC 0x7e3
> +#define CSR_THEAD_MHPMCR 0x7f0
> +#define CSR_THEAD_MHPMSR 0x7f1
> +#define CSR_THEAD_MHPMER 0x7f2
> +#define CSR_THEAD_MSMPR 0x7f3
> +#define CSR_THEAD_MTEECFG 0x7f4
> +#define CSR_THEAD_MZONEID 0x7f5
> +#define CSR_THEAD_ML2CPID 0x7f6
> +#define CSR_THEAD_ML2WP 0x7f7
> +#define CSR_THEAD_MDTCMCR 0x7f8
> +#define CSR_THEAD_USP 0x7d1
> +#define CSR_THEAD_MCINS 0x7d2
> +#define CSR_THEAD_MCINDEX 0x7d3
> +#define CSR_THEAD_MCDATA0 0x7d4
> +#define CSR_THEAD_MCDATA1 0x7d5
> +#define CSR_THEAD_MEICR 0x7d6
> +#define CSR_THEAD_MEICR2 0x7d7
> +#define CSR_THEAD_MBEADDR 0x7d8
> +#define CSR_THEAD_MCPUID 0xfc0
> +#define CSR_THEAD_MAPBADDR 0xfc1
> +#define CSR_THEAD_MWMSR 0xfc2
> +#define CSR_THEAD_MHALTCAUSE 0xfe0
> +#define CSR_THEAD_MDBGINFO 0xfe1
> +#define CSR_THEAD_MPCFIFO 0xfe2
> +/* T-HEAD S mode CSR.  */
> +#define CSR_THEAD_SXSTATUS 0x5c0
> +#define CSR_THEAD_SHCR 0x5c1
> +#define CSR_THEAD_SCER2 0x5c2
> +#define CSR_THEAD_SCER 0x5c3
> +#define CSR_THEAD_SCOUNTERINTEN 0x5c4
> +#define CSR_THEAD_SCOUNTEROF 0x5c5
> +#define CSR_THEAD_SHINT 0x5c6
> +#define CSR_THEAD_SHINT2 0x5c7
> +#define CSR_THEAD_SHPMINHIBIT 0x5c8
> +#define CSR_THEAD_SHPMCR 0x5c9
> +#define CSR_THEAD_SHPMSR 0x5ca
> +#define CSR_THEAD_SHPMER 0x5cb
> +#define CSR_THEAD_SL2CPID 0x5cc
> +#define CSR_THEAD_SL2WP 0x5cd
> +#define CSR_THEAD_SBEADDR 0x5d0
> +#define CSR_THEAD_SCYCLE 0x5e0
> +#define CSR_THEAD_SHPMCOUNTER1 0x5e1
> +#define CSR_THEAD_SHPMCOUNTER2 0x5e2
> +#define CSR_THEAD_SHPMCOUNTER3 0x5e3
> +#define CSR_THEAD_SHPMCOUNTER4 0x5e4
> +#define CSR_THEAD_SHPMCOUNTER5 0x5e5
> +#define CSR_THEAD_SHPMCOUNTER6 0x5e6
> +#define CSR_THEAD_SHPMCOUNTER7 0x5e7
> +#define CSR_THEAD_SHPMCOUNTER8 0x5e8
> +#define CSR_THEAD_SHPMCOUNTER9 0x5e9
> +#define CSR_THEAD_SHPMCOUNTER10 0x5ea
> +#define CSR_THEAD_SHPMCOUNTER11 0x5eb
> +#define CSR_THEAD_SHPMCOUNTER12 0x5ec
> +#define CSR_THEAD_SHPMCOUNTER13 0x5ed
> +#define CSR_THEAD_SHPMCOUNTER14 0x5ee
> +#define CSR_THEAD_SHPMCOUNTER15 0x5ef
> +#define CSR_THEAD_SHPMCOUNTER16 0x5f0
> +#define CSR_THEAD_SHPMCOUNTER17 0x5f1
> +#define CSR_THEAD_SHPMCOUNTER18 0x5f2
> +#define CSR_THEAD_SHPMCOUNTER19 0x5f3
> +#define CSR_THEAD_SHPMCOUNTER20 0x5f4
> +#define CSR_THEAD_SHPMCOUNTER21 0x5f5
> +#define CSR_THEAD_SHPMCOUNTER22 0x5f6
> +#define CSR_THEAD_SHPMCOUNTER23 0x5f7
> +#define CSR_THEAD_SHPMCOUNTER24 0x5f8
> +#define CSR_THEAD_SHPMCOUNTER25 0x5f9
> +#define CSR_THEAD_SHPMCOUNTER26 0x5fa
> +#define CSR_THEAD_SHPMCOUNTER27 0x5fb
> +#define CSR_THEAD_SHPMCOUNTER28 0x5fc
> +#define CSR_THEAD_SHPMCOUNTER29 0x5fd
> +#define CSR_THEAD_SHPMCOUNTER30 0x5fe
> +#define CSR_THEAD_SHPMCOUNTER31 0x5ff
> +/* T-HEAD U mode CSR.  */
> +#define CSR_THEAD_FXCR 0x800
> +/* T-HEAD MMU extentions.  */
> +#define CSR_THEAD_SMIR 0x9c0
> +#define CSR_THEAD_SMEL 0x9c1
> +#define CSR_THEAD_SMEH 0x9c2
> +#define CSR_THEAD_SMCIR 0x9c3
> +/* T-HEAD Security CSR(May be dropped).  */
> +#define CSR_THEAD_MEBR 0xbe0
> +#define CSR_THEAD_NT_MSTATUS 0xbe1
> +#define CSR_THEAD_NT_MIE 0xbe2
> +#define CSR_THEAD_NT_MTVEC 0xbe3
> +#define CSR_THEAD_NT_MTVT 0xbe4
> +#define CSR_THEAD_NT_MEPC 0xbe5
> +#define CSR_THEAD_NT_MCAUSE 0xbe6
> +#define CSR_THEAD_NT_MIP 0xbe7
> +#define CSR_THEAD_NT_MINTSTATE 0xbe8
> +#define CSR_THEAD_NT_MXSTATUS 0xbe9
> +#define CSR_THEAD_NT_MEBR 0xbea
> +#define CSR_THEAD_NT_MSP 0xbeb
> +#define CSR_THEAD_T_USP 0xbec
> +#define CSR_THEAD_T_MDCR 0xbed
> +#define CSR_THEAD_T_MPCR 0xbee
> +#define CSR_THEAD_PMPTEECFG 0xbef
> +/* T-HEAD extentions.  */
> +DECLARE_CSR(th_mxstatus, CSR_THEAD_MXSTATUS, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mhcr, CSR_THEAD_MHCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mcor, CSR_THEAD_MCOR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mccr2, CSR_THEAD_MCCR2, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mcer2, CSR_THEAD_MCER2, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mhint, CSR_THEAD_MHINT, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mrmr, CSR_THEAD_MRMR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mrvbr, CSR_THEAD_MRVBR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mcer, CSR_THEAD_MCER, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mcounterwen, CSR_THEAD_MCOUNTERWEN, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mcounterinten, CSR_THEAD_MCOUNTERINTEN, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mcounterof, CSR_THEAD_MCOUNTEROF, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mhint2, CSR_THEAD_MHINT2, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mhint3, CSR_THEAD_MHINT3, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mraddr, CSR_THEAD_MRADDR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mexstatus, CSR_THEAD_MEXSTATUS, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mnmicause, CSR_THEAD_MNMICAUSE, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mnmipc, CSR_THEAD_MNMIPC, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mhpmcr, CSR_THEAD_MHPMCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mhpmsr, CSR_THEAD_MHPMSR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mhpmer, CSR_THEAD_MHPMER, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_msmpr, CSR_THEAD_MSMPR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mteecfg, CSR_THEAD_MTEECFG, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mzoneid, CSR_THEAD_MZONEID, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_ml2cpid, CSR_THEAD_ML2CPID, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_ml2wp, CSR_THEAD_ML2WP, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mdtcmcr, CSR_THEAD_MDTCMCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_usp, CSR_THEAD_USP, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mcins, CSR_THEAD_MCINS, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mcindex, CSR_THEAD_MCINDEX, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mcdata0, CSR_THEAD_MCDATA0, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mcdata1, CSR_THEAD_MCDATA1, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_meicr, CSR_THEAD_MEICR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_meicr2, CSR_THEAD_MEICR2, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mbeaddr, CSR_THEAD_MBEADDR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mebr, CSR_THEAD_MEBR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_nt_mstatus, CSR_THEAD_NT_MSTATUS, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_nt_mtvec, CSR_THEAD_NT_MTVEC, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_nt_mie, CSR_THEAD_NT_MIE, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_nt_mtvt, CSR_THEAD_NT_MTVT, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_nt_mepc, CSR_THEAD_NT_MEPC, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_nt_mcause, CSR_THEAD_NT_MCAUSE, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_nt_mip, CSR_THEAD_NT_MIP, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_nt_mintstate, CSR_THEAD_NT_MINTSTATE, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_nt_mxstatus, CSR_THEAD_NT_MXSTATUS, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_nt_mebr, CSR_THEAD_NT_MEBR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_nt_msp, CSR_THEAD_NT_MSP, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_t_usp, CSR_THEAD_T_USP, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_t_mdcr, CSR_THEAD_T_MDCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_t_mpcr, CSR_THEAD_T_MPCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_pmpteecfg, CSR_THEAD_PMPTEECFG, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mcpuid, CSR_THEAD_MCPUID, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mapbaddr, CSR_THEAD_MAPBADDR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_mwmsr, CSR_THEAD_MWMSR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_fxcr, CSR_THEAD_FXCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_smir, CSR_THEAD_SMIR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_smel, CSR_THEAD_SMEL, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_smeh, CSR_THEAD_SMEH, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_smcir, CSR_THEAD_SMCIR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_sxstatus, CSR_THEAD_SXSTATUS, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shcr, CSR_THEAD_SHCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_scer2, CSR_THEAD_SCER2, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_scer, CSR_THEAD_SCER, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_scounterinten , CSR_THEAD_SCOUNTERINTEN, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_scounterof, CSR_THEAD_SCOUNTEROF, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shint, CSR_THEAD_SHINT, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shint2, CSR_THEAD_SHINT2, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpminhibit, CSR_THEAD_SHPMINHIBIT, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcr, CSR_THEAD_SHPMCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmsr, CSR_THEAD_SHPMSR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmer, CSR_THEAD_SHPMER, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_sl2cpid, CSR_THEAD_SL2CPID, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_sl2wp, CSR_THEAD_SL2WP, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_sbeaddr, CSR_THEAD_SBEADDR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_scycle, CSR_THEAD_SCYCLE, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcounter1, CSR_THEAD_SHPMCOUNTER1, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcounter2, CSR_THEAD_SHPMCOUNTER2, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcounter3, CSR_THEAD_SHPMCOUNTER3, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcounter4, CSR_THEAD_SHPMCOUNTER4, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcounter5, CSR_THEAD_SHPMCOUNTER5, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcounter6, CSR_THEAD_SHPMCOUNTER6, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcounter7, CSR_THEAD_SHPMCOUNTER7, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcounter8, CSR_THEAD_SHPMCOUNTER8, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcounter9, CSR_THEAD_SHPMCOUNTER9, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcounter10, CSR_THEAD_SHPMCOUNTER10, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcounter11, CSR_THEAD_SHPMCOUNTER11, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcounter12, CSR_THEAD_SHPMCOUNTER12, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcounter13, CSR_THEAD_SHPMCOUNTER13, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcounter14, CSR_THEAD_SHPMCOUNTER14, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcounter15, CSR_THEAD_SHPMCOUNTER15, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcounter16, CSR_THEAD_SHPMCOUNTER16, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcounter17, CSR_THEAD_SHPMCOUNTER17, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcounter18, CSR_THEAD_SHPMCOUNTER18, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcounter19, CSR_THEAD_SHPMCOUNTER19, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcounter20, CSR_THEAD_SHPMCOUNTER20, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcounter21, CSR_THEAD_SHPMCOUNTER21, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcounter22, CSR_THEAD_SHPMCOUNTER22, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcounter23, CSR_THEAD_SHPMCOUNTER23, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcounter24, CSR_THEAD_SHPMCOUNTER24, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcounter25, CSR_THEAD_SHPMCOUNTER25, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcounter26, CSR_THEAD_SHPMCOUNTER26, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcounter27, CSR_THEAD_SHPMCOUNTER27, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcounter28, CSR_THEAD_SHPMCOUNTER28, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcounter29, CSR_THEAD_SHPMCOUNTER29, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcounter30, CSR_THEAD_SHPMCOUNTER30, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(th_shpmcounter31, CSR_THEAD_SHPMCOUNTER31, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +#endif /* DECLARE_CSR */
> diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
> index 88b8d7ff595..f755d0e0643 100644
> --- a/include/opcode/riscv-opc.h
> +++ b/include/opcode/riscv-opc.h
> @@ -3276,3 +3276,5 @@ DECLARE_CSR_ALIAS(tmexttrigger, CSR_TDATA1, CSR_CLASS_DEBUG, PRIV_SPEC_CLASS_NON
>  DECLARE_CSR_ALIAS(textra32, CSR_TDATA3, CSR_CLASS_DEBUG, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>  DECLARE_CSR_ALIAS(textra64, CSR_TDATA3, CSR_CLASS_DEBUG, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>  #endif /* DECLARE_CSR_ALIAS */
> +
> +#include "riscv-opc-thead.h"
> diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
> index b115e338a05..eff93641bae 100644
> --- a/include/opcode/riscv.h
> +++ b/include/opcode/riscv.h
> @@ -397,6 +397,11 @@ enum riscv_insn_class
>    INSN_CLASS_ZICBOP,
>    INSN_CLASS_ZICBOZ,
>    INSN_CLASS_H,
> +  INSN_CLASS_THEAD_C,
> +  INSN_CLASS_THEAD_E,
> +  INSN_CLASS_THEAD_SE,
> +  INSN_CLASS_THEAD_C_OR_E,
> +  INSN_CLASS_THEAD_C_OR_E_OR_SE,
>  };
>
>  /* This structure holds information for a particular instruction.  */
> @@ -531,4 +536,20 @@ extern const char * const riscv_vma[2];
>  extern const struct riscv_opcode riscv_opcodes[];
>  extern const struct riscv_opcode riscv_insn_types[];
>
> +/* T-HEAD IMM Encoding.  */
> +#define EXTRACT_VENDOR_THEAD_IMM(x,nbit,at) \
> +  (RV_X(x, at, nbit))
> +#define EXTRACT_VENDOR_THEAD_SIGN_IMM(x,nbit,at) \
> +  (RV_X(x, at, nbit) | ((-(RV_X(x, (at+nbit-1),1))) << (nbit)))
> +
> +#define ENCODE_VENDOR_THEAD_IMM(x,nbit,at) \
> +  (RV_X(x, 0, nbit) << at)
> +#define ENCODE_VENDOR_THEAD_SIGN_IMM(x,nbit,at) \
> +  (RV_X(x, 0, nbit) << at)
> +
> +#define VALID_VENDOR_THEAD_IMM(x,nbit,at) \
> +  (EXTRACT_VENDOR_THEAD_IMM(ENCODE_VENDOR_THEAD_IMM(x,nbit,at),nbit,at) == (x))
> +#define VALID_VENDOR_THEAD_SIGN_IMM(x,nbit,at) \
> +  (EXTRACT_VENDOR_THEAD_SIGN_IMM(ENCODE_VENDOR_THEAD_SIGN_IMM(x,nbit,at),nbit,at) == (x))
> +
>  #endif /* _RISCV_H_ */
> diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
> index 164fd209dbd..43646cc0731 100644
> --- a/opcodes/riscv-dis.c
> +++ b/opcodes/riscv-dis.c
> @@ -554,6 +554,30 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
>           print (info->stream, dis_style_text, "%d", rs1);
>           break;
>
> +       case 'X':
> +         {
> +           int nbit, at, n;
> +           if (sscanf(oparg, "XI%d@%d%n", &nbit, &at, &n) == 2)
> +             {
> +               int value = EXTRACT_BITS (l, (1 << nbit) - 1, at);
> +               print (info->stream, dis_style_immediate, "%d", value);
> +               oparg += n - 1;
> +             }
> +           else if (sscanf(oparg, "XS%d@%d%n", &nbit, &at, &n) == 2)
> +             {
> +               int value = EXTRACT_BITS (l, (1 << nbit) - 1, at);
> +               print (info->stream, dis_style_immediate, "%d", value);
> +               oparg += n - 1;
> +             }
> +           else
> +             {
> +               print (info->stream, dis_style_text,
> +                      _("# internal error, unknown X modifier %s"),
> +                      oparg);
> +             }
> +         }
> +         break;
> +
>         default:
>           /* xgettext:c-format */
>           print (info->stream, dis_style_text,
> diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
> index 2f9945aa930..0e9a2f597c2 100644
> --- a/opcodes/riscv-opc.c
> +++ b/opcodes/riscv-opc.c
> @@ -266,6 +266,17 @@ match_vd_eq_vs1_eq_vs2 (const struct riscv_opcode *op,
>    return match_opcode (op, insn) && vd == vs1 && vs1 == vs2;
>  }
>
> +static int
> +match_thead_rd1_rd2_neq_rs1(const struct riscv_opcode *op,
> +                           insn_t insn)
> +{
> +  int rd1 = (insn & MASK_RD) >> OP_SH_RD;
> +  int rd2 = (insn & MASK_RS2) >> OP_SH_RS2;
> +  int rs1 = (insn & MASK_RS1) >> OP_SH_RS1;
> +
> +  return match_opcode (op, insn) && rd1 != rs1 && rd2 != rs1;
> +}
> +
>  const struct riscv_opcode riscv_opcodes[] =
>  {
>  /* name, xlen, isa, operands, match, mask, match_func, pinfo.  */
> @@ -1825,6 +1836,119 @@ const struct riscv_opcode riscv_opcodes[] =
>  {"hsv.w",       0, INSN_CLASS_H, "t,0(s)", MATCH_HSV_W, MASK_HSV_W, match_opcode, INSN_DREF|INSN_4_BYTE },
>  {"hsv.d",      64, INSN_CLASS_H, "t,0(s)", MATCH_HSV_D, MASK_HSV_D, match_opcode, INSN_DREF|INSN_8_BYTE },
>
> +/* The vendor extension opcodes for T-HEAD.  */
> +{"th.wsc",             0, INSN_CLASS_THEAD_C_OR_E,   "",  MATCH_WSC, MASK_WSC, match_opcode, 0},
> +{"th.dcache.iall",     0, INSN_CLASS_THEAD_C_OR_E,   "",  MATCH_DCACHE_IALL, MASK_DCACHE_IALL, match_opcode, 0},
> +{"th.dcache.call",     0, INSN_CLASS_THEAD_C_OR_E,   "",  MATCH_DCACHE_CALL, MASK_DCACHE_CALL, match_opcode, 0},
> +{"th.dcache.ciall",    0, INSN_CLASS_THEAD_C_OR_E,   "",  MATCH_DCACHE_CIALL, MASK_DCACHE_CIALL, match_opcode, 0},
> +{"th.dcache.isw",      0, INSN_CLASS_THEAD_C_OR_E,   "s",     MATCH_DCACHE_ISW, MASK_DCACHE_ISW, match_opcode, 0},
> +{"th.dcache.csw",      0, INSN_CLASS_THEAD_C_OR_E,   "s",     MATCH_DCACHE_CSW, MASK_DCACHE_CSW, match_opcode, 0},
> +{"th.dcache.cisw",     0, INSN_CLASS_THEAD_C_OR_E,   "s",     MATCH_DCACHE_CISW, MASK_DCACHE_CISW, match_opcode, 0},
> +{"th.dcache.iva",      0, INSN_CLASS_THEAD_C,   "s",     MATCH_DCACHE_IVA, MASK_DCACHE_IVA, match_opcode, 0},
> +{"th.dcache.cva",      0, INSN_CLASS_THEAD_C,   "s",     MATCH_DCACHE_CVA, MASK_DCACHE_CVA, match_opcode, 0},
> +{"th.dcache.cval1",    0, INSN_CLASS_THEAD_C,   "s",     MATCH_DCACHE_CVAL1, MASK_DCACHE_CVAL1, match_opcode, 0},
> +{"th.dcache.civa",     0, INSN_CLASS_THEAD_C,   "s",     MATCH_DCACHE_CIVA, MASK_DCACHE_CIVA, match_opcode, 0},
> +{"th.dcache.ipa",      0, INSN_CLASS_THEAD_C_OR_E,   "s",     MATCH_DCACHE_IPA, MASK_DCACHE_IPA, match_opcode, 0},
> +{"th.dcache.cpa",      0, INSN_CLASS_THEAD_C_OR_E,   "s",     MATCH_DCACHE_CPA, MASK_DCACHE_CPA, match_opcode, 0},
> +{"th.dcache.cpal1",    0, INSN_CLASS_THEAD_C,   "s",     MATCH_DCACHE_CPAL1, MASK_DCACHE_CPAL1, match_opcode, 0},
> +{"th.dcache.cipa",     0, INSN_CLASS_THEAD_C_OR_E,   "s",     MATCH_DCACHE_CIPA, MASK_DCACHE_CIPA, match_opcode, 0},
> +{"th.icache.iall",     0, INSN_CLASS_THEAD_C_OR_E_OR_SE,   "",      MATCH_ICACHE_IALL, MASK_ICACHE_IALL, match_opcode, 0},
> +{"th.icache.iall",     0, INSN_CLASS_THEAD_SE,   "",      MATCH_ICACHE_IALL, MASK_ICACHE_IALL, match_opcode, INSN_ALIAS},
> +{"th.icache.ialls",    0, INSN_CLASS_THEAD_C,   "",      MATCH_ICACHE_IALLS, MASK_ICACHE_IALLS, match_opcode, 0},
> +{"th.icache.iva",      0, INSN_CLASS_THEAD_C,   "s",     MATCH_ICACHE_IVA, MASK_ICACHE_IVA, match_opcode, 0},
> +{"th.icache.ipa",      0, INSN_CLASS_THEAD_C_OR_E,   "s",     MATCH_ICACHE_IPA, MASK_ICACHE_IPA, match_opcode, 0},
> +{"th.l2cache.iall",    0, INSN_CLASS_THEAD_C,   "",      MATCH_L2CACHE_IALL, MASK_L2CACHE_IALL, match_opcode, 0},
> +{"th.l2cache.call",    0, INSN_CLASS_THEAD_C,   "",      MATCH_L2CACHE_CALL, MASK_L2CACHE_CALL, match_opcode, 0},
> +{"th.l2cache.ciall",   0, INSN_CLASS_THEAD_C_OR_E,   "",      MATCH_L2CACHE_CIALL, MASK_L2CACHE_CIALL, match_opcode, 0},
> +{"th.sync",            0, INSN_CLASS_THEAD_C_OR_E,   "",      MATCH_SYNC, MASK_SYNC, match_opcode, 0},
> +{"th.sync.i",          0, INSN_CLASS_THEAD_C_OR_E,   "",      MATCH_SYNC_I, MASK_SYNC_I, match_opcode, 0},
> +{"th.sync.s",          0, INSN_CLASS_THEAD_C,   "",      MATCH_SYNC_S, MASK_SYNC_S, match_opcode, 0},
> +{"th.sync.is",         0, INSN_CLASS_THEAD_C,   "",      MATCH_SYNC_IS, MASK_SYNC_IS, match_opcode, 0},
> +{"th.tstnbz",          0, INSN_CLASS_THEAD_C_OR_E,   "d,s",     MATCH_TSTNBZ, MASK_TSTNBZ, match_opcode, 0},
> +{"th.mula",            0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MULA, MASK_MULA, match_opcode, 0},
> +{"th.muls",            0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MULS, MASK_MULS, match_opcode, 0},
> +{"th.mulah",           0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MULAH, MASK_MULAH, match_opcode, 0},
> +{"th.mulsh",           0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MULSH, MASK_MULSH, match_opcode, 0},
> +{"th.sfence.vmas",     0, INSN_CLASS_THEAD_C,   "s,t",      MATCH_SFENCE_VMAS, MASK_SFENCE_VMAS, match_opcode, 0},
> +{"th.mveqz",           0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MVEQZ, MASK_MVEQZ, match_opcode, 0},
> +{"th.mvnez",           0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MVNEZ, MASK_MVNEZ, match_opcode, 0},
> +{"th.mulaw",           0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MULAW, MASK_MULAW, match_opcode, 0},
> +{"th.mulsw",           0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MULSW, MASK_MULSW, match_opcode, 0},
> +{"th.ext",             64, INSN_CLASS_THEAD_C,  "d,s,XI6@26,XI6@20",   MATCH_EXT, MASK_EXT, match_opcode, 0 },
> +{"th.ext",             32, INSN_CLASS_THEAD_E,  "d,s,XI5@26,XI5@20",   MATCH_EXT, (MASK_EXT | (1U<<25) | (1U<<31)), match_opcode, 0 },
> +{"th.extu",            64, INSN_CLASS_THEAD_C,  "d,s,XI6@26,XI6@20",   MATCH_EXTU, MASK_EXTU, match_opcode, 0 },
> +{"th.extu",            32, INSN_CLASS_THEAD_E,  "d,s,XI5@26,XI5@20",   MATCH_EXTU, (MASK_EXTU | (1U<<25) | (1U<<31)), match_opcode, 0 },
> +{"th.ff1",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s",   MATCH_FF1, MASK_FF1, match_opcode, 0},
> +{"th.ff0",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s",   MATCH_FF0, MASK_FF1, match_opcode, 0},
> +{"th.rev",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s",   MATCH_REV, MASK_REV, match_opcode, 0},
> +{"th.lrb",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_LRB, MASK_LRB, match_opcode, 0 },
> +{"th.lrbu",            0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_LRBU, MASK_LRBU, match_opcode, 0 },
> +{"th.lrh",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_LRH, MASK_LRH, match_opcode, 0 },
> +{"th.lrhu",            0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_LRHU, MASK_LRHU, match_opcode, 0 },
> +{"th.lrw",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_LRW, MASK_LRW, match_opcode, 0 },
> +{"th.lrwu",            0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_LRWU, MASK_LRWU, match_opcode, 0 },
> +{"th.srb",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_SRB, MASK_SRB, match_opcode, 0 },
> +{"th.srh",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_SRH, MASK_SRH, match_opcode, 0 },
> +{"th.srw",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_SRW, MASK_SRW, match_opcode, 0 },
> +{"th.lrd",             0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LRD, MASK_LRD, match_opcode, 0 },
> +{"th.srd",             0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_SRD, MASK_SRD, match_opcode, 0 },
> +{"th.lurb",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LURB, MASK_LURB, match_opcode, 0 },
> +{"th.lurbu",           0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LURBU, MASK_LURBU, match_opcode, 0 },
> +{"th.lurh",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LURH, MASK_LURH, match_opcode, 0 },
> +{"th.lurhu",           0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LURHU, MASK_LURHU, match_opcode, 0 },
> +{"th.lurw",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LURW, MASK_LURW, match_opcode, 0 },
> +{"th.lurwu",           0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LURWU, MASK_LURWU, match_opcode, 0 },
> +{"th.lurd",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LURD, MASK_LURD, match_opcode, 0 },
> +{"th.surb",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_SURB, MASK_SURB, match_opcode, 0 },
> +{"th.surh",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_SURH, MASK_SURH, match_opcode, 0 },
> +{"th.surw",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_SURW, MASK_SURW, match_opcode, 0 },
> +{"th.surd",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_SURD, MASK_SURD, match_opcode, 0 },
> +{"th.tst",             64, INSN_CLASS_THEAD_C,  "d,s,XI6@20",   MATCH_TST, MASK_TST, match_opcode, 0 },
> +{"th.tst",             32, INSN_CLASS_THEAD_E,   "d,s,XI5@20",   MATCH_TST, (MASK_TST | (1U << 25)), match_opcode, INSN_ALIAS},
> +{"th.srriw",           0, INSN_CLASS_THEAD_C,   "d,s,XI5@20",   MATCH_SRRIW, MASK_SRRIW, match_opcode, 0 },
> +{"th.srri",            0, INSN_CLASS_THEAD_C_OR_E,   "d,s,XI6@20",   MATCH_SRRI, MASK_SRRI, match_opcode, 0 },
> +{"th.addsl",           0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25", MATCH_ADDSL, MASK_ADDSL, match_opcode, 0 },
> +{"th.lwd",             0, INSN_CLASS_THEAD_C,   "d,t,(s),XI2@25", MATCH_LWD, MASK_LWD, match_thead_rd1_rd2_neq_rs1, 0 },
> +{"th.ldd",             0, INSN_CLASS_THEAD_C,   "d,t,(s),XI2@25", MATCH_LDD, MASK_LDD, match_thead_rd1_rd2_neq_rs1, 0 },
> +{"th.swd",             0, INSN_CLASS_THEAD_C,   "d,t,(s),XI2@25", MATCH_SWD, MASK_SWD, match_opcode, 0 },
> +{"th.sdd",             0, INSN_CLASS_THEAD_C,   "d,t,(s),XI2@25", MATCH_SDD, MASK_SDD, match_opcode, 0 },
> +{"th.sdia",            0, INSN_CLASS_THEAD_C,   "d,(s),XS5@20,XI2@25", MATCH_SDIA, MASK_SDIA, match_opcode, 0 },
> +{"th.sdib",            0, INSN_CLASS_THEAD_C,   "d,(s),XS5@20,XI2@25", MATCH_SDIB, MASK_SDIB, match_opcode, 0 },
> +{"th.lwud",            0, INSN_CLASS_THEAD_C,   "d,t,(s),XI2@25", MATCH_LWUD, MASK_LWUD, match_thead_rd1_rd2_neq_rs1, 0 },
> +{"th.swia",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_SWIA, MASK_SWIA, match_opcode, 0},
> +{"th.swib",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_SWIB, MASK_SWIB, match_opcode, 0},
> +{"th.shia",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_SHIA, MASK_SHIA, match_opcode, 0},
> +{"th.shib",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_SHIB, MASK_SHIB, match_opcode, 0},
> +{"th.sbia",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_SBIA, MASK_SBIA, match_opcode, 0},
> +{"th.sbib",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_SBIB, MASK_SBIB, match_opcode, 0},
> +{"th.lwuia",           0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LWUIA, MASK_LWUIA, match_opcode, 0},
> +{"th.lwuib",           0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LWUIB, MASK_LWUIB, match_opcode, 0},
> +{"th.lhuia",           0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LHUIA, MASK_LHUIA, match_opcode, 0},
> +{"th.lhuib",           0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LHUIB, MASK_LHUIB, match_opcode, 0},
> +{"th.lbuia",           0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LBUIA, MASK_LBUIA, match_opcode, 0},
> +{"th.lbuib",           0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LBUIB, MASK_LBUIB, match_opcode, 0},
> +{"th.ldia",            0, INSN_CLASS_THEAD_C,   "d,(s),XS5@20,XI2@25", MATCH_LDIA, MASK_LDIA, match_opcode, 0},
> +{"th.ldib",            0, INSN_CLASS_THEAD_C,   "d,(s),XS5@20,XI2@25", MATCH_LDIB, MASK_LDIB, match_opcode, 0},
> +{"th.lwia",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LWIA, MASK_LWIA, match_opcode, 0},
> +{"th.lwib",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LWIB, MASK_LWIB, match_opcode, 0},
> +{"th.lhia",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LHIA, MASK_LHIA, match_opcode, 0},
> +{"th.lhib",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LHIB, MASK_LHIB, match_opcode, 0},
> +{"th.lbia",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LBIA, MASK_LBIA, match_opcode, 0},
> +{"th.lbib",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LBIB, MASK_LBIB, match_opcode, 0},
> +{"th.fsurd",           0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FSURD, MASK_FSURD, match_opcode, 0},
> +{"th.revw",            0, INSN_CLASS_THEAD_C,   "d,s", MATCH_REVW, MASK_REVW, match_opcode, 0},
> +{"th.fsurw",           0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FSURW, MASK_FSURW, match_opcode, 0},
> +{"th.flurd",           0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FLURD, MASK_FLURD, match_opcode, 0},
> +{"th.flurw",           0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FLURW, MASK_FLURW, match_opcode, 0},
> +{"th.fsrd",            0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FSRD, MASK_FSRD, match_opcode, 0},
> +{"th.fsrw",            0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FSRW, MASK_FSRW, match_opcode, 0},
> +{"th.flrd",            0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FLRD, MASK_FLRD, match_opcode, 0},
> +{"th.flrw",            0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FLRW, MASK_FLRW, match_opcode, 0},
> +{"th.ipush",           0, INSN_CLASS_THEAD_E,   "",  MATCH_IPUSH, MASK_IPUSH, match_opcode, 0},
> +{"th.ipop",            0, INSN_CLASS_THEAD_E,   "",  MATCH_IPOP, MASK_IPOP, match_opcode, 0},
> +{"th.fmv.x.hw",        32, INSN_CLASS_THEAD_E,  "d,S",  MATCH_FMV_X_HW, MASK_FMV_X_HW, match_opcode, 0},
> +{"th.fmv.hw.x",        32, INSN_CLASS_THEAD_E,  "D,s",  MATCH_FMV_HW_X, MASK_FMV_HW_X, match_opcode, 0},
> +
>  /* Terminate the list.  */
>  {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}
>  };
> --
> 2.34.1
>

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

* Re: [PATCH] RISC-V/t-head: Add CSRs and opcodes of the T-HEAD XUANTIE CPUs
  2022-07-29  0:28 ` Kito Cheng
@ 2022-07-29  8:43   ` Jojo R
  2022-07-29  9:19   ` Lifang Xia
  1 sibling, 0 replies; 4+ messages in thread
From: Jojo R @ 2022-07-29  8:43 UTC (permalink / raw)
  To: Kito Cheng, Palmer Dabbelt; +Cc: Binutils, Christoph Muellner, Lifang Xia


在 2022/7/29 上午8:28, Kito Cheng 写道:
> Hi Palmer
>
> They are trying to reorg the structure of their extensions as I know,
> so the extension name might be obsolete now?
>
> https://github.com/riscv-non-isa/riscv-toolchain-conventions/pull/19
>
> Hi Jojo, Li-Fan:
>
> Could you confirm that?

Hi,

Yes, there are some changes for our ISAs, and @cmuellner has made a 
draft version of english ISA manual,

we can follow it as specification of T-HEAD ISAs.

>
> Thanks
>
> On Fri, Jul 29, 2022 at 6:08 AM Palmer Dabbelt <palmer@rivosinc.com> wrote:
>> From: Lifang Xia <lifang_xia@c-sky.com>
>>
>> Add CSRs and opcodes of the XUANTIE CPUs, extensions named "theadc",
>> "xtheade" and "xtheadse".
>>
>> bfd/ChangeLog
>>
>>          * cpu-riscv.h (riscv_spec_class) <VENDOR_SPEC_CLASS_THEAD>: New
>>          value.
>>          * elfxx-riscv.c (riscv_supported_custom_ext): New table.
>>          (riscv_all_supported_ext): Add riscv_supported_custom_ext.
>>          (riscv_recognized_prefixed_ext): Update comment.
>>          (riscv_get_default_ext_version): Add the t-head extensions.
>>          (riscv_multi_subset_supports): Likewise.
>>          (riscv_multi_subset_supports_ext): Likewise.
>>
>> gas/ChangeLog
>>
>>          * config/tc-riscv.c (riscv_csr_class) <CSR_CLASS_THEAD>: New
>>          value.
>>          (riscv_csr_address): Add CSR_CLASS_THEAD.
>>          (validate_riscv_insn): Add the XI and XS formats.
>>          (riscv_ip): Likewise.
>>
>> gas/testsuite/ChangeLog
>>
>>          * gas/riscv/thead-csr-list.d: New test.
>>          * gas/riscv/theadc-ext.d: Likewise.
>>          * gas/riscv/theadc-ext.s: Likewise.
>>          * gas/riscv/theade-ext.d: Likewise.
>>          * gas/riscv/theade-ext.s: Likewise.
>>
>> include/ChangeLog
>>
>>          * opcode/iscv-opc-thead.h: New file.
>>
>> opcodes/ChangeLog
>>
>>          * riscv-dis.c (print_insn_args): Support XI and XS formats.
>>          * riscv-opc.c (match_thead_rd1_rd2_neq_rs1): New function.
>>          (riscv_opcodes): Add the t-thead extensions.
>> ---
>> I cherry-picked this off Nelson's integration branch at sourceware, and
>> then went through it a bit to avoid the dependencies on the experimental
>> extension handling (and also just some cleanups).  This should be
>> functionally the same as what was originally posted, aside from having
>> the "th." prefix on instructions and the "th_" prefix on CSRs.
>>
>> This passes the tests, but I don't currently have any other way to
>> verify it.
>> ---
>>   bfd/cpu-riscv.h                          |   3 +
>>   bfd/elfxx-riscv.c                        |  43 +-
>>   gas/config/tc-riscv.c                    |  85 ++++
>>   gas/testsuite/gas/riscv/thead-csr-list.d | 107 +++++
>>   gas/testsuite/gas/riscv/thead-csr-list.s |  98 ++++
>>   gas/testsuite/gas/riscv/theadc-ext.d     | 112 +++++
>>   gas/testsuite/gas/riscv/theadc-ext.s     | 115 +++++
>>   gas/testsuite/gas/riscv/theade-ext.d     |  62 +++
>>   gas/testsuite/gas/riscv/theade-ext.s     |  66 +++
>>   include/opcode/riscv-opc-thead.h         | 571 +++++++++++++++++++++++
>>   include/opcode/riscv-opc.h               |   2 +
>>   include/opcode/riscv.h                   |  21 +
>>   opcodes/riscv-dis.c                      |  24 +
>>   opcodes/riscv-opc.c                      | 124 +++++
>>   14 files changed, 1428 insertions(+), 5 deletions(-)
>>   create mode 100644 gas/testsuite/gas/riscv/thead-csr-list.d
>>   create mode 100644 gas/testsuite/gas/riscv/thead-csr-list.s
>>   create mode 100644 gas/testsuite/gas/riscv/theadc-ext.d
>>   create mode 100644 gas/testsuite/gas/riscv/theadc-ext.s
>>   create mode 100644 gas/testsuite/gas/riscv/theade-ext.d
>>   create mode 100644 gas/testsuite/gas/riscv/theade-ext.s
>>   create mode 100644 include/opcode/riscv-opc-thead.h
>>
>> diff --git a/bfd/cpu-riscv.h b/bfd/cpu-riscv.h
>> index ff037d127e2..3e0839fec3c 100644
>> --- a/bfd/cpu-riscv.h
>> +++ b/bfd/cpu-riscv.h
>> @@ -34,6 +34,9 @@ enum riscv_spec_class
>>     PRIV_SPEC_CLASS_1P11,
>>     PRIV_SPEC_CLASS_1P12,
>>     PRIV_SPEC_CLASS_DRAFT,
>> +
>> +  /* Vendor spec for T_HEAD XuanTie.  */
>> +  VENDOR_SPEC_CLASS_THEAD,
>>   };
>>
>>   struct riscv_spec
>> diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
>> index 0b2021f5cc7..2af0917381e 100644
>> --- a/bfd/elfxx-riscv.c
>> +++ b/bfd/elfxx-riscv.c
>> @@ -1245,12 +1245,21 @@ static struct riscv_supported_ext riscv_supported_std_zxm_ext[] =
>>     {NULL, 0, 0, 0, 0}
>>   };
>>
>> +static struct riscv_supported_ext riscv_supported_custom_ext[] =
>> +{
>> +  {"xtheadc",          VENDOR_SPEC_CLASS_THEAD,        2, 0, 0 },
>> +  {"xtheade",          VENDOR_SPEC_CLASS_THEAD,        2, 0, 0 },
>> +  {"xtheadse",         VENDOR_SPEC_CLASS_THEAD,        2, 0, 0 },
>> +  {NULL, 0, 0, 0, 0}
>> +};
>> +
>>   const struct riscv_supported_ext *riscv_all_supported_ext[] =
>>   {
>>     riscv_supported_std_ext,
>>     riscv_supported_std_z_ext,
>>     riscv_supported_std_s_ext,
>>     riscv_supported_std_zxm_ext,
>> +  riscv_supported_custom_ext,
>>     NULL
>>   };
>>
>> @@ -1331,7 +1340,8 @@ riscv_recognized_prefixed_ext (const char *ext)
>>     case RV_ISA_CLASS_S:
>>       return riscv_known_prefixed_ext (ext, riscv_supported_std_s_ext);
>>     case RV_ISA_CLASS_X:
>> -    /* Only the single x is unrecognized.  */
>> +    /* For compatibility this pretends to support any X extension except the
>> +       single letter "x". */
>>       if (strcmp (ext, "x") != 0)
>>         return true;
>>     default:
>> @@ -1504,10 +1514,9 @@ riscv_get_default_ext_version (enum riscv_spec_class *default_isa_spec,
>>     switch (class)
>>       {
>>       case RV_ISA_CLASS_ZXM: table = riscv_supported_std_zxm_ext; break;
>> -    case RV_ISA_CLASS_Z: table = riscv_supported_std_z_ext; break;
>> -    case RV_ISA_CLASS_S: table = riscv_supported_std_s_ext; break;
>> -    case RV_ISA_CLASS_X:
>> -      break;
>> +    case RV_ISA_CLASS_Z: table = riscv_supported_std_z_ext;     break;
>> +    case RV_ISA_CLASS_S: table = riscv_supported_std_s_ext;     break;
>> +    case RV_ISA_CLASS_X: table = riscv_supported_custom_ext;    break;
>>       default:
>>         table = riscv_supported_std_ext;
>>       }
>> @@ -1517,6 +1526,7 @@ riscv_get_default_ext_version (enum riscv_spec_class *default_isa_spec,
>>       {
>>         if (strcmp (table[i].name, name) == 0
>>            && (table[i].isa_spec_class == ISA_SPEC_CLASS_DRAFT
>> +             || table[i].isa_spec_class == VENDOR_SPEC_CLASS_THEAD
>>                || table[i].isa_spec_class == *default_isa_spec))
>>          {
>>            *major_version = table[i].major_version;
>> @@ -2402,6 +2412,19 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
>>         return riscv_subset_supports (rps, "svinval");
>>       case INSN_CLASS_H:
>>         return riscv_subset_supports (rps, "h");
>> +    case INSN_CLASS_THEAD_C:
>> +      return riscv_subset_supports (rps, "xtheadc");
>> +    case INSN_CLASS_THEAD_E:
>> +      return riscv_subset_supports (rps, "xtheade");
>> +    case INSN_CLASS_THEAD_SE:
>> +      return riscv_subset_supports (rps, "xtheadse");
>> +    case INSN_CLASS_THEAD_C_OR_E:
>> +      return (riscv_subset_supports (rps, "xtheadc")
>> +             || riscv_subset_supports (rps, "xtheade"));
>> +    case INSN_CLASS_THEAD_C_OR_E_OR_SE:
>> +      return (riscv_subset_supports (rps, "xtheadc")
>> +             || riscv_subset_supports (rps, "xtheade")
>> +             || riscv_subset_supports (rps, "xtheadse"));
>>       default:
>>         rps->error_handler
>>           (_("internal: unreachable INSN_CLASS_*"));
>> @@ -2527,6 +2550,16 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
>>         return "svinval";
>>       case INSN_CLASS_H:
>>         return _("h");
>> +    case INSN_CLASS_THEAD_C:
>> +      return "xtheadc";
>> +    case INSN_CLASS_THEAD_E:
>> +      return "xtheade";
>> +    case INSN_CLASS_THEAD_SE:
>> +      return "xtheadse";
>> +    case INSN_CLASS_THEAD_C_OR_E:
>> +      return _("xtheadc' or `xtheade");
>> +    case INSN_CLASS_THEAD_C_OR_E_OR_SE:
>> +      return _("xtheadc' or `xtheade' or `xtheadse");
>>       default:
>>         rps->error_handler
>>           (_("internal: unreachable INSN_CLASS_*"));
>> diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
>> index 291d07f6d8f..8a473d4b3fe 100644
>> --- a/gas/config/tc-riscv.c
>> +++ b/gas/config/tc-riscv.c
>> @@ -78,6 +78,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_THEAD,             /* vendor CSR for T-HEAD */
>>   };
>>
>>   /* This structure holds all restricted conditions for a CSR.  */
>> @@ -965,6 +966,9 @@ riscv_csr_address (const char *csr_name,
>>         break;
>>       case CSR_CLASS_DEBUG:
>>         break;
>> +    case CSR_CLASS_THEAD:
>> +      extension = "xthead";
>> +      break;
>>       default:
>>         as_bad (_("internal: bad RISC-V CSR class (0x%x)"), csr_class);
>>       }
>> @@ -1253,6 +1257,30 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
>>                  goto unknown_validate_operand;
>>              }
>>            break;
>> +       case 'X': /* Opcode for custom instructions.  */
>> +         {
>> +           int nbit, at, n;
>> +           if (sscanf(oparg, "XI%d@%d%n", &nbit, &at, &n) == 2)
>> +             {
>> +               used_bits |= ENCODE_VENDOR_THEAD_IMM ((1ULL << nbit) - 1,
>> +                                                     nbit, at);
>> +               oparg += n - 1;
>> +             }
>> +           else if (sscanf(oparg, "XS%d@%d%n", &nbit, &at, &n) == 2)
>> +             {
>> +               used_bits |= ENCODE_VENDOR_THEAD_SIGN_IMM ((1ULL << nbit) - 1,
>> +                                                          nbit, at);
>> +               oparg += n - 1;
>> +             }
>> +           else
>> +             {
>> +               as_bad (_("internal: bad X opcode type `%s'"),
>> +                       oparg);
>> +               return false;
>> +             }
>> +         }
>> +         break;
>> +
>>          default:
>>          unknown_validate_operand:
>>            as_bad (_("internal: bad RISC-V opcode "
>> @@ -3265,6 +3293,63 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
>>                asarg = expr_end;
>>                continue;
>>
>> +           case 'X': /* Vendor-specific.  */
>> +             {
>> +               int nbit, at, n;
>> +               if (sscanf(oparg, "XI%d@%d%n", &nbit, &at, &n) == 2)
>> +                 {
>> +                   my_getExpression (imm_expr, asarg);
>> +                   if (imm_expr->X_op != O_constant)
>> +                     {
>> +                       as_bad (_("non-constant operand"));
>> +                       break;
>> +                     }
>> +
>> +                   if (!VALID_VENDOR_THEAD_IMM (imm_expr->X_add_number, nbit, at))
>> +                     {
>> +                       as_bad (_("invalid immediate"));
>> +                       break;
>> +                     }
>> +
>> +                   ip->insn_opcode |=
>> +                     ENCODE_VENDOR_THEAD_IMM (imm_expr->X_add_number, nbit, at);
>> +                   asarg = expr_end;
>> +                   imm_expr->X_op = O_absent;
>> +                   oparg += n - 1;
>> +                   continue;
>> +                 }
>> +               else if (sscanf(oparg, "XS%d@%d%n", &nbit, &at, &n) == 2)
>> +                 {
>> +                   my_getExpression (imm_expr, asarg);
>> +                   if (imm_expr->X_op != O_constant)
>> +                     {
>> +                       as_bad (_("non-constant operand"));
>> +                       break;
>> +                     }
>> +
>> +                   if (!VALID_VENDOR_THEAD_SIGN_IMM (imm_expr->X_add_number, nbit, at))
>> +                     {
>> +                       as_bad (_("invalid immediate"));
>> +                       break;
>> +                     }
>> +
>> +                   ip->insn_opcode |=
>> +                     ENCODE_VENDOR_THEAD_SIGN_IMM (imm_expr->X_add_number, nbit, at);
>> +                   asarg = expr_end;
>> +                   imm_expr->X_op = O_absent;
>> +                   oparg += n - 1;
>> +                   continue;
>> +                 }
>> +
>> +               else
>> +                 {
>> +                   as_fatal (_("internal: unknown X argument type `%s'"),
>> +                             opargStart);
>> +                   break;
>> +                 }
>> +               continue;
>> +             }
>> +
>>              default:
>>              unknown_riscv_ip_operand:
>>                as_fatal (_("internal: unknown argument type `%s'"),
>> diff --git a/gas/testsuite/gas/riscv/thead-csr-list.d b/gas/testsuite/gas/riscv/thead-csr-list.d
>> new file mode 100644
>> index 00000000000..08bda4d24ea
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/thead-csr-list.d
>> @@ -0,0 +1,107 @@
>> +#as: -march=rv64gcxtheadc
>> +#objdump: -dr
>> +
>> +.*:[   ]+file format .*
>> +
>> +
>> +Disassembly of section .text:
>> +
>> +0000000000000000 <.text>:
>> +   0:  7c002573                csrr    a0,th_mxstatus
>> +   4:  7c102573                csrr    a0,th_mhcr
>> +   8:  7c202573                csrr    a0,th_mcor
>> +   c:  7c302573                csrr    a0,th_mccr2
>> +  10:  7c402573                csrr    a0,th_mcer2
>> +  14:  7c502573                csrr    a0,th_mhint
>> +  18:  7c602573                csrr    a0,th_mrmr
>> +  1c:  7c702573                csrr    a0,th_mrvbr
>> +  20:  7c802573                csrr    a0,th_mcer
>> +  24:  7c902573                csrr    a0,th_mcounterwen
>> +  28:  7ca02573                csrr    a0,th_mcounterinten
>> +  2c:  7cb02573                csrr    a0,th_mcounterof
>> +  30:  7cc02573                csrr    a0,th_mhint2
>> +  34:  7cd02573                csrr    a0,th_mhint3
>> +  38:  7e002573                csrr    a0,th_mraddr
>> +  3c:  7e102573                csrr    a0,th_mexstatus
>> +  40:  7e202573                csrr    a0,th_mnmicause
>> +  44:  7e302573                csrr    a0,th_mnmipc
>> +  48:  7f002573                csrr    a0,th_mhpmcr
>> +  4c:  7f102573                csrr    a0,th_mhpmsr
>> +  50:  7f202573                csrr    a0,th_mhpmer
>> +  54:  7f302573                csrr    a0,th_msmpr
>> +  58:  7f402573                csrr    a0,th_mteecfg
>> +  5c:  7d102573                csrr    a0,th_usp
>> +  60:  7d202573                csrr    a0,th_mcins
>> +  64:  7d302573                csrr    a0,th_mcindex
>> +  68:  7d402573                csrr    a0,th_mcdata0
>> +  6c:  7d502573                csrr    a0,th_mcdata1
>> +  70:  7d602573                csrr    a0,th_meicr
>> +  74:  7d702573                csrr    a0,th_meicr2
>> +  78:  be002573                csrr    a0,th_mebr
>> +  7c:  be102573                csrr    a0,th_nt_mstatus
>> +  80:  be302573                csrr    a0,th_nt_mtvec
>> +  84:  be202573                csrr    a0,th_nt_mie
>> +  88:  be402573                csrr    a0,th_nt_mtvt
>> +  8c:  be502573                csrr    a0,th_nt_mepc
>> +  90:  be602573                csrr    a0,th_nt_mcause
>> +  94:  be702573                csrr    a0,th_nt_mip
>> +  98:  be802573                csrr    a0,th_nt_mintstate
>> +  9c:  be902573                csrr    a0,th_nt_mxstatus
>> +  a0:  bea02573                csrr    a0,th_nt_mebr
>> +  a4:  beb02573                csrr    a0,th_nt_msp
>> +  a8:  bec02573                csrr    a0,th_t_usp
>> +  ac:  bed02573                csrr    a0,th_t_mdcr
>> +  b0:  bee02573                csrr    a0,th_t_mpcr
>> +  b4:  bef02573                csrr    a0,th_pmpteecfg
>> +  b8:  fc002573                csrr    a0,th_mcpuid
>> +  bc:  fc102573                csrr    a0,th_mapbaddr
>> +  c0:  fc202573                csrr    a0,th_mwmsr
>> +  c4:  80002573                csrr    a0,th_fxcr
>> +  c8:  9c002573                csrr    a0,th_smir
>> +  cc:  9c102573                csrr    a0,th_smel
>> +  d0:  9c202573                csrr    a0,th_smeh
>> +  d4:  9c302573                csrr    a0,th_smcir
>> +  d8:  5c002573                csrr    a0,th_sxstatus
>> +  dc:  5c102573                csrr    a0,th_shcr
>> +  e0:  5c202573                csrr    a0,th_scer2
>> +  e4:  5c302573                csrr    a0,th_scer
>> +  e8:  5c402573                csrr    a0,th_scounterinten
>> +  ec:  5c502573                csrr    a0,th_scounterof
>> +  f0:  5c602573                csrr    a0,th_shint
>> +  f4:  5c702573                csrr    a0,th_shint2
>> +  f8:  5c802573                csrr    a0,th_shpminhibit
>> +  fc:  5c902573                csrr    a0,th_shpmcr
>> + 100:  5ca02573                csrr    a0,th_shpmsr
>> + 104:  5cb02573                csrr    a0,th_shpmer
>> + 108:  5e002573                csrr    a0,th_scycle
>> + 10c:  5e102573                csrr    a0,th_shpmcounter1
>> + 110:  5e202573                csrr    a0,th_shpmcounter2
>> + 114:  5e302573                csrr    a0,th_shpmcounter3
>> + 118:  5e402573                csrr    a0,th_shpmcounter4
>> + 11c:  5e502573                csrr    a0,th_shpmcounter5
>> + 120:  5e602573                csrr    a0,th_shpmcounter6
>> + 124:  5e702573                csrr    a0,th_shpmcounter7
>> + 128:  5e802573                csrr    a0,th_shpmcounter8
>> + 12c:  5e902573                csrr    a0,th_shpmcounter9
>> + 130:  5ea02573                csrr    a0,th_shpmcounter10
>> + 134:  5eb02573                csrr    a0,th_shpmcounter11
>> + 138:  5ec02573                csrr    a0,th_shpmcounter12
>> + 13c:  5ed02573                csrr    a0,th_shpmcounter13
>> + 140:  5ee02573                csrr    a0,th_shpmcounter14
>> + 144:  5ef02573                csrr    a0,th_shpmcounter15
>> + 148:  5f002573                csrr    a0,th_shpmcounter16
>> + 14c:  5f102573                csrr    a0,th_shpmcounter17
>> + 150:  5f202573                csrr    a0,th_shpmcounter18
>> + 154:  5f302573                csrr    a0,th_shpmcounter19
>> + 158:  5f402573                csrr    a0,th_shpmcounter20
>> + 15c:  5f502573                csrr    a0,th_shpmcounter21
>> + 160:  5f602573                csrr    a0,th_shpmcounter22
>> + 164:  5f702573                csrr    a0,th_shpmcounter23
>> + 168:  5f802573                csrr    a0,th_shpmcounter24
>> + 16c:  5f902573                csrr    a0,th_shpmcounter25
>> + 170:  5fa02573                csrr    a0,th_shpmcounter26
>> + 174:  5fb02573                csrr    a0,th_shpmcounter27
>> + 178:  5fc02573                csrr    a0,th_shpmcounter28
>> + 17c:  5fd02573                csrr    a0,th_shpmcounter29
>> + 180:  5fe02573                csrr    a0,th_shpmcounter30
>> + 184:  5ff02573                csrr    a0,th_shpmcounter31
>> diff --git a/gas/testsuite/gas/riscv/thead-csr-list.s b/gas/testsuite/gas/riscv/thead-csr-list.s
>> new file mode 100644
>> index 00000000000..0784179683d
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/thead-csr-list.s
>> @@ -0,0 +1,98 @@
>> +csrr a0, th_mxstatus
>> +csrr a0, th_mhcr
>> +csrr a0, th_mcor
>> +csrr a0, th_mccr2
>> +csrr a0, th_mcer2
>> +csrr a0, th_mhint
>> +csrr a0, th_mrmr
>> +csrr a0, th_mrvbr
>> +csrr a0, th_mcer
>> +csrr a0, th_mcounterwen
>> +csrr a0, th_mcounterinten
>> +csrr a0, th_mcounterof
>> +csrr a0, th_mhint2
>> +csrr a0, th_mhint3
>> +csrr a0, th_mraddr
>> +csrr a0, th_mexstatus
>> +csrr a0, th_mnmicause
>> +csrr a0, th_mnmipc
>> +csrr a0, th_mhpmcr
>> +csrr a0, th_mhpmsr
>> +csrr a0, th_mhpmer
>> +csrr a0, th_msmpr
>> +csrr a0, th_mteecfg
>> +csrr a0, th_usp
>> +csrr a0, th_mcins
>> +csrr a0, th_mcindex
>> +csrr a0, th_mcdata0
>> +csrr a0, th_mcdata1
>> +csrr a0, th_meicr
>> +csrr a0, th_meicr2
>> +csrr a0, th_mebr
>> +csrr a0, th_nt_mstatus
>> +csrr a0, th_nt_mtvec
>> +csrr a0, th_nt_mie
>> +csrr a0, th_nt_mtvt
>> +csrr a0, th_nt_mepc
>> +csrr a0, th_nt_mcause
>> +csrr a0, th_nt_mip
>> +csrr a0, th_nt_mintstate
>> +csrr a0, th_nt_mxstatus
>> +csrr a0, th_nt_mebr
>> +csrr a0, th_nt_msp
>> +csrr a0, th_t_usp
>> +csrr a0, th_t_mdcr
>> +csrr a0, th_t_mpcr
>> +csrr a0, th_pmpteecfg
>> +csrr a0, th_mcpuid
>> +csrr a0, th_mapbaddr
>> +csrr a0, th_mwmsr
>> +csrr a0, th_fxcr
>> +csrr a0, th_smir
>> +csrr a0, th_smel
>> +csrr a0, th_smeh
>> +csrr a0, th_smcir
>> +csrr a0, th_sxstatus
>> +csrr a0, th_shcr
>> +csrr a0, th_scer2
>> +csrr a0, th_scer
>> +csrr a0, th_scounterinten
>> +csrr a0, th_scounterof
>> +csrr a0, th_shint
>> +csrr a0, th_shint2
>> +csrr a0, th_shpminhibit
>> +csrr a0, th_shpmcr
>> +csrr a0, th_shpmsr
>> +csrr a0, th_shpmer
>> +csrr a0, th_scycle
>> +csrr a0, th_shpmcounter1
>> +csrr a0, th_shpmcounter2
>> +csrr a0, th_shpmcounter3
>> +csrr a0, th_shpmcounter4
>> +csrr a0, th_shpmcounter5
>> +csrr a0, th_shpmcounter6
>> +csrr a0, th_shpmcounter7
>> +csrr a0, th_shpmcounter8
>> +csrr a0, th_shpmcounter9
>> +csrr a0, th_shpmcounter10
>> +csrr a0, th_shpmcounter11
>> +csrr a0, th_shpmcounter12
>> +csrr a0, th_shpmcounter13
>> +csrr a0, th_shpmcounter14
>> +csrr a0, th_shpmcounter15
>> +csrr a0, th_shpmcounter16
>> +csrr a0, th_shpmcounter17
>> +csrr a0, th_shpmcounter18
>> +csrr a0, th_shpmcounter19
>> +csrr a0, th_shpmcounter20
>> +csrr a0, th_shpmcounter21
>> +csrr a0, th_shpmcounter22
>> +csrr a0, th_shpmcounter23
>> +csrr a0, th_shpmcounter24
>> +csrr a0, th_shpmcounter25
>> +csrr a0, th_shpmcounter26
>> +csrr a0, th_shpmcounter27
>> +csrr a0, th_shpmcounter28
>> +csrr a0, th_shpmcounter29
>> +csrr a0, th_shpmcounter30
>> +csrr a0, th_shpmcounter31
>> diff --git a/gas/testsuite/gas/riscv/theadc-ext.d b/gas/testsuite/gas/riscv/theadc-ext.d
>> new file mode 100644
>> index 00000000000..b697f1b1c86
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/theadc-ext.d
>> @@ -0,0 +1,112 @@
>> +#as: -march=rv64gcxtheadc
>> +#objdump: -dr
>> +
>> +.*:[   ]+file format .*
>> +
>> +
>> +Disassembly of section .text:
>> +
>> +0000000000000000 <.text>:
>> +   0:  cff01073                csrw    0xcff,zero
>> +   4:  0010000b                th.dcache.call
>> +   8:  0030000b                th.dcache.ciall
>> +   c:  02b5000b                th.dcache.cipa  a0
>> +  10:  0235000b                th.dcache.cisw  a0
>> +  14:  0275000b                th.dcache.civa  a0
>> +  18:  0295000b                th.dcache.cpa   a0
>> +  1c:  0285000b                th.dcache.cpal1 a0
>> +  20:  0255000b                th.dcache.cva   a0
>> +  24:  0245000b                th.dcache.cval1 a0
>> +  28:  02a5000b                th.dcache.ipa   a0
>> +  2c:  0225000b                th.dcache.isw   a0
>> +  30:  0265000b                th.dcache.iva   a0
>> +  34:  0020000b                th.dcache.iall
>> +  38:  0215000b                th.dcache.csw   a0
>> +  3c:  0100000b                th.icache.iall
>> +  40:  0110000b                th.icache.ialls
>> +  44:  0305000b                th.icache.iva   a0
>> +  48:  0385000b                th.icache.ipa   a0
>> +  4c:  0160000b                th.l2cache.iall
>> +  50:  0150000b                th.l2cache.call
>> +  54:  0170000b                th.l2cache.ciall
>> +  58:  04b5000b                th.sfence.vmas  a0,a1
>> +  5c:  0180000b                th.sync
>> +  60:  01a0000b                th.sync.i
>> +  64:  0190000b                th.sync.s
>> +  68:  01b0000b                th.sync.is
>> +  6c:  02c5950b                th.addsl        a0,a1,a2,1
>> +  70:  20c5950b                th.mula a0,a1,a2
>> +  74:  22c5950b                th.muls a0,a1,a2
>> +  78:  24c5950b                th.mulaw        a0,a1,a2
>> +  7c:  26c5950b                th.mulsw        a0,a1,a2
>> +  80:  28c5950b                th.mulah        a0,a1,a2
>> +  84:  2ac5950b                th.mulsh        a0,a1,a2
>> +  88:  1105950b                th.srri a0,a1,16
>> +  8c:  1505950b                th.srriw        a0,a1,16
>> +  90:  40c5950b                th.mveqz        a0,a1,a2
>> +  94:  42c5950b                th.mvnez        a0,a1,a2
>> +  98:  8905950b                th.tst  a0,a1,16
>> +  9c:  8005950b                th.tstnbz       a0,a1
>> +  a0:  4105a50b                th.ext  a0,a1,16,16
>> +  a4:  4105b50b                th.extu a0,a1,16,16
>> +  a8:  8605950b                th.ff1  a0,a1
>> +  ac:  8405950b                th.ff0  a0,a1
>> +  b0:  8205950b                th.rev  a0,a1
>> +  b4:  9005950b                th.revw a0,a1
>> +  b8:  62b5600b                th.flrd ft0,a0,a1,1
>> +  bc:  42b5600b                th.flrw ft0,a0,a1,1
>> +  c0:  72b5600b                th.flurd        ft0,a0,a1,1
>> +  c4:  52b5600b                th.flurw        ft0,a0,a1,1
>> +  c8:  02c5c50b                th.lrb  a0,a1,a2,1
>> +  cc:  22c5c50b                th.lrh  a0,a1,a2,1
>> +  d0:  42c5c50b                th.lrw  a0,a1,a2,1
>> +  d4:  62c5c50b                th.lrd  a0,a1,a2,1
>> +  d8:  82c5c50b                th.lrbu a0,a1,a2,1
>> +  dc:  a2c5c50b                th.lrhu a0,a1,a2,1
>> +  e0:  c2c5c50b                th.lrwu a0,a1,a2,1
>> +  e4:  12c5c50b                th.lurb a0,a1,a2,1
>> +  e8:  32c5c50b                th.lurh a0,a1,a2,1
>> +  ec:  52c5c50b                th.lurw a0,a1,a2,1
>> +  f0:  72c5c50b                th.lurd a0,a1,a2,1
>> +  f4:  92c5c50b                th.lurbu        a0,a1,a2,1
>> +  f8:  b2c5c50b                th.lurhu        a0,a1,a2,1
>> +  fc:  d2c5c50b                th.lurwu        a0,a1,a2,1
>> + 100:  1af5c50b                th.lbia a0,\(a1\),15,1
>> + 104:  0af5c50b                th.lbib a0,\(a1\),15,1
>> + 108:  3af5c50b                th.lhia a0,\(a1\),15,1
>> + 10c:  2af5c50b                th.lhib a0,\(a1\),15,1
>> + 110:  5af5c50b                th.lwia a0,\(a1\),15,1
>> + 114:  4af5c50b                th.lwib a0,\(a1\),15,1
>> + 118:  7af5c50b                th.ldia a0,\(a1\),15,1
>> + 11c:  6af5c50b                th.ldib a0,\(a1\),15,1
>> + 120:  9af5c50b                th.lbuia        a0,\(a1\),15,1
>> + 124:  8af5c50b                th.lbuib        a0,\(a1\),15,1
>> + 128:  baf5c50b                th.lhuia        a0,\(a1\),15,1
>> + 12c:  aaf5c50b                th.lhuib        a0,\(a1\),15,1
>> + 130:  daf5c50b                th.lwuia        a0,\(a1\),15,1
>> + 134:  caf5c50b                th.lwuib        a0,\(a1\),15,1
>> + 138:  fab6450b                th.ldd  a0,a1,\(a2\),1
>> + 13c:  e2b6450b                th.lwd  a0,a1,\(a2\),1
>> + 140:  f2b6450b                th.lwud a0,a1,\(a2\),1
>> + 144:  62b5700b                th.fsrd ft0,a0,a1,1
>> + 148:  42b5700b                th.fsrw ft0,a0,a1,1
>> + 14c:  72b5700b                th.fsurd        ft0,a0,a1,1
>> + 150:  52b5700b                th.fsurw        ft0,a0,a1,1
>> + 154:  02c5d50b                th.srb  a0,a1,a2,1
>> + 158:  22c5d50b                th.srh  a0,a1,a2,1
>> + 15c:  42c5d50b                th.srw  a0,a1,a2,1
>> + 160:  62c5d50b                th.srd  a0,a1,a2,1
>> + 164:  12c5d50b                th.surb a0,a1,a2,1
>> + 168:  32c5d50b                th.surh a0,a1,a2,1
>> + 16c:  52c5d50b                th.surw a0,a1,a2,1
>> + 170:  72c5d50b                th.surd a0,a1,a2,1
>> + 174:  1af5d50b                th.sbia a0,\(a1\),15,1
>> + 178:  0af5d50b                th.sbib a0,\(a1\),15,1
>> + 17c:  3af5d50b                th.shia a0,\(a1\),15,1
>> + 180:  2af5d50b                th.shib a0,\(a1\),15,1
>> + 184:  5ac5d50b                th.swia a0,\(a1\),12,1
>> + 188:  4af5d50b                th.swib a0,\(a1\),15,1
>> + 18c:  7af5d50b                th.sdia a0,\(a1\),15,1
>> + 190:  6af5d50b                th.sdib a0,\(a1\),15,1
>> + 194:  fab6550b                th.sdd  a0,a1,\(a2\),1
>> + 198:  e2b6550b                th.swd  a0,a1,\(a2\),1
>> diff --git a/gas/testsuite/gas/riscv/theadc-ext.s b/gas/testsuite/gas/riscv/theadc-ext.s
>> new file mode 100644
>> index 00000000000..fda4319863b
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/theadc-ext.s
>> @@ -0,0 +1,115 @@
>> +.text
>> +
>> +th.wsc
>> +
>> +# cache ext
>> +th.dcache.call
>> +th.dcache.ciall
>> +th.dcache.cipa a0
>> +th.dcache.cisw a0
>> +th.dcache.civa a0
>> +th.dcache.cpa a0
>> +th.dcache.cpal1 a0
>> +th.dcache.cva a0
>> +th.dcache.cval1 a0
>> +th.dcache.ipa a0
>> +th.dcache.isw a0
>> +th.dcache.iva a0
>> +th.dcache.iall
>> +th.dcache.csw a0
>> +th.icache.iall
>> +th.icache.ialls
>> +th.icache.iva a0
>> +th.icache.ipa a0
>> +th.l2cache.iall
>> +th.l2cache.call
>> +th.l2cache.ciall
>> +
>> +# sync ext
>> +th.sfence.vmas       a0, a1
>> +th.sync
>> +th.sync.i
>> +th.sync.s
>> +th.sync.is
>> +
>> +# calc ext
>> +th.addsl             a0, a1, a2, 1
>> +th.mula              a0, a1, a2
>> +th.muls              a0, a1, a2
>> +th.mulaw             a0, a1, a2
>> +th.mulsw             a0, a1, a2
>> +th.mulah             a0, a1, a2
>> +th.mulsh             a0, a1, a2
>> +th.srri              a0, a1, 16
>> +th.srriw             a0, a1, 16
>> +th.mveqz             a0, a1, a2
>> +th.mvnez             a0, a1, a2
>> +
>> +# bit ext
>> +th.tst               a0, a1, 16
>> +th.tstnbz            a0, a1
>> +th.ext               a0, a1, 16, 16
>> +th.extu              a0, a1, 16, 16
>> +th.ff1               a0, a1
>> +th.ff0               a0, a1
>> +th.rev               a0, a1
>> +th.revw       a0, a1
>> +
>> +# load/store ext
>> +th.flrd       f0, a0, a1, 1
>> +th.flrw       f0, a0, a1, 1
>> +th.flurd      f0, a0, a1, 1
>> +th.flurw      f0, a0, a1, 1
>> +th.lrb               a0, a1, a2, 1
>> +th.lrh               a0, a1, a2, 1
>> +th.lrw               a0, a1, a2, 1
>> +th.lrd               a0, a1, a2, 1
>> +th.lrbu              a0, a1, a2, 1
>> +th.lrhu              a0, a1, a2, 1
>> +th.lrwu              a0, a1, a2, 1
>> +th.lurb              a0, a1, a2, 1
>> +th.lurh              a0, a1, a2, 1
>> +th.lurw              a0, a1, a2, 1
>> +th.lurd              a0, a1, a2, 1
>> +th.lurbu             a0, a1, a2, 1
>> +th.lurhu             a0, a1, a2, 1
>> +th.lurwu             a0, a1, a2, 1
>> +th.lbia       a0, (a1), 15, 1
>> +th.lbib       a0, (a1), 15, 1
>> +th.lhia       a0, (a1), 15, 1
>> +th.lhib       a0, (a1), 15, 1
>> +th.lwia       a0, (a1), 15, 1
>> +th.lwib       a0, (a1), 15, 1
>> +th.ldia       a0, (a1), 15, 1
>> +th.ldib       a0, (a1), 15, 1
>> +th.lbuia      a0, (a1), 15, 1
>> +th.lbuib      a0, (a1), 15, 1
>> +th.lhuia      a0, (a1), 15, 1
>> +th.lhuib      a0, (a1), 15, 1
>> +th.lwuia      a0, (a1), 15, 1
>> +th.lwuib      a0, (a1), 15, 1
>> +th.ldd               a0, a1, (a2), 1
>> +th.lwd               a0, a1, (a2), 1
>> +th.lwud              a0, a1, (a2), 1
>> +th.fsrd       f0, a0, a1, 1
>> +th.fsrw       f0, a0, a1, 1
>> +th.fsurd      f0, a0, a1, 1
>> +th.fsurw      f0, a0, a1, 1
>> +th.srb               a0, a1, a2, 1
>> +th.srh               a0, a1, a2, 1
>> +th.srw               a0, a1, a2, 1
>> +th.srd               a0, a1, a2, 1
>> +th.surb              a0, a1, a2, 1
>> +th.surh              a0, a1, a2, 1
>> +th.surw              a0, a1, a2, 1
>> +th.surd              a0, a1, a2, 1
>> +th.sbia              a0, (a1), 15, 1
>> +th.sbib              a0, (a1), 15, 1
>> +th.shia              a0, (a1), 15, 1
>> +th.shib              a0, (a1), 15, 1
>> +th.swia              a0, (a1), 12, 1
>> +th.swib              a0, (a1), 15, 1
>> +th.sdia              a0, (a1), 15, 1
>> +th.sdib              a0, (a1), 15, 1
>> +th.sdd               a0, a1, (a2), 1
>> +th.swd               a0, a1, (a2), 1
>> diff --git a/gas/testsuite/gas/riscv/theade-ext.d b/gas/testsuite/gas/riscv/theade-ext.d
>> new file mode 100644
>> index 00000000000..ff4234d323e
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/theade-ext.d
>> @@ -0,0 +1,62 @@
>> +#as: -march=rv32gcxtheade
>> +#objdump: -dr
>> +
>> +.*:[   ]+file format .*
>> +
>> +
>> +Disassembly of section .text:
>> +
>> +00000000 <.text>:
>> +[       ]+[0-9a-f]+:\s+cff01073                csrw    0xcff,zero
>> +[       ]+[0-9a-f]+:\s+02a5000b                th.dcache.ipa   a0
>> +[       ]+[0-9a-f]+:\s+0295000b                th.dcache.cpa   a0
>> +[       ]+[0-9a-f]+:\s+02b5000b                th.dcache.cipa  a0
>> +[       ]+[0-9a-f]+:\s+0225000b                th.dcache.isw   a0
>> +[       ]+[0-9a-f]+:\s+0215000b                th.dcache.csw   a0
>> +[       ]+[0-9a-f]+:\s+0235000b                th.dcache.cisw  a0
>> +[       ]+[0-9a-f]+:\s+0020000b                th.dcache.iall
>> +[       ]+[0-9a-f]+:\s+0010000b                th.dcache.call
>> +[       ]+[0-9a-f]+:\s+0030000b                th.dcache.ciall
>> +[       ]+[0-9a-f]+:\s+0100000b                th.icache.iall
>> +[       ]+[0-9a-f]+:\s+0385000b                th.icache.ipa   a0
>> +[       ]+[0-9a-f]+:\s+0180000b                th.sync
>> +[       ]+[0-9a-f]+:\s+01a0000b                th.sync.i
>> +[       ]+[0-9a-f]+:\s+02c5950b                th.addsl        a0,a1,a2,1
>> +[       ]+[0-9a-f]+:\s+1105950b                th.srri a0,a1,16
>> +[       ]+[0-9a-f]+:\s+20c5950b                th.mula a0,a1,a2
>> +[       ]+[0-9a-f]+:\s+28c5950b                th.mulah        a0,a1,a2
>> +[       ]+[0-9a-f]+:\s+22c5950b                th.muls a0,a1,a2
>> +[       ]+[0-9a-f]+:\s+2ac5950b                th.mulsh        a0,a1,a2
>> +[       ]+[0-9a-f]+:\s+40c5950b                th.mveqz        a0,a1,a2
>> +[       ]+[0-9a-f]+:\s+42c5950b                th.mvnez        a0,a1,a2
>> +[       ]+[0-9a-f]+:\s+4105a50b                th.ext  a0,a1,16,16
>> +[       ]+[0-9a-f]+:\s+4105b50b                th.extu a0,a1,16,16
>> +[       ]+[0-9a-f]+:\s+8605950b                th.ff1  a0,a1
>> +[       ]+[0-9a-f]+:\s+8405950b                th.ff0  a0,a1
>> +[       ]+[0-9a-f]+:\s+8205950b                th.rev  a0,a1
>> +[       ]+[0-9a-f]+:\s+8905950b                th.tst  a0,a1,16
>> +[       ]+[0-9a-f]+:\s+8005950b                th.tstnbz       a0,a1
>> +[       ]+[0-9a-f]+:\s+02c5c50b                th.lrb  a0,a1,a2,1
>> +[       ]+[0-9a-f]+:\s+22c5c50b                th.lrh  a0,a1,a2,1
>> +[       ]+[0-9a-f]+:\s+42c5c50b                th.lrw  a0,a1,a2,1
>> +[       ]+[0-9a-f]+:\s+82c5c50b                th.lrbu a0,a1,a2,1
>> +[       ]+[0-9a-f]+:\s+a2c5c50b                th.lrhu a0,a1,a2,1
>> +[       ]+[0-9a-f]+:\s+1af5c50b                th.lbia a0,\(a1\),15,1
>> +[       ]+[0-9a-f]+:\s+0af5c50b                th.lbib a0,\(a1\),15,1
>> +[       ]+[0-9a-f]+:\s+3af5c50b                th.lhia a0,\(a1\),15,1
>> +[       ]+[0-9a-f]+:\s+2af5c50b                th.lhib a0,\(a1\),15,1
>> +[       ]+[0-9a-f]+:\s+5af5c50b                th.lwia a0,\(a1\),15,1
>> +[       ]+[0-9a-f]+:\s+4af5c50b                th.lwib a0,\(a1\),15,1
>> +[       ]+[0-9a-f]+:\s+02c5d50b                th.srb  a0,a1,a2,1
>> +[       ]+[0-9a-f]+:\s+22c5d50b                th.srh  a0,a1,a2,1
>> +[       ]+[0-9a-f]+:\s+42c5d50b                th.srw  a0,a1,a2,1
>> +[       ]+[0-9a-f]+:\s+1af5d50b                th.sbia a0,\(a1\),15,1
>> +[       ]+[0-9a-f]+:\s+0af5d50b                th.sbib a0,\(a1\),15,1
>> +[       ]+[0-9a-f]+:\s+3af5d50b                th.shia a0,\(a1\),15,1
>> +[       ]+[0-9a-f]+:\s+2af5d50b                th.shib a0,\(a1\),15,1
>> +[       ]+[0-9a-f]+:\s+5ac5d50b                th.swia a0,\(a1\),12,1
>> +[       ]+[0-9a-f]+:\s+4af5d50b                th.swib a0,\(a1\),15,1
>> +[       ]+[0-9a-f]+:\s+c000150b                th.fmv.x.hw     a0,ft0
>> +[       ]+[0-9a-f]+:\s+a005100b                th.fmv.hw.x     ft0,a0
>> +[       ]+[0-9a-f]+:\s+0040000b                th.ipush
>> +[       ]+[0-9a-f]+:\s+0050000b                th.ipop
>> diff --git a/gas/testsuite/gas/riscv/theade-ext.s b/gas/testsuite/gas/riscv/theade-ext.s
>> new file mode 100644
>> index 00000000000..a56385802b1
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/theade-ext.s
>> @@ -0,0 +1,66 @@
>> +.text
>> +
>> +th.wsc
>> +
>> +# cache ext
>> +th.dcache.ipa a0
>> +th.dcache.cpa a0
>> +th.dcache.cipa a0
>> +th.dcache.isw a0
>> +th.dcache.csw a0
>> +th.dcache.cisw a0
>> +th.dcache.iall
>> +th.dcache.call
>> +th.dcache.ciall
>> +th.icache.iall
>> +th.icache.ipa a0
>> +
>> +# sync ext
>> +th.sync
>> +th.sync.i
>> +
>> +# calc ext
>> +th.addsl             a0, a1, a2, 1
>> +th.srri              a0, a1, 16
>> +th.mula              a0, a1, a2
>> +th.mulah             a0, a1, a2
>> +th.muls              a0, a1, a2
>> +th.mulsh             a0, a1, a2
>> +th.mveqz             a0, a1, a2
>> +th.mvnez             a0, a1, a2
>> +
>> +# bit ext
>> +th.ext               a0, a1, 16, 16
>> +th.extu              a0, a1, 16, 16
>> +th.ff1               a0, a1
>> +th.ff0               a0, a1
>> +th.rev               a0, a1
>> +th.tst               a0, a1, 16
>> +th.tstnbz            a0, a1
>> +
>> +# load/store ext
>> +th.lrb               a0, a1, a2, 1
>> +th.lrh               a0, a1, a2, 1
>> +th.lrw               a0, a1, a2, 1
>> +th.lrbu              a0, a1, a2, 1
>> +th.lrhu              a0, a1, a2, 1
>> +th.lbia       a0, (a1), 15, 1
>> +th.lbib       a0, (a1), 15, 1
>> +th.lhia       a0, (a1), 15, 1
>> +th.lhib       a0, (a1), 15, 1
>> +th.lwia       a0, (a1), 15, 1
>> +th.lwib       a0, (a1), 15, 1
>> +th.srb               a0, a1, a2, 1
>> +th.srh               a0, a1, a2, 1
>> +th.srw               a0, a1, a2, 1
>> +th.sbia              a0, (a1), 15, 1
>> +th.sbib              a0, (a1), 15, 1
>> +th.shia              a0, (a1), 15, 1
>> +th.shib              a0, (a1), 15, 1
>> +th.swia              a0, (a1), 12, 1
>> +th.swib              a0, (a1), 15, 1
>> +
>> +th.fmv.x.hw   a0, f0
>> +th.fmv.hw.x   f0, a0
>> +th.ipush
>> +th.ipop
>> diff --git a/include/opcode/riscv-opc-thead.h b/include/opcode/riscv-opc-thead.h
>> new file mode 100644
>> index 00000000000..98935f6b2b0
>> --- /dev/null
>> +++ b/include/opcode/riscv-opc-thead.h
>> @@ -0,0 +1,571 @@
>> +/* riscv-opcextended.h.  RISC-V extended instruction opcode.
>> +   Copyright (C) 2021 Free Software Foundation, Inc.
>> +
>> +   This file is part of GDB, GAS, and the GNU binutils.
>> +
>> +   GDB, GAS, and the GNU binutils are free software; you can redistribute
>> +   them and/or modify them under the terms of the GNU General Public
>> +   License as published by the Free Software Foundation; either version
>> +   3, or (at your option) any later version.
>> +
>> +   GDB, GAS, and the GNU binutils are distributed in the hope that they
>> +   will be useful, but WITHOUT ANY WARRANTY; without even the implied
>> +   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
>> +   the GNU General Public License for more details.
>> +
>> +   You should have received a copy of the GNU General Public License
>> +   along with this program; see the file COPYING3. If not,
>> +   see <http://www.gnu.org/licenses/>.  */
>> +
>> +#ifndef __RISCV_OPC_THEAD__
>> +#define __RISCV_OPC_THEAD__
>> +/* Opcodes for T-HEAD.  */
>> +#define MATCH_DCACHE_CALL      0x0010000b
>> +#define MASK_DCACHE_CALL       0xffffffff
>> +#define MATCH_DCACHE_IALL      0x0020000b
>> +#define MASK_DCACHE_IALL       0xffffffff
>> +#define MATCH_DCACHE_CSW       0x0210000b
>> +#define MASK_DCACHE_CSW                0xfff07fff
>> +#define MATCH_DCACHE_ISW       0x0220000b
>> +#define MASK_DCACHE_ISW                0xfff07fff
>> +#define MATCH_DCACHE_CIALL     0x0030000b
>> +#define MASK_DCACHE_CIALL      0xffffffff
>> +#define MATCH_DCACHE_CISW      0x0230000b
>> +#define MASK_DCACHE_CISW       0xfff07fff
>> +#define MATCH_DCACHE_CVAL1     0x0240000b
>> +#define MASK_DCACHE_CVAL1      0xfff07fff
>> +#define MATCH_DCACHE_CVA       0x0250000b
>> +#define MASK_DCACHE_CVA                0xfff07fff
>> +#define MATCH_DCACHE_IVA       0x0260000b
>> +#define MASK_DCACHE_IVA                0xfff07fff
>> +#define MATCH_DCACHE_CIVA      0x0270000b
>> +#define MASK_DCACHE_CIVA       0xfff07fff
>> +#define MATCH_DCACHE_CPAL1     0x0280000b
>> +#define MASK_DCACHE_CPAL1      0xfff07fff
>> +#define MATCH_DCACHE_CPA       0x0290000b
>> +#define MASK_DCACHE_CPA                0xfff07fff
>> +#define MATCH_DCACHE_IPA       0x02a0000b
>> +#define MASK_DCACHE_IPA                0xfff07fff
>> +#define MATCH_DCACHE_CIPA      0x02b0000b
>> +#define MASK_DCACHE_CIPA       0xfff07fff
>> +#define MATCH_ICACHE_IALL      0x0100000b
>> +#define MASK_ICACHE_IALL       0xffffffff
>> +#define MATCH_ICACHE_IALLS     0x0110000b
>> +#define MASK_ICACHE_IALLS      0xffffffff
>> +#define MATCH_ICACHE_IVA       0x0300000b
>> +#define MASK_ICACHE_IVA                0xfff07fff
>> +#define MATCH_ICACHE_IPA       0x0380000b
>> +#define MASK_ICACHE_IPA                0xfff07fff
>> +#define MATCH_L2CACHE_CALL     0x0150000b
>> +#define MASK_L2CACHE_CALL      0xffffffff
>> +#define MATCH_L2CACHE_IALL     0x0160000b
>> +#define MASK_L2CACHE_IALL      0xffffffff
>> +#define MATCH_L2CACHE_CIALL    0x0170000b
>> +#define MASK_L2CACHE_CIALL     0xffffffff
>> +#define MATCH_SYNC             0x0180000b
>> +#define MASK_SYNC              0xffffffff
>> +#define MATCH_SYNC_S           0x0190000b
>> +#define MASK_SYNC_S            0xffffffff
>> +#define MATCH_SYNC_I           0x01a0000b
>> +#define MASK_SYNC_I            0xffffffff
>> +#define MATCH_SYNC_IS          0x01b0000b
>> +#define MASK_SYNC_IS           0xffffffff
>> +#define MATCH_SFENCE_VMAS      0x0400000b
>> +#define MASK_SFENCE_VMAS       0xfe007fff
>> +#define MATCH_TSTNBZ           0x8000100b
>> +#define MASK_TSTNBZ            0xfff0707f
>> +#define MATCH_MVEQZ            0x4000100b
>> +#define MASK_MVEQZ             0xfe00707f
>> +#define MATCH_MVNEZ            0x4200100b
>> +#define MASK_MVNEZ             0xfe00707f
>> +#define MATCH_MULA             0x2000100b
>> +#define MASK_MULA              0xfe00707f
>> +#define MATCH_MULS             0x2200100b
>> +#define MASK_MULS              0xfe00707f
>> +#define MATCH_MULAW            0x2400100b
>> +#define MASK_MULAW             0xfe00707f
>> +#define MATCH_MULSW            0x2600100b
>> +#define MASK_MULSW             0xfe00707f
>> +#define MATCH_MULAH            0x2800100b
>> +#define MASK_MULAH             0xfe00707f
>> +#define MATCH_MULSH            0x2a00100b
>> +#define MASK_MULSH             0xfe00707f
>> +#define MATCH_EXT              0x0000200b
>> +#define MASK_EXT               0x0000707f
>> +#define MATCH_EXTU             0x0000300b
>> +#define MASK_EXTU              0x0000707f
>> +#define MATCH_LRB              0x0000400b
>> +#define MASK_LRB               0xf800707f
>> +#define MATCH_LRH              0x2000400b
>> +#define MASK_LRH               0xf800707f
>> +#define MATCH_LRW              0x4000400b
>> +#define MASK_LRW               0xf800707f
>> +#define MATCH_LRD              0x6000400b
>> +#define MASK_LRD               0xf800707f
>> +#define MATCH_LRBU             0x8000400b
>> +#define MASK_LRBU              0xf800707f
>> +#define MATCH_LRHU             0xa000400b
>> +#define MASK_LRHU              0xf800707f
>> +#define MATCH_LRWU             0xc000400b
>> +#define MASK_LRWU              0xf800707f
>> +#define MATCH_LURB             0x1000400b
>> +#define MASK_LURB              0xf800707f
>> +#define MATCH_LURH             0x3000400b
>> +#define MASK_LURH              0xf800707f
>> +#define MATCH_LURW             0x5000400b
>> +#define MASK_LURW              0xf800707f
>> +#define MATCH_LURD             0x7000400b
>> +#define MASK_LURD              0xf800707f
>> +#define MATCH_LURBU            0x9000400b
>> +#define MASK_LURBU             0xf800707f
>> +#define MATCH_LURHU            0xb000400b
>> +#define MASK_LURHU             0xf800707f
>> +#define MATCH_LURWU            0xd000400b
>> +#define MASK_LURWU             0xf800707f
>> +#define MATCH_REV              0x8200100b
>> +#define MASK_REV               0xfff0707f
>> +#define MATCH_FF0              0x8400100b
>> +#define MASK_FF0               0xfff0707f
>> +#define MATCH_FF1              0x8600100b
>> +#define MASK_FF1               0xfff0707f
>> +#define MATCH_SRB              0x0000500b
>> +#define MASK_SRB               0xf800707f
>> +#define MATCH_SRH              0x2000500b
>> +#define MASK_SRH               0xf800707f
>> +#define MATCH_SRW              0x4000500b
>> +#define MASK_SRW               0xf800707f
>> +#define MATCH_SRD              0x6000500b
>> +#define MASK_SRD               0xf800707f
>> +#define MATCH_SURB             0x1000500b
>> +#define MASK_SURB              0xf800707f
>> +#define MATCH_SURH             0x3000500b
>> +#define MASK_SURH              0xf800707f
>> +#define MATCH_SURW             0x5000500b
>> +#define MASK_SURW              0xf800707f
>> +#define MATCH_SURD             0x7000500b
>> +#define MASK_SURD              0xf800707f
>> +#define MATCH_TST              0x8800100b
>> +#define MASK_TST               0xfc00707f
>> +#define MATCH_SRRIW            0x1400100b
>> +#define MASK_SRRIW             0xfe00707f
>> +#define MATCH_SRRI             0x1000100b
>> +#define MASK_SRRI              0xfc00707f
>> +#define MATCH_ADDSL            0x0000100b
>> +#define MASK_ADDSL             0xf800707f
>> +#define MATCH_SWD              0xe000500b
>> +#define MASK_SWD               0xf800707f
>> +#define MATCH_SDD              0xf800500b
>> +#define MASK_SDD               0xf800707f
>> +#define MATCH_SDIA             0x7800500b
>> +#define MASK_SDIA              0xf800707f
>> +#define MATCH_SDIB             0x6800500b
>> +#define MASK_SDIB              0xf800707f
>> +#define MATCH_SWIA             0x5800500b
>> +#define MASK_SWIA              0xf800707f
>> +#define MATCH_SWIB             0x4800500b
>> +#define MASK_SWIB              0xf800707f
>> +#define MATCH_SHIB             0x2800500b
>> +#define MASK_SHIB              0xf800707f
>> +#define MATCH_SHIA             0x3800500b
>> +#define MASK_SHIA              0xf800707f
>> +#define MATCH_SBIA             0x1800500b
>> +#define MASK_SBIA              0xf800707f
>> +#define MATCH_SBIB             0x0800500b
>> +#define MASK_SBIB              0xf800707f
>> +#define MATCH_LWUD             0xf000400b
>> +#define MASK_LWUD              0xf800707f
>> +#define MATCH_LWD              0xe000400b
>> +#define MASK_LWD               0xf800707f
>> +#define MATCH_LDD              0xf800400b
>> +#define MASK_LDD               0xf800707f
>> +#define MATCH_LWUIA            0xd800400b
>> +#define MASK_LWUIA             0xf800707f
>> +#define MATCH_LWUIB            0xc800400b
>> +#define MASK_LWUIB             0xf800707f
>> +#define MATCH_LHUIA            0xb800400b
>> +#define MASK_LHUIA             0xf800707f
>> +#define MATCH_LHUIB            0xa800400b
>> +#define MASK_LHUIB             0xf800707f
>> +#define MATCH_LBUIA            0x9800400b
>> +#define MASK_LBUIA             0xf800707f
>> +#define MATCH_LBUIB            0x8800400b
>> +#define MASK_LBUIB             0xf800707f
>> +#define MATCH_LDIA             0x7800400b
>> +#define MASK_LDIA              0xf800707f
>> +#define MATCH_LDIB             0x6800400b
>> +#define MASK_LDIB              0xf800707f
>> +#define MATCH_LWIA             0x5800400b
>> +#define MASK_LWIA              0xf800707f
>> +#define MATCH_LWIB             0x4800400b
>> +#define MASK_LWIB              0xf800707f
>> +#define MATCH_LHIA             0x3800400b
>> +#define MASK_LHIA              0xf800707f
>> +#define MATCH_LHIB             0x2800400b
>> +#define MASK_LHIB              0xf800707f
>> +#define MATCH_LBIA             0x1800400b
>> +#define MASK_LBIA              0xf800707f
>> +#define MATCH_LBIB             0x0800400b
>> +#define MASK_LBIB              0xf800707f
>> +#define MATCH_REVW             0x9000100b
>> +#define MASK_REVW              0xfff0707f
>> +#define MATCH_FSURD            0x7000700b
>> +#define MASK_FSURD             0xf800707f
>> +#define MATCH_FSURW            0x5000700b
>> +#define MASK_FSURW             0xf800707f
>> +#define MATCH_FSRD             0x6000700b
>> +#define MASK_FSRD              0xf800707f
>> +#define MATCH_FSRW             0x4000700b
>> +#define MASK_FSRW              0xf800707f
>> +#define MATCH_FLURD            0x7000600b
>> +#define MASK_FLURD             0xf800707f
>> +#define MATCH_FLURW            0x5000600b
>> +#define MASK_FLURW             0xf800707f
>> +#define MATCH_FLRD             0x6000600b
>> +#define MASK_FLRD              0xf800707f
>> +#define MATCH_FLRW             0x4000600b
>> +#define MASK_FLRW              0xf800707f
>> +#define MATCH_IPUSH            0x0040000b
>> +#define MASK_IPUSH             0xffffffff
>> +#define MATCH_IPOP             0x0050000b
>> +#define MASK_IPOP              0xffffffff
>> +/* T-HEAD security.  */
>> +#define MATCH_WSC              0xcff01073
>> +#define MASK_WSC               0xffffffff
>> +/* T-HEAD Float for rv32.  */
>> +#define MATCH_FMV_X_HW         0xc000100b
>> +#define MASK_FMV_X_HW          0xfff0707f
>> +#define MATCH_FMV_HW_X         0xa000100b
>> +#define MASK_FMV_HW_X          0xfff0707f
>> +#endif /* __RISCV_OPC_THEAD__ */
>> +#ifdef DECLARE_INSN
>> +DECLARE_INSN(th_wsc, MATCH_WSC, MASK_WSC)
>> +DECLARE_INSN(th_dcache_giall, MATCH_DCACHE_IALL, MASK_DCACHE_IALL)
>> +DECLARE_INSN(th_dcache_gcall, MATCH_DCACHE_CALL, MASK_DCACHE_CALL)
>> +DECLARE_INSN(th_dcache_gciall, MATCH_DCACHE_CIALL, MASK_DCACHE_CIALL)
>> +DECLARE_INSN(th_dcache_gisw, MATCH_DCACHE_ISW, MASK_DCACHE_ISW)
>> +DECLARE_INSN(th_dcache_gcsw, MATCH_DCACHE_CSW, MASK_DCACHE_CSW)
>> +DECLARE_INSN(th_dcache_gcisw, MATCH_DCACHE_CISW, MASK_DCACHE_CISW)
>> +DECLARE_INSN(th_dcache_giva, MATCH_DCACHE_IVA, MASK_DCACHE_IVA)
>> +DECLARE_INSN(th_dcache_gcva, MATCH_DCACHE_CVA, MASK_DCACHE_CVA)
>> +DECLARE_INSN(th_dcache_gcval1, MATCH_DCACHE_CVAL1, MASK_DCACHE_CVAL1)
>> +DECLARE_INSN(th_dcache_gciva, MATCH_DCACHE_CIVA, MASK_DCACHE_CIVA)
>> +DECLARE_INSN(th_dcache_gipa, MATCH_DCACHE_IPA, MASK_DCACHE_IPA)
>> +DECLARE_INSN(th_dcache_gcpa, MATCH_DCACHE_CPA, MASK_DCACHE_CPA)
>> +DECLARE_INSN(th_dcache_gcpal1, MATCH_DCACHE_CPAL1, MASK_DCACHE_CPAL1)
>> +DECLARE_INSN(th_dcache_gcipa, MATCH_DCACHE_CIPA, MASK_DCACHE_CIPA)
>> +DECLARE_INSN(th_icache_giall, MATCH_ICACHE_IALL, MASK_ICACHE_IALL)
>> +DECLARE_INSN(th_icache_gialls, MATCH_ICACHE_IALLS, MASK_ICACHE_IALLS)
>> +DECLARE_INSN(th_icache_giva, MATCH_ICACHE_IVA, MASK_ICACHE_IVA)
>> +DECLARE_INSN(th_icache_gipa, MATCH_ICACHE_IPA, MASK_ICACHE_IPA)
>> +DECLARE_INSN(th_l2cache_giall, MATCH_L2CACHE_IALL, MASK_L2CACHE_IALL)
>> +DECLARE_INSN(th_l2cache_gcall, MATCH_L2CACHE_CALL, MASK_L2CACHE_CALL)
>> +DECLARE_INSN(th_l2cache_gciall, MATCH_L2CACHE_CIALL, MASK_L2CACHE_CIALL)
>> +DECLARE_INSN(th_sync, MATCH_SYNC, MASK_SYNC)
>> +DECLARE_INSN(th_sync_gi, MATCH_SYNC_I, MASK_SYNC_I)
>> +DECLARE_INSN(th_sync_gs, MATCH_SYNC_S, MASK_SYNC_S)
>> +DECLARE_INSN(th_sync_gis, MATCH_SYNC_IS, MASK_SYNC_IS)
>> +DECLARE_INSN(th_tstnbz, MATCH_TSTNBZ, MASK_TSTNBZ)
>> +DECLARE_INSN(th_mula, MATCH_MULA, MASK_MULA)
>> +DECLARE_INSN(th_muls, MATCH_MULS, MASK_MULS)
>> +DECLARE_INSN(th_mulah, MATCH_MULAH, MASK_MULAH)
>> +DECLARE_INSN(th_mulsh, MATCH_MULSH, MASK_MULSH)
>> +DECLARE_INSN(th_sfence_vmas, MATCH_SFENCE_VMAS, MASK_SFENCE_VMAS)
>> +DECLARE_INSN(th_mveqz, MATCH_MVEQZ, MASK_MVEQZ)
>> +DECLARE_INSN(th_mvnez, MATCH_MVNEZ, MASK_MVNEZ)
>> +DECLARE_INSN(th_mulaw, MATCH_MULAW, MASK_MULAW)
>> +DECLARE_INSN(th_mulsw, MATCH_MULSW, MASK_MULSW)
>> +DECLARE_INSN(th_ext, MATCH_EXT, MASK_EXT)
>> +DECLARE_INSN(th_extu, MATCH_EXTU, MASK_EXTU)
>> +DECLARE_INSN(th_ff1, MATCH_FF1, MASK_FF1)
>> +DECLARE_INSN(th_ff0, MATCH_FF0, MASK_FF1)
>> +DECLARE_INSN(th_rev, MATCH_REV, MASK_REV)
>> +DECLARE_INSN(th_lrb, MATCH_LRB, MASK_LRB)
>> +DECLARE_INSN(th_lrbu, MATCH_LRBU, MASK_LRBU)
>> +DECLARE_INSN(th_lrh, MATCH_LRH, MASK_LRH)
>> +DECLARE_INSN(th_lrhu, MATCH_LRHU, MASK_LRHU)
>> +DECLARE_INSN(th_lrw, MATCH_LRW, MASK_LRW)
>> +DECLARE_INSN(th_lrwu, MATCH_LRWU, MASK_LRWU)
>> +DECLARE_INSN(th_srb, MATCH_SRB, MASK_SRB)
>> +DECLARE_INSN(th_srh, MATCH_SRH, MASK_SRH)
>> +DECLARE_INSN(th_srw, MATCH_SRW, MASK_SRW)
>> +DECLARE_INSN(th_lrd, MATCH_LRD, MASK_LRD)
>> +DECLARE_INSN(th_srd, MATCH_SRD, MASK_SRD)
>> +DECLARE_INSN(th_lurb, MATCH_LURB, MASK_LURB)
>> +DECLARE_INSN(th_lurbu, MATCH_LURBU, MASK_LURBU)
>> +DECLARE_INSN(th_lurh, MATCH_LURH, MASK_LURH)
>> +DECLARE_INSN(th_lurhu, MATCH_LURHU, MASK_LURHU)
>> +DECLARE_INSN(th_lurw, MATCH_LURW, MASK_LURW)
>> +DECLARE_INSN(th_lurwu, MATCH_LURWU, MASK_LURWU)
>> +DECLARE_INSN(th_lurd, MATCH_LURD, MASK_LURD)
>> +DECLARE_INSN(th_surb, MATCH_SURB, MASK_SURB)
>> +DECLARE_INSN(th_surh, MATCH_SURH, MASK_SURH)
>> +DECLARE_INSN(th_surw, MATCH_SURW, MASK_SURW)
>> +DECLARE_INSN(th_surd, MATCH_SURD, MASK_SURD)
>> +DECLARE_INSN(th_tst, MATCH_TST, MASK_TST)
>> +DECLARE_INSN(th_srriw, MATCH_SRRIW, MASK_SRRIW)
>> +DECLARE_INSN(th_srri, MATCH_SRRI, MASK_SRRI)
>> +DECLARE_INSN(th_addsl, MATCH_ADDSL, MASK_ADDSL)
>> +DECLARE_INSN(th_lwd, MATCH_LWD, MASK_LWD)
>> +DECLARE_INSN(th_ldd, MATCH_LDD, MASK_LDD)
>> +DECLARE_INSN(th_swd, MATCH_SWD, MASK_SWD)
>> +DECLARE_INSN(th_sdd, MATCH_SDD, MASK_SDD)
>> +DECLARE_INSN(th_sdia, MATCH_SDIA, MASK_SDIA)
>> +DECLARE_INSN(th_sdib, MATCH_SDIB, MASK_SDIB)
>> +DECLARE_INSN(th_lwud, MATCH_LWUD, MASK_LWUD)
>> +DECLARE_INSN(th_swia, MATCH_SWIA, MASK_SWIA)
>> +DECLARE_INSN(th_swib, MATCH_SWIB, MASK_SWIB)
>> +DECLARE_INSN(th_shia, MATCH_SHIA, MASK_SHIA)
>> +DECLARE_INSN(th_shib, MATCH_SHIB, MASK_SHIB)
>> +DECLARE_INSN(th_sbia, MATCH_SBIA, MASK_SBIA)
>> +DECLARE_INSN(th_sbib, MATCH_SBIB, MASK_SBIB)
>> +DECLARE_INSN(th_lwuia, MATCH_LWUIA, MASK_LWUIA)
>> +DECLARE_INSN(th_lwuib, MATCH_LWUIB, MASK_LWUIB)
>> +DECLARE_INSN(th_lhuia, MATCH_LHUIA, MASK_LHUIA)
>> +DECLARE_INSN(th_lhuib, MATCH_LHUIB, MASK_LHUIB)
>> +DECLARE_INSN(th_lbuia, MATCH_LBUIA, MASK_LBUIA)
>> +DECLARE_INSN(th_lbuib, MATCH_LBUIB, MASK_LBUIB)
>> +DECLARE_INSN(th_ldia, MATCH_LDIA, MASK_LDIA)
>> +DECLARE_INSN(th_ldib, MATCH_LDIB, MASK_LDIB)
>> +DECLARE_INSN(th_lwia, MATCH_LWIA, MASK_LWIA)
>> +DECLARE_INSN(th_lwib, MATCH_LWIB, MASK_LWIB)
>> +DECLARE_INSN(th_lhia, MATCH_LHIA, MASK_LHIA)
>> +DECLARE_INSN(th_lhib, MATCH_LHIB, MASK_LHIB)
>> +DECLARE_INSN(th_lbia, MATCH_LBIA, MASK_LBIA)
>> +DECLARE_INSN(th_lbib, MATCH_LBIB, MASK_LBIB)
>> +DECLARE_INSN(th_fsurd, MATCH_FSURD, MASK_FSURD)
>> +DECLARE_INSN(th_revw, MATCH_REVW, MASK_REVW)
>> +DECLARE_INSN(th_fsurw, MATCH_FSURW, MASK_FSURW)
>> +DECLARE_INSN(th_flurd, MATCH_FLURD, MASK_FLURD)
>> +DECLARE_INSN(th_flurw, MATCH_FLURW, MASK_FLURW)
>> +DECLARE_INSN(th_fsrd, MATCH_FSRD, MASK_FSRD)
>> +DECLARE_INSN(th_fsrw, MATCH_FSRW, MASK_FSRW)
>> +DECLARE_INSN(th_flrd, MATCH_FLRD, MASK_FLRD)
>> +DECLARE_INSN(th_flrw, MATCH_FLRW, MASK_FLRW)
>> +DECLARE_INSN(th_ipush, MATCH_IPUSH, MASK_IPUSH)
>> +DECLARE_INSN(th_ipop, MATCH_IPOP, MASK_IPOP)
>> +DECLARE_INSN(th_fmv_x_hw, MATCH_FMV_X_HW, MASK_FMV_X_HW)
>> +DECLARE_INSN(th_fmv_hw_x, MATCH_FMV_HW_X, MASK_FMV_HW_X)
>> +#endif /* DECLARE_INSN */
>> +#ifdef DECLARE_CSR
>> +/* T-HEAD M mode CSR.  */
>> +#define CSR_THEAD_MXSTATUS 0x7c0
>> +#define CSR_THEAD_MHCR 0x7c1
>> +#define CSR_THEAD_MCOR 0x7c2
>> +#define CSR_THEAD_MCCR2 0x7c3
>> +#define CSR_THEAD_MCER2 0x7c4
>> +#define CSR_THEAD_MHINT 0x7c5
>> +#define CSR_THEAD_MRMR 0x7c6
>> +#define CSR_THEAD_MRVBR 0x7c7
>> +#define CSR_THEAD_MCER 0x7c8
>> +#define CSR_THEAD_MCOUNTERWEN 0x7c9
>> +#define CSR_THEAD_MCOUNTERINTEN 0x7ca
>> +#define CSR_THEAD_MCOUNTEROF 0x7cb
>> +#define CSR_THEAD_MHINT2 0x7cc
>> +#define CSR_THEAD_MHINT3 0x7cd
>> +#define CSR_THEAD_MRADDR 0x7e0
>> +#define CSR_THEAD_MEXSTATUS 0x7e1
>> +#define CSR_THEAD_MNMICAUSE 0x7e2
>> +#define CSR_THEAD_MNMIPC 0x7e3
>> +#define CSR_THEAD_MHPMCR 0x7f0
>> +#define CSR_THEAD_MHPMSR 0x7f1
>> +#define CSR_THEAD_MHPMER 0x7f2
>> +#define CSR_THEAD_MSMPR 0x7f3
>> +#define CSR_THEAD_MTEECFG 0x7f4
>> +#define CSR_THEAD_MZONEID 0x7f5
>> +#define CSR_THEAD_ML2CPID 0x7f6
>> +#define CSR_THEAD_ML2WP 0x7f7
>> +#define CSR_THEAD_MDTCMCR 0x7f8
>> +#define CSR_THEAD_USP 0x7d1
>> +#define CSR_THEAD_MCINS 0x7d2
>> +#define CSR_THEAD_MCINDEX 0x7d3
>> +#define CSR_THEAD_MCDATA0 0x7d4
>> +#define CSR_THEAD_MCDATA1 0x7d5
>> +#define CSR_THEAD_MEICR 0x7d6
>> +#define CSR_THEAD_MEICR2 0x7d7
>> +#define CSR_THEAD_MBEADDR 0x7d8
>> +#define CSR_THEAD_MCPUID 0xfc0
>> +#define CSR_THEAD_MAPBADDR 0xfc1
>> +#define CSR_THEAD_MWMSR 0xfc2
>> +#define CSR_THEAD_MHALTCAUSE 0xfe0
>> +#define CSR_THEAD_MDBGINFO 0xfe1
>> +#define CSR_THEAD_MPCFIFO 0xfe2
>> +/* T-HEAD S mode CSR.  */
>> +#define CSR_THEAD_SXSTATUS 0x5c0
>> +#define CSR_THEAD_SHCR 0x5c1
>> +#define CSR_THEAD_SCER2 0x5c2
>> +#define CSR_THEAD_SCER 0x5c3
>> +#define CSR_THEAD_SCOUNTERINTEN 0x5c4
>> +#define CSR_THEAD_SCOUNTEROF 0x5c5
>> +#define CSR_THEAD_SHINT 0x5c6
>> +#define CSR_THEAD_SHINT2 0x5c7
>> +#define CSR_THEAD_SHPMINHIBIT 0x5c8
>> +#define CSR_THEAD_SHPMCR 0x5c9
>> +#define CSR_THEAD_SHPMSR 0x5ca
>> +#define CSR_THEAD_SHPMER 0x5cb
>> +#define CSR_THEAD_SL2CPID 0x5cc
>> +#define CSR_THEAD_SL2WP 0x5cd
>> +#define CSR_THEAD_SBEADDR 0x5d0
>> +#define CSR_THEAD_SCYCLE 0x5e0
>> +#define CSR_THEAD_SHPMCOUNTER1 0x5e1
>> +#define CSR_THEAD_SHPMCOUNTER2 0x5e2
>> +#define CSR_THEAD_SHPMCOUNTER3 0x5e3
>> +#define CSR_THEAD_SHPMCOUNTER4 0x5e4
>> +#define CSR_THEAD_SHPMCOUNTER5 0x5e5
>> +#define CSR_THEAD_SHPMCOUNTER6 0x5e6
>> +#define CSR_THEAD_SHPMCOUNTER7 0x5e7
>> +#define CSR_THEAD_SHPMCOUNTER8 0x5e8
>> +#define CSR_THEAD_SHPMCOUNTER9 0x5e9
>> +#define CSR_THEAD_SHPMCOUNTER10 0x5ea
>> +#define CSR_THEAD_SHPMCOUNTER11 0x5eb
>> +#define CSR_THEAD_SHPMCOUNTER12 0x5ec
>> +#define CSR_THEAD_SHPMCOUNTER13 0x5ed
>> +#define CSR_THEAD_SHPMCOUNTER14 0x5ee
>> +#define CSR_THEAD_SHPMCOUNTER15 0x5ef
>> +#define CSR_THEAD_SHPMCOUNTER16 0x5f0
>> +#define CSR_THEAD_SHPMCOUNTER17 0x5f1
>> +#define CSR_THEAD_SHPMCOUNTER18 0x5f2
>> +#define CSR_THEAD_SHPMCOUNTER19 0x5f3
>> +#define CSR_THEAD_SHPMCOUNTER20 0x5f4
>> +#define CSR_THEAD_SHPMCOUNTER21 0x5f5
>> +#define CSR_THEAD_SHPMCOUNTER22 0x5f6
>> +#define CSR_THEAD_SHPMCOUNTER23 0x5f7
>> +#define CSR_THEAD_SHPMCOUNTER24 0x5f8
>> +#define CSR_THEAD_SHPMCOUNTER25 0x5f9
>> +#define CSR_THEAD_SHPMCOUNTER26 0x5fa
>> +#define CSR_THEAD_SHPMCOUNTER27 0x5fb
>> +#define CSR_THEAD_SHPMCOUNTER28 0x5fc
>> +#define CSR_THEAD_SHPMCOUNTER29 0x5fd
>> +#define CSR_THEAD_SHPMCOUNTER30 0x5fe
>> +#define CSR_THEAD_SHPMCOUNTER31 0x5ff
>> +/* T-HEAD U mode CSR.  */
>> +#define CSR_THEAD_FXCR 0x800
>> +/* T-HEAD MMU extentions.  */
>> +#define CSR_THEAD_SMIR 0x9c0
>> +#define CSR_THEAD_SMEL 0x9c1
>> +#define CSR_THEAD_SMEH 0x9c2
>> +#define CSR_THEAD_SMCIR 0x9c3
>> +/* T-HEAD Security CSR(May be dropped).  */
>> +#define CSR_THEAD_MEBR 0xbe0
>> +#define CSR_THEAD_NT_MSTATUS 0xbe1
>> +#define CSR_THEAD_NT_MIE 0xbe2
>> +#define CSR_THEAD_NT_MTVEC 0xbe3
>> +#define CSR_THEAD_NT_MTVT 0xbe4
>> +#define CSR_THEAD_NT_MEPC 0xbe5
>> +#define CSR_THEAD_NT_MCAUSE 0xbe6
>> +#define CSR_THEAD_NT_MIP 0xbe7
>> +#define CSR_THEAD_NT_MINTSTATE 0xbe8
>> +#define CSR_THEAD_NT_MXSTATUS 0xbe9
>> +#define CSR_THEAD_NT_MEBR 0xbea
>> +#define CSR_THEAD_NT_MSP 0xbeb
>> +#define CSR_THEAD_T_USP 0xbec
>> +#define CSR_THEAD_T_MDCR 0xbed
>> +#define CSR_THEAD_T_MPCR 0xbee
>> +#define CSR_THEAD_PMPTEECFG 0xbef
>> +/* T-HEAD extentions.  */
>> +DECLARE_CSR(th_mxstatus, CSR_THEAD_MXSTATUS, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mhcr, CSR_THEAD_MHCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mcor, CSR_THEAD_MCOR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mccr2, CSR_THEAD_MCCR2, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mcer2, CSR_THEAD_MCER2, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mhint, CSR_THEAD_MHINT, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mrmr, CSR_THEAD_MRMR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mrvbr, CSR_THEAD_MRVBR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mcer, CSR_THEAD_MCER, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mcounterwen, CSR_THEAD_MCOUNTERWEN, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mcounterinten, CSR_THEAD_MCOUNTERINTEN, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mcounterof, CSR_THEAD_MCOUNTEROF, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mhint2, CSR_THEAD_MHINT2, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mhint3, CSR_THEAD_MHINT3, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mraddr, CSR_THEAD_MRADDR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mexstatus, CSR_THEAD_MEXSTATUS, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mnmicause, CSR_THEAD_MNMICAUSE, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mnmipc, CSR_THEAD_MNMIPC, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mhpmcr, CSR_THEAD_MHPMCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mhpmsr, CSR_THEAD_MHPMSR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mhpmer, CSR_THEAD_MHPMER, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_msmpr, CSR_THEAD_MSMPR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mteecfg, CSR_THEAD_MTEECFG, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mzoneid, CSR_THEAD_MZONEID, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_ml2cpid, CSR_THEAD_ML2CPID, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_ml2wp, CSR_THEAD_ML2WP, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mdtcmcr, CSR_THEAD_MDTCMCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_usp, CSR_THEAD_USP, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mcins, CSR_THEAD_MCINS, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mcindex, CSR_THEAD_MCINDEX, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mcdata0, CSR_THEAD_MCDATA0, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mcdata1, CSR_THEAD_MCDATA1, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_meicr, CSR_THEAD_MEICR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_meicr2, CSR_THEAD_MEICR2, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mbeaddr, CSR_THEAD_MBEADDR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mebr, CSR_THEAD_MEBR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_nt_mstatus, CSR_THEAD_NT_MSTATUS, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_nt_mtvec, CSR_THEAD_NT_MTVEC, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_nt_mie, CSR_THEAD_NT_MIE, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_nt_mtvt, CSR_THEAD_NT_MTVT, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_nt_mepc, CSR_THEAD_NT_MEPC, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_nt_mcause, CSR_THEAD_NT_MCAUSE, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_nt_mip, CSR_THEAD_NT_MIP, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_nt_mintstate, CSR_THEAD_NT_MINTSTATE, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_nt_mxstatus, CSR_THEAD_NT_MXSTATUS, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_nt_mebr, CSR_THEAD_NT_MEBR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_nt_msp, CSR_THEAD_NT_MSP, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_t_usp, CSR_THEAD_T_USP, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_t_mdcr, CSR_THEAD_T_MDCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_t_mpcr, CSR_THEAD_T_MPCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_pmpteecfg, CSR_THEAD_PMPTEECFG, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mcpuid, CSR_THEAD_MCPUID, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mapbaddr, CSR_THEAD_MAPBADDR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mwmsr, CSR_THEAD_MWMSR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_fxcr, CSR_THEAD_FXCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_smir, CSR_THEAD_SMIR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_smel, CSR_THEAD_SMEL, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_smeh, CSR_THEAD_SMEH, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_smcir, CSR_THEAD_SMCIR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_sxstatus, CSR_THEAD_SXSTATUS, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shcr, CSR_THEAD_SHCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_scer2, CSR_THEAD_SCER2, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_scer, CSR_THEAD_SCER, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_scounterinten , CSR_THEAD_SCOUNTERINTEN, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_scounterof, CSR_THEAD_SCOUNTEROF, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shint, CSR_THEAD_SHINT, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shint2, CSR_THEAD_SHINT2, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpminhibit, CSR_THEAD_SHPMINHIBIT, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcr, CSR_THEAD_SHPMCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmsr, CSR_THEAD_SHPMSR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmer, CSR_THEAD_SHPMER, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_sl2cpid, CSR_THEAD_SL2CPID, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_sl2wp, CSR_THEAD_SL2WP, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_sbeaddr, CSR_THEAD_SBEADDR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_scycle, CSR_THEAD_SCYCLE, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter1, CSR_THEAD_SHPMCOUNTER1, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter2, CSR_THEAD_SHPMCOUNTER2, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter3, CSR_THEAD_SHPMCOUNTER3, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter4, CSR_THEAD_SHPMCOUNTER4, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter5, CSR_THEAD_SHPMCOUNTER5, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter6, CSR_THEAD_SHPMCOUNTER6, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter7, CSR_THEAD_SHPMCOUNTER7, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter8, CSR_THEAD_SHPMCOUNTER8, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter9, CSR_THEAD_SHPMCOUNTER9, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter10, CSR_THEAD_SHPMCOUNTER10, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter11, CSR_THEAD_SHPMCOUNTER11, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter12, CSR_THEAD_SHPMCOUNTER12, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter13, CSR_THEAD_SHPMCOUNTER13, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter14, CSR_THEAD_SHPMCOUNTER14, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter15, CSR_THEAD_SHPMCOUNTER15, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter16, CSR_THEAD_SHPMCOUNTER16, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter17, CSR_THEAD_SHPMCOUNTER17, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter18, CSR_THEAD_SHPMCOUNTER18, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter19, CSR_THEAD_SHPMCOUNTER19, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter20, CSR_THEAD_SHPMCOUNTER20, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter21, CSR_THEAD_SHPMCOUNTER21, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter22, CSR_THEAD_SHPMCOUNTER22, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter23, CSR_THEAD_SHPMCOUNTER23, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter24, CSR_THEAD_SHPMCOUNTER24, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter25, CSR_THEAD_SHPMCOUNTER25, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter26, CSR_THEAD_SHPMCOUNTER26, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter27, CSR_THEAD_SHPMCOUNTER27, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter28, CSR_THEAD_SHPMCOUNTER28, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter29, CSR_THEAD_SHPMCOUNTER29, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter30, CSR_THEAD_SHPMCOUNTER30, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter31, CSR_THEAD_SHPMCOUNTER31, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +#endif /* DECLARE_CSR */
>> diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
>> index 88b8d7ff595..f755d0e0643 100644
>> --- a/include/opcode/riscv-opc.h
>> +++ b/include/opcode/riscv-opc.h
>> @@ -3276,3 +3276,5 @@ DECLARE_CSR_ALIAS(tmexttrigger, CSR_TDATA1, CSR_CLASS_DEBUG, PRIV_SPEC_CLASS_NON
>>   DECLARE_CSR_ALIAS(textra32, CSR_TDATA3, CSR_CLASS_DEBUG, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>>   DECLARE_CSR_ALIAS(textra64, CSR_TDATA3, CSR_CLASS_DEBUG, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>>   #endif /* DECLARE_CSR_ALIAS */
>> +
>> +#include "riscv-opc-thead.h"
>> diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
>> index b115e338a05..eff93641bae 100644
>> --- a/include/opcode/riscv.h
>> +++ b/include/opcode/riscv.h
>> @@ -397,6 +397,11 @@ enum riscv_insn_class
>>     INSN_CLASS_ZICBOP,
>>     INSN_CLASS_ZICBOZ,
>>     INSN_CLASS_H,
>> +  INSN_CLASS_THEAD_C,
>> +  INSN_CLASS_THEAD_E,
>> +  INSN_CLASS_THEAD_SE,
>> +  INSN_CLASS_THEAD_C_OR_E,
>> +  INSN_CLASS_THEAD_C_OR_E_OR_SE,
>>   };
>>
>>   /* This structure holds information for a particular instruction.  */
>> @@ -531,4 +536,20 @@ extern const char * const riscv_vma[2];
>>   extern const struct riscv_opcode riscv_opcodes[];
>>   extern const struct riscv_opcode riscv_insn_types[];
>>
>> +/* T-HEAD IMM Encoding.  */
>> +#define EXTRACT_VENDOR_THEAD_IMM(x,nbit,at) \
>> +  (RV_X(x, at, nbit))
>> +#define EXTRACT_VENDOR_THEAD_SIGN_IMM(x,nbit,at) \
>> +  (RV_X(x, at, nbit) | ((-(RV_X(x, (at+nbit-1),1))) << (nbit)))
>> +
>> +#define ENCODE_VENDOR_THEAD_IMM(x,nbit,at) \
>> +  (RV_X(x, 0, nbit) << at)
>> +#define ENCODE_VENDOR_THEAD_SIGN_IMM(x,nbit,at) \
>> +  (RV_X(x, 0, nbit) << at)
>> +
>> +#define VALID_VENDOR_THEAD_IMM(x,nbit,at) \
>> +  (EXTRACT_VENDOR_THEAD_IMM(ENCODE_VENDOR_THEAD_IMM(x,nbit,at),nbit,at) == (x))
>> +#define VALID_VENDOR_THEAD_SIGN_IMM(x,nbit,at) \
>> +  (EXTRACT_VENDOR_THEAD_SIGN_IMM(ENCODE_VENDOR_THEAD_SIGN_IMM(x,nbit,at),nbit,at) == (x))
>> +
>>   #endif /* _RISCV_H_ */
>> diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
>> index 164fd209dbd..43646cc0731 100644
>> --- a/opcodes/riscv-dis.c
>> +++ b/opcodes/riscv-dis.c
>> @@ -554,6 +554,30 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
>>            print (info->stream, dis_style_text, "%d", rs1);
>>            break;
>>
>> +       case 'X':
>> +         {
>> +           int nbit, at, n;
>> +           if (sscanf(oparg, "XI%d@%d%n", &nbit, &at, &n) == 2)
>> +             {
>> +               int value = EXTRACT_BITS (l, (1 << nbit) - 1, at);
>> +               print (info->stream, dis_style_immediate, "%d", value);
>> +               oparg += n - 1;
>> +             }
>> +           else if (sscanf(oparg, "XS%d@%d%n", &nbit, &at, &n) == 2)
>> +             {
>> +               int value = EXTRACT_BITS (l, (1 << nbit) - 1, at);
>> +               print (info->stream, dis_style_immediate, "%d", value);
>> +               oparg += n - 1;
>> +             }
>> +           else
>> +             {
>> +               print (info->stream, dis_style_text,
>> +                      _("# internal error, unknown X modifier %s"),
>> +                      oparg);
>> +             }
>> +         }
>> +         break;
>> +
>>          default:
>>            /* xgettext:c-format */
>>            print (info->stream, dis_style_text,
>> diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
>> index 2f9945aa930..0e9a2f597c2 100644
>> --- a/opcodes/riscv-opc.c
>> +++ b/opcodes/riscv-opc.c
>> @@ -266,6 +266,17 @@ match_vd_eq_vs1_eq_vs2 (const struct riscv_opcode *op,
>>     return match_opcode (op, insn) && vd == vs1 && vs1 == vs2;
>>   }
>>
>> +static int
>> +match_thead_rd1_rd2_neq_rs1(const struct riscv_opcode *op,
>> +                           insn_t insn)
>> +{
>> +  int rd1 = (insn & MASK_RD) >> OP_SH_RD;
>> +  int rd2 = (insn & MASK_RS2) >> OP_SH_RS2;
>> +  int rs1 = (insn & MASK_RS1) >> OP_SH_RS1;
>> +
>> +  return match_opcode (op, insn) && rd1 != rs1 && rd2 != rs1;
>> +}
>> +
>>   const struct riscv_opcode riscv_opcodes[] =
>>   {
>>   /* name, xlen, isa, operands, match, mask, match_func, pinfo.  */
>> @@ -1825,6 +1836,119 @@ const struct riscv_opcode riscv_opcodes[] =
>>   {"hsv.w",       0, INSN_CLASS_H, "t,0(s)", MATCH_HSV_W, MASK_HSV_W, match_opcode, INSN_DREF|INSN_4_BYTE },
>>   {"hsv.d",      64, INSN_CLASS_H, "t,0(s)", MATCH_HSV_D, MASK_HSV_D, match_opcode, INSN_DREF|INSN_8_BYTE },
>>
>> +/* The vendor extension opcodes for T-HEAD.  */
>> +{"th.wsc",             0, INSN_CLASS_THEAD_C_OR_E,   "",  MATCH_WSC, MASK_WSC, match_opcode, 0},
>> +{"th.dcache.iall",     0, INSN_CLASS_THEAD_C_OR_E,   "",  MATCH_DCACHE_IALL, MASK_DCACHE_IALL, match_opcode, 0},
>> +{"th.dcache.call",     0, INSN_CLASS_THEAD_C_OR_E,   "",  MATCH_DCACHE_CALL, MASK_DCACHE_CALL, match_opcode, 0},
>> +{"th.dcache.ciall",    0, INSN_CLASS_THEAD_C_OR_E,   "",  MATCH_DCACHE_CIALL, MASK_DCACHE_CIALL, match_opcode, 0},
>> +{"th.dcache.isw",      0, INSN_CLASS_THEAD_C_OR_E,   "s",     MATCH_DCACHE_ISW, MASK_DCACHE_ISW, match_opcode, 0},
>> +{"th.dcache.csw",      0, INSN_CLASS_THEAD_C_OR_E,   "s",     MATCH_DCACHE_CSW, MASK_DCACHE_CSW, match_opcode, 0},
>> +{"th.dcache.cisw",     0, INSN_CLASS_THEAD_C_OR_E,   "s",     MATCH_DCACHE_CISW, MASK_DCACHE_CISW, match_opcode, 0},
>> +{"th.dcache.iva",      0, INSN_CLASS_THEAD_C,   "s",     MATCH_DCACHE_IVA, MASK_DCACHE_IVA, match_opcode, 0},
>> +{"th.dcache.cva",      0, INSN_CLASS_THEAD_C,   "s",     MATCH_DCACHE_CVA, MASK_DCACHE_CVA, match_opcode, 0},
>> +{"th.dcache.cval1",    0, INSN_CLASS_THEAD_C,   "s",     MATCH_DCACHE_CVAL1, MASK_DCACHE_CVAL1, match_opcode, 0},
>> +{"th.dcache.civa",     0, INSN_CLASS_THEAD_C,   "s",     MATCH_DCACHE_CIVA, MASK_DCACHE_CIVA, match_opcode, 0},
>> +{"th.dcache.ipa",      0, INSN_CLASS_THEAD_C_OR_E,   "s",     MATCH_DCACHE_IPA, MASK_DCACHE_IPA, match_opcode, 0},
>> +{"th.dcache.cpa",      0, INSN_CLASS_THEAD_C_OR_E,   "s",     MATCH_DCACHE_CPA, MASK_DCACHE_CPA, match_opcode, 0},
>> +{"th.dcache.cpal1",    0, INSN_CLASS_THEAD_C,   "s",     MATCH_DCACHE_CPAL1, MASK_DCACHE_CPAL1, match_opcode, 0},
>> +{"th.dcache.cipa",     0, INSN_CLASS_THEAD_C_OR_E,   "s",     MATCH_DCACHE_CIPA, MASK_DCACHE_CIPA, match_opcode, 0},
>> +{"th.icache.iall",     0, INSN_CLASS_THEAD_C_OR_E_OR_SE,   "",      MATCH_ICACHE_IALL, MASK_ICACHE_IALL, match_opcode, 0},
>> +{"th.icache.iall",     0, INSN_CLASS_THEAD_SE,   "",      MATCH_ICACHE_IALL, MASK_ICACHE_IALL, match_opcode, INSN_ALIAS},
>> +{"th.icache.ialls",    0, INSN_CLASS_THEAD_C,   "",      MATCH_ICACHE_IALLS, MASK_ICACHE_IALLS, match_opcode, 0},
>> +{"th.icache.iva",      0, INSN_CLASS_THEAD_C,   "s",     MATCH_ICACHE_IVA, MASK_ICACHE_IVA, match_opcode, 0},
>> +{"th.icache.ipa",      0, INSN_CLASS_THEAD_C_OR_E,   "s",     MATCH_ICACHE_IPA, MASK_ICACHE_IPA, match_opcode, 0},
>> +{"th.l2cache.iall",    0, INSN_CLASS_THEAD_C,   "",      MATCH_L2CACHE_IALL, MASK_L2CACHE_IALL, match_opcode, 0},
>> +{"th.l2cache.call",    0, INSN_CLASS_THEAD_C,   "",      MATCH_L2CACHE_CALL, MASK_L2CACHE_CALL, match_opcode, 0},
>> +{"th.l2cache.ciall",   0, INSN_CLASS_THEAD_C_OR_E,   "",      MATCH_L2CACHE_CIALL, MASK_L2CACHE_CIALL, match_opcode, 0},
>> +{"th.sync",            0, INSN_CLASS_THEAD_C_OR_E,   "",      MATCH_SYNC, MASK_SYNC, match_opcode, 0},
>> +{"th.sync.i",          0, INSN_CLASS_THEAD_C_OR_E,   "",      MATCH_SYNC_I, MASK_SYNC_I, match_opcode, 0},
>> +{"th.sync.s",          0, INSN_CLASS_THEAD_C,   "",      MATCH_SYNC_S, MASK_SYNC_S, match_opcode, 0},
>> +{"th.sync.is",         0, INSN_CLASS_THEAD_C,   "",      MATCH_SYNC_IS, MASK_SYNC_IS, match_opcode, 0},
>> +{"th.tstnbz",          0, INSN_CLASS_THEAD_C_OR_E,   "d,s",     MATCH_TSTNBZ, MASK_TSTNBZ, match_opcode, 0},
>> +{"th.mula",            0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MULA, MASK_MULA, match_opcode, 0},
>> +{"th.muls",            0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MULS, MASK_MULS, match_opcode, 0},
>> +{"th.mulah",           0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MULAH, MASK_MULAH, match_opcode, 0},
>> +{"th.mulsh",           0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MULSH, MASK_MULSH, match_opcode, 0},
>> +{"th.sfence.vmas",     0, INSN_CLASS_THEAD_C,   "s,t",      MATCH_SFENCE_VMAS, MASK_SFENCE_VMAS, match_opcode, 0},
>> +{"th.mveqz",           0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MVEQZ, MASK_MVEQZ, match_opcode, 0},
>> +{"th.mvnez",           0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MVNEZ, MASK_MVNEZ, match_opcode, 0},
>> +{"th.mulaw",           0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MULAW, MASK_MULAW, match_opcode, 0},
>> +{"th.mulsw",           0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MULSW, MASK_MULSW, match_opcode, 0},
>> +{"th.ext",             64, INSN_CLASS_THEAD_C,  "d,s,XI6@26,XI6@20",   MATCH_EXT, MASK_EXT, match_opcode, 0 },
>> +{"th.ext",             32, INSN_CLASS_THEAD_E,  "d,s,XI5@26,XI5@20",   MATCH_EXT, (MASK_EXT | (1U<<25) | (1U<<31)), match_opcode, 0 },
>> +{"th.extu",            64, INSN_CLASS_THEAD_C,  "d,s,XI6@26,XI6@20",   MATCH_EXTU, MASK_EXTU, match_opcode, 0 },
>> +{"th.extu",            32, INSN_CLASS_THEAD_E,  "d,s,XI5@26,XI5@20",   MATCH_EXTU, (MASK_EXTU | (1U<<25) | (1U<<31)), match_opcode, 0 },
>> +{"th.ff1",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s",   MATCH_FF1, MASK_FF1, match_opcode, 0},
>> +{"th.ff0",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s",   MATCH_FF0, MASK_FF1, match_opcode, 0},
>> +{"th.rev",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s",   MATCH_REV, MASK_REV, match_opcode, 0},
>> +{"th.lrb",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_LRB, MASK_LRB, match_opcode, 0 },
>> +{"th.lrbu",            0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_LRBU, MASK_LRBU, match_opcode, 0 },
>> +{"th.lrh",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_LRH, MASK_LRH, match_opcode, 0 },
>> +{"th.lrhu",            0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_LRHU, MASK_LRHU, match_opcode, 0 },
>> +{"th.lrw",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_LRW, MASK_LRW, match_opcode, 0 },
>> +{"th.lrwu",            0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_LRWU, MASK_LRWU, match_opcode, 0 },
>> +{"th.srb",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_SRB, MASK_SRB, match_opcode, 0 },
>> +{"th.srh",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_SRH, MASK_SRH, match_opcode, 0 },
>> +{"th.srw",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_SRW, MASK_SRW, match_opcode, 0 },
>> +{"th.lrd",             0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LRD, MASK_LRD, match_opcode, 0 },
>> +{"th.srd",             0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_SRD, MASK_SRD, match_opcode, 0 },
>> +{"th.lurb",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LURB, MASK_LURB, match_opcode, 0 },
>> +{"th.lurbu",           0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LURBU, MASK_LURBU, match_opcode, 0 },
>> +{"th.lurh",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LURH, MASK_LURH, match_opcode, 0 },
>> +{"th.lurhu",           0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LURHU, MASK_LURHU, match_opcode, 0 },
>> +{"th.lurw",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LURW, MASK_LURW, match_opcode, 0 },
>> +{"th.lurwu",           0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LURWU, MASK_LURWU, match_opcode, 0 },
>> +{"th.lurd",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LURD, MASK_LURD, match_opcode, 0 },
>> +{"th.surb",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_SURB, MASK_SURB, match_opcode, 0 },
>> +{"th.surh",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_SURH, MASK_SURH, match_opcode, 0 },
>> +{"th.surw",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_SURW, MASK_SURW, match_opcode, 0 },
>> +{"th.surd",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_SURD, MASK_SURD, match_opcode, 0 },
>> +{"th.tst",             64, INSN_CLASS_THEAD_C,  "d,s,XI6@20",   MATCH_TST, MASK_TST, match_opcode, 0 },
>> +{"th.tst",             32, INSN_CLASS_THEAD_E,   "d,s,XI5@20",   MATCH_TST, (MASK_TST | (1U << 25)), match_opcode, INSN_ALIAS},
>> +{"th.srriw",           0, INSN_CLASS_THEAD_C,   "d,s,XI5@20",   MATCH_SRRIW, MASK_SRRIW, match_opcode, 0 },
>> +{"th.srri",            0, INSN_CLASS_THEAD_C_OR_E,   "d,s,XI6@20",   MATCH_SRRI, MASK_SRRI, match_opcode, 0 },
>> +{"th.addsl",           0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25", MATCH_ADDSL, MASK_ADDSL, match_opcode, 0 },
>> +{"th.lwd",             0, INSN_CLASS_THEAD_C,   "d,t,(s),XI2@25", MATCH_LWD, MASK_LWD, match_thead_rd1_rd2_neq_rs1, 0 },
>> +{"th.ldd",             0, INSN_CLASS_THEAD_C,   "d,t,(s),XI2@25", MATCH_LDD, MASK_LDD, match_thead_rd1_rd2_neq_rs1, 0 },
>> +{"th.swd",             0, INSN_CLASS_THEAD_C,   "d,t,(s),XI2@25", MATCH_SWD, MASK_SWD, match_opcode, 0 },
>> +{"th.sdd",             0, INSN_CLASS_THEAD_C,   "d,t,(s),XI2@25", MATCH_SDD, MASK_SDD, match_opcode, 0 },
>> +{"th.sdia",            0, INSN_CLASS_THEAD_C,   "d,(s),XS5@20,XI2@25", MATCH_SDIA, MASK_SDIA, match_opcode, 0 },
>> +{"th.sdib",            0, INSN_CLASS_THEAD_C,   "d,(s),XS5@20,XI2@25", MATCH_SDIB, MASK_SDIB, match_opcode, 0 },
>> +{"th.lwud",            0, INSN_CLASS_THEAD_C,   "d,t,(s),XI2@25", MATCH_LWUD, MASK_LWUD, match_thead_rd1_rd2_neq_rs1, 0 },
>> +{"th.swia",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_SWIA, MASK_SWIA, match_opcode, 0},
>> +{"th.swib",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_SWIB, MASK_SWIB, match_opcode, 0},
>> +{"th.shia",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_SHIA, MASK_SHIA, match_opcode, 0},
>> +{"th.shib",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_SHIB, MASK_SHIB, match_opcode, 0},
>> +{"th.sbia",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_SBIA, MASK_SBIA, match_opcode, 0},
>> +{"th.sbib",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_SBIB, MASK_SBIB, match_opcode, 0},
>> +{"th.lwuia",           0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LWUIA, MASK_LWUIA, match_opcode, 0},
>> +{"th.lwuib",           0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LWUIB, MASK_LWUIB, match_opcode, 0},
>> +{"th.lhuia",           0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LHUIA, MASK_LHUIA, match_opcode, 0},
>> +{"th.lhuib",           0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LHUIB, MASK_LHUIB, match_opcode, 0},
>> +{"th.lbuia",           0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LBUIA, MASK_LBUIA, match_opcode, 0},
>> +{"th.lbuib",           0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LBUIB, MASK_LBUIB, match_opcode, 0},
>> +{"th.ldia",            0, INSN_CLASS_THEAD_C,   "d,(s),XS5@20,XI2@25", MATCH_LDIA, MASK_LDIA, match_opcode, 0},
>> +{"th.ldib",            0, INSN_CLASS_THEAD_C,   "d,(s),XS5@20,XI2@25", MATCH_LDIB, MASK_LDIB, match_opcode, 0},
>> +{"th.lwia",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LWIA, MASK_LWIA, match_opcode, 0},
>> +{"th.lwib",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LWIB, MASK_LWIB, match_opcode, 0},
>> +{"th.lhia",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LHIA, MASK_LHIA, match_opcode, 0},
>> +{"th.lhib",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LHIB, MASK_LHIB, match_opcode, 0},
>> +{"th.lbia",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LBIA, MASK_LBIA, match_opcode, 0},
>> +{"th.lbib",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LBIB, MASK_LBIB, match_opcode, 0},
>> +{"th.fsurd",           0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FSURD, MASK_FSURD, match_opcode, 0},
>> +{"th.revw",            0, INSN_CLASS_THEAD_C,   "d,s", MATCH_REVW, MASK_REVW, match_opcode, 0},
>> +{"th.fsurw",           0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FSURW, MASK_FSURW, match_opcode, 0},
>> +{"th.flurd",           0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FLURD, MASK_FLURD, match_opcode, 0},
>> +{"th.flurw",           0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FLURW, MASK_FLURW, match_opcode, 0},
>> +{"th.fsrd",            0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FSRD, MASK_FSRD, match_opcode, 0},
>> +{"th.fsrw",            0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FSRW, MASK_FSRW, match_opcode, 0},
>> +{"th.flrd",            0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FLRD, MASK_FLRD, match_opcode, 0},
>> +{"th.flrw",            0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FLRW, MASK_FLRW, match_opcode, 0},
>> +{"th.ipush",           0, INSN_CLASS_THEAD_E,   "",  MATCH_IPUSH, MASK_IPUSH, match_opcode, 0},
>> +{"th.ipop",            0, INSN_CLASS_THEAD_E,   "",  MATCH_IPOP, MASK_IPOP, match_opcode, 0},
>> +{"th.fmv.x.hw",        32, INSN_CLASS_THEAD_E,  "d,S",  MATCH_FMV_X_HW, MASK_FMV_X_HW, match_opcode, 0},
>> +{"th.fmv.hw.x",        32, INSN_CLASS_THEAD_E,  "D,s",  MATCH_FMV_HW_X, MASK_FMV_HW_X, match_opcode, 0},
>> +
>>   /* Terminate the list.  */
>>   {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}
>>   };
>> --
>> 2.34.1
>>

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

* Re: [PATCH] RISC-V/t-head: Add CSRs and opcodes of the T-HEAD XUANTIE CPUs
  2022-07-29  0:28 ` Kito Cheng
  2022-07-29  8:43   ` Jojo R
@ 2022-07-29  9:19   ` Lifang Xia
  1 sibling, 0 replies; 4+ messages in thread
From: Lifang Xia @ 2022-07-29  9:19 UTC (permalink / raw)
  To: Kito Cheng, Palmer Dabbelt; +Cc: Binutils, Christoph Muellner, Jojo R

Hi Kito & Palmer,

Thanks for this patch.

We are implementing the opcodes following this PR. And there are some 
diffecerences about the ISA string.

If you want do some tests about the instructions, this patch is OK.

Thanks,
Lifang

On 2022/7/29 08:28, Kito Cheng wrote:
> Hi Palmer
>
> They are trying to reorg the structure of their extensions as I know,
> so the extension name might be obsolete now?
>
> https://github.com/riscv-non-isa/riscv-toolchain-conventions/pull/19
>
> Hi Jojo, Li-Fan:
>
> Could you confirm that?
>
> Thanks
>
> On Fri, Jul 29, 2022 at 6:08 AM Palmer Dabbelt <palmer@rivosinc.com> wrote:
>> From: Lifang Xia <lifang_xia@c-sky.com>
>>
>> Add CSRs and opcodes of the XUANTIE CPUs, extensions named "theadc",
>> "xtheade" and "xtheadse".
>>
>> bfd/ChangeLog
>>
>>          * cpu-riscv.h (riscv_spec_class) <VENDOR_SPEC_CLASS_THEAD>: New
>>          value.
>>          * elfxx-riscv.c (riscv_supported_custom_ext): New table.
>>          (riscv_all_supported_ext): Add riscv_supported_custom_ext.
>>          (riscv_recognized_prefixed_ext): Update comment.
>>          (riscv_get_default_ext_version): Add the t-head extensions.
>>          (riscv_multi_subset_supports): Likewise.
>>          (riscv_multi_subset_supports_ext): Likewise.
>>
>> gas/ChangeLog
>>
>>          * config/tc-riscv.c (riscv_csr_class) <CSR_CLASS_THEAD>: New
>>          value.
>>          (riscv_csr_address): Add CSR_CLASS_THEAD.
>>          (validate_riscv_insn): Add the XI and XS formats.
>>          (riscv_ip): Likewise.
>>
>> gas/testsuite/ChangeLog
>>
>>          * gas/riscv/thead-csr-list.d: New test.
>>          * gas/riscv/theadc-ext.d: Likewise.
>>          * gas/riscv/theadc-ext.s: Likewise.
>>          * gas/riscv/theade-ext.d: Likewise.
>>          * gas/riscv/theade-ext.s: Likewise.
>>
>> include/ChangeLog
>>
>>          * opcode/iscv-opc-thead.h: New file.
>>
>> opcodes/ChangeLog
>>
>>          * riscv-dis.c (print_insn_args): Support XI and XS formats.
>>          * riscv-opc.c (match_thead_rd1_rd2_neq_rs1): New function.
>>          (riscv_opcodes): Add the t-thead extensions.
>> ---
>> I cherry-picked this off Nelson's integration branch at sourceware, and
>> then went through it a bit to avoid the dependencies on the experimental
>> extension handling (and also just some cleanups).  This should be
>> functionally the same as what was originally posted, aside from having
>> the "th." prefix on instructions and the "th_" prefix on CSRs.
>>
>> This passes the tests, but I don't currently have any other way to
>> verify it.
>> ---
>>   bfd/cpu-riscv.h                          |   3 +
>>   bfd/elfxx-riscv.c                        |  43 +-
>>   gas/config/tc-riscv.c                    |  85 ++++
>>   gas/testsuite/gas/riscv/thead-csr-list.d | 107 +++++
>>   gas/testsuite/gas/riscv/thead-csr-list.s |  98 ++++
>>   gas/testsuite/gas/riscv/theadc-ext.d     | 112 +++++
>>   gas/testsuite/gas/riscv/theadc-ext.s     | 115 +++++
>>   gas/testsuite/gas/riscv/theade-ext.d     |  62 +++
>>   gas/testsuite/gas/riscv/theade-ext.s     |  66 +++
>>   include/opcode/riscv-opc-thead.h         | 571 +++++++++++++++++++++++
>>   include/opcode/riscv-opc.h               |   2 +
>>   include/opcode/riscv.h                   |  21 +
>>   opcodes/riscv-dis.c                      |  24 +
>>   opcodes/riscv-opc.c                      | 124 +++++
>>   14 files changed, 1428 insertions(+), 5 deletions(-)
>>   create mode 100644 gas/testsuite/gas/riscv/thead-csr-list.d
>>   create mode 100644 gas/testsuite/gas/riscv/thead-csr-list.s
>>   create mode 100644 gas/testsuite/gas/riscv/theadc-ext.d
>>   create mode 100644 gas/testsuite/gas/riscv/theadc-ext.s
>>   create mode 100644 gas/testsuite/gas/riscv/theade-ext.d
>>   create mode 100644 gas/testsuite/gas/riscv/theade-ext.s
>>   create mode 100644 include/opcode/riscv-opc-thead.h
>>
>> diff --git a/bfd/cpu-riscv.h b/bfd/cpu-riscv.h
>> index ff037d127e2..3e0839fec3c 100644
>> --- a/bfd/cpu-riscv.h
>> +++ b/bfd/cpu-riscv.h
>> @@ -34,6 +34,9 @@ enum riscv_spec_class
>>     PRIV_SPEC_CLASS_1P11,
>>     PRIV_SPEC_CLASS_1P12,
>>     PRIV_SPEC_CLASS_DRAFT,
>> +
>> +  /* Vendor spec for T_HEAD XuanTie.  */
>> +  VENDOR_SPEC_CLASS_THEAD,
>>   };
>>
>>   struct riscv_spec
>> diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
>> index 0b2021f5cc7..2af0917381e 100644
>> --- a/bfd/elfxx-riscv.c
>> +++ b/bfd/elfxx-riscv.c
>> @@ -1245,12 +1245,21 @@ static struct riscv_supported_ext riscv_supported_std_zxm_ext[] =
>>     {NULL, 0, 0, 0, 0}
>>   };
>>
>> +static struct riscv_supported_ext riscv_supported_custom_ext[] =
>> +{
>> +  {"xtheadc",          VENDOR_SPEC_CLASS_THEAD,        2, 0, 0 },
>> +  {"xtheade",          VENDOR_SPEC_CLASS_THEAD,        2, 0, 0 },
>> +  {"xtheadse",         VENDOR_SPEC_CLASS_THEAD,        2, 0, 0 },
>> +  {NULL, 0, 0, 0, 0}
>> +};
>> +
>>   const struct riscv_supported_ext *riscv_all_supported_ext[] =
>>   {
>>     riscv_supported_std_ext,
>>     riscv_supported_std_z_ext,
>>     riscv_supported_std_s_ext,
>>     riscv_supported_std_zxm_ext,
>> +  riscv_supported_custom_ext,
>>     NULL
>>   };
>>
>> @@ -1331,7 +1340,8 @@ riscv_recognized_prefixed_ext (const char *ext)
>>     case RV_ISA_CLASS_S:
>>       return riscv_known_prefixed_ext (ext, riscv_supported_std_s_ext);
>>     case RV_ISA_CLASS_X:
>> -    /* Only the single x is unrecognized.  */
>> +    /* For compatibility this pretends to support any X extension except the
>> +       single letter "x". */
>>       if (strcmp (ext, "x") != 0)
>>         return true;
>>     default:
>> @@ -1504,10 +1514,9 @@ riscv_get_default_ext_version (enum riscv_spec_class *default_isa_spec,
>>     switch (class)
>>       {
>>       case RV_ISA_CLASS_ZXM: table = riscv_supported_std_zxm_ext; break;
>> -    case RV_ISA_CLASS_Z: table = riscv_supported_std_z_ext; break;
>> -    case RV_ISA_CLASS_S: table = riscv_supported_std_s_ext; break;
>> -    case RV_ISA_CLASS_X:
>> -      break;
>> +    case RV_ISA_CLASS_Z: table = riscv_supported_std_z_ext;     break;
>> +    case RV_ISA_CLASS_S: table = riscv_supported_std_s_ext;     break;
>> +    case RV_ISA_CLASS_X: table = riscv_supported_custom_ext;    break;
>>       default:
>>         table = riscv_supported_std_ext;
>>       }
>> @@ -1517,6 +1526,7 @@ riscv_get_default_ext_version (enum riscv_spec_class *default_isa_spec,
>>       {
>>         if (strcmp (table[i].name, name) == 0
>>            && (table[i].isa_spec_class == ISA_SPEC_CLASS_DRAFT
>> +             || table[i].isa_spec_class == VENDOR_SPEC_CLASS_THEAD
>>                || table[i].isa_spec_class == *default_isa_spec))
>>          {
>>            *major_version = table[i].major_version;
>> @@ -2402,6 +2412,19 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
>>         return riscv_subset_supports (rps, "svinval");
>>       case INSN_CLASS_H:
>>         return riscv_subset_supports (rps, "h");
>> +    case INSN_CLASS_THEAD_C:
>> +      return riscv_subset_supports (rps, "xtheadc");
>> +    case INSN_CLASS_THEAD_E:
>> +      return riscv_subset_supports (rps, "xtheade");
>> +    case INSN_CLASS_THEAD_SE:
>> +      return riscv_subset_supports (rps, "xtheadse");
>> +    case INSN_CLASS_THEAD_C_OR_E:
>> +      return (riscv_subset_supports (rps, "xtheadc")
>> +             || riscv_subset_supports (rps, "xtheade"));
>> +    case INSN_CLASS_THEAD_C_OR_E_OR_SE:
>> +      return (riscv_subset_supports (rps, "xtheadc")
>> +             || riscv_subset_supports (rps, "xtheade")
>> +             || riscv_subset_supports (rps, "xtheadse"));
>>       default:
>>         rps->error_handler
>>           (_("internal: unreachable INSN_CLASS_*"));
>> @@ -2527,6 +2550,16 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
>>         return "svinval";
>>       case INSN_CLASS_H:
>>         return _("h");
>> +    case INSN_CLASS_THEAD_C:
>> +      return "xtheadc";
>> +    case INSN_CLASS_THEAD_E:
>> +      return "xtheade";
>> +    case INSN_CLASS_THEAD_SE:
>> +      return "xtheadse";
>> +    case INSN_CLASS_THEAD_C_OR_E:
>> +      return _("xtheadc' or `xtheade");
>> +    case INSN_CLASS_THEAD_C_OR_E_OR_SE:
>> +      return _("xtheadc' or `xtheade' or `xtheadse");
>>       default:
>>         rps->error_handler
>>           (_("internal: unreachable INSN_CLASS_*"));
>> diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
>> index 291d07f6d8f..8a473d4b3fe 100644
>> --- a/gas/config/tc-riscv.c
>> +++ b/gas/config/tc-riscv.c
>> @@ -78,6 +78,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_THEAD,             /* vendor CSR for T-HEAD */
>>   };
>>
>>   /* This structure holds all restricted conditions for a CSR.  */
>> @@ -965,6 +966,9 @@ riscv_csr_address (const char *csr_name,
>>         break;
>>       case CSR_CLASS_DEBUG:
>>         break;
>> +    case CSR_CLASS_THEAD:
>> +      extension = "xthead";
>> +      break;
>>       default:
>>         as_bad (_("internal: bad RISC-V CSR class (0x%x)"), csr_class);
>>       }
>> @@ -1253,6 +1257,30 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
>>                  goto unknown_validate_operand;
>>              }
>>            break;
>> +       case 'X': /* Opcode for custom instructions.  */
>> +         {
>> +           int nbit, at, n;
>> +           if (sscanf(oparg, "XI%d@%d%n", &nbit, &at, &n) == 2)
>> +             {
>> +               used_bits |= ENCODE_VENDOR_THEAD_IMM ((1ULL << nbit) - 1,
>> +                                                     nbit, at);
>> +               oparg += n - 1;
>> +             }
>> +           else if (sscanf(oparg, "XS%d@%d%n", &nbit, &at, &n) == 2)
>> +             {
>> +               used_bits |= ENCODE_VENDOR_THEAD_SIGN_IMM ((1ULL << nbit) - 1,
>> +                                                          nbit, at);
>> +               oparg += n - 1;
>> +             }
>> +           else
>> +             {
>> +               as_bad (_("internal: bad X opcode type `%s'"),
>> +                       oparg);
>> +               return false;
>> +             }
>> +         }
>> +         break;
>> +
>>          default:
>>          unknown_validate_operand:
>>            as_bad (_("internal: bad RISC-V opcode "
>> @@ -3265,6 +3293,63 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
>>                asarg = expr_end;
>>                continue;
>>
>> +           case 'X': /* Vendor-specific.  */
>> +             {
>> +               int nbit, at, n;
>> +               if (sscanf(oparg, "XI%d@%d%n", &nbit, &at, &n) == 2)
>> +                 {
>> +                   my_getExpression (imm_expr, asarg);
>> +                   if (imm_expr->X_op != O_constant)
>> +                     {
>> +                       as_bad (_("non-constant operand"));
>> +                       break;
>> +                     }
>> +
>> +                   if (!VALID_VENDOR_THEAD_IMM (imm_expr->X_add_number, nbit, at))
>> +                     {
>> +                       as_bad (_("invalid immediate"));
>> +                       break;
>> +                     }
>> +
>> +                   ip->insn_opcode |=
>> +                     ENCODE_VENDOR_THEAD_IMM (imm_expr->X_add_number, nbit, at);
>> +                   asarg = expr_end;
>> +                   imm_expr->X_op = O_absent;
>> +                   oparg += n - 1;
>> +                   continue;
>> +                 }
>> +               else if (sscanf(oparg, "XS%d@%d%n", &nbit, &at, &n) == 2)
>> +                 {
>> +                   my_getExpression (imm_expr, asarg);
>> +                   if (imm_expr->X_op != O_constant)
>> +                     {
>> +                       as_bad (_("non-constant operand"));
>> +                       break;
>> +                     }
>> +
>> +                   if (!VALID_VENDOR_THEAD_SIGN_IMM (imm_expr->X_add_number, nbit, at))
>> +                     {
>> +                       as_bad (_("invalid immediate"));
>> +                       break;
>> +                     }
>> +
>> +                   ip->insn_opcode |=
>> +                     ENCODE_VENDOR_THEAD_SIGN_IMM (imm_expr->X_add_number, nbit, at);
>> +                   asarg = expr_end;
>> +                   imm_expr->X_op = O_absent;
>> +                   oparg += n - 1;
>> +                   continue;
>> +                 }
>> +
>> +               else
>> +                 {
>> +                   as_fatal (_("internal: unknown X argument type `%s'"),
>> +                             opargStart);
>> +                   break;
>> +                 }
>> +               continue;
>> +             }
>> +
>>              default:
>>              unknown_riscv_ip_operand:
>>                as_fatal (_("internal: unknown argument type `%s'"),
>> diff --git a/gas/testsuite/gas/riscv/thead-csr-list.d b/gas/testsuite/gas/riscv/thead-csr-list.d
>> new file mode 100644
>> index 00000000000..08bda4d24ea
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/thead-csr-list.d
>> @@ -0,0 +1,107 @@
>> +#as: -march=rv64gcxtheadc
>> +#objdump: -dr
>> +
>> +.*:[   ]+file format .*
>> +
>> +
>> +Disassembly of section .text:
>> +
>> +0000000000000000 <.text>:
>> +   0:  7c002573                csrr    a0,th_mxstatus
>> +   4:  7c102573                csrr    a0,th_mhcr
>> +   8:  7c202573                csrr    a0,th_mcor
>> +   c:  7c302573                csrr    a0,th_mccr2
>> +  10:  7c402573                csrr    a0,th_mcer2
>> +  14:  7c502573                csrr    a0,th_mhint
>> +  18:  7c602573                csrr    a0,th_mrmr
>> +  1c:  7c702573                csrr    a0,th_mrvbr
>> +  20:  7c802573                csrr    a0,th_mcer
>> +  24:  7c902573                csrr    a0,th_mcounterwen
>> +  28:  7ca02573                csrr    a0,th_mcounterinten
>> +  2c:  7cb02573                csrr    a0,th_mcounterof
>> +  30:  7cc02573                csrr    a0,th_mhint2
>> +  34:  7cd02573                csrr    a0,th_mhint3
>> +  38:  7e002573                csrr    a0,th_mraddr
>> +  3c:  7e102573                csrr    a0,th_mexstatus
>> +  40:  7e202573                csrr    a0,th_mnmicause
>> +  44:  7e302573                csrr    a0,th_mnmipc
>> +  48:  7f002573                csrr    a0,th_mhpmcr
>> +  4c:  7f102573                csrr    a0,th_mhpmsr
>> +  50:  7f202573                csrr    a0,th_mhpmer
>> +  54:  7f302573                csrr    a0,th_msmpr
>> +  58:  7f402573                csrr    a0,th_mteecfg
>> +  5c:  7d102573                csrr    a0,th_usp
>> +  60:  7d202573                csrr    a0,th_mcins
>> +  64:  7d302573                csrr    a0,th_mcindex
>> +  68:  7d402573                csrr    a0,th_mcdata0
>> +  6c:  7d502573                csrr    a0,th_mcdata1
>> +  70:  7d602573                csrr    a0,th_meicr
>> +  74:  7d702573                csrr    a0,th_meicr2
>> +  78:  be002573                csrr    a0,th_mebr
>> +  7c:  be102573                csrr    a0,th_nt_mstatus
>> +  80:  be302573                csrr    a0,th_nt_mtvec
>> +  84:  be202573                csrr    a0,th_nt_mie
>> +  88:  be402573                csrr    a0,th_nt_mtvt
>> +  8c:  be502573                csrr    a0,th_nt_mepc
>> +  90:  be602573                csrr    a0,th_nt_mcause
>> +  94:  be702573                csrr    a0,th_nt_mip
>> +  98:  be802573                csrr    a0,th_nt_mintstate
>> +  9c:  be902573                csrr    a0,th_nt_mxstatus
>> +  a0:  bea02573                csrr    a0,th_nt_mebr
>> +  a4:  beb02573                csrr    a0,th_nt_msp
>> +  a8:  bec02573                csrr    a0,th_t_usp
>> +  ac:  bed02573                csrr    a0,th_t_mdcr
>> +  b0:  bee02573                csrr    a0,th_t_mpcr
>> +  b4:  bef02573                csrr    a0,th_pmpteecfg
>> +  b8:  fc002573                csrr    a0,th_mcpuid
>> +  bc:  fc102573                csrr    a0,th_mapbaddr
>> +  c0:  fc202573                csrr    a0,th_mwmsr
>> +  c4:  80002573                csrr    a0,th_fxcr
>> +  c8:  9c002573                csrr    a0,th_smir
>> +  cc:  9c102573                csrr    a0,th_smel
>> +  d0:  9c202573                csrr    a0,th_smeh
>> +  d4:  9c302573                csrr    a0,th_smcir
>> +  d8:  5c002573                csrr    a0,th_sxstatus
>> +  dc:  5c102573                csrr    a0,th_shcr
>> +  e0:  5c202573                csrr    a0,th_scer2
>> +  e4:  5c302573                csrr    a0,th_scer
>> +  e8:  5c402573                csrr    a0,th_scounterinten
>> +  ec:  5c502573                csrr    a0,th_scounterof
>> +  f0:  5c602573                csrr    a0,th_shint
>> +  f4:  5c702573                csrr    a0,th_shint2
>> +  f8:  5c802573                csrr    a0,th_shpminhibit
>> +  fc:  5c902573                csrr    a0,th_shpmcr
>> + 100:  5ca02573                csrr    a0,th_shpmsr
>> + 104:  5cb02573                csrr    a0,th_shpmer
>> + 108:  5e002573                csrr    a0,th_scycle
>> + 10c:  5e102573                csrr    a0,th_shpmcounter1
>> + 110:  5e202573                csrr    a0,th_shpmcounter2
>> + 114:  5e302573                csrr    a0,th_shpmcounter3
>> + 118:  5e402573                csrr    a0,th_shpmcounter4
>> + 11c:  5e502573                csrr    a0,th_shpmcounter5
>> + 120:  5e602573                csrr    a0,th_shpmcounter6
>> + 124:  5e702573                csrr    a0,th_shpmcounter7
>> + 128:  5e802573                csrr    a0,th_shpmcounter8
>> + 12c:  5e902573                csrr    a0,th_shpmcounter9
>> + 130:  5ea02573                csrr    a0,th_shpmcounter10
>> + 134:  5eb02573                csrr    a0,th_shpmcounter11
>> + 138:  5ec02573                csrr    a0,th_shpmcounter12
>> + 13c:  5ed02573                csrr    a0,th_shpmcounter13
>> + 140:  5ee02573                csrr    a0,th_shpmcounter14
>> + 144:  5ef02573                csrr    a0,th_shpmcounter15
>> + 148:  5f002573                csrr    a0,th_shpmcounter16
>> + 14c:  5f102573                csrr    a0,th_shpmcounter17
>> + 150:  5f202573                csrr    a0,th_shpmcounter18
>> + 154:  5f302573                csrr    a0,th_shpmcounter19
>> + 158:  5f402573                csrr    a0,th_shpmcounter20
>> + 15c:  5f502573                csrr    a0,th_shpmcounter21
>> + 160:  5f602573                csrr    a0,th_shpmcounter22
>> + 164:  5f702573                csrr    a0,th_shpmcounter23
>> + 168:  5f802573                csrr    a0,th_shpmcounter24
>> + 16c:  5f902573                csrr    a0,th_shpmcounter25
>> + 170:  5fa02573                csrr    a0,th_shpmcounter26
>> + 174:  5fb02573                csrr    a0,th_shpmcounter27
>> + 178:  5fc02573                csrr    a0,th_shpmcounter28
>> + 17c:  5fd02573                csrr    a0,th_shpmcounter29
>> + 180:  5fe02573                csrr    a0,th_shpmcounter30
>> + 184:  5ff02573                csrr    a0,th_shpmcounter31
>> diff --git a/gas/testsuite/gas/riscv/thead-csr-list.s b/gas/testsuite/gas/riscv/thead-csr-list.s
>> new file mode 100644
>> index 00000000000..0784179683d
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/thead-csr-list.s
>> @@ -0,0 +1,98 @@
>> +csrr a0, th_mxstatus
>> +csrr a0, th_mhcr
>> +csrr a0, th_mcor
>> +csrr a0, th_mccr2
>> +csrr a0, th_mcer2
>> +csrr a0, th_mhint
>> +csrr a0, th_mrmr
>> +csrr a0, th_mrvbr
>> +csrr a0, th_mcer
>> +csrr a0, th_mcounterwen
>> +csrr a0, th_mcounterinten
>> +csrr a0, th_mcounterof
>> +csrr a0, th_mhint2
>> +csrr a0, th_mhint3
>> +csrr a0, th_mraddr
>> +csrr a0, th_mexstatus
>> +csrr a0, th_mnmicause
>> +csrr a0, th_mnmipc
>> +csrr a0, th_mhpmcr
>> +csrr a0, th_mhpmsr
>> +csrr a0, th_mhpmer
>> +csrr a0, th_msmpr
>> +csrr a0, th_mteecfg
>> +csrr a0, th_usp
>> +csrr a0, th_mcins
>> +csrr a0, th_mcindex
>> +csrr a0, th_mcdata0
>> +csrr a0, th_mcdata1
>> +csrr a0, th_meicr
>> +csrr a0, th_meicr2
>> +csrr a0, th_mebr
>> +csrr a0, th_nt_mstatus
>> +csrr a0, th_nt_mtvec
>> +csrr a0, th_nt_mie
>> +csrr a0, th_nt_mtvt
>> +csrr a0, th_nt_mepc
>> +csrr a0, th_nt_mcause
>> +csrr a0, th_nt_mip
>> +csrr a0, th_nt_mintstate
>> +csrr a0, th_nt_mxstatus
>> +csrr a0, th_nt_mebr
>> +csrr a0, th_nt_msp
>> +csrr a0, th_t_usp
>> +csrr a0, th_t_mdcr
>> +csrr a0, th_t_mpcr
>> +csrr a0, th_pmpteecfg
>> +csrr a0, th_mcpuid
>> +csrr a0, th_mapbaddr
>> +csrr a0, th_mwmsr
>> +csrr a0, th_fxcr
>> +csrr a0, th_smir
>> +csrr a0, th_smel
>> +csrr a0, th_smeh
>> +csrr a0, th_smcir
>> +csrr a0, th_sxstatus
>> +csrr a0, th_shcr
>> +csrr a0, th_scer2
>> +csrr a0, th_scer
>> +csrr a0, th_scounterinten
>> +csrr a0, th_scounterof
>> +csrr a0, th_shint
>> +csrr a0, th_shint2
>> +csrr a0, th_shpminhibit
>> +csrr a0, th_shpmcr
>> +csrr a0, th_shpmsr
>> +csrr a0, th_shpmer
>> +csrr a0, th_scycle
>> +csrr a0, th_shpmcounter1
>> +csrr a0, th_shpmcounter2
>> +csrr a0, th_shpmcounter3
>> +csrr a0, th_shpmcounter4
>> +csrr a0, th_shpmcounter5
>> +csrr a0, th_shpmcounter6
>> +csrr a0, th_shpmcounter7
>> +csrr a0, th_shpmcounter8
>> +csrr a0, th_shpmcounter9
>> +csrr a0, th_shpmcounter10
>> +csrr a0, th_shpmcounter11
>> +csrr a0, th_shpmcounter12
>> +csrr a0, th_shpmcounter13
>> +csrr a0, th_shpmcounter14
>> +csrr a0, th_shpmcounter15
>> +csrr a0, th_shpmcounter16
>> +csrr a0, th_shpmcounter17
>> +csrr a0, th_shpmcounter18
>> +csrr a0, th_shpmcounter19
>> +csrr a0, th_shpmcounter20
>> +csrr a0, th_shpmcounter21
>> +csrr a0, th_shpmcounter22
>> +csrr a0, th_shpmcounter23
>> +csrr a0, th_shpmcounter24
>> +csrr a0, th_shpmcounter25
>> +csrr a0, th_shpmcounter26
>> +csrr a0, th_shpmcounter27
>> +csrr a0, th_shpmcounter28
>> +csrr a0, th_shpmcounter29
>> +csrr a0, th_shpmcounter30
>> +csrr a0, th_shpmcounter31
>> diff --git a/gas/testsuite/gas/riscv/theadc-ext.d b/gas/testsuite/gas/riscv/theadc-ext.d
>> new file mode 100644
>> index 00000000000..b697f1b1c86
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/theadc-ext.d
>> @@ -0,0 +1,112 @@
>> +#as: -march=rv64gcxtheadc
>> +#objdump: -dr
>> +
>> +.*:[   ]+file format .*
>> +
>> +
>> +Disassembly of section .text:
>> +
>> +0000000000000000 <.text>:
>> +   0:  cff01073                csrw    0xcff,zero
>> +   4:  0010000b                th.dcache.call
>> +   8:  0030000b                th.dcache.ciall
>> +   c:  02b5000b                th.dcache.cipa  a0
>> +  10:  0235000b                th.dcache.cisw  a0
>> +  14:  0275000b                th.dcache.civa  a0
>> +  18:  0295000b                th.dcache.cpa   a0
>> +  1c:  0285000b                th.dcache.cpal1 a0
>> +  20:  0255000b                th.dcache.cva   a0
>> +  24:  0245000b                th.dcache.cval1 a0
>> +  28:  02a5000b                th.dcache.ipa   a0
>> +  2c:  0225000b                th.dcache.isw   a0
>> +  30:  0265000b                th.dcache.iva   a0
>> +  34:  0020000b                th.dcache.iall
>> +  38:  0215000b                th.dcache.csw   a0
>> +  3c:  0100000b                th.icache.iall
>> +  40:  0110000b                th.icache.ialls
>> +  44:  0305000b                th.icache.iva   a0
>> +  48:  0385000b                th.icache.ipa   a0
>> +  4c:  0160000b                th.l2cache.iall
>> +  50:  0150000b                th.l2cache.call
>> +  54:  0170000b                th.l2cache.ciall
>> +  58:  04b5000b                th.sfence.vmas  a0,a1
>> +  5c:  0180000b                th.sync
>> +  60:  01a0000b                th.sync.i
>> +  64:  0190000b                th.sync.s
>> +  68:  01b0000b                th.sync.is
>> +  6c:  02c5950b                th.addsl        a0,a1,a2,1
>> +  70:  20c5950b                th.mula a0,a1,a2
>> +  74:  22c5950b                th.muls a0,a1,a2
>> +  78:  24c5950b                th.mulaw        a0,a1,a2
>> +  7c:  26c5950b                th.mulsw        a0,a1,a2
>> +  80:  28c5950b                th.mulah        a0,a1,a2
>> +  84:  2ac5950b                th.mulsh        a0,a1,a2
>> +  88:  1105950b                th.srri a0,a1,16
>> +  8c:  1505950b                th.srriw        a0,a1,16
>> +  90:  40c5950b                th.mveqz        a0,a1,a2
>> +  94:  42c5950b                th.mvnez        a0,a1,a2
>> +  98:  8905950b                th.tst  a0,a1,16
>> +  9c:  8005950b                th.tstnbz       a0,a1
>> +  a0:  4105a50b                th.ext  a0,a1,16,16
>> +  a4:  4105b50b                th.extu a0,a1,16,16
>> +  a8:  8605950b                th.ff1  a0,a1
>> +  ac:  8405950b                th.ff0  a0,a1
>> +  b0:  8205950b                th.rev  a0,a1
>> +  b4:  9005950b                th.revw a0,a1
>> +  b8:  62b5600b                th.flrd ft0,a0,a1,1
>> +  bc:  42b5600b                th.flrw ft0,a0,a1,1
>> +  c0:  72b5600b                th.flurd        ft0,a0,a1,1
>> +  c4:  52b5600b                th.flurw        ft0,a0,a1,1
>> +  c8:  02c5c50b                th.lrb  a0,a1,a2,1
>> +  cc:  22c5c50b                th.lrh  a0,a1,a2,1
>> +  d0:  42c5c50b                th.lrw  a0,a1,a2,1
>> +  d4:  62c5c50b                th.lrd  a0,a1,a2,1
>> +  d8:  82c5c50b                th.lrbu a0,a1,a2,1
>> +  dc:  a2c5c50b                th.lrhu a0,a1,a2,1
>> +  e0:  c2c5c50b                th.lrwu a0,a1,a2,1
>> +  e4:  12c5c50b                th.lurb a0,a1,a2,1
>> +  e8:  32c5c50b                th.lurh a0,a1,a2,1
>> +  ec:  52c5c50b                th.lurw a0,a1,a2,1
>> +  f0:  72c5c50b                th.lurd a0,a1,a2,1
>> +  f4:  92c5c50b                th.lurbu        a0,a1,a2,1
>> +  f8:  b2c5c50b                th.lurhu        a0,a1,a2,1
>> +  fc:  d2c5c50b                th.lurwu        a0,a1,a2,1
>> + 100:  1af5c50b                th.lbia a0,\(a1\),15,1
>> + 104:  0af5c50b                th.lbib a0,\(a1\),15,1
>> + 108:  3af5c50b                th.lhia a0,\(a1\),15,1
>> + 10c:  2af5c50b                th.lhib a0,\(a1\),15,1
>> + 110:  5af5c50b                th.lwia a0,\(a1\),15,1
>> + 114:  4af5c50b                th.lwib a0,\(a1\),15,1
>> + 118:  7af5c50b                th.ldia a0,\(a1\),15,1
>> + 11c:  6af5c50b                th.ldib a0,\(a1\),15,1
>> + 120:  9af5c50b                th.lbuia        a0,\(a1\),15,1
>> + 124:  8af5c50b                th.lbuib        a0,\(a1\),15,1
>> + 128:  baf5c50b                th.lhuia        a0,\(a1\),15,1
>> + 12c:  aaf5c50b                th.lhuib        a0,\(a1\),15,1
>> + 130:  daf5c50b                th.lwuia        a0,\(a1\),15,1
>> + 134:  caf5c50b                th.lwuib        a0,\(a1\),15,1
>> + 138:  fab6450b                th.ldd  a0,a1,\(a2\),1
>> + 13c:  e2b6450b                th.lwd  a0,a1,\(a2\),1
>> + 140:  f2b6450b                th.lwud a0,a1,\(a2\),1
>> + 144:  62b5700b                th.fsrd ft0,a0,a1,1
>> + 148:  42b5700b                th.fsrw ft0,a0,a1,1
>> + 14c:  72b5700b                th.fsurd        ft0,a0,a1,1
>> + 150:  52b5700b                th.fsurw        ft0,a0,a1,1
>> + 154:  02c5d50b                th.srb  a0,a1,a2,1
>> + 158:  22c5d50b                th.srh  a0,a1,a2,1
>> + 15c:  42c5d50b                th.srw  a0,a1,a2,1
>> + 160:  62c5d50b                th.srd  a0,a1,a2,1
>> + 164:  12c5d50b                th.surb a0,a1,a2,1
>> + 168:  32c5d50b                th.surh a0,a1,a2,1
>> + 16c:  52c5d50b                th.surw a0,a1,a2,1
>> + 170:  72c5d50b                th.surd a0,a1,a2,1
>> + 174:  1af5d50b                th.sbia a0,\(a1\),15,1
>> + 178:  0af5d50b                th.sbib a0,\(a1\),15,1
>> + 17c:  3af5d50b                th.shia a0,\(a1\),15,1
>> + 180:  2af5d50b                th.shib a0,\(a1\),15,1
>> + 184:  5ac5d50b                th.swia a0,\(a1\),12,1
>> + 188:  4af5d50b                th.swib a0,\(a1\),15,1
>> + 18c:  7af5d50b                th.sdia a0,\(a1\),15,1
>> + 190:  6af5d50b                th.sdib a0,\(a1\),15,1
>> + 194:  fab6550b                th.sdd  a0,a1,\(a2\),1
>> + 198:  e2b6550b                th.swd  a0,a1,\(a2\),1
>> diff --git a/gas/testsuite/gas/riscv/theadc-ext.s b/gas/testsuite/gas/riscv/theadc-ext.s
>> new file mode 100644
>> index 00000000000..fda4319863b
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/theadc-ext.s
>> @@ -0,0 +1,115 @@
>> +.text
>> +
>> +th.wsc
>> +
>> +# cache ext
>> +th.dcache.call
>> +th.dcache.ciall
>> +th.dcache.cipa a0
>> +th.dcache.cisw a0
>> +th.dcache.civa a0
>> +th.dcache.cpa a0
>> +th.dcache.cpal1 a0
>> +th.dcache.cva a0
>> +th.dcache.cval1 a0
>> +th.dcache.ipa a0
>> +th.dcache.isw a0
>> +th.dcache.iva a0
>> +th.dcache.iall
>> +th.dcache.csw a0
>> +th.icache.iall
>> +th.icache.ialls
>> +th.icache.iva a0
>> +th.icache.ipa a0
>> +th.l2cache.iall
>> +th.l2cache.call
>> +th.l2cache.ciall
>> +
>> +# sync ext
>> +th.sfence.vmas       a0, a1
>> +th.sync
>> +th.sync.i
>> +th.sync.s
>> +th.sync.is
>> +
>> +# calc ext
>> +th.addsl             a0, a1, a2, 1
>> +th.mula              a0, a1, a2
>> +th.muls              a0, a1, a2
>> +th.mulaw             a0, a1, a2
>> +th.mulsw             a0, a1, a2
>> +th.mulah             a0, a1, a2
>> +th.mulsh             a0, a1, a2
>> +th.srri              a0, a1, 16
>> +th.srriw             a0, a1, 16
>> +th.mveqz             a0, a1, a2
>> +th.mvnez             a0, a1, a2
>> +
>> +# bit ext
>> +th.tst               a0, a1, 16
>> +th.tstnbz            a0, a1
>> +th.ext               a0, a1, 16, 16
>> +th.extu              a0, a1, 16, 16
>> +th.ff1               a0, a1
>> +th.ff0               a0, a1
>> +th.rev               a0, a1
>> +th.revw       a0, a1
>> +
>> +# load/store ext
>> +th.flrd       f0, a0, a1, 1
>> +th.flrw       f0, a0, a1, 1
>> +th.flurd      f0, a0, a1, 1
>> +th.flurw      f0, a0, a1, 1
>> +th.lrb               a0, a1, a2, 1
>> +th.lrh               a0, a1, a2, 1
>> +th.lrw               a0, a1, a2, 1
>> +th.lrd               a0, a1, a2, 1
>> +th.lrbu              a0, a1, a2, 1
>> +th.lrhu              a0, a1, a2, 1
>> +th.lrwu              a0, a1, a2, 1
>> +th.lurb              a0, a1, a2, 1
>> +th.lurh              a0, a1, a2, 1
>> +th.lurw              a0, a1, a2, 1
>> +th.lurd              a0, a1, a2, 1
>> +th.lurbu             a0, a1, a2, 1
>> +th.lurhu             a0, a1, a2, 1
>> +th.lurwu             a0, a1, a2, 1
>> +th.lbia       a0, (a1), 15, 1
>> +th.lbib       a0, (a1), 15, 1
>> +th.lhia       a0, (a1), 15, 1
>> +th.lhib       a0, (a1), 15, 1
>> +th.lwia       a0, (a1), 15, 1
>> +th.lwib       a0, (a1), 15, 1
>> +th.ldia       a0, (a1), 15, 1
>> +th.ldib       a0, (a1), 15, 1
>> +th.lbuia      a0, (a1), 15, 1
>> +th.lbuib      a0, (a1), 15, 1
>> +th.lhuia      a0, (a1), 15, 1
>> +th.lhuib      a0, (a1), 15, 1
>> +th.lwuia      a0, (a1), 15, 1
>> +th.lwuib      a0, (a1), 15, 1
>> +th.ldd               a0, a1, (a2), 1
>> +th.lwd               a0, a1, (a2), 1
>> +th.lwud              a0, a1, (a2), 1
>> +th.fsrd       f0, a0, a1, 1
>> +th.fsrw       f0, a0, a1, 1
>> +th.fsurd      f0, a0, a1, 1
>> +th.fsurw      f0, a0, a1, 1
>> +th.srb               a0, a1, a2, 1
>> +th.srh               a0, a1, a2, 1
>> +th.srw               a0, a1, a2, 1
>> +th.srd               a0, a1, a2, 1
>> +th.surb              a0, a1, a2, 1
>> +th.surh              a0, a1, a2, 1
>> +th.surw              a0, a1, a2, 1
>> +th.surd              a0, a1, a2, 1
>> +th.sbia              a0, (a1), 15, 1
>> +th.sbib              a0, (a1), 15, 1
>> +th.shia              a0, (a1), 15, 1
>> +th.shib              a0, (a1), 15, 1
>> +th.swia              a0, (a1), 12, 1
>> +th.swib              a0, (a1), 15, 1
>> +th.sdia              a0, (a1), 15, 1
>> +th.sdib              a0, (a1), 15, 1
>> +th.sdd               a0, a1, (a2), 1
>> +th.swd               a0, a1, (a2), 1
>> diff --git a/gas/testsuite/gas/riscv/theade-ext.d b/gas/testsuite/gas/riscv/theade-ext.d
>> new file mode 100644
>> index 00000000000..ff4234d323e
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/theade-ext.d
>> @@ -0,0 +1,62 @@
>> +#as: -march=rv32gcxtheade
>> +#objdump: -dr
>> +
>> +.*:[   ]+file format .*
>> +
>> +
>> +Disassembly of section .text:
>> +
>> +00000000 <.text>:
>> +[       ]+[0-9a-f]+:\s+cff01073                csrw    0xcff,zero
>> +[       ]+[0-9a-f]+:\s+02a5000b                th.dcache.ipa   a0
>> +[       ]+[0-9a-f]+:\s+0295000b                th.dcache.cpa   a0
>> +[       ]+[0-9a-f]+:\s+02b5000b                th.dcache.cipa  a0
>> +[       ]+[0-9a-f]+:\s+0225000b                th.dcache.isw   a0
>> +[       ]+[0-9a-f]+:\s+0215000b                th.dcache.csw   a0
>> +[       ]+[0-9a-f]+:\s+0235000b                th.dcache.cisw  a0
>> +[       ]+[0-9a-f]+:\s+0020000b                th.dcache.iall
>> +[       ]+[0-9a-f]+:\s+0010000b                th.dcache.call
>> +[       ]+[0-9a-f]+:\s+0030000b                th.dcache.ciall
>> +[       ]+[0-9a-f]+:\s+0100000b                th.icache.iall
>> +[       ]+[0-9a-f]+:\s+0385000b                th.icache.ipa   a0
>> +[       ]+[0-9a-f]+:\s+0180000b                th.sync
>> +[       ]+[0-9a-f]+:\s+01a0000b                th.sync.i
>> +[       ]+[0-9a-f]+:\s+02c5950b                th.addsl        a0,a1,a2,1
>> +[       ]+[0-9a-f]+:\s+1105950b                th.srri a0,a1,16
>> +[       ]+[0-9a-f]+:\s+20c5950b                th.mula a0,a1,a2
>> +[       ]+[0-9a-f]+:\s+28c5950b                th.mulah        a0,a1,a2
>> +[       ]+[0-9a-f]+:\s+22c5950b                th.muls a0,a1,a2
>> +[       ]+[0-9a-f]+:\s+2ac5950b                th.mulsh        a0,a1,a2
>> +[       ]+[0-9a-f]+:\s+40c5950b                th.mveqz        a0,a1,a2
>> +[       ]+[0-9a-f]+:\s+42c5950b                th.mvnez        a0,a1,a2
>> +[       ]+[0-9a-f]+:\s+4105a50b                th.ext  a0,a1,16,16
>> +[       ]+[0-9a-f]+:\s+4105b50b                th.extu a0,a1,16,16
>> +[       ]+[0-9a-f]+:\s+8605950b                th.ff1  a0,a1
>> +[       ]+[0-9a-f]+:\s+8405950b                th.ff0  a0,a1
>> +[       ]+[0-9a-f]+:\s+8205950b                th.rev  a0,a1
>> +[       ]+[0-9a-f]+:\s+8905950b                th.tst  a0,a1,16
>> +[       ]+[0-9a-f]+:\s+8005950b                th.tstnbz       a0,a1
>> +[       ]+[0-9a-f]+:\s+02c5c50b                th.lrb  a0,a1,a2,1
>> +[       ]+[0-9a-f]+:\s+22c5c50b                th.lrh  a0,a1,a2,1
>> +[       ]+[0-9a-f]+:\s+42c5c50b                th.lrw  a0,a1,a2,1
>> +[       ]+[0-9a-f]+:\s+82c5c50b                th.lrbu a0,a1,a2,1
>> +[       ]+[0-9a-f]+:\s+a2c5c50b                th.lrhu a0,a1,a2,1
>> +[       ]+[0-9a-f]+:\s+1af5c50b                th.lbia a0,\(a1\),15,1
>> +[       ]+[0-9a-f]+:\s+0af5c50b                th.lbib a0,\(a1\),15,1
>> +[       ]+[0-9a-f]+:\s+3af5c50b                th.lhia a0,\(a1\),15,1
>> +[       ]+[0-9a-f]+:\s+2af5c50b                th.lhib a0,\(a1\),15,1
>> +[       ]+[0-9a-f]+:\s+5af5c50b                th.lwia a0,\(a1\),15,1
>> +[       ]+[0-9a-f]+:\s+4af5c50b                th.lwib a0,\(a1\),15,1
>> +[       ]+[0-9a-f]+:\s+02c5d50b                th.srb  a0,a1,a2,1
>> +[       ]+[0-9a-f]+:\s+22c5d50b                th.srh  a0,a1,a2,1
>> +[       ]+[0-9a-f]+:\s+42c5d50b                th.srw  a0,a1,a2,1
>> +[       ]+[0-9a-f]+:\s+1af5d50b                th.sbia a0,\(a1\),15,1
>> +[       ]+[0-9a-f]+:\s+0af5d50b                th.sbib a0,\(a1\),15,1
>> +[       ]+[0-9a-f]+:\s+3af5d50b                th.shia a0,\(a1\),15,1
>> +[       ]+[0-9a-f]+:\s+2af5d50b                th.shib a0,\(a1\),15,1
>> +[       ]+[0-9a-f]+:\s+5ac5d50b                th.swia a0,\(a1\),12,1
>> +[       ]+[0-9a-f]+:\s+4af5d50b                th.swib a0,\(a1\),15,1
>> +[       ]+[0-9a-f]+:\s+c000150b                th.fmv.x.hw     a0,ft0
>> +[       ]+[0-9a-f]+:\s+a005100b                th.fmv.hw.x     ft0,a0
>> +[       ]+[0-9a-f]+:\s+0040000b                th.ipush
>> +[       ]+[0-9a-f]+:\s+0050000b                th.ipop
>> diff --git a/gas/testsuite/gas/riscv/theade-ext.s b/gas/testsuite/gas/riscv/theade-ext.s
>> new file mode 100644
>> index 00000000000..a56385802b1
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/theade-ext.s
>> @@ -0,0 +1,66 @@
>> +.text
>> +
>> +th.wsc
>> +
>> +# cache ext
>> +th.dcache.ipa a0
>> +th.dcache.cpa a0
>> +th.dcache.cipa a0
>> +th.dcache.isw a0
>> +th.dcache.csw a0
>> +th.dcache.cisw a0
>> +th.dcache.iall
>> +th.dcache.call
>> +th.dcache.ciall
>> +th.icache.iall
>> +th.icache.ipa a0
>> +
>> +# sync ext
>> +th.sync
>> +th.sync.i
>> +
>> +# calc ext
>> +th.addsl             a0, a1, a2, 1
>> +th.srri              a0, a1, 16
>> +th.mula              a0, a1, a2
>> +th.mulah             a0, a1, a2
>> +th.muls              a0, a1, a2
>> +th.mulsh             a0, a1, a2
>> +th.mveqz             a0, a1, a2
>> +th.mvnez             a0, a1, a2
>> +
>> +# bit ext
>> +th.ext               a0, a1, 16, 16
>> +th.extu              a0, a1, 16, 16
>> +th.ff1               a0, a1
>> +th.ff0               a0, a1
>> +th.rev               a0, a1
>> +th.tst               a0, a1, 16
>> +th.tstnbz            a0, a1
>> +
>> +# load/store ext
>> +th.lrb               a0, a1, a2, 1
>> +th.lrh               a0, a1, a2, 1
>> +th.lrw               a0, a1, a2, 1
>> +th.lrbu              a0, a1, a2, 1
>> +th.lrhu              a0, a1, a2, 1
>> +th.lbia       a0, (a1), 15, 1
>> +th.lbib       a0, (a1), 15, 1
>> +th.lhia       a0, (a1), 15, 1
>> +th.lhib       a0, (a1), 15, 1
>> +th.lwia       a0, (a1), 15, 1
>> +th.lwib       a0, (a1), 15, 1
>> +th.srb               a0, a1, a2, 1
>> +th.srh               a0, a1, a2, 1
>> +th.srw               a0, a1, a2, 1
>> +th.sbia              a0, (a1), 15, 1
>> +th.sbib              a0, (a1), 15, 1
>> +th.shia              a0, (a1), 15, 1
>> +th.shib              a0, (a1), 15, 1
>> +th.swia              a0, (a1), 12, 1
>> +th.swib              a0, (a1), 15, 1
>> +
>> +th.fmv.x.hw   a0, f0
>> +th.fmv.hw.x   f0, a0
>> +th.ipush
>> +th.ipop
>> diff --git a/include/opcode/riscv-opc-thead.h b/include/opcode/riscv-opc-thead.h
>> new file mode 100644
>> index 00000000000..98935f6b2b0
>> --- /dev/null
>> +++ b/include/opcode/riscv-opc-thead.h
>> @@ -0,0 +1,571 @@
>> +/* riscv-opcextended.h.  RISC-V extended instruction opcode.
>> +   Copyright (C) 2021 Free Software Foundation, Inc.
>> +
>> +   This file is part of GDB, GAS, and the GNU binutils.
>> +
>> +   GDB, GAS, and the GNU binutils are free software; you can redistribute
>> +   them and/or modify them under the terms of the GNU General Public
>> +   License as published by the Free Software Foundation; either version
>> +   3, or (at your option) any later version.
>> +
>> +   GDB, GAS, and the GNU binutils are distributed in the hope that they
>> +   will be useful, but WITHOUT ANY WARRANTY; without even the implied
>> +   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
>> +   the GNU General Public License for more details.
>> +
>> +   You should have received a copy of the GNU General Public License
>> +   along with this program; see the file COPYING3. If not,
>> +   see <http://www.gnu.org/licenses/>.  */
>> +
>> +#ifndef __RISCV_OPC_THEAD__
>> +#define __RISCV_OPC_THEAD__
>> +/* Opcodes for T-HEAD.  */
>> +#define MATCH_DCACHE_CALL      0x0010000b
>> +#define MASK_DCACHE_CALL       0xffffffff
>> +#define MATCH_DCACHE_IALL      0x0020000b
>> +#define MASK_DCACHE_IALL       0xffffffff
>> +#define MATCH_DCACHE_CSW       0x0210000b
>> +#define MASK_DCACHE_CSW                0xfff07fff
>> +#define MATCH_DCACHE_ISW       0x0220000b
>> +#define MASK_DCACHE_ISW                0xfff07fff
>> +#define MATCH_DCACHE_CIALL     0x0030000b
>> +#define MASK_DCACHE_CIALL      0xffffffff
>> +#define MATCH_DCACHE_CISW      0x0230000b
>> +#define MASK_DCACHE_CISW       0xfff07fff
>> +#define MATCH_DCACHE_CVAL1     0x0240000b
>> +#define MASK_DCACHE_CVAL1      0xfff07fff
>> +#define MATCH_DCACHE_CVA       0x0250000b
>> +#define MASK_DCACHE_CVA                0xfff07fff
>> +#define MATCH_DCACHE_IVA       0x0260000b
>> +#define MASK_DCACHE_IVA                0xfff07fff
>> +#define MATCH_DCACHE_CIVA      0x0270000b
>> +#define MASK_DCACHE_CIVA       0xfff07fff
>> +#define MATCH_DCACHE_CPAL1     0x0280000b
>> +#define MASK_DCACHE_CPAL1      0xfff07fff
>> +#define MATCH_DCACHE_CPA       0x0290000b
>> +#define MASK_DCACHE_CPA                0xfff07fff
>> +#define MATCH_DCACHE_IPA       0x02a0000b
>> +#define MASK_DCACHE_IPA                0xfff07fff
>> +#define MATCH_DCACHE_CIPA      0x02b0000b
>> +#define MASK_DCACHE_CIPA       0xfff07fff
>> +#define MATCH_ICACHE_IALL      0x0100000b
>> +#define MASK_ICACHE_IALL       0xffffffff
>> +#define MATCH_ICACHE_IALLS     0x0110000b
>> +#define MASK_ICACHE_IALLS      0xffffffff
>> +#define MATCH_ICACHE_IVA       0x0300000b
>> +#define MASK_ICACHE_IVA                0xfff07fff
>> +#define MATCH_ICACHE_IPA       0x0380000b
>> +#define MASK_ICACHE_IPA                0xfff07fff
>> +#define MATCH_L2CACHE_CALL     0x0150000b
>> +#define MASK_L2CACHE_CALL      0xffffffff
>> +#define MATCH_L2CACHE_IALL     0x0160000b
>> +#define MASK_L2CACHE_IALL      0xffffffff
>> +#define MATCH_L2CACHE_CIALL    0x0170000b
>> +#define MASK_L2CACHE_CIALL     0xffffffff
>> +#define MATCH_SYNC             0x0180000b
>> +#define MASK_SYNC              0xffffffff
>> +#define MATCH_SYNC_S           0x0190000b
>> +#define MASK_SYNC_S            0xffffffff
>> +#define MATCH_SYNC_I           0x01a0000b
>> +#define MASK_SYNC_I            0xffffffff
>> +#define MATCH_SYNC_IS          0x01b0000b
>> +#define MASK_SYNC_IS           0xffffffff
>> +#define MATCH_SFENCE_VMAS      0x0400000b
>> +#define MASK_SFENCE_VMAS       0xfe007fff
>> +#define MATCH_TSTNBZ           0x8000100b
>> +#define MASK_TSTNBZ            0xfff0707f
>> +#define MATCH_MVEQZ            0x4000100b
>> +#define MASK_MVEQZ             0xfe00707f
>> +#define MATCH_MVNEZ            0x4200100b
>> +#define MASK_MVNEZ             0xfe00707f
>> +#define MATCH_MULA             0x2000100b
>> +#define MASK_MULA              0xfe00707f
>> +#define MATCH_MULS             0x2200100b
>> +#define MASK_MULS              0xfe00707f
>> +#define MATCH_MULAW            0x2400100b
>> +#define MASK_MULAW             0xfe00707f
>> +#define MATCH_MULSW            0x2600100b
>> +#define MASK_MULSW             0xfe00707f
>> +#define MATCH_MULAH            0x2800100b
>> +#define MASK_MULAH             0xfe00707f
>> +#define MATCH_MULSH            0x2a00100b
>> +#define MASK_MULSH             0xfe00707f
>> +#define MATCH_EXT              0x0000200b
>> +#define MASK_EXT               0x0000707f
>> +#define MATCH_EXTU             0x0000300b
>> +#define MASK_EXTU              0x0000707f
>> +#define MATCH_LRB              0x0000400b
>> +#define MASK_LRB               0xf800707f
>> +#define MATCH_LRH              0x2000400b
>> +#define MASK_LRH               0xf800707f
>> +#define MATCH_LRW              0x4000400b
>> +#define MASK_LRW               0xf800707f
>> +#define MATCH_LRD              0x6000400b
>> +#define MASK_LRD               0xf800707f
>> +#define MATCH_LRBU             0x8000400b
>> +#define MASK_LRBU              0xf800707f
>> +#define MATCH_LRHU             0xa000400b
>> +#define MASK_LRHU              0xf800707f
>> +#define MATCH_LRWU             0xc000400b
>> +#define MASK_LRWU              0xf800707f
>> +#define MATCH_LURB             0x1000400b
>> +#define MASK_LURB              0xf800707f
>> +#define MATCH_LURH             0x3000400b
>> +#define MASK_LURH              0xf800707f
>> +#define MATCH_LURW             0x5000400b
>> +#define MASK_LURW              0xf800707f
>> +#define MATCH_LURD             0x7000400b
>> +#define MASK_LURD              0xf800707f
>> +#define MATCH_LURBU            0x9000400b
>> +#define MASK_LURBU             0xf800707f
>> +#define MATCH_LURHU            0xb000400b
>> +#define MASK_LURHU             0xf800707f
>> +#define MATCH_LURWU            0xd000400b
>> +#define MASK_LURWU             0xf800707f
>> +#define MATCH_REV              0x8200100b
>> +#define MASK_REV               0xfff0707f
>> +#define MATCH_FF0              0x8400100b
>> +#define MASK_FF0               0xfff0707f
>> +#define MATCH_FF1              0x8600100b
>> +#define MASK_FF1               0xfff0707f
>> +#define MATCH_SRB              0x0000500b
>> +#define MASK_SRB               0xf800707f
>> +#define MATCH_SRH              0x2000500b
>> +#define MASK_SRH               0xf800707f
>> +#define MATCH_SRW              0x4000500b
>> +#define MASK_SRW               0xf800707f
>> +#define MATCH_SRD              0x6000500b
>> +#define MASK_SRD               0xf800707f
>> +#define MATCH_SURB             0x1000500b
>> +#define MASK_SURB              0xf800707f
>> +#define MATCH_SURH             0x3000500b
>> +#define MASK_SURH              0xf800707f
>> +#define MATCH_SURW             0x5000500b
>> +#define MASK_SURW              0xf800707f
>> +#define MATCH_SURD             0x7000500b
>> +#define MASK_SURD              0xf800707f
>> +#define MATCH_TST              0x8800100b
>> +#define MASK_TST               0xfc00707f
>> +#define MATCH_SRRIW            0x1400100b
>> +#define MASK_SRRIW             0xfe00707f
>> +#define MATCH_SRRI             0x1000100b
>> +#define MASK_SRRI              0xfc00707f
>> +#define MATCH_ADDSL            0x0000100b
>> +#define MASK_ADDSL             0xf800707f
>> +#define MATCH_SWD              0xe000500b
>> +#define MASK_SWD               0xf800707f
>> +#define MATCH_SDD              0xf800500b
>> +#define MASK_SDD               0xf800707f
>> +#define MATCH_SDIA             0x7800500b
>> +#define MASK_SDIA              0xf800707f
>> +#define MATCH_SDIB             0x6800500b
>> +#define MASK_SDIB              0xf800707f
>> +#define MATCH_SWIA             0x5800500b
>> +#define MASK_SWIA              0xf800707f
>> +#define MATCH_SWIB             0x4800500b
>> +#define MASK_SWIB              0xf800707f
>> +#define MATCH_SHIB             0x2800500b
>> +#define MASK_SHIB              0xf800707f
>> +#define MATCH_SHIA             0x3800500b
>> +#define MASK_SHIA              0xf800707f
>> +#define MATCH_SBIA             0x1800500b
>> +#define MASK_SBIA              0xf800707f
>> +#define MATCH_SBIB             0x0800500b
>> +#define MASK_SBIB              0xf800707f
>> +#define MATCH_LWUD             0xf000400b
>> +#define MASK_LWUD              0xf800707f
>> +#define MATCH_LWD              0xe000400b
>> +#define MASK_LWD               0xf800707f
>> +#define MATCH_LDD              0xf800400b
>> +#define MASK_LDD               0xf800707f
>> +#define MATCH_LWUIA            0xd800400b
>> +#define MASK_LWUIA             0xf800707f
>> +#define MATCH_LWUIB            0xc800400b
>> +#define MASK_LWUIB             0xf800707f
>> +#define MATCH_LHUIA            0xb800400b
>> +#define MASK_LHUIA             0xf800707f
>> +#define MATCH_LHUIB            0xa800400b
>> +#define MASK_LHUIB             0xf800707f
>> +#define MATCH_LBUIA            0x9800400b
>> +#define MASK_LBUIA             0xf800707f
>> +#define MATCH_LBUIB            0x8800400b
>> +#define MASK_LBUIB             0xf800707f
>> +#define MATCH_LDIA             0x7800400b
>> +#define MASK_LDIA              0xf800707f
>> +#define MATCH_LDIB             0x6800400b
>> +#define MASK_LDIB              0xf800707f
>> +#define MATCH_LWIA             0x5800400b
>> +#define MASK_LWIA              0xf800707f
>> +#define MATCH_LWIB             0x4800400b
>> +#define MASK_LWIB              0xf800707f
>> +#define MATCH_LHIA             0x3800400b
>> +#define MASK_LHIA              0xf800707f
>> +#define MATCH_LHIB             0x2800400b
>> +#define MASK_LHIB              0xf800707f
>> +#define MATCH_LBIA             0x1800400b
>> +#define MASK_LBIA              0xf800707f
>> +#define MATCH_LBIB             0x0800400b
>> +#define MASK_LBIB              0xf800707f
>> +#define MATCH_REVW             0x9000100b
>> +#define MASK_REVW              0xfff0707f
>> +#define MATCH_FSURD            0x7000700b
>> +#define MASK_FSURD             0xf800707f
>> +#define MATCH_FSURW            0x5000700b
>> +#define MASK_FSURW             0xf800707f
>> +#define MATCH_FSRD             0x6000700b
>> +#define MASK_FSRD              0xf800707f
>> +#define MATCH_FSRW             0x4000700b
>> +#define MASK_FSRW              0xf800707f
>> +#define MATCH_FLURD            0x7000600b
>> +#define MASK_FLURD             0xf800707f
>> +#define MATCH_FLURW            0x5000600b
>> +#define MASK_FLURW             0xf800707f
>> +#define MATCH_FLRD             0x6000600b
>> +#define MASK_FLRD              0xf800707f
>> +#define MATCH_FLRW             0x4000600b
>> +#define MASK_FLRW              0xf800707f
>> +#define MATCH_IPUSH            0x0040000b
>> +#define MASK_IPUSH             0xffffffff
>> +#define MATCH_IPOP             0x0050000b
>> +#define MASK_IPOP              0xffffffff
>> +/* T-HEAD security.  */
>> +#define MATCH_WSC              0xcff01073
>> +#define MASK_WSC               0xffffffff
>> +/* T-HEAD Float for rv32.  */
>> +#define MATCH_FMV_X_HW         0xc000100b
>> +#define MASK_FMV_X_HW          0xfff0707f
>> +#define MATCH_FMV_HW_X         0xa000100b
>> +#define MASK_FMV_HW_X          0xfff0707f
>> +#endif /* __RISCV_OPC_THEAD__ */
>> +#ifdef DECLARE_INSN
>> +DECLARE_INSN(th_wsc, MATCH_WSC, MASK_WSC)
>> +DECLARE_INSN(th_dcache_giall, MATCH_DCACHE_IALL, MASK_DCACHE_IALL)
>> +DECLARE_INSN(th_dcache_gcall, MATCH_DCACHE_CALL, MASK_DCACHE_CALL)
>> +DECLARE_INSN(th_dcache_gciall, MATCH_DCACHE_CIALL, MASK_DCACHE_CIALL)
>> +DECLARE_INSN(th_dcache_gisw, MATCH_DCACHE_ISW, MASK_DCACHE_ISW)
>> +DECLARE_INSN(th_dcache_gcsw, MATCH_DCACHE_CSW, MASK_DCACHE_CSW)
>> +DECLARE_INSN(th_dcache_gcisw, MATCH_DCACHE_CISW, MASK_DCACHE_CISW)
>> +DECLARE_INSN(th_dcache_giva, MATCH_DCACHE_IVA, MASK_DCACHE_IVA)
>> +DECLARE_INSN(th_dcache_gcva, MATCH_DCACHE_CVA, MASK_DCACHE_CVA)
>> +DECLARE_INSN(th_dcache_gcval1, MATCH_DCACHE_CVAL1, MASK_DCACHE_CVAL1)
>> +DECLARE_INSN(th_dcache_gciva, MATCH_DCACHE_CIVA, MASK_DCACHE_CIVA)
>> +DECLARE_INSN(th_dcache_gipa, MATCH_DCACHE_IPA, MASK_DCACHE_IPA)
>> +DECLARE_INSN(th_dcache_gcpa, MATCH_DCACHE_CPA, MASK_DCACHE_CPA)
>> +DECLARE_INSN(th_dcache_gcpal1, MATCH_DCACHE_CPAL1, MASK_DCACHE_CPAL1)
>> +DECLARE_INSN(th_dcache_gcipa, MATCH_DCACHE_CIPA, MASK_DCACHE_CIPA)
>> +DECLARE_INSN(th_icache_giall, MATCH_ICACHE_IALL, MASK_ICACHE_IALL)
>> +DECLARE_INSN(th_icache_gialls, MATCH_ICACHE_IALLS, MASK_ICACHE_IALLS)
>> +DECLARE_INSN(th_icache_giva, MATCH_ICACHE_IVA, MASK_ICACHE_IVA)
>> +DECLARE_INSN(th_icache_gipa, MATCH_ICACHE_IPA, MASK_ICACHE_IPA)
>> +DECLARE_INSN(th_l2cache_giall, MATCH_L2CACHE_IALL, MASK_L2CACHE_IALL)
>> +DECLARE_INSN(th_l2cache_gcall, MATCH_L2CACHE_CALL, MASK_L2CACHE_CALL)
>> +DECLARE_INSN(th_l2cache_gciall, MATCH_L2CACHE_CIALL, MASK_L2CACHE_CIALL)
>> +DECLARE_INSN(th_sync, MATCH_SYNC, MASK_SYNC)
>> +DECLARE_INSN(th_sync_gi, MATCH_SYNC_I, MASK_SYNC_I)
>> +DECLARE_INSN(th_sync_gs, MATCH_SYNC_S, MASK_SYNC_S)
>> +DECLARE_INSN(th_sync_gis, MATCH_SYNC_IS, MASK_SYNC_IS)
>> +DECLARE_INSN(th_tstnbz, MATCH_TSTNBZ, MASK_TSTNBZ)
>> +DECLARE_INSN(th_mula, MATCH_MULA, MASK_MULA)
>> +DECLARE_INSN(th_muls, MATCH_MULS, MASK_MULS)
>> +DECLARE_INSN(th_mulah, MATCH_MULAH, MASK_MULAH)
>> +DECLARE_INSN(th_mulsh, MATCH_MULSH, MASK_MULSH)
>> +DECLARE_INSN(th_sfence_vmas, MATCH_SFENCE_VMAS, MASK_SFENCE_VMAS)
>> +DECLARE_INSN(th_mveqz, MATCH_MVEQZ, MASK_MVEQZ)
>> +DECLARE_INSN(th_mvnez, MATCH_MVNEZ, MASK_MVNEZ)
>> +DECLARE_INSN(th_mulaw, MATCH_MULAW, MASK_MULAW)
>> +DECLARE_INSN(th_mulsw, MATCH_MULSW, MASK_MULSW)
>> +DECLARE_INSN(th_ext, MATCH_EXT, MASK_EXT)
>> +DECLARE_INSN(th_extu, MATCH_EXTU, MASK_EXTU)
>> +DECLARE_INSN(th_ff1, MATCH_FF1, MASK_FF1)
>> +DECLARE_INSN(th_ff0, MATCH_FF0, MASK_FF1)
>> +DECLARE_INSN(th_rev, MATCH_REV, MASK_REV)
>> +DECLARE_INSN(th_lrb, MATCH_LRB, MASK_LRB)
>> +DECLARE_INSN(th_lrbu, MATCH_LRBU, MASK_LRBU)
>> +DECLARE_INSN(th_lrh, MATCH_LRH, MASK_LRH)
>> +DECLARE_INSN(th_lrhu, MATCH_LRHU, MASK_LRHU)
>> +DECLARE_INSN(th_lrw, MATCH_LRW, MASK_LRW)
>> +DECLARE_INSN(th_lrwu, MATCH_LRWU, MASK_LRWU)
>> +DECLARE_INSN(th_srb, MATCH_SRB, MASK_SRB)
>> +DECLARE_INSN(th_srh, MATCH_SRH, MASK_SRH)
>> +DECLARE_INSN(th_srw, MATCH_SRW, MASK_SRW)
>> +DECLARE_INSN(th_lrd, MATCH_LRD, MASK_LRD)
>> +DECLARE_INSN(th_srd, MATCH_SRD, MASK_SRD)
>> +DECLARE_INSN(th_lurb, MATCH_LURB, MASK_LURB)
>> +DECLARE_INSN(th_lurbu, MATCH_LURBU, MASK_LURBU)
>> +DECLARE_INSN(th_lurh, MATCH_LURH, MASK_LURH)
>> +DECLARE_INSN(th_lurhu, MATCH_LURHU, MASK_LURHU)
>> +DECLARE_INSN(th_lurw, MATCH_LURW, MASK_LURW)
>> +DECLARE_INSN(th_lurwu, MATCH_LURWU, MASK_LURWU)
>> +DECLARE_INSN(th_lurd, MATCH_LURD, MASK_LURD)
>> +DECLARE_INSN(th_surb, MATCH_SURB, MASK_SURB)
>> +DECLARE_INSN(th_surh, MATCH_SURH, MASK_SURH)
>> +DECLARE_INSN(th_surw, MATCH_SURW, MASK_SURW)
>> +DECLARE_INSN(th_surd, MATCH_SURD, MASK_SURD)
>> +DECLARE_INSN(th_tst, MATCH_TST, MASK_TST)
>> +DECLARE_INSN(th_srriw, MATCH_SRRIW, MASK_SRRIW)
>> +DECLARE_INSN(th_srri, MATCH_SRRI, MASK_SRRI)
>> +DECLARE_INSN(th_addsl, MATCH_ADDSL, MASK_ADDSL)
>> +DECLARE_INSN(th_lwd, MATCH_LWD, MASK_LWD)
>> +DECLARE_INSN(th_ldd, MATCH_LDD, MASK_LDD)
>> +DECLARE_INSN(th_swd, MATCH_SWD, MASK_SWD)
>> +DECLARE_INSN(th_sdd, MATCH_SDD, MASK_SDD)
>> +DECLARE_INSN(th_sdia, MATCH_SDIA, MASK_SDIA)
>> +DECLARE_INSN(th_sdib, MATCH_SDIB, MASK_SDIB)
>> +DECLARE_INSN(th_lwud, MATCH_LWUD, MASK_LWUD)
>> +DECLARE_INSN(th_swia, MATCH_SWIA, MASK_SWIA)
>> +DECLARE_INSN(th_swib, MATCH_SWIB, MASK_SWIB)
>> +DECLARE_INSN(th_shia, MATCH_SHIA, MASK_SHIA)
>> +DECLARE_INSN(th_shib, MATCH_SHIB, MASK_SHIB)
>> +DECLARE_INSN(th_sbia, MATCH_SBIA, MASK_SBIA)
>> +DECLARE_INSN(th_sbib, MATCH_SBIB, MASK_SBIB)
>> +DECLARE_INSN(th_lwuia, MATCH_LWUIA, MASK_LWUIA)
>> +DECLARE_INSN(th_lwuib, MATCH_LWUIB, MASK_LWUIB)
>> +DECLARE_INSN(th_lhuia, MATCH_LHUIA, MASK_LHUIA)
>> +DECLARE_INSN(th_lhuib, MATCH_LHUIB, MASK_LHUIB)
>> +DECLARE_INSN(th_lbuia, MATCH_LBUIA, MASK_LBUIA)
>> +DECLARE_INSN(th_lbuib, MATCH_LBUIB, MASK_LBUIB)
>> +DECLARE_INSN(th_ldia, MATCH_LDIA, MASK_LDIA)
>> +DECLARE_INSN(th_ldib, MATCH_LDIB, MASK_LDIB)
>> +DECLARE_INSN(th_lwia, MATCH_LWIA, MASK_LWIA)
>> +DECLARE_INSN(th_lwib, MATCH_LWIB, MASK_LWIB)
>> +DECLARE_INSN(th_lhia, MATCH_LHIA, MASK_LHIA)
>> +DECLARE_INSN(th_lhib, MATCH_LHIB, MASK_LHIB)
>> +DECLARE_INSN(th_lbia, MATCH_LBIA, MASK_LBIA)
>> +DECLARE_INSN(th_lbib, MATCH_LBIB, MASK_LBIB)
>> +DECLARE_INSN(th_fsurd, MATCH_FSURD, MASK_FSURD)
>> +DECLARE_INSN(th_revw, MATCH_REVW, MASK_REVW)
>> +DECLARE_INSN(th_fsurw, MATCH_FSURW, MASK_FSURW)
>> +DECLARE_INSN(th_flurd, MATCH_FLURD, MASK_FLURD)
>> +DECLARE_INSN(th_flurw, MATCH_FLURW, MASK_FLURW)
>> +DECLARE_INSN(th_fsrd, MATCH_FSRD, MASK_FSRD)
>> +DECLARE_INSN(th_fsrw, MATCH_FSRW, MASK_FSRW)
>> +DECLARE_INSN(th_flrd, MATCH_FLRD, MASK_FLRD)
>> +DECLARE_INSN(th_flrw, MATCH_FLRW, MASK_FLRW)
>> +DECLARE_INSN(th_ipush, MATCH_IPUSH, MASK_IPUSH)
>> +DECLARE_INSN(th_ipop, MATCH_IPOP, MASK_IPOP)
>> +DECLARE_INSN(th_fmv_x_hw, MATCH_FMV_X_HW, MASK_FMV_X_HW)
>> +DECLARE_INSN(th_fmv_hw_x, MATCH_FMV_HW_X, MASK_FMV_HW_X)
>> +#endif /* DECLARE_INSN */
>> +#ifdef DECLARE_CSR
>> +/* T-HEAD M mode CSR.  */
>> +#define CSR_THEAD_MXSTATUS 0x7c0
>> +#define CSR_THEAD_MHCR 0x7c1
>> +#define CSR_THEAD_MCOR 0x7c2
>> +#define CSR_THEAD_MCCR2 0x7c3
>> +#define CSR_THEAD_MCER2 0x7c4
>> +#define CSR_THEAD_MHINT 0x7c5
>> +#define CSR_THEAD_MRMR 0x7c6
>> +#define CSR_THEAD_MRVBR 0x7c7
>> +#define CSR_THEAD_MCER 0x7c8
>> +#define CSR_THEAD_MCOUNTERWEN 0x7c9
>> +#define CSR_THEAD_MCOUNTERINTEN 0x7ca
>> +#define CSR_THEAD_MCOUNTEROF 0x7cb
>> +#define CSR_THEAD_MHINT2 0x7cc
>> +#define CSR_THEAD_MHINT3 0x7cd
>> +#define CSR_THEAD_MRADDR 0x7e0
>> +#define CSR_THEAD_MEXSTATUS 0x7e1
>> +#define CSR_THEAD_MNMICAUSE 0x7e2
>> +#define CSR_THEAD_MNMIPC 0x7e3
>> +#define CSR_THEAD_MHPMCR 0x7f0
>> +#define CSR_THEAD_MHPMSR 0x7f1
>> +#define CSR_THEAD_MHPMER 0x7f2
>> +#define CSR_THEAD_MSMPR 0x7f3
>> +#define CSR_THEAD_MTEECFG 0x7f4
>> +#define CSR_THEAD_MZONEID 0x7f5
>> +#define CSR_THEAD_ML2CPID 0x7f6
>> +#define CSR_THEAD_ML2WP 0x7f7
>> +#define CSR_THEAD_MDTCMCR 0x7f8
>> +#define CSR_THEAD_USP 0x7d1
>> +#define CSR_THEAD_MCINS 0x7d2
>> +#define CSR_THEAD_MCINDEX 0x7d3
>> +#define CSR_THEAD_MCDATA0 0x7d4
>> +#define CSR_THEAD_MCDATA1 0x7d5
>> +#define CSR_THEAD_MEICR 0x7d6
>> +#define CSR_THEAD_MEICR2 0x7d7
>> +#define CSR_THEAD_MBEADDR 0x7d8
>> +#define CSR_THEAD_MCPUID 0xfc0
>> +#define CSR_THEAD_MAPBADDR 0xfc1
>> +#define CSR_THEAD_MWMSR 0xfc2
>> +#define CSR_THEAD_MHALTCAUSE 0xfe0
>> +#define CSR_THEAD_MDBGINFO 0xfe1
>> +#define CSR_THEAD_MPCFIFO 0xfe2
>> +/* T-HEAD S mode CSR.  */
>> +#define CSR_THEAD_SXSTATUS 0x5c0
>> +#define CSR_THEAD_SHCR 0x5c1
>> +#define CSR_THEAD_SCER2 0x5c2
>> +#define CSR_THEAD_SCER 0x5c3
>> +#define CSR_THEAD_SCOUNTERINTEN 0x5c4
>> +#define CSR_THEAD_SCOUNTEROF 0x5c5
>> +#define CSR_THEAD_SHINT 0x5c6
>> +#define CSR_THEAD_SHINT2 0x5c7
>> +#define CSR_THEAD_SHPMINHIBIT 0x5c8
>> +#define CSR_THEAD_SHPMCR 0x5c9
>> +#define CSR_THEAD_SHPMSR 0x5ca
>> +#define CSR_THEAD_SHPMER 0x5cb
>> +#define CSR_THEAD_SL2CPID 0x5cc
>> +#define CSR_THEAD_SL2WP 0x5cd
>> +#define CSR_THEAD_SBEADDR 0x5d0
>> +#define CSR_THEAD_SCYCLE 0x5e0
>> +#define CSR_THEAD_SHPMCOUNTER1 0x5e1
>> +#define CSR_THEAD_SHPMCOUNTER2 0x5e2
>> +#define CSR_THEAD_SHPMCOUNTER3 0x5e3
>> +#define CSR_THEAD_SHPMCOUNTER4 0x5e4
>> +#define CSR_THEAD_SHPMCOUNTER5 0x5e5
>> +#define CSR_THEAD_SHPMCOUNTER6 0x5e6
>> +#define CSR_THEAD_SHPMCOUNTER7 0x5e7
>> +#define CSR_THEAD_SHPMCOUNTER8 0x5e8
>> +#define CSR_THEAD_SHPMCOUNTER9 0x5e9
>> +#define CSR_THEAD_SHPMCOUNTER10 0x5ea
>> +#define CSR_THEAD_SHPMCOUNTER11 0x5eb
>> +#define CSR_THEAD_SHPMCOUNTER12 0x5ec
>> +#define CSR_THEAD_SHPMCOUNTER13 0x5ed
>> +#define CSR_THEAD_SHPMCOUNTER14 0x5ee
>> +#define CSR_THEAD_SHPMCOUNTER15 0x5ef
>> +#define CSR_THEAD_SHPMCOUNTER16 0x5f0
>> +#define CSR_THEAD_SHPMCOUNTER17 0x5f1
>> +#define CSR_THEAD_SHPMCOUNTER18 0x5f2
>> +#define CSR_THEAD_SHPMCOUNTER19 0x5f3
>> +#define CSR_THEAD_SHPMCOUNTER20 0x5f4
>> +#define CSR_THEAD_SHPMCOUNTER21 0x5f5
>> +#define CSR_THEAD_SHPMCOUNTER22 0x5f6
>> +#define CSR_THEAD_SHPMCOUNTER23 0x5f7
>> +#define CSR_THEAD_SHPMCOUNTER24 0x5f8
>> +#define CSR_THEAD_SHPMCOUNTER25 0x5f9
>> +#define CSR_THEAD_SHPMCOUNTER26 0x5fa
>> +#define CSR_THEAD_SHPMCOUNTER27 0x5fb
>> +#define CSR_THEAD_SHPMCOUNTER28 0x5fc
>> +#define CSR_THEAD_SHPMCOUNTER29 0x5fd
>> +#define CSR_THEAD_SHPMCOUNTER30 0x5fe
>> +#define CSR_THEAD_SHPMCOUNTER31 0x5ff
>> +/* T-HEAD U mode CSR.  */
>> +#define CSR_THEAD_FXCR 0x800
>> +/* T-HEAD MMU extentions.  */
>> +#define CSR_THEAD_SMIR 0x9c0
>> +#define CSR_THEAD_SMEL 0x9c1
>> +#define CSR_THEAD_SMEH 0x9c2
>> +#define CSR_THEAD_SMCIR 0x9c3
>> +/* T-HEAD Security CSR(May be dropped).  */
>> +#define CSR_THEAD_MEBR 0xbe0
>> +#define CSR_THEAD_NT_MSTATUS 0xbe1
>> +#define CSR_THEAD_NT_MIE 0xbe2
>> +#define CSR_THEAD_NT_MTVEC 0xbe3
>> +#define CSR_THEAD_NT_MTVT 0xbe4
>> +#define CSR_THEAD_NT_MEPC 0xbe5
>> +#define CSR_THEAD_NT_MCAUSE 0xbe6
>> +#define CSR_THEAD_NT_MIP 0xbe7
>> +#define CSR_THEAD_NT_MINTSTATE 0xbe8
>> +#define CSR_THEAD_NT_MXSTATUS 0xbe9
>> +#define CSR_THEAD_NT_MEBR 0xbea
>> +#define CSR_THEAD_NT_MSP 0xbeb
>> +#define CSR_THEAD_T_USP 0xbec
>> +#define CSR_THEAD_T_MDCR 0xbed
>> +#define CSR_THEAD_T_MPCR 0xbee
>> +#define CSR_THEAD_PMPTEECFG 0xbef
>> +/* T-HEAD extentions.  */
>> +DECLARE_CSR(th_mxstatus, CSR_THEAD_MXSTATUS, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mhcr, CSR_THEAD_MHCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mcor, CSR_THEAD_MCOR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mccr2, CSR_THEAD_MCCR2, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mcer2, CSR_THEAD_MCER2, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mhint, CSR_THEAD_MHINT, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mrmr, CSR_THEAD_MRMR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mrvbr, CSR_THEAD_MRVBR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mcer, CSR_THEAD_MCER, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mcounterwen, CSR_THEAD_MCOUNTERWEN, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mcounterinten, CSR_THEAD_MCOUNTERINTEN, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mcounterof, CSR_THEAD_MCOUNTEROF, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mhint2, CSR_THEAD_MHINT2, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mhint3, CSR_THEAD_MHINT3, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mraddr, CSR_THEAD_MRADDR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mexstatus, CSR_THEAD_MEXSTATUS, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mnmicause, CSR_THEAD_MNMICAUSE, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mnmipc, CSR_THEAD_MNMIPC, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mhpmcr, CSR_THEAD_MHPMCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mhpmsr, CSR_THEAD_MHPMSR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mhpmer, CSR_THEAD_MHPMER, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_msmpr, CSR_THEAD_MSMPR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mteecfg, CSR_THEAD_MTEECFG, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mzoneid, CSR_THEAD_MZONEID, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_ml2cpid, CSR_THEAD_ML2CPID, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_ml2wp, CSR_THEAD_ML2WP, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mdtcmcr, CSR_THEAD_MDTCMCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_usp, CSR_THEAD_USP, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mcins, CSR_THEAD_MCINS, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mcindex, CSR_THEAD_MCINDEX, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mcdata0, CSR_THEAD_MCDATA0, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mcdata1, CSR_THEAD_MCDATA1, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_meicr, CSR_THEAD_MEICR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_meicr2, CSR_THEAD_MEICR2, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mbeaddr, CSR_THEAD_MBEADDR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mebr, CSR_THEAD_MEBR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_nt_mstatus, CSR_THEAD_NT_MSTATUS, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_nt_mtvec, CSR_THEAD_NT_MTVEC, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_nt_mie, CSR_THEAD_NT_MIE, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_nt_mtvt, CSR_THEAD_NT_MTVT, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_nt_mepc, CSR_THEAD_NT_MEPC, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_nt_mcause, CSR_THEAD_NT_MCAUSE, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_nt_mip, CSR_THEAD_NT_MIP, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_nt_mintstate, CSR_THEAD_NT_MINTSTATE, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_nt_mxstatus, CSR_THEAD_NT_MXSTATUS, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_nt_mebr, CSR_THEAD_NT_MEBR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_nt_msp, CSR_THEAD_NT_MSP, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_t_usp, CSR_THEAD_T_USP, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_t_mdcr, CSR_THEAD_T_MDCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_t_mpcr, CSR_THEAD_T_MPCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_pmpteecfg, CSR_THEAD_PMPTEECFG, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mcpuid, CSR_THEAD_MCPUID, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mapbaddr, CSR_THEAD_MAPBADDR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_mwmsr, CSR_THEAD_MWMSR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_fxcr, CSR_THEAD_FXCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_smir, CSR_THEAD_SMIR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_smel, CSR_THEAD_SMEL, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_smeh, CSR_THEAD_SMEH, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_smcir, CSR_THEAD_SMCIR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_sxstatus, CSR_THEAD_SXSTATUS, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shcr, CSR_THEAD_SHCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_scer2, CSR_THEAD_SCER2, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_scer, CSR_THEAD_SCER, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_scounterinten , CSR_THEAD_SCOUNTERINTEN, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_scounterof, CSR_THEAD_SCOUNTEROF, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shint, CSR_THEAD_SHINT, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shint2, CSR_THEAD_SHINT2, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpminhibit, CSR_THEAD_SHPMINHIBIT, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcr, CSR_THEAD_SHPMCR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmsr, CSR_THEAD_SHPMSR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmer, CSR_THEAD_SHPMER, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_sl2cpid, CSR_THEAD_SL2CPID, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_sl2wp, CSR_THEAD_SL2WP, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_sbeaddr, CSR_THEAD_SBEADDR, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_scycle, CSR_THEAD_SCYCLE, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter1, CSR_THEAD_SHPMCOUNTER1, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter2, CSR_THEAD_SHPMCOUNTER2, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter3, CSR_THEAD_SHPMCOUNTER3, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter4, CSR_THEAD_SHPMCOUNTER4, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter5, CSR_THEAD_SHPMCOUNTER5, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter6, CSR_THEAD_SHPMCOUNTER6, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter7, CSR_THEAD_SHPMCOUNTER7, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter8, CSR_THEAD_SHPMCOUNTER8, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter9, CSR_THEAD_SHPMCOUNTER9, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter10, CSR_THEAD_SHPMCOUNTER10, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter11, CSR_THEAD_SHPMCOUNTER11, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter12, CSR_THEAD_SHPMCOUNTER12, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter13, CSR_THEAD_SHPMCOUNTER13, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter14, CSR_THEAD_SHPMCOUNTER14, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter15, CSR_THEAD_SHPMCOUNTER15, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter16, CSR_THEAD_SHPMCOUNTER16, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter17, CSR_THEAD_SHPMCOUNTER17, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter18, CSR_THEAD_SHPMCOUNTER18, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter19, CSR_THEAD_SHPMCOUNTER19, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter20, CSR_THEAD_SHPMCOUNTER20, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter21, CSR_THEAD_SHPMCOUNTER21, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter22, CSR_THEAD_SHPMCOUNTER22, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter23, CSR_THEAD_SHPMCOUNTER23, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter24, CSR_THEAD_SHPMCOUNTER24, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter25, CSR_THEAD_SHPMCOUNTER25, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter26, CSR_THEAD_SHPMCOUNTER26, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter27, CSR_THEAD_SHPMCOUNTER27, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter28, CSR_THEAD_SHPMCOUNTER28, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter29, CSR_THEAD_SHPMCOUNTER29, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter30, CSR_THEAD_SHPMCOUNTER30, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +DECLARE_CSR(th_shpmcounter31, CSR_THEAD_SHPMCOUNTER31, CSR_CLASS_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>> +#endif /* DECLARE_CSR */
>> diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
>> index 88b8d7ff595..f755d0e0643 100644
>> --- a/include/opcode/riscv-opc.h
>> +++ b/include/opcode/riscv-opc.h
>> @@ -3276,3 +3276,5 @@ DECLARE_CSR_ALIAS(tmexttrigger, CSR_TDATA1, CSR_CLASS_DEBUG, PRIV_SPEC_CLASS_NON
>>   DECLARE_CSR_ALIAS(textra32, CSR_TDATA3, CSR_CLASS_DEBUG, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>>   DECLARE_CSR_ALIAS(textra64, CSR_TDATA3, CSR_CLASS_DEBUG, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>>   #endif /* DECLARE_CSR_ALIAS */
>> +
>> +#include "riscv-opc-thead.h"
>> diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
>> index b115e338a05..eff93641bae 100644
>> --- a/include/opcode/riscv.h
>> +++ b/include/opcode/riscv.h
>> @@ -397,6 +397,11 @@ enum riscv_insn_class
>>     INSN_CLASS_ZICBOP,
>>     INSN_CLASS_ZICBOZ,
>>     INSN_CLASS_H,
>> +  INSN_CLASS_THEAD_C,
>> +  INSN_CLASS_THEAD_E,
>> +  INSN_CLASS_THEAD_SE,
>> +  INSN_CLASS_THEAD_C_OR_E,
>> +  INSN_CLASS_THEAD_C_OR_E_OR_SE,
>>   };
>>
>>   /* This structure holds information for a particular instruction.  */
>> @@ -531,4 +536,20 @@ extern const char * const riscv_vma[2];
>>   extern const struct riscv_opcode riscv_opcodes[];
>>   extern const struct riscv_opcode riscv_insn_types[];
>>
>> +/* T-HEAD IMM Encoding.  */
>> +#define EXTRACT_VENDOR_THEAD_IMM(x,nbit,at) \
>> +  (RV_X(x, at, nbit))
>> +#define EXTRACT_VENDOR_THEAD_SIGN_IMM(x,nbit,at) \
>> +  (RV_X(x, at, nbit) | ((-(RV_X(x, (at+nbit-1),1))) << (nbit)))
>> +
>> +#define ENCODE_VENDOR_THEAD_IMM(x,nbit,at) \
>> +  (RV_X(x, 0, nbit) << at)
>> +#define ENCODE_VENDOR_THEAD_SIGN_IMM(x,nbit,at) \
>> +  (RV_X(x, 0, nbit) << at)
>> +
>> +#define VALID_VENDOR_THEAD_IMM(x,nbit,at) \
>> +  (EXTRACT_VENDOR_THEAD_IMM(ENCODE_VENDOR_THEAD_IMM(x,nbit,at),nbit,at) == (x))
>> +#define VALID_VENDOR_THEAD_SIGN_IMM(x,nbit,at) \
>> +  (EXTRACT_VENDOR_THEAD_SIGN_IMM(ENCODE_VENDOR_THEAD_SIGN_IMM(x,nbit,at),nbit,at) == (x))
>> +
>>   #endif /* _RISCV_H_ */
>> diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
>> index 164fd209dbd..43646cc0731 100644
>> --- a/opcodes/riscv-dis.c
>> +++ b/opcodes/riscv-dis.c
>> @@ -554,6 +554,30 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
>>            print (info->stream, dis_style_text, "%d", rs1);
>>            break;
>>
>> +       case 'X':
>> +         {
>> +           int nbit, at, n;
>> +           if (sscanf(oparg, "XI%d@%d%n", &nbit, &at, &n) == 2)
>> +             {
>> +               int value = EXTRACT_BITS (l, (1 << nbit) - 1, at);
>> +               print (info->stream, dis_style_immediate, "%d", value);
>> +               oparg += n - 1;
>> +             }
>> +           else if (sscanf(oparg, "XS%d@%d%n", &nbit, &at, &n) == 2)
>> +             {
>> +               int value = EXTRACT_BITS (l, (1 << nbit) - 1, at);
>> +               print (info->stream, dis_style_immediate, "%d", value);
>> +               oparg += n - 1;
>> +             }
>> +           else
>> +             {
>> +               print (info->stream, dis_style_text,
>> +                      _("# internal error, unknown X modifier %s"),
>> +                      oparg);
>> +             }
>> +         }
>> +         break;
>> +
>>          default:
>>            /* xgettext:c-format */
>>            print (info->stream, dis_style_text,
>> diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
>> index 2f9945aa930..0e9a2f597c2 100644
>> --- a/opcodes/riscv-opc.c
>> +++ b/opcodes/riscv-opc.c
>> @@ -266,6 +266,17 @@ match_vd_eq_vs1_eq_vs2 (const struct riscv_opcode *op,
>>     return match_opcode (op, insn) && vd == vs1 && vs1 == vs2;
>>   }
>>
>> +static int
>> +match_thead_rd1_rd2_neq_rs1(const struct riscv_opcode *op,
>> +                           insn_t insn)
>> +{
>> +  int rd1 = (insn & MASK_RD) >> OP_SH_RD;
>> +  int rd2 = (insn & MASK_RS2) >> OP_SH_RS2;
>> +  int rs1 = (insn & MASK_RS1) >> OP_SH_RS1;
>> +
>> +  return match_opcode (op, insn) && rd1 != rs1 && rd2 != rs1;
>> +}
>> +
>>   const struct riscv_opcode riscv_opcodes[] =
>>   {
>>   /* name, xlen, isa, operands, match, mask, match_func, pinfo.  */
>> @@ -1825,6 +1836,119 @@ const struct riscv_opcode riscv_opcodes[] =
>>   {"hsv.w",       0, INSN_CLASS_H, "t,0(s)", MATCH_HSV_W, MASK_HSV_W, match_opcode, INSN_DREF|INSN_4_BYTE },
>>   {"hsv.d",      64, INSN_CLASS_H, "t,0(s)", MATCH_HSV_D, MASK_HSV_D, match_opcode, INSN_DREF|INSN_8_BYTE },
>>
>> +/* The vendor extension opcodes for T-HEAD.  */
>> +{"th.wsc",             0, INSN_CLASS_THEAD_C_OR_E,   "",  MATCH_WSC, MASK_WSC, match_opcode, 0},
>> +{"th.dcache.iall",     0, INSN_CLASS_THEAD_C_OR_E,   "",  MATCH_DCACHE_IALL, MASK_DCACHE_IALL, match_opcode, 0},
>> +{"th.dcache.call",     0, INSN_CLASS_THEAD_C_OR_E,   "",  MATCH_DCACHE_CALL, MASK_DCACHE_CALL, match_opcode, 0},
>> +{"th.dcache.ciall",    0, INSN_CLASS_THEAD_C_OR_E,   "",  MATCH_DCACHE_CIALL, MASK_DCACHE_CIALL, match_opcode, 0},
>> +{"th.dcache.isw",      0, INSN_CLASS_THEAD_C_OR_E,   "s",     MATCH_DCACHE_ISW, MASK_DCACHE_ISW, match_opcode, 0},
>> +{"th.dcache.csw",      0, INSN_CLASS_THEAD_C_OR_E,   "s",     MATCH_DCACHE_CSW, MASK_DCACHE_CSW, match_opcode, 0},
>> +{"th.dcache.cisw",     0, INSN_CLASS_THEAD_C_OR_E,   "s",     MATCH_DCACHE_CISW, MASK_DCACHE_CISW, match_opcode, 0},
>> +{"th.dcache.iva",      0, INSN_CLASS_THEAD_C,   "s",     MATCH_DCACHE_IVA, MASK_DCACHE_IVA, match_opcode, 0},
>> +{"th.dcache.cva",      0, INSN_CLASS_THEAD_C,   "s",     MATCH_DCACHE_CVA, MASK_DCACHE_CVA, match_opcode, 0},
>> +{"th.dcache.cval1",    0, INSN_CLASS_THEAD_C,   "s",     MATCH_DCACHE_CVAL1, MASK_DCACHE_CVAL1, match_opcode, 0},
>> +{"th.dcache.civa",     0, INSN_CLASS_THEAD_C,   "s",     MATCH_DCACHE_CIVA, MASK_DCACHE_CIVA, match_opcode, 0},
>> +{"th.dcache.ipa",      0, INSN_CLASS_THEAD_C_OR_E,   "s",     MATCH_DCACHE_IPA, MASK_DCACHE_IPA, match_opcode, 0},
>> +{"th.dcache.cpa",      0, INSN_CLASS_THEAD_C_OR_E,   "s",     MATCH_DCACHE_CPA, MASK_DCACHE_CPA, match_opcode, 0},
>> +{"th.dcache.cpal1",    0, INSN_CLASS_THEAD_C,   "s",     MATCH_DCACHE_CPAL1, MASK_DCACHE_CPAL1, match_opcode, 0},
>> +{"th.dcache.cipa",     0, INSN_CLASS_THEAD_C_OR_E,   "s",     MATCH_DCACHE_CIPA, MASK_DCACHE_CIPA, match_opcode, 0},
>> +{"th.icache.iall",     0, INSN_CLASS_THEAD_C_OR_E_OR_SE,   "",      MATCH_ICACHE_IALL, MASK_ICACHE_IALL, match_opcode, 0},
>> +{"th.icache.iall",     0, INSN_CLASS_THEAD_SE,   "",      MATCH_ICACHE_IALL, MASK_ICACHE_IALL, match_opcode, INSN_ALIAS},
>> +{"th.icache.ialls",    0, INSN_CLASS_THEAD_C,   "",      MATCH_ICACHE_IALLS, MASK_ICACHE_IALLS, match_opcode, 0},
>> +{"th.icache.iva",      0, INSN_CLASS_THEAD_C,   "s",     MATCH_ICACHE_IVA, MASK_ICACHE_IVA, match_opcode, 0},
>> +{"th.icache.ipa",      0, INSN_CLASS_THEAD_C_OR_E,   "s",     MATCH_ICACHE_IPA, MASK_ICACHE_IPA, match_opcode, 0},
>> +{"th.l2cache.iall",    0, INSN_CLASS_THEAD_C,   "",      MATCH_L2CACHE_IALL, MASK_L2CACHE_IALL, match_opcode, 0},
>> +{"th.l2cache.call",    0, INSN_CLASS_THEAD_C,   "",      MATCH_L2CACHE_CALL, MASK_L2CACHE_CALL, match_opcode, 0},
>> +{"th.l2cache.ciall",   0, INSN_CLASS_THEAD_C_OR_E,   "",      MATCH_L2CACHE_CIALL, MASK_L2CACHE_CIALL, match_opcode, 0},
>> +{"th.sync",            0, INSN_CLASS_THEAD_C_OR_E,   "",      MATCH_SYNC, MASK_SYNC, match_opcode, 0},
>> +{"th.sync.i",          0, INSN_CLASS_THEAD_C_OR_E,   "",      MATCH_SYNC_I, MASK_SYNC_I, match_opcode, 0},
>> +{"th.sync.s",          0, INSN_CLASS_THEAD_C,   "",      MATCH_SYNC_S, MASK_SYNC_S, match_opcode, 0},
>> +{"th.sync.is",         0, INSN_CLASS_THEAD_C,   "",      MATCH_SYNC_IS, MASK_SYNC_IS, match_opcode, 0},
>> +{"th.tstnbz",          0, INSN_CLASS_THEAD_C_OR_E,   "d,s",     MATCH_TSTNBZ, MASK_TSTNBZ, match_opcode, 0},
>> +{"th.mula",            0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MULA, MASK_MULA, match_opcode, 0},
>> +{"th.muls",            0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MULS, MASK_MULS, match_opcode, 0},
>> +{"th.mulah",           0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MULAH, MASK_MULAH, match_opcode, 0},
>> +{"th.mulsh",           0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MULSH, MASK_MULSH, match_opcode, 0},
>> +{"th.sfence.vmas",     0, INSN_CLASS_THEAD_C,   "s,t",      MATCH_SFENCE_VMAS, MASK_SFENCE_VMAS, match_opcode, 0},
>> +{"th.mveqz",           0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MVEQZ, MASK_MVEQZ, match_opcode, 0},
>> +{"th.mvnez",           0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MVNEZ, MASK_MVNEZ, match_opcode, 0},
>> +{"th.mulaw",           0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MULAW, MASK_MULAW, match_opcode, 0},
>> +{"th.mulsw",           0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t",   MATCH_MULSW, MASK_MULSW, match_opcode, 0},
>> +{"th.ext",             64, INSN_CLASS_THEAD_C,  "d,s,XI6@26,XI6@20",   MATCH_EXT, MASK_EXT, match_opcode, 0 },
>> +{"th.ext",             32, INSN_CLASS_THEAD_E,  "d,s,XI5@26,XI5@20",   MATCH_EXT, (MASK_EXT | (1U<<25) | (1U<<31)), match_opcode, 0 },
>> +{"th.extu",            64, INSN_CLASS_THEAD_C,  "d,s,XI6@26,XI6@20",   MATCH_EXTU, MASK_EXTU, match_opcode, 0 },
>> +{"th.extu",            32, INSN_CLASS_THEAD_E,  "d,s,XI5@26,XI5@20",   MATCH_EXTU, (MASK_EXTU | (1U<<25) | (1U<<31)), match_opcode, 0 },
>> +{"th.ff1",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s",   MATCH_FF1, MASK_FF1, match_opcode, 0},
>> +{"th.ff0",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s",   MATCH_FF0, MASK_FF1, match_opcode, 0},
>> +{"th.rev",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s",   MATCH_REV, MASK_REV, match_opcode, 0},
>> +{"th.lrb",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_LRB, MASK_LRB, match_opcode, 0 },
>> +{"th.lrbu",            0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_LRBU, MASK_LRBU, match_opcode, 0 },
>> +{"th.lrh",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_LRH, MASK_LRH, match_opcode, 0 },
>> +{"th.lrhu",            0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_LRHU, MASK_LRHU, match_opcode, 0 },
>> +{"th.lrw",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_LRW, MASK_LRW, match_opcode, 0 },
>> +{"th.lrwu",            0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_LRWU, MASK_LRWU, match_opcode, 0 },
>> +{"th.srb",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_SRB, MASK_SRB, match_opcode, 0 },
>> +{"th.srh",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_SRH, MASK_SRH, match_opcode, 0 },
>> +{"th.srw",             0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25",   MATCH_SRW, MASK_SRW, match_opcode, 0 },
>> +{"th.lrd",             0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LRD, MASK_LRD, match_opcode, 0 },
>> +{"th.srd",             0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_SRD, MASK_SRD, match_opcode, 0 },
>> +{"th.lurb",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LURB, MASK_LURB, match_opcode, 0 },
>> +{"th.lurbu",           0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LURBU, MASK_LURBU, match_opcode, 0 },
>> +{"th.lurh",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LURH, MASK_LURH, match_opcode, 0 },
>> +{"th.lurhu",           0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LURHU, MASK_LURHU, match_opcode, 0 },
>> +{"th.lurw",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LURW, MASK_LURW, match_opcode, 0 },
>> +{"th.lurwu",           0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LURWU, MASK_LURWU, match_opcode, 0 },
>> +{"th.lurd",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_LURD, MASK_LURD, match_opcode, 0 },
>> +{"th.surb",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_SURB, MASK_SURB, match_opcode, 0 },
>> +{"th.surh",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_SURH, MASK_SURH, match_opcode, 0 },
>> +{"th.surw",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_SURW, MASK_SURW, match_opcode, 0 },
>> +{"th.surd",            0, INSN_CLASS_THEAD_C,   "d,s,t,XI2@25",   MATCH_SURD, MASK_SURD, match_opcode, 0 },
>> +{"th.tst",             64, INSN_CLASS_THEAD_C,  "d,s,XI6@20",   MATCH_TST, MASK_TST, match_opcode, 0 },
>> +{"th.tst",             32, INSN_CLASS_THEAD_E,   "d,s,XI5@20",   MATCH_TST, (MASK_TST | (1U << 25)), match_opcode, INSN_ALIAS},
>> +{"th.srriw",           0, INSN_CLASS_THEAD_C,   "d,s,XI5@20",   MATCH_SRRIW, MASK_SRRIW, match_opcode, 0 },
>> +{"th.srri",            0, INSN_CLASS_THEAD_C_OR_E,   "d,s,XI6@20",   MATCH_SRRI, MASK_SRRI, match_opcode, 0 },
>> +{"th.addsl",           0, INSN_CLASS_THEAD_C_OR_E,   "d,s,t,XI2@25", MATCH_ADDSL, MASK_ADDSL, match_opcode, 0 },
>> +{"th.lwd",             0, INSN_CLASS_THEAD_C,   "d,t,(s),XI2@25", MATCH_LWD, MASK_LWD, match_thead_rd1_rd2_neq_rs1, 0 },
>> +{"th.ldd",             0, INSN_CLASS_THEAD_C,   "d,t,(s),XI2@25", MATCH_LDD, MASK_LDD, match_thead_rd1_rd2_neq_rs1, 0 },
>> +{"th.swd",             0, INSN_CLASS_THEAD_C,   "d,t,(s),XI2@25", MATCH_SWD, MASK_SWD, match_opcode, 0 },
>> +{"th.sdd",             0, INSN_CLASS_THEAD_C,   "d,t,(s),XI2@25", MATCH_SDD, MASK_SDD, match_opcode, 0 },
>> +{"th.sdia",            0, INSN_CLASS_THEAD_C,   "d,(s),XS5@20,XI2@25", MATCH_SDIA, MASK_SDIA, match_opcode, 0 },
>> +{"th.sdib",            0, INSN_CLASS_THEAD_C,   "d,(s),XS5@20,XI2@25", MATCH_SDIB, MASK_SDIB, match_opcode, 0 },
>> +{"th.lwud",            0, INSN_CLASS_THEAD_C,   "d,t,(s),XI2@25", MATCH_LWUD, MASK_LWUD, match_thead_rd1_rd2_neq_rs1, 0 },
>> +{"th.swia",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_SWIA, MASK_SWIA, match_opcode, 0},
>> +{"th.swib",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_SWIB, MASK_SWIB, match_opcode, 0},
>> +{"th.shia",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_SHIA, MASK_SHIA, match_opcode, 0},
>> +{"th.shib",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_SHIB, MASK_SHIB, match_opcode, 0},
>> +{"th.sbia",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_SBIA, MASK_SBIA, match_opcode, 0},
>> +{"th.sbib",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_SBIB, MASK_SBIB, match_opcode, 0},
>> +{"th.lwuia",           0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LWUIA, MASK_LWUIA, match_opcode, 0},
>> +{"th.lwuib",           0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LWUIB, MASK_LWUIB, match_opcode, 0},
>> +{"th.lhuia",           0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LHUIA, MASK_LHUIA, match_opcode, 0},
>> +{"th.lhuib",           0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LHUIB, MASK_LHUIB, match_opcode, 0},
>> +{"th.lbuia",           0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LBUIA, MASK_LBUIA, match_opcode, 0},
>> +{"th.lbuib",           0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LBUIB, MASK_LBUIB, match_opcode, 0},
>> +{"th.ldia",            0, INSN_CLASS_THEAD_C,   "d,(s),XS5@20,XI2@25", MATCH_LDIA, MASK_LDIA, match_opcode, 0},
>> +{"th.ldib",            0, INSN_CLASS_THEAD_C,   "d,(s),XS5@20,XI2@25", MATCH_LDIB, MASK_LDIB, match_opcode, 0},
>> +{"th.lwia",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LWIA, MASK_LWIA, match_opcode, 0},
>> +{"th.lwib",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LWIB, MASK_LWIB, match_opcode, 0},
>> +{"th.lhia",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LHIA, MASK_LHIA, match_opcode, 0},
>> +{"th.lhib",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LHIB, MASK_LHIB, match_opcode, 0},
>> +{"th.lbia",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LBIA, MASK_LBIA, match_opcode, 0},
>> +{"th.lbib",            0, INSN_CLASS_THEAD_C_OR_E,   "d,(s),XS5@20,XI2@25", MATCH_LBIB, MASK_LBIB, match_opcode, 0},
>> +{"th.fsurd",           0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FSURD, MASK_FSURD, match_opcode, 0},
>> +{"th.revw",            0, INSN_CLASS_THEAD_C,   "d,s", MATCH_REVW, MASK_REVW, match_opcode, 0},
>> +{"th.fsurw",           0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FSURW, MASK_FSURW, match_opcode, 0},
>> +{"th.flurd",           0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FLURD, MASK_FLURD, match_opcode, 0},
>> +{"th.flurw",           0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FLURW, MASK_FLURW, match_opcode, 0},
>> +{"th.fsrd",            0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FSRD, MASK_FSRD, match_opcode, 0},
>> +{"th.fsrw",            0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FSRW, MASK_FSRW, match_opcode, 0},
>> +{"th.flrd",            0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FLRD, MASK_FLRD, match_opcode, 0},
>> +{"th.flrw",            0, INSN_CLASS_THEAD_C,   "D,s,t,XI2@25", MATCH_FLRW, MASK_FLRW, match_opcode, 0},
>> +{"th.ipush",           0, INSN_CLASS_THEAD_E,   "",  MATCH_IPUSH, MASK_IPUSH, match_opcode, 0},
>> +{"th.ipop",            0, INSN_CLASS_THEAD_E,   "",  MATCH_IPOP, MASK_IPOP, match_opcode, 0},
>> +{"th.fmv.x.hw",        32, INSN_CLASS_THEAD_E,  "d,S",  MATCH_FMV_X_HW, MASK_FMV_X_HW, match_opcode, 0},
>> +{"th.fmv.hw.x",        32, INSN_CLASS_THEAD_E,  "D,s",  MATCH_FMV_HW_X, MASK_FMV_HW_X, match_opcode, 0},
>> +
>>   /* Terminate the list.  */
>>   {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}
>>   };
>> --
>> 2.34.1
>>

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

end of thread, other threads:[~2022-07-29  9:19 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-28 22:04 [PATCH] RISC-V/t-head: Add CSRs and opcodes of the T-HEAD XUANTIE CPUs Palmer Dabbelt
2022-07-29  0:28 ` Kito Cheng
2022-07-29  8:43   ` Jojo R
2022-07-29  9:19   ` Lifang Xia

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).