public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/2] RISC-V: Add vendor opcodes
@ 2021-08-27  3:39 Lifang Xia
  2021-08-27  3:39 ` [PATCH 1/2] RISC-V: add " Lifang Xia
  2021-08-27  3:39 ` [PATCH 2/2] RISC-V: Update csr and opcodes for Xuantie CPUs Lifang Xia
  0 siblings, 2 replies; 5+ messages in thread
From: Lifang Xia @ 2021-08-27  3:39 UTC (permalink / raw)
  To: binutils, palmer, jimw, nelson.chu, kito.cheng; +Cc: rjiejie


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] 5+ messages in thread

* [PATCH 1/2] RISC-V: add vendor opcodes
  2021-08-27  3:39 [PATCH 0/2] RISC-V: Add vendor opcodes Lifang Xia
@ 2021-08-27  3:39 ` Lifang Xia
  2021-08-27  4:01   ` Nelson Chu
  2021-08-27  3:39 ` [PATCH 2/2] RISC-V: Update csr and opcodes for Xuantie CPUs Lifang Xia
  1 sibling, 1 reply; 5+ messages in thread
From: Lifang Xia @ 2021-08-27  3:39 UTC (permalink / raw)
  To: binutils, palmer, jimw, nelson.chu, kito.cheng; +Cc: rjiejie, Lifang Xia

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_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 460667e4349..260a10ab9b9 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -143,6 +143,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}
 };
@@ -211,6 +214,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.  */
@@ -343,6 +362,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:
       as_fatal ("internal: unreachable");
       return false;
@@ -390,6 +412,7 @@ riscv_get_default_ext_version (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;
@@ -1176,6 +1199,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;
@@ -1206,6 +1230,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;
 }
 
@@ -1220,8 +1267,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);
@@ -3916,3 +3966,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 fdf3df4f5c1..96dace50729 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -319,6 +319,9 @@ enum riscv_insn_class
   INSN_CLASS_ZBA,
   INSN_CLASS_ZBB,
   INSN_CLASS_ZBC,
+
+  /* INSN class for THEAD.  */
+  INSN_CLASS_THEADC,
 };
 
 /* This structure holds information for a particular instruction.  */
@@ -359,6 +362,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
 
@@ -433,5 +442,6 @@ 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[];
 
 #endif /* _RISCV_H_ */
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 fe8dfb88d90..cafcf1ecfaa 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
@@ -443,6 +459,11 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
 	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;
     }
 
@@ -611,6 +632,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] 5+ messages in thread

* [PATCH 2/2] RISC-V: Update csr and opcodes for Xuantie CPUs.
  2021-08-27  3:39 [PATCH 0/2] RISC-V: Add vendor opcodes Lifang Xia
  2021-08-27  3:39 ` [PATCH 1/2] RISC-V: add " Lifang Xia
@ 2021-08-27  3:39 ` Lifang Xia
  1 sibling, 0 replies; 5+ messages in thread
From: Lifang Xia @ 2021-08-27  3:39 UTC (permalink / raw)
  To: binutils, palmer, jimw, nelson.chu, kito.cheng; +Cc: rjiejie, Lifang Xia

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, 1414 insertions(+), 8 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 260a10ab9b9..06421076723 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -64,7 +64,8 @@ enum riscv_csr_class
   CSR_CLASS_I,
   CSR_CLASS_I_32, /* rv32 only */
   CSR_CLASS_F, /* f-ext only */
-  CSR_CLASS_DEBUG /* debug CSR */
+  CSR_CLASS_DEBUG, /* debug CSR */
+  CSR_CLASS_VENDOR /* vendor CSR */
 };
 
 /* This structure holds all restricted conditions for a CSR.  */
@@ -145,6 +146,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}
@@ -364,6 +367,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:
       as_fatal ("internal: unreachable");
@@ -909,6 +924,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:
@@ -1170,6 +1186,47 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
 	     return false;
 	  }
 	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:
 	as_bad (_("internal: bad RISC-V opcode "
 		  "(unknown operand type `%c'): %s %s"),
@@ -2780,6 +2837,94 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 	      s = 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:
 	      as_fatal (_("internal: unknown argument type `%c'"), *args);
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 96dace50729..da87f71188f 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -101,6 +101,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)
@@ -142,6 +146,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))
@@ -165,6 +174,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))
@@ -322,6 +333,10 @@ enum riscv_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 structure holds information for a particular instruction.  */
@@ -444,4 +459,8 @@ extern const struct riscv_opcode riscv_opcodes[];
 extern const struct riscv_opcode riscv_insn_types[];
 extern const struct riscv_vendor_opcode riscv_vendor_list[];
 
+
+/* 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 cafcf1ecfaa..bc2efe6e373 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -426,6 +426,56 @@ print_insn_args (const char *d, 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:
 	  /* xgettext:c-format */
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index f55a01b071c..3b60b22647d 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)
 {
   return ((insn ^ op->match) & op->mask) == 0;
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] 5+ messages in thread

* Re: [PATCH 1/2] RISC-V: add vendor opcodes
  2021-08-27  3:39 ` [PATCH 1/2] RISC-V: add " Lifang Xia
@ 2021-08-27  4:01   ` Nelson Chu
  2021-08-27  7:18     ` 夏立方
  0 siblings, 1 reply; 5+ messages in thread
From: Nelson Chu @ 2021-08-27  4:01 UTC (permalink / raw)
  To: Lifang Xia; +Cc: Binutils, Palmer Dabbelt, Jim Wilson, Kito Cheng, rjiejie

I suppose you should add vendor extensions to the integration branch,
rather than mainline.  Please check the
users/riscv/binutils-integration-branch.

Nelson

On Fri, Aug 27, 2021 at 11:39 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_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 460667e4349..260a10ab9b9 100644
> --- a/gas/config/tc-riscv.c
> +++ b/gas/config/tc-riscv.c
> @@ -143,6 +143,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}
>  };
> @@ -211,6 +214,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.  */
> @@ -343,6 +362,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:
>        as_fatal ("internal: unreachable");
>        return false;
> @@ -390,6 +412,7 @@ riscv_get_default_ext_version (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;
> @@ -1176,6 +1199,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;
> @@ -1206,6 +1230,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;
>  }
>
> @@ -1220,8 +1267,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);
> @@ -3916,3 +3966,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 fdf3df4f5c1..96dace50729 100644
> --- a/include/opcode/riscv.h
> +++ b/include/opcode/riscv.h
> @@ -319,6 +319,9 @@ enum riscv_insn_class
>    INSN_CLASS_ZBA,
>    INSN_CLASS_ZBB,
>    INSN_CLASS_ZBC,
> +
> +  /* INSN class for THEAD.  */
> +  INSN_CLASS_THEADC,
>  };
>
>  /* This structure holds information for a particular instruction.  */
> @@ -359,6 +362,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
>
> @@ -433,5 +442,6 @@ 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[];
>
>  #endif /* _RISCV_H_ */
> 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 fe8dfb88d90..cafcf1ecfaa 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
> @@ -443,6 +459,11 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
>         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;
>      }
>
> @@ -611,6 +632,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] 5+ messages in thread

* Re: [PATCH 1/2] RISC-V: add vendor opcodes
  2021-08-27  4:01   ` Nelson Chu
@ 2021-08-27  7:18     ` 夏立方
  0 siblings, 0 replies; 5+ messages in thread
From: 夏立方 @ 2021-08-27  7:18 UTC (permalink / raw)
  To: Nelson Chu; +Cc: binutils, Palmer Dabbelt, Jim Wilson, Kito Cheng, rjiejie

Thanks.
That's a good choice.
I will re-send these patch with "[integaration XXXX] RISC-V XXXXXXXXX".

Lifang
------------------------------------------------------------------
Sender:Nelson Chu <nelson.chu@sifive.com>
Sent At:2021 Aug. 27 (Fri.) 12:01
Recipient:夏立方 <lifang_xia@c-sky.com>
Cc:binutils@sourceware.org <binutils@sourceware.org>; Palmer Dabbelt <palmer@dabbelt.com>; Jim Wilson <jimw@sifive.com>; Kito Cheng <kito.cheng@sifive.com>; rjiejie <rjiejie@linux.alibaba.com>
Subject:Re: [PATCH 1/2] RISC-V: add vendor opcodes

I suppose you should add vendor extensions to the integration branch,
rather than mainline.  Please check the
users/riscv/binutils-integration-branch.

Nelson

On Fri, Aug 27, 2021 at 11:39 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_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 460667e4349..260a10ab9b9 100644
> --- a/gas/config/tc-riscv.c
> +++ b/gas/config/tc-riscv.c
> @@ -143,6 +143,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}
>  };
> @@ -211,6 +214,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.  */
> @@ -343,6 +362,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:
>        as_fatal ("internal: unreachable");
>        return false;
> @@ -390,6 +412,7 @@ riscv_get_default_ext_version (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;
> @@ -1176,6 +1199,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;
> @@ -1206,6 +1230,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;
>  }
>
> @@ -1220,8 +1267,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);
> @@ -3916,3 +3966,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 fdf3df4f5c1..96dace50729 100644
> --- a/include/opcode/riscv.h
> +++ b/include/opcode/riscv.h
> @@ -319,6 +319,9 @@ enum riscv_insn_class
>    INSN_CLASS_ZBA,
>    INSN_CLASS_ZBB,
>    INSN_CLASS_ZBC,
> +
> +  /* INSN class for THEAD.  */
> +  INSN_CLASS_THEADC,
>  };
>
>  /* This structure holds information for a particular instruction.  */
> @@ -359,6 +362,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
>
> @@ -433,5 +442,6 @@ 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[];
>
>  #endif /* _RISCV_H_ */
> 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 fe8dfb88d90..cafcf1ecfaa 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
> @@ -443,6 +459,11 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
>         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;
>      }
>
> @@ -611,6 +632,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] 5+ messages in thread

end of thread, other threads:[~2021-08-27  7:18 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-27  3:39 [PATCH 0/2] RISC-V: Add vendor opcodes Lifang Xia
2021-08-27  3:39 ` [PATCH 1/2] RISC-V: add " Lifang Xia
2021-08-27  4:01   ` Nelson Chu
2021-08-27  7:18     ` 夏立方
2021-08-27  3:39 ` [PATCH 2/2] RISC-V: Update csr and opcodes for Xuantie CPUs Lifang Xia

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