public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [Integration 0/2] RISC-V: Add vendor(T-HEAD) opcodes
@ 2021-09-03  2:59 Lifang Xia
  2021-09-03  3:00 ` [Integration 1/2] RISC-V: add vendor opcodes Lifang Xia
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Lifang Xia @ 2021-09-03  2:59 UTC (permalink / raw)
  To: binutils


These patches are add a mechanism to support vendor's opcodes.
The [PATCH 2/2] is THEAD extension, which contains THEADC, THEADE ISAs.
The doc is https://github.com/rjiejie/XuanTie-doc



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

* [Integration 1/2] RISC-V: add vendor opcodes
  2021-09-03  2:59 [Integration 0/2] RISC-V: Add vendor(T-HEAD) opcodes Lifang Xia
@ 2021-09-03  3:00 ` Lifang Xia
  2021-09-03  4:00   ` Nelson Chu
  2021-09-03  3:00 ` [Integration 2/2] RISC-V: Update csr and opcodes for Xuantie CPUs Lifang Xia
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 10+ messages in thread
From: Lifang Xia @ 2021-09-03  3:00 UTC (permalink / raw)
  To: binutils

This patch uses the T-HEAD Xuantie processor as an example to solve that
how to add the vendor's opcode and CSR.
Without modifying the existing mechanism, create a new
opcodes/riscv-vendor-opc.c, similar to opcodes/riscv-opc.c, used to
describe the vendor's opcodes.
New file, include/opcodes/riscv-vendor-opc.h, used to define the encoding,
mask and CSR of the opcodes.

The sub-string from -march option is used to pick the suitable list of
the vendor's opcodes.

bfd/
	* cpu-riscv.h (enum riscv_spec_class): New
	ISA_SPEC_CLASS_VENDOR.
gas/
	* config/tc-riscv.c (ext_version_table): New "theadc".
	(riscv_vendor_get_opcodes): New.
	(riscv_multi_subset_supports): Check xtheadc extensions.
	(riscv_get_default_ext_version): Skip for vendor.
	(init_opcode_hash): Add vendor's extensions to the hash.
	(md_begin): Init opcode hash.
include/
	* opcode/riscv-opc.h: Include riscv-vendor-opc.h
	* opcode/riscv-vendor-opc.h: New.
	* opcode/riscv.h (enum riscv_extended_insn_class): New class for vendor.
	(struct riscv_vendor_opcode): New.
	(riscv_vendor_list): New.
opcodes/
	* Makefile.am: Add riscv-vendor-opc.c.
	* Makefile.in: Likewise.
	* configure: Likewise
	* configure.ac: Likewise
	* riscv-dis.c (arch_string): New.
	(get_vendor_opcodes): Get the vendor opcodes.
	(riscv_disassemble_insn): Add vendor's opcode to the hash.
	(riscv_get_disassembler): Setup arch_string with attr.
	* riscv-vendor-opc.c: New.
---
 bfd/cpu-riscv.h                   |  1 +
 gas/config/tc-riscv.c             | 55 +++++++++++++++++++++++++++++--
 include/opcode/riscv-opc.h        |  1 +
 include/opcode/riscv-vendor-opc.h | 34 +++++++++++++++++++
 include/opcode/riscv.h            | 10 ++++++
 opcodes/Makefile.am               |  1 +
 opcodes/Makefile.in               |  2 ++
 opcodes/configure                 |  2 +-
 opcodes/configure.ac              |  2 +-
 opcodes/riscv-dis.c               | 23 +++++++++++++
 opcodes/riscv-vendor-opc.c        | 43 ++++++++++++++++++++++++
 11 files changed, 170 insertions(+), 4 deletions(-)
 create mode 100644 include/opcode/riscv-vendor-opc.h
 create mode 100644 opcodes/riscv-vendor-opc.c

diff --git a/bfd/cpu-riscv.h b/bfd/cpu-riscv.h
index cafaca23be0..06ede1b2bef 100644
--- a/bfd/cpu-riscv.h
+++ b/bfd/cpu-riscv.h
@@ -26,6 +26,7 @@ enum riscv_spec_class
   ISA_SPEC_CLASS_20190608,
   ISA_SPEC_CLASS_20191213,
   ISA_SPEC_CLASS_DRAFT,
+  ISA_SPEC_CLASS_VENDOR,
 
   /* Privileged spec.  */
   PRIV_SPEC_CLASS_NONE,
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 18992949954..99bc9298b16 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -157,6 +157,9 @@ static const struct riscv_ext_version ext_version_table[] =
   {"zba",   ISA_SPEC_CLASS_DRAFT, 0, 93},
   {"zbc",   ISA_SPEC_CLASS_DRAFT, 0, 93},
 
+  /* T-HEAD extentions for Xuantie C9xx.  */
+  {"xtheadc",   ISA_SPEC_CLASS_VENDOR, 2, 0},
+
   /* Terminate the list.  */
   {NULL, 0, 0, 0}
 };
@@ -238,6 +241,22 @@ riscv_set_default_isa_spec (const char *s)
   return 1;
 }
 
+/* Get the opcodes from vendors.  */
+static struct riscv_opcode *
+riscv_vendor_get_opcodes (riscv_subset_list_t *subsets)
+{
+  unsigned int i = 0;
+  struct riscv_subset_t *subset = NULL;
+
+  for (i = 0; riscv_vendor_list[i].vendor; i++)
+    {
+      if (riscv_lookup_subset (subsets, riscv_vendor_list[i].vendor, &subset))
+	return riscv_vendor_list[i].opcodes;
+    }
+
+  return NULL;
+}
+
 /* Set the default_priv_spec.  Find the privileged elf attributes when
    the input string is NULL.  Return 0 if the spec isn't supported.
    Otherwise, return 1.  */
@@ -407,6 +426,9 @@ riscv_multi_subset_supports (enum riscv_insn_class insn_class)
     case INSN_CLASS_ZBC:
       return riscv_subset_supports ("zbc");
 
+    case INSN_CLASS_THEADC:
+      return riscv_subset_supports ("xtheadc");
+
     default:
       return riscv_extended_subset_supports (insn_class);
     }
@@ -458,6 +480,7 @@ riscv_search_ext_version_hash (const char *name,
 	 && strcmp (ext->name, name) == 0)
     {
       if (ext->isa_spec_class == ISA_SPEC_CLASS_DRAFT
+	  || ext->isa_spec_class == ISA_SPEC_CLASS_VENDOR
 	  || ext->isa_spec_class == default_isa_spec)
 	{
 	  *major_version = ext->major_version;
@@ -1328,6 +1351,7 @@ struct percent_op_match
 
 static htab_t
 init_opcode_hash (const struct riscv_opcode *opcodes,
+		  const struct riscv_opcode *ext_opcodes,
 		  bool insn_directive_p)
 {
   int i = 0;
@@ -1358,6 +1382,29 @@ init_opcode_hash (const struct riscv_opcode *opcodes,
       while (opcodes[i].name && !strcmp (opcodes[i].name, name));
     }
 
+  i = 0;
+  while (ext_opcodes && ext_opcodes[i].name)
+    {
+      const char *name = ext_opcodes[i].name;
+      if (str_hash_insert (hash, name, &ext_opcodes[i], 0) != NULL)
+	as_fatal (_("internal: duplicate %s"), name);
+
+      do
+	{
+	  if (ext_opcodes[i].pinfo != INSN_MACRO)
+	    {
+	      length = 0; /* Let assembler determine the length.  */
+	      if (!validate_riscv_insn (&ext_opcodes[i], length))
+		as_fatal (_("internal: broken assembler.  "
+			    "No assembly attempted"));
+	    }
+	  else
+	    gas_assert (!insn_directive_p);
+	  ++i;
+	}
+      while (ext_opcodes[i].name && !strcmp (ext_opcodes[i].name, name));
+    }
+
   return hash;
 }
 
@@ -1372,8 +1419,11 @@ md_begin (void)
   if (! bfd_set_arch_mach (stdoutput, bfd_arch_riscv, mach))
     as_warn (_("could not set architecture and machine"));
 
-  op_hash = init_opcode_hash (riscv_opcodes, false);
-  insn_type_hash = init_opcode_hash (riscv_insn_types, true);
+  op_hash = init_opcode_hash (riscv_opcodes,
+			      riscv_vendor_get_opcodes (&riscv_subsets),
+			      false);
+
+  insn_type_hash = init_opcode_hash (riscv_insn_types, NULL, true);
 
   reg_names_hash = str_htab_create ();
   hash_reg_names (RCLASS_GPR, riscv_gpr_names_numeric, NGPR);
@@ -4587,3 +4637,4 @@ riscv_pop_insert (void)
 
   pop_insert (riscv_pseudo_table);
 }
+
diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
index 9999da6241a..84fc2ee0e8e 100644
--- a/include/opcode/riscv-opc.h
+++ b/include/opcode/riscv-opc.h
@@ -20,6 +20,7 @@
 
 #ifndef RISCV_ENCODING_H
 #define RISCV_ENCODING_H
+#include "opcode/riscv-vendor-opc.h"
 /* Instruction opcode macros.  */
 #define MATCH_SLLI_RV32 0x1013
 #define MASK_SLLI_RV32  0xfe00707f
diff --git a/include/opcode/riscv-vendor-opc.h b/include/opcode/riscv-vendor-opc.h
new file mode 100644
index 00000000000..949047239f8
--- /dev/null
+++ b/include/opcode/riscv-vendor-opc.h
@@ -0,0 +1,34 @@
+/* riscv-vendor-opc.h.  RISC-V instruction opcode and CSR macros from vendors.
+   Copyright (C) 2011-2021 Free Software Foundation, Inc.
+   Contributed by Andrew Waterman
+
+   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_VENDOR_OPC_H__
+#define __RISCV_VENDOR_OPC_H__
+
+
+/* Opcodes for VENDOR 0.  */
+
+
+/* Opcodes for VENDOR 1.  */
+
+
+/* Opcodes for VENDOR 2.  */
+
+
+#endif
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index 8d5251c50e4..af8df794d1b 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -361,6 +361,12 @@ struct riscv_opcode
   unsigned long pinfo;
 };
 
+struct riscv_vendor_opcode
+{
+  const char *vendor;
+  struct riscv_opcode *opcodes;
+};
+
 /* Instruction is a simple alias (e.g. "mv" for "addi").  */
 #define	INSN_ALIAS		0x00000001
 
@@ -434,6 +440,7 @@ extern const char * const riscv_fpr_names_abi[NFPR];
 
 extern const struct riscv_opcode riscv_opcodes[];
 extern const struct riscv_opcode riscv_insn_types[];
+extern const struct riscv_vendor_opcode riscv_vendor_list[];
 
 /* Extended extensions.  */
 
@@ -496,6 +503,9 @@ enum riscv_extended_insn_class
   INSN_CLASS_D_AND_ZFH,
   INSN_CLASS_Q_AND_ZFH,
   INSN_CLASS_SVINVAL,
+
+  /* INSN class for THEAD.  */
+  INSN_CLASS_THEADC,
 };
 
 /* This is a list of macro expanded instructions for extended
diff --git a/opcodes/Makefile.am b/opcodes/Makefile.am
index 0e04b4c05c4..4f3ad0e69cd 100644
--- a/opcodes/Makefile.am
+++ b/opcodes/Makefile.am
@@ -229,6 +229,7 @@ TARGET_LIBOPCODES_CFILES = \
 	pru-opc.c \
 	riscv-dis.c \
 	riscv-opc.c \
+	riscv-vendor-opc.c \
 	rl78-decode.c \
 	rl78-dis.c \
 	rx-decode.c \
diff --git a/opcodes/Makefile.in b/opcodes/Makefile.in
index 42c15f00d30..5dcbc204a1e 100644
--- a/opcodes/Makefile.in
+++ b/opcodes/Makefile.in
@@ -620,6 +620,7 @@ TARGET_LIBOPCODES_CFILES = \
 	pru-opc.c \
 	riscv-dis.c \
 	riscv-opc.c \
+	riscv-vendor-opc.c \
 	rl78-decode.c \
 	rl78-dis.c \
 	rx-decode.c \
@@ -1036,6 +1037,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pru-opc.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/riscv-dis.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/riscv-opc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/riscv-vendor-opc.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rl78-decode.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rl78-dis.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rx-decode.Plo@am__quote@
diff --git a/opcodes/configure b/opcodes/configure
index 3513e408ce1..ad9ec966411 100755
--- a/opcodes/configure
+++ b/opcodes/configure
@@ -12265,7 +12265,7 @@ if test x${all_targets} = xfalse ; then
 	bfd_pru_arch)		ta="$ta pru-dis.lo pru-opc.lo" ;;
 	bfd_pyramid_arch)	;;
 	bfd_romp_arch)		;;
-	bfd_riscv_arch)         ta="$ta riscv-dis.lo riscv-opc.lo" ;;
+	bfd_riscv_arch)         ta="$ta riscv-dis.lo riscv-opc.lo riscv-vendor-opc.lo" ;;
 	bfd_rs6000_arch)	ta="$ta ppc-dis.lo ppc-opc.lo" ;;
 	bfd_rl78_arch)		ta="$ta rl78-dis.lo rl78-decode.lo";;
 	bfd_rx_arch)		ta="$ta rx-dis.lo rx-decode.lo";;
diff --git a/opcodes/configure.ac b/opcodes/configure.ac
index e564f067334..16024f2f0d5 100644
--- a/opcodes/configure.ac
+++ b/opcodes/configure.ac
@@ -326,7 +326,7 @@ if test x${all_targets} = xfalse ; then
 	bfd_pru_arch)		ta="$ta pru-dis.lo pru-opc.lo" ;;
 	bfd_pyramid_arch)	;;
 	bfd_romp_arch)		;;
-	bfd_riscv_arch)         ta="$ta riscv-dis.lo riscv-opc.lo" ;;
+	bfd_riscv_arch)         ta="$ta riscv-dis.lo riscv-opc.lo riscv-vendor-opc.lo" ;;
 	bfd_rs6000_arch)	ta="$ta ppc-dis.lo ppc-opc.lo" ;;
 	bfd_rl78_arch)		ta="$ta rl78-dis.lo rl78-decode.lo";;
 	bfd_rx_arch)		ta="$ta rx-dis.lo rx-decode.lo";;
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index dcc5a09213b..8ddc6bec370 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -33,6 +33,7 @@
 #include <ctype.h>
 
 static enum riscv_spec_class default_priv_spec = PRIV_SPEC_CLASS_NONE;
+static const char *arch_string = NULL;
 
 struct riscv_private_data
 {
@@ -140,6 +141,21 @@ parse_riscv_dis_options (const char *opts_in)
   free (opts);
 }
 
+static struct riscv_opcode*
+get_vendor_opcodes (const char *arch)
+{
+  int i = 0;
+  if (arch == NULL)
+    return NULL;
+
+  for (i = 0; riscv_vendor_list[i].vendor; i++)
+    {
+      if (strstr(arch, riscv_vendor_list[i].vendor) != NULL)
+	return riscv_vendor_list[i].opcodes;
+    }
+  return NULL;
+}
+
 /* Print one argument from an array.  */
 
 static void
@@ -548,6 +564,11 @@ riscv_disassemble_opcode (insn_t word,
 	if (!riscv_hash[OP_HASH_IDX (op->match)])
 	  riscv_hash[OP_HASH_IDX (op->match)] = op;
 
+      op = get_vendor_opcodes (arch_string);
+      for (; op && op->name; op++)
+	if (!riscv_hash[OP_HASH_IDX (op->match)])
+	  riscv_hash[OP_HASH_IDX (op->match)] = op;
+
       init = 1;
     }
 
@@ -744,6 +765,8 @@ riscv_get_disassembler (bfd *abfd)
 						      attr[Tag_b].i,
 						      attr[Tag_c].i,
 						      &default_priv_spec);
+	      /* Get Vendor opcodes.  */
+	      arch_string = attr[Tag_RISCV_arch].s;
 	    }
         }
     }
diff --git a/opcodes/riscv-vendor-opc.c b/opcodes/riscv-vendor-opc.c
new file mode 100644
index 00000000000..9191b654c14
--- /dev/null
+++ b/opcodes/riscv-vendor-opc.c
@@ -0,0 +1,43 @@
+/* RISC-V opcode list from vendors.
+   Copyright (C) 2011-2021 Free Software Foundation, Inc.
+
+   Contributed by Andrew Waterman (andrew@sifive.com).
+   Based on MIPS target.
+
+   This file is part of the GNU opcodes library.
+
+   This library is free software; you can redistribute it and/or modify
+   it 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.
+
+   It is distributed in the hope that it 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/>.  */
+
+
+#include "sysdep.h"
+#include "opcode/riscv.h"
+#include <stdio.h>
+#include "bfd.h"
+
+/* The vendor extension opcodes for T-HEAD.  */
+struct riscv_opcode vendor_thead_opcodes[] =
+{
+  {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}
+
+};
+
+/* The vendor opcodes list.  */
+const struct riscv_vendor_opcode riscv_vendor_list[] =
+{
+  /* Vendor T-HEAD.  */
+  {"xtheadc", vendor_thead_opcodes},
+  {NULL, NULL},
+};
+
-- 
2.17.1


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

* [Integration 2/2] RISC-V: Update csr and opcodes for Xuantie CPUs.
  2021-09-03  2:59 [Integration 0/2] RISC-V: Add vendor(T-HEAD) opcodes Lifang Xia
  2021-09-03  3:00 ` [Integration 1/2] RISC-V: add vendor opcodes Lifang Xia
@ 2021-09-03  3:00 ` Lifang Xia
  2021-09-03  4:27   ` Nelson Chu
  2021-09-03  4:37 ` [Integration 0/2] RISC-V: Add vendor(T-HEAD) opcodes Nelson Chu
  2021-09-07  9:20 ` [integration 0/1] RISC-V: Add CSRs and opcodes of T-HEAD XUANTIE CPUs Lifang Xia
  3 siblings, 1 reply; 10+ messages in thread
From: Lifang Xia @ 2021-09-03  3:00 UTC (permalink / raw)
  To: binutils

New ARG format for operands:
"Xgm@n": encode GPR with m bit at opcode[m+n-1:n].
   "Xg5@0": encode GPR with 5 bit at opcode[4:0].
   "Xg5@8": encode GPR with 5 bit at opcode[12:8].

"XCm": constant m, no encode for this.
   "XC4": constant 4.

"XIm@n": m bits unsigned immediate at opcode[m+n-1:n].
   "XI5@0": 5 bits unsigned immediate at opcode[4:0].
   "XI4@8": 4 bits unsigned immediate at opcode[11:8].

"XSm@n": m bits signed immediate at opcode[m+n-1:n].
   "XS5@0": 5 bits signed immediate at opcode[4:0].
   "XS4@8": 4 bits signed immediate at opcode[11:8].

"XFm@n": m bits FR at opcode[m+n-1:n].
   "XF5@0": 5 bits FR at opcode[4:0].
   "XF5@0": 5 bits FR at opcode[4:0].

gas/
	* config/tc-riscv.c (riscv_csr_class): New CSR_CLASS_VENDOR.
	(ext_version_table): New thead extensions.
	(riscv_multi_subset_supports): New thead extensions.
	(riscv_csr_address) <case CSR_CLASS_VENDOR>: New.
	(validate_riscv_insn) <case 'X'>: New operands for vendor.
	(init_opcode_hash): New ext_opcodes.
	(riscv_ip) <case 'X'>: New operands for vendor.
	* testsuite/gas/riscv/thead/*: New testcases for Xuantie.
include/
	* opcode/riscv-opc.h: move "riscv-vendor-opc.h" out.
	* opcode/riscv-vendor-opc.h: New CSR and opcodes for T-HEAD
	Xuantie CPUS.
	* opcode/riscv.h (EXTRACT_VENDOR_IMM): New.
	(EXTRACT_VENDOR_SIGN_IMM): New.
	(ENCODE_VENDOR_IMM): New.
	(ENCODE_VENDOR_SIGN_IMM): New.
	(VALID_VENDOR_IMM): New.
	(VALID_VENDOR_SIGN_IMM: New.
	(riscv_insn_class): New T-HEAD insn class.
	(match_opcode): Define as an global function.
opcodes/
	* riscv-dis.c (print_insn_args) <case 'X'>: New operands
	parsing.
	* riscv-opc.c (match_opcode): Define as an global function.
	* riscv-vendor-opc.c (match_thead_rd1_rd2_neq_rs1): New.
 	(vendor_thead_opcodes): Define opcodes for Xuantie CPUs.
	(riscv_vendor_list): Add xtheade/xtheadse.
---
 gas/config/tc-riscv.c                         | 147 ++++++
 gas/testsuite/gas/riscv/thead/riscv.exp       |   3 +
 .../gas/riscv/thead/thead-csr-list.d          | 108 ++++
 .../gas/riscv/thead/thead-csr-list.s          |  99 ++++
 gas/testsuite/gas/riscv/thead/theadc-ext.d    | 112 +++++
 gas/testsuite/gas/riscv/thead/theadc-ext.s    | 116 +++++
 gas/testsuite/gas/riscv/thead/theade-ext.d    |  62 +++
 gas/testsuite/gas/riscv/thead/theade-ext.s    |  67 +++
 include/opcode/riscv-opc.h                    |   3 +-
 include/opcode/riscv-vendor-opc.h             | 476 +++++++++++++++++-
 include/opcode/riscv.h                        |  19 +
 opcodes/riscv-dis.c                           |  50 ++
 opcodes/riscv-opc.c                           |   2 +-
 opcodes/riscv-vendor-opc.c                    | 158 ++++++
 14 files changed, 1415 insertions(+), 7 deletions(-)
 create mode 100644 gas/testsuite/gas/riscv/thead/riscv.exp
 create mode 100644 gas/testsuite/gas/riscv/thead/thead-csr-list.d
 create mode 100644 gas/testsuite/gas/riscv/thead/thead-csr-list.s
 create mode 100644 gas/testsuite/gas/riscv/thead/theadc-ext.d
 create mode 100644 gas/testsuite/gas/riscv/thead/theadc-ext.s
 create mode 100644 gas/testsuite/gas/riscv/thead/theade-ext.d
 create mode 100644 gas/testsuite/gas/riscv/thead/theade-ext.s

diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 99bc9298b16..d58bfcdcbc3 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -79,6 +79,7 @@ enum riscv_csr_class
 enum riscv_extended_csr_class
 {
   CSR_CLASS_V = CSR_CLASS_EXTENDED, /* RVV CSR */
+  CSR_CLASS_VENDOR /* vendor CSR */
 };
 
 /* This structure holds all restricted conditions for a CSR.  */
@@ -159,6 +160,8 @@ static const struct riscv_ext_version ext_version_table[] =
 
   /* T-HEAD extentions for Xuantie C9xx.  */
   {"xtheadc",   ISA_SPEC_CLASS_VENDOR, 2, 0},
+  {"xtheade",   ISA_SPEC_CLASS_VENDOR, 2, 0},
+  {"xtheadse",   ISA_SPEC_CLASS_VENDOR, 2, 0},
 
   /* Terminate the list.  */
   {NULL, 0, 0, 0}
@@ -428,6 +431,18 @@ riscv_multi_subset_supports (enum riscv_insn_class insn_class)
 
     case INSN_CLASS_THEADC:
       return riscv_subset_supports ("xtheadc");
+    case INSN_CLASS_THEADC_OR_THEADE:
+      return (riscv_subset_supports ("xtheadc")
+	      || riscv_subset_supports ("xtheade"));
+    case INSN_CLASS_THEADC_OR_THEADE_OR_THEADSE:
+      return (riscv_subset_supports ("xtheadc")
+	      || riscv_subset_supports ("xtheade")
+	      || riscv_subset_supports ("xtheadse"));
+    case INSN_CLASS_THEADE:
+      return riscv_subset_supports ("xtheade");
+    case INSN_CLASS_THEADSE:
+      return riscv_subset_supports ("xtheadse");
+
 
     default:
       return riscv_extended_subset_supports (insn_class);
@@ -1019,6 +1034,7 @@ riscv_csr_address (const char *csr_name,
       need_check_version = false;
       break;
     case CSR_CLASS_DEBUG:
+    case CSR_CLASS_VENDOR:
       need_check_version = false;
       break;
     default:
@@ -1315,6 +1331,48 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
 		goto validate_extended_insn;
 	    }
 	  break;
+	case 'X':
+	  switch (*p++)
+	    {
+	    case 'g':
+	      /* Xgm@n.  */
+	    case 'F':
+	      /* XFm@n.  */
+	    case 'I':
+		{
+		  /* XIm@n.  */
+		  int nbit = 0;
+		  int at = -1;
+		  int shift = 0;
+		  nbit = strtol (p, (char **)&p, 10);
+		  if (*p =='@')
+		    at = strtol(++p, (char **)&p, 10);
+
+		  used_bits |= ENCODE_VENDOR_IMM((-1U>>shift), nbit, at);
+		  break;
+		}
+	    case 'S':
+	      /* XSm@n.  */
+		{
+		  int nbit = 0;
+		  int at = -1;
+		  int shift = 0;
+		  nbit = strtol (p, (char **)&p, 10);
+		  if ((*p) =='>' && (*(p+1)) == '>')
+		    shift = strtol (p, (char **)&p, 10);
+		  if (*p =='@')
+		    at = strtol(++p, (char **)&p, 10);
+
+		  used_bits |= ENCODE_VENDOR_IMM((-1>>shift), nbit, at);
+		  break;
+		}
+	    case 'C':
+	      /* XCm.  */
+	      strtol (p, (char **)&p, 10);
+	      break;
+	    }
+	  break;
+
 	default:
 	validate_extended_insn:
 	  oparg = opargStart;
@@ -1327,6 +1385,7 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
 	    }
 	}
     }
+
   if (used_bits != required_bits)
     {
       as_bad (_("internal: bad RISC-V opcode "
@@ -3429,6 +3488,94 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 	      asarg = expr_end;
 	      imm_expr->X_op = O_absent;
 	      continue;
+	    case 'X':
+		{
+		  int nbit = 0;
+		  int at = -1;
+		  int shift = 0;
+		  int constant;
+		  args++;
+		  c = *args++;
+		  switch (c)
+		    {
+		    case 'I':
+		      /* XIm@n.  */
+		      nbit = strtol (args, (char **)&args, 10);
+		      if ((*args) =='@')
+			at = strtol(++args, (char **)&args, 10);
+
+		      args--;
+
+		      if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
+			  || imm_expr->X_op != O_constant
+			  || !VALID_VENDOR_IMM(imm_expr->X_add_number, nbit, at))
+			break;
+		      ip->insn_opcode |=
+			ENCODE_VENDOR_IMM ((imm_expr->X_add_number >> shift), nbit, at);
+		      s = expr_end;
+		      imm_expr->X_op = O_absent;
+		      continue;
+		    case 'S':
+		      /* XSm@n.  */
+		      nbit = strtol (args, (char **)&args, 10);
+		      if ((*args) =='<' && (*(args+1)) == '<')
+			{
+			  args += 2;
+			  shift = strtol(++args, (char **)&args, 10);
+			}
+
+		      if ((*args) =='@')
+			at = strtol(++args, (char **)&args, 10);
+
+		      args--;
+
+
+		      if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
+			  || imm_expr->X_op != O_constant
+			  || !VALID_VENDOR_SIGN_IMM((imm_expr->X_add_number >> shift), nbit, at))
+			break;
+		      ip->insn_opcode |=
+			ENCODE_VENDOR_SIGN_IMM (imm_expr->X_add_number, nbit, at);
+		      s = expr_end;
+		      imm_expr->X_op = O_absent;
+		      continue;
+		    case 'g':
+		      /* Xgm@n.  */
+		      nbit = strtol (args, (char **)&args, 10);
+		      if ((*args) =='<' && (*(args+1)) == '<')
+			{
+			  args += 2;
+			  shift = strtol(++args, (char **)&args, 10);
+			}
+
+		      if ((*args) =='@')
+			at = strtol(++args, (char **)&args, 10);
+
+		      args--;
+
+
+		      if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
+			  || imm_expr->X_op != O_register
+			  || !VALID_VENDOR_IMM(imm_expr->X_add_number, nbit, at))
+			break;
+		      ip->insn_opcode |=
+			ENCODE_VENDOR_IMM (imm_expr->X_add_number, nbit, at);
+		      s = expr_end;
+		      continue;
+		    case 'C':
+		      /* XCm, constant with no encode.  */
+		      constant = strtol (args, (char **)&args, 10);
+		      args--;
+
+		      if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
+			  || imm_expr->X_op != O_constant
+			  || (imm_expr->X_add_number != constant))
+			break;
+		      s = expr_end;
+		      continue;
+		    }
+		}
+	      break;;
 
 	    default:
 	      parse_extended_operand:
diff --git a/gas/testsuite/gas/riscv/thead/riscv.exp b/gas/testsuite/gas/riscv/thead/riscv.exp
new file mode 100644
index 00000000000..11602fb3fcc
--- /dev/null
+++ b/gas/testsuite/gas/riscv/thead/riscv.exp
@@ -0,0 +1,3 @@
+if {[istarget riscv*-*-*]} {
+ run_dump_tests [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
+}
diff --git a/gas/testsuite/gas/riscv/thead/thead-csr-list.d b/gas/testsuite/gas/riscv/thead/thead-csr-list.d
new file mode 100644
index 00000000000..efe7859decd
--- /dev/null
+++ b/gas/testsuite/gas/riscv/thead/thead-csr-list.d
@@ -0,0 +1,108 @@
+#as: -march=rv64gcxtheadc
+#objdump: -dr
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0000000000000000 <.text>:
+   0:	7c002573          	csrr	a0,mxstatus
+   4:	7c102573          	csrr	a0,mhcr
+   8:	7c202573          	csrr	a0,mcor
+   c:	7c302573          	csrr	a0,mccr2
+  10:	7c402573          	csrr	a0,mcer2
+  14:	7c502573          	csrr	a0,mhint
+  18:	7c602573          	csrr	a0,mrmr
+  1c:	7c702573          	csrr	a0,mrvbr
+  20:	7c802573          	csrr	a0,mcer
+  24:	7c902573          	csrr	a0,mcounterwen
+  28:	7ca02573          	csrr	a0,mcounterinten
+  2c:	7cb02573          	csrr	a0,mcounterof
+  30:	7cc02573          	csrr	a0,mhint2
+  34:	7cd02573          	csrr	a0,mhint3
+  38:	7e002573          	csrr	a0,mraddr
+  3c:	7e102573          	csrr	a0,mexstatus
+  40:	7e202573          	csrr	a0,mnmicause
+  44:	7e302573          	csrr	a0,mnmipc
+  48:	7f002573          	csrr	a0,mhpmcr
+  4c:	7f102573          	csrr	a0,mhpmsr
+  50:	7f202573          	csrr	a0,mhpmer
+  54:	7f302573          	csrr	a0,msmpr
+  58:	7f402573          	csrr	a0,mteecfg
+  5c:	7d102573          	csrr	a0,usp
+  60:	7d202573          	csrr	a0,mcins
+  64:	7d302573          	csrr	a0,mcindex
+  68:	7d402573          	csrr	a0,mcdata0
+  6c:	7d502573          	csrr	a0,mcdata1
+  70:	7d602573          	csrr	a0,meicr
+  74:	7d702573          	csrr	a0,meicr2
+  78:	be002573          	csrr	a0,mebr
+  7c:	be102573          	csrr	a0,nt_mstatus
+  80:	be302573          	csrr	a0,nt_mtvec
+  84:	be202573          	csrr	a0,nt_mie
+  88:	be402573          	csrr	a0,nt_mtvt
+  8c:	be502573          	csrr	a0,nt_mepc
+  90:	be602573          	csrr	a0,nt_mcause
+  94:	be702573          	csrr	a0,nt_mip
+  98:	be802573          	csrr	a0,nt_mintstate
+  9c:	be902573          	csrr	a0,nt_mxstatus
+  a0:	bea02573          	csrr	a0,nt_mebr
+  a4:	beb02573          	csrr	a0,nt_msp
+  a8:	bec02573          	csrr	a0,t_usp
+  ac:	bed02573          	csrr	a0,t_mdcr
+  b0:	bee02573          	csrr	a0,t_mpcr
+  b4:	bef02573          	csrr	a0,pmpteecfg
+  b8:	fc002573          	csrr	a0,mcpuid
+  bc:	fc102573          	csrr	a0,mapbaddr
+  c0:	fc202573          	csrr	a0,mwmsr
+  c4:	80002573          	csrr	a0,fxcr
+  c8:	9c002573          	csrr	a0,smir
+  cc:	9c102573          	csrr	a0,smel
+  d0:	9c202573          	csrr	a0,smeh
+  d4:	9c302573          	csrr	a0,smcir
+  d8:	5c002573          	csrr	a0,sxstatus
+  dc:	5c102573          	csrr	a0,shcr
+  e0:	5c202573          	csrr	a0,scer2
+  e4:	5c302573          	csrr	a0,scer
+  e8:	5c402573          	csrr	a0,scounterinten
+  ec:	5c502573          	csrr	a0,scounterof
+  f0:	5c602573          	csrr	a0,shint
+  f4:	5c702573          	csrr	a0,shint2
+  f8:	5c802573          	csrr	a0,shpminhibit
+  fc:	5c902573          	csrr	a0,shpmcr
+ 100:	5ca02573          	csrr	a0,shpmsr
+ 104:	5cb02573          	csrr	a0,shpmer
+ 108:	5e002573          	csrr	a0,scycle
+ 10c:	5e102573          	csrr	a0,shpmcounter1
+ 110:	5e202573          	csrr	a0,shpmcounter2
+ 114:	5e302573          	csrr	a0,shpmcounter3
+ 118:	5e402573          	csrr	a0,shpmcounter4
+ 11c:	5e502573          	csrr	a0,shpmcounter5
+ 120:	5e602573          	csrr	a0,shpmcounter6
+ 124:	5e702573          	csrr	a0,shpmcounter7
+ 128:	5e802573          	csrr	a0,shpmcounter8
+ 12c:	5e902573          	csrr	a0,shpmcounter9
+ 130:	5ea02573          	csrr	a0,shpmcounter10
+ 134:	5eb02573          	csrr	a0,shpmcounter11
+ 138:	5ec02573          	csrr	a0,shpmcounter12
+ 13c:	5ed02573          	csrr	a0,shpmcounter13
+ 140:	5ee02573          	csrr	a0,shpmcounter14
+ 144:	5ef02573          	csrr	a0,shpmcounter15
+ 148:	5f002573          	csrr	a0,shpmcounter16
+ 14c:	5f102573          	csrr	a0,shpmcounter17
+ 150:	5f202573          	csrr	a0,shpmcounter18
+ 154:	5f302573          	csrr	a0,shpmcounter19
+ 158:	5f402573          	csrr	a0,shpmcounter20
+ 15c:	5f502573          	csrr	a0,shpmcounter21
+ 160:	5f602573          	csrr	a0,shpmcounter22
+ 164:	5f702573          	csrr	a0,shpmcounter23
+ 168:	5f802573          	csrr	a0,shpmcounter24
+ 16c:	5f902573          	csrr	a0,shpmcounter25
+ 170:	5fa02573          	csrr	a0,shpmcounter26
+ 174:	5fb02573          	csrr	a0,shpmcounter27
+ 178:	5fc02573          	csrr	a0,shpmcounter28
+ 17c:	5fd02573          	csrr	a0,shpmcounter29
+ 180:	5fe02573          	csrr	a0,shpmcounter30
+ 184:	5ff02573          	csrr	a0,shpmcounter31
+
diff --git a/gas/testsuite/gas/riscv/thead/thead-csr-list.s b/gas/testsuite/gas/riscv/thead/thead-csr-list.s
new file mode 100644
index 00000000000..d6de0274dc5
--- /dev/null
+++ b/gas/testsuite/gas/riscv/thead/thead-csr-list.s
@@ -0,0 +1,99 @@
+csrr a0, mxstatus
+csrr a0, mhcr
+csrr a0, mcor
+csrr a0, mccr2
+csrr a0, mcer2
+csrr a0, mhint
+csrr a0, mrmr
+csrr a0, mrvbr
+csrr a0, mcer
+csrr a0, mcounterwen
+csrr a0, mcounterinten
+csrr a0, mcounterof
+csrr a0, mhint2
+csrr a0, mhint3
+csrr a0, mraddr
+csrr a0, mexstatus
+csrr a0, mnmicause
+csrr a0, mnmipc
+csrr a0, mhpmcr
+csrr a0, mhpmsr
+csrr a0, mhpmer
+csrr a0, msmpr
+csrr a0, mteecfg
+csrr a0, usp
+csrr a0, mcins
+csrr a0, mcindex
+csrr a0, mcdata0
+csrr a0, mcdata1
+csrr a0, meicr
+csrr a0, meicr2
+csrr a0, mebr
+csrr a0, nt_mstatus
+csrr a0, nt_mtvec
+csrr a0, nt_mie
+csrr a0, nt_mtvt
+csrr a0, nt_mepc
+csrr a0, nt_mcause
+csrr a0, nt_mip
+csrr a0, nt_mintstate
+csrr a0, nt_mxstatus
+csrr a0, nt_mebr
+csrr a0, nt_msp
+csrr a0, t_usp
+csrr a0, t_mdcr
+csrr a0, t_mpcr
+csrr a0, pmpteecfg
+csrr a0, mcpuid
+csrr a0, mapbaddr
+csrr a0, mwmsr
+csrr a0, fxcr
+csrr a0, smir
+csrr a0, smel
+csrr a0, smeh
+csrr a0, smcir
+csrr a0, sxstatus
+csrr a0, shcr
+csrr a0, scer2
+csrr a0, scer
+csrr a0, scounterinten
+csrr a0, scounterof
+csrr a0, shint
+csrr a0, shint2
+csrr a0, shpminhibit
+csrr a0, shpmcr
+csrr a0, shpmsr
+csrr a0, shpmer
+csrr a0, scycle
+csrr a0, shpmcounter1
+csrr a0, shpmcounter2
+csrr a0, shpmcounter3
+csrr a0, shpmcounter4
+csrr a0, shpmcounter5
+csrr a0, shpmcounter6
+csrr a0, shpmcounter7
+csrr a0, shpmcounter8
+csrr a0, shpmcounter9
+csrr a0, shpmcounter10
+csrr a0, shpmcounter11
+csrr a0, shpmcounter12
+csrr a0, shpmcounter13
+csrr a0, shpmcounter14
+csrr a0, shpmcounter15
+csrr a0, shpmcounter16
+csrr a0, shpmcounter17
+csrr a0, shpmcounter18
+csrr a0, shpmcounter19
+csrr a0, shpmcounter20
+csrr a0, shpmcounter21
+csrr a0, shpmcounter22
+csrr a0, shpmcounter23
+csrr a0, shpmcounter24
+csrr a0, shpmcounter25
+csrr a0, shpmcounter26
+csrr a0, shpmcounter27
+csrr a0, shpmcounter28
+csrr a0, shpmcounter29
+csrr a0, shpmcounter30
+csrr a0, shpmcounter31
+
diff --git a/gas/testsuite/gas/riscv/thead/theadc-ext.d b/gas/testsuite/gas/riscv/thead/theadc-ext.d
new file mode 100644
index 00000000000..d9dfd0682c7
--- /dev/null
+++ b/gas/testsuite/gas/riscv/thead/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          	dcache.call
+   8:	0030000b          	dcache.ciall
+   c:	02b5000b          	dcache.cipa	a0
+  10:	0235000b          	dcache.cisw	a0
+  14:	0275000b          	dcache.civa	a0
+  18:	0295000b          	dcache.cpa	a0
+  1c:	0285000b          	dcache.cpal1	a0
+  20:	0255000b          	dcache.cva	a0
+  24:	0245000b          	dcache.cval1	a0
+  28:	02a5000b          	dcache.ipa	a0
+  2c:	0225000b          	dcache.isw	a0
+  30:	0265000b          	dcache.iva	a0
+  34:	0020000b          	dcache.iall
+  38:	0215000b          	dcache.csw	a0
+  3c:	0100000b          	icache.iall
+  40:	0110000b          	icache.ialls
+  44:	0305000b          	icache.iva	a0
+  48:	0385000b          	icache.ipa	a0
+  4c:	0160000b          	l2cache.iall
+  50:	0150000b          	l2cache.call
+  54:	0170000b          	l2cache.ciall
+  58:	04b5000b          	sfence.vmas	a0,a1
+  5c:	0180000b          	sync
+  60:	01a0000b          	sync.i
+  64:	0190000b          	sync.s
+  68:	01b0000b          	sync.is
+  6c:	02c5950b          	addsl	a0,a1,a2,1
+  70:	20c5950b          	mula	a0,a1,a2
+  74:	22c5950b          	muls	a0,a1,a2
+  78:	24c5950b          	mulaw	a0,a1,a2
+  7c:	26c5950b          	mulsw	a0,a1,a2
+  80:	28c5950b          	mulah	a0,a1,a2
+  84:	2ac5950b          	mulsh	a0,a1,a2
+  88:	1105950b          	srri	a0,a1,16
+  8c:	1505950b          	srriw	a0,a1,16
+  90:	40c5950b          	mveqz	a0,a1,a2
+  94:	42c5950b          	mvnez	a0,a1,a2
+  98:	8905950b          	tst	a0,a1,16
+  9c:	8005950b          	tstnbz	a0,a1
+  a0:	4105a50b          	ext	a0,a1,16,16
+  a4:	4105b50b          	extu	a0,a1,16,16
+  a8:	8605950b          	ff1	a0,a1
+  ac:	8405950b          	ff0	a0,a1
+  b0:	8205950b          	rev	a0,a1
+  b4:	9005950b          	revw	a0,a1
+  b8:	62b5600b          	flrd	ft0,a0,a1,1
+  bc:	42b5600b          	flrw	ft0,a0,a1,1
+  c0:	72b5600b          	flurd	ft0,a0,a1,1
+  c4:	52b5600b          	flurw	ft0,a0,a1,1
+  c8:	02c5c50b          	lrb	a0,a1,a2,1
+  cc:	22c5c50b          	lrh	a0,a1,a2,1
+  d0:	42c5c50b          	lrw	a0,a1,a2,1
+  d4:	62c5c50b          	lrd	a0,a1,a2,1
+  d8:	82c5c50b          	lrbu	a0,a1,a2,1
+  dc:	a2c5c50b          	lrhu	a0,a1,a2,1
+  e0:	c2c5c50b          	lrwu	a0,a1,a2,1
+  e4:	12c5c50b          	lurb	a0,a1,a2,1
+  e8:	32c5c50b          	lurh	a0,a1,a2,1
+  ec:	52c5c50b          	lurw	a0,a1,a2,1
+  f0:	72c5c50b          	lurd	a0,a1,a2,1
+  f4:	92c5c50b          	lurbu	a0,a1,a2,1
+  f8:	b2c5c50b          	lurhu	a0,a1,a2,1
+  fc:	d2c5c50b          	lurwu	a0,a1,a2,1
+ 100:	1af5c50b          	lbia	a0,\(a1\),15,1
+ 104:	0af5c50b          	lbib	a0,\(a1\),15,1
+ 108:	3af5c50b          	lhia	a0,\(a1\),15,1
+ 10c:	2af5c50b          	lhib	a0,\(a1\),15,1
+ 110:	5af5c50b          	lwia	a0,\(a1\),15,1
+ 114:	4af5c50b          	lwib	a0,\(a1\),15,1
+ 118:	7af5c50b          	ldia	a0,\(a1\),15,1
+ 11c:	6af5c50b          	ldib	a0,\(a1\),15,1
+ 120:	9af5c50b          	lbuia	a0,\(a1\),15,1
+ 124:	8af5c50b          	lbuib	a0,\(a1\),15,1
+ 128:	baf5c50b          	lhuia	a0,\(a1\),15,1
+ 12c:	aaf5c50b          	lhuib	a0,\(a1\),15,1
+ 130:	daf5c50b          	lwuia	a0,\(a1\),15,1
+ 134:	caf5c50b          	lwuib	a0,\(a1\),15,1
+ 138:	fab6450b          	ldd	a0,a1,\(a2\),1,4
+ 13c:	e2b6450b          	lwd	a0,a1,\(a2\),1,3
+ 140:	f2b6450b          	lwud	a0,a1,\(a2\),1,3
+ 144:	62b5700b          	fsrd	ft0,a0,a1,1
+ 148:	42b5700b          	fsrw	ft0,a0,a1,1
+ 14c:	72b5700b          	fsurd	ft0,a0,a1,1
+ 150:	52b5700b          	fsurw	ft0,a0,a1,1
+ 154:	02c5d50b          	srb	a0,a1,a2,1
+ 158:	22c5d50b          	srh	a0,a1,a2,1
+ 15c:	42c5d50b          	srw	a0,a1,a2,1
+ 160:	62c5d50b          	srd	a0,a1,a2,1
+ 164:	12c5d50b          	surb	a0,a1,a2,1
+ 168:	32c5d50b          	surh	a0,a1,a2,1
+ 16c:	52c5d50b          	surw	a0,a1,a2,1
+ 170:	72c5d50b          	surd	a0,a1,a2,1
+ 174:	1af5d50b          	sbia	a0,\(a1\),15,1
+ 178:	0af5d50b          	sbib	a0,\(a1\),15,1
+ 17c:	3af5d50b          	shia	a0,\(a1\),15,1
+ 180:	2af5d50b          	shib	a0,\(a1\),15,1
+ 184:	5ac5d50b          	swia	a0,\(a1\),12,1
+ 188:	4af5d50b          	swib	a0,\(a1\),15,1
+ 18c:	7af5d50b          	sdia	a0,\(a1\),15,1
+ 190:	6af5d50b          	sdib	a0,\(a1\),15,1
+ 194:	fab6550b          	sdd	a0,a1,\(a2\),1,4
+ 198:	e2b6550b          	swd	a0,a1,\(a2\),1,3
diff --git a/gas/testsuite/gas/riscv/thead/theadc-ext.s b/gas/testsuite/gas/riscv/thead/theadc-ext.s
new file mode 100644
index 00000000000..1bc43310fc1
--- /dev/null
+++ b/gas/testsuite/gas/riscv/thead/theadc-ext.s
@@ -0,0 +1,116 @@
+.text
+
+wsc
+
+# cache ext
+dcache.call
+dcache.ciall
+dcache.cipa a0
+dcache.cisw a0
+dcache.civa a0
+dcache.cpa a0
+dcache.cpal1 a0
+dcache.cva a0
+dcache.cval1 a0
+dcache.ipa a0
+dcache.isw a0
+dcache.iva a0
+dcache.iall
+dcache.csw a0
+icache.iall
+icache.ialls
+icache.iva a0
+icache.ipa a0
+l2cache.iall
+l2cache.call
+l2cache.ciall
+
+# sync ext
+sfence.vmas       a0, a1
+sync
+sync.i
+sync.s
+sync.is
+
+# calc ext
+addsl             a0, a1, a2, 1
+mula              a0, a1, a2
+muls              a0, a1, a2
+mulaw             a0, a1, a2
+mulsw             a0, a1, a2
+mulah             a0, a1, a2
+mulsh             a0, a1, a2
+srri              a0, a1, 16
+srriw             a0, a1, 16
+mveqz             a0, a1, a2
+mvnez             a0, a1, a2
+
+# bit ext
+tst               a0, a1, 16
+tstnbz            a0, a1
+ext               a0, a1, 16, 16
+extu              a0, a1, 16, 16
+ff1               a0, a1
+ff0               a0, a1
+rev               a0, a1
+revw       a0, a1
+
+# load/store ext
+flrd       f0, a0, a1, 1
+flrw       f0, a0, a1, 1
+flurd      f0, a0, a1, 1
+flurw      f0, a0, a1, 1
+lrb               a0, a1, a2, 1
+lrh               a0, a1, a2, 1
+lrw               a0, a1, a2, 1
+lrd               a0, a1, a2, 1
+lrbu              a0, a1, a2, 1
+lrhu              a0, a1, a2, 1
+lrwu              a0, a1, a2, 1
+lurb              a0, a1, a2, 1
+lurh              a0, a1, a2, 1
+lurw              a0, a1, a2, 1
+lurd              a0, a1, a2, 1
+lurbu             a0, a1, a2, 1
+lurhu             a0, a1, a2, 1
+lurwu             a0, a1, a2, 1
+lbia       a0, (a1), 15, 1
+lbib       a0, (a1), 15, 1
+lhia       a0, (a1), 15, 1
+lhib       a0, (a1), 15, 1
+lwia       a0, (a1), 15, 1
+lwib       a0, (a1), 15, 1
+ldia       a0, (a1), 15, 1
+ldib       a0, (a1), 15, 1
+lbuia      a0, (a1), 15, 1
+lbuib      a0, (a1), 15, 1
+lhuia      a0, (a1), 15, 1
+lhuib      a0, (a1), 15, 1
+lwuia      a0, (a1), 15, 1
+lwuib      a0, (a1), 15, 1
+ldd               a0, a1, (a2), 1, 4
+lwd               a0, a1, (a2), 1, 3
+lwud              a0, a1, (a2), 1, 3
+fsrd       f0, a0, a1, 1
+fsrw       f0, a0, a1, 1
+fsurd      f0, a0, a1, 1
+fsurw      f0, a0, a1, 1
+srb               a0, a1, a2, 1
+srh               a0, a1, a2, 1
+srw               a0, a1, a2, 1
+srd               a0, a1, a2, 1
+surb              a0, a1, a2, 1
+surh              a0, a1, a2, 1
+surw              a0, a1, a2, 1
+surd              a0, a1, a2, 1
+sbia              a0, (a1), 15, 1
+sbib              a0, (a1), 15, 1
+shia              a0, (a1), 15, 1
+shib              a0, (a1), 15, 1
+swia              a0, (a1), 12, 1
+swib              a0, (a1), 15, 1
+sdia              a0, (a1), 15, 1
+sdib              a0, (a1), 15, 1
+sdd               a0, a1, (a2), 1, 4
+swd               a0, a1, (a2), 1, 3
+
diff --git a/gas/testsuite/gas/riscv/thead/theade-ext.d b/gas/testsuite/gas/riscv/thead/theade-ext.d
new file mode 100644
index 00000000000..6f9cb5251c7
--- /dev/null
+++ b/gas/testsuite/gas/riscv/thead/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          	dcache.ipa	a0
+[       ]+[0-9a-f]+:\s+0295000b          	dcache.cpa	a0
+[       ]+[0-9a-f]+:\s+02b5000b          	dcache.cipa	a0
+[       ]+[0-9a-f]+:\s+0225000b          	dcache.isw	a0
+[       ]+[0-9a-f]+:\s+0215000b          	dcache.csw	a0
+[       ]+[0-9a-f]+:\s+0235000b          	dcache.cisw	a0
+[       ]+[0-9a-f]+:\s+0020000b          	dcache.iall
+[       ]+[0-9a-f]+:\s+0010000b          	dcache.call
+[       ]+[0-9a-f]+:\s+0030000b          	dcache.ciall
+[       ]+[0-9a-f]+:\s+0100000b          	icache.iall
+[       ]+[0-9a-f]+:\s+0385000b          	icache.ipa	a0
+[       ]+[0-9a-f]+:\s+0180000b          	sync
+[       ]+[0-9a-f]+:\s+01a0000b          	sync.i
+[       ]+[0-9a-f]+:\s+02c5950b          	addsl	a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+1105950b          	srri	a0,a1,16
+[       ]+[0-9a-f]+:\s+20c5950b          	mula	a0,a1,a2
+[       ]+[0-9a-f]+:\s+28c5950b          	mulah	a0,a1,a2
+[       ]+[0-9a-f]+:\s+22c5950b          	muls	a0,a1,a2
+[       ]+[0-9a-f]+:\s+2ac5950b          	mulsh	a0,a1,a2
+[       ]+[0-9a-f]+:\s+40c5950b          	mveqz	a0,a1,a2
+[       ]+[0-9a-f]+:\s+42c5950b          	mvnez	a0,a1,a2
+[       ]+[0-9a-f]+:\s+4105a50b          	ext	a0,a1,16,16
+[       ]+[0-9a-f]+:\s+4105b50b          	extu	a0,a1,16,16
+[       ]+[0-9a-f]+:\s+8605950b          	ff1	a0,a1
+[       ]+[0-9a-f]+:\s+8405950b          	ff0	a0,a1
+[       ]+[0-9a-f]+:\s+8205950b          	rev	a0,a1
+[       ]+[0-9a-f]+:\s+8905950b          	tst	a0,a1,16
+[       ]+[0-9a-f]+:\s+8005950b          	tstnbz	a0,a1
+[       ]+[0-9a-f]+:\s+02c5c50b          	lrb	a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+22c5c50b          	lrh	a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+42c5c50b          	lrw	a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+82c5c50b          	lrbu	a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+a2c5c50b          	lrhu	a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+1af5c50b          	lbia	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+0af5c50b          	lbib	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+3af5c50b          	lhia	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+2af5c50b          	lhib	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+5af5c50b          	lwia	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+4af5c50b          	lwib	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+02c5d50b          	srb	a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+22c5d50b          	srh	a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+42c5d50b          	srw	a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+1af5d50b          	sbia	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+0af5d50b          	sbib	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+3af5d50b          	shia	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+2af5d50b          	shib	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+5ac5d50b          	swia	a0,\(a1\),12,1
+[       ]+[0-9a-f]+:\s+4af5d50b          	swib	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+c000150b          	fmv.x.hw	a0,ft0
+[       ]+[0-9a-f]+:\s+a005100b          	fmv.hw.x	ft0,a0
+[       ]+[0-9a-f]+:\s+0040000b          	ipush
+[       ]+[0-9a-f]+:\s+0050000b          	ipop
diff --git a/gas/testsuite/gas/riscv/thead/theade-ext.s b/gas/testsuite/gas/riscv/thead/theade-ext.s
new file mode 100644
index 00000000000..5c93e04ef9f
--- /dev/null
+++ b/gas/testsuite/gas/riscv/thead/theade-ext.s
@@ -0,0 +1,67 @@
+.text
+
+wsc
+
+# cache ext
+dcache.ipa a0
+dcache.cpa a0
+dcache.cipa a0
+dcache.isw a0
+dcache.csw a0
+dcache.cisw a0
+dcache.iall
+dcache.call
+dcache.ciall
+icache.iall
+icache.ipa a0
+
+# sync ext
+sync
+sync.i
+
+# calc ext
+addsl             a0, a1, a2, 1
+srri              a0, a1, 16
+mula              a0, a1, a2
+mulah             a0, a1, a2
+muls              a0, a1, a2
+mulsh             a0, a1, a2
+mveqz             a0, a1, a2
+mvnez             a0, a1, a2
+
+# bit ext
+ext               a0, a1, 16, 16
+extu              a0, a1, 16, 16
+ff1               a0, a1
+ff0               a0, a1
+rev               a0, a1
+tst               a0, a1, 16
+tstnbz            a0, a1
+
+# load/store ext
+lrb               a0, a1, a2, 1
+lrh               a0, a1, a2, 1
+lrw               a0, a1, a2, 1
+lrbu              a0, a1, a2, 1
+lrhu              a0, a1, a2, 1
+lbia       a0, (a1), 15, 1
+lbib       a0, (a1), 15, 1
+lhia       a0, (a1), 15, 1
+lhib       a0, (a1), 15, 1
+lwia       a0, (a1), 15, 1
+lwib       a0, (a1), 15, 1
+srb               a0, a1, a2, 1
+srh               a0, a1, a2, 1
+srw               a0, a1, a2, 1
+sbia              a0, (a1), 15, 1
+sbib              a0, (a1), 15, 1
+shia              a0, (a1), 15, 1
+shib              a0, (a1), 15, 1
+swia              a0, (a1), 12, 1
+swib              a0, (a1), 15, 1
+
+fmv.x.hw   a0, f0
+fmv.hw.x   f0, a0
+ipush
+ipop
+
diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
index 84fc2ee0e8e..63664cb308c 100644
--- a/include/opcode/riscv-opc.h
+++ b/include/opcode/riscv-opc.h
@@ -18,9 +18,10 @@
    along with this program; see the file COPYING3. If not,
    see <http://www.gnu.org/licenses/>.  */
 
+#include "opcode/riscv-vendor-opc.h"
+
 #ifndef RISCV_ENCODING_H
 #define RISCV_ENCODING_H
-#include "opcode/riscv-vendor-opc.h"
 /* Instruction opcode macros.  */
 #define MATCH_SLLI_RV32 0x1013
 #define MASK_SLLI_RV32  0xfe00707f
diff --git a/include/opcode/riscv-vendor-opc.h b/include/opcode/riscv-vendor-opc.h
index 949047239f8..3cf6c6a7fb5 100644
--- a/include/opcode/riscv-vendor-opc.h
+++ b/include/opcode/riscv-vendor-opc.h
@@ -18,17 +18,483 @@
    along with this program; see the file COPYING3. If not,
    see <http://www.gnu.org/licenses/>.  */
 
-#ifndef __RISCV_VENDOR_OPC_H__
-#define __RISCV_VENDOR_OPC_H__
+#ifndef __RISCV_VENDOR_THEAD_OPC__
+#define __RISCV_VENDOR_THEAD_OPC__
 
+/* 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
 
-/* Opcodes for VENDOR 0.  */
+/* H extensions.  */
+#define MATCH_HFENCE_VVMA 0x22000073
+#define MASK_HFENCE_VVMA 0xfe007fff
+#define MATCH_HFENCE_GVMA 0x62000073
+#define MASK_HFENCE_GVMA 0xfe007fff
 
+/* T-Head crypto extensions.  */
+#define MATCH_THEAD_ANDN 0x0800100b
+#define MASK_THEAD_ANDN 0xfe00707f
+#define MATCH_THEAD_ORN 0x0a00100b
+#define MASK_THEAD_ORN 0xfe00707f
+#define MATCH_THEAD_XORN 0x0c00100b
+#define MASK_THEAD_XORN 0xfe00707f
+#define MATCH_THEAD_PACKL 0x1800100b
+#define MASK_THEAD_PACKL 0xfe00707f
+#define MATCH_THEAD_PACKH 0x1a00100b
+#define MASK_THEAD_PACKH 0xfe00707f
+#define MATCH_THEAD_PACKHL 0x1c00100b
+#define MASK_THEAD_PACKHL 0xfe00707f
 
-/* Opcodes for VENDOR 1.  */
+/* 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
 
-/* Opcodes for VENDOR 2.  */
+/* T-HEAD M mode CSR.  */
+#define CSR_MXSTATUS 0x7c0
+#define CSR_MHCR 0x7c1
+#define CSR_MCOR 0x7c2
+#define CSR_MCCR2 0x7c3
+#define CSR_MCER2 0x7c4
+#define CSR_MHINT 0x7c5
+#define CSR_MRMR 0x7c6
+#define CSR_MRVBR 0x7c7
+#define CSR_MCER 0x7c8
+#define CSR_MCOUNTERWEN 0x7c9
+#define CSR_MCOUNTERINTEN 0x7ca
+#define CSR_MCOUNTEROF 0x7cb
+#define CSR_MHINT2 0x7cc
+#define CSR_MHINT3 0x7cd
+#define CSR_MRADDR 0x7e0
+#define CSR_MEXSTATUS 0x7e1
+#define CSR_MNMICAUSE 0x7e2
+#define CSR_MNMIPC 0x7e3
+#define CSR_MHPMCR 0x7f0
+#define CSR_MHPMSR 0x7f1
+#define CSR_MHPMER 0x7f2
+#define CSR_MSMPR 0x7f3
+#define CSR_MTEECFG 0x7f4
+#define CSR_MZONEID 0x7f5
+#define CSR_ML2CPID 0x7f6
+#define CSR_ML2WP 0x7f7
+#define CSR_MDTCMCR 0x7f8
+#define CSR_USP 0x7d1
+#define CSR_MCINS 0x7d2
+#define CSR_MCINDEX 0x7d3
+#define CSR_MCDATA0 0x7d4
+#define CSR_MCDATA1 0x7d5
+#define CSR_MEICR 0x7d6
+#define CSR_MEICR2 0x7d7
+#define CSR_MBEADDR 0x7d8
+#define CSR_MCPUID 0xfc0
+#define CSR_MAPBADDR 0xfc1
+#define CSR_MWMSR 0xfc2
+#define CSR_MHALTCAUSE 0xfe0
+#define CSR_MDBGINFO 0xfe1
+#define CSR_MPCFIFO 0xfe2
+
+
+/* T-HEAD S mode CSR.  */
+#define CSR_SXSTATUS 0x5c0
+#define CSR_SHCR 0x5c1
+#define CSR_SCER2 0x5c2
+#define CSR_SCER 0x5c3
+#define CSR_SCOUNTERINTEN 0x5c4
+#define CSR_SCOUNTEROF 0x5c5
+#define CSR_SHINT 0x5c6
+#define CSR_SHINT2 0x5c7
+#define CSR_SHPMINHIBIT 0x5c8
+#define CSR_SHPMCR 0x5c9
+#define CSR_SHPMSR 0x5ca
+#define CSR_SHPMER 0x5cb
+#define CSR_SL2CPID 0x5cc
+#define CSR_SL2WP 0x5cd
+#define CSR_SBEADDR 0x5d0
+#define CSR_SCYCLE 0x5e0
+#define CSR_SHPMCOUNTER1 0x5e1
+#define CSR_SHPMCOUNTER2 0x5e2
+#define CSR_SHPMCOUNTER3 0x5e3
+#define CSR_SHPMCOUNTER4 0x5e4
+#define CSR_SHPMCOUNTER5 0x5e5
+#define CSR_SHPMCOUNTER6 0x5e6
+#define CSR_SHPMCOUNTER7 0x5e7
+#define CSR_SHPMCOUNTER8 0x5e8
+#define CSR_SHPMCOUNTER9 0x5e9
+#define CSR_SHPMCOUNTER10 0x5ea
+#define CSR_SHPMCOUNTER11 0x5eb
+#define CSR_SHPMCOUNTER12 0x5ec
+#define CSR_SHPMCOUNTER13 0x5ed
+#define CSR_SHPMCOUNTER14 0x5ee
+#define CSR_SHPMCOUNTER15 0x5ef
+#define CSR_SHPMCOUNTER16 0x5f0
+#define CSR_SHPMCOUNTER17 0x5f1
+#define CSR_SHPMCOUNTER18 0x5f2
+#define CSR_SHPMCOUNTER19 0x5f3
+#define CSR_SHPMCOUNTER20 0x5f4
+#define CSR_SHPMCOUNTER21 0x5f5
+#define CSR_SHPMCOUNTER22 0x5f6
+#define CSR_SHPMCOUNTER23 0x5f7
+#define CSR_SHPMCOUNTER24 0x5f8
+#define CSR_SHPMCOUNTER25 0x5f9
+#define CSR_SHPMCOUNTER26 0x5fa
+#define CSR_SHPMCOUNTER27 0x5fb
+#define CSR_SHPMCOUNTER28 0x5fc
+#define CSR_SHPMCOUNTER29 0x5fd
+#define CSR_SHPMCOUNTER30 0x5fe
+#define CSR_SHPMCOUNTER31 0x5ff
 
+/* T-HEAD U mode CSR.  */
+#define CSR_FXCR 0x800
+
+/* T-HEAD MMU extentions.  */
+#define CSR_SMIR 0x9c0
+#define CSR_SMEL 0x9c1
+#define CSR_SMEH 0x9c2
+#define CSR_SMCIR 0x9c3
+
+/* T-HEAD Security CSR(May be droped).  */
+#define CSR_MEBR 0xbe0
+#define CSR_NT_MSTATUS 0xbe1
+#define CSR_NT_MIE 0xbe2
+#define CSR_NT_MTVEC 0xbe3
+#define CSR_NT_MTVT 0xbe4
+#define CSR_NT_MEPC 0xbe5
+#define CSR_NT_MCAUSE 0xbe6
+#define CSR_NT_MIP 0xbe7
+#define CSR_NT_MINTSTATE 0xbe8
+#define CSR_NT_MXSTATUS 0xbe9
+#define CSR_NT_MEBR 0xbea
+#define CSR_NT_MSP 0xbeb
+#define CSR_T_USP 0xbec
+#define CSR_T_MDCR 0xbed
+#define CSR_T_MPCR 0xbee
+#define CSR_PMPTEECFG 0xbef
+#endif
 
+#ifdef DECLARE_CSR
+/* T-HEAD extentions.  */
+DECLARE_CSR(mxstatus, CSR_MXSTATUS, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mhcr, CSR_MHCR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcor, CSR_MCOR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mccr2, CSR_MCCR2, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcer2, CSR_MCER2, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mhint, CSR_MHINT, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mrmr, CSR_MRMR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mrvbr, CSR_MRVBR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcer, CSR_MCER, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcounterwen, CSR_MCOUNTERWEN, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcounterinten, CSR_MCOUNTERINTEN, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcounterof, CSR_MCOUNTEROF, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mhint2, CSR_MHINT2, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mhint3, CSR_MHINT3, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mraddr, CSR_MRADDR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mexstatus, CSR_MEXSTATUS, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mnmicause, CSR_MNMICAUSE, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mnmipc, CSR_MNMIPC, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mhpmcr, CSR_MHPMCR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mhpmsr, CSR_MHPMSR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mhpmer, CSR_MHPMER, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(msmpr, CSR_MSMPR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mteecfg, CSR_MTEECFG, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mzoneid, CSR_MZONEID, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(ml2cpid, CSR_ML2CPID, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(ml2wp, CSR_ML2WP, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mdtcmcr, CSR_MDTCMCR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(usp, CSR_USP, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcins, CSR_MCINS, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcindex, CSR_MCINDEX, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcdata0, CSR_MCDATA0, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcdata1, CSR_MCDATA1, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(meicr, CSR_MEICR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(meicr2, CSR_MEICR2, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mbeaddr, CSR_MBEADDR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mebr, CSR_MEBR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_mstatus, CSR_NT_MSTATUS, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_mtvec, CSR_NT_MTVEC, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_mie, CSR_NT_MIE, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_mtvt, CSR_NT_MTVT, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_mepc, CSR_NT_MEPC, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_mcause, CSR_NT_MCAUSE, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_mip, CSR_NT_MIP, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_mintstate, CSR_NT_MINTSTATE, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_mxstatus, CSR_NT_MXSTATUS, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_mebr, CSR_NT_MEBR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_msp, CSR_NT_MSP, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(t_usp, CSR_T_USP, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(t_mdcr, CSR_T_MDCR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(t_mpcr, CSR_T_MPCR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(pmpteecfg, CSR_PMPTEECFG, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcpuid, CSR_MCPUID, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mapbaddr, CSR_MAPBADDR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mwmsr, CSR_MWMSR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(fxcr, CSR_FXCR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(smir, CSR_SMIR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(smel, CSR_SMEL, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(smeh, CSR_SMEH, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(smcir, CSR_SMCIR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(sxstatus, CSR_SXSTATUS, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shcr, CSR_SHCR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(scer2, CSR_SCER2, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(scer, CSR_SCER, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(scounterinten , CSR_SCOUNTERINTEN, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(scounterof, CSR_SCOUNTEROF, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shint, CSR_SHINT, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shint2, CSR_SHINT2, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpminhibit, CSR_SHPMINHIBIT, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcr, CSR_SHPMCR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmsr, CSR_SHPMSR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmer, CSR_SHPMER, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(sl2cpid, CSR_SL2CPID, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(sl2wp, CSR_SL2WP, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(sbeaddr, CSR_SBEADDR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(scycle, CSR_SCYCLE, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter1, CSR_SHPMCOUNTER1, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter2, CSR_SHPMCOUNTER2, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter3, CSR_SHPMCOUNTER3, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter4, CSR_SHPMCOUNTER4, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter5, CSR_SHPMCOUNTER5, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter6, CSR_SHPMCOUNTER6, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter7, CSR_SHPMCOUNTER7, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter8, CSR_SHPMCOUNTER8, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter9, CSR_SHPMCOUNTER9, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter10, CSR_SHPMCOUNTER10, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter11, CSR_SHPMCOUNTER11, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter12, CSR_SHPMCOUNTER12, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter13, CSR_SHPMCOUNTER13, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter14, CSR_SHPMCOUNTER14, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter15, CSR_SHPMCOUNTER15, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter16, CSR_SHPMCOUNTER16, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter17, CSR_SHPMCOUNTER17, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter18, CSR_SHPMCOUNTER18, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter19, CSR_SHPMCOUNTER19, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter20, CSR_SHPMCOUNTER20, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter21, CSR_SHPMCOUNTER21, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter22, CSR_SHPMCOUNTER22, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter23, CSR_SHPMCOUNTER23, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter24, CSR_SHPMCOUNTER24, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter25, CSR_SHPMCOUNTER25, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter26, CSR_SHPMCOUNTER26, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter27, CSR_SHPMCOUNTER27, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter28, CSR_SHPMCOUNTER28, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter29, CSR_SHPMCOUNTER29, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter30, CSR_SHPMCOUNTER30, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter31, CSR_SHPMCOUNTER31, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
 #endif
+
+
+/* Opcodes for VENDOR 1.  */
+
+
+/* Opcodes for VENDOR 2.  */
+
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index af8df794d1b..7ea645b8bfe 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -102,6 +102,10 @@ static const char * const riscv_pred_succ[16] =
   ((RV_X(x, 3, 2) << 1) | (RV_X(x, 10, 2) << 3) | (RV_X(x, 2, 1) << 5) | (RV_X(x, 5, 2) << 6) | (-RV_X(x, 12, 1) << 8))
 #define EXTRACT_CJTYPE_IMM(x) \
   ((RV_X(x, 3, 3) << 1) | (RV_X(x, 11, 1) << 4) | (RV_X(x, 2, 1) << 5) | (RV_X(x, 7, 1) << 6) | (RV_X(x, 6, 1) << 7) | (RV_X(x, 9, 2) << 8) | (RV_X(x, 8, 1) << 10) | (-RV_X(x, 12, 1) << 11))
+#define EXTRACT_VENDOR_IMM(x,nbit,at) \
+  (RV_X(x, at, nbit))
+#define EXTRACT_VENDOR_SIGN_IMM(x,nbit,at) \
+  (RV_X(x, at, nbit) | ((-(RV_X(x, (at+nbit-1),1))) << (nbit)))
 
 #define ENCODE_ITYPE_IMM(x) \
   (RV_X(x, 0, 12) << 20)
@@ -143,6 +147,11 @@ static const char * const riscv_pred_succ[16] =
   ((RV_X(x, 1, 2) << 3) | (RV_X(x, 3, 2) << 10) | (RV_X(x, 5, 1) << 2) | (RV_X(x, 6, 2) << 5) | (RV_X(x, 8, 1) << 12))
 #define ENCODE_CJTYPE_IMM(x) \
   ((RV_X(x, 1, 3) << 3) | (RV_X(x, 4, 1) << 11) | (RV_X(x, 5, 1) << 2) | (RV_X(x, 6, 1) << 7) | (RV_X(x, 7, 1) << 6) | (RV_X(x, 8, 2) << 9) | (RV_X(x, 10, 1) << 8) | (RV_X(x, 11, 1) << 12))
+#define ENCODE_VENDOR_IMM(x,nbit,at) \
+  (RV_X(x, 0, nbit) << at)
+#define ENCODE_VENDOR_SIGN_IMM(x,nbit,at) \
+  (RV_X(x, 0, nbit) << at)
+
 
 #define VALID_ITYPE_IMM(x) (EXTRACT_ITYPE_IMM(ENCODE_ITYPE_IMM(x)) == (x))
 #define VALID_STYPE_IMM(x) (EXTRACT_STYPE_IMM(ENCODE_STYPE_IMM(x)) == (x))
@@ -166,6 +175,8 @@ static const char * const riscv_pred_succ[16] =
 #define VALID_CLTYPE_LD_IMM(x) (EXTRACT_CLTYPE_LD_IMM(ENCODE_CLTYPE_LD_IMM(x)) == (x))
 #define VALID_CBTYPE_IMM(x) (EXTRACT_CBTYPE_IMM(ENCODE_CBTYPE_IMM(x)) == (x))
 #define VALID_CJTYPE_IMM(x) (EXTRACT_CJTYPE_IMM(ENCODE_CJTYPE_IMM(x)) == (x))
+#define VALID_VENDOR_IMM(x,nbit,at) (EXTRACT_VENDOR_IMM(ENCODE_VENDOR_IMM(x,nbit,at),nbit,at) == (x))
+#define VALID_VENDOR_SIGN_IMM(x,nbit,at) (EXTRACT_VENDOR_SIGN_IMM(ENCODE_VENDOR_SIGN_IMM(x,nbit,at),nbit,at) == (x))
 
 #define RISCV_RTYPE(insn, rd, rs1, rs2) \
   ((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ((rs1) << OP_SH_RS1) | ((rs2) << OP_SH_RS2))
@@ -320,6 +331,7 @@ enum riscv_insn_class
   INSN_CLASS_ZBB,
   INSN_CLASS_ZBC,
   INSN_CLASS_EXTENDED
+
 };
 
 /* This structure holds information for a particular instruction.  */
@@ -506,6 +518,10 @@ enum riscv_extended_insn_class
 
   /* INSN class for THEAD.  */
   INSN_CLASS_THEADC,
+  INSN_CLASS_THEADC_OR_THEADE,
+  INSN_CLASS_THEADC_OR_THEADE_OR_THEADSE,
+  INSN_CLASS_THEADE,
+  INSN_CLASS_THEADSE,
 };
 
 /* This is a list of macro expanded instructions for extended
@@ -528,4 +544,7 @@ extern const char * const riscv_vma[2];
 
 extern const struct riscv_opcode *riscv_extended_opcodes[];
 
+/* Matches for opcode.  */
+int match_opcode (const struct riscv_opcode *op, insn_t insn);
+
 #endif /* _RISCV_H_ */
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index 8ddc6bec370..c67c18946f1 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -528,6 +528,56 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 	case 'Z':
 	  print (info->stream, "%d", rs1);
 	  break;
+	case 'X':
+	    {
+	      int nbit = 0;
+	      int at = -1;
+	      char c = 0;
+	      int shift = 0;
+	      int constant = 0;
+	      d++;
+	      c = *d++;
+	      switch (c)
+		{
+		case 'I':
+		  nbit = strtol (d, (char **)&d, 10);
+		  if ((*d) =='@')
+		    at = strtol(++d, (char **)&d, 10);
+
+		  d--;
+
+		  print (info->stream, "%d", (unsigned int)(EXTRACT_VENDOR_IMM(l, nbit, at) << shift));
+		  break;
+		case 'S':
+		  nbit = strtol (d, (char **)&d, 10);
+		  if ((*d) =='<' && (*(d + 1) == '<'))
+		    {
+		      d += 2;
+		      shift = strtol (d, (char **)&d, 10);
+		    }
+		  if ((*d) =='@')
+		    at = strtol(++d, (char **)&d, 10);
+
+		  d--;
+
+		  print (info->stream, "%d", (unsigned)(EXTRACT_VENDOR_SIGN_IMM(l, nbit, at) << shift));
+		  break;
+		case 'g':
+		  nbit = strtol (d, (char **)&d, 10);
+		  if ((*d) =='@')
+		    at = strtol(++d, (char **)&d, 10);
+
+		  d--;
+		  print (info->stream, "%s", riscv_gpr_names[EXTRACT_VENDOR_IMM(l, nbit, at)]);
+		  break;
+		case 'C':
+		  constant = strtol (d, (char **)&d, 10);
+		  print (info->stream, "%d", constant);
+		  d--;
+		  break;
+		}
+	    }
+	  break;
 
 	default:
 	  oparg = opargStart;
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index c8e773460e1..6cb3b264f9c 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -86,7 +86,7 @@ const char * const riscv_fpr_names_abi[NFPR] =
 #define MATCH_SHAMT_REV8_64 (0b111000 << OP_SH_SHAMT)
 #define MATCH_SHAMT_ORC_B (0b00111 << OP_SH_SHAMT)
 
-static int
+int
 match_opcode (const struct riscv_opcode *op,
 	      insn_t insn,
 	      int constraints ATTRIBUTE_UNUSED,
diff --git a/opcodes/riscv-vendor-opc.c b/opcodes/riscv-vendor-opc.c
index 9191b654c14..085a38525a6 100644
--- a/opcodes/riscv-vendor-opc.c
+++ b/opcodes/riscv-vendor-opc.c
@@ -26,9 +26,165 @@
 #include <stdio.h>
 #include "bfd.h"
 
+
+/*
+   ARG format:
+
+   "Xgm@n": encode GPR with m bit at opcode[m+n-1:n].
+    "Xg5@0": encode GPR with 5 bit at opcode[4:0].
+    "Xg5@8": encode GPR with 5 bit at opcode[12:8].
+
+   "XCm": constant m, no encode for this.
+    "XC4": constant 4.
+
+   "XIm@n": m bits unsigned immediate at opcode[m+n-1:n].
+    "XI5@0": 5 bits unsigned immediate at opcode[4:0].
+    "XI4@8": 4 bits unsigned immediate at opcode[11:8].
+
+   "XSm@n": m bits signed immediate at opcode[m+n-1:n].
+    "XS5@0": 5 bits signed immediate at opcode[4:0].
+    "XS4@8": 4 bits signed immediate at opcode[11:8].
+
+   "XFm@n": m bits FR at opcode[m+n-1:n].
+    "XF5@0": 5 bits FR at opcode[4:0].
+    "XF5@0": 5 bits FR at opcode[4:0].
+*/
+
+#define MASK_RS1 (OP_MASK_RS1 << OP_SH_RS1)
+#define MASK_RS2 (OP_MASK_RS2 << OP_SH_RS2)
+#define MASK_RD (OP_MASK_RD << OP_SH_RD)
+
+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;
+
+  /* FIXME: add xlen check.  */
+  return match_opcode (op, insn) && rd1 != rs1 && rd2 != rs1;
+}
+
 /* The vendor extension opcodes for T-HEAD.  */
 struct riscv_opcode vendor_thead_opcodes[] =
 {
+  {"wsc",             0, INSN_CLASS_THEADC_OR_THEADE,   "",  MATCH_WSC, MASK_WSC, match_opcode, 0},
+  {"dcache.iall",     0, INSN_CLASS_THEADC_OR_THEADE,   "",  MATCH_DCACHE_IALL, MASK_DCACHE_IALL, match_opcode, 0},
+  {"dcache.call",     0, INSN_CLASS_THEADC_OR_THEADE,   "",  MATCH_DCACHE_CALL, MASK_DCACHE_CALL, match_opcode, 0},
+  {"dcache.ciall",    0, INSN_CLASS_THEADC_OR_THEADE,   "",  MATCH_DCACHE_CIALL, MASK_DCACHE_CIALL, match_opcode, 0},
+  {"dcache.isw",      0, INSN_CLASS_THEADC_OR_THEADE,   "s",     MATCH_DCACHE_ISW, MASK_DCACHE_ISW, match_opcode, 0},
+  {"dcache.csw",      0, INSN_CLASS_THEADC_OR_THEADE,   "s",     MATCH_DCACHE_CSW, MASK_DCACHE_CSW, match_opcode, 0},
+  {"dcache.cisw",     0, INSN_CLASS_THEADC_OR_THEADE,   "s",     MATCH_DCACHE_CISW, MASK_DCACHE_CISW, match_opcode, 0},
+  {"dcache.iva",      0, INSN_CLASS_THEADC,   "s",     MATCH_DCACHE_IVA, MASK_DCACHE_IVA, match_opcode, 0},
+  {"dcache.cva",      0, INSN_CLASS_THEADC,   "s",     MATCH_DCACHE_CVA, MASK_DCACHE_CVA, match_opcode, 0},
+  {"dcache.cval1",    0, INSN_CLASS_THEADC,   "s",     MATCH_DCACHE_CVAL1, MASK_DCACHE_CVAL1, match_opcode, 0},
+  {"dcache.civa",     0, INSN_CLASS_THEADC,   "s",     MATCH_DCACHE_CIVA, MASK_DCACHE_CIVA, match_opcode, 0},
+  {"dcache.ipa",      0, INSN_CLASS_THEADC_OR_THEADE,   "s",     MATCH_DCACHE_IPA, MASK_DCACHE_IPA, match_opcode, 0},
+  {"dcache.cpa",      0, INSN_CLASS_THEADC_OR_THEADE,   "s",     MATCH_DCACHE_CPA, MASK_DCACHE_CPA, match_opcode, 0},
+  {"dcache.cpal1",    0, INSN_CLASS_THEADC,   "s",     MATCH_DCACHE_CPAL1, MASK_DCACHE_CPAL1, match_opcode, 0},
+  {"dcache.cipa",     0, INSN_CLASS_THEADC_OR_THEADE,   "s",     MATCH_DCACHE_CIPA, MASK_DCACHE_CIPA, match_opcode, 0},
+  {"icache.iall",     0, INSN_CLASS_THEADC_OR_THEADE_OR_THEADSE,   "",      MATCH_ICACHE_IALL, MASK_ICACHE_IALL, match_opcode, 0},
+  {"icache.iall",     0, INSN_CLASS_THEADSE,   "",      MATCH_ICACHE_IALL, MASK_ICACHE_IALL, match_opcode, INSN_ALIAS},
+  {"icache.ialls",    0, INSN_CLASS_THEADC,   "",      MATCH_ICACHE_IALLS, MASK_ICACHE_IALLS, match_opcode, 0},
+  {"icache.iva",      0, INSN_CLASS_THEADC,   "s",     MATCH_ICACHE_IVA, MASK_ICACHE_IVA, match_opcode, 0},
+  {"icache.ipa",      0, INSN_CLASS_THEADC_OR_THEADE,   "s",     MATCH_ICACHE_IPA, MASK_ICACHE_IPA, match_opcode, 0},
+  {"l2cache.iall",    0, INSN_CLASS_THEADC,   "",      MATCH_L2CACHE_IALL, MASK_L2CACHE_IALL, match_opcode, 0},
+  {"l2cache.call",    0, INSN_CLASS_THEADC,   "",      MATCH_L2CACHE_CALL, MASK_L2CACHE_CALL, match_opcode, 0},
+  {"l2cache.ciall",   0, INSN_CLASS_THEADC_OR_THEADE,   "",      MATCH_L2CACHE_CIALL, MASK_L2CACHE_CIALL, match_opcode, 0},
+  {"sync",            0, INSN_CLASS_THEADC_OR_THEADE,   "",      MATCH_SYNC, MASK_SYNC, match_opcode, 0},
+  {"sync.i",          0, INSN_CLASS_THEADC_OR_THEADE,   "",      MATCH_SYNC_I, MASK_SYNC_I, match_opcode, 0},
+  {"sync.s",          0, INSN_CLASS_THEADC,   "",      MATCH_SYNC_S, MASK_SYNC_S, match_opcode, 0},
+  {"sync.is",         0, INSN_CLASS_THEADC,   "",      MATCH_SYNC_IS, MASK_SYNC_IS, match_opcode, 0},
+  {"tstnbz",          0, INSN_CLASS_THEADC_OR_THEADE,   "d,s",     MATCH_TSTNBZ, MASK_TSTNBZ, match_opcode, 0},
+  {"mula",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MULA, MASK_MULA, match_opcode, 0},
+  {"muls",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MULS, MASK_MULS, match_opcode, 0},
+  {"mulah",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MULAH, MASK_MULAH, match_opcode, 0},
+  {"mulsh",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MULSH, MASK_MULSH, match_opcode, 0},
+  {"sfence.vmas",     0, INSN_CLASS_THEADC,   "s,t",      MATCH_SFENCE_VMAS, MASK_SFENCE_VMAS, match_opcode, 0},
+  {"mveqz",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MVEQZ, MASK_MVEQZ, match_opcode, 0},
+  {"mvnez",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MVNEZ, MASK_MVNEZ, match_opcode, 0},
+  {"mulaw",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MULAW, MASK_MULAW, match_opcode, 0},
+  {"mulsw",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MULSW, MASK_MULSW, match_opcode, 0},
+  {"ext",             64, INSN_CLASS_THEADC,  "d,s,XI6@26,XI6@20",   MATCH_EXT, MASK_EXT, match_opcode, 0 },
+  {"ext",             32, INSN_CLASS_THEADE,  "d,s,XI5@26,XI5@20",   MATCH_EXT, (MASK_EXT | (1U<<25) | (1U<<31)), match_opcode, 0 },
+  {"extu",            64, INSN_CLASS_THEADC,  "d,s,XI6@26,XI6@20",   MATCH_EXTU, MASK_EXTU, match_opcode, 0 },
+  {"extu",            32, INSN_CLASS_THEADE,  "d,s,XI5@26,XI5@20",   MATCH_EXTU, (MASK_EXTU | (1U<<25) | (1U<<31)), match_opcode, 0 },
+  {"ff1",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s",   MATCH_FF1, MASK_FF1, match_opcode, 0},
+  {"ff0",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s",   MATCH_FF0, MASK_FF1, match_opcode, 0},
+  {"rev",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s",   MATCH_REV, MASK_REV, match_opcode, 0},
+  {"lrb",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_LRB, MASK_LRB, match_opcode, 0 },
+  {"lrbu",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_LRBU, MASK_LRBU, match_opcode, 0 },
+  {"lrh",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_LRH, MASK_LRH, match_opcode, 0 },
+  {"lrhu",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_LRHU, MASK_LRHU, match_opcode, 0 },
+  {"lrw",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_LRW, MASK_LRW, match_opcode, 0 },
+  {"lrwu",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_LRWU, MASK_LRWU, match_opcode, 0 },
+  {"srb",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_SRB, MASK_SRB, match_opcode, 0 },
+  {"srh",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_SRH, MASK_SRH, match_opcode, 0 },
+  {"srw",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_SRW, MASK_SRW, match_opcode, 0 },
+  {"lrd",             0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LRD, MASK_LRD, match_opcode, 0 },
+  {"srd",             0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_SRD, MASK_SRD, match_opcode, 0 },
+  {"lurb",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LURB, MASK_LURB, match_opcode, 0 },
+  {"lurbu",           0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LURBU, MASK_LURBU, match_opcode, 0 },
+  {"lurh",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LURH, MASK_LURH, match_opcode, 0 },
+  {"lurhu",           0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LURHU, MASK_LURHU, match_opcode, 0 },
+  {"lurw",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LURW, MASK_LURW, match_opcode, 0 },
+  {"lurwu",           0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LURWU, MASK_LURWU, match_opcode, 0 },
+  {"lurd",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LURD, MASK_LURD, match_opcode, 0 },
+  {"surb",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_SURB, MASK_SURB, match_opcode, 0 },
+  {"surh",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_SURH, MASK_SURH, match_opcode, 0 },
+  {"surw",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_SURW, MASK_SURW, match_opcode, 0 },
+  {"surd",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_SURD, MASK_SURD, match_opcode, 0 },
+  {"tst",             64, INSN_CLASS_THEADC,  "d,s,XI6@20",   MATCH_TST, MASK_TST, match_opcode, 0 },
+  {"tst",             32, INSN_CLASS_THEADE,   "d,s,XI5@20",   MATCH_TST, (MASK_TST | (1U << 25)), match_opcode, INSN_ALIAS},
+  {"srriw",           0, INSN_CLASS_THEADC,   "d,s,XI5@20",   MATCH_SRRIW, MASK_SRRIW, match_opcode, 0 },
+  {"srri",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,XI6@20",   MATCH_SRRI, MASK_SRRI, match_opcode, 0 },
+  {"addsl",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25", MATCH_ADDSL, MASK_ADDSL, match_opcode, 0 },
+  {"lwd",             0, INSN_CLASS_THEADC,   "d,t,(s),XI2@25,XC3", MATCH_LWD, MASK_LWD, match_thead_rd1_rd2_neq_rs1, 0 },
+  {"ldd",             0, INSN_CLASS_THEADC,   "d,t,(s),XI2@25,XC4", MATCH_LDD, MASK_LDD, match_thead_rd1_rd2_neq_rs1, 0 },
+  {"swd",             0, INSN_CLASS_THEADC,   "d,t,(s),XI2@25,XC3", MATCH_SWD, MASK_SWD, match_opcode, 0 },
+  {"sdd",             0, INSN_CLASS_THEADC,   "d,t,(s),XI2@25,XC4", MATCH_SDD, MASK_SDD, match_opcode, 0 },
+  {"sdia",            0, INSN_CLASS_THEADC,   "d,(s),XS5@20,XI2@25", MATCH_SDIA, MASK_SDIA, match_opcode, 0 },
+  {"sdib",            0, INSN_CLASS_THEADC,   "d,(s),XS5@20,XI2@25", MATCH_SDIB, MASK_SDIB, match_opcode, 0 },
+  {"lwud",            0, INSN_CLASS_THEADC,   "d,t,(s),XI2@25,XC3", MATCH_LWUD, MASK_LWUD, match_thead_rd1_rd2_neq_rs1, 0 },
+  {"swia",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_SWIA, MASK_SWIA, match_opcode, 0},
+  {"swib",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_SWIB, MASK_SWIB, match_opcode, 0},
+  {"shia",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_SHIA, MASK_SHIA, match_opcode, 0},
+  {"shib",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_SHIB, MASK_SHIB, match_opcode, 0},
+  {"sbia",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_SBIA, MASK_SBIA, match_opcode, 0},
+  {"sbib",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_SBIB, MASK_SBIB, match_opcode, 0},
+  {"lwuia",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LWUIA, MASK_LWUIA, match_opcode, 0},
+  {"lwuib",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LWUIB, MASK_LWUIB, match_opcode, 0},
+  {"lhuia",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LHUIA, MASK_LHUIA, match_opcode, 0},
+  {"lhuib",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LHUIB, MASK_LHUIB, match_opcode, 0},
+  {"lbuia",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LBUIA, MASK_LBUIA, match_opcode, 0},
+  {"lbuib",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LBUIB, MASK_LBUIB, match_opcode, 0},
+  {"ldia",            0, INSN_CLASS_THEADC,   "d,(s),XS5@20,XI2@25", MATCH_LDIA, MASK_LDIA, match_opcode, 0},
+  {"ldib",            0, INSN_CLASS_THEADC,   "d,(s),XS5@20,XI2@25", MATCH_LDIB, MASK_LDIB, match_opcode, 0},
+  {"lwia",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LWIA, MASK_LWIA, match_opcode, 0},
+  {"lwib",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LWIB, MASK_LWIB, match_opcode, 0},
+  {"lhia",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LHIA, MASK_LHIA, match_opcode, 0},
+  {"lhib",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LHIB, MASK_LHIB, match_opcode, 0},
+  {"lbia",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LBIA, MASK_LBIA, match_opcode, 0},
+  {"lbib",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LBIB, MASK_LBIB, match_opcode, 0},
+  {"fsurd",           0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FSURD, MASK_FSURD, match_opcode, 0},
+  {"revw",            0, INSN_CLASS_THEADC,   "d,s", MATCH_REVW, MASK_REVW, match_opcode, 0},
+  {"fsurw",           0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FSURW, MASK_FSURW, match_opcode, 0},
+  {"flurd",           0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FLURD, MASK_FLURD, match_opcode, 0},
+  {"flurw",           0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FLURW, MASK_FLURW, match_opcode, 0},
+  {"fsrd",            0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FSRD, MASK_FSRD, match_opcode, 0},
+  {"fsrw",            0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FSRW, MASK_FSRW, match_opcode, 0},
+  {"flrd",            0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FLRD, MASK_FLRD, match_opcode, 0},
+  {"flrw",            0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FLRW, MASK_FLRW, match_opcode, 0},
+
+  /* THEADE only.  */
+  {"ipush",           0, INSN_CLASS_THEADE,   "",  MATCH_IPUSH, MASK_IPUSH, match_opcode, 0},
+  {"ipop",            0, INSN_CLASS_THEADE,   "",  MATCH_IPOP, MASK_IPOP, match_opcode, 0},
+  /* Float move.  */
+  {"fmv.x.hw",        32, INSN_CLASS_THEADE,  "d,S",  MATCH_FMV_X_HW, MASK_FMV_X_HW, match_opcode, 0},
+  {"fmv.hw.x",        32, INSN_CLASS_THEADE,  "D,s",  MATCH_FMV_HW_X, MASK_FMV_HW_X, match_opcode, 0},
+
+
   {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}
 
 };
@@ -38,6 +194,8 @@ const struct riscv_vendor_opcode riscv_vendor_list[] =
 {
   /* Vendor T-HEAD.  */
   {"xtheadc", vendor_thead_opcodes},
+  {"xtheade", vendor_thead_opcodes},
+  {"xtheadse", vendor_thead_opcodes},
   {NULL, NULL},
 };
 
-- 
2.17.1


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

* Re: [Integration 1/2] RISC-V: add vendor opcodes
  2021-09-03  3:00 ` [Integration 1/2] RISC-V: add vendor opcodes Lifang Xia
@ 2021-09-03  4:00   ` Nelson Chu
  0 siblings, 0 replies; 10+ messages in thread
From: Nelson Chu @ 2021-09-03  4:00 UTC (permalink / raw)
  To: Lifang Xia; +Cc: Binutils

On Fri, Sep 3, 2021 at 11:00 AM Lifang Xia <lifang_xia@c-sky.com> wrote:
>
> This patch uses the T-HEAD Xuantie processor as an example to solve that
> how to add the vendor's opcode and CSR.
> Without modifying the existing mechanism, create a new
> opcodes/riscv-vendor-opc.c, similar to opcodes/riscv-opc.c, used to
> describe the vendor's opcodes.
> New file, include/opcodes/riscv-vendor-opc.h, used to define the encoding,
> mask and CSR of the opcodes.
>
> The sub-string from -march option is used to pick the suitable list of
> the vendor's opcodes.
>
> bfd/
>         * cpu-riscv.h (enum riscv_spec_class): New
>         ISA_SPEC_CLASS_VENDOR.
> gas/
>         * config/tc-riscv.c (ext_version_table): New "theadc".
>         (riscv_vendor_get_opcodes): New.
>         (riscv_multi_subset_supports): Check xtheadc extensions.
>         (riscv_get_default_ext_version): Skip for vendor.
>         (init_opcode_hash): Add vendor's extensions to the hash.
>         (md_begin): Init opcode hash.
> include/
>         * opcode/riscv-opc.h: Include riscv-vendor-opc.h
>         * opcode/riscv-vendor-opc.h: New.
>         * opcode/riscv.h (enum riscv_extended_insn_class): New class for vendor.
>         (struct riscv_vendor_opcode): New.
>         (riscv_vendor_list): New.
> opcodes/
>         * Makefile.am: Add riscv-vendor-opc.c.
>         * Makefile.in: Likewise.
>         * configure: Likewise
>         * configure.ac: Likewise
>         * riscv-dis.c (arch_string): New.
>         (get_vendor_opcodes): Get the vendor opcodes.
>         (riscv_disassemble_insn): Add vendor's opcode to the hash.
>         (riscv_get_disassembler): Setup arch_string with attr.
>         * riscv-vendor-opc.c: New.
> ---
>  bfd/cpu-riscv.h                   |  1 +
>  gas/config/tc-riscv.c             | 55 +++++++++++++++++++++++++++++--
>  include/opcode/riscv-opc.h        |  1 +
>  include/opcode/riscv-vendor-opc.h | 34 +++++++++++++++++++
>  include/opcode/riscv.h            | 10 ++++++
>  opcodes/Makefile.am               |  1 +
>  opcodes/Makefile.in               |  2 ++
>  opcodes/configure                 |  2 +-
>  opcodes/configure.ac              |  2 +-
>  opcodes/riscv-dis.c               | 23 +++++++++++++
>  opcodes/riscv-vendor-opc.c        | 43 ++++++++++++++++++++++++
>  11 files changed, 170 insertions(+), 4 deletions(-)
>  create mode 100644 include/opcode/riscv-vendor-opc.h
>  create mode 100644 opcodes/riscv-vendor-opc.c
>
> diff --git a/bfd/cpu-riscv.h b/bfd/cpu-riscv.h
> index cafaca23be0..06ede1b2bef 100644
> --- a/bfd/cpu-riscv.h
> +++ b/bfd/cpu-riscv.h
> @@ -26,6 +26,7 @@ enum riscv_spec_class
>    ISA_SPEC_CLASS_20190608,
>    ISA_SPEC_CLASS_20191213,
>    ISA_SPEC_CLASS_DRAFT,
> +  ISA_SPEC_CLASS_VENDOR,

The basic idea of riscv_spec_class is that -  Every spec should have
their own names and versions, so the ISA_SPEC is riscv ISA spec,
PRIV_SPEC is the privileged spec, we also may have DEBUG_SPEC for
debug.  Therefore, each vendor should have it's own <VENDOR_NAME>_SPEC
and versions.  For example, maybe SIFIVE_XXX_SPEC_1p0, ....  The riscv
isa spec doesn't define vendor stuff, so ISA_SPEC_CLASS_VENDOR isn't
suitable for me.

>    /* Privileged spec.  */
>    PRIV_SPEC_CLASS_NONE,
> diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
> index 18992949954..99bc9298b16 100644
> --- a/gas/config/tc-riscv.c
> +++ b/gas/config/tc-riscv.c
> @@ -157,6 +157,9 @@ static const struct riscv_ext_version ext_version_table[] =
>    {"zba",   ISA_SPEC_CLASS_DRAFT, 0, 93},
>    {"zbc",   ISA_SPEC_CLASS_DRAFT, 0, 93},
>
> +  /* T-HEAD extentions for Xuantie C9xx.  */
> +  {"xtheadc",   ISA_SPEC_CLASS_VENDOR, 2, 0},

Likewise.

>    /* Terminate the list.  */
>    {NULL, 0, 0, 0}
>  };
> @@ -238,6 +241,22 @@ riscv_set_default_isa_spec (const char *s)
>    return 1;
>  }
>
> +/* Get the opcodes from vendors.  */
> +static struct riscv_opcode *
> +riscv_vendor_get_opcodes (riscv_subset_list_t *subsets)
> +{
> +  unsigned int i = 0;
> +  struct riscv_subset_t *subset = NULL;
> +
> +  for (i = 0; riscv_vendor_list[i].vendor; i++)
> +    {
> +      if (riscv_lookup_subset (subsets, riscv_vendor_list[i].vendor, &subset))
> +       return riscv_vendor_list[i].opcodes;
> +    }
> +
> +  return NULL;
> +}

Each function should have the corresponding extended function, which
is used to handle draft or vendor stuff.  Could you port your vendor
extensions into these extended functions?  For your
riscv_vendor_get_opcodes, you just need to add your vendor opcodes
into riscv_extended_opcodes, and then update the
riscv_find_extended_opcode_hash.  You don't need to build the whole
vendor structures again, I suppose the extended functions should be
enough to handle most of the vendor extensions, except the vendor
relocations.

>  /* Set the default_priv_spec.  Find the privileged elf attributes when
>     the input string is NULL.  Return 0 if the spec isn't supported.
>     Otherwise, return 1.  */
> @@ -407,6 +426,9 @@ riscv_multi_subset_supports (enum riscv_insn_class insn_class)
>      case INSN_CLASS_ZBC:
>        return riscv_subset_supports ("zbc");
>
> +    case INSN_CLASS_THEADC:
> +      return riscv_subset_supports ("xtheadc");

Likewise, it is better to be added in the riscv_extended_subset_supports.

>      default:
>        return riscv_extended_subset_supports (insn_class);
>      }
> @@ -458,6 +480,7 @@ riscv_search_ext_version_hash (const char *name,
>          && strcmp (ext->name, name) == 0)
>      {
>        if (ext->isa_spec_class == ISA_SPEC_CLASS_DRAFT
> +         || ext->isa_spec_class == ISA_SPEC_CLASS_VENDOR
>           || ext->isa_spec_class == default_isa_spec)
>         {
>           *major_version = ext->major_version;
> @@ -1328,6 +1351,7 @@ struct percent_op_match
>
>  static htab_t
>  init_opcode_hash (const struct riscv_opcode *opcodes,
> +                 const struct riscv_opcode *ext_opcodes,
>                   bool insn_directive_p)
>  {
>    int i = 0;
> @@ -1358,6 +1382,29 @@ init_opcode_hash (const struct riscv_opcode *opcodes,
>        while (opcodes[i].name && !strcmp (opcodes[i].name, name));
>      }
>
> +  i = 0;
> +  while (ext_opcodes && ext_opcodes[i].name)
> +    {
> +      const char *name = ext_opcodes[i].name;
> +      if (str_hash_insert (hash, name, &ext_opcodes[i], 0) != NULL)
> +       as_fatal (_("internal: duplicate %s"), name);
> +
> +      do
> +       {
> +         if (ext_opcodes[i].pinfo != INSN_MACRO)
> +           {
> +             length = 0; /* Let assembler determine the length.  */
> +             if (!validate_riscv_insn (&ext_opcodes[i], length))
> +               as_fatal (_("internal: broken assembler.  "
> +                           "No assembly attempted"));
> +           }
> +         else
> +           gas_assert (!insn_directive_p);
> +         ++i;
> +       }
> +      while (ext_opcodes[i].name && !strcmp (ext_opcodes[i].name, name));
> +    }
> +
>    return hash;
>  }

Please check the md_begin, and see how draft extensions are
initialized.  I think you can create a new vendor opcode hash, and
just call the init_opcode_hash.

> @@ -1372,8 +1419,11 @@ md_begin (void)
>    if (! bfd_set_arch_mach (stdoutput, bfd_arch_riscv, mach))
>      as_warn (_("could not set architecture and machine"));
>
> -  op_hash = init_opcode_hash (riscv_opcodes, false);
> -  insn_type_hash = init_opcode_hash (riscv_insn_types, true);
> +  op_hash = init_opcode_hash (riscv_opcodes,
> +                             riscv_vendor_get_opcodes (&riscv_subsets),
> +                             false);
> +
> +  insn_type_hash = init_opcode_hash (riscv_insn_types, NULL, true);

Likewise, don't need to change this.

>    reg_names_hash = str_htab_create ();
>    hash_reg_names (RCLASS_GPR, riscv_gpr_names_numeric, NGPR);
> @@ -4587,3 +4637,4 @@ riscv_pop_insert (void)
>
>    pop_insert (riscv_pseudo_table);
>  }
> +
> diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
> index 9999da6241a..84fc2ee0e8e 100644
> --- a/include/opcode/riscv-opc.h
> +++ b/include/opcode/riscv-opc.h
> @@ -20,6 +20,7 @@
>
>  #ifndef RISCV_ENCODING_H
>  #define RISCV_ENCODING_H
> +#include "opcode/riscv-vendor-opc.h"
>  /* Instruction opcode macros.  */
>  #define MATCH_SLLI_RV32 0x1013
>  #define MASK_SLLI_RV32  0xfe00707f
> diff --git a/include/opcode/riscv-vendor-opc.h b/include/opcode/riscv-vendor-opc.h

Could these encodings be added in the riscv-opc-extended.h?

> new file mode 100644
> index 00000000000..949047239f8
> --- /dev/null
> +++ b/include/opcode/riscv-vendor-opc.h
> @@ -0,0 +1,34 @@
> +/* riscv-vendor-opc.h.  RISC-V instruction opcode and CSR macros from vendors.
> +   Copyright (C) 2011-2021 Free Software Foundation, Inc.
> +   Contributed by Andrew Waterman
> +
> +   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_VENDOR_OPC_H__
> +#define __RISCV_VENDOR_OPC_H__
> +
> +
> +/* Opcodes for VENDOR 0.  */
> +
> +
> +/* Opcodes for VENDOR 1.  */
> +
> +
> +/* Opcodes for VENDOR 2.  */
> +
> +
> +#endif
> diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
> index 8d5251c50e4..af8df794d1b 100644
> --- a/include/opcode/riscv.h
> +++ b/include/opcode/riscv.h

I think just updating the extended structures and classes should be enough.

> @@ -361,6 +361,12 @@ struct riscv_opcode
>    unsigned long pinfo;
>  };
>
> +struct riscv_vendor_opcode
> +{
> +  const char *vendor;
> +  struct riscv_opcode *opcodes;
> +};
> +
>  /* Instruction is a simple alias (e.g. "mv" for "addi").  */
>  #define        INSN_ALIAS              0x00000001
>
> @@ -434,6 +440,7 @@ extern const char * const riscv_fpr_names_abi[NFPR];
>
>  extern const struct riscv_opcode riscv_opcodes[];
>  extern const struct riscv_opcode riscv_insn_types[];
> +extern const struct riscv_vendor_opcode riscv_vendor_list[];

You don't need to add this, just add your vendor opcodes into
riscv_extended_opcodes in the opcodes/riscv-opc.c.

>  /* Extended extensions.  */
>
> @@ -496,6 +503,9 @@ enum riscv_extended_insn_class
>    INSN_CLASS_D_AND_ZFH,
>    INSN_CLASS_Q_AND_ZFH,
>    INSN_CLASS_SVINVAL,
> +
> +  /* INSN class for THEAD.  */
> +  INSN_CLASS_THEADC,
>  };

Yes, this one is good, added vendor stuff into extended classes is
what I suggest.

>  /* This is a list of macro expanded instructions for extended
> diff --git a/opcodes/Makefile.am b/opcodes/Makefile.am
> index 0e04b4c05c4..4f3ad0e69cd 100644
> --- a/opcodes/Makefile.am
> +++ b/opcodes/Makefile.am
> @@ -229,6 +229,7 @@ TARGET_LIBOPCODES_CFILES = \
>         pru-opc.c \
>         riscv-dis.c \
>         riscv-opc.c \
> +       riscv-vendor-opc.c \
>         rl78-decode.c \
>         rl78-dis.c \
>         rx-decode.c \
> diff --git a/opcodes/Makefile.in b/opcodes/Makefile.in
> index 42c15f00d30..5dcbc204a1e 100644
> --- a/opcodes/Makefile.in
> +++ b/opcodes/Makefile.in
> @@ -620,6 +620,7 @@ TARGET_LIBOPCODES_CFILES = \
>         pru-opc.c \
>         riscv-dis.c \
>         riscv-opc.c \
> +       riscv-vendor-opc.c \
>         rl78-decode.c \
>         rl78-dis.c \
>         rx-decode.c \
> @@ -1036,6 +1037,7 @@ distclean-compile:
>  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pru-opc.Plo@am__quote@
>  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/riscv-dis.Plo@am__quote@
>  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/riscv-opc.Plo@am__quote@
> +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/riscv-vendor-opc.Plo@am__quote@
>  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rl78-decode.Plo@am__quote@
>  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rl78-dis.Plo@am__quote@
>  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rx-decode.Plo@am__quote@
> diff --git a/opcodes/configure b/opcodes/configure
> index 3513e408ce1..ad9ec966411 100755
> --- a/opcodes/configure
> +++ b/opcodes/configure
> @@ -12265,7 +12265,7 @@ if test x${all_targets} = xfalse ; then
>         bfd_pru_arch)           ta="$ta pru-dis.lo pru-opc.lo" ;;
>         bfd_pyramid_arch)       ;;
>         bfd_romp_arch)          ;;
> -       bfd_riscv_arch)         ta="$ta riscv-dis.lo riscv-opc.lo" ;;
> +       bfd_riscv_arch)         ta="$ta riscv-dis.lo riscv-opc.lo riscv-vendor-opc.lo" ;;
>         bfd_rs6000_arch)        ta="$ta ppc-dis.lo ppc-opc.lo" ;;
>         bfd_rl78_arch)          ta="$ta rl78-dis.lo rl78-decode.lo";;
>         bfd_rx_arch)            ta="$ta rx-dis.lo rx-decode.lo";;
> diff --git a/opcodes/configure.ac b/opcodes/configure.ac
> index e564f067334..16024f2f0d5 100644
> --- a/opcodes/configure.ac
> +++ b/opcodes/configure.ac
> @@ -326,7 +326,7 @@ if test x${all_targets} = xfalse ; then
>         bfd_pru_arch)           ta="$ta pru-dis.lo pru-opc.lo" ;;
>         bfd_pyramid_arch)       ;;
>         bfd_romp_arch)          ;;
> -       bfd_riscv_arch)         ta="$ta riscv-dis.lo riscv-opc.lo" ;;
> +       bfd_riscv_arch)         ta="$ta riscv-dis.lo riscv-opc.lo riscv-vendor-opc.lo" ;;
>         bfd_rs6000_arch)        ta="$ta ppc-dis.lo ppc-opc.lo" ;;
>         bfd_rl78_arch)          ta="$ta rl78-dis.lo rl78-decode.lo";;
>         bfd_rx_arch)            ta="$ta rx-dis.lo rx-decode.lo";;

We all have a consensus that no longer need to add new files for draft
and vendor stuff.  I cannot find the first mailing discussions about
my first integration patches, but you can see this one:
https://sourceware.org/pipermail/binutils/2021-March/115990.html.
Anyway, I suppose all you need to do is to port vendor extensions into
the existing extended functions.

> diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
> index dcc5a09213b..8ddc6bec370 100644
> --- a/opcodes/riscv-dis.c
> +++ b/opcodes/riscv-dis.c
> @@ -33,6 +33,7 @@
>  #include <ctype.h>
>
>  static enum riscv_spec_class default_priv_spec = PRIV_SPEC_CLASS_NONE;
> +static const char *arch_string = NULL;
>
>  struct riscv_private_data
>  {
> @@ -140,6 +141,21 @@ parse_riscv_dis_options (const char *opts_in)
>    free (opts);
>  }
>
> +static struct riscv_opcode*
> +get_vendor_opcodes (const char *arch)
> +{
> +  int i = 0;
> +  if (arch == NULL)
> +    return NULL;
> +
> +  for (i = 0; riscv_vendor_list[i].vendor; i++)
> +    {
> +      if (strstr(arch, riscv_vendor_list[i].vendor) != NULL)
> +       return riscv_vendor_list[i].opcodes;
> +    }
> +  return NULL;
> +}
> +
>  /* Print one argument from an array.  */
>
>  static void
> @@ -548,6 +564,11 @@ riscv_disassemble_opcode (insn_t word,
>         if (!riscv_hash[OP_HASH_IDX (op->match)])
>           riscv_hash[OP_HASH_IDX (op->match)] = op;
>
> +      op = get_vendor_opcodes (arch_string);
> +      for (; op && op->name; op++)
> +       if (!riscv_hash[OP_HASH_IDX (op->match)])
> +         riscv_hash[OP_HASH_IDX (op->match)] = op;
> +
>        init = 1;
>      }
>
> @@ -744,6 +765,8 @@ riscv_get_disassembler (bfd *abfd)
>                                                       attr[Tag_b].i,
>                                                       attr[Tag_c].i,
>                                                       &default_priv_spec);
> +             /* Get Vendor opcodes.  */
> +             arch_string = attr[Tag_RISCV_arch].s;
>             }
>          }
>      }

Likewise, if you add your vendor opcode into the
riscv_extended_opcodes, then you don't need to do anything here,
except that you have vendor operands.  Then you will need to update
your vendor operands in print_extended_insn_args, that's all.

> diff --git a/opcodes/riscv-vendor-opc.c b/opcodes/riscv-vendor-opc.c
> new file mode 100644
> index 00000000000..9191b654c14
> --- /dev/null
> +++ b/opcodes/riscv-vendor-opc.c
> @@ -0,0 +1,43 @@
> +/* RISC-V opcode list from vendors.
> +   Copyright (C) 2011-2021 Free Software Foundation, Inc.
> +
> +   Contributed by Andrew Waterman (andrew@sifive.com).
> +   Based on MIPS target.
> +
> +   This file is part of the GNU opcodes library.
> +
> +   This library is free software; you can redistribute it and/or modify
> +   it 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.
> +
> +   It is distributed in the hope that it 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/>.  */
> +
> +
> +#include "sysdep.h"
> +#include "opcode/riscv.h"
> +#include <stdio.h>
> +#include "bfd.h"
> +
> +/* The vendor extension opcodes for T-HEAD.  */
> +struct riscv_opcode vendor_thead_opcodes[] =
> +{
> +  {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}
> +
> +};
> +
> +/* The vendor opcodes list.  */
> +const struct riscv_vendor_opcode riscv_vendor_list[] =
> +{
> +  /* Vendor T-HEAD.  */
> +  {"xtheadc", vendor_thead_opcodes},
> +  {NULL, NULL},
> +};
> +
> --
> 2.17.1
>

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

* Re: [Integration 2/2] RISC-V: Update csr and opcodes for Xuantie CPUs.
  2021-09-03  3:00 ` [Integration 2/2] RISC-V: Update csr and opcodes for Xuantie CPUs Lifang Xia
@ 2021-09-03  4:27   ` Nelson Chu
  0 siblings, 0 replies; 10+ messages in thread
From: Nelson Chu @ 2021-09-03  4:27 UTC (permalink / raw)
  To: Lifang Xia; +Cc: Binutils

On Fri, Sep 3, 2021 at 11:00 AM Lifang Xia <lifang_xia@c-sky.com> wrote:
>
> New ARG format for operands:
> "Xgm@n": encode GPR with m bit at opcode[m+n-1:n].
>    "Xg5@0": encode GPR with 5 bit at opcode[4:0].
>    "Xg5@8": encode GPR with 5 bit at opcode[12:8].
>
> "XCm": constant m, no encode for this.
>    "XC4": constant 4.
>
> "XIm@n": m bits unsigned immediate at opcode[m+n-1:n].
>    "XI5@0": 5 bits unsigned immediate at opcode[4:0].
>    "XI4@8": 4 bits unsigned immediate at opcode[11:8].
>
> "XSm@n": m bits signed immediate at opcode[m+n-1:n].
>    "XS5@0": 5 bits signed immediate at opcode[4:0].
>    "XS4@8": 4 bits signed immediate at opcode[11:8].
>
> "XFm@n": m bits FR at opcode[m+n-1:n].
>    "XF5@0": 5 bits FR at opcode[4:0].
>    "XF5@0": 5 bits FR at opcode[4:0].
>
> gas/
>         * config/tc-riscv.c (riscv_csr_class): New CSR_CLASS_VENDOR.
>         (ext_version_table): New thead extensions.
>         (riscv_multi_subset_supports): New thead extensions.
>         (riscv_csr_address) <case CSR_CLASS_VENDOR>: New.
>         (validate_riscv_insn) <case 'X'>: New operands for vendor.
>         (init_opcode_hash): New ext_opcodes.
>         (riscv_ip) <case 'X'>: New operands for vendor.
>         * testsuite/gas/riscv/thead/*: New testcases for Xuantie.
> include/
>         * opcode/riscv-opc.h: move "riscv-vendor-opc.h" out.
>         * opcode/riscv-vendor-opc.h: New CSR and opcodes for T-HEAD
>         Xuantie CPUS.
>         * opcode/riscv.h (EXTRACT_VENDOR_IMM): New.
>         (EXTRACT_VENDOR_SIGN_IMM): New.
>         (ENCODE_VENDOR_IMM): New.
>         (ENCODE_VENDOR_SIGN_IMM): New.
>         (VALID_VENDOR_IMM): New.
>         (VALID_VENDOR_SIGN_IMM: New.
>         (riscv_insn_class): New T-HEAD insn class.
>         (match_opcode): Define as an global function.
> opcodes/
>         * riscv-dis.c (print_insn_args) <case 'X'>: New operands
>         parsing.
>         * riscv-opc.c (match_opcode): Define as an global function.
>         * riscv-vendor-opc.c (match_thead_rd1_rd2_neq_rs1): New.
>         (vendor_thead_opcodes): Define opcodes for Xuantie CPUs.
>         (riscv_vendor_list): Add xtheade/xtheadse.
> ---
>  gas/config/tc-riscv.c                         | 147 ++++++
>  gas/testsuite/gas/riscv/thead/riscv.exp       |   3 +
>  .../gas/riscv/thead/thead-csr-list.d          | 108 ++++
>  .../gas/riscv/thead/thead-csr-list.s          |  99 ++++
>  gas/testsuite/gas/riscv/thead/theadc-ext.d    | 112 +++++
>  gas/testsuite/gas/riscv/thead/theadc-ext.s    | 116 +++++
>  gas/testsuite/gas/riscv/thead/theade-ext.d    |  62 +++
>  gas/testsuite/gas/riscv/thead/theade-ext.s    |  67 +++
>  include/opcode/riscv-opc.h                    |   3 +-
>  include/opcode/riscv-vendor-opc.h             | 476 +++++++++++++++++-
>  include/opcode/riscv.h                        |  19 +
>  opcodes/riscv-dis.c                           |  50 ++
>  opcodes/riscv-opc.c                           |   2 +-
>  opcodes/riscv-vendor-opc.c                    | 158 ++++++
>  14 files changed, 1415 insertions(+), 7 deletions(-)
>  create mode 100644 gas/testsuite/gas/riscv/thead/riscv.exp
>  create mode 100644 gas/testsuite/gas/riscv/thead/thead-csr-list.d
>  create mode 100644 gas/testsuite/gas/riscv/thead/thead-csr-list.s
>  create mode 100644 gas/testsuite/gas/riscv/thead/theadc-ext.d
>  create mode 100644 gas/testsuite/gas/riscv/thead/theadc-ext.s
>  create mode 100644 gas/testsuite/gas/riscv/thead/theade-ext.d
>  create mode 100644 gas/testsuite/gas/riscv/thead/theade-ext.s
>
> diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
> index 99bc9298b16..d58bfcdcbc3 100644
> --- a/gas/config/tc-riscv.c
> +++ b/gas/config/tc-riscv.c
> @@ -79,6 +79,7 @@ enum riscv_csr_class
>  enum riscv_extended_csr_class
>  {
>    CSR_CLASS_V = CSR_CLASS_EXTENDED, /* RVV CSR */
> +  CSR_CLASS_VENDOR /* vendor CSR */
>  };

Yeah, this is the right place to add.  But I think each vendor may
have their own CSRs, so it would be better to give a name to it.
Maybe CSR_CLASS_XUANTIE? or CSR_CLASS_VENDOR_XUANTIE?

>  /* This structure holds all restricted conditions for a CSR.  */
> @@ -159,6 +160,8 @@ static const struct riscv_ext_version ext_version_table[] =
>
>    /* T-HEAD extentions for Xuantie C9xx.  */
>    {"xtheadc",   ISA_SPEC_CLASS_VENDOR, 2, 0},
> +  {"xtheade",   ISA_SPEC_CLASS_VENDOR, 2, 0},
> +  {"xtheadse",   ISA_SPEC_CLASS_VENDOR, 2, 0},

Added these into extended_ext_version_table is better for me.

>    /* Terminate the list.  */
>    {NULL, 0, 0, 0}
> @@ -428,6 +431,18 @@ riscv_multi_subset_supports (enum riscv_insn_class insn_class)
>
>      case INSN_CLASS_THEADC:
>        return riscv_subset_supports ("xtheadc");
> +    case INSN_CLASS_THEADC_OR_THEADE:
> +      return (riscv_subset_supports ("xtheadc")
> +             || riscv_subset_supports ("xtheade"));
> +    case INSN_CLASS_THEADC_OR_THEADE_OR_THEADSE:
> +      return (riscv_subset_supports ("xtheadc")
> +             || riscv_subset_supports ("xtheade")
> +             || riscv_subset_supports ("xtheadse"));
> +    case INSN_CLASS_THEADE:
> +      return riscv_subset_supports ("xtheade");
> +    case INSN_CLASS_THEADSE:
> +      return riscv_subset_supports ("xtheadse");
> +

Likewise, added these into riscv_extended_subset_supports.

>      default:
>        return riscv_extended_subset_supports (insn_class);
> @@ -1019,6 +1034,7 @@ riscv_csr_address (const char *csr_name,
>        need_check_version = false;
>        break;
>      case CSR_CLASS_DEBUG:
> +    case CSR_CLASS_VENDOR:
>        need_check_version = false;
>        break;
>      default:
> @@ -1315,6 +1331,48 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
>                 goto validate_extended_insn;
>             }
>           break;
> +       case 'X':
> +         switch (*p++)
> +           {
> +           case 'g':
> +             /* Xgm@n.  */
> +           case 'F':
> +             /* XFm@n.  */
> +           case 'I':
> +               {
> +                 /* XIm@n.  */
> +                 int nbit = 0;
> +                 int at = -1;
> +                 int shift = 0;
> +                 nbit = strtol (p, (char **)&p, 10);
> +                 if (*p =='@')
> +                   at = strtol(++p, (char **)&p, 10);
> +
> +                 used_bits |= ENCODE_VENDOR_IMM((-1U>>shift), nbit, at);
> +                 break;
> +               }
> +           case 'S':
> +             /* XSm@n.  */
> +               {
> +                 int nbit = 0;
> +                 int at = -1;
> +                 int shift = 0;
> +                 nbit = strtol (p, (char **)&p, 10);
> +                 if ((*p) =='>' && (*(p+1)) == '>')
> +                   shift = strtol (p, (char **)&p, 10);
> +                 if (*p =='@')
> +                   at = strtol(++p, (char **)&p, 10);
> +
> +                 used_bits |= ENCODE_VENDOR_IMM((-1>>shift), nbit, at);
> +                 break;
> +               }
> +           case 'C':
> +             /* XCm.  */
> +             strtol (p, (char **)&p, 10);
> +             break;
> +           }
> +         break;
> +
>         default:
>         validate_extended_insn:
>           oparg = opargStart;
> @@ -1327,6 +1385,7 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
>             }
>         }
>      }
> +
>    if (used_bits != required_bits)
>      {
>        as_bad (_("internal: bad RISC-V opcode "
> @@ -3429,6 +3488,94 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
>               asarg = expr_end;
>               imm_expr->X_op = O_absent;
>               continue;
> +           case 'X':
> +               {
> +                 int nbit = 0;
> +                 int at = -1;
> +                 int shift = 0;
> +                 int constant;
> +                 args++;
> +                 c = *args++;
> +                 switch (c)
> +                   {
> +                   case 'I':
> +                     /* XIm@n.  */
> +                     nbit = strtol (args, (char **)&args, 10);
> +                     if ((*args) =='@')
> +                       at = strtol(++args, (char **)&args, 10);
> +
> +                     args--;
> +
> +                     if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
> +                         || imm_expr->X_op != O_constant
> +                         || !VALID_VENDOR_IMM(imm_expr->X_add_number, nbit, at))
> +                       break;
> +                     ip->insn_opcode |=
> +                       ENCODE_VENDOR_IMM ((imm_expr->X_add_number >> shift), nbit, at);
> +                     s = expr_end;
> +                     imm_expr->X_op = O_absent;
> +                     continue;
> +                   case 'S':
> +                     /* XSm@n.  */
> +                     nbit = strtol (args, (char **)&args, 10);
> +                     if ((*args) =='<' && (*(args+1)) == '<')
> +                       {
> +                         args += 2;
> +                         shift = strtol(++args, (char **)&args, 10);
> +                       }
> +
> +                     if ((*args) =='@')
> +                       at = strtol(++args, (char **)&args, 10);
> +
> +                     args--;
> +
> +
> +                     if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
> +                         || imm_expr->X_op != O_constant
> +                         || !VALID_VENDOR_SIGN_IMM((imm_expr->X_add_number >> shift), nbit, at))
> +                       break;
> +                     ip->insn_opcode |=
> +                       ENCODE_VENDOR_SIGN_IMM (imm_expr->X_add_number, nbit, at);
> +                     s = expr_end;
> +                     imm_expr->X_op = O_absent;
> +                     continue;
> +                   case 'g':
> +                     /* Xgm@n.  */
> +                     nbit = strtol (args, (char **)&args, 10);
> +                     if ((*args) =='<' && (*(args+1)) == '<')
> +                       {
> +                         args += 2;
> +                         shift = strtol(++args, (char **)&args, 10);
> +                       }
> +
> +                     if ((*args) =='@')
> +                       at = strtol(++args, (char **)&args, 10);
> +
> +                     args--;
> +
> +
> +                     if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
> +                         || imm_expr->X_op != O_register
> +                         || !VALID_VENDOR_IMM(imm_expr->X_add_number, nbit, at))
> +                       break;
> +                     ip->insn_opcode |=
> +                       ENCODE_VENDOR_IMM (imm_expr->X_add_number, nbit, at);
> +                     s = expr_end;
> +                     continue;
> +                   case 'C':
> +                     /* XCm, constant with no encode.  */
> +                     constant = strtol (args, (char **)&args, 10);
> +                     args--;
> +
> +                     if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
> +                         || imm_expr->X_op != O_constant
> +                         || (imm_expr->X_add_number != constant))
> +                       break;
> +                     s = expr_end;
> +                     continue;
> +                   }
> +               }
> +             break;;

OK I see you have vendor operands, so you can add these codes into
validate_riscv_extended_insn and riscv_parse_extended_operands, and
also remember to update the print_extended_insn_args for
dis-assembler.

>             default:
>               parse_extended_operand:
> diff --git a/gas/testsuite/gas/riscv/thead/riscv.exp b/gas/testsuite/gas/riscv/thead/riscv.exp
> new file mode 100644
> index 00000000000..11602fb3fcc
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/thead/riscv.exp
> @@ -0,0 +1,3 @@
> +if {[istarget riscv*-*-*]} {
> + run_dump_tests [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
> +}

We already have gas/testsuite/gas/riscv/extended/ folder for draft and
vendor extensions.  It would be good if you can your test cases there.

> diff --git a/gas/testsuite/gas/riscv/thead/thead-csr-list.d b/gas/testsuite/gas/riscv/thead/thead-csr-list.d
> new file mode 100644
> index 00000000000..efe7859decd
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/thead/thead-csr-list.d
> @@ -0,0 +1,108 @@
> +#as: -march=rv64gcxtheadc
> +#objdump: -dr
> +
> +.*:[   ]+file format .*
> +
> +
> +Disassembly of section .text:
> +
> +0000000000000000 <.text>:
> +   0:  7c002573                csrr    a0,mxstatus
> +   4:  7c102573                csrr    a0,mhcr
> +   8:  7c202573                csrr    a0,mcor
> +   c:  7c302573                csrr    a0,mccr2
> +  10:  7c402573                csrr    a0,mcer2
> +  14:  7c502573                csrr    a0,mhint
> +  18:  7c602573                csrr    a0,mrmr
> +  1c:  7c702573                csrr    a0,mrvbr
> +  20:  7c802573                csrr    a0,mcer
> +  24:  7c902573                csrr    a0,mcounterwen
> +  28:  7ca02573                csrr    a0,mcounterinten
> +  2c:  7cb02573                csrr    a0,mcounterof
> +  30:  7cc02573                csrr    a0,mhint2
> +  34:  7cd02573                csrr    a0,mhint3
> +  38:  7e002573                csrr    a0,mraddr
> +  3c:  7e102573                csrr    a0,mexstatus
> +  40:  7e202573                csrr    a0,mnmicause
> +  44:  7e302573                csrr    a0,mnmipc
> +  48:  7f002573                csrr    a0,mhpmcr
> +  4c:  7f102573                csrr    a0,mhpmsr
> +  50:  7f202573                csrr    a0,mhpmer
> +  54:  7f302573                csrr    a0,msmpr
> +  58:  7f402573                csrr    a0,mteecfg
> +  5c:  7d102573                csrr    a0,usp
> +  60:  7d202573                csrr    a0,mcins
> +  64:  7d302573                csrr    a0,mcindex
> +  68:  7d402573                csrr    a0,mcdata0
> +  6c:  7d502573                csrr    a0,mcdata1
> +  70:  7d602573                csrr    a0,meicr
> +  74:  7d702573                csrr    a0,meicr2
> +  78:  be002573                csrr    a0,mebr
> +  7c:  be102573                csrr    a0,nt_mstatus
> +  80:  be302573                csrr    a0,nt_mtvec
> +  84:  be202573                csrr    a0,nt_mie
> +  88:  be402573                csrr    a0,nt_mtvt
> +  8c:  be502573                csrr    a0,nt_mepc
> +  90:  be602573                csrr    a0,nt_mcause
> +  94:  be702573                csrr    a0,nt_mip
> +  98:  be802573                csrr    a0,nt_mintstate
> +  9c:  be902573                csrr    a0,nt_mxstatus
> +  a0:  bea02573                csrr    a0,nt_mebr
> +  a4:  beb02573                csrr    a0,nt_msp
> +  a8:  bec02573                csrr    a0,t_usp
> +  ac:  bed02573                csrr    a0,t_mdcr
> +  b0:  bee02573                csrr    a0,t_mpcr
> +  b4:  bef02573                csrr    a0,pmpteecfg
> +  b8:  fc002573                csrr    a0,mcpuid
> +  bc:  fc102573                csrr    a0,mapbaddr
> +  c0:  fc202573                csrr    a0,mwmsr
> +  c4:  80002573                csrr    a0,fxcr
> +  c8:  9c002573                csrr    a0,smir
> +  cc:  9c102573                csrr    a0,smel
> +  d0:  9c202573                csrr    a0,smeh
> +  d4:  9c302573                csrr    a0,smcir
> +  d8:  5c002573                csrr    a0,sxstatus
> +  dc:  5c102573                csrr    a0,shcr
> +  e0:  5c202573                csrr    a0,scer2
> +  e4:  5c302573                csrr    a0,scer
> +  e8:  5c402573                csrr    a0,scounterinten
> +  ec:  5c502573                csrr    a0,scounterof
> +  f0:  5c602573                csrr    a0,shint
> +  f4:  5c702573                csrr    a0,shint2
> +  f8:  5c802573                csrr    a0,shpminhibit
> +  fc:  5c902573                csrr    a0,shpmcr
> + 100:  5ca02573                csrr    a0,shpmsr
> + 104:  5cb02573                csrr    a0,shpmer
> + 108:  5e002573                csrr    a0,scycle
> + 10c:  5e102573                csrr    a0,shpmcounter1
> + 110:  5e202573                csrr    a0,shpmcounter2
> + 114:  5e302573                csrr    a0,shpmcounter3
> + 118:  5e402573                csrr    a0,shpmcounter4
> + 11c:  5e502573                csrr    a0,shpmcounter5
> + 120:  5e602573                csrr    a0,shpmcounter6
> + 124:  5e702573                csrr    a0,shpmcounter7
> + 128:  5e802573                csrr    a0,shpmcounter8
> + 12c:  5e902573                csrr    a0,shpmcounter9
> + 130:  5ea02573                csrr    a0,shpmcounter10
> + 134:  5eb02573                csrr    a0,shpmcounter11
> + 138:  5ec02573                csrr    a0,shpmcounter12
> + 13c:  5ed02573                csrr    a0,shpmcounter13
> + 140:  5ee02573                csrr    a0,shpmcounter14
> + 144:  5ef02573                csrr    a0,shpmcounter15
> + 148:  5f002573                csrr    a0,shpmcounter16
> + 14c:  5f102573                csrr    a0,shpmcounter17
> + 150:  5f202573                csrr    a0,shpmcounter18
> + 154:  5f302573                csrr    a0,shpmcounter19
> + 158:  5f402573                csrr    a0,shpmcounter20
> + 15c:  5f502573                csrr    a0,shpmcounter21
> + 160:  5f602573                csrr    a0,shpmcounter22
> + 164:  5f702573                csrr    a0,shpmcounter23
> + 168:  5f802573                csrr    a0,shpmcounter24
> + 16c:  5f902573                csrr    a0,shpmcounter25
> + 170:  5fa02573                csrr    a0,shpmcounter26
> + 174:  5fb02573                csrr    a0,shpmcounter27
> + 178:  5fc02573                csrr    a0,shpmcounter28
> + 17c:  5fd02573                csrr    a0,shpmcounter29
> + 180:  5fe02573                csrr    a0,shpmcounter30
> + 184:  5ff02573                csrr    a0,shpmcounter31
> +
> diff --git a/gas/testsuite/gas/riscv/thead/thead-csr-list.s b/gas/testsuite/gas/riscv/thead/thead-csr-list.s
> new file mode 100644
> index 00000000000..d6de0274dc5
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/thead/thead-csr-list.s
> @@ -0,0 +1,99 @@
> +csrr a0, mxstatus
> +csrr a0, mhcr
> +csrr a0, mcor
> +csrr a0, mccr2
> +csrr a0, mcer2
> +csrr a0, mhint
> +csrr a0, mrmr
> +csrr a0, mrvbr
> +csrr a0, mcer
> +csrr a0, mcounterwen
> +csrr a0, mcounterinten
> +csrr a0, mcounterof
> +csrr a0, mhint2
> +csrr a0, mhint3
> +csrr a0, mraddr
> +csrr a0, mexstatus
> +csrr a0, mnmicause
> +csrr a0, mnmipc
> +csrr a0, mhpmcr
> +csrr a0, mhpmsr
> +csrr a0, mhpmer
> +csrr a0, msmpr
> +csrr a0, mteecfg
> +csrr a0, usp
> +csrr a0, mcins
> +csrr a0, mcindex
> +csrr a0, mcdata0
> +csrr a0, mcdata1
> +csrr a0, meicr
> +csrr a0, meicr2
> +csrr a0, mebr
> +csrr a0, nt_mstatus
> +csrr a0, nt_mtvec
> +csrr a0, nt_mie
> +csrr a0, nt_mtvt
> +csrr a0, nt_mepc
> +csrr a0, nt_mcause
> +csrr a0, nt_mip
> +csrr a0, nt_mintstate
> +csrr a0, nt_mxstatus
> +csrr a0, nt_mebr
> +csrr a0, nt_msp
> +csrr a0, t_usp
> +csrr a0, t_mdcr
> +csrr a0, t_mpcr
> +csrr a0, pmpteecfg
> +csrr a0, mcpuid
> +csrr a0, mapbaddr
> +csrr a0, mwmsr
> +csrr a0, fxcr
> +csrr a0, smir
> +csrr a0, smel
> +csrr a0, smeh
> +csrr a0, smcir
> +csrr a0, sxstatus
> +csrr a0, shcr
> +csrr a0, scer2
> +csrr a0, scer
> +csrr a0, scounterinten
> +csrr a0, scounterof
> +csrr a0, shint
> +csrr a0, shint2
> +csrr a0, shpminhibit
> +csrr a0, shpmcr
> +csrr a0, shpmsr
> +csrr a0, shpmer
> +csrr a0, scycle
> +csrr a0, shpmcounter1
> +csrr a0, shpmcounter2
> +csrr a0, shpmcounter3
> +csrr a0, shpmcounter4
> +csrr a0, shpmcounter5
> +csrr a0, shpmcounter6
> +csrr a0, shpmcounter7
> +csrr a0, shpmcounter8
> +csrr a0, shpmcounter9
> +csrr a0, shpmcounter10
> +csrr a0, shpmcounter11
> +csrr a0, shpmcounter12
> +csrr a0, shpmcounter13
> +csrr a0, shpmcounter14
> +csrr a0, shpmcounter15
> +csrr a0, shpmcounter16
> +csrr a0, shpmcounter17
> +csrr a0, shpmcounter18
> +csrr a0, shpmcounter19
> +csrr a0, shpmcounter20
> +csrr a0, shpmcounter21
> +csrr a0, shpmcounter22
> +csrr a0, shpmcounter23
> +csrr a0, shpmcounter24
> +csrr a0, shpmcounter25
> +csrr a0, shpmcounter26
> +csrr a0, shpmcounter27
> +csrr a0, shpmcounter28
> +csrr a0, shpmcounter29
> +csrr a0, shpmcounter30
> +csrr a0, shpmcounter31

You probably can add these into gas/testsuite/gas/riscv/extended/extended-csr.s.

> diff --git a/gas/testsuite/gas/riscv/thead/theadc-ext.d b/gas/testsuite/gas/riscv/thead/theadc-ext.d
> new file mode 100644
> index 00000000000..d9dfd0682c7
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/thead/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                dcache.call
> +   8:  0030000b                dcache.ciall
> +   c:  02b5000b                dcache.cipa     a0
> +  10:  0235000b                dcache.cisw     a0
> +  14:  0275000b                dcache.civa     a0
> +  18:  0295000b                dcache.cpa      a0
> +  1c:  0285000b                dcache.cpal1    a0
> +  20:  0255000b                dcache.cva      a0
> +  24:  0245000b                dcache.cval1    a0
> +  28:  02a5000b                dcache.ipa      a0
> +  2c:  0225000b                dcache.isw      a0
> +  30:  0265000b                dcache.iva      a0
> +  34:  0020000b                dcache.iall
> +  38:  0215000b                dcache.csw      a0
> +  3c:  0100000b                icache.iall
> +  40:  0110000b                icache.ialls
> +  44:  0305000b                icache.iva      a0
> +  48:  0385000b                icache.ipa      a0
> +  4c:  0160000b                l2cache.iall
> +  50:  0150000b                l2cache.call
> +  54:  0170000b                l2cache.ciall
> +  58:  04b5000b                sfence.vmas     a0,a1
> +  5c:  0180000b                sync
> +  60:  01a0000b                sync.i
> +  64:  0190000b                sync.s
> +  68:  01b0000b                sync.is
> +  6c:  02c5950b                addsl   a0,a1,a2,1
> +  70:  20c5950b                mula    a0,a1,a2
> +  74:  22c5950b                muls    a0,a1,a2
> +  78:  24c5950b                mulaw   a0,a1,a2
> +  7c:  26c5950b                mulsw   a0,a1,a2
> +  80:  28c5950b                mulah   a0,a1,a2
> +  84:  2ac5950b                mulsh   a0,a1,a2
> +  88:  1105950b                srri    a0,a1,16
> +  8c:  1505950b                srriw   a0,a1,16
> +  90:  40c5950b                mveqz   a0,a1,a2
> +  94:  42c5950b                mvnez   a0,a1,a2
> +  98:  8905950b                tst     a0,a1,16
> +  9c:  8005950b                tstnbz  a0,a1
> +  a0:  4105a50b                ext     a0,a1,16,16
> +  a4:  4105b50b                extu    a0,a1,16,16
> +  a8:  8605950b                ff1     a0,a1
> +  ac:  8405950b                ff0     a0,a1
> +  b0:  8205950b                rev     a0,a1
> +  b4:  9005950b                revw    a0,a1
> +  b8:  62b5600b                flrd    ft0,a0,a1,1
> +  bc:  42b5600b                flrw    ft0,a0,a1,1
> +  c0:  72b5600b                flurd   ft0,a0,a1,1
> +  c4:  52b5600b                flurw   ft0,a0,a1,1
> +  c8:  02c5c50b                lrb     a0,a1,a2,1
> +  cc:  22c5c50b                lrh     a0,a1,a2,1
> +  d0:  42c5c50b                lrw     a0,a1,a2,1
> +  d4:  62c5c50b                lrd     a0,a1,a2,1
> +  d8:  82c5c50b                lrbu    a0,a1,a2,1
> +  dc:  a2c5c50b                lrhu    a0,a1,a2,1
> +  e0:  c2c5c50b                lrwu    a0,a1,a2,1
> +  e4:  12c5c50b                lurb    a0,a1,a2,1
> +  e8:  32c5c50b                lurh    a0,a1,a2,1
> +  ec:  52c5c50b                lurw    a0,a1,a2,1
> +  f0:  72c5c50b                lurd    a0,a1,a2,1
> +  f4:  92c5c50b                lurbu   a0,a1,a2,1
> +  f8:  b2c5c50b                lurhu   a0,a1,a2,1
> +  fc:  d2c5c50b                lurwu   a0,a1,a2,1
> + 100:  1af5c50b                lbia    a0,\(a1\),15,1
> + 104:  0af5c50b                lbib    a0,\(a1\),15,1
> + 108:  3af5c50b                lhia    a0,\(a1\),15,1
> + 10c:  2af5c50b                lhib    a0,\(a1\),15,1
> + 110:  5af5c50b                lwia    a0,\(a1\),15,1
> + 114:  4af5c50b                lwib    a0,\(a1\),15,1
> + 118:  7af5c50b                ldia    a0,\(a1\),15,1
> + 11c:  6af5c50b                ldib    a0,\(a1\),15,1
> + 120:  9af5c50b                lbuia   a0,\(a1\),15,1
> + 124:  8af5c50b                lbuib   a0,\(a1\),15,1
> + 128:  baf5c50b                lhuia   a0,\(a1\),15,1
> + 12c:  aaf5c50b                lhuib   a0,\(a1\),15,1
> + 130:  daf5c50b                lwuia   a0,\(a1\),15,1
> + 134:  caf5c50b                lwuib   a0,\(a1\),15,1
> + 138:  fab6450b                ldd     a0,a1,\(a2\),1,4
> + 13c:  e2b6450b                lwd     a0,a1,\(a2\),1,3
> + 140:  f2b6450b                lwud    a0,a1,\(a2\),1,3
> + 144:  62b5700b                fsrd    ft0,a0,a1,1
> + 148:  42b5700b                fsrw    ft0,a0,a1,1
> + 14c:  72b5700b                fsurd   ft0,a0,a1,1
> + 150:  52b5700b                fsurw   ft0,a0,a1,1
> + 154:  02c5d50b                srb     a0,a1,a2,1
> + 158:  22c5d50b                srh     a0,a1,a2,1
> + 15c:  42c5d50b                srw     a0,a1,a2,1
> + 160:  62c5d50b                srd     a0,a1,a2,1
> + 164:  12c5d50b                surb    a0,a1,a2,1
> + 168:  32c5d50b                surh    a0,a1,a2,1
> + 16c:  52c5d50b                surw    a0,a1,a2,1
> + 170:  72c5d50b                surd    a0,a1,a2,1
> + 174:  1af5d50b                sbia    a0,\(a1\),15,1
> + 178:  0af5d50b                sbib    a0,\(a1\),15,1
> + 17c:  3af5d50b                shia    a0,\(a1\),15,1
> + 180:  2af5d50b                shib    a0,\(a1\),15,1
> + 184:  5ac5d50b                swia    a0,\(a1\),12,1
> + 188:  4af5d50b                swib    a0,\(a1\),15,1
> + 18c:  7af5d50b                sdia    a0,\(a1\),15,1
> + 190:  6af5d50b                sdib    a0,\(a1\),15,1
> + 194:  fab6550b                sdd     a0,a1,\(a2\),1,4
> + 198:  e2b6550b                swd     a0,a1,\(a2\),1,3
> diff --git a/gas/testsuite/gas/riscv/thead/theadc-ext.s b/gas/testsuite/gas/riscv/thead/theadc-ext.s
> new file mode 100644
> index 00000000000..1bc43310fc1
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/thead/theadc-ext.s
> @@ -0,0 +1,116 @@
> +.text
> +
> +wsc
> +
> +# cache ext
> +dcache.call
> +dcache.ciall
> +dcache.cipa a0
> +dcache.cisw a0
> +dcache.civa a0
> +dcache.cpa a0
> +dcache.cpal1 a0
> +dcache.cva a0
> +dcache.cval1 a0
> +dcache.ipa a0
> +dcache.isw a0
> +dcache.iva a0
> +dcache.iall
> +dcache.csw a0
> +icache.iall
> +icache.ialls
> +icache.iva a0
> +icache.ipa a0
> +l2cache.iall
> +l2cache.call
> +l2cache.ciall
> +
> +# sync ext
> +sfence.vmas       a0, a1
> +sync
> +sync.i
> +sync.s
> +sync.is
> +
> +# calc ext
> +addsl             a0, a1, a2, 1
> +mula              a0, a1, a2
> +muls              a0, a1, a2
> +mulaw             a0, a1, a2
> +mulsw             a0, a1, a2
> +mulah             a0, a1, a2
> +mulsh             a0, a1, a2
> +srri              a0, a1, 16
> +srriw             a0, a1, 16
> +mveqz             a0, a1, a2
> +mvnez             a0, a1, a2
> +
> +# bit ext
> +tst               a0, a1, 16
> +tstnbz            a0, a1
> +ext               a0, a1, 16, 16
> +extu              a0, a1, 16, 16
> +ff1               a0, a1
> +ff0               a0, a1
> +rev               a0, a1
> +revw       a0, a1
> +
> +# load/store ext
> +flrd       f0, a0, a1, 1
> +flrw       f0, a0, a1, 1
> +flurd      f0, a0, a1, 1
> +flurw      f0, a0, a1, 1
> +lrb               a0, a1, a2, 1
> +lrh               a0, a1, a2, 1
> +lrw               a0, a1, a2, 1
> +lrd               a0, a1, a2, 1
> +lrbu              a0, a1, a2, 1
> +lrhu              a0, a1, a2, 1
> +lrwu              a0, a1, a2, 1
> +lurb              a0, a1, a2, 1
> +lurh              a0, a1, a2, 1
> +lurw              a0, a1, a2, 1
> +lurd              a0, a1, a2, 1
> +lurbu             a0, a1, a2, 1
> +lurhu             a0, a1, a2, 1
> +lurwu             a0, a1, a2, 1
> +lbia       a0, (a1), 15, 1
> +lbib       a0, (a1), 15, 1
> +lhia       a0, (a1), 15, 1
> +lhib       a0, (a1), 15, 1
> +lwia       a0, (a1), 15, 1
> +lwib       a0, (a1), 15, 1
> +ldia       a0, (a1), 15, 1
> +ldib       a0, (a1), 15, 1
> +lbuia      a0, (a1), 15, 1
> +lbuib      a0, (a1), 15, 1
> +lhuia      a0, (a1), 15, 1
> +lhuib      a0, (a1), 15, 1
> +lwuia      a0, (a1), 15, 1
> +lwuib      a0, (a1), 15, 1
> +ldd               a0, a1, (a2), 1, 4
> +lwd               a0, a1, (a2), 1, 3
> +lwud              a0, a1, (a2), 1, 3
> +fsrd       f0, a0, a1, 1
> +fsrw       f0, a0, a1, 1
> +fsurd      f0, a0, a1, 1
> +fsurw      f0, a0, a1, 1
> +srb               a0, a1, a2, 1
> +srh               a0, a1, a2, 1
> +srw               a0, a1, a2, 1
> +srd               a0, a1, a2, 1
> +surb              a0, a1, a2, 1
> +surh              a0, a1, a2, 1
> +surw              a0, a1, a2, 1
> +surd              a0, a1, a2, 1
> +sbia              a0, (a1), 15, 1
> +sbib              a0, (a1), 15, 1
> +shia              a0, (a1), 15, 1
> +shib              a0, (a1), 15, 1
> +swia              a0, (a1), 12, 1
> +swib              a0, (a1), 15, 1
> +sdia              a0, (a1), 15, 1
> +sdib              a0, (a1), 15, 1
> +sdd               a0, a1, (a2), 1, 4
> +swd               a0, a1, (a2), 1, 3
> +
> diff --git a/gas/testsuite/gas/riscv/thead/theade-ext.d b/gas/testsuite/gas/riscv/thead/theade-ext.d
> new file mode 100644
> index 00000000000..6f9cb5251c7
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/thead/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                dcache.ipa      a0
> +[       ]+[0-9a-f]+:\s+0295000b                dcache.cpa      a0
> +[       ]+[0-9a-f]+:\s+02b5000b                dcache.cipa     a0
> +[       ]+[0-9a-f]+:\s+0225000b                dcache.isw      a0
> +[       ]+[0-9a-f]+:\s+0215000b                dcache.csw      a0
> +[       ]+[0-9a-f]+:\s+0235000b                dcache.cisw     a0
> +[       ]+[0-9a-f]+:\s+0020000b                dcache.iall
> +[       ]+[0-9a-f]+:\s+0010000b                dcache.call
> +[       ]+[0-9a-f]+:\s+0030000b                dcache.ciall
> +[       ]+[0-9a-f]+:\s+0100000b                icache.iall
> +[       ]+[0-9a-f]+:\s+0385000b                icache.ipa      a0
> +[       ]+[0-9a-f]+:\s+0180000b                sync
> +[       ]+[0-9a-f]+:\s+01a0000b                sync.i
> +[       ]+[0-9a-f]+:\s+02c5950b                addsl   a0,a1,a2,1
> +[       ]+[0-9a-f]+:\s+1105950b                srri    a0,a1,16
> +[       ]+[0-9a-f]+:\s+20c5950b                mula    a0,a1,a2
> +[       ]+[0-9a-f]+:\s+28c5950b                mulah   a0,a1,a2
> +[       ]+[0-9a-f]+:\s+22c5950b                muls    a0,a1,a2
> +[       ]+[0-9a-f]+:\s+2ac5950b                mulsh   a0,a1,a2
> +[       ]+[0-9a-f]+:\s+40c5950b                mveqz   a0,a1,a2
> +[       ]+[0-9a-f]+:\s+42c5950b                mvnez   a0,a1,a2
> +[       ]+[0-9a-f]+:\s+4105a50b                ext     a0,a1,16,16
> +[       ]+[0-9a-f]+:\s+4105b50b                extu    a0,a1,16,16
> +[       ]+[0-9a-f]+:\s+8605950b                ff1     a0,a1
> +[       ]+[0-9a-f]+:\s+8405950b                ff0     a0,a1
> +[       ]+[0-9a-f]+:\s+8205950b                rev     a0,a1
> +[       ]+[0-9a-f]+:\s+8905950b                tst     a0,a1,16
> +[       ]+[0-9a-f]+:\s+8005950b                tstnbz  a0,a1
> +[       ]+[0-9a-f]+:\s+02c5c50b                lrb     a0,a1,a2,1
> +[       ]+[0-9a-f]+:\s+22c5c50b                lrh     a0,a1,a2,1
> +[       ]+[0-9a-f]+:\s+42c5c50b                lrw     a0,a1,a2,1
> +[       ]+[0-9a-f]+:\s+82c5c50b                lrbu    a0,a1,a2,1
> +[       ]+[0-9a-f]+:\s+a2c5c50b                lrhu    a0,a1,a2,1
> +[       ]+[0-9a-f]+:\s+1af5c50b                lbia    a0,\(a1\),15,1
> +[       ]+[0-9a-f]+:\s+0af5c50b                lbib    a0,\(a1\),15,1
> +[       ]+[0-9a-f]+:\s+3af5c50b                lhia    a0,\(a1\),15,1
> +[       ]+[0-9a-f]+:\s+2af5c50b                lhib    a0,\(a1\),15,1
> +[       ]+[0-9a-f]+:\s+5af5c50b                lwia    a0,\(a1\),15,1
> +[       ]+[0-9a-f]+:\s+4af5c50b                lwib    a0,\(a1\),15,1
> +[       ]+[0-9a-f]+:\s+02c5d50b                srb     a0,a1,a2,1
> +[       ]+[0-9a-f]+:\s+22c5d50b                srh     a0,a1,a2,1
> +[       ]+[0-9a-f]+:\s+42c5d50b                srw     a0,a1,a2,1
> +[       ]+[0-9a-f]+:\s+1af5d50b                sbia    a0,\(a1\),15,1
> +[       ]+[0-9a-f]+:\s+0af5d50b                sbib    a0,\(a1\),15,1
> +[       ]+[0-9a-f]+:\s+3af5d50b                shia    a0,\(a1\),15,1
> +[       ]+[0-9a-f]+:\s+2af5d50b                shib    a0,\(a1\),15,1
> +[       ]+[0-9a-f]+:\s+5ac5d50b                swia    a0,\(a1\),12,1
> +[       ]+[0-9a-f]+:\s+4af5d50b                swib    a0,\(a1\),15,1
> +[       ]+[0-9a-f]+:\s+c000150b                fmv.x.hw        a0,ft0
> +[       ]+[0-9a-f]+:\s+a005100b                fmv.hw.x        ft0,a0
> +[       ]+[0-9a-f]+:\s+0040000b                ipush
> +[       ]+[0-9a-f]+:\s+0050000b                ipop
> diff --git a/gas/testsuite/gas/riscv/thead/theade-ext.s b/gas/testsuite/gas/riscv/thead/theade-ext.s
> new file mode 100644
> index 00000000000..5c93e04ef9f
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/thead/theade-ext.s
> @@ -0,0 +1,67 @@
> +.text
> +
> +wsc
> +
> +# cache ext
> +dcache.ipa a0
> +dcache.cpa a0
> +dcache.cipa a0
> +dcache.isw a0
> +dcache.csw a0
> +dcache.cisw a0
> +dcache.iall
> +dcache.call
> +dcache.ciall
> +icache.iall
> +icache.ipa a0
> +
> +# sync ext
> +sync
> +sync.i
> +
> +# calc ext
> +addsl             a0, a1, a2, 1
> +srri              a0, a1, 16
> +mula              a0, a1, a2
> +mulah             a0, a1, a2
> +muls              a0, a1, a2
> +mulsh             a0, a1, a2
> +mveqz             a0, a1, a2
> +mvnez             a0, a1, a2
> +
> +# bit ext
> +ext               a0, a1, 16, 16
> +extu              a0, a1, 16, 16
> +ff1               a0, a1
> +ff0               a0, a1
> +rev               a0, a1
> +tst               a0, a1, 16
> +tstnbz            a0, a1
> +
> +# load/store ext
> +lrb               a0, a1, a2, 1
> +lrh               a0, a1, a2, 1
> +lrw               a0, a1, a2, 1
> +lrbu              a0, a1, a2, 1
> +lrhu              a0, a1, a2, 1
> +lbia       a0, (a1), 15, 1
> +lbib       a0, (a1), 15, 1
> +lhia       a0, (a1), 15, 1
> +lhib       a0, (a1), 15, 1
> +lwia       a0, (a1), 15, 1
> +lwib       a0, (a1), 15, 1
> +srb               a0, a1, a2, 1
> +srh               a0, a1, a2, 1
> +srw               a0, a1, a2, 1
> +sbia              a0, (a1), 15, 1
> +sbib              a0, (a1), 15, 1
> +shia              a0, (a1), 15, 1
> +shib              a0, (a1), 15, 1
> +swia              a0, (a1), 12, 1
> +swib              a0, (a1), 15, 1
> +
> +fmv.x.hw   a0, f0
> +fmv.hw.x   f0, a0
> +ipush
> +ipop
> +
> diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
> index 84fc2ee0e8e..63664cb308c 100644
> --- a/include/opcode/riscv-opc.h
> +++ b/include/opcode/riscv-opc.h
> @@ -18,9 +18,10 @@
>     along with this program; see the file COPYING3. If not,
>     see <http://www.gnu.org/licenses/>.  */
>
> +#include "opcode/riscv-vendor-opc.h"
> +
>  #ifndef RISCV_ENCODING_H
>  #define RISCV_ENCODING_H
> -#include "opcode/riscv-vendor-opc.h"
>  /* Instruction opcode macros.  */
>  #define MATCH_SLLI_RV32 0x1013
>  #define MASK_SLLI_RV32  0xfe00707f
> diff --git a/include/opcode/riscv-vendor-opc.h b/include/opcode/riscv-vendor-opc.h
> index 949047239f8..3cf6c6a7fb5 100644
> --- a/include/opcode/riscv-vendor-opc.h
> +++ b/include/opcode/riscv-vendor-opc.h
> @@ -18,17 +18,483 @@
>     along with this program; see the file COPYING3. If not,
>     see <http://www.gnu.org/licenses/>.  */
>
> -#ifndef __RISCV_VENDOR_OPC_H__
> -#define __RISCV_VENDOR_OPC_H__
> +#ifndef __RISCV_VENDOR_THEAD_OPC__
> +#define __RISCV_VENDOR_THEAD_OPC__
>
> +/* 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
>
> -/* Opcodes for VENDOR 0.  */
> +/* H extensions.  */
> +#define MATCH_HFENCE_VVMA 0x22000073
> +#define MASK_HFENCE_VVMA 0xfe007fff
> +#define MATCH_HFENCE_GVMA 0x62000073
> +#define MASK_HFENCE_GVMA 0xfe007fff
>
> +/* T-Head crypto extensions.  */
> +#define MATCH_THEAD_ANDN 0x0800100b
> +#define MASK_THEAD_ANDN 0xfe00707f
> +#define MATCH_THEAD_ORN 0x0a00100b
> +#define MASK_THEAD_ORN 0xfe00707f
> +#define MATCH_THEAD_XORN 0x0c00100b
> +#define MASK_THEAD_XORN 0xfe00707f
> +#define MATCH_THEAD_PACKL 0x1800100b
> +#define MASK_THEAD_PACKL 0xfe00707f
> +#define MATCH_THEAD_PACKH 0x1a00100b
> +#define MASK_THEAD_PACKH 0xfe00707f
> +#define MATCH_THEAD_PACKHL 0x1c00100b
> +#define MASK_THEAD_PACKHL 0xfe00707f
>
> -/* Opcodes for VENDOR 1.  */
> +/* 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
>
> -/* Opcodes for VENDOR 2.  */
> +/* T-HEAD M mode CSR.  */
> +#define CSR_MXSTATUS 0x7c0
> +#define CSR_MHCR 0x7c1
> +#define CSR_MCOR 0x7c2
> +#define CSR_MCCR2 0x7c3
> +#define CSR_MCER2 0x7c4
> +#define CSR_MHINT 0x7c5
> +#define CSR_MRMR 0x7c6
> +#define CSR_MRVBR 0x7c7
> +#define CSR_MCER 0x7c8
> +#define CSR_MCOUNTERWEN 0x7c9
> +#define CSR_MCOUNTERINTEN 0x7ca
> +#define CSR_MCOUNTEROF 0x7cb
> +#define CSR_MHINT2 0x7cc
> +#define CSR_MHINT3 0x7cd
> +#define CSR_MRADDR 0x7e0
> +#define CSR_MEXSTATUS 0x7e1
> +#define CSR_MNMICAUSE 0x7e2
> +#define CSR_MNMIPC 0x7e3
> +#define CSR_MHPMCR 0x7f0
> +#define CSR_MHPMSR 0x7f1
> +#define CSR_MHPMER 0x7f2
> +#define CSR_MSMPR 0x7f3
> +#define CSR_MTEECFG 0x7f4
> +#define CSR_MZONEID 0x7f5
> +#define CSR_ML2CPID 0x7f6
> +#define CSR_ML2WP 0x7f7
> +#define CSR_MDTCMCR 0x7f8
> +#define CSR_USP 0x7d1
> +#define CSR_MCINS 0x7d2
> +#define CSR_MCINDEX 0x7d3
> +#define CSR_MCDATA0 0x7d4
> +#define CSR_MCDATA1 0x7d5
> +#define CSR_MEICR 0x7d6
> +#define CSR_MEICR2 0x7d7
> +#define CSR_MBEADDR 0x7d8
> +#define CSR_MCPUID 0xfc0
> +#define CSR_MAPBADDR 0xfc1
> +#define CSR_MWMSR 0xfc2
> +#define CSR_MHALTCAUSE 0xfe0
> +#define CSR_MDBGINFO 0xfe1
> +#define CSR_MPCFIFO 0xfe2
> +
> +
> +/* T-HEAD S mode CSR.  */
> +#define CSR_SXSTATUS 0x5c0
> +#define CSR_SHCR 0x5c1
> +#define CSR_SCER2 0x5c2
> +#define CSR_SCER 0x5c3
> +#define CSR_SCOUNTERINTEN 0x5c4
> +#define CSR_SCOUNTEROF 0x5c5
> +#define CSR_SHINT 0x5c6
> +#define CSR_SHINT2 0x5c7
> +#define CSR_SHPMINHIBIT 0x5c8
> +#define CSR_SHPMCR 0x5c9
> +#define CSR_SHPMSR 0x5ca
> +#define CSR_SHPMER 0x5cb
> +#define CSR_SL2CPID 0x5cc
> +#define CSR_SL2WP 0x5cd
> +#define CSR_SBEADDR 0x5d0
> +#define CSR_SCYCLE 0x5e0
> +#define CSR_SHPMCOUNTER1 0x5e1
> +#define CSR_SHPMCOUNTER2 0x5e2
> +#define CSR_SHPMCOUNTER3 0x5e3
> +#define CSR_SHPMCOUNTER4 0x5e4
> +#define CSR_SHPMCOUNTER5 0x5e5
> +#define CSR_SHPMCOUNTER6 0x5e6
> +#define CSR_SHPMCOUNTER7 0x5e7
> +#define CSR_SHPMCOUNTER8 0x5e8
> +#define CSR_SHPMCOUNTER9 0x5e9
> +#define CSR_SHPMCOUNTER10 0x5ea
> +#define CSR_SHPMCOUNTER11 0x5eb
> +#define CSR_SHPMCOUNTER12 0x5ec
> +#define CSR_SHPMCOUNTER13 0x5ed
> +#define CSR_SHPMCOUNTER14 0x5ee
> +#define CSR_SHPMCOUNTER15 0x5ef
> +#define CSR_SHPMCOUNTER16 0x5f0
> +#define CSR_SHPMCOUNTER17 0x5f1
> +#define CSR_SHPMCOUNTER18 0x5f2
> +#define CSR_SHPMCOUNTER19 0x5f3
> +#define CSR_SHPMCOUNTER20 0x5f4
> +#define CSR_SHPMCOUNTER21 0x5f5
> +#define CSR_SHPMCOUNTER22 0x5f6
> +#define CSR_SHPMCOUNTER23 0x5f7
> +#define CSR_SHPMCOUNTER24 0x5f8
> +#define CSR_SHPMCOUNTER25 0x5f9
> +#define CSR_SHPMCOUNTER26 0x5fa
> +#define CSR_SHPMCOUNTER27 0x5fb
> +#define CSR_SHPMCOUNTER28 0x5fc
> +#define CSR_SHPMCOUNTER29 0x5fd
> +#define CSR_SHPMCOUNTER30 0x5fe
> +#define CSR_SHPMCOUNTER31 0x5ff
>
> +/* T-HEAD U mode CSR.  */
> +#define CSR_FXCR 0x800
> +
> +/* T-HEAD MMU extentions.  */
> +#define CSR_SMIR 0x9c0
> +#define CSR_SMEL 0x9c1
> +#define CSR_SMEH 0x9c2
> +#define CSR_SMCIR 0x9c3
> +
> +/* T-HEAD Security CSR(May be droped).  */
> +#define CSR_MEBR 0xbe0
> +#define CSR_NT_MSTATUS 0xbe1
> +#define CSR_NT_MIE 0xbe2
> +#define CSR_NT_MTVEC 0xbe3
> +#define CSR_NT_MTVT 0xbe4
> +#define CSR_NT_MEPC 0xbe5
> +#define CSR_NT_MCAUSE 0xbe6
> +#define CSR_NT_MIP 0xbe7
> +#define CSR_NT_MINTSTATE 0xbe8
> +#define CSR_NT_MXSTATUS 0xbe9
> +#define CSR_NT_MEBR 0xbea
> +#define CSR_NT_MSP 0xbeb
> +#define CSR_T_USP 0xbec
> +#define CSR_T_MDCR 0xbed
> +#define CSR_T_MPCR 0xbee
> +#define CSR_PMPTEECFG 0xbef
> +#endif
>
> +#ifdef DECLARE_CSR
> +/* T-HEAD extentions.  */
> +DECLARE_CSR(mxstatus, CSR_MXSTATUS, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mhcr, CSR_MHCR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mcor, CSR_MCOR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mccr2, CSR_MCCR2, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mcer2, CSR_MCER2, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mhint, CSR_MHINT, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mrmr, CSR_MRMR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mrvbr, CSR_MRVBR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mcer, CSR_MCER, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mcounterwen, CSR_MCOUNTERWEN, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mcounterinten, CSR_MCOUNTERINTEN, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mcounterof, CSR_MCOUNTEROF, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mhint2, CSR_MHINT2, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mhint3, CSR_MHINT3, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mraddr, CSR_MRADDR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mexstatus, CSR_MEXSTATUS, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mnmicause, CSR_MNMICAUSE, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mnmipc, CSR_MNMIPC, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mhpmcr, CSR_MHPMCR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mhpmsr, CSR_MHPMSR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mhpmer, CSR_MHPMER, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(msmpr, CSR_MSMPR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mteecfg, CSR_MTEECFG, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mzoneid, CSR_MZONEID, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(ml2cpid, CSR_ML2CPID, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(ml2wp, CSR_ML2WP, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mdtcmcr, CSR_MDTCMCR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(usp, CSR_USP, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mcins, CSR_MCINS, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mcindex, CSR_MCINDEX, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mcdata0, CSR_MCDATA0, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mcdata1, CSR_MCDATA1, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(meicr, CSR_MEICR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(meicr2, CSR_MEICR2, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mbeaddr, CSR_MBEADDR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mebr, CSR_MEBR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(nt_mstatus, CSR_NT_MSTATUS, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(nt_mtvec, CSR_NT_MTVEC, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(nt_mie, CSR_NT_MIE, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(nt_mtvt, CSR_NT_MTVT, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(nt_mepc, CSR_NT_MEPC, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(nt_mcause, CSR_NT_MCAUSE, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(nt_mip, CSR_NT_MIP, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(nt_mintstate, CSR_NT_MINTSTATE, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(nt_mxstatus, CSR_NT_MXSTATUS, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(nt_mebr, CSR_NT_MEBR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(nt_msp, CSR_NT_MSP, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(t_usp, CSR_T_USP, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(t_mdcr, CSR_T_MDCR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(t_mpcr, CSR_T_MPCR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(pmpteecfg, CSR_PMPTEECFG, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mcpuid, CSR_MCPUID, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mapbaddr, CSR_MAPBADDR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(mwmsr, CSR_MWMSR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(fxcr, CSR_FXCR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(smir, CSR_SMIR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(smel, CSR_SMEL, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(smeh, CSR_SMEH, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(smcir, CSR_SMCIR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(sxstatus, CSR_SXSTATUS, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shcr, CSR_SHCR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(scer2, CSR_SCER2, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(scer, CSR_SCER, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(scounterinten , CSR_SCOUNTERINTEN, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(scounterof, CSR_SCOUNTEROF, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shint, CSR_SHINT, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shint2, CSR_SHINT2, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpminhibit, CSR_SHPMINHIBIT, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcr, CSR_SHPMCR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmsr, CSR_SHPMSR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmer, CSR_SHPMER, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(sl2cpid, CSR_SL2CPID, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(sl2wp, CSR_SL2WP, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(sbeaddr, CSR_SBEADDR, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(scycle, CSR_SCYCLE, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcounter1, CSR_SHPMCOUNTER1, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcounter2, CSR_SHPMCOUNTER2, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcounter3, CSR_SHPMCOUNTER3, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcounter4, CSR_SHPMCOUNTER4, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcounter5, CSR_SHPMCOUNTER5, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcounter6, CSR_SHPMCOUNTER6, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcounter7, CSR_SHPMCOUNTER7, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcounter8, CSR_SHPMCOUNTER8, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcounter9, CSR_SHPMCOUNTER9, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcounter10, CSR_SHPMCOUNTER10, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcounter11, CSR_SHPMCOUNTER11, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcounter12, CSR_SHPMCOUNTER12, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcounter13, CSR_SHPMCOUNTER13, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcounter14, CSR_SHPMCOUNTER14, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcounter15, CSR_SHPMCOUNTER15, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcounter16, CSR_SHPMCOUNTER16, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcounter17, CSR_SHPMCOUNTER17, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcounter18, CSR_SHPMCOUNTER18, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcounter19, CSR_SHPMCOUNTER19, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcounter20, CSR_SHPMCOUNTER20, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcounter21, CSR_SHPMCOUNTER21, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcounter22, CSR_SHPMCOUNTER22, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcounter23, CSR_SHPMCOUNTER23, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcounter24, CSR_SHPMCOUNTER24, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcounter25, CSR_SHPMCOUNTER25, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcounter26, CSR_SHPMCOUNTER26, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcounter27, CSR_SHPMCOUNTER27, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcounter28, CSR_SHPMCOUNTER28, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcounter29, CSR_SHPMCOUNTER29, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcounter30, CSR_SHPMCOUNTER30, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
> +DECLARE_CSR(shpmcounter31, CSR_SHPMCOUNTER31, CSR_CLASS_VENDOR, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
>  #endif

Likewise, add these into include/opcode/riscv-opc-extended.h should be enough.

> +
> +/* Opcodes for VENDOR 1.  */
> +
> +
> +/* Opcodes for VENDOR 2.  */
> +
> diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
> index af8df794d1b..7ea645b8bfe 100644
> --- a/include/opcode/riscv.h
> +++ b/include/opcode/riscv.h
> @@ -102,6 +102,10 @@ static const char * const riscv_pred_succ[16] =
>    ((RV_X(x, 3, 2) << 1) | (RV_X(x, 10, 2) << 3) | (RV_X(x, 2, 1) << 5) | (RV_X(x, 5, 2) << 6) | (-RV_X(x, 12, 1) << 8))
>  #define EXTRACT_CJTYPE_IMM(x) \
>    ((RV_X(x, 3, 3) << 1) | (RV_X(x, 11, 1) << 4) | (RV_X(x, 2, 1) << 5) | (RV_X(x, 7, 1) << 6) | (RV_X(x, 6, 1) << 7) | (RV_X(x, 9, 2) << 8) | (RV_X(x, 8, 1) << 10) | (-RV_X(x, 12, 1) << 11))
> +#define EXTRACT_VENDOR_IMM(x,nbit,at) \
> +  (RV_X(x, at, nbit))
> +#define EXTRACT_VENDOR_SIGN_IMM(x,nbit,at) \
> +  (RV_X(x, at, nbit) | ((-(RV_X(x, (at+nbit-1),1))) << (nbit)))
>
>  #define ENCODE_ITYPE_IMM(x) \
>    (RV_X(x, 0, 12) << 20)
> @@ -143,6 +147,11 @@ static const char * const riscv_pred_succ[16] =
>    ((RV_X(x, 1, 2) << 3) | (RV_X(x, 3, 2) << 10) | (RV_X(x, 5, 1) << 2) | (RV_X(x, 6, 2) << 5) | (RV_X(x, 8, 1) << 12))
>  #define ENCODE_CJTYPE_IMM(x) \
>    ((RV_X(x, 1, 3) << 3) | (RV_X(x, 4, 1) << 11) | (RV_X(x, 5, 1) << 2) | (RV_X(x, 6, 1) << 7) | (RV_X(x, 7, 1) << 6) | (RV_X(x, 8, 2) << 9) | (RV_X(x, 10, 1) << 8) | (RV_X(x, 11, 1) << 12))
> +#define ENCODE_VENDOR_IMM(x,nbit,at) \
> +  (RV_X(x, 0, nbit) << at)
> +#define ENCODE_VENDOR_SIGN_IMM(x,nbit,at) \
> +  (RV_X(x, 0, nbit) << at)
> +
>
>  #define VALID_ITYPE_IMM(x) (EXTRACT_ITYPE_IMM(ENCODE_ITYPE_IMM(x)) == (x))
>  #define VALID_STYPE_IMM(x) (EXTRACT_STYPE_IMM(ENCODE_STYPE_IMM(x)) == (x))
> @@ -166,6 +175,8 @@ static const char * const riscv_pred_succ[16] =
>  #define VALID_CLTYPE_LD_IMM(x) (EXTRACT_CLTYPE_LD_IMM(ENCODE_CLTYPE_LD_IMM(x)) == (x))
>  #define VALID_CBTYPE_IMM(x) (EXTRACT_CBTYPE_IMM(ENCODE_CBTYPE_IMM(x)) == (x))
>  #define VALID_CJTYPE_IMM(x) (EXTRACT_CJTYPE_IMM(ENCODE_CJTYPE_IMM(x)) == (x))
> +#define VALID_VENDOR_IMM(x,nbit,at) (EXTRACT_VENDOR_IMM(ENCODE_VENDOR_IMM(x,nbit,at),nbit,at) == (x))
> +#define VALID_VENDOR_SIGN_IMM(x,nbit,at) (EXTRACT_VENDOR_SIGN_IMM(ENCODE_VENDOR_SIGN_IMM(x,nbit,at),nbit,at) == (x))

Could you add these after the comment - /* Extended extensions.  */?
or at the end of the file.  Besides, VENDOR keywords isn't really
good, since we may have more than one vendor, so it would be good of
you can give this vendor extension a name.

>  #define RISCV_RTYPE(insn, rd, rs1, rs2) \
>    ((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ((rs1) << OP_SH_RS1) | ((rs2) << OP_SH_RS2))
> @@ -320,6 +331,7 @@ enum riscv_insn_class
>    INSN_CLASS_ZBB,
>    INSN_CLASS_ZBC,
>    INSN_CLASS_EXTENDED
> +
>  };
>
>  /* This structure holds information for a particular instruction.  */
> @@ -506,6 +518,10 @@ enum riscv_extended_insn_class
>
>    /* INSN class for THEAD.  */
>    INSN_CLASS_THEADC,
> +  INSN_CLASS_THEADC_OR_THEADE,
> +  INSN_CLASS_THEADC_OR_THEADE_OR_THEADSE,
> +  INSN_CLASS_THEADE,
> +  INSN_CLASS_THEADSE,
>  };

Yes, this is the right place to add.

>  /* This is a list of macro expanded instructions for extended
> @@ -528,4 +544,7 @@ extern const char * const riscv_vma[2];
>
>  extern const struct riscv_opcode *riscv_extended_opcodes[];
>
> +/* Matches for opcode.  */
> +int match_opcode (const struct riscv_opcode *op, insn_t insn);
> +
>  #endif /* _RISCV_H_ */
> diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
> index 8ddc6bec370..c67c18946f1 100644
> --- a/opcodes/riscv-dis.c
> +++ b/opcodes/riscv-dis.c
> @@ -528,6 +528,56 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
>         case 'Z':
>           print (info->stream, "%d", rs1);
>           break;
> +       case 'X':
> +           {
> +             int nbit = 0;
> +             int at = -1;
> +             char c = 0;
> +             int shift = 0;
> +             int constant = 0;
> +             d++;
> +             c = *d++;
> +             switch (c)
> +               {
> +               case 'I':
> +                 nbit = strtol (d, (char **)&d, 10);
> +                 if ((*d) =='@')
> +                   at = strtol(++d, (char **)&d, 10);
> +
> +                 d--;
> +
> +                 print (info->stream, "%d", (unsigned int)(EXTRACT_VENDOR_IMM(l, nbit, at) << shift));
> +                 break;
> +               case 'S':
> +                 nbit = strtol (d, (char **)&d, 10);
> +                 if ((*d) =='<' && (*(d + 1) == '<'))
> +                   {
> +                     d += 2;
> +                     shift = strtol (d, (char **)&d, 10);
> +                   }
> +                 if ((*d) =='@')
> +                   at = strtol(++d, (char **)&d, 10);
> +
> +                 d--;
> +
> +                 print (info->stream, "%d", (unsigned)(EXTRACT_VENDOR_SIGN_IMM(l, nbit, at) << shift));
> +                 break;
> +               case 'g':
> +                 nbit = strtol (d, (char **)&d, 10);
> +                 if ((*d) =='@')
> +                   at = strtol(++d, (char **)&d, 10);
> +
> +                 d--;
> +                 print (info->stream, "%s", riscv_gpr_names[EXTRACT_VENDOR_IMM(l, nbit, at)]);
> +                 break;
> +               case 'C':
> +                 constant = strtol (d, (char **)&d, 10);
> +                 print (info->stream, "%d", constant);
> +                 d--;
> +                 break;
> +               }
> +           }
> +         break;

Likewise, add these things in the print_extended_insn_args.

>         default:
>           oparg = opargStart;
> diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
> index c8e773460e1..6cb3b264f9c 100644
> --- a/opcodes/riscv-opc.c
> +++ b/opcodes/riscv-opc.c
> @@ -86,7 +86,7 @@ const char * const riscv_fpr_names_abi[NFPR] =
>  #define MATCH_SHAMT_REV8_64 (0b111000 << OP_SH_SHAMT)
>  #define MATCH_SHAMT_ORC_B (0b00111 << OP_SH_SHAMT)
>
> -static int
> +int
>  match_opcode (const struct riscv_opcode *op,
>               insn_t insn,
>               int constraints ATTRIBUTE_UNUSED,
> diff --git a/opcodes/riscv-vendor-opc.c b/opcodes/riscv-vendor-opc.c
> index 9191b654c14..085a38525a6 100644
> --- a/opcodes/riscv-vendor-opc.c
> +++ b/opcodes/riscv-vendor-opc.c
> @@ -26,9 +26,165 @@
>  #include <stdio.h>
>  #include "bfd.h"
>
> +
> +/*
> +   ARG format:
> +
> +   "Xgm@n": encode GPR with m bit at opcode[m+n-1:n].
> +    "Xg5@0": encode GPR with 5 bit at opcode[4:0].
> +    "Xg5@8": encode GPR with 5 bit at opcode[12:8].
> +
> +   "XCm": constant m, no encode for this.
> +    "XC4": constant 4.
> +
> +   "XIm@n": m bits unsigned immediate at opcode[m+n-1:n].
> +    "XI5@0": 5 bits unsigned immediate at opcode[4:0].
> +    "XI4@8": 4 bits unsigned immediate at opcode[11:8].
> +
> +   "XSm@n": m bits signed immediate at opcode[m+n-1:n].
> +    "XS5@0": 5 bits signed immediate at opcode[4:0].
> +    "XS4@8": 4 bits signed immediate at opcode[11:8].
> +
> +   "XFm@n": m bits FR at opcode[m+n-1:n].
> +    "XF5@0": 5 bits FR at opcode[4:0].
> +    "XF5@0": 5 bits FR at opcode[4:0].
> +*/
> +
> +#define MASK_RS1 (OP_MASK_RS1 << OP_SH_RS1)
> +#define MASK_RS2 (OP_MASK_RS2 << OP_SH_RS2)
> +#define MASK_RD (OP_MASK_RD << OP_SH_RD)
> +
> +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;
> +
> +  /* FIXME: add xlen check.  */
> +  return match_opcode (op, insn) && rd1 != rs1 && rd2 != rs1;
> +}
> +
>  /* The vendor extension opcodes for T-HEAD.  */
>  struct riscv_opcode vendor_thead_opcodes[] =
>  {
> +  {"wsc",             0, INSN_CLASS_THEADC_OR_THEADE,   "",  MATCH_WSC, MASK_WSC, match_opcode, 0},
> +  {"dcache.iall",     0, INSN_CLASS_THEADC_OR_THEADE,   "",  MATCH_DCACHE_IALL, MASK_DCACHE_IALL, match_opcode, 0},
> +  {"dcache.call",     0, INSN_CLASS_THEADC_OR_THEADE,   "",  MATCH_DCACHE_CALL, MASK_DCACHE_CALL, match_opcode, 0},
> +  {"dcache.ciall",    0, INSN_CLASS_THEADC_OR_THEADE,   "",  MATCH_DCACHE_CIALL, MASK_DCACHE_CIALL, match_opcode, 0},
> +  {"dcache.isw",      0, INSN_CLASS_THEADC_OR_THEADE,   "s",     MATCH_DCACHE_ISW, MASK_DCACHE_ISW, match_opcode, 0},
> +  {"dcache.csw",      0, INSN_CLASS_THEADC_OR_THEADE,   "s",     MATCH_DCACHE_CSW, MASK_DCACHE_CSW, match_opcode, 0},
> +  {"dcache.cisw",     0, INSN_CLASS_THEADC_OR_THEADE,   "s",     MATCH_DCACHE_CISW, MASK_DCACHE_CISW, match_opcode, 0},
> +  {"dcache.iva",      0, INSN_CLASS_THEADC,   "s",     MATCH_DCACHE_IVA, MASK_DCACHE_IVA, match_opcode, 0},
> +  {"dcache.cva",      0, INSN_CLASS_THEADC,   "s",     MATCH_DCACHE_CVA, MASK_DCACHE_CVA, match_opcode, 0},
> +  {"dcache.cval1",    0, INSN_CLASS_THEADC,   "s",     MATCH_DCACHE_CVAL1, MASK_DCACHE_CVAL1, match_opcode, 0},
> +  {"dcache.civa",     0, INSN_CLASS_THEADC,   "s",     MATCH_DCACHE_CIVA, MASK_DCACHE_CIVA, match_opcode, 0},
> +  {"dcache.ipa",      0, INSN_CLASS_THEADC_OR_THEADE,   "s",     MATCH_DCACHE_IPA, MASK_DCACHE_IPA, match_opcode, 0},
> +  {"dcache.cpa",      0, INSN_CLASS_THEADC_OR_THEADE,   "s",     MATCH_DCACHE_CPA, MASK_DCACHE_CPA, match_opcode, 0},
> +  {"dcache.cpal1",    0, INSN_CLASS_THEADC,   "s",     MATCH_DCACHE_CPAL1, MASK_DCACHE_CPAL1, match_opcode, 0},
> +  {"dcache.cipa",     0, INSN_CLASS_THEADC_OR_THEADE,   "s",     MATCH_DCACHE_CIPA, MASK_DCACHE_CIPA, match_opcode, 0},
> +  {"icache.iall",     0, INSN_CLASS_THEADC_OR_THEADE_OR_THEADSE,   "",      MATCH_ICACHE_IALL, MASK_ICACHE_IALL, match_opcode, 0},
> +  {"icache.iall",     0, INSN_CLASS_THEADSE,   "",      MATCH_ICACHE_IALL, MASK_ICACHE_IALL, match_opcode, INSN_ALIAS},
> +  {"icache.ialls",    0, INSN_CLASS_THEADC,   "",      MATCH_ICACHE_IALLS, MASK_ICACHE_IALLS, match_opcode, 0},
> +  {"icache.iva",      0, INSN_CLASS_THEADC,   "s",     MATCH_ICACHE_IVA, MASK_ICACHE_IVA, match_opcode, 0},
> +  {"icache.ipa",      0, INSN_CLASS_THEADC_OR_THEADE,   "s",     MATCH_ICACHE_IPA, MASK_ICACHE_IPA, match_opcode, 0},
> +  {"l2cache.iall",    0, INSN_CLASS_THEADC,   "",      MATCH_L2CACHE_IALL, MASK_L2CACHE_IALL, match_opcode, 0},
> +  {"l2cache.call",    0, INSN_CLASS_THEADC,   "",      MATCH_L2CACHE_CALL, MASK_L2CACHE_CALL, match_opcode, 0},
> +  {"l2cache.ciall",   0, INSN_CLASS_THEADC_OR_THEADE,   "",      MATCH_L2CACHE_CIALL, MASK_L2CACHE_CIALL, match_opcode, 0},
> +  {"sync",            0, INSN_CLASS_THEADC_OR_THEADE,   "",      MATCH_SYNC, MASK_SYNC, match_opcode, 0},
> +  {"sync.i",          0, INSN_CLASS_THEADC_OR_THEADE,   "",      MATCH_SYNC_I, MASK_SYNC_I, match_opcode, 0},
> +  {"sync.s",          0, INSN_CLASS_THEADC,   "",      MATCH_SYNC_S, MASK_SYNC_S, match_opcode, 0},
> +  {"sync.is",         0, INSN_CLASS_THEADC,   "",      MATCH_SYNC_IS, MASK_SYNC_IS, match_opcode, 0},
> +  {"tstnbz",          0, INSN_CLASS_THEADC_OR_THEADE,   "d,s",     MATCH_TSTNBZ, MASK_TSTNBZ, match_opcode, 0},
> +  {"mula",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MULA, MASK_MULA, match_opcode, 0},
> +  {"muls",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MULS, MASK_MULS, match_opcode, 0},
> +  {"mulah",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MULAH, MASK_MULAH, match_opcode, 0},
> +  {"mulsh",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MULSH, MASK_MULSH, match_opcode, 0},
> +  {"sfence.vmas",     0, INSN_CLASS_THEADC,   "s,t",      MATCH_SFENCE_VMAS, MASK_SFENCE_VMAS, match_opcode, 0},
> +  {"mveqz",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MVEQZ, MASK_MVEQZ, match_opcode, 0},
> +  {"mvnez",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MVNEZ, MASK_MVNEZ, match_opcode, 0},
> +  {"mulaw",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MULAW, MASK_MULAW, match_opcode, 0},
> +  {"mulsw",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MULSW, MASK_MULSW, match_opcode, 0},
> +  {"ext",             64, INSN_CLASS_THEADC,  "d,s,XI6@26,XI6@20",   MATCH_EXT, MASK_EXT, match_opcode, 0 },
> +  {"ext",             32, INSN_CLASS_THEADE,  "d,s,XI5@26,XI5@20",   MATCH_EXT, (MASK_EXT | (1U<<25) | (1U<<31)), match_opcode, 0 },
> +  {"extu",            64, INSN_CLASS_THEADC,  "d,s,XI6@26,XI6@20",   MATCH_EXTU, MASK_EXTU, match_opcode, 0 },
> +  {"extu",            32, INSN_CLASS_THEADE,  "d,s,XI5@26,XI5@20",   MATCH_EXTU, (MASK_EXTU | (1U<<25) | (1U<<31)), match_opcode, 0 },
> +  {"ff1",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s",   MATCH_FF1, MASK_FF1, match_opcode, 0},
> +  {"ff0",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s",   MATCH_FF0, MASK_FF1, match_opcode, 0},
> +  {"rev",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s",   MATCH_REV, MASK_REV, match_opcode, 0},
> +  {"lrb",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_LRB, MASK_LRB, match_opcode, 0 },
> +  {"lrbu",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_LRBU, MASK_LRBU, match_opcode, 0 },
> +  {"lrh",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_LRH, MASK_LRH, match_opcode, 0 },
> +  {"lrhu",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_LRHU, MASK_LRHU, match_opcode, 0 },
> +  {"lrw",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_LRW, MASK_LRW, match_opcode, 0 },
> +  {"lrwu",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_LRWU, MASK_LRWU, match_opcode, 0 },
> +  {"srb",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_SRB, MASK_SRB, match_opcode, 0 },
> +  {"srh",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_SRH, MASK_SRH, match_opcode, 0 },
> +  {"srw",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_SRW, MASK_SRW, match_opcode, 0 },
> +  {"lrd",             0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LRD, MASK_LRD, match_opcode, 0 },
> +  {"srd",             0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_SRD, MASK_SRD, match_opcode, 0 },
> +  {"lurb",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LURB, MASK_LURB, match_opcode, 0 },
> +  {"lurbu",           0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LURBU, MASK_LURBU, match_opcode, 0 },
> +  {"lurh",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LURH, MASK_LURH, match_opcode, 0 },
> +  {"lurhu",           0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LURHU, MASK_LURHU, match_opcode, 0 },
> +  {"lurw",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LURW, MASK_LURW, match_opcode, 0 },
> +  {"lurwu",           0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LURWU, MASK_LURWU, match_opcode, 0 },
> +  {"lurd",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LURD, MASK_LURD, match_opcode, 0 },
> +  {"surb",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_SURB, MASK_SURB, match_opcode, 0 },
> +  {"surh",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_SURH, MASK_SURH, match_opcode, 0 },
> +  {"surw",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_SURW, MASK_SURW, match_opcode, 0 },
> +  {"surd",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_SURD, MASK_SURD, match_opcode, 0 },
> +  {"tst",             64, INSN_CLASS_THEADC,  "d,s,XI6@20",   MATCH_TST, MASK_TST, match_opcode, 0 },
> +  {"tst",             32, INSN_CLASS_THEADE,   "d,s,XI5@20",   MATCH_TST, (MASK_TST | (1U << 25)), match_opcode, INSN_ALIAS},
> +  {"srriw",           0, INSN_CLASS_THEADC,   "d,s,XI5@20",   MATCH_SRRIW, MASK_SRRIW, match_opcode, 0 },
> +  {"srri",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,XI6@20",   MATCH_SRRI, MASK_SRRI, match_opcode, 0 },
> +  {"addsl",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25", MATCH_ADDSL, MASK_ADDSL, match_opcode, 0 },
> +  {"lwd",             0, INSN_CLASS_THEADC,   "d,t,(s),XI2@25,XC3", MATCH_LWD, MASK_LWD, match_thead_rd1_rd2_neq_rs1, 0 },
> +  {"ldd",             0, INSN_CLASS_THEADC,   "d,t,(s),XI2@25,XC4", MATCH_LDD, MASK_LDD, match_thead_rd1_rd2_neq_rs1, 0 },
> +  {"swd",             0, INSN_CLASS_THEADC,   "d,t,(s),XI2@25,XC3", MATCH_SWD, MASK_SWD, match_opcode, 0 },
> +  {"sdd",             0, INSN_CLASS_THEADC,   "d,t,(s),XI2@25,XC4", MATCH_SDD, MASK_SDD, match_opcode, 0 },
> +  {"sdia",            0, INSN_CLASS_THEADC,   "d,(s),XS5@20,XI2@25", MATCH_SDIA, MASK_SDIA, match_opcode, 0 },
> +  {"sdib",            0, INSN_CLASS_THEADC,   "d,(s),XS5@20,XI2@25", MATCH_SDIB, MASK_SDIB, match_opcode, 0 },
> +  {"lwud",            0, INSN_CLASS_THEADC,   "d,t,(s),XI2@25,XC3", MATCH_LWUD, MASK_LWUD, match_thead_rd1_rd2_neq_rs1, 0 },
> +  {"swia",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_SWIA, MASK_SWIA, match_opcode, 0},
> +  {"swib",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_SWIB, MASK_SWIB, match_opcode, 0},
> +  {"shia",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_SHIA, MASK_SHIA, match_opcode, 0},
> +  {"shib",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_SHIB, MASK_SHIB, match_opcode, 0},
> +  {"sbia",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_SBIA, MASK_SBIA, match_opcode, 0},
> +  {"sbib",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_SBIB, MASK_SBIB, match_opcode, 0},
> +  {"lwuia",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LWUIA, MASK_LWUIA, match_opcode, 0},
> +  {"lwuib",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LWUIB, MASK_LWUIB, match_opcode, 0},
> +  {"lhuia",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LHUIA, MASK_LHUIA, match_opcode, 0},
> +  {"lhuib",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LHUIB, MASK_LHUIB, match_opcode, 0},
> +  {"lbuia",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LBUIA, MASK_LBUIA, match_opcode, 0},
> +  {"lbuib",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LBUIB, MASK_LBUIB, match_opcode, 0},
> +  {"ldia",            0, INSN_CLASS_THEADC,   "d,(s),XS5@20,XI2@25", MATCH_LDIA, MASK_LDIA, match_opcode, 0},
> +  {"ldib",            0, INSN_CLASS_THEADC,   "d,(s),XS5@20,XI2@25", MATCH_LDIB, MASK_LDIB, match_opcode, 0},
> +  {"lwia",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LWIA, MASK_LWIA, match_opcode, 0},
> +  {"lwib",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LWIB, MASK_LWIB, match_opcode, 0},
> +  {"lhia",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LHIA, MASK_LHIA, match_opcode, 0},
> +  {"lhib",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LHIB, MASK_LHIB, match_opcode, 0},
> +  {"lbia",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LBIA, MASK_LBIA, match_opcode, 0},
> +  {"lbib",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LBIB, MASK_LBIB, match_opcode, 0},
> +  {"fsurd",           0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FSURD, MASK_FSURD, match_opcode, 0},
> +  {"revw",            0, INSN_CLASS_THEADC,   "d,s", MATCH_REVW, MASK_REVW, match_opcode, 0},
> +  {"fsurw",           0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FSURW, MASK_FSURW, match_opcode, 0},
> +  {"flurd",           0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FLURD, MASK_FLURD, match_opcode, 0},
> +  {"flurw",           0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FLURW, MASK_FLURW, match_opcode, 0},
> +  {"fsrd",            0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FSRD, MASK_FSRD, match_opcode, 0},
> +  {"fsrw",            0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FSRW, MASK_FSRW, match_opcode, 0},
> +  {"flrd",            0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FLRD, MASK_FLRD, match_opcode, 0},
> +  {"flrw",            0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FLRW, MASK_FLRW, match_opcode, 0},
> +
> +  /* THEADE only.  */
> +  {"ipush",           0, INSN_CLASS_THEADE,   "",  MATCH_IPUSH, MASK_IPUSH, match_opcode, 0},
> +  {"ipop",            0, INSN_CLASS_THEADE,   "",  MATCH_IPOP, MASK_IPOP, match_opcode, 0},
> +  /* Float move.  */
> +  {"fmv.x.hw",        32, INSN_CLASS_THEADE,  "d,S",  MATCH_FMV_X_HW, MASK_FMV_X_HW, match_opcode, 0},
> +  {"fmv.hw.x",        32, INSN_CLASS_THEADE,  "D,s",  MATCH_FMV_HW_X, MASK_FMV_HW_X, match_opcode, 0},
> +
> +
>    {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}
>
>  };
> @@ -38,6 +194,8 @@ const struct riscv_vendor_opcode riscv_vendor_list[] =
>  {
>    /* Vendor T-HEAD.  */
>    {"xtheadc", vendor_thead_opcodes},
> +  {"xtheade", vendor_thead_opcodes},
> +  {"xtheadse", vendor_thead_opcodes},
>    {NULL, NULL},
>  };

I think these probably for alibaba?  So you probably can change VENDOR
to ALIBABA, and rename the opcode table to riscv_alibaba_opcodes.
Then just add riscv_alibaba_opcodes into riscv_extended_opcodes.  Umm
maybe we should also give ISA names for these vendor extensions names
in the arch string.  But I remember that we don’t seem to have a
consensus in the community about this, so it should be time to discuss
this issue again.

> --
> 2.17.1
>

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

* Re: [Integration 0/2] RISC-V: Add vendor(T-HEAD) opcodes
  2021-09-03  2:59 [Integration 0/2] RISC-V: Add vendor(T-HEAD) opcodes Lifang Xia
  2021-09-03  3:00 ` [Integration 1/2] RISC-V: add vendor opcodes Lifang Xia
  2021-09-03  3:00 ` [Integration 2/2] RISC-V: Update csr and opcodes for Xuantie CPUs Lifang Xia
@ 2021-09-03  4:37 ` Nelson Chu
  2021-09-07  9:20 ` [integration 0/1] RISC-V: Add CSRs and opcodes of T-HEAD XUANTIE CPUs Lifang Xia
  3 siblings, 0 replies; 10+ messages in thread
From: Nelson Chu @ 2021-09-03  4:37 UTC (permalink / raw)
  To: Lifang Xia; +Cc: Binutils

Hi Lifang,

Basically, I am so happy that you are willing to open and share these
great vendor works, with a formal document.  But I remember that the
community seems to have no consensus on vendor extensions yet.
Personally I would like to accept these patches, except the comments
and thoughts which I have given in the previous mails.  Maybe it is
the time that we should discuss the vendor extensions in the community
again.

Thank you very much
Nelson

On Fri, Sep 3, 2021 at 11:00 AM Lifang Xia <lifang_xia@c-sky.com> wrote:
>
>
> These patches are add a mechanism to support vendor's opcodes.
> The [PATCH 2/2] is THEAD extension, which contains THEADC, THEADE ISAs.
> The doc is https://github.com/rjiejie/XuanTie-doc
>
>

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

* [integration 0/1] RISC-V: Add CSRs and opcodes of T-HEAD XUANTIE CPUs
  2021-09-03  2:59 [Integration 0/2] RISC-V: Add vendor(T-HEAD) opcodes Lifang Xia
                   ` (2 preceding siblings ...)
  2021-09-03  4:37 ` [Integration 0/2] RISC-V: Add vendor(T-HEAD) opcodes Nelson Chu
@ 2021-09-07  9:20 ` Lifang Xia
  2021-09-07  9:20   ` [PATCH] RISC-V: Add CSRs and opcodes of the " Lifang Xia
  2021-09-13 11:07   ` [integration 0/1] RISC-V: Add CSRs and opcodes of " Nelson Chu
  3 siblings, 2 replies; 10+ messages in thread
From: Lifang Xia @ 2021-09-07  9:20 UTC (permalink / raw)
  To: binutils; +Cc: nelson.chu, rjiejie


Hi Nelson,
Thanks for reveiwing these patches.
That's my fault that I'm not checking these patches in
binutils-integration-branch. I thought there are not much changes from
master. Sorry. :(

I re-write the patches, merge them to one patch here.
The extended solutions is suitable for adding CSRs and opcodes of T-HEAD
XUANTIE CPUs.
As you metioned in the previous e-mail, I agree with that it is not a
good solution for vendors. Is there any discussions about that?

Thanks!
Lifang Xia


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

* [PATCH] RISC-V: Add CSRs and opcodes of the T-HEAD XUANTIE CPUs
  2021-09-07  9:20 ` [integration 0/1] RISC-V: Add CSRs and opcodes of T-HEAD XUANTIE CPUs Lifang Xia
@ 2021-09-07  9:20   ` Lifang Xia
  2021-09-07  9:27     ` 夏立方
  2021-09-13 11:07   ` [integration 0/1] RISC-V: Add CSRs and opcodes of " Nelson Chu
  1 sibling, 1 reply; 10+ messages in thread
From: Lifang Xia @ 2021-09-07  9:20 UTC (permalink / raw)
  To: binutils; +Cc: nelson.chu, rjiejie, Lifang Xia

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

New ARG format for operands:
"Xgm@n": encode GPR with m bit at opcode[m+n-1:n].
  "Xg5@0": encode GPR with 5 bit at opcode[4:0].
  "Xg5@8": encode GPR with 5 bit at opcode[12:8].

"XIm@n": m bits unsigned immediate at opcode[m+n-1:n].
  "XI5@0": 5 bits unsigned immediate at opcode[4:0].
  "XI4@8": 4 bits unsigned immediate at opcode[11:8].

"XSm@n": m bits signed immediate at opcode[m+n-1:n].
  "XS5@0": 5 bits signed immediate at opcode[4:0].
  "XS4@8": 4 bits signed immediate at opcode[11:8].

"XFm@n": m bits FR at opcode[m+n-1:n].
  "XF5@0": 5 bits FR at opcode[4:0].
  "XF5@0": 5 bits FR at opcode[4:0].

bfd/
	* cpu-riscv.h (enum riscv_spec_class)
	<ISA_SPEC_CLASS_VENDOR_THEAD>: New.
gas/
	* config/tc-riscv.c (VENDOR_THEAD_EXT): New.
	(enum riscv_extended_csr_class) <CSR_CLASS_VENDOR_THEAD>: New.
	(extended_ext_version_table): Add "xtheadc", "xtheade",
	"xtheadse".
	(riscv_extended_subset_supports): Check subset:
	INSN_CLASS_THEAD*
	(riscv_search_ext_version_hash): Update versions for T-HEAD.
	(op_vendor_thead_hash): New, the hash of T-HEAD Xuantie's
	opcodes.
	(riscv_csr_address): Skip check version for T-HEAD Xuantie CPUs.
	(validate_riscv_extended_insn): Parsing T-HEAD opargs.
	(md_begin): Init op_vendor_thead_hash.
	(riscv_find_extended_opcode_hash): Search op_vendor_thead_hash.
	(riscv_parse_extended_operands): Parsing T-HEAD opargs.
	* testsuite/gas/riscv/extended/thead*: New testcases.
include/
	* opcode/riscv-opc-extended.h: Add CSRs and opcode of the T-HEAD
	XUANTIE CPUs.
	* opcode/riscv.h (riscv_extended_insn_class)
	<INSN_CLASS_THEADC>: New.
	<INSN_CLASS_THEADC_OR_THEADE>: New.
	<INSN_CLASS_THEADC_OR_THEADE_OR_THEADSE>: New.
	<INSN_CLASS_THEADE>: New.
	<INSN_CLASS_THEADSE>: New.
	(*VENDOR_THEAD_*): T-HEAD IMM encoding.
opcodes/
	* riscv-dis.c (print_extended_insn_args): Parsing T-HEAD opargs.
	* riscv-opc.c (match_thead_rd1_rd2_neq_rs1): New.
	(riscv_vendor_thead_opcodes): New.
	(riscv_extended_opcodes): Add riscv_vendor_thead_opcodes.
---
 bfd/cpu-riscv.h                                   |   1 +
 gas/config/tc-riscv.c                             | 151 ++++++
 gas/testsuite/gas/riscv/extended/thead-csr-list.d | 108 ++++
 gas/testsuite/gas/riscv/extended/thead-csr-list.s |  99 ++++
 gas/testsuite/gas/riscv/extended/theadc-ext.d     | 112 +++++
 gas/testsuite/gas/riscv/extended/theadc-ext.s     | 116 +++++
 gas/testsuite/gas/riscv/extended/theade-ext.d     |  62 +++
 gas/testsuite/gas/riscv/extended/theade-ext.s     |  67 +++
 include/opcode/riscv-opc-extended.h               | 572 ++++++++++++++++++++++
 include/opcode/riscv.h                            |  24 +
 opcodes/riscv-dis.c                               |  45 ++
 opcodes/riscv-opc.c                               | 160 ++++++
 12 files changed, 1517 insertions(+)
 create mode 100644 gas/testsuite/gas/riscv/extended/thead-csr-list.d
 create mode 100644 gas/testsuite/gas/riscv/extended/thead-csr-list.s
 create mode 100644 gas/testsuite/gas/riscv/extended/theadc-ext.d
 create mode 100644 gas/testsuite/gas/riscv/extended/theadc-ext.s
 create mode 100644 gas/testsuite/gas/riscv/extended/theade-ext.d
 create mode 100644 gas/testsuite/gas/riscv/extended/theade-ext.s

diff --git a/bfd/cpu-riscv.h b/bfd/cpu-riscv.h
index cafaca2..c1dcfce 100644
--- a/bfd/cpu-riscv.h
+++ b/bfd/cpu-riscv.h
@@ -26,6 +26,7 @@ enum riscv_spec_class
   ISA_SPEC_CLASS_20190608,
   ISA_SPEC_CLASS_20191213,
   ISA_SPEC_CLASS_DRAFT,
+  ISA_SPEC_CLASS_VENDOR_THEAD,
 
   /* Privileged spec.  */
   PRIV_SPEC_CLASS_NONE,
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 1899294..28cf183 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -40,6 +40,7 @@
 enum
 {
   DRAFT_EXT = 0,
+  VENDOR_THEAD_EXT,
   EXTENDED_EXT_NUM
 };
 
@@ -79,6 +80,7 @@ enum riscv_csr_class
 enum riscv_extended_csr_class
 {
   CSR_CLASS_V = CSR_CLASS_EXTENDED, /* RVV CSR */
+  CSR_CLASS_VENDOR_THEAD, /* vendor CSR for T-HEAD */
 };
 
 /* This structure holds all restricted conditions for a CSR.  */
@@ -170,6 +172,12 @@ static const struct riscv_ext_version extended_ext_version_table[] =
   {"zfh",     ISA_SPEC_CLASS_DRAFT, 0, 1},
   {"svinval", ISA_SPEC_CLASS_DRAFT, 0, 1},
 
+  /* T-HEAD extentions for Xuantie C9xx.
+     The version 2.0 just keeps compatible.  */
+  {"xtheadc",   ISA_SPEC_CLASS_VENDOR_THEAD, 2, 0},
+  {"xtheade",   ISA_SPEC_CLASS_VENDOR_THEAD, 2, 0},
+  {"xtheadse",   ISA_SPEC_CLASS_VENDOR_THEAD, 2, 0},
+
   /* Terminate the list.  */
   {NULL, 0, 0, 0}
 };
@@ -365,6 +373,20 @@ riscv_extended_subset_supports (int insn_class)
     case INSN_CLASS_SVINVAL:
       return riscv_subset_supports ("svinval");
 
+    case INSN_CLASS_THEADC:
+      return riscv_subset_supports ("xtheadc");
+    case INSN_CLASS_THEADC_OR_THEADE:
+      return (riscv_subset_supports ("xtheadc")
+	      || riscv_subset_supports ("xtheade"));
+    case INSN_CLASS_THEADC_OR_THEADE_OR_THEADSE:
+      return (riscv_subset_supports ("xtheadc")
+	      || riscv_subset_supports ("xtheade")
+	      || riscv_subset_supports ("xtheadse"));
+    case INSN_CLASS_THEADE:
+      return riscv_subset_supports ("xtheade");
+    case INSN_CLASS_THEADSE:
+      return riscv_subset_supports ("xtheadse");
+
     default:
       as_fatal ("internal: unknown INSN_CLASS (0x%x)", insn_class);
       return false;
@@ -458,6 +480,7 @@ riscv_search_ext_version_hash (const char *name,
 	 && strcmp (ext->name, name) == 0)
     {
       if (ext->isa_spec_class == ISA_SPEC_CLASS_DRAFT
+	  || ext->isa_spec_class == ISA_SPEC_CLASS_VENDOR_THEAD
 	  || ext->isa_spec_class == default_isa_spec)
 	{
 	  *major_version = ext->major_version;
@@ -576,6 +599,9 @@ static htab_t op_hash = NULL;
 /* Handle of the draft OPCODE hash table.  */
 static htab_t op_draft_hash = NULL;
 
+/* Handle of the T-HEAD OPCODE hash table.  */
+static htab_t op_vendor_thead_hash = NULL;
+
 /* Handle of the type of .insn hash table.  */
 static htab_t insn_type_hash = NULL;
 
@@ -996,6 +1022,7 @@ riscv_csr_address (const char *csr_name,
       need_check_version = false;
       break;
     case CSR_CLASS_DEBUG:
+    case CSR_CLASS_VENDOR_THEAD:
       need_check_version = false;
       break;
     default:
@@ -1150,6 +1177,48 @@ validate_riscv_extended_insn (insn_t *bits,
 	  return false;
 	}
       break;
+
+    case 'X':
+      switch (*++oparg)
+	{
+	case 'g':
+	  /* Xgm@n.  */
+	case 'F':
+	  /* XFm@n.  */
+	case 'I':
+	    {
+	      /* XIm@n.  */
+	      int nbit = 0;
+	      int at = -1;
+	      int shift = 0;
+	      nbit = strtol (++oparg, (char **)&oparg, 10);
+	      if (*oparg =='@')
+		at = strtol(++oparg, (char **)&oparg, 10);
+	      oparg--;
+
+	      used_bits |= ENCODE_VENDOR_THEAD_IMM((-1U>>shift), nbit, at);
+	      break;
+	    }
+	case 'S':
+	  /* XSm@n.  */
+	    {
+	      int nbit = 0;
+	      int at = -1;
+	      int shift = 0;
+	      nbit = strtol (++oparg, (char **)&oparg, 10);
+	      if ((*oparg) =='>' && (*(oparg+1)) == '>')
+		shift = strtol (oparg, (char **)&oparg, 10);
+	      if (*oparg =='@')
+		at = strtol(++oparg, (char **)&oparg, 10);
+	      oparg--;
+
+	      used_bits |= ENCODE_VENDOR_THEAD_IMM((-1>>shift), nbit, at);
+	      break;
+	    }
+	}
+      break;
+
+
     default:
       return false;
     }
@@ -1403,6 +1472,7 @@ md_begin (void)
   hash_reg_names (RCLASS_VECR, riscv_vecr_names_numeric, NVECR);
   hash_reg_names (RCLASS_VECM, riscv_vecm_names_numeric, NVECM);
   op_draft_hash = init_opcode_hash (riscv_extended_opcodes[DRAFT_EXT], false);
+  op_vendor_thead_hash = init_opcode_hash (riscv_extended_opcodes[VENDOR_THEAD_EXT], false);
 }
 
 static insn_t
@@ -1511,6 +1581,9 @@ riscv_find_extended_opcode_hash (char *str ATTRIBUTE_UNUSED)
 	case DRAFT_EXT:
 	  insn = (struct riscv_opcode *) str_hash_find (op_draft_hash, str);
 	  continue;
+	case VENDOR_THEAD_EXT:
+	  insn = (struct riscv_opcode *) str_hash_find (op_vendor_thead_hash, str);
+	  continue;
 	default:
 	  break;
 	}
@@ -2615,6 +2688,83 @@ riscv_parse_extended_operands (struct riscv_cl_insn *ip ATTRIBUTE_UNUSED,
 	}
       break;
 
+    case 'X':
+	{
+	  int nbit = 0;
+	  int at = -1;
+	  int shift = 0;
+	  switch (*++oparg)
+	    {
+	    case 'I':
+	      /* XIm@n.  */
+	      nbit = strtol (++oparg, (char **)&oparg, 10);
+	      if ((*oparg) =='@')
+		at = strtol(++oparg, (char **)&oparg, 10);
+
+	      oparg--;
+
+	      my_getExpression(imm_expr, asarg);
+	      if (imm_expr->X_op != O_constant
+		  || !VALID_VENDOR_THEAD_IMM(imm_expr->X_add_number, nbit, at))
+		return false;
+	      ip->insn_opcode |=
+		ENCODE_VENDOR_THEAD_IMM ((imm_expr->X_add_number >> shift), nbit, at);
+	      asarg = expr_end;
+	      imm_expr->X_op = O_absent;
+	      break;
+
+	    case 'S':
+	      /* XSm@n.  */
+	      nbit = strtol (++oparg, (char **)&oparg, 10);
+	      if ((*oparg) =='<' && (*(oparg+1)) == '<')
+		{
+		  oparg+= 2;
+		  shift = strtol(++oparg, (char **)&oparg, 10);
+		}
+
+	      if ((*oparg) =='@')
+		at = strtol(++oparg, (char **)&oparg, 10);
+
+	      oparg--;
+
+	      my_getExpression(imm_expr, asarg);
+	      if (imm_expr->X_op != O_constant
+		  || !VALID_VENDOR_THEAD_SIGN_IMM((imm_expr->X_add_number >> shift), nbit, at))
+		return false;
+	      ip->insn_opcode |=
+		ENCODE_VENDOR_THEAD_SIGN_IMM (imm_expr->X_add_number, nbit, at);
+	      asarg = expr_end;
+	      imm_expr->X_op = O_absent;
+	      break;;
+
+	    case 'g':
+	      /* Xgm@n.  */
+	      nbit = strtol (++oparg, (char **)&oparg, 10);
+	      if ((*oparg) =='<' && (*(oparg+1)) == '<')
+		{
+		  oparg+= 2;
+		  shift = strtol(++oparg, (char **)&oparg, 10);
+		}
+
+	      if ((*oparg) =='@')
+		at = strtol(++oparg, (char **)&oparg, 10);
+
+	      oparg--;
+
+
+	      my_getExpression(imm_expr, asarg);
+	      if (imm_expr->X_op != O_register
+		  || !VALID_VENDOR_THEAD_IMM(imm_expr->X_add_number, nbit, at))
+		return false;
+	      ip->insn_opcode |=
+		ENCODE_VENDOR_THEAD_IMM (imm_expr->X_add_number, nbit, at);
+	      asarg = expr_end;
+	      break;;
+	    }
+	}
+      break;;
+
+
     default:
       as_fatal (_("internal: unknown argument type `%s'"),
 		*opcode_args);
@@ -4587,3 +4737,4 @@ riscv_pop_insert (void)
 
   pop_insert (riscv_pseudo_table);
 }
+
diff --git a/gas/testsuite/gas/riscv/extended/thead-csr-list.d b/gas/testsuite/gas/riscv/extended/thead-csr-list.d
new file mode 100644
index 0000000..efe7859
--- /dev/null
+++ b/gas/testsuite/gas/riscv/extended/thead-csr-list.d
@@ -0,0 +1,108 @@
+#as: -march=rv64gcxtheadc
+#objdump: -dr
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0000000000000000 <.text>:
+   0:	7c002573          	csrr	a0,mxstatus
+   4:	7c102573          	csrr	a0,mhcr
+   8:	7c202573          	csrr	a0,mcor
+   c:	7c302573          	csrr	a0,mccr2
+  10:	7c402573          	csrr	a0,mcer2
+  14:	7c502573          	csrr	a0,mhint
+  18:	7c602573          	csrr	a0,mrmr
+  1c:	7c702573          	csrr	a0,mrvbr
+  20:	7c802573          	csrr	a0,mcer
+  24:	7c902573          	csrr	a0,mcounterwen
+  28:	7ca02573          	csrr	a0,mcounterinten
+  2c:	7cb02573          	csrr	a0,mcounterof
+  30:	7cc02573          	csrr	a0,mhint2
+  34:	7cd02573          	csrr	a0,mhint3
+  38:	7e002573          	csrr	a0,mraddr
+  3c:	7e102573          	csrr	a0,mexstatus
+  40:	7e202573          	csrr	a0,mnmicause
+  44:	7e302573          	csrr	a0,mnmipc
+  48:	7f002573          	csrr	a0,mhpmcr
+  4c:	7f102573          	csrr	a0,mhpmsr
+  50:	7f202573          	csrr	a0,mhpmer
+  54:	7f302573          	csrr	a0,msmpr
+  58:	7f402573          	csrr	a0,mteecfg
+  5c:	7d102573          	csrr	a0,usp
+  60:	7d202573          	csrr	a0,mcins
+  64:	7d302573          	csrr	a0,mcindex
+  68:	7d402573          	csrr	a0,mcdata0
+  6c:	7d502573          	csrr	a0,mcdata1
+  70:	7d602573          	csrr	a0,meicr
+  74:	7d702573          	csrr	a0,meicr2
+  78:	be002573          	csrr	a0,mebr
+  7c:	be102573          	csrr	a0,nt_mstatus
+  80:	be302573          	csrr	a0,nt_mtvec
+  84:	be202573          	csrr	a0,nt_mie
+  88:	be402573          	csrr	a0,nt_mtvt
+  8c:	be502573          	csrr	a0,nt_mepc
+  90:	be602573          	csrr	a0,nt_mcause
+  94:	be702573          	csrr	a0,nt_mip
+  98:	be802573          	csrr	a0,nt_mintstate
+  9c:	be902573          	csrr	a0,nt_mxstatus
+  a0:	bea02573          	csrr	a0,nt_mebr
+  a4:	beb02573          	csrr	a0,nt_msp
+  a8:	bec02573          	csrr	a0,t_usp
+  ac:	bed02573          	csrr	a0,t_mdcr
+  b0:	bee02573          	csrr	a0,t_mpcr
+  b4:	bef02573          	csrr	a0,pmpteecfg
+  b8:	fc002573          	csrr	a0,mcpuid
+  bc:	fc102573          	csrr	a0,mapbaddr
+  c0:	fc202573          	csrr	a0,mwmsr
+  c4:	80002573          	csrr	a0,fxcr
+  c8:	9c002573          	csrr	a0,smir
+  cc:	9c102573          	csrr	a0,smel
+  d0:	9c202573          	csrr	a0,smeh
+  d4:	9c302573          	csrr	a0,smcir
+  d8:	5c002573          	csrr	a0,sxstatus
+  dc:	5c102573          	csrr	a0,shcr
+  e0:	5c202573          	csrr	a0,scer2
+  e4:	5c302573          	csrr	a0,scer
+  e8:	5c402573          	csrr	a0,scounterinten
+  ec:	5c502573          	csrr	a0,scounterof
+  f0:	5c602573          	csrr	a0,shint
+  f4:	5c702573          	csrr	a0,shint2
+  f8:	5c802573          	csrr	a0,shpminhibit
+  fc:	5c902573          	csrr	a0,shpmcr
+ 100:	5ca02573          	csrr	a0,shpmsr
+ 104:	5cb02573          	csrr	a0,shpmer
+ 108:	5e002573          	csrr	a0,scycle
+ 10c:	5e102573          	csrr	a0,shpmcounter1
+ 110:	5e202573          	csrr	a0,shpmcounter2
+ 114:	5e302573          	csrr	a0,shpmcounter3
+ 118:	5e402573          	csrr	a0,shpmcounter4
+ 11c:	5e502573          	csrr	a0,shpmcounter5
+ 120:	5e602573          	csrr	a0,shpmcounter6
+ 124:	5e702573          	csrr	a0,shpmcounter7
+ 128:	5e802573          	csrr	a0,shpmcounter8
+ 12c:	5e902573          	csrr	a0,shpmcounter9
+ 130:	5ea02573          	csrr	a0,shpmcounter10
+ 134:	5eb02573          	csrr	a0,shpmcounter11
+ 138:	5ec02573          	csrr	a0,shpmcounter12
+ 13c:	5ed02573          	csrr	a0,shpmcounter13
+ 140:	5ee02573          	csrr	a0,shpmcounter14
+ 144:	5ef02573          	csrr	a0,shpmcounter15
+ 148:	5f002573          	csrr	a0,shpmcounter16
+ 14c:	5f102573          	csrr	a0,shpmcounter17
+ 150:	5f202573          	csrr	a0,shpmcounter18
+ 154:	5f302573          	csrr	a0,shpmcounter19
+ 158:	5f402573          	csrr	a0,shpmcounter20
+ 15c:	5f502573          	csrr	a0,shpmcounter21
+ 160:	5f602573          	csrr	a0,shpmcounter22
+ 164:	5f702573          	csrr	a0,shpmcounter23
+ 168:	5f802573          	csrr	a0,shpmcounter24
+ 16c:	5f902573          	csrr	a0,shpmcounter25
+ 170:	5fa02573          	csrr	a0,shpmcounter26
+ 174:	5fb02573          	csrr	a0,shpmcounter27
+ 178:	5fc02573          	csrr	a0,shpmcounter28
+ 17c:	5fd02573          	csrr	a0,shpmcounter29
+ 180:	5fe02573          	csrr	a0,shpmcounter30
+ 184:	5ff02573          	csrr	a0,shpmcounter31
+
diff --git a/gas/testsuite/gas/riscv/extended/thead-csr-list.s b/gas/testsuite/gas/riscv/extended/thead-csr-list.s
new file mode 100644
index 0000000..d6de027
--- /dev/null
+++ b/gas/testsuite/gas/riscv/extended/thead-csr-list.s
@@ -0,0 +1,99 @@
+csrr a0, mxstatus
+csrr a0, mhcr
+csrr a0, mcor
+csrr a0, mccr2
+csrr a0, mcer2
+csrr a0, mhint
+csrr a0, mrmr
+csrr a0, mrvbr
+csrr a0, mcer
+csrr a0, mcounterwen
+csrr a0, mcounterinten
+csrr a0, mcounterof
+csrr a0, mhint2
+csrr a0, mhint3
+csrr a0, mraddr
+csrr a0, mexstatus
+csrr a0, mnmicause
+csrr a0, mnmipc
+csrr a0, mhpmcr
+csrr a0, mhpmsr
+csrr a0, mhpmer
+csrr a0, msmpr
+csrr a0, mteecfg
+csrr a0, usp
+csrr a0, mcins
+csrr a0, mcindex
+csrr a0, mcdata0
+csrr a0, mcdata1
+csrr a0, meicr
+csrr a0, meicr2
+csrr a0, mebr
+csrr a0, nt_mstatus
+csrr a0, nt_mtvec
+csrr a0, nt_mie
+csrr a0, nt_mtvt
+csrr a0, nt_mepc
+csrr a0, nt_mcause
+csrr a0, nt_mip
+csrr a0, nt_mintstate
+csrr a0, nt_mxstatus
+csrr a0, nt_mebr
+csrr a0, nt_msp
+csrr a0, t_usp
+csrr a0, t_mdcr
+csrr a0, t_mpcr
+csrr a0, pmpteecfg
+csrr a0, mcpuid
+csrr a0, mapbaddr
+csrr a0, mwmsr
+csrr a0, fxcr
+csrr a0, smir
+csrr a0, smel
+csrr a0, smeh
+csrr a0, smcir
+csrr a0, sxstatus
+csrr a0, shcr
+csrr a0, scer2
+csrr a0, scer
+csrr a0, scounterinten
+csrr a0, scounterof
+csrr a0, shint
+csrr a0, shint2
+csrr a0, shpminhibit
+csrr a0, shpmcr
+csrr a0, shpmsr
+csrr a0, shpmer
+csrr a0, scycle
+csrr a0, shpmcounter1
+csrr a0, shpmcounter2
+csrr a0, shpmcounter3
+csrr a0, shpmcounter4
+csrr a0, shpmcounter5
+csrr a0, shpmcounter6
+csrr a0, shpmcounter7
+csrr a0, shpmcounter8
+csrr a0, shpmcounter9
+csrr a0, shpmcounter10
+csrr a0, shpmcounter11
+csrr a0, shpmcounter12
+csrr a0, shpmcounter13
+csrr a0, shpmcounter14
+csrr a0, shpmcounter15
+csrr a0, shpmcounter16
+csrr a0, shpmcounter17
+csrr a0, shpmcounter18
+csrr a0, shpmcounter19
+csrr a0, shpmcounter20
+csrr a0, shpmcounter21
+csrr a0, shpmcounter22
+csrr a0, shpmcounter23
+csrr a0, shpmcounter24
+csrr a0, shpmcounter25
+csrr a0, shpmcounter26
+csrr a0, shpmcounter27
+csrr a0, shpmcounter28
+csrr a0, shpmcounter29
+csrr a0, shpmcounter30
+csrr a0, shpmcounter31
+
diff --git a/gas/testsuite/gas/riscv/extended/theadc-ext.d b/gas/testsuite/gas/riscv/extended/theadc-ext.d
new file mode 100644
index 0000000..3ba0f86
--- /dev/null
+++ b/gas/testsuite/gas/riscv/extended/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          	dcache.call
+   8:	0030000b          	dcache.ciall
+   c:	02b5000b          	dcache.cipa	a0
+  10:	0235000b          	dcache.cisw	a0
+  14:	0275000b          	dcache.civa	a0
+  18:	0295000b          	dcache.cpa	a0
+  1c:	0285000b          	dcache.cpal1	a0
+  20:	0255000b          	dcache.cva	a0
+  24:	0245000b          	dcache.cval1	a0
+  28:	02a5000b          	dcache.ipa	a0
+  2c:	0225000b          	dcache.isw	a0
+  30:	0265000b          	dcache.iva	a0
+  34:	0020000b          	dcache.iall
+  38:	0215000b          	dcache.csw	a0
+  3c:	0100000b          	icache.iall
+  40:	0110000b          	icache.ialls
+  44:	0305000b          	icache.iva	a0
+  48:	0385000b          	icache.ipa	a0
+  4c:	0160000b          	l2cache.iall
+  50:	0150000b          	l2cache.call
+  54:	0170000b          	l2cache.ciall
+  58:	04b5000b          	sfence.vmas	a0,a1
+  5c:	0180000b          	sync
+  60:	01a0000b          	sync.i
+  64:	0190000b          	sync.s
+  68:	01b0000b          	sync.is
+  6c:	02c5950b          	addsl	a0,a1,a2,1
+  70:	20c5950b          	mula	a0,a1,a2
+  74:	22c5950b          	muls	a0,a1,a2
+  78:	24c5950b          	mulaw	a0,a1,a2
+  7c:	26c5950b          	mulsw	a0,a1,a2
+  80:	28c5950b          	mulah	a0,a1,a2
+  84:	2ac5950b          	mulsh	a0,a1,a2
+  88:	1105950b          	srri	a0,a1,16
+  8c:	1505950b          	srriw	a0,a1,16
+  90:	40c5950b          	mveqz	a0,a1,a2
+  94:	42c5950b          	mvnez	a0,a1,a2
+  98:	8905950b          	tst	a0,a1,16
+  9c:	8005950b          	tstnbz	a0,a1
+  a0:	4105a50b          	ext	a0,a1,16,16
+  a4:	4105b50b          	extu	a0,a1,16,16
+  a8:	8605950b          	ff1	a0,a1
+  ac:	8405950b          	ff0	a0,a1
+  b0:	8205950b          	rev	a0,a1
+  b4:	9005950b          	revw	a0,a1
+  b8:	62b5600b          	flrd	ft0,a0,a1,1
+  bc:	42b5600b          	flrw	ft0,a0,a1,1
+  c0:	72b5600b          	flurd	ft0,a0,a1,1
+  c4:	52b5600b          	flurw	ft0,a0,a1,1
+  c8:	02c5c50b          	lrb	a0,a1,a2,1
+  cc:	22c5c50b          	lrh	a0,a1,a2,1
+  d0:	42c5c50b          	lrw	a0,a1,a2,1
+  d4:	62c5c50b          	lrd	a0,a1,a2,1
+  d8:	82c5c50b          	lrbu	a0,a1,a2,1
+  dc:	a2c5c50b          	lrhu	a0,a1,a2,1
+  e0:	c2c5c50b          	lrwu	a0,a1,a2,1
+  e4:	12c5c50b          	lurb	a0,a1,a2,1
+  e8:	32c5c50b          	lurh	a0,a1,a2,1
+  ec:	52c5c50b          	lurw	a0,a1,a2,1
+  f0:	72c5c50b          	lurd	a0,a1,a2,1
+  f4:	92c5c50b          	lurbu	a0,a1,a2,1
+  f8:	b2c5c50b          	lurhu	a0,a1,a2,1
+  fc:	d2c5c50b          	lurwu	a0,a1,a2,1
+ 100:	1af5c50b          	lbia	a0,\(a1\),15,1
+ 104:	0af5c50b          	lbib	a0,\(a1\),15,1
+ 108:	3af5c50b          	lhia	a0,\(a1\),15,1
+ 10c:	2af5c50b          	lhib	a0,\(a1\),15,1
+ 110:	5af5c50b          	lwia	a0,\(a1\),15,1
+ 114:	4af5c50b          	lwib	a0,\(a1\),15,1
+ 118:	7af5c50b          	ldia	a0,\(a1\),15,1
+ 11c:	6af5c50b          	ldib	a0,\(a1\),15,1
+ 120:	9af5c50b          	lbuia	a0,\(a1\),15,1
+ 124:	8af5c50b          	lbuib	a0,\(a1\),15,1
+ 128:	baf5c50b          	lhuia	a0,\(a1\),15,1
+ 12c:	aaf5c50b          	lhuib	a0,\(a1\),15,1
+ 130:	daf5c50b          	lwuia	a0,\(a1\),15,1
+ 134:	caf5c50b          	lwuib	a0,\(a1\),15,1
+ 138:	fab6450b          	ldd	a0,a1,\(a2\),1
+ 13c:	e2b6450b          	lwd	a0,a1,\(a2\),1
+ 140:	f2b6450b          	lwud	a0,a1,\(a2\),1
+ 144:	62b5700b          	fsrd	ft0,a0,a1,1
+ 148:	42b5700b          	fsrw	ft0,a0,a1,1
+ 14c:	72b5700b          	fsurd	ft0,a0,a1,1
+ 150:	52b5700b          	fsurw	ft0,a0,a1,1
+ 154:	02c5d50b          	srb	a0,a1,a2,1
+ 158:	22c5d50b          	srh	a0,a1,a2,1
+ 15c:	42c5d50b          	srw	a0,a1,a2,1
+ 160:	62c5d50b          	srd	a0,a1,a2,1
+ 164:	12c5d50b          	surb	a0,a1,a2,1
+ 168:	32c5d50b          	surh	a0,a1,a2,1
+ 16c:	52c5d50b          	surw	a0,a1,a2,1
+ 170:	72c5d50b          	surd	a0,a1,a2,1
+ 174:	1af5d50b          	sbia	a0,\(a1\),15,1
+ 178:	0af5d50b          	sbib	a0,\(a1\),15,1
+ 17c:	3af5d50b          	shia	a0,\(a1\),15,1
+ 180:	2af5d50b          	shib	a0,\(a1\),15,1
+ 184:	5ac5d50b          	swia	a0,\(a1\),12,1
+ 188:	4af5d50b          	swib	a0,\(a1\),15,1
+ 18c:	7af5d50b          	sdia	a0,\(a1\),15,1
+ 190:	6af5d50b          	sdib	a0,\(a1\),15,1
+ 194:	fab6550b          	sdd	a0,a1,\(a2\),1
+ 198:	e2b6550b          	swd	a0,a1,\(a2\),1
diff --git a/gas/testsuite/gas/riscv/extended/theadc-ext.s b/gas/testsuite/gas/riscv/extended/theadc-ext.s
new file mode 100644
index 0000000..b7a1a7a
--- /dev/null
+++ b/gas/testsuite/gas/riscv/extended/theadc-ext.s
@@ -0,0 +1,116 @@
+.text
+
+wsc
+
+# cache ext
+dcache.call
+dcache.ciall
+dcache.cipa a0
+dcache.cisw a0
+dcache.civa a0
+dcache.cpa a0
+dcache.cpal1 a0
+dcache.cva a0
+dcache.cval1 a0
+dcache.ipa a0
+dcache.isw a0
+dcache.iva a0
+dcache.iall
+dcache.csw a0
+icache.iall
+icache.ialls
+icache.iva a0
+icache.ipa a0
+l2cache.iall
+l2cache.call
+l2cache.ciall
+
+# sync ext
+sfence.vmas       a0, a1
+sync
+sync.i
+sync.s
+sync.is
+
+# calc ext
+addsl             a0, a1, a2, 1
+mula              a0, a1, a2
+muls              a0, a1, a2
+mulaw             a0, a1, a2
+mulsw             a0, a1, a2
+mulah             a0, a1, a2
+mulsh             a0, a1, a2
+srri              a0, a1, 16
+srriw             a0, a1, 16
+mveqz             a0, a1, a2
+mvnez             a0, a1, a2
+
+# bit ext
+tst               a0, a1, 16
+tstnbz            a0, a1
+ext               a0, a1, 16, 16
+extu              a0, a1, 16, 16
+ff1               a0, a1
+ff0               a0, a1
+rev               a0, a1
+revw       a0, a1
+
+# load/store ext
+flrd       f0, a0, a1, 1
+flrw       f0, a0, a1, 1
+flurd      f0, a0, a1, 1
+flurw      f0, a0, a1, 1
+lrb               a0, a1, a2, 1
+lrh               a0, a1, a2, 1
+lrw               a0, a1, a2, 1
+lrd               a0, a1, a2, 1
+lrbu              a0, a1, a2, 1
+lrhu              a0, a1, a2, 1
+lrwu              a0, a1, a2, 1
+lurb              a0, a1, a2, 1
+lurh              a0, a1, a2, 1
+lurw              a0, a1, a2, 1
+lurd              a0, a1, a2, 1
+lurbu             a0, a1, a2, 1
+lurhu             a0, a1, a2, 1
+lurwu             a0, a1, a2, 1
+lbia       a0, (a1), 15, 1
+lbib       a0, (a1), 15, 1
+lhia       a0, (a1), 15, 1
+lhib       a0, (a1), 15, 1
+lwia       a0, (a1), 15, 1
+lwib       a0, (a1), 15, 1
+ldia       a0, (a1), 15, 1
+ldib       a0, (a1), 15, 1
+lbuia      a0, (a1), 15, 1
+lbuib      a0, (a1), 15, 1
+lhuia      a0, (a1), 15, 1
+lhuib      a0, (a1), 15, 1
+lwuia      a0, (a1), 15, 1
+lwuib      a0, (a1), 15, 1
+ldd               a0, a1, (a2), 1
+lwd               a0, a1, (a2), 1
+lwud              a0, a1, (a2), 1
+fsrd       f0, a0, a1, 1
+fsrw       f0, a0, a1, 1
+fsurd      f0, a0, a1, 1
+fsurw      f0, a0, a1, 1
+srb               a0, a1, a2, 1
+srh               a0, a1, a2, 1
+srw               a0, a1, a2, 1
+srd               a0, a1, a2, 1
+surb              a0, a1, a2, 1
+surh              a0, a1, a2, 1
+surw              a0, a1, a2, 1
+surd              a0, a1, a2, 1
+sbia              a0, (a1), 15, 1
+sbib              a0, (a1), 15, 1
+shia              a0, (a1), 15, 1
+shib              a0, (a1), 15, 1
+swia              a0, (a1), 12, 1
+swib              a0, (a1), 15, 1
+sdia              a0, (a1), 15, 1
+sdib              a0, (a1), 15, 1
+sdd               a0, a1, (a2), 1
+swd               a0, a1, (a2), 1
+
diff --git a/gas/testsuite/gas/riscv/extended/theade-ext.d b/gas/testsuite/gas/riscv/extended/theade-ext.d
new file mode 100644
index 0000000..6f9cb52
--- /dev/null
+++ b/gas/testsuite/gas/riscv/extended/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          	dcache.ipa	a0
+[       ]+[0-9a-f]+:\s+0295000b          	dcache.cpa	a0
+[       ]+[0-9a-f]+:\s+02b5000b          	dcache.cipa	a0
+[       ]+[0-9a-f]+:\s+0225000b          	dcache.isw	a0
+[       ]+[0-9a-f]+:\s+0215000b          	dcache.csw	a0
+[       ]+[0-9a-f]+:\s+0235000b          	dcache.cisw	a0
+[       ]+[0-9a-f]+:\s+0020000b          	dcache.iall
+[       ]+[0-9a-f]+:\s+0010000b          	dcache.call
+[       ]+[0-9a-f]+:\s+0030000b          	dcache.ciall
+[       ]+[0-9a-f]+:\s+0100000b          	icache.iall
+[       ]+[0-9a-f]+:\s+0385000b          	icache.ipa	a0
+[       ]+[0-9a-f]+:\s+0180000b          	sync
+[       ]+[0-9a-f]+:\s+01a0000b          	sync.i
+[       ]+[0-9a-f]+:\s+02c5950b          	addsl	a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+1105950b          	srri	a0,a1,16
+[       ]+[0-9a-f]+:\s+20c5950b          	mula	a0,a1,a2
+[       ]+[0-9a-f]+:\s+28c5950b          	mulah	a0,a1,a2
+[       ]+[0-9a-f]+:\s+22c5950b          	muls	a0,a1,a2
+[       ]+[0-9a-f]+:\s+2ac5950b          	mulsh	a0,a1,a2
+[       ]+[0-9a-f]+:\s+40c5950b          	mveqz	a0,a1,a2
+[       ]+[0-9a-f]+:\s+42c5950b          	mvnez	a0,a1,a2
+[       ]+[0-9a-f]+:\s+4105a50b          	ext	a0,a1,16,16
+[       ]+[0-9a-f]+:\s+4105b50b          	extu	a0,a1,16,16
+[       ]+[0-9a-f]+:\s+8605950b          	ff1	a0,a1
+[       ]+[0-9a-f]+:\s+8405950b          	ff0	a0,a1
+[       ]+[0-9a-f]+:\s+8205950b          	rev	a0,a1
+[       ]+[0-9a-f]+:\s+8905950b          	tst	a0,a1,16
+[       ]+[0-9a-f]+:\s+8005950b          	tstnbz	a0,a1
+[       ]+[0-9a-f]+:\s+02c5c50b          	lrb	a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+22c5c50b          	lrh	a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+42c5c50b          	lrw	a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+82c5c50b          	lrbu	a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+a2c5c50b          	lrhu	a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+1af5c50b          	lbia	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+0af5c50b          	lbib	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+3af5c50b          	lhia	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+2af5c50b          	lhib	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+5af5c50b          	lwia	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+4af5c50b          	lwib	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+02c5d50b          	srb	a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+22c5d50b          	srh	a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+42c5d50b          	srw	a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+1af5d50b          	sbia	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+0af5d50b          	sbib	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+3af5d50b          	shia	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+2af5d50b          	shib	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+5ac5d50b          	swia	a0,\(a1\),12,1
+[       ]+[0-9a-f]+:\s+4af5d50b          	swib	a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+c000150b          	fmv.x.hw	a0,ft0
+[       ]+[0-9a-f]+:\s+a005100b          	fmv.hw.x	ft0,a0
+[       ]+[0-9a-f]+:\s+0040000b          	ipush
+[       ]+[0-9a-f]+:\s+0050000b          	ipop
diff --git a/gas/testsuite/gas/riscv/extended/theade-ext.s b/gas/testsuite/gas/riscv/extended/theade-ext.s
new file mode 100644
index 0000000..5c93e04
--- /dev/null
+++ b/gas/testsuite/gas/riscv/extended/theade-ext.s
@@ -0,0 +1,67 @@
+.text
+
+wsc
+
+# cache ext
+dcache.ipa a0
+dcache.cpa a0
+dcache.cipa a0
+dcache.isw a0
+dcache.csw a0
+dcache.cisw a0
+dcache.iall
+dcache.call
+dcache.ciall
+icache.iall
+icache.ipa a0
+
+# sync ext
+sync
+sync.i
+
+# calc ext
+addsl             a0, a1, a2, 1
+srri              a0, a1, 16
+mula              a0, a1, a2
+mulah             a0, a1, a2
+muls              a0, a1, a2
+mulsh             a0, a1, a2
+mveqz             a0, a1, a2
+mvnez             a0, a1, a2
+
+# bit ext
+ext               a0, a1, 16, 16
+extu              a0, a1, 16, 16
+ff1               a0, a1
+ff0               a0, a1
+rev               a0, a1
+tst               a0, a1, 16
+tstnbz            a0, a1
+
+# load/store ext
+lrb               a0, a1, a2, 1
+lrh               a0, a1, a2, 1
+lrw               a0, a1, a2, 1
+lrbu              a0, a1, a2, 1
+lrhu              a0, a1, a2, 1
+lbia       a0, (a1), 15, 1
+lbib       a0, (a1), 15, 1
+lhia       a0, (a1), 15, 1
+lhib       a0, (a1), 15, 1
+lwia       a0, (a1), 15, 1
+lwib       a0, (a1), 15, 1
+srb               a0, a1, a2, 1
+srh               a0, a1, a2, 1
+srw               a0, a1, a2, 1
+sbia              a0, (a1), 15, 1
+sbib              a0, (a1), 15, 1
+shia              a0, (a1), 15, 1
+shib              a0, (a1), 15, 1
+swia              a0, (a1), 12, 1
+swib              a0, (a1), 15, 1
+
+fmv.x.hw   a0, f0
+fmv.hw.x   f0, a0
+ipush
+ipop
+
diff --git a/include/opcode/riscv-opc-extended.h b/include/opcode/riscv-opc-extended.h
index 6f664ed..2d283ca 100644
--- a/include/opcode/riscv-opc-extended.h
+++ b/include/opcode/riscv-opc-extended.h
@@ -1520,3 +1520,575 @@ DECLARE_CSR(vl, CSR_VL, CSR_CLASS_V, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
 DECLARE_CSR(vtype, CSR_VTYPE, CSR_CLASS_V, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
 DECLARE_CSR(vlenb, CSR_VLENB, CSR_CLASS_V, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
 #endif /* DECLARE_CSR */
+
+
+#ifndef __RISCV_OPC_VENDOR_THEAD__
+#define __RISCV_OPC_VENDOR_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
+
+/* T-HEAD M mode CSR.  */
+#define CSR_MXSTATUS 0x7c0
+#define CSR_MHCR 0x7c1
+#define CSR_MCOR 0x7c2
+#define CSR_MCCR2 0x7c3
+#define CSR_MCER2 0x7c4
+#define CSR_MHINT 0x7c5
+#define CSR_MRMR 0x7c6
+#define CSR_MRVBR 0x7c7
+#define CSR_MCER 0x7c8
+#define CSR_MCOUNTERWEN 0x7c9
+#define CSR_MCOUNTERINTEN 0x7ca
+#define CSR_MCOUNTEROF 0x7cb
+#define CSR_MHINT2 0x7cc
+#define CSR_MHINT3 0x7cd
+#define CSR_MRADDR 0x7e0
+#define CSR_MEXSTATUS 0x7e1
+#define CSR_MNMICAUSE 0x7e2
+#define CSR_MNMIPC 0x7e3
+#define CSR_MHPMCR 0x7f0
+#define CSR_MHPMSR 0x7f1
+#define CSR_MHPMER 0x7f2
+#define CSR_MSMPR 0x7f3
+#define CSR_MTEECFG 0x7f4
+#define CSR_MZONEID 0x7f5
+#define CSR_ML2CPID 0x7f6
+#define CSR_ML2WP 0x7f7
+#define CSR_MDTCMCR 0x7f8
+#define CSR_USP 0x7d1
+#define CSR_MCINS 0x7d2
+#define CSR_MCINDEX 0x7d3
+#define CSR_MCDATA0 0x7d4
+#define CSR_MCDATA1 0x7d5
+#define CSR_MEICR 0x7d6
+#define CSR_MEICR2 0x7d7
+#define CSR_MBEADDR 0x7d8
+#define CSR_MCPUID 0xfc0
+#define CSR_MAPBADDR 0xfc1
+#define CSR_MWMSR 0xfc2
+#define CSR_MHALTCAUSE 0xfe0
+#define CSR_MDBGINFO 0xfe1
+#define CSR_MPCFIFO 0xfe2
+
+
+/* T-HEAD S mode CSR.  */
+#define CSR_SXSTATUS 0x5c0
+#define CSR_SHCR 0x5c1
+#define CSR_SCER2 0x5c2
+#define CSR_SCER 0x5c3
+#define CSR_SCOUNTERINTEN 0x5c4
+#define CSR_SCOUNTEROF 0x5c5
+#define CSR_SHINT 0x5c6
+#define CSR_SHINT2 0x5c7
+#define CSR_SHPMINHIBIT 0x5c8
+#define CSR_SHPMCR 0x5c9
+#define CSR_SHPMSR 0x5ca
+#define CSR_SHPMER 0x5cb
+#define CSR_SL2CPID 0x5cc
+#define CSR_SL2WP 0x5cd
+#define CSR_SBEADDR 0x5d0
+#define CSR_SCYCLE 0x5e0
+#define CSR_SHPMCOUNTER1 0x5e1
+#define CSR_SHPMCOUNTER2 0x5e2
+#define CSR_SHPMCOUNTER3 0x5e3
+#define CSR_SHPMCOUNTER4 0x5e4
+#define CSR_SHPMCOUNTER5 0x5e5
+#define CSR_SHPMCOUNTER6 0x5e6
+#define CSR_SHPMCOUNTER7 0x5e7
+#define CSR_SHPMCOUNTER8 0x5e8
+#define CSR_SHPMCOUNTER9 0x5e9
+#define CSR_SHPMCOUNTER10 0x5ea
+#define CSR_SHPMCOUNTER11 0x5eb
+#define CSR_SHPMCOUNTER12 0x5ec
+#define CSR_SHPMCOUNTER13 0x5ed
+#define CSR_SHPMCOUNTER14 0x5ee
+#define CSR_SHPMCOUNTER15 0x5ef
+#define CSR_SHPMCOUNTER16 0x5f0
+#define CSR_SHPMCOUNTER17 0x5f1
+#define CSR_SHPMCOUNTER18 0x5f2
+#define CSR_SHPMCOUNTER19 0x5f3
+#define CSR_SHPMCOUNTER20 0x5f4
+#define CSR_SHPMCOUNTER21 0x5f5
+#define CSR_SHPMCOUNTER22 0x5f6
+#define CSR_SHPMCOUNTER23 0x5f7
+#define CSR_SHPMCOUNTER24 0x5f8
+#define CSR_SHPMCOUNTER25 0x5f9
+#define CSR_SHPMCOUNTER26 0x5fa
+#define CSR_SHPMCOUNTER27 0x5fb
+#define CSR_SHPMCOUNTER28 0x5fc
+#define CSR_SHPMCOUNTER29 0x5fd
+#define CSR_SHPMCOUNTER30 0x5fe
+#define CSR_SHPMCOUNTER31 0x5ff
+
+/* T-HEAD U mode CSR.  */
+#define CSR_FXCR 0x800
+
+/* T-HEAD MMU extentions.  */
+#define CSR_SMIR 0x9c0
+#define CSR_SMEL 0x9c1
+#define CSR_SMEH 0x9c2
+#define CSR_SMCIR 0x9c3
+
+/* T-HEAD Security CSR(May be droped).  */
+#define CSR_MEBR 0xbe0
+#define CSR_NT_MSTATUS 0xbe1
+#define CSR_NT_MIE 0xbe2
+#define CSR_NT_MTVEC 0xbe3
+#define CSR_NT_MTVT 0xbe4
+#define CSR_NT_MEPC 0xbe5
+#define CSR_NT_MCAUSE 0xbe6
+#define CSR_NT_MIP 0xbe7
+#define CSR_NT_MINTSTATE 0xbe8
+#define CSR_NT_MXSTATUS 0xbe9
+#define CSR_NT_MEBR 0xbea
+#define CSR_NT_MSP 0xbeb
+#define CSR_T_USP 0xbec
+#define CSR_T_MDCR 0xbed
+#define CSR_T_MPCR 0xbee
+#define CSR_PMPTEECFG 0xbef
+#endif
+
+#ifdef DECLARE_INSN
+DECLARE_INSN(wsc, MATCH_WSC, MASK_WSC)
+DECLARE_INSN(dcache.iall, MATCH_DCACHE_IALL, MASK_DCACHE_IALL)
+DECLARE_INSN(dcache.call, MATCH_DCACHE_CALL, MASK_DCACHE_CALL)
+DECLARE_INSN(dcache.ciall, MATCH_DCACHE_CIALL, MASK_DCACHE_CIALL)
+DECLARE_INSN(dcache.isw, MATCH_DCACHE_ISW, MASK_DCACHE_ISW, match_opcode, 0)
+DECLARE_INSN(dcache.csw, MATCH_DCACHE_CSW, MASK_DCACHE_CSW)
+DECLARE_INSN(dcache.cisw, MATCH_DCACHE_CISW, MASK_DCACHE_CISW)
+DECLARE_INSN(dcache.iva, MATCH_DCACHE_IVA, MASK_DCACHE_IVA)
+DECLARE_INSN(dcache.cva, MATCH_DCACHE_CVA, MASK_DCACHE_CVA)
+DECLARE_INSN(dcache.cval1, MATCH_DCACHE_CVAL1, MASK_DCACHE_CVAL1)
+DECLARE_INSN(dcache.civa, MATCH_DCACHE_CIVA, MASK_DCACHE_CIVA)
+DECLARE_INSN(dcache.ipa, MATCH_DCACHE_IPA, MASK_DCACHE_IPA)
+DECLARE_INSN(dcache.cpa, MATCH_DCACHE_CPA, MASK_DCACHE_CPA)
+DECLARE_INSN(dcache.cpal1, MATCH_DCACHE_CPAL1, MASK_DCACHE_CPAL1)
+DECLARE_INSN(dcache.cipa, MATCH_DCACHE_CIPA, MASK_DCACHE_CIPA)
+DECLARE_INSN(icache.iall, MATCH_ICACHE_IALL, MASK_ICACHE_IALL)
+DECLARE_INSN(icache.iall, MATCH_ICACHE_IALL, MASK_ICACHE_IALL, match_opcode)
+DECLARE_INSN(icache.ialls, MATCH_ICACHE_IALLS, MASK_ICACHE_IALLS)
+DECLARE_INSN(icache.iva, MATCH_ICACHE_IVA, MASK_ICACHE_IVA)
+DECLARE_INSN(icache.ipa, MATCH_ICACHE_IPA, MASK_ICACHE_IPA)
+DECLARE_INSN(l2cache.iall, MATCH_L2CACHE_IALL, MASK_L2CACHE_IALL)
+DECLARE_INSN(l2cache.call, MATCH_L2CACHE_CALL, MASK_L2CACHE_CALL)
+DECLARE_INSN(l2cache.ciall, MATCH_L2CACHE_CIALL, MASK_L2CACHE_CIALL)
+DECLARE_INSN(sync, MATCH_SYNC, MASK_SYNC)
+DECLARE_INSN(sync.i, MATCH_SYNC_I, MASK_SYNC_I)
+DECLARE_INSN(sync.s, MATCH_SYNC_S, MASK_SYNC_S)
+DECLARE_INSN(sync.is, MATCH_SYNC_IS, MASK_SYNC_IS)
+DECLARE_INSN(tstnbz, MATCH_TSTNBZ, MASK_TSTNBZ)
+DECLARE_INSN(mula, MATCH_MULA, MASK_MULA)
+DECLARE_INSN(muls, MATCH_MULS, MASK_MULS)
+DECLARE_INSN(mulah, MATCH_MULAH, MASK_MULAH)
+DECLARE_INSN(mulsh, MATCH_MULSH, MASK_MULSH)
+DECLARE_INSN(sfence.vmas, MATCH_SFENCE_VMAS, MASK_SFENCE_VMAS)
+DECLARE_INSN(mveqz, MATCH_MVEQZ, MASK_MVEQZ)
+DECLARE_INSN(mvnez, MATCH_MVNEZ, MASK_MVNEZ)
+DECLARE_INSN(mulaw, MATCH_MULAW, MASK_MULAW)
+DECLARE_INSN(mulsw, MATCH_MULSW, MASK_MULSW)
+DECLARE_INSN(ext, MATCH_EXT, MASK_EXT)
+DECLARE_INSN(ext, MATCH_EXT, (MASK_EXT | (1U<<25) | (1U<<31)))
+DECLARE_INSN(extu, MATCH_EXTU, MASK_EXTU)
+DECLARE_INSN(extu, MATCH_EXTU, (MASK_EXTU | (1U<<25) | (1U<<31)))
+DECLARE_INSN(ff1, MATCH_FF1, MASK_FF1)
+DECLARE_INSN(ff0, MATCH_FF0, MASK_FF1)
+DECLARE_INSN(rev, MATCH_REV, MASK_REV)
+DECLARE_INSN(lrb, MATCH_LRB, MASK_LRB)
+DECLARE_INSN(lrbu, MATCH_LRBU, MASK_LRBU)
+DECLARE_INSN(lrh, MATCH_LRH, MASK_LRH)
+DECLARE_INSN(lrhu, MATCH_LRHU, MASK_LRHU)
+DECLARE_INSN(lrw, MATCH_LRW, MASK_LRW)
+DECLARE_INSN(lrwu, MATCH_LRWU, MASK_LRWU)
+DECLARE_INSN(srb, MATCH_SRB, MASK_SRB)
+DECLARE_INSN(srh, MATCH_SRH, MASK_SRH)
+DECLARE_INSN(srw, MATCH_SRW, MASK_SRW)
+DECLARE_INSN(lrd, MATCH_LRD, MASK_LRD)
+DECLARE_INSN(srd, MATCH_SRD, MASK_SRD)
+DECLARE_INSN(lurb, MATCH_LURB, MASK_LURB)
+DECLARE_INSN(lurbu, MATCH_LURBU, MASK_LURBU)
+DECLARE_INSN(lurh, MATCH_LURH, MASK_LURH)
+DECLARE_INSN(lurhu, MATCH_LURHU, MASK_LURHU)
+DECLARE_INSN(lurw, MATCH_LURW, MASK_LURW)
+DECLARE_INSN(lurwu, MATCH_LURWU, MASK_LURWU)
+DECLARE_INSN(lurd, MATCH_LURD, MASK_LURD)
+DECLARE_INSN(surb, MATCH_SURB, MASK_SURB)
+DECLARE_INSN(surh, MATCH_SURH, MASK_SURH)
+DECLARE_INSN(surw, MATCH_SURW, MASK_SURW)
+DECLARE_INSN(surd, MATCH_SURD, MASK_SURD)
+DECLARE_INSN(tst, MATCH_TST, MASK_TST)
+DECLARE_INSN(tst, MATCH_TST, (MASK_TST | (1U << 25)), match_opcode)
+DECLARE_INSN(srriw, MATCH_SRRIW, MASK_SRRIW)
+DECLARE_INSN(srri, MATCH_SRRI, MASK_SRRI)
+DECLARE_INSN(addsl, MATCH_ADDSL, MASK_ADDSL)
+DECLARE_INSN(lwd, MATCH_LWD, MASK_LWD)
+DECLARE_INSN(ldd, MATCH_LDD, MASK_LDD)
+DECLARE_INSN(swd, MATCH_SWD, MASK_SWD)
+DECLARE_INSN(sdd, MATCH_SDD, MASK_SDD)
+DECLARE_INSN(sdia, MATCH_SDIA, MASK_SDIA)
+DECLARE_INSN(sdib, MATCH_SDIB, MASK_SDIB)
+DECLARE_INSN(lwud, MATCH_LWUD, MASK_LWUD)
+DECLARE_INSN(lwud, MATCH_LWUD, MASK_LWUD)
+DECLARE_INSN(swia, MATCH_SWIA, MASK_SWIA)
+DECLARE_INSN(swib, MATCH_SWIB, MASK_SWIB)
+DECLARE_INSN(shia, MATCH_SHIA, MASK_SHIA)
+DECLARE_INSN(shib, MATCH_SHIB, MASK_SHIB)
+DECLARE_INSN(sbia, MATCH_SBIA, MASK_SBIA)
+DECLARE_INSN(sbib, MATCH_SBIB, MASK_SBIB)
+DECLARE_INSN(lwuia, MATCH_LWUIA, MASK_LWUIA)
+DECLARE_INSN(lwuib, MATCH_LWUIB, MASK_LWUIB)
+DECLARE_INSN(lhuia, MATCH_LHUIA, MASK_LHUIA)
+DECLARE_INSN(lhuib, MATCH_LHUIB, MASK_LHUIB)
+DECLARE_INSN(lbuia, MATCH_LBUIA, MASK_LBUIA)
+DECLARE_INSN(lbuib, MATCH_LBUIB, MASK_LBUIB)
+DECLARE_INSN(ldia, MATCH_LDIA, MASK_LDIA)
+DECLARE_INSN(ldib, MATCH_LDIB, MASK_LDIB)
+DECLARE_INSN(lwia, MATCH_LWIA, MASK_LWIA)
+DECLARE_INSN(lwib, MATCH_LWIB, MASK_LWIB)
+DECLARE_INSN(lhia, MATCH_LHIA, MASK_LHIA)
+DECLARE_INSN(lhib, MATCH_LHIB, MASK_LHIB)
+DECLARE_INSN(lbia, MATCH_LBIA, MASK_LBIA)
+DECLARE_INSN(lbib, MATCH_LBIB, MASK_LBIB)
+DECLARE_INSN(fsurd, MATCH_FSURD, MASK_FSURD)
+DECLARE_INSN(revw, MATCH_REVW, MASK_REVW)
+DECLARE_INSN(fsurw, MATCH_FSURW, MASK_FSURW)
+DECLARE_INSN(flurd, MATCH_FLURD, MASK_FLURD)
+DECLARE_INSN(flurw, MATCH_FLURW, MASK_FLURW)
+DECLARE_INSN(fsrd, MATCH_FSRD, MASK_FSRD)
+DECLARE_INSN(fsrw, MATCH_FSRW, MASK_FSRW)
+DECLARE_INSN(flrd, MATCH_FLRD, MASK_FLRD)
+DECLARE_INSN(flrw, MATCH_FLRW, MASK_FLRW)
+DECLARE_INSN(ipush, MATCH_IPUSH, MASK_IPUSH)
+DECLARE_INSN(ipop, MATCH_IPOP, MASK_IPOP)
+DECLARE_INSN(fmv.x.hw, MATCH_FMV_X_HW, MASK_FMV_X_HW)
+DECLARE_INSN(fmv.hw.x, MATCH_FMV_HW_X, MASK_FMV_HW_X)
+#endif /* DECLARE_INSN */
+
+#ifdef DECLARE_CSR
+/* T-HEAD extentions.  */
+DECLARE_CSR(mxstatus, CSR_MXSTATUS, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mhcr, CSR_MHCR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcor, CSR_MCOR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mccr2, CSR_MCCR2, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcer2, CSR_MCER2, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mhint, CSR_MHINT, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mrmr, CSR_MRMR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mrvbr, CSR_MRVBR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcer, CSR_MCER, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcounterwen, CSR_MCOUNTERWEN, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcounterinten, CSR_MCOUNTERINTEN, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcounterof, CSR_MCOUNTEROF, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mhint2, CSR_MHINT2, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mhint3, CSR_MHINT3, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mraddr, CSR_MRADDR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mexstatus, CSR_MEXSTATUS, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mnmicause, CSR_MNMICAUSE, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mnmipc, CSR_MNMIPC, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mhpmcr, CSR_MHPMCR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mhpmsr, CSR_MHPMSR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mhpmer, CSR_MHPMER, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(msmpr, CSR_MSMPR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mteecfg, CSR_MTEECFG, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mzoneid, CSR_MZONEID, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(ml2cpid, CSR_ML2CPID, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(ml2wp, CSR_ML2WP, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mdtcmcr, CSR_MDTCMCR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(usp, CSR_USP, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcins, CSR_MCINS, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcindex, CSR_MCINDEX, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcdata0, CSR_MCDATA0, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcdata1, CSR_MCDATA1, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(meicr, CSR_MEICR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(meicr2, CSR_MEICR2, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mbeaddr, CSR_MBEADDR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mebr, CSR_MEBR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_mstatus, CSR_NT_MSTATUS, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_mtvec, CSR_NT_MTVEC, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_mie, CSR_NT_MIE, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_mtvt, CSR_NT_MTVT, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_mepc, CSR_NT_MEPC, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_mcause, CSR_NT_MCAUSE, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_mip, CSR_NT_MIP, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_mintstate, CSR_NT_MINTSTATE, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_mxstatus, CSR_NT_MXSTATUS, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_mebr, CSR_NT_MEBR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_msp, CSR_NT_MSP, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(t_usp, CSR_T_USP, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(t_mdcr, CSR_T_MDCR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(t_mpcr, CSR_T_MPCR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(pmpteecfg, CSR_PMPTEECFG, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcpuid, CSR_MCPUID, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mapbaddr, CSR_MAPBADDR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mwmsr, CSR_MWMSR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(fxcr, CSR_FXCR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(smir, CSR_SMIR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(smel, CSR_SMEL, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(smeh, CSR_SMEH, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(smcir, CSR_SMCIR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(sxstatus, CSR_SXSTATUS, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shcr, CSR_SHCR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(scer2, CSR_SCER2, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(scer, CSR_SCER, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(scounterinten , CSR_SCOUNTERINTEN, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(scounterof, CSR_SCOUNTEROF, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shint, CSR_SHINT, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shint2, CSR_SHINT2, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpminhibit, CSR_SHPMINHIBIT, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcr, CSR_SHPMCR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmsr, CSR_SHPMSR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmer, CSR_SHPMER, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(sl2cpid, CSR_SL2CPID, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(sl2wp, CSR_SL2WP, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(sbeaddr, CSR_SBEADDR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(scycle, CSR_SCYCLE, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter1, CSR_SHPMCOUNTER1, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter2, CSR_SHPMCOUNTER2, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter3, CSR_SHPMCOUNTER3, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter4, CSR_SHPMCOUNTER4, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter5, CSR_SHPMCOUNTER5, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter6, CSR_SHPMCOUNTER6, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter7, CSR_SHPMCOUNTER7, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter8, CSR_SHPMCOUNTER8, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter9, CSR_SHPMCOUNTER9, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter10, CSR_SHPMCOUNTER10, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter11, CSR_SHPMCOUNTER11, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter12, CSR_SHPMCOUNTER12, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter13, CSR_SHPMCOUNTER13, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter14, CSR_SHPMCOUNTER14, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter15, CSR_SHPMCOUNTER15, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter16, CSR_SHPMCOUNTER16, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter17, CSR_SHPMCOUNTER17, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter18, CSR_SHPMCOUNTER18, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter19, CSR_SHPMCOUNTER19, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter20, CSR_SHPMCOUNTER20, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter21, CSR_SHPMCOUNTER21, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter22, CSR_SHPMCOUNTER22, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter23, CSR_SHPMCOUNTER23, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter24, CSR_SHPMCOUNTER24, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter25, CSR_SHPMCOUNTER25, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter26, CSR_SHPMCOUNTER26, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter27, CSR_SHPMCOUNTER27, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter28, CSR_SHPMCOUNTER28, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter29, CSR_SHPMCOUNTER29, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter30, CSR_SHPMCOUNTER30, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter31, CSR_SHPMCOUNTER31, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+#endif
+
+
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index 8d5251c..2719393 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -496,6 +496,13 @@ enum riscv_extended_insn_class
   INSN_CLASS_D_AND_ZFH,
   INSN_CLASS_Q_AND_ZFH,
   INSN_CLASS_SVINVAL,
+
+  /* INSN class for THEAD.  */
+  INSN_CLASS_THEADC,
+  INSN_CLASS_THEADC_OR_THEADE,
+  INSN_CLASS_THEADC_OR_THEADE_OR_THEADSE,
+  INSN_CLASS_THEADE,
+  INSN_CLASS_THEADSE,
 };
 
 /* This is a list of macro expanded instructions for extended
@@ -518,4 +525,21 @@ extern const char * const riscv_vma[2];
 
 extern const struct riscv_opcode *riscv_extended_opcodes[];
 
+/* 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 dcc5a09..33aff18 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -255,6 +255,51 @@ print_extended_insn_args (const char **opcode_args,
 	}
       break;
 
+    case 'X':
+	{
+	  int nbit = 0;
+	  int at = -1;
+	  char c = 0;
+	  int shift = 0;
+	  oparg++;
+	  c = *oparg++;
+	  switch (c)
+	    {
+	    case 'I':
+	      nbit = strtol (oparg, (char **)&oparg, 10);
+	      if ((*oparg) =='@')
+		at = strtol(++oparg, (char **)&oparg, 10);
+
+	      oparg--;
+
+	      print (info->stream, "%d", (unsigned int)(EXTRACT_VENDOR_THEAD_IMM(l, nbit, at) << shift));
+	      break;
+	    case 'S':
+	      nbit = strtol (oparg, (char **)&oparg, 10);
+	      if ((*oparg) =='<' && (*(oparg + 1) == '<'))
+		{
+		  oparg += 2;
+		  shift = strtol (oparg, (char **)&oparg, 10);
+		}
+	      if ((*oparg) =='@')
+		at = strtol(++oparg, (char **)&oparg, 10);
+
+	      oparg--;
+
+	      print (info->stream, "%d", (unsigned)(EXTRACT_VENDOR_THEAD_SIGN_IMM(l, nbit, at) << shift));
+	      break;
+	    case 'g':
+	      nbit = strtol (oparg, (char **)&oparg, 10);
+	      if ((*oparg) =='@')
+		at = strtol(++oparg, (char **)&oparg, 10);
+
+	      oparg--;
+	      print (info->stream, "%s", riscv_gpr_names[EXTRACT_VENDOR_THEAD_IMM(l, nbit, at)]);
+	      break;
+	    }
+	}
+      break;
+
     default:
       return false;
     }
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index c8e7734..05f9470 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -2219,9 +2219,169 @@ const struct riscv_opcode riscv_draft_opcodes[] =
 {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0 },
 };
 
+
+/* Vendor T-HEAD opcodes.  */
+/*
+   ARG format:
+
+   "Xgm@n": encode GPR with m bit at opcode[m+n-1:n].
+    "Xg5@0": encode GPR with 5 bit at opcode[4:0].
+    "Xg5@8": encode GPR with 5 bit at opcode[12:8].
+
+   "XIm@n": m bits unsigned immediate at opcode[m+n-1:n].
+    "XI5@0": 5 bits unsigned immediate at opcode[4:0].
+    "XI4@8": 4 bits unsigned immediate at opcode[11:8].
+
+   "XSm@n": m bits signed immediate at opcode[m+n-1:n].
+    "XS5@0": 5 bits signed immediate at opcode[4:0].
+    "XS4@8": 4 bits signed immediate at opcode[11:8].
+
+   "XFm@n": m bits FR at opcode[m+n-1:n].
+    "XF5@0": 5 bits FR at opcode[4:0].
+    "XF5@0": 5 bits FR at opcode[4:0].
+*/
+
+static int
+match_thead_rd1_rd2_neq_rs1(const struct riscv_opcode *op,
+			    insn_t insn,
+			    int constraints,
+			    const char **error)
+{
+  int rd1 = (insn & MASK_RD) >> OP_SH_RD;
+  int rd2 = (insn & MASK_RS2) >> OP_SH_RS2;
+  int rs1 = (insn & MASK_RS1) >> OP_SH_RS1;
+
+  /* FIXME: add xlen check.  */
+  return match_opcode (op, insn, constraints, error) && rd1 != rs1 && rd2 != rs1;
+}
+
+/* The vendor extension opcodes for T-HEAD.  */
+struct riscv_opcode riscv_vendor_thead_opcodes[] =
+{
+  {"wsc",             0, INSN_CLASS_THEADC_OR_THEADE,   "",  MATCH_WSC, MASK_WSC, match_opcode, 0},
+  {"dcache.iall",     0, INSN_CLASS_THEADC_OR_THEADE,   "",  MATCH_DCACHE_IALL, MASK_DCACHE_IALL, match_opcode, 0},
+  {"dcache.call",     0, INSN_CLASS_THEADC_OR_THEADE,   "",  MATCH_DCACHE_CALL, MASK_DCACHE_CALL, match_opcode, 0},
+  {"dcache.ciall",    0, INSN_CLASS_THEADC_OR_THEADE,   "",  MATCH_DCACHE_CIALL, MASK_DCACHE_CIALL, match_opcode, 0},
+  {"dcache.isw",      0, INSN_CLASS_THEADC_OR_THEADE,   "s",     MATCH_DCACHE_ISW, MASK_DCACHE_ISW, match_opcode, 0},
+  {"dcache.csw",      0, INSN_CLASS_THEADC_OR_THEADE,   "s",     MATCH_DCACHE_CSW, MASK_DCACHE_CSW, match_opcode, 0},
+  {"dcache.cisw",     0, INSN_CLASS_THEADC_OR_THEADE,   "s",     MATCH_DCACHE_CISW, MASK_DCACHE_CISW, match_opcode, 0},
+  {"dcache.iva",      0, INSN_CLASS_THEADC,   "s",     MATCH_DCACHE_IVA, MASK_DCACHE_IVA, match_opcode, 0},
+  {"dcache.cva",      0, INSN_CLASS_THEADC,   "s",     MATCH_DCACHE_CVA, MASK_DCACHE_CVA, match_opcode, 0},
+  {"dcache.cval1",    0, INSN_CLASS_THEADC,   "s",     MATCH_DCACHE_CVAL1, MASK_DCACHE_CVAL1, match_opcode, 0},
+  {"dcache.civa",     0, INSN_CLASS_THEADC,   "s",     MATCH_DCACHE_CIVA, MASK_DCACHE_CIVA, match_opcode, 0},
+  {"dcache.ipa",      0, INSN_CLASS_THEADC_OR_THEADE,   "s",     MATCH_DCACHE_IPA, MASK_DCACHE_IPA, match_opcode, 0},
+  {"dcache.cpa",      0, INSN_CLASS_THEADC_OR_THEADE,   "s",     MATCH_DCACHE_CPA, MASK_DCACHE_CPA, match_opcode, 0},
+  {"dcache.cpal1",    0, INSN_CLASS_THEADC,   "s",     MATCH_DCACHE_CPAL1, MASK_DCACHE_CPAL1, match_opcode, 0},
+  {"dcache.cipa",     0, INSN_CLASS_THEADC_OR_THEADE,   "s",     MATCH_DCACHE_CIPA, MASK_DCACHE_CIPA, match_opcode, 0},
+  {"icache.iall",     0, INSN_CLASS_THEADC_OR_THEADE_OR_THEADSE,   "",      MATCH_ICACHE_IALL, MASK_ICACHE_IALL, match_opcode, 0},
+  {"icache.iall",     0, INSN_CLASS_THEADSE,   "",      MATCH_ICACHE_IALL, MASK_ICACHE_IALL, match_opcode, INSN_ALIAS},
+  {"icache.ialls",    0, INSN_CLASS_THEADC,   "",      MATCH_ICACHE_IALLS, MASK_ICACHE_IALLS, match_opcode, 0},
+  {"icache.iva",      0, INSN_CLASS_THEADC,   "s",     MATCH_ICACHE_IVA, MASK_ICACHE_IVA, match_opcode, 0},
+  {"icache.ipa",      0, INSN_CLASS_THEADC_OR_THEADE,   "s",     MATCH_ICACHE_IPA, MASK_ICACHE_IPA, match_opcode, 0},
+  {"l2cache.iall",    0, INSN_CLASS_THEADC,   "",      MATCH_L2CACHE_IALL, MASK_L2CACHE_IALL, match_opcode, 0},
+  {"l2cache.call",    0, INSN_CLASS_THEADC,   "",      MATCH_L2CACHE_CALL, MASK_L2CACHE_CALL, match_opcode, 0},
+  {"l2cache.ciall",   0, INSN_CLASS_THEADC_OR_THEADE,   "",      MATCH_L2CACHE_CIALL, MASK_L2CACHE_CIALL, match_opcode, 0},
+  {"sync",            0, INSN_CLASS_THEADC_OR_THEADE,   "",      MATCH_SYNC, MASK_SYNC, match_opcode, 0},
+  {"sync.i",          0, INSN_CLASS_THEADC_OR_THEADE,   "",      MATCH_SYNC_I, MASK_SYNC_I, match_opcode, 0},
+  {"sync.s",          0, INSN_CLASS_THEADC,   "",      MATCH_SYNC_S, MASK_SYNC_S, match_opcode, 0},
+  {"sync.is",         0, INSN_CLASS_THEADC,   "",      MATCH_SYNC_IS, MASK_SYNC_IS, match_opcode, 0},
+  {"tstnbz",          0, INSN_CLASS_THEADC_OR_THEADE,   "d,s",     MATCH_TSTNBZ, MASK_TSTNBZ, match_opcode, 0},
+  {"mula",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MULA, MASK_MULA, match_opcode, 0},
+  {"muls",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MULS, MASK_MULS, match_opcode, 0},
+  {"mulah",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MULAH, MASK_MULAH, match_opcode, 0},
+  {"mulsh",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MULSH, MASK_MULSH, match_opcode, 0},
+  {"sfence.vmas",     0, INSN_CLASS_THEADC,   "s,t",      MATCH_SFENCE_VMAS, MASK_SFENCE_VMAS, match_opcode, 0},
+  {"mveqz",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MVEQZ, MASK_MVEQZ, match_opcode, 0},
+  {"mvnez",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MVNEZ, MASK_MVNEZ, match_opcode, 0},
+  {"mulaw",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MULAW, MASK_MULAW, match_opcode, 0},
+  {"mulsw",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MULSW, MASK_MULSW, match_opcode, 0},
+  {"ext",             64, INSN_CLASS_THEADC,  "d,s,XI6@26,XI6@20",   MATCH_EXT, MASK_EXT, match_opcode, 0 },
+  {"ext",             32, INSN_CLASS_THEADE,  "d,s,XI5@26,XI5@20",   MATCH_EXT, (MASK_EXT | (1U<<25) | (1U<<31)), match_opcode, 0 },
+  {"extu",            64, INSN_CLASS_THEADC,  "d,s,XI6@26,XI6@20",   MATCH_EXTU, MASK_EXTU, match_opcode, 0 },
+  {"extu",            32, INSN_CLASS_THEADE,  "d,s,XI5@26,XI5@20",   MATCH_EXTU, (MASK_EXTU | (1U<<25) | (1U<<31)), match_opcode, 0 },
+  {"ff1",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s",   MATCH_FF1, MASK_FF1, match_opcode, 0},
+  {"ff0",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s",   MATCH_FF0, MASK_FF1, match_opcode, 0},
+  {"rev",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s",   MATCH_REV, MASK_REV, match_opcode, 0},
+  {"lrb",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_LRB, MASK_LRB, match_opcode, 0 },
+  {"lrbu",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_LRBU, MASK_LRBU, match_opcode, 0 },
+  {"lrh",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_LRH, MASK_LRH, match_opcode, 0 },
+  {"lrhu",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_LRHU, MASK_LRHU, match_opcode, 0 },
+  {"lrw",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_LRW, MASK_LRW, match_opcode, 0 },
+  {"lrwu",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_LRWU, MASK_LRWU, match_opcode, 0 },
+  {"srb",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_SRB, MASK_SRB, match_opcode, 0 },
+  {"srh",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_SRH, MASK_SRH, match_opcode, 0 },
+  {"srw",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_SRW, MASK_SRW, match_opcode, 0 },
+  {"lrd",             0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LRD, MASK_LRD, match_opcode, 0 },
+  {"srd",             0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_SRD, MASK_SRD, match_opcode, 0 },
+  {"lurb",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LURB, MASK_LURB, match_opcode, 0 },
+  {"lurbu",           0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LURBU, MASK_LURBU, match_opcode, 0 },
+  {"lurh",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LURH, MASK_LURH, match_opcode, 0 },
+  {"lurhu",           0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LURHU, MASK_LURHU, match_opcode, 0 },
+  {"lurw",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LURW, MASK_LURW, match_opcode, 0 },
+  {"lurwu",           0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LURWU, MASK_LURWU, match_opcode, 0 },
+  {"lurd",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LURD, MASK_LURD, match_opcode, 0 },
+  {"surb",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_SURB, MASK_SURB, match_opcode, 0 },
+  {"surh",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_SURH, MASK_SURH, match_opcode, 0 },
+  {"surw",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_SURW, MASK_SURW, match_opcode, 0 },
+  {"surd",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_SURD, MASK_SURD, match_opcode, 0 },
+  {"tst",             64, INSN_CLASS_THEADC,  "d,s,XI6@20",   MATCH_TST, MASK_TST, match_opcode, 0 },
+  {"tst",             32, INSN_CLASS_THEADE,   "d,s,XI5@20",   MATCH_TST, (MASK_TST | (1U << 25)), match_opcode, INSN_ALIAS},
+  {"srriw",           0, INSN_CLASS_THEADC,   "d,s,XI5@20",   MATCH_SRRIW, MASK_SRRIW, match_opcode, 0 },
+  {"srri",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,XI6@20",   MATCH_SRRI, MASK_SRRI, match_opcode, 0 },
+  {"addsl",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25", MATCH_ADDSL, MASK_ADDSL, match_opcode, 0 },
+  {"lwd",             0, INSN_CLASS_THEADC,   "d,t,(s),XI2@25", MATCH_LWD, MASK_LWD, match_thead_rd1_rd2_neq_rs1, 0 },
+  {"ldd",             0, INSN_CLASS_THEADC,   "d,t,(s),XI2@25", MATCH_LDD, MASK_LDD, match_thead_rd1_rd2_neq_rs1, 0 },
+  {"swd",             0, INSN_CLASS_THEADC,   "d,t,(s),XI2@25", MATCH_SWD, MASK_SWD, match_opcode, 0 },
+  {"sdd",             0, INSN_CLASS_THEADC,   "d,t,(s),XI2@25", MATCH_SDD, MASK_SDD, match_opcode, 0 },
+  {"sdia",            0, INSN_CLASS_THEADC,   "d,(s),XS5@20,XI2@25", MATCH_SDIA, MASK_SDIA, match_opcode, 0 },
+  {"sdib",            0, INSN_CLASS_THEADC,   "d,(s),XS5@20,XI2@25", MATCH_SDIB, MASK_SDIB, match_opcode, 0 },
+  {"lwud",            0, INSN_CLASS_THEADC,   "d,t,(s),XI2@25", MATCH_LWUD, MASK_LWUD, match_thead_rd1_rd2_neq_rs1, 0 },
+  {"swia",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_SWIA, MASK_SWIA, match_opcode, 0},
+  {"swib",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_SWIB, MASK_SWIB, match_opcode, 0},
+  {"shia",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_SHIA, MASK_SHIA, match_opcode, 0},
+  {"shib",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_SHIB, MASK_SHIB, match_opcode, 0},
+  {"sbia",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_SBIA, MASK_SBIA, match_opcode, 0},
+  {"sbib",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_SBIB, MASK_SBIB, match_opcode, 0},
+  {"lwuia",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LWUIA, MASK_LWUIA, match_opcode, 0},
+  {"lwuib",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LWUIB, MASK_LWUIB, match_opcode, 0},
+  {"lhuia",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LHUIA, MASK_LHUIA, match_opcode, 0},
+  {"lhuib",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LHUIB, MASK_LHUIB, match_opcode, 0},
+  {"lbuia",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LBUIA, MASK_LBUIA, match_opcode, 0},
+  {"lbuib",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LBUIB, MASK_LBUIB, match_opcode, 0},
+  {"ldia",            0, INSN_CLASS_THEADC,   "d,(s),XS5@20,XI2@25", MATCH_LDIA, MASK_LDIA, match_opcode, 0},
+  {"ldib",            0, INSN_CLASS_THEADC,   "d,(s),XS5@20,XI2@25", MATCH_LDIB, MASK_LDIB, match_opcode, 0},
+  {"lwia",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LWIA, MASK_LWIA, match_opcode, 0},
+  {"lwib",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LWIB, MASK_LWIB, match_opcode, 0},
+  {"lhia",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LHIA, MASK_LHIA, match_opcode, 0},
+  {"lhib",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LHIB, MASK_LHIB, match_opcode, 0},
+  {"lbia",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LBIA, MASK_LBIA, match_opcode, 0},
+  {"lbib",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LBIB, MASK_LBIB, match_opcode, 0},
+  {"fsurd",           0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FSURD, MASK_FSURD, match_opcode, 0},
+  {"revw",            0, INSN_CLASS_THEADC,   "d,s", MATCH_REVW, MASK_REVW, match_opcode, 0},
+  {"fsurw",           0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FSURW, MASK_FSURW, match_opcode, 0},
+  {"flurd",           0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FLURD, MASK_FLURD, match_opcode, 0},
+  {"flurw",           0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FLURW, MASK_FLURW, match_opcode, 0},
+  {"fsrd",            0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FSRD, MASK_FSRD, match_opcode, 0},
+  {"fsrw",            0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FSRW, MASK_FSRW, match_opcode, 0},
+  {"flrd",            0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FLRD, MASK_FLRD, match_opcode, 0},
+  {"flrw",            0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FLRW, MASK_FLRW, match_opcode, 0},
+
+  /* THEADE only.  */
+  {"ipush",           0, INSN_CLASS_THEADE,   "",  MATCH_IPUSH, MASK_IPUSH, match_opcode, 0},
+  {"ipop",            0, INSN_CLASS_THEADE,   "",  MATCH_IPOP, MASK_IPOP, match_opcode, 0},
+  /* Float move.  */
+  {"fmv.x.hw",        32, INSN_CLASS_THEADE,  "d,S",  MATCH_FMV_X_HW, MASK_FMV_X_HW, match_opcode, 0},
+  {"fmv.hw.x",        32, INSN_CLASS_THEADE,  "D,s",  MATCH_FMV_HW_X, MASK_FMV_HW_X, match_opcode, 0},
+
+
+  {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}
+
+};
+
 /* The supported extended extensions.  */
 const struct riscv_opcode *riscv_extended_opcodes[] =
 {
   riscv_draft_opcodes,
+  riscv_vendor_thead_opcodes,
   NULL
 };
-- 
2.6.0-rc0


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

* Re: [PATCH] RISC-V: Add CSRs and opcodes of the T-HEAD XUANTIE CPUs
  2021-09-07  9:20   ` [PATCH] RISC-V: Add CSRs and opcodes of the " Lifang Xia
@ 2021-09-07  9:27     ` 夏立方
  0 siblings, 0 replies; 10+ messages in thread
From: 夏立方 @ 2021-09-07  9:27 UTC (permalink / raw)
  To: binutils; +Cc: nelson.chu, rjiejie

Sorry the subject should be [integartion 1/1]!
------------------------------------------------------------------
Sender:夏立方 <lifang_xia@c-sky.com>
Sent At:2021 Sep. 7 (Tue.) 17:20
Recipient:binutils@sourceware.org <binutils@sourceware.org>
Cc:nelson.chu <nelson.chu@sifive.com>; rjiejie <rjiejie@linux.alibaba.com>; 夏立方 <lifang_xia@c-sky.com>
Subject:[PATCH] RISC-V: Add CSRs and opcodes of the T-HEAD XUANTIE CPUs

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

New ARG format for operands:
"Xgm@n": encode GPR with m bit at opcode[m+n-1:n].
  "Xg5@0": encode GPR with 5 bit at opcode[4:0].
  "Xg5@8": encode GPR with 5 bit at opcode[12:8].

"XIm@n": m bits unsigned immediate at opcode[m+n-1:n].
  "XI5@0": 5 bits unsigned immediate at opcode[4:0].
  "XI4@8": 4 bits unsigned immediate at opcode[11:8].

"XSm@n": m bits signed immediate at opcode[m+n-1:n].
  "XS5@0": 5 bits signed immediate at opcode[4:0].
  "XS4@8": 4 bits signed immediate at opcode[11:8].

"XFm@n": m bits FR at opcode[m+n-1:n].
  "XF5@0": 5 bits FR at opcode[4:0].
  "XF5@0": 5 bits FR at opcode[4:0].

bfd/
 * cpu-riscv.h (enum riscv_spec_class)
 <ISA_SPEC_CLASS_VENDOR_THEAD>: New.
gas/
 * config/tc-riscv.c (VENDOR_THEAD_EXT): New.
 (enum riscv_extended_csr_class) <CSR_CLASS_VENDOR_THEAD>: New.
 (extended_ext_version_table): Add "xtheadc", "xtheade",
 "xtheadse".
 (riscv_extended_subset_supports): Check subset:
 INSN_CLASS_THEAD*
 (riscv_search_ext_version_hash): Update versions for T-HEAD.
 (op_vendor_thead_hash): New, the hash of T-HEAD Xuantie's
 opcodes.
 (riscv_csr_address): Skip check version for T-HEAD Xuantie CPUs.
 (validate_riscv_extended_insn): Parsing T-HEAD opargs.
 (md_begin): Init op_vendor_thead_hash.
 (riscv_find_extended_opcode_hash): Search op_vendor_thead_hash.
 (riscv_parse_extended_operands): Parsing T-HEAD opargs.
 * testsuite/gas/riscv/extended/thead*: New testcases.
include/
 * opcode/riscv-opc-extended.h: Add CSRs and opcode of the T-HEAD
 XUANTIE CPUs.
 * opcode/riscv.h (riscv_extended_insn_class)
 <INSN_CLASS_THEADC>: New.
 <INSN_CLASS_THEADC_OR_THEADE>: New.
 <INSN_CLASS_THEADC_OR_THEADE_OR_THEADSE>: New.
 <INSN_CLASS_THEADE>: New.
 <INSN_CLASS_THEADSE>: New.
 (*VENDOR_THEAD_*): T-HEAD IMM encoding.
opcodes/
 * riscv-dis.c (print_extended_insn_args): Parsing T-HEAD opargs.
 * riscv-opc.c (match_thead_rd1_rd2_neq_rs1): New.
 (riscv_vendor_thead_opcodes): New.
 (riscv_extended_opcodes): Add riscv_vendor_thead_opcodes.
---
 bfd/cpu-riscv.h                                   |   1 +
 gas/config/tc-riscv.c                             | 151 ++++++
 gas/testsuite/gas/riscv/extended/thead-csr-list.d | 108 ++++
 gas/testsuite/gas/riscv/extended/thead-csr-list.s |  99 ++++
 gas/testsuite/gas/riscv/extended/theadc-ext.d     | 112 +++++
 gas/testsuite/gas/riscv/extended/theadc-ext.s     | 116 +++++
 gas/testsuite/gas/riscv/extended/theade-ext.d     |  62 +++
 gas/testsuite/gas/riscv/extended/theade-ext.s     |  67 +++
 include/opcode/riscv-opc-extended.h               | 572 ++++++++++++++++++++++
 include/opcode/riscv.h                            |  24 +
 opcodes/riscv-dis.c                               |  45 ++
 opcodes/riscv-opc.c                               | 160 ++++++
 12 files changed, 1517 insertions(+)
 create mode 100644 gas/testsuite/gas/riscv/extended/thead-csr-list.d
 create mode 100644 gas/testsuite/gas/riscv/extended/thead-csr-list.s
 create mode 100644 gas/testsuite/gas/riscv/extended/theadc-ext.d
 create mode 100644 gas/testsuite/gas/riscv/extended/theadc-ext.s
 create mode 100644 gas/testsuite/gas/riscv/extended/theade-ext.d
 create mode 100644 gas/testsuite/gas/riscv/extended/theade-ext.s

diff --git a/bfd/cpu-riscv.h b/bfd/cpu-riscv.h
index cafaca2..c1dcfce 100644
--- a/bfd/cpu-riscv.h
+++ b/bfd/cpu-riscv.h
@@ -26,6 +26,7 @@ enum riscv_spec_class
   ISA_SPEC_CLASS_20190608,
   ISA_SPEC_CLASS_20191213,
   ISA_SPEC_CLASS_DRAFT,
+  ISA_SPEC_CLASS_VENDOR_THEAD,

   /* Privileged spec.  */
   PRIV_SPEC_CLASS_NONE,
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 1899294..28cf183 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -40,6 +40,7 @@
 enum
 {
   DRAFT_EXT = 0,
+  VENDOR_THEAD_EXT,
   EXTENDED_EXT_NUM
 };

@@ -79,6 +80,7 @@ enum riscv_csr_class
 enum riscv_extended_csr_class
 {
   CSR_CLASS_V = CSR_CLASS_EXTENDED, /* RVV CSR */
+  CSR_CLASS_VENDOR_THEAD, /* vendor CSR for T-HEAD */
 };

 /* This structure holds all restricted conditions for a CSR.  */
@@ -170,6 +172,12 @@ static const struct riscv_ext_version extended_ext_version_table[] =
   {"zfh",     ISA_SPEC_CLASS_DRAFT, 0, 1},
   {"svinval", ISA_SPEC_CLASS_DRAFT, 0, 1},

+  /* T-HEAD extentions for Xuantie C9xx.
+     The version 2.0 just keeps compatible.  */
+  {"xtheadc",   ISA_SPEC_CLASS_VENDOR_THEAD, 2, 0},
+  {"xtheade",   ISA_SPEC_CLASS_VENDOR_THEAD, 2, 0},
+  {"xtheadse",   ISA_SPEC_CLASS_VENDOR_THEAD, 2, 0},
+
   /* Terminate the list.  */
   {NULL, 0, 0, 0}
 };
@@ -365,6 +373,20 @@ riscv_extended_subset_supports (int insn_class)
     case INSN_CLASS_SVINVAL:
       return riscv_subset_supports ("svinval");

+    case INSN_CLASS_THEADC:
+      return riscv_subset_supports ("xtheadc");
+    case INSN_CLASS_THEADC_OR_THEADE:
+      return (riscv_subset_supports ("xtheadc")
+       || riscv_subset_supports ("xtheade"));
+    case INSN_CLASS_THEADC_OR_THEADE_OR_THEADSE:
+      return (riscv_subset_supports ("xtheadc")
+       || riscv_subset_supports ("xtheade")
+       || riscv_subset_supports ("xtheadse"));
+    case INSN_CLASS_THEADE:
+      return riscv_subset_supports ("xtheade");
+    case INSN_CLASS_THEADSE:
+      return riscv_subset_supports ("xtheadse");
+
     default:
       as_fatal ("internal: unknown INSN_CLASS (0x%x)", insn_class);
       return false;
@@ -458,6 +480,7 @@ riscv_search_ext_version_hash (const char *name,
   && strcmp (ext->name, name) == 0)
     {
       if (ext->isa_spec_class == ISA_SPEC_CLASS_DRAFT
+   || ext->isa_spec_class == ISA_SPEC_CLASS_VENDOR_THEAD
    || ext->isa_spec_class == default_isa_spec)
  {
    *major_version = ext->major_version;
@@ -576,6 +599,9 @@ static htab_t op_hash = NULL;
 /* Handle of the draft OPCODE hash table.  */
 static htab_t op_draft_hash = NULL;

+/* Handle of the T-HEAD OPCODE hash table.  */
+static htab_t op_vendor_thead_hash = NULL;
+
 /* Handle of the type of .insn hash table.  */
 static htab_t insn_type_hash = NULL;

@@ -996,6 +1022,7 @@ riscv_csr_address (const char *csr_name,
       need_check_version = false;
       break;
     case CSR_CLASS_DEBUG:
+    case CSR_CLASS_VENDOR_THEAD:
       need_check_version = false;
       break;
     default:
@@ -1150,6 +1177,48 @@ validate_riscv_extended_insn (insn_t *bits,
    return false;
  }
       break;
+
+    case 'X':
+      switch (*++oparg)
+ {
+ case 'g':
+   /* Xgm@n.  */
+ case 'F':
+   /* XFm@n.  */
+ case 'I':
+     {
+       /* XIm@n.  */
+       int nbit = 0;
+       int at = -1;
+       int shift = 0;
+       nbit = strtol (++oparg, (char **)&oparg, 10);
+       if (*oparg =='@')
+  at = strtol(++oparg, (char **)&oparg, 10);
+       oparg--;
+
+       used_bits |= ENCODE_VENDOR_THEAD_IMM((-1U>>shift), nbit, at);
+       break;
+     }
+ case 'S':
+   /* XSm@n.  */
+     {
+       int nbit = 0;
+       int at = -1;
+       int shift = 0;
+       nbit = strtol (++oparg, (char **)&oparg, 10);
+       if ((*oparg) =='>' && (*(oparg+1)) == '>')
+  shift = strtol (oparg, (char **)&oparg, 10);
+       if (*oparg =='@')
+  at = strtol(++oparg, (char **)&oparg, 10);
+       oparg--;
+
+       used_bits |= ENCODE_VENDOR_THEAD_IMM((-1>>shift), nbit, at);
+       break;
+     }
+ }
+      break;
+
+
     default:
       return false;
     }
@@ -1403,6 +1472,7 @@ md_begin (void)
   hash_reg_names (RCLASS_VECR, riscv_vecr_names_numeric, NVECR);
   hash_reg_names (RCLASS_VECM, riscv_vecm_names_numeric, NVECM);
   op_draft_hash = init_opcode_hash (riscv_extended_opcodes[DRAFT_EXT], false);
+  op_vendor_thead_hash = init_opcode_hash (riscv_extended_opcodes[VENDOR_THEAD_EXT], false);
 }

 static insn_t
@@ -1511,6 +1581,9 @@ riscv_find_extended_opcode_hash (char *str ATTRIBUTE_UNUSED)
  case DRAFT_EXT:
    insn = (struct riscv_opcode *) str_hash_find (op_draft_hash, str);
    continue;
+ case VENDOR_THEAD_EXT:
+   insn = (struct riscv_opcode *) str_hash_find (op_vendor_thead_hash, str);
+   continue;
  default:
    break;
  }
@@ -2615,6 +2688,83 @@ riscv_parse_extended_operands (struct riscv_cl_insn *ip ATTRIBUTE_UNUSED,
  }
       break;

+    case 'X':
+ {
+   int nbit = 0;
+   int at = -1;
+   int shift = 0;
+   switch (*++oparg)
+     {
+     case 'I':
+       /* XIm@n.  */
+       nbit = strtol (++oparg, (char **)&oparg, 10);
+       if ((*oparg) =='@')
+  at = strtol(++oparg, (char **)&oparg, 10);
+
+       oparg--;
+
+       my_getExpression(imm_expr, asarg);
+       if (imm_expr->X_op != O_constant
+    || !VALID_VENDOR_THEAD_IMM(imm_expr->X_add_number, nbit, at))
+  return false;
+       ip->insn_opcode |=
+  ENCODE_VENDOR_THEAD_IMM ((imm_expr->X_add_number >> shift), nbit, at);
+       asarg = expr_end;
+       imm_expr->X_op = O_absent;
+       break;
+
+     case 'S':
+       /* XSm@n.  */
+       nbit = strtol (++oparg, (char **)&oparg, 10);
+       if ((*oparg) =='<' && (*(oparg+1)) == '<')
+  {
+    oparg+= 2;
+    shift = strtol(++oparg, (char **)&oparg, 10);
+  }
+
+       if ((*oparg) =='@')
+  at = strtol(++oparg, (char **)&oparg, 10);
+
+       oparg--;
+
+       my_getExpression(imm_expr, asarg);
+       if (imm_expr->X_op != O_constant
+    || !VALID_VENDOR_THEAD_SIGN_IMM((imm_expr->X_add_number >> shift), nbit, at))
+  return false;
+       ip->insn_opcode |=
+  ENCODE_VENDOR_THEAD_SIGN_IMM (imm_expr->X_add_number, nbit, at);
+       asarg = expr_end;
+       imm_expr->X_op = O_absent;
+       break;;
+
+     case 'g':
+       /* Xgm@n.  */
+       nbit = strtol (++oparg, (char **)&oparg, 10);
+       if ((*oparg) =='<' && (*(oparg+1)) == '<')
+  {
+    oparg+= 2;
+    shift = strtol(++oparg, (char **)&oparg, 10);
+  }
+
+       if ((*oparg) =='@')
+  at = strtol(++oparg, (char **)&oparg, 10);
+
+       oparg--;
+
+
+       my_getExpression(imm_expr, asarg);
+       if (imm_expr->X_op != O_register
+    || !VALID_VENDOR_THEAD_IMM(imm_expr->X_add_number, nbit, at))
+  return false;
+       ip->insn_opcode |=
+  ENCODE_VENDOR_THEAD_IMM (imm_expr->X_add_number, nbit, at);
+       asarg = expr_end;
+       break;;
+     }
+ }
+      break;;
+
+
     default:
       as_fatal (_("internal: unknown argument type `%s'"),
   *opcode_args);
@@ -4587,3 +4737,4 @@ riscv_pop_insert (void)

   pop_insert (riscv_pseudo_table);
 }
+
diff --git a/gas/testsuite/gas/riscv/extended/thead-csr-list.d b/gas/testsuite/gas/riscv/extended/thead-csr-list.d
new file mode 100644
index 0000000..efe7859
--- /dev/null
+++ b/gas/testsuite/gas/riscv/extended/thead-csr-list.d
@@ -0,0 +1,108 @@
+#as: -march=rv64gcxtheadc
+#objdump: -dr
+
+.*:[  ]+file format .*
+
+
+Disassembly of section .text:
+
+0000000000000000 <.text>:
+   0: 7c002573           csrr a0,mxstatus
+   4: 7c102573           csrr a0,mhcr
+   8: 7c202573           csrr a0,mcor
+   c: 7c302573           csrr a0,mccr2
+  10: 7c402573           csrr a0,mcer2
+  14: 7c502573           csrr a0,mhint
+  18: 7c602573           csrr a0,mrmr
+  1c: 7c702573           csrr a0,mrvbr
+  20: 7c802573           csrr a0,mcer
+  24: 7c902573           csrr a0,mcounterwen
+  28: 7ca02573           csrr a0,mcounterinten
+  2c: 7cb02573           csrr a0,mcounterof
+  30: 7cc02573           csrr a0,mhint2
+  34: 7cd02573           csrr a0,mhint3
+  38: 7e002573           csrr a0,mraddr
+  3c: 7e102573           csrr a0,mexstatus
+  40: 7e202573           csrr a0,mnmicause
+  44: 7e302573           csrr a0,mnmipc
+  48: 7f002573           csrr a0,mhpmcr
+  4c: 7f102573           csrr a0,mhpmsr
+  50: 7f202573           csrr a0,mhpmer
+  54: 7f302573           csrr a0,msmpr
+  58: 7f402573           csrr a0,mteecfg
+  5c: 7d102573           csrr a0,usp
+  60: 7d202573           csrr a0,mcins
+  64: 7d302573           csrr a0,mcindex
+  68: 7d402573           csrr a0,mcdata0
+  6c: 7d502573           csrr a0,mcdata1
+  70: 7d602573           csrr a0,meicr
+  74: 7d702573           csrr a0,meicr2
+  78: be002573           csrr a0,mebr
+  7c: be102573           csrr a0,nt_mstatus
+  80: be302573           csrr a0,nt_mtvec
+  84: be202573           csrr a0,nt_mie
+  88: be402573           csrr a0,nt_mtvt
+  8c: be502573           csrr a0,nt_mepc
+  90: be602573           csrr a0,nt_mcause
+  94: be702573           csrr a0,nt_mip
+  98: be802573           csrr a0,nt_mintstate
+  9c: be902573           csrr a0,nt_mxstatus
+  a0: bea02573           csrr a0,nt_mebr
+  a4: beb02573           csrr a0,nt_msp
+  a8: bec02573           csrr a0,t_usp
+  ac: bed02573           csrr a0,t_mdcr
+  b0: bee02573           csrr a0,t_mpcr
+  b4: bef02573           csrr a0,pmpteecfg
+  b8: fc002573           csrr a0,mcpuid
+  bc: fc102573           csrr a0,mapbaddr
+  c0: fc202573           csrr a0,mwmsr
+  c4: 80002573           csrr a0,fxcr
+  c8: 9c002573           csrr a0,smir
+  cc: 9c102573           csrr a0,smel
+  d0: 9c202573           csrr a0,smeh
+  d4: 9c302573           csrr a0,smcir
+  d8: 5c002573           csrr a0,sxstatus
+  dc: 5c102573           csrr a0,shcr
+  e0: 5c202573           csrr a0,scer2
+  e4: 5c302573           csrr a0,scer
+  e8: 5c402573           csrr a0,scounterinten
+  ec: 5c502573           csrr a0,scounterof
+  f0: 5c602573           csrr a0,shint
+  f4: 5c702573           csrr a0,shint2
+  f8: 5c802573           csrr a0,shpminhibit
+  fc: 5c902573           csrr a0,shpmcr
+ 100: 5ca02573           csrr a0,shpmsr
+ 104: 5cb02573           csrr a0,shpmer
+ 108: 5e002573           csrr a0,scycle
+ 10c: 5e102573           csrr a0,shpmcounter1
+ 110: 5e202573           csrr a0,shpmcounter2
+ 114: 5e302573           csrr a0,shpmcounter3
+ 118: 5e402573           csrr a0,shpmcounter4
+ 11c: 5e502573           csrr a0,shpmcounter5
+ 120: 5e602573           csrr a0,shpmcounter6
+ 124: 5e702573           csrr a0,shpmcounter7
+ 128: 5e802573           csrr a0,shpmcounter8
+ 12c: 5e902573           csrr a0,shpmcounter9
+ 130: 5ea02573           csrr a0,shpmcounter10
+ 134: 5eb02573           csrr a0,shpmcounter11
+ 138: 5ec02573           csrr a0,shpmcounter12
+ 13c: 5ed02573           csrr a0,shpmcounter13
+ 140: 5ee02573           csrr a0,shpmcounter14
+ 144: 5ef02573           csrr a0,shpmcounter15
+ 148: 5f002573           csrr a0,shpmcounter16
+ 14c: 5f102573           csrr a0,shpmcounter17
+ 150: 5f202573           csrr a0,shpmcounter18
+ 154: 5f302573           csrr a0,shpmcounter19
+ 158: 5f402573           csrr a0,shpmcounter20
+ 15c: 5f502573           csrr a0,shpmcounter21
+ 160: 5f602573           csrr a0,shpmcounter22
+ 164: 5f702573           csrr a0,shpmcounter23
+ 168: 5f802573           csrr a0,shpmcounter24
+ 16c: 5f902573           csrr a0,shpmcounter25
+ 170: 5fa02573           csrr a0,shpmcounter26
+ 174: 5fb02573           csrr a0,shpmcounter27
+ 178: 5fc02573           csrr a0,shpmcounter28
+ 17c: 5fd02573           csrr a0,shpmcounter29
+ 180: 5fe02573           csrr a0,shpmcounter30
+ 184: 5ff02573           csrr a0,shpmcounter31
+
diff --git a/gas/testsuite/gas/riscv/extended/thead-csr-list.s b/gas/testsuite/gas/riscv/extended/thead-csr-list.s
new file mode 100644
index 0000000..d6de027
--- /dev/null
+++ b/gas/testsuite/gas/riscv/extended/thead-csr-list.s
@@ -0,0 +1,99 @@
+csrr a0, mxstatus
+csrr a0, mhcr
+csrr a0, mcor
+csrr a0, mccr2
+csrr a0, mcer2
+csrr a0, mhint
+csrr a0, mrmr
+csrr a0, mrvbr
+csrr a0, mcer
+csrr a0, mcounterwen
+csrr a0, mcounterinten
+csrr a0, mcounterof
+csrr a0, mhint2
+csrr a0, mhint3
+csrr a0, mraddr
+csrr a0, mexstatus
+csrr a0, mnmicause
+csrr a0, mnmipc
+csrr a0, mhpmcr
+csrr a0, mhpmsr
+csrr a0, mhpmer
+csrr a0, msmpr
+csrr a0, mteecfg
+csrr a0, usp
+csrr a0, mcins
+csrr a0, mcindex
+csrr a0, mcdata0
+csrr a0, mcdata1
+csrr a0, meicr
+csrr a0, meicr2
+csrr a0, mebr
+csrr a0, nt_mstatus
+csrr a0, nt_mtvec
+csrr a0, nt_mie
+csrr a0, nt_mtvt
+csrr a0, nt_mepc
+csrr a0, nt_mcause
+csrr a0, nt_mip
+csrr a0, nt_mintstate
+csrr a0, nt_mxstatus
+csrr a0, nt_mebr
+csrr a0, nt_msp
+csrr a0, t_usp
+csrr a0, t_mdcr
+csrr a0, t_mpcr
+csrr a0, pmpteecfg
+csrr a0, mcpuid
+csrr a0, mapbaddr
+csrr a0, mwmsr
+csrr a0, fxcr
+csrr a0, smir
+csrr a0, smel
+csrr a0, smeh
+csrr a0, smcir
+csrr a0, sxstatus
+csrr a0, shcr
+csrr a0, scer2
+csrr a0, scer
+csrr a0, scounterinten
+csrr a0, scounterof
+csrr a0, shint
+csrr a0, shint2
+csrr a0, shpminhibit
+csrr a0, shpmcr
+csrr a0, shpmsr
+csrr a0, shpmer
+csrr a0, scycle
+csrr a0, shpmcounter1
+csrr a0, shpmcounter2
+csrr a0, shpmcounter3
+csrr a0, shpmcounter4
+csrr a0, shpmcounter5
+csrr a0, shpmcounter6
+csrr a0, shpmcounter7
+csrr a0, shpmcounter8
+csrr a0, shpmcounter9
+csrr a0, shpmcounter10
+csrr a0, shpmcounter11
+csrr a0, shpmcounter12
+csrr a0, shpmcounter13
+csrr a0, shpmcounter14
+csrr a0, shpmcounter15
+csrr a0, shpmcounter16
+csrr a0, shpmcounter17
+csrr a0, shpmcounter18
+csrr a0, shpmcounter19
+csrr a0, shpmcounter20
+csrr a0, shpmcounter21
+csrr a0, shpmcounter22
+csrr a0, shpmcounter23
+csrr a0, shpmcounter24
+csrr a0, shpmcounter25
+csrr a0, shpmcounter26
+csrr a0, shpmcounter27
+csrr a0, shpmcounter28
+csrr a0, shpmcounter29
+csrr a0, shpmcounter30
+csrr a0, shpmcounter31
+
diff --git a/gas/testsuite/gas/riscv/extended/theadc-ext.d b/gas/testsuite/gas/riscv/extended/theadc-ext.d
new file mode 100644
index 0000000..3ba0f86
--- /dev/null
+++ b/gas/testsuite/gas/riscv/extended/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           dcache.call
+   8: 0030000b           dcache.ciall
+   c: 02b5000b           dcache.cipa a0
+  10: 0235000b           dcache.cisw a0
+  14: 0275000b           dcache.civa a0
+  18: 0295000b           dcache.cpa a0
+  1c: 0285000b           dcache.cpal1 a0
+  20: 0255000b           dcache.cva a0
+  24: 0245000b           dcache.cval1 a0
+  28: 02a5000b           dcache.ipa a0
+  2c: 0225000b           dcache.isw a0
+  30: 0265000b           dcache.iva a0
+  34: 0020000b           dcache.iall
+  38: 0215000b           dcache.csw a0
+  3c: 0100000b           icache.iall
+  40: 0110000b           icache.ialls
+  44: 0305000b           icache.iva a0
+  48: 0385000b           icache.ipa a0
+  4c: 0160000b           l2cache.iall
+  50: 0150000b           l2cache.call
+  54: 0170000b           l2cache.ciall
+  58: 04b5000b           sfence.vmas a0,a1
+  5c: 0180000b           sync
+  60: 01a0000b           sync.i
+  64: 0190000b           sync.s
+  68: 01b0000b           sync.is
+  6c: 02c5950b           addsl a0,a1,a2,1
+  70: 20c5950b           mula a0,a1,a2
+  74: 22c5950b           muls a0,a1,a2
+  78: 24c5950b           mulaw a0,a1,a2
+  7c: 26c5950b           mulsw a0,a1,a2
+  80: 28c5950b           mulah a0,a1,a2
+  84: 2ac5950b           mulsh a0,a1,a2
+  88: 1105950b           srri a0,a1,16
+  8c: 1505950b           srriw a0,a1,16
+  90: 40c5950b           mveqz a0,a1,a2
+  94: 42c5950b           mvnez a0,a1,a2
+  98: 8905950b           tst a0,a1,16
+  9c: 8005950b           tstnbz a0,a1
+  a0: 4105a50b           ext a0,a1,16,16
+  a4: 4105b50b           extu a0,a1,16,16
+  a8: 8605950b           ff1 a0,a1
+  ac: 8405950b           ff0 a0,a1
+  b0: 8205950b           rev a0,a1
+  b4: 9005950b           revw a0,a1
+  b8: 62b5600b           flrd ft0,a0,a1,1
+  bc: 42b5600b           flrw ft0,a0,a1,1
+  c0: 72b5600b           flurd ft0,a0,a1,1
+  c4: 52b5600b           flurw ft0,a0,a1,1
+  c8: 02c5c50b           lrb a0,a1,a2,1
+  cc: 22c5c50b           lrh a0,a1,a2,1
+  d0: 42c5c50b           lrw a0,a1,a2,1
+  d4: 62c5c50b           lrd a0,a1,a2,1
+  d8: 82c5c50b           lrbu a0,a1,a2,1
+  dc: a2c5c50b           lrhu a0,a1,a2,1
+  e0: c2c5c50b           lrwu a0,a1,a2,1
+  e4: 12c5c50b           lurb a0,a1,a2,1
+  e8: 32c5c50b           lurh a0,a1,a2,1
+  ec: 52c5c50b           lurw a0,a1,a2,1
+  f0: 72c5c50b           lurd a0,a1,a2,1
+  f4: 92c5c50b           lurbu a0,a1,a2,1
+  f8: b2c5c50b           lurhu a0,a1,a2,1
+  fc: d2c5c50b           lurwu a0,a1,a2,1
+ 100: 1af5c50b           lbia a0,\(a1\),15,1
+ 104: 0af5c50b           lbib a0,\(a1\),15,1
+ 108: 3af5c50b           lhia a0,\(a1\),15,1
+ 10c: 2af5c50b           lhib a0,\(a1\),15,1
+ 110: 5af5c50b           lwia a0,\(a1\),15,1
+ 114: 4af5c50b           lwib a0,\(a1\),15,1
+ 118: 7af5c50b           ldia a0,\(a1\),15,1
+ 11c: 6af5c50b           ldib a0,\(a1\),15,1
+ 120: 9af5c50b           lbuia a0,\(a1\),15,1
+ 124: 8af5c50b           lbuib a0,\(a1\),15,1
+ 128: baf5c50b           lhuia a0,\(a1\),15,1
+ 12c: aaf5c50b           lhuib a0,\(a1\),15,1
+ 130: daf5c50b           lwuia a0,\(a1\),15,1
+ 134: caf5c50b           lwuib a0,\(a1\),15,1
+ 138: fab6450b           ldd a0,a1,\(a2\),1
+ 13c: e2b6450b           lwd a0,a1,\(a2\),1
+ 140: f2b6450b           lwud a0,a1,\(a2\),1
+ 144: 62b5700b           fsrd ft0,a0,a1,1
+ 148: 42b5700b           fsrw ft0,a0,a1,1
+ 14c: 72b5700b           fsurd ft0,a0,a1,1
+ 150: 52b5700b           fsurw ft0,a0,a1,1
+ 154: 02c5d50b           srb a0,a1,a2,1
+ 158: 22c5d50b           srh a0,a1,a2,1
+ 15c: 42c5d50b           srw a0,a1,a2,1
+ 160: 62c5d50b           srd a0,a1,a2,1
+ 164: 12c5d50b           surb a0,a1,a2,1
+ 168: 32c5d50b           surh a0,a1,a2,1
+ 16c: 52c5d50b           surw a0,a1,a2,1
+ 170: 72c5d50b           surd a0,a1,a2,1
+ 174: 1af5d50b           sbia a0,\(a1\),15,1
+ 178: 0af5d50b           sbib a0,\(a1\),15,1
+ 17c: 3af5d50b           shia a0,\(a1\),15,1
+ 180: 2af5d50b           shib a0,\(a1\),15,1
+ 184: 5ac5d50b           swia a0,\(a1\),12,1
+ 188: 4af5d50b           swib a0,\(a1\),15,1
+ 18c: 7af5d50b           sdia a0,\(a1\),15,1
+ 190: 6af5d50b           sdib a0,\(a1\),15,1
+ 194: fab6550b           sdd a0,a1,\(a2\),1
+ 198: e2b6550b           swd a0,a1,\(a2\),1
diff --git a/gas/testsuite/gas/riscv/extended/theadc-ext.s b/gas/testsuite/gas/riscv/extended/theadc-ext.s
new file mode 100644
index 0000000..b7a1a7a
--- /dev/null
+++ b/gas/testsuite/gas/riscv/extended/theadc-ext.s
@@ -0,0 +1,116 @@
+.text
+
+wsc
+
+# cache ext
+dcache.call
+dcache.ciall
+dcache.cipa a0
+dcache.cisw a0
+dcache.civa a0
+dcache.cpa a0
+dcache.cpal1 a0
+dcache.cva a0
+dcache.cval1 a0
+dcache.ipa a0
+dcache.isw a0
+dcache.iva a0
+dcache.iall
+dcache.csw a0
+icache.iall
+icache.ialls
+icache.iva a0
+icache.ipa a0
+l2cache.iall
+l2cache.call
+l2cache.ciall
+
+# sync ext
+sfence.vmas       a0, a1
+sync
+sync.i
+sync.s
+sync.is
+
+# calc ext
+addsl             a0, a1, a2, 1
+mula              a0, a1, a2
+muls              a0, a1, a2
+mulaw             a0, a1, a2
+mulsw             a0, a1, a2
+mulah             a0, a1, a2
+mulsh             a0, a1, a2
+srri              a0, a1, 16
+srriw             a0, a1, 16
+mveqz             a0, a1, a2
+mvnez             a0, a1, a2
+
+# bit ext
+tst               a0, a1, 16
+tstnbz            a0, a1
+ext               a0, a1, 16, 16
+extu              a0, a1, 16, 16
+ff1               a0, a1
+ff0               a0, a1
+rev               a0, a1
+revw       a0, a1
+
+# load/store ext
+flrd       f0, a0, a1, 1
+flrw       f0, a0, a1, 1
+flurd      f0, a0, a1, 1
+flurw      f0, a0, a1, 1
+lrb               a0, a1, a2, 1
+lrh               a0, a1, a2, 1
+lrw               a0, a1, a2, 1
+lrd               a0, a1, a2, 1
+lrbu              a0, a1, a2, 1
+lrhu              a0, a1, a2, 1
+lrwu              a0, a1, a2, 1
+lurb              a0, a1, a2, 1
+lurh              a0, a1, a2, 1
+lurw              a0, a1, a2, 1
+lurd              a0, a1, a2, 1
+lurbu             a0, a1, a2, 1
+lurhu             a0, a1, a2, 1
+lurwu             a0, a1, a2, 1
+lbia       a0, (a1), 15, 1
+lbib       a0, (a1), 15, 1
+lhia       a0, (a1), 15, 1
+lhib       a0, (a1), 15, 1
+lwia       a0, (a1), 15, 1
+lwib       a0, (a1), 15, 1
+ldia       a0, (a1), 15, 1
+ldib       a0, (a1), 15, 1
+lbuia      a0, (a1), 15, 1
+lbuib      a0, (a1), 15, 1
+lhuia      a0, (a1), 15, 1
+lhuib      a0, (a1), 15, 1
+lwuia      a0, (a1), 15, 1
+lwuib      a0, (a1), 15, 1
+ldd               a0, a1, (a2), 1
+lwd               a0, a1, (a2), 1
+lwud              a0, a1, (a2), 1
+fsrd       f0, a0, a1, 1
+fsrw       f0, a0, a1, 1
+fsurd      f0, a0, a1, 1
+fsurw      f0, a0, a1, 1
+srb               a0, a1, a2, 1
+srh               a0, a1, a2, 1
+srw               a0, a1, a2, 1
+srd               a0, a1, a2, 1
+surb              a0, a1, a2, 1
+surh              a0, a1, a2, 1
+surw              a0, a1, a2, 1
+surd              a0, a1, a2, 1
+sbia              a0, (a1), 15, 1
+sbib              a0, (a1), 15, 1
+shia              a0, (a1), 15, 1
+shib              a0, (a1), 15, 1
+swia              a0, (a1), 12, 1
+swib              a0, (a1), 15, 1
+sdia              a0, (a1), 15, 1
+sdib              a0, (a1), 15, 1
+sdd               a0, a1, (a2), 1
+swd               a0, a1, (a2), 1
+
diff --git a/gas/testsuite/gas/riscv/extended/theade-ext.d b/gas/testsuite/gas/riscv/extended/theade-ext.d
new file mode 100644
index 0000000..6f9cb52
--- /dev/null
+++ b/gas/testsuite/gas/riscv/extended/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           dcache.ipa a0
+[       ]+[0-9a-f]+:\s+0295000b           dcache.cpa a0
+[       ]+[0-9a-f]+:\s+02b5000b           dcache.cipa a0
+[       ]+[0-9a-f]+:\s+0225000b           dcache.isw a0
+[       ]+[0-9a-f]+:\s+0215000b           dcache.csw a0
+[       ]+[0-9a-f]+:\s+0235000b           dcache.cisw a0
+[       ]+[0-9a-f]+:\s+0020000b           dcache.iall
+[       ]+[0-9a-f]+:\s+0010000b           dcache.call
+[       ]+[0-9a-f]+:\s+0030000b           dcache.ciall
+[       ]+[0-9a-f]+:\s+0100000b           icache.iall
+[       ]+[0-9a-f]+:\s+0385000b           icache.ipa a0
+[       ]+[0-9a-f]+:\s+0180000b           sync
+[       ]+[0-9a-f]+:\s+01a0000b           sync.i
+[       ]+[0-9a-f]+:\s+02c5950b           addsl a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+1105950b           srri a0,a1,16
+[       ]+[0-9a-f]+:\s+20c5950b           mula a0,a1,a2
+[       ]+[0-9a-f]+:\s+28c5950b           mulah a0,a1,a2
+[       ]+[0-9a-f]+:\s+22c5950b           muls a0,a1,a2
+[       ]+[0-9a-f]+:\s+2ac5950b           mulsh a0,a1,a2
+[       ]+[0-9a-f]+:\s+40c5950b           mveqz a0,a1,a2
+[       ]+[0-9a-f]+:\s+42c5950b           mvnez a0,a1,a2
+[       ]+[0-9a-f]+:\s+4105a50b           ext a0,a1,16,16
+[       ]+[0-9a-f]+:\s+4105b50b           extu a0,a1,16,16
+[       ]+[0-9a-f]+:\s+8605950b           ff1 a0,a1
+[       ]+[0-9a-f]+:\s+8405950b           ff0 a0,a1
+[       ]+[0-9a-f]+:\s+8205950b           rev a0,a1
+[       ]+[0-9a-f]+:\s+8905950b           tst a0,a1,16
+[       ]+[0-9a-f]+:\s+8005950b           tstnbz a0,a1
+[       ]+[0-9a-f]+:\s+02c5c50b           lrb a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+22c5c50b           lrh a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+42c5c50b           lrw a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+82c5c50b           lrbu a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+a2c5c50b           lrhu a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+1af5c50b           lbia a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+0af5c50b           lbib a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+3af5c50b           lhia a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+2af5c50b           lhib a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+5af5c50b           lwia a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+4af5c50b           lwib a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+02c5d50b           srb a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+22c5d50b           srh a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+42c5d50b           srw a0,a1,a2,1
+[       ]+[0-9a-f]+:\s+1af5d50b           sbia a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+0af5d50b           sbib a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+3af5d50b           shia a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+2af5d50b           shib a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+5ac5d50b           swia a0,\(a1\),12,1
+[       ]+[0-9a-f]+:\s+4af5d50b           swib a0,\(a1\),15,1
+[       ]+[0-9a-f]+:\s+c000150b           fmv.x.hw a0,ft0
+[       ]+[0-9a-f]+:\s+a005100b           fmv.hw.x ft0,a0
+[       ]+[0-9a-f]+:\s+0040000b           ipush
+[       ]+[0-9a-f]+:\s+0050000b           ipop
diff --git a/gas/testsuite/gas/riscv/extended/theade-ext.s b/gas/testsuite/gas/riscv/extended/theade-ext.s
new file mode 100644
index 0000000..5c93e04
--- /dev/null
+++ b/gas/testsuite/gas/riscv/extended/theade-ext.s
@@ -0,0 +1,67 @@
+.text
+
+wsc
+
+# cache ext
+dcache.ipa a0
+dcache.cpa a0
+dcache.cipa a0
+dcache.isw a0
+dcache.csw a0
+dcache.cisw a0
+dcache.iall
+dcache.call
+dcache.ciall
+icache.iall
+icache.ipa a0
+
+# sync ext
+sync
+sync.i
+
+# calc ext
+addsl             a0, a1, a2, 1
+srri              a0, a1, 16
+mula              a0, a1, a2
+mulah             a0, a1, a2
+muls              a0, a1, a2
+mulsh             a0, a1, a2
+mveqz             a0, a1, a2
+mvnez             a0, a1, a2
+
+# bit ext
+ext               a0, a1, 16, 16
+extu              a0, a1, 16, 16
+ff1               a0, a1
+ff0               a0, a1
+rev               a0, a1
+tst               a0, a1, 16
+tstnbz            a0, a1
+
+# load/store ext
+lrb               a0, a1, a2, 1
+lrh               a0, a1, a2, 1
+lrw               a0, a1, a2, 1
+lrbu              a0, a1, a2, 1
+lrhu              a0, a1, a2, 1
+lbia       a0, (a1), 15, 1
+lbib       a0, (a1), 15, 1
+lhia       a0, (a1), 15, 1
+lhib       a0, (a1), 15, 1
+lwia       a0, (a1), 15, 1
+lwib       a0, (a1), 15, 1
+srb               a0, a1, a2, 1
+srh               a0, a1, a2, 1
+srw               a0, a1, a2, 1
+sbia              a0, (a1), 15, 1
+sbib              a0, (a1), 15, 1
+shia              a0, (a1), 15, 1
+shib              a0, (a1), 15, 1
+swia              a0, (a1), 12, 1
+swib              a0, (a1), 15, 1
+
+fmv.x.hw   a0, f0
+fmv.hw.x   f0, a0
+ipush
+ipop
+
diff --git a/include/opcode/riscv-opc-extended.h b/include/opcode/riscv-opc-extended.h
index 6f664ed..2d283ca 100644
--- a/include/opcode/riscv-opc-extended.h
+++ b/include/opcode/riscv-opc-extended.h
@@ -1520,3 +1520,575 @@ DECLARE_CSR(vl, CSR_VL, CSR_CLASS_V, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
 DECLARE_CSR(vtype, CSR_VTYPE, CSR_CLASS_V, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
 DECLARE_CSR(vlenb, CSR_VLENB, CSR_CLASS_V, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
 #endif /* DECLARE_CSR */
+
+
+#ifndef __RISCV_OPC_VENDOR_THEAD__
+#define __RISCV_OPC_VENDOR_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
+
+/* T-HEAD M mode CSR.  */
+#define CSR_MXSTATUS 0x7c0
+#define CSR_MHCR 0x7c1
+#define CSR_MCOR 0x7c2
+#define CSR_MCCR2 0x7c3
+#define CSR_MCER2 0x7c4
+#define CSR_MHINT 0x7c5
+#define CSR_MRMR 0x7c6
+#define CSR_MRVBR 0x7c7
+#define CSR_MCER 0x7c8
+#define CSR_MCOUNTERWEN 0x7c9
+#define CSR_MCOUNTERINTEN 0x7ca
+#define CSR_MCOUNTEROF 0x7cb
+#define CSR_MHINT2 0x7cc
+#define CSR_MHINT3 0x7cd
+#define CSR_MRADDR 0x7e0
+#define CSR_MEXSTATUS 0x7e1
+#define CSR_MNMICAUSE 0x7e2
+#define CSR_MNMIPC 0x7e3
+#define CSR_MHPMCR 0x7f0
+#define CSR_MHPMSR 0x7f1
+#define CSR_MHPMER 0x7f2
+#define CSR_MSMPR 0x7f3
+#define CSR_MTEECFG 0x7f4
+#define CSR_MZONEID 0x7f5
+#define CSR_ML2CPID 0x7f6
+#define CSR_ML2WP 0x7f7
+#define CSR_MDTCMCR 0x7f8
+#define CSR_USP 0x7d1
+#define CSR_MCINS 0x7d2
+#define CSR_MCINDEX 0x7d3
+#define CSR_MCDATA0 0x7d4
+#define CSR_MCDATA1 0x7d5
+#define CSR_MEICR 0x7d6
+#define CSR_MEICR2 0x7d7
+#define CSR_MBEADDR 0x7d8
+#define CSR_MCPUID 0xfc0
+#define CSR_MAPBADDR 0xfc1
+#define CSR_MWMSR 0xfc2
+#define CSR_MHALTCAUSE 0xfe0
+#define CSR_MDBGINFO 0xfe1
+#define CSR_MPCFIFO 0xfe2
+
+
+/* T-HEAD S mode CSR.  */
+#define CSR_SXSTATUS 0x5c0
+#define CSR_SHCR 0x5c1
+#define CSR_SCER2 0x5c2
+#define CSR_SCER 0x5c3
+#define CSR_SCOUNTERINTEN 0x5c4
+#define CSR_SCOUNTEROF 0x5c5
+#define CSR_SHINT 0x5c6
+#define CSR_SHINT2 0x5c7
+#define CSR_SHPMINHIBIT 0x5c8
+#define CSR_SHPMCR 0x5c9
+#define CSR_SHPMSR 0x5ca
+#define CSR_SHPMER 0x5cb
+#define CSR_SL2CPID 0x5cc
+#define CSR_SL2WP 0x5cd
+#define CSR_SBEADDR 0x5d0
+#define CSR_SCYCLE 0x5e0
+#define CSR_SHPMCOUNTER1 0x5e1
+#define CSR_SHPMCOUNTER2 0x5e2
+#define CSR_SHPMCOUNTER3 0x5e3
+#define CSR_SHPMCOUNTER4 0x5e4
+#define CSR_SHPMCOUNTER5 0x5e5
+#define CSR_SHPMCOUNTER6 0x5e6
+#define CSR_SHPMCOUNTER7 0x5e7
+#define CSR_SHPMCOUNTER8 0x5e8
+#define CSR_SHPMCOUNTER9 0x5e9
+#define CSR_SHPMCOUNTER10 0x5ea
+#define CSR_SHPMCOUNTER11 0x5eb
+#define CSR_SHPMCOUNTER12 0x5ec
+#define CSR_SHPMCOUNTER13 0x5ed
+#define CSR_SHPMCOUNTER14 0x5ee
+#define CSR_SHPMCOUNTER15 0x5ef
+#define CSR_SHPMCOUNTER16 0x5f0
+#define CSR_SHPMCOUNTER17 0x5f1
+#define CSR_SHPMCOUNTER18 0x5f2
+#define CSR_SHPMCOUNTER19 0x5f3
+#define CSR_SHPMCOUNTER20 0x5f4
+#define CSR_SHPMCOUNTER21 0x5f5
+#define CSR_SHPMCOUNTER22 0x5f6
+#define CSR_SHPMCOUNTER23 0x5f7
+#define CSR_SHPMCOUNTER24 0x5f8
+#define CSR_SHPMCOUNTER25 0x5f9
+#define CSR_SHPMCOUNTER26 0x5fa
+#define CSR_SHPMCOUNTER27 0x5fb
+#define CSR_SHPMCOUNTER28 0x5fc
+#define CSR_SHPMCOUNTER29 0x5fd
+#define CSR_SHPMCOUNTER30 0x5fe
+#define CSR_SHPMCOUNTER31 0x5ff
+
+/* T-HEAD U mode CSR.  */
+#define CSR_FXCR 0x800
+
+/* T-HEAD MMU extentions.  */
+#define CSR_SMIR 0x9c0
+#define CSR_SMEL 0x9c1
+#define CSR_SMEH 0x9c2
+#define CSR_SMCIR 0x9c3
+
+/* T-HEAD Security CSR(May be droped).  */
+#define CSR_MEBR 0xbe0
+#define CSR_NT_MSTATUS 0xbe1
+#define CSR_NT_MIE 0xbe2
+#define CSR_NT_MTVEC 0xbe3
+#define CSR_NT_MTVT 0xbe4
+#define CSR_NT_MEPC 0xbe5
+#define CSR_NT_MCAUSE 0xbe6
+#define CSR_NT_MIP 0xbe7
+#define CSR_NT_MINTSTATE 0xbe8
+#define CSR_NT_MXSTATUS 0xbe9
+#define CSR_NT_MEBR 0xbea
+#define CSR_NT_MSP 0xbeb
+#define CSR_T_USP 0xbec
+#define CSR_T_MDCR 0xbed
+#define CSR_T_MPCR 0xbee
+#define CSR_PMPTEECFG 0xbef
+#endif
+
+#ifdef DECLARE_INSN
+DECLARE_INSN(wsc, MATCH_WSC, MASK_WSC)
+DECLARE_INSN(dcache.iall, MATCH_DCACHE_IALL, MASK_DCACHE_IALL)
+DECLARE_INSN(dcache.call, MATCH_DCACHE_CALL, MASK_DCACHE_CALL)
+DECLARE_INSN(dcache.ciall, MATCH_DCACHE_CIALL, MASK_DCACHE_CIALL)
+DECLARE_INSN(dcache.isw, MATCH_DCACHE_ISW, MASK_DCACHE_ISW, match_opcode, 0)
+DECLARE_INSN(dcache.csw, MATCH_DCACHE_CSW, MASK_DCACHE_CSW)
+DECLARE_INSN(dcache.cisw, MATCH_DCACHE_CISW, MASK_DCACHE_CISW)
+DECLARE_INSN(dcache.iva, MATCH_DCACHE_IVA, MASK_DCACHE_IVA)
+DECLARE_INSN(dcache.cva, MATCH_DCACHE_CVA, MASK_DCACHE_CVA)
+DECLARE_INSN(dcache.cval1, MATCH_DCACHE_CVAL1, MASK_DCACHE_CVAL1)
+DECLARE_INSN(dcache.civa, MATCH_DCACHE_CIVA, MASK_DCACHE_CIVA)
+DECLARE_INSN(dcache.ipa, MATCH_DCACHE_IPA, MASK_DCACHE_IPA)
+DECLARE_INSN(dcache.cpa, MATCH_DCACHE_CPA, MASK_DCACHE_CPA)
+DECLARE_INSN(dcache.cpal1, MATCH_DCACHE_CPAL1, MASK_DCACHE_CPAL1)
+DECLARE_INSN(dcache.cipa, MATCH_DCACHE_CIPA, MASK_DCACHE_CIPA)
+DECLARE_INSN(icache.iall, MATCH_ICACHE_IALL, MASK_ICACHE_IALL)
+DECLARE_INSN(icache.iall, MATCH_ICACHE_IALL, MASK_ICACHE_IALL, match_opcode)
+DECLARE_INSN(icache.ialls, MATCH_ICACHE_IALLS, MASK_ICACHE_IALLS)
+DECLARE_INSN(icache.iva, MATCH_ICACHE_IVA, MASK_ICACHE_IVA)
+DECLARE_INSN(icache.ipa, MATCH_ICACHE_IPA, MASK_ICACHE_IPA)
+DECLARE_INSN(l2cache.iall, MATCH_L2CACHE_IALL, MASK_L2CACHE_IALL)
+DECLARE_INSN(l2cache.call, MATCH_L2CACHE_CALL, MASK_L2CACHE_CALL)
+DECLARE_INSN(l2cache.ciall, MATCH_L2CACHE_CIALL, MASK_L2CACHE_CIALL)
+DECLARE_INSN(sync, MATCH_SYNC, MASK_SYNC)
+DECLARE_INSN(sync.i, MATCH_SYNC_I, MASK_SYNC_I)
+DECLARE_INSN(sync.s, MATCH_SYNC_S, MASK_SYNC_S)
+DECLARE_INSN(sync.is, MATCH_SYNC_IS, MASK_SYNC_IS)
+DECLARE_INSN(tstnbz, MATCH_TSTNBZ, MASK_TSTNBZ)
+DECLARE_INSN(mula, MATCH_MULA, MASK_MULA)
+DECLARE_INSN(muls, MATCH_MULS, MASK_MULS)
+DECLARE_INSN(mulah, MATCH_MULAH, MASK_MULAH)
+DECLARE_INSN(mulsh, MATCH_MULSH, MASK_MULSH)
+DECLARE_INSN(sfence.vmas, MATCH_SFENCE_VMAS, MASK_SFENCE_VMAS)
+DECLARE_INSN(mveqz, MATCH_MVEQZ, MASK_MVEQZ)
+DECLARE_INSN(mvnez, MATCH_MVNEZ, MASK_MVNEZ)
+DECLARE_INSN(mulaw, MATCH_MULAW, MASK_MULAW)
+DECLARE_INSN(mulsw, MATCH_MULSW, MASK_MULSW)
+DECLARE_INSN(ext, MATCH_EXT, MASK_EXT)
+DECLARE_INSN(ext, MATCH_EXT, (MASK_EXT | (1U<<25) | (1U<<31)))
+DECLARE_INSN(extu, MATCH_EXTU, MASK_EXTU)
+DECLARE_INSN(extu, MATCH_EXTU, (MASK_EXTU | (1U<<25) | (1U<<31)))
+DECLARE_INSN(ff1, MATCH_FF1, MASK_FF1)
+DECLARE_INSN(ff0, MATCH_FF0, MASK_FF1)
+DECLARE_INSN(rev, MATCH_REV, MASK_REV)
+DECLARE_INSN(lrb, MATCH_LRB, MASK_LRB)
+DECLARE_INSN(lrbu, MATCH_LRBU, MASK_LRBU)
+DECLARE_INSN(lrh, MATCH_LRH, MASK_LRH)
+DECLARE_INSN(lrhu, MATCH_LRHU, MASK_LRHU)
+DECLARE_INSN(lrw, MATCH_LRW, MASK_LRW)
+DECLARE_INSN(lrwu, MATCH_LRWU, MASK_LRWU)
+DECLARE_INSN(srb, MATCH_SRB, MASK_SRB)
+DECLARE_INSN(srh, MATCH_SRH, MASK_SRH)
+DECLARE_INSN(srw, MATCH_SRW, MASK_SRW)
+DECLARE_INSN(lrd, MATCH_LRD, MASK_LRD)
+DECLARE_INSN(srd, MATCH_SRD, MASK_SRD)
+DECLARE_INSN(lurb, MATCH_LURB, MASK_LURB)
+DECLARE_INSN(lurbu, MATCH_LURBU, MASK_LURBU)
+DECLARE_INSN(lurh, MATCH_LURH, MASK_LURH)
+DECLARE_INSN(lurhu, MATCH_LURHU, MASK_LURHU)
+DECLARE_INSN(lurw, MATCH_LURW, MASK_LURW)
+DECLARE_INSN(lurwu, MATCH_LURWU, MASK_LURWU)
+DECLARE_INSN(lurd, MATCH_LURD, MASK_LURD)
+DECLARE_INSN(surb, MATCH_SURB, MASK_SURB)
+DECLARE_INSN(surh, MATCH_SURH, MASK_SURH)
+DECLARE_INSN(surw, MATCH_SURW, MASK_SURW)
+DECLARE_INSN(surd, MATCH_SURD, MASK_SURD)
+DECLARE_INSN(tst, MATCH_TST, MASK_TST)
+DECLARE_INSN(tst, MATCH_TST, (MASK_TST | (1U << 25)), match_opcode)
+DECLARE_INSN(srriw, MATCH_SRRIW, MASK_SRRIW)
+DECLARE_INSN(srri, MATCH_SRRI, MASK_SRRI)
+DECLARE_INSN(addsl, MATCH_ADDSL, MASK_ADDSL)
+DECLARE_INSN(lwd, MATCH_LWD, MASK_LWD)
+DECLARE_INSN(ldd, MATCH_LDD, MASK_LDD)
+DECLARE_INSN(swd, MATCH_SWD, MASK_SWD)
+DECLARE_INSN(sdd, MATCH_SDD, MASK_SDD)
+DECLARE_INSN(sdia, MATCH_SDIA, MASK_SDIA)
+DECLARE_INSN(sdib, MATCH_SDIB, MASK_SDIB)
+DECLARE_INSN(lwud, MATCH_LWUD, MASK_LWUD)
+DECLARE_INSN(lwud, MATCH_LWUD, MASK_LWUD)
+DECLARE_INSN(swia, MATCH_SWIA, MASK_SWIA)
+DECLARE_INSN(swib, MATCH_SWIB, MASK_SWIB)
+DECLARE_INSN(shia, MATCH_SHIA, MASK_SHIA)
+DECLARE_INSN(shib, MATCH_SHIB, MASK_SHIB)
+DECLARE_INSN(sbia, MATCH_SBIA, MASK_SBIA)
+DECLARE_INSN(sbib, MATCH_SBIB, MASK_SBIB)
+DECLARE_INSN(lwuia, MATCH_LWUIA, MASK_LWUIA)
+DECLARE_INSN(lwuib, MATCH_LWUIB, MASK_LWUIB)
+DECLARE_INSN(lhuia, MATCH_LHUIA, MASK_LHUIA)
+DECLARE_INSN(lhuib, MATCH_LHUIB, MASK_LHUIB)
+DECLARE_INSN(lbuia, MATCH_LBUIA, MASK_LBUIA)
+DECLARE_INSN(lbuib, MATCH_LBUIB, MASK_LBUIB)
+DECLARE_INSN(ldia, MATCH_LDIA, MASK_LDIA)
+DECLARE_INSN(ldib, MATCH_LDIB, MASK_LDIB)
+DECLARE_INSN(lwia, MATCH_LWIA, MASK_LWIA)
+DECLARE_INSN(lwib, MATCH_LWIB, MASK_LWIB)
+DECLARE_INSN(lhia, MATCH_LHIA, MASK_LHIA)
+DECLARE_INSN(lhib, MATCH_LHIB, MASK_LHIB)
+DECLARE_INSN(lbia, MATCH_LBIA, MASK_LBIA)
+DECLARE_INSN(lbib, MATCH_LBIB, MASK_LBIB)
+DECLARE_INSN(fsurd, MATCH_FSURD, MASK_FSURD)
+DECLARE_INSN(revw, MATCH_REVW, MASK_REVW)
+DECLARE_INSN(fsurw, MATCH_FSURW, MASK_FSURW)
+DECLARE_INSN(flurd, MATCH_FLURD, MASK_FLURD)
+DECLARE_INSN(flurw, MATCH_FLURW, MASK_FLURW)
+DECLARE_INSN(fsrd, MATCH_FSRD, MASK_FSRD)
+DECLARE_INSN(fsrw, MATCH_FSRW, MASK_FSRW)
+DECLARE_INSN(flrd, MATCH_FLRD, MASK_FLRD)
+DECLARE_INSN(flrw, MATCH_FLRW, MASK_FLRW)
+DECLARE_INSN(ipush, MATCH_IPUSH, MASK_IPUSH)
+DECLARE_INSN(ipop, MATCH_IPOP, MASK_IPOP)
+DECLARE_INSN(fmv.x.hw, MATCH_FMV_X_HW, MASK_FMV_X_HW)
+DECLARE_INSN(fmv.hw.x, MATCH_FMV_HW_X, MASK_FMV_HW_X)
+#endif /* DECLARE_INSN */
+
+#ifdef DECLARE_CSR
+/* T-HEAD extentions.  */
+DECLARE_CSR(mxstatus, CSR_MXSTATUS, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mhcr, CSR_MHCR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcor, CSR_MCOR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mccr2, CSR_MCCR2, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcer2, CSR_MCER2, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mhint, CSR_MHINT, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mrmr, CSR_MRMR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mrvbr, CSR_MRVBR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcer, CSR_MCER, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcounterwen, CSR_MCOUNTERWEN, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcounterinten, CSR_MCOUNTERINTEN, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcounterof, CSR_MCOUNTEROF, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mhint2, CSR_MHINT2, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mhint3, CSR_MHINT3, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mraddr, CSR_MRADDR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mexstatus, CSR_MEXSTATUS, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mnmicause, CSR_MNMICAUSE, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mnmipc, CSR_MNMIPC, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mhpmcr, CSR_MHPMCR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mhpmsr, CSR_MHPMSR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mhpmer, CSR_MHPMER, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(msmpr, CSR_MSMPR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mteecfg, CSR_MTEECFG, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mzoneid, CSR_MZONEID, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(ml2cpid, CSR_ML2CPID, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(ml2wp, CSR_ML2WP, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mdtcmcr, CSR_MDTCMCR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(usp, CSR_USP, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcins, CSR_MCINS, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcindex, CSR_MCINDEX, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcdata0, CSR_MCDATA0, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcdata1, CSR_MCDATA1, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(meicr, CSR_MEICR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(meicr2, CSR_MEICR2, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mbeaddr, CSR_MBEADDR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mebr, CSR_MEBR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_mstatus, CSR_NT_MSTATUS, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_mtvec, CSR_NT_MTVEC, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_mie, CSR_NT_MIE, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_mtvt, CSR_NT_MTVT, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_mepc, CSR_NT_MEPC, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_mcause, CSR_NT_MCAUSE, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_mip, CSR_NT_MIP, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_mintstate, CSR_NT_MINTSTATE, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_mxstatus, CSR_NT_MXSTATUS, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_mebr, CSR_NT_MEBR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(nt_msp, CSR_NT_MSP, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(t_usp, CSR_T_USP, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(t_mdcr, CSR_T_MDCR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(t_mpcr, CSR_T_MPCR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(pmpteecfg, CSR_PMPTEECFG, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mcpuid, CSR_MCPUID, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mapbaddr, CSR_MAPBADDR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(mwmsr, CSR_MWMSR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(fxcr, CSR_FXCR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(smir, CSR_SMIR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(smel, CSR_SMEL, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(smeh, CSR_SMEH, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(smcir, CSR_SMCIR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(sxstatus, CSR_SXSTATUS, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shcr, CSR_SHCR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(scer2, CSR_SCER2, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(scer, CSR_SCER, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(scounterinten , CSR_SCOUNTERINTEN, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(scounterof, CSR_SCOUNTEROF, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shint, CSR_SHINT, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shint2, CSR_SHINT2, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpminhibit, CSR_SHPMINHIBIT, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcr, CSR_SHPMCR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmsr, CSR_SHPMSR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmer, CSR_SHPMER, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(sl2cpid, CSR_SL2CPID, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(sl2wp, CSR_SL2WP, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(sbeaddr, CSR_SBEADDR, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(scycle, CSR_SCYCLE, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter1, CSR_SHPMCOUNTER1, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter2, CSR_SHPMCOUNTER2, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter3, CSR_SHPMCOUNTER3, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter4, CSR_SHPMCOUNTER4, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter5, CSR_SHPMCOUNTER5, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter6, CSR_SHPMCOUNTER6, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter7, CSR_SHPMCOUNTER7, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter8, CSR_SHPMCOUNTER8, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter9, CSR_SHPMCOUNTER9, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter10, CSR_SHPMCOUNTER10, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter11, CSR_SHPMCOUNTER11, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter12, CSR_SHPMCOUNTER12, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter13, CSR_SHPMCOUNTER13, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter14, CSR_SHPMCOUNTER14, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter15, CSR_SHPMCOUNTER15, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter16, CSR_SHPMCOUNTER16, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter17, CSR_SHPMCOUNTER17, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter18, CSR_SHPMCOUNTER18, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter19, CSR_SHPMCOUNTER19, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter20, CSR_SHPMCOUNTER20, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter21, CSR_SHPMCOUNTER21, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter22, CSR_SHPMCOUNTER22, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter23, CSR_SHPMCOUNTER23, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter24, CSR_SHPMCOUNTER24, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter25, CSR_SHPMCOUNTER25, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter26, CSR_SHPMCOUNTER26, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter27, CSR_SHPMCOUNTER27, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter28, CSR_SHPMCOUNTER28, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter29, CSR_SHPMCOUNTER29, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter30, CSR_SHPMCOUNTER30, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+DECLARE_CSR(shpmcounter31, CSR_SHPMCOUNTER31, CSR_CLASS_VENDOR_THEAD, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+#endif
+
+
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index 8d5251c..2719393 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -496,6 +496,13 @@ enum riscv_extended_insn_class
   INSN_CLASS_D_AND_ZFH,
   INSN_CLASS_Q_AND_ZFH,
   INSN_CLASS_SVINVAL,
+
+  /* INSN class for THEAD.  */
+  INSN_CLASS_THEADC,
+  INSN_CLASS_THEADC_OR_THEADE,
+  INSN_CLASS_THEADC_OR_THEADE_OR_THEADSE,
+  INSN_CLASS_THEADE,
+  INSN_CLASS_THEADSE,
 };

 /* This is a list of macro expanded instructions for extended
@@ -518,4 +525,21 @@ extern const char * const riscv_vma[2];

 extern const struct riscv_opcode *riscv_extended_opcodes[];

+/* 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 dcc5a09..33aff18 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -255,6 +255,51 @@ print_extended_insn_args (const char **opcode_args,
  }
       break;

+    case 'X':
+ {
+   int nbit = 0;
+   int at = -1;
+   char c = 0;
+   int shift = 0;
+   oparg++;
+   c = *oparg++;
+   switch (c)
+     {
+     case 'I':
+       nbit = strtol (oparg, (char **)&oparg, 10);
+       if ((*oparg) =='@')
+  at = strtol(++oparg, (char **)&oparg, 10);
+
+       oparg--;
+
+       print (info->stream, "%d", (unsigned int)(EXTRACT_VENDOR_THEAD_IMM(l, nbit, at) << shift));
+       break;
+     case 'S':
+       nbit = strtol (oparg, (char **)&oparg, 10);
+       if ((*oparg) =='<' && (*(oparg + 1) == '<'))
+  {
+    oparg += 2;
+    shift = strtol (oparg, (char **)&oparg, 10);
+  }
+       if ((*oparg) =='@')
+  at = strtol(++oparg, (char **)&oparg, 10);
+
+       oparg--;
+
+       print (info->stream, "%d", (unsigned)(EXTRACT_VENDOR_THEAD_SIGN_IMM(l, nbit, at) << shift));
+       break;
+     case 'g':
+       nbit = strtol (oparg, (char **)&oparg, 10);
+       if ((*oparg) =='@')
+  at = strtol(++oparg, (char **)&oparg, 10);
+
+       oparg--;
+       print (info->stream, "%s", riscv_gpr_names[EXTRACT_VENDOR_THEAD_IMM(l, nbit, at)]);
+       break;
+     }
+ }
+      break;
+
     default:
       return false;
     }
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index c8e7734..05f9470 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -2219,9 +2219,169 @@ const struct riscv_opcode riscv_draft_opcodes[] =
 {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0 },
 };

+
+/* Vendor T-HEAD opcodes.  */
+/*
+   ARG format:
+
+   "Xgm@n": encode GPR with m bit at opcode[m+n-1:n].
+    "Xg5@0": encode GPR with 5 bit at opcode[4:0].
+    "Xg5@8": encode GPR with 5 bit at opcode[12:8].
+
+   "XIm@n": m bits unsigned immediate at opcode[m+n-1:n].
+    "XI5@0": 5 bits unsigned immediate at opcode[4:0].
+    "XI4@8": 4 bits unsigned immediate at opcode[11:8].
+
+   "XSm@n": m bits signed immediate at opcode[m+n-1:n].
+    "XS5@0": 5 bits signed immediate at opcode[4:0].
+    "XS4@8": 4 bits signed immediate at opcode[11:8].
+
+   "XFm@n": m bits FR at opcode[m+n-1:n].
+    "XF5@0": 5 bits FR at opcode[4:0].
+    "XF5@0": 5 bits FR at opcode[4:0].
+*/
+
+static int
+match_thead_rd1_rd2_neq_rs1(const struct riscv_opcode *op,
+       insn_t insn,
+       int constraints,
+       const char **error)
+{
+  int rd1 = (insn & MASK_RD) >> OP_SH_RD;
+  int rd2 = (insn & MASK_RS2) >> OP_SH_RS2;
+  int rs1 = (insn & MASK_RS1) >> OP_SH_RS1;
+
+  /* FIXME: add xlen check.  */
+  return match_opcode (op, insn, constraints, error) && rd1 != rs1 && rd2 != rs1;
+}
+
+/* The vendor extension opcodes for T-HEAD.  */
+struct riscv_opcode riscv_vendor_thead_opcodes[] =
+{
+  {"wsc",             0, INSN_CLASS_THEADC_OR_THEADE,   "",  MATCH_WSC, MASK_WSC, match_opcode, 0},
+  {"dcache.iall",     0, INSN_CLASS_THEADC_OR_THEADE,   "",  MATCH_DCACHE_IALL, MASK_DCACHE_IALL, match_opcode, 0},
+  {"dcache.call",     0, INSN_CLASS_THEADC_OR_THEADE,   "",  MATCH_DCACHE_CALL, MASK_DCACHE_CALL, match_opcode, 0},
+  {"dcache.ciall",    0, INSN_CLASS_THEADC_OR_THEADE,   "",  MATCH_DCACHE_CIALL, MASK_DCACHE_CIALL, match_opcode, 0},
+  {"dcache.isw",      0, INSN_CLASS_THEADC_OR_THEADE,   "s",     MATCH_DCACHE_ISW, MASK_DCACHE_ISW, match_opcode, 0},
+  {"dcache.csw",      0, INSN_CLASS_THEADC_OR_THEADE,   "s",     MATCH_DCACHE_CSW, MASK_DCACHE_CSW, match_opcode, 0},
+  {"dcache.cisw",     0, INSN_CLASS_THEADC_OR_THEADE,   "s",     MATCH_DCACHE_CISW, MASK_DCACHE_CISW, match_opcode, 0},
+  {"dcache.iva",      0, INSN_CLASS_THEADC,   "s",     MATCH_DCACHE_IVA, MASK_DCACHE_IVA, match_opcode, 0},
+  {"dcache.cva",      0, INSN_CLASS_THEADC,   "s",     MATCH_DCACHE_CVA, MASK_DCACHE_CVA, match_opcode, 0},
+  {"dcache.cval1",    0, INSN_CLASS_THEADC,   "s",     MATCH_DCACHE_CVAL1, MASK_DCACHE_CVAL1, match_opcode, 0},
+  {"dcache.civa",     0, INSN_CLASS_THEADC,   "s",     MATCH_DCACHE_CIVA, MASK_DCACHE_CIVA, match_opcode, 0},
+  {"dcache.ipa",      0, INSN_CLASS_THEADC_OR_THEADE,   "s",     MATCH_DCACHE_IPA, MASK_DCACHE_IPA, match_opcode, 0},
+  {"dcache.cpa",      0, INSN_CLASS_THEADC_OR_THEADE,   "s",     MATCH_DCACHE_CPA, MASK_DCACHE_CPA, match_opcode, 0},
+  {"dcache.cpal1",    0, INSN_CLASS_THEADC,   "s",     MATCH_DCACHE_CPAL1, MASK_DCACHE_CPAL1, match_opcode, 0},
+  {"dcache.cipa",     0, INSN_CLASS_THEADC_OR_THEADE,   "s",     MATCH_DCACHE_CIPA, MASK_DCACHE_CIPA, match_opcode, 0},
+  {"icache.iall",     0, INSN_CLASS_THEADC_OR_THEADE_OR_THEADSE,   "",      MATCH_ICACHE_IALL, MASK_ICACHE_IALL, match_opcode, 0},
+  {"icache.iall",     0, INSN_CLASS_THEADSE,   "",      MATCH_ICACHE_IALL, MASK_ICACHE_IALL, match_opcode, INSN_ALIAS},
+  {"icache.ialls",    0, INSN_CLASS_THEADC,   "",      MATCH_ICACHE_IALLS, MASK_ICACHE_IALLS, match_opcode, 0},
+  {"icache.iva",      0, INSN_CLASS_THEADC,   "s",     MATCH_ICACHE_IVA, MASK_ICACHE_IVA, match_opcode, 0},
+  {"icache.ipa",      0, INSN_CLASS_THEADC_OR_THEADE,   "s",     MATCH_ICACHE_IPA, MASK_ICACHE_IPA, match_opcode, 0},
+  {"l2cache.iall",    0, INSN_CLASS_THEADC,   "",      MATCH_L2CACHE_IALL, MASK_L2CACHE_IALL, match_opcode, 0},
+  {"l2cache.call",    0, INSN_CLASS_THEADC,   "",      MATCH_L2CACHE_CALL, MASK_L2CACHE_CALL, match_opcode, 0},
+  {"l2cache.ciall",   0, INSN_CLASS_THEADC_OR_THEADE,   "",      MATCH_L2CACHE_CIALL, MASK_L2CACHE_CIALL, match_opcode, 0},
+  {"sync",            0, INSN_CLASS_THEADC_OR_THEADE,   "",      MATCH_SYNC, MASK_SYNC, match_opcode, 0},
+  {"sync.i",          0, INSN_CLASS_THEADC_OR_THEADE,   "",      MATCH_SYNC_I, MASK_SYNC_I, match_opcode, 0},
+  {"sync.s",          0, INSN_CLASS_THEADC,   "",      MATCH_SYNC_S, MASK_SYNC_S, match_opcode, 0},
+  {"sync.is",         0, INSN_CLASS_THEADC,   "",      MATCH_SYNC_IS, MASK_SYNC_IS, match_opcode, 0},
+  {"tstnbz",          0, INSN_CLASS_THEADC_OR_THEADE,   "d,s",     MATCH_TSTNBZ, MASK_TSTNBZ, match_opcode, 0},
+  {"mula",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MULA, MASK_MULA, match_opcode, 0},
+  {"muls",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MULS, MASK_MULS, match_opcode, 0},
+  {"mulah",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MULAH, MASK_MULAH, match_opcode, 0},
+  {"mulsh",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MULSH, MASK_MULSH, match_opcode, 0},
+  {"sfence.vmas",     0, INSN_CLASS_THEADC,   "s,t",      MATCH_SFENCE_VMAS, MASK_SFENCE_VMAS, match_opcode, 0},
+  {"mveqz",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MVEQZ, MASK_MVEQZ, match_opcode, 0},
+  {"mvnez",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MVNEZ, MASK_MVNEZ, match_opcode, 0},
+  {"mulaw",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MULAW, MASK_MULAW, match_opcode, 0},
+  {"mulsw",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t",   MATCH_MULSW, MASK_MULSW, match_opcode, 0},
+  {"ext",             64, INSN_CLASS_THEADC,  "d,s,XI6@26,XI6@20",   MATCH_EXT, MASK_EXT, match_opcode, 0 },
+  {"ext",             32, INSN_CLASS_THEADE,  "d,s,XI5@26,XI5@20",   MATCH_EXT, (MASK_EXT | (1U<<25) | (1U<<31)), match_opcode, 0 },
+  {"extu",            64, INSN_CLASS_THEADC,  "d,s,XI6@26,XI6@20",   MATCH_EXTU, MASK_EXTU, match_opcode, 0 },
+  {"extu",            32, INSN_CLASS_THEADE,  "d,s,XI5@26,XI5@20",   MATCH_EXTU, (MASK_EXTU | (1U<<25) | (1U<<31)), match_opcode, 0 },
+  {"ff1",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s",   MATCH_FF1, MASK_FF1, match_opcode, 0},
+  {"ff0",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s",   MATCH_FF0, MASK_FF1, match_opcode, 0},
+  {"rev",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s",   MATCH_REV, MASK_REV, match_opcode, 0},
+  {"lrb",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_LRB, MASK_LRB, match_opcode, 0 },
+  {"lrbu",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_LRBU, MASK_LRBU, match_opcode, 0 },
+  {"lrh",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_LRH, MASK_LRH, match_opcode, 0 },
+  {"lrhu",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_LRHU, MASK_LRHU, match_opcode, 0 },
+  {"lrw",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_LRW, MASK_LRW, match_opcode, 0 },
+  {"lrwu",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_LRWU, MASK_LRWU, match_opcode, 0 },
+  {"srb",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_SRB, MASK_SRB, match_opcode, 0 },
+  {"srh",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_SRH, MASK_SRH, match_opcode, 0 },
+  {"srw",             0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25",   MATCH_SRW, MASK_SRW, match_opcode, 0 },
+  {"lrd",             0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LRD, MASK_LRD, match_opcode, 0 },
+  {"srd",             0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_SRD, MASK_SRD, match_opcode, 0 },
+  {"lurb",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LURB, MASK_LURB, match_opcode, 0 },
+  {"lurbu",           0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LURBU, MASK_LURBU, match_opcode, 0 },
+  {"lurh",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LURH, MASK_LURH, match_opcode, 0 },
+  {"lurhu",           0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LURHU, MASK_LURHU, match_opcode, 0 },
+  {"lurw",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LURW, MASK_LURW, match_opcode, 0 },
+  {"lurwu",           0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LURWU, MASK_LURWU, match_opcode, 0 },
+  {"lurd",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_LURD, MASK_LURD, match_opcode, 0 },
+  {"surb",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_SURB, MASK_SURB, match_opcode, 0 },
+  {"surh",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_SURH, MASK_SURH, match_opcode, 0 },
+  {"surw",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_SURW, MASK_SURW, match_opcode, 0 },
+  {"surd",            0, INSN_CLASS_THEADC,   "d,s,t,XI2@25",   MATCH_SURD, MASK_SURD, match_opcode, 0 },
+  {"tst",             64, INSN_CLASS_THEADC,  "d,s,XI6@20",   MATCH_TST, MASK_TST, match_opcode, 0 },
+  {"tst",             32, INSN_CLASS_THEADE,   "d,s,XI5@20",   MATCH_TST, (MASK_TST | (1U << 25)), match_opcode, INSN_ALIAS},
+  {"srriw",           0, INSN_CLASS_THEADC,   "d,s,XI5@20",   MATCH_SRRIW, MASK_SRRIW, match_opcode, 0 },
+  {"srri",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,XI6@20",   MATCH_SRRI, MASK_SRRI, match_opcode, 0 },
+  {"addsl",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,s,t,XI2@25", MATCH_ADDSL, MASK_ADDSL, match_opcode, 0 },
+  {"lwd",             0, INSN_CLASS_THEADC,   "d,t,(s),XI2@25", MATCH_LWD, MASK_LWD, match_thead_rd1_rd2_neq_rs1, 0 },
+  {"ldd",             0, INSN_CLASS_THEADC,   "d,t,(s),XI2@25", MATCH_LDD, MASK_LDD, match_thead_rd1_rd2_neq_rs1, 0 },
+  {"swd",             0, INSN_CLASS_THEADC,   "d,t,(s),XI2@25", MATCH_SWD, MASK_SWD, match_opcode, 0 },
+  {"sdd",             0, INSN_CLASS_THEADC,   "d,t,(s),XI2@25", MATCH_SDD, MASK_SDD, match_opcode, 0 },
+  {"sdia",            0, INSN_CLASS_THEADC,   "d,(s),XS5@20,XI2@25", MATCH_SDIA, MASK_SDIA, match_opcode, 0 },
+  {"sdib",            0, INSN_CLASS_THEADC,   "d,(s),XS5@20,XI2@25", MATCH_SDIB, MASK_SDIB, match_opcode, 0 },
+  {"lwud",            0, INSN_CLASS_THEADC,   "d,t,(s),XI2@25", MATCH_LWUD, MASK_LWUD, match_thead_rd1_rd2_neq_rs1, 0 },
+  {"swia",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_SWIA, MASK_SWIA, match_opcode, 0},
+  {"swib",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_SWIB, MASK_SWIB, match_opcode, 0},
+  {"shia",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_SHIA, MASK_SHIA, match_opcode, 0},
+  {"shib",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_SHIB, MASK_SHIB, match_opcode, 0},
+  {"sbia",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_SBIA, MASK_SBIA, match_opcode, 0},
+  {"sbib",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_SBIB, MASK_SBIB, match_opcode, 0},
+  {"lwuia",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LWUIA, MASK_LWUIA, match_opcode, 0},
+  {"lwuib",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LWUIB, MASK_LWUIB, match_opcode, 0},
+  {"lhuia",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LHUIA, MASK_LHUIA, match_opcode, 0},
+  {"lhuib",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LHUIB, MASK_LHUIB, match_opcode, 0},
+  {"lbuia",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LBUIA, MASK_LBUIA, match_opcode, 0},
+  {"lbuib",           0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LBUIB, MASK_LBUIB, match_opcode, 0},
+  {"ldia",            0, INSN_CLASS_THEADC,   "d,(s),XS5@20,XI2@25", MATCH_LDIA, MASK_LDIA, match_opcode, 0},
+  {"ldib",            0, INSN_CLASS_THEADC,   "d,(s),XS5@20,XI2@25", MATCH_LDIB, MASK_LDIB, match_opcode, 0},
+  {"lwia",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LWIA, MASK_LWIA, match_opcode, 0},
+  {"lwib",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LWIB, MASK_LWIB, match_opcode, 0},
+  {"lhia",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LHIA, MASK_LHIA, match_opcode, 0},
+  {"lhib",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LHIB, MASK_LHIB, match_opcode, 0},
+  {"lbia",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LBIA, MASK_LBIA, match_opcode, 0},
+  {"lbib",            0, INSN_CLASS_THEADC_OR_THEADE,   "d,(s),XS5@20,XI2@25", MATCH_LBIB, MASK_LBIB, match_opcode, 0},
+  {"fsurd",           0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FSURD, MASK_FSURD, match_opcode, 0},
+  {"revw",            0, INSN_CLASS_THEADC,   "d,s", MATCH_REVW, MASK_REVW, match_opcode, 0},
+  {"fsurw",           0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FSURW, MASK_FSURW, match_opcode, 0},
+  {"flurd",           0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FLURD, MASK_FLURD, match_opcode, 0},
+  {"flurw",           0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FLURW, MASK_FLURW, match_opcode, 0},
+  {"fsrd",            0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FSRD, MASK_FSRD, match_opcode, 0},
+  {"fsrw",            0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FSRW, MASK_FSRW, match_opcode, 0},
+  {"flrd",            0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FLRD, MASK_FLRD, match_opcode, 0},
+  {"flrw",            0, INSN_CLASS_THEADC,   "D,s,t,XI2@25", MATCH_FLRW, MASK_FLRW, match_opcode, 0},
+
+  /* THEADE only.  */
+  {"ipush",           0, INSN_CLASS_THEADE,   "",  MATCH_IPUSH, MASK_IPUSH, match_opcode, 0},
+  {"ipop",            0, INSN_CLASS_THEADE,   "",  MATCH_IPOP, MASK_IPOP, match_opcode, 0},
+  /* Float move.  */
+  {"fmv.x.hw",        32, INSN_CLASS_THEADE,  "d,S",  MATCH_FMV_X_HW, MASK_FMV_X_HW, match_opcode, 0},
+  {"fmv.hw.x",        32, INSN_CLASS_THEADE,  "D,s",  MATCH_FMV_HW_X, MASK_FMV_HW_X, match_opcode, 0},
+
+
+  {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}
+
+};
+
 /* The supported extended extensions.  */
 const struct riscv_opcode *riscv_extended_opcodes[] =
 {
   riscv_draft_opcodes,
+  riscv_vendor_thead_opcodes,
   NULL
 };
-- 
2.6.0-rc0

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

* Re: [integration 0/1] RISC-V: Add CSRs and opcodes of T-HEAD XUANTIE CPUs
  2021-09-07  9:20 ` [integration 0/1] RISC-V: Add CSRs and opcodes of T-HEAD XUANTIE CPUs Lifang Xia
  2021-09-07  9:20   ` [PATCH] RISC-V: Add CSRs and opcodes of the " Lifang Xia
@ 2021-09-13 11:07   ` Nelson Chu
  1 sibling, 0 replies; 10+ messages in thread
From: Nelson Chu @ 2021-09-13 11:07 UTC (permalink / raw)
  To: Lifang Xia; +Cc: Binutils, rjiejie

On Tue, Sep 7, 2021 at 5:20 PM Lifang Xia <lifang_xia@c-sky.com> wrote:
>
>
> Hi Nelson,
> Thanks for reveiwing these patches.
> That's my fault that I'm not checking these patches in
> binutils-integration-branch. I thought there are not much changes from
> master. Sorry. :(

That' fine :)

> I re-write the patches, merge them to one patch here.

The v2 version looks pretty good to me, thanks!  Committed.

> The extended solutions is suitable for adding CSRs and opcodes of T-HEAD
> XUANTIE CPUs.
> As you metioned in the previous e-mail, I agree with that it is not a
> good solution for vendors. Is there any discussions about that?

Not yet, but we can discuss and update them in the future.  Currently
your patch is good enough, so I already committed it, with some minor
updates.  Most of the updates are related to GNU coding standards.
Besides, I renamed ISA_SPEC_CLASS_VENDOR_THEAD to
VENDOR_SPEC_CLASS_THEAD, since I suppose vendor extensions should be
controlled by vendor specs, rather than the isa spec.

However, we are considering moving the stable vendor stuff back to the
mainline, based on the extended structures.  So before that, the
t-head and vendor extension will be maintained at the integration
branch for now.

Thanks
Nelson

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

end of thread, other threads:[~2021-09-13 11:08 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-03  2:59 [Integration 0/2] RISC-V: Add vendor(T-HEAD) opcodes Lifang Xia
2021-09-03  3:00 ` [Integration 1/2] RISC-V: add vendor opcodes Lifang Xia
2021-09-03  4:00   ` Nelson Chu
2021-09-03  3:00 ` [Integration 2/2] RISC-V: Update csr and opcodes for Xuantie CPUs Lifang Xia
2021-09-03  4:27   ` Nelson Chu
2021-09-03  4:37 ` [Integration 0/2] RISC-V: Add vendor(T-HEAD) opcodes Nelson Chu
2021-09-07  9:20 ` [integration 0/1] RISC-V: Add CSRs and opcodes of T-HEAD XUANTIE CPUs Lifang Xia
2021-09-07  9:20   ` [PATCH] RISC-V: Add CSRs and opcodes of the " Lifang Xia
2021-09-07  9:27     ` 夏立方
2021-09-13 11:07   ` [integration 0/1] RISC-V: Add CSRs and opcodes of " Nelson Chu

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