[committed,v2] RISC-V: Add bfd/cpu-riscv.h to support all spec versions controlling.

Message ID 1613633396-23511-1-git-send-email-nelson.chu@sifive.com
State New
Headers show
Series
  • [committed,v2] RISC-V: Add bfd/cpu-riscv.h to support all spec versions controlling.
Related show

Commit Message

Nelson Chu Feb. 18, 2021, 7:29 a.m.
Make the opcode/riscv-opc.c and include/opcode/riscv.h tidy, move the
spec versions stuff to bfd/cpu-riscv.h.  Also move the csr stuff and
ext_version_table to gas/config/tc-riscv.c for internal use.  To avoid
too many repeated code, define general RISCV_GET_SPEC_NAME/SPEC_CLASS
macros.  Therefore, assembler/dis-assembler/linker/gdb can get all spec
versions related stuff from cpu-riscv.h and cpu-riscv.c, since the stuff
are defined there uniformly.

bfd/
    * Makefile.am: Added cpu-riscv.h.
    * Makefile.in: Regenerated.
    * po/SRC-POTFILES.in: Regenerated.
    * cpu-riscv.h: Added to support spec versions controlling.
    Also added extern arrays and functions for cpu-riscv.c.
    (enum riscv_spec_class): Define all spec classes here uniformly.
    (struct riscv_spec): Added for all specs.
    (RISCV_GET_SPEC_CLASS): Added to reduce repeated code.
    (RISCV_GET_SPEC_NAME): Likewise.
    (RISCV_GET_ISA_SPEC_CLASS): Added to get ISA spec class.
    (RISCV_GET_PRIV_SPEC_CLASS): Added to get privileged spec class.
    (RISCV_GET_PRIV_SPEC_NAME): Added to get privileged spec name.
    * cpu-riscv.c (struct priv_spec_t): Replaced with struct riscv_spec.
    (riscv_get_priv_spec_class): Replaced with RISCV_GET_PRIV_SPEC_CLASS.
    (riscv_get_priv_spec_name): Replaced with RISCV_GET_PRIV_SPEC_NAME.
    (riscv_priv_specs): Moved below.
    (riscv_get_priv_spec_class_from_numbers): Likewise, updated.
    (riscv_isa_specs): Moved from include/opcode/riscv.h.
    * elfnn-riscv.c: Included cpu-riscv.h.
    (riscv_merge_attributes): Initialize in_priv_spec and out_priv_spec.
    * elfxx-riscv.c: Included cpu-riscv.h and opcode/riscv.h.
    (RISCV_UNKNOWN_VERSION): Moved from include/opcode/riscv.h.
    * elfxx-riscv.h: Removed extern functions to cpu-riscv.h.
gas/
    * config/tc-riscv.c: Included cpu-riscv.h.
    (enum riscv_csr_clas): Moved from include/opcode/riscv.h.
    (struct riscv_csr_extra): Likewise.
    (struct riscv_ext_version): Likewise.
    (ext_version_table): Moved from opcodes/riscv-opc.c.
    (default_isa_spec): Updated type to riscv_spec_class.
    (default_priv_spec): Likewise.
    (riscv_set_default_isa_spec): Updated.
    (init_ext_version_hash): Likewise.
    (riscv_init_csr_hash): Likewise, also fixed indent.
include/
    * opcode/riscv.h: Moved stuff and make the file tidy.
opcodes/
    * riscv-dis.c: Included cpu-riscv.h, and removed elfxx-riscv.h.
    (default_priv_spec): Updated type to riscv_spec_class.
    (parse_riscv_dis_option): Updated.
    * riscv-opc.c: Moved stuff and make the file tidy.
---
 bfd/ChangeLog          |  26 ++++++++++
 bfd/Makefile.am        |   2 +-
 bfd/Makefile.in        |   2 +-
 bfd/cpu-riscv.c        | 123 ++++++++++++++------------------------------
 bfd/cpu-riscv.h        |  81 +++++++++++++++++++++++++++++
 bfd/elfnn-riscv.c      |   5 +-
 bfd/elfxx-riscv.c      |   5 +-
 bfd/elfxx-riscv.h      |  12 -----
 bfd/po/SRC-POTFILES.in |   1 +
 gas/ChangeLog          |  13 +++++
 gas/config/tc-riscv.c  | 137 ++++++++++++++++++++++++++++++++++++++++---------
 include/ChangeLog      |   4 ++
 include/opcode/riscv.h |  69 -------------------------
 opcodes/ChangeLog      |   7 +++
 opcodes/riscv-dis.c    |  21 +++++---
 opcodes/riscv-opc.c    |  87 -------------------------------
 16 files changed, 306 insertions(+), 289 deletions(-)
 create mode 100644 bfd/cpu-riscv.h

-- 
2.7.4

Patch

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 7feb608..0197e7b 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,29 @@ 
+2021-02-18  Nelson Chu  <nelson.chu@sifive.com>
+
+	* Makefile.am: Added cpu-riscv.h.
+	* Makefile.in: Regenerated.
+	* po/SRC-POTFILES.in: Regenerated.
+	* cpu-riscv.h: Added to support spec versions controlling.
+	Also added extern arrays and functions for cpu-riscv.c.
+	(enum riscv_spec_class): Define all spec classes here uniformly.
+	(struct riscv_spec): Added for all specs.
+	(RISCV_GET_SPEC_CLASS): Added to reduce repeated code.
+	(RISCV_GET_SPEC_NAME): Likewise.
+	(RISCV_GET_ISA_SPEC_CLASS): Added to get ISA spec class.
+	(RISCV_GET_PRIV_SPEC_CLASS): Added to get privileged spec class.
+	(RISCV_GET_PRIV_SPEC_NAME): Added to get privileged spec name.
+	* cpu-riscv.c (struct priv_spec_t): Replaced with struct riscv_spec.
+	(riscv_get_priv_spec_class): Replaced with RISCV_GET_PRIV_SPEC_CLASS.
+	(riscv_get_priv_spec_name): Replaced with RISCV_GET_PRIV_SPEC_NAME.
+	(riscv_priv_specs): Moved below.
+	(riscv_get_priv_spec_class_from_numbers): Likewise, updated.
+	(riscv_isa_specs): Moved from include/opcode/riscv.h.
+	* elfnn-riscv.c: Included cpu-riscv.h.
+	(riscv_merge_attributes): Initialize in_priv_spec and out_priv_spec.
+	* elfxx-riscv.c: Included cpu-riscv.h and opcode/riscv.h.
+	(RISCV_UNKNOWN_VERSION): Moved from include/opcode/riscv.h.
+	* elfxx-riscv.h: Removed extern functions to cpu-riscv.h.
+
 2021-02-17  Alan Modra  <amodra@gmail.com>
 
 	* wasm-module.c: Guard include of limits.h.
diff --git a/bfd/Makefile.am b/bfd/Makefile.am
index 9908249..3f143dc 100644
--- a/bfd/Makefile.am
+++ b/bfd/Makefile.am
@@ -675,7 +675,7 @@  CFILES = $(SOURCE_CFILES) $(BUILD_CFILES)
 SOURCE_HFILES = \
 	aout-target.h aoutx.h arc-got.h arc-plt.h \
 	coff-arm.h coff-bfd.h coffcode.h coffswap.h \
-	cpu-aarch64.h cpu-arm.h cpu-h8300.h cpu-m68k.h \
+	cpu-aarch64.h cpu-arm.h cpu-h8300.h cpu-m68k.h cpu-riscv.h \
 	ecoff-bfd.h ecoffswap.h \
 	elf32-arm.h elf32-avr.h elf32-bfin.h elf32-cr16.h elf32-csky.h \
 	elf32-dlx.h elf32-hppa.h elf32-m68hc1x.h elf32-m68k.h \
diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index a5d1f8e..bd64658 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -1099,7 +1099,7 @@  CFILES = $(SOURCE_CFILES) $(BUILD_CFILES)
 SOURCE_HFILES = \
 	aout-target.h aoutx.h arc-got.h arc-plt.h \
 	coff-arm.h coff-bfd.h coffcode.h coffswap.h \
-	cpu-aarch64.h cpu-arm.h cpu-h8300.h cpu-m68k.h \
+	cpu-aarch64.h cpu-arm.h cpu-h8300.h cpu-m68k.h cpu-riscv.h \
 	ecoff-bfd.h ecoffswap.h \
 	elf32-arm.h elf32-avr.h elf32-bfin.h elf32-cr16.h elf32-csky.h \
 	elf32-dlx.h elf32-hppa.h elf32-m68hc1x.h elf32-m68k.h \
diff --git a/bfd/cpu-riscv.c b/bfd/cpu-riscv.c
index eec61b4..ce87ccf 100644
--- a/bfd/cpu-riscv.c
+++ b/bfd/cpu-riscv.c
@@ -23,89 +23,7 @@ 
 #include "sysdep.h"
 #include "bfd.h"
 #include "libbfd.h"
-#include "elfxx-riscv.h"
-
-/* Record the priv spec version string and the corresponding class.  */
-
-struct priv_spec_t
-{
-  const char *name;
-  enum riscv_priv_spec_class class;
-};
-
-/* List for all supported privilege versions.  */
-
-static const struct priv_spec_t priv_specs[] =
-{
-  {"1.9.1", PRIV_SPEC_CLASS_1P9P1},
-  {"1.10",  PRIV_SPEC_CLASS_1P10},
-  {"1.11",  PRIV_SPEC_CLASS_1P11},
-
-/* Terminate the list.  */
-  {NULL, 0}
-};
-
-/* Get the corresponding CSR version class by giving a privilege
-   version string.  */
-
-int
-riscv_get_priv_spec_class (const char *s,
-			   enum riscv_priv_spec_class *class)
-{
-  const struct priv_spec_t *version;
-
-  if (s == NULL)
-    return 0;
-
-  for (version = &priv_specs[0]; version->name != NULL; ++version)
-    if (strcmp (version->name, s) == 0)
-      {
-	*class = version->class;
-	return 1;
-      }
-
-  /* Can not find the supported privilege version.  */
-  return 0;
-}
-
-/* Get the corresponding CSR version class by giving privilege
-   version numbers.  It is usually used to convert the priv
-   attribute numbers into the corresponding class.  */
-
-int
-riscv_get_priv_spec_class_from_numbers (unsigned int major,
-					unsigned int minor,
-					unsigned int revision,
-					enum riscv_priv_spec_class *class)
-{
-  char buf[36];
-
-  if (major == 0 && minor == 0 && revision == 0)
-    {
-      *class = PRIV_SPEC_CLASS_NONE;
-      return 1;
-    }
-
-  if (revision != 0)
-    snprintf (buf, sizeof (buf), "%u.%u.%u", major, minor, revision);
-  else
-    snprintf (buf, sizeof (buf), "%u.%u", major, minor);
-
-  return riscv_get_priv_spec_class (buf, class);
-}
-
-/* Get the corresponding privilege version string by giving a CSR
-   version class.  */
-
-const char *
-riscv_get_priv_spec_name (enum riscv_priv_spec_class class)
-{
-  /* The first enum is PRIV_SPEC_CLASS_NONE.  */
-  return priv_specs[class - 1].name;
-}
-
-/* This routine is provided two arch_infos and returns an arch_info
-   that is compatible with both, or NULL if none exists.  */
+#include "cpu-riscv.h"
 
 static const bfd_arch_info_type *
 riscv_compatible (const bfd_arch_info_type *a, const bfd_arch_info_type *b)
@@ -182,6 +100,43 @@  static const bfd_arch_info_type arch_info_struct[] =
 };
 
 /* The default architecture is riscv:rv64.  */
-
 const bfd_arch_info_type bfd_riscv_arch =
   N (64, 0, "riscv", TRUE, &arch_info_struct[0]);
+
+/* List for all supported ISA spec versions.  */
+const struct riscv_spec riscv_isa_specs[] =
+{
+  {"2.2",      ISA_SPEC_CLASS_2P2},
+  {"20190608", ISA_SPEC_CLASS_20190608},
+  {"20191213", ISA_SPEC_CLASS_20191213},
+};
+
+/* List for all supported privileged spec versions.  */
+const struct riscv_spec riscv_priv_specs[] =
+{
+  {"1.9.1", PRIV_SPEC_CLASS_1P9P1},
+  {"1.10",  PRIV_SPEC_CLASS_1P10},
+  {"1.11",  PRIV_SPEC_CLASS_1P11},
+};
+
+/* Get the corresponding CSR version class by giving privilege
+   version numbers.  It is usually used to convert the priv
+   attribute numbers into the corresponding class.  */
+
+void
+riscv_get_priv_spec_class_from_numbers (unsigned int major,
+					unsigned int minor,
+					unsigned int revision,
+					enum riscv_spec_class *class)
+{
+  enum riscv_spec_class class_t = *class;
+  char buf[36];
+
+  if (revision != 0)
+    snprintf (buf, sizeof (buf), "%u.%u.%u", major, minor, revision);
+  else
+    snprintf (buf, sizeof (buf), "%u.%u", major, minor);
+
+  RISCV_GET_PRIV_SPEC_CLASS (buf, class_t);
+  *class = class_t;
+}
diff --git a/bfd/cpu-riscv.h b/bfd/cpu-riscv.h
new file mode 100644
index 0000000..cafaca2
--- /dev/null
+++ b/bfd/cpu-riscv.h
@@ -0,0 +1,81 @@ 
+/* RISC-V spec version controlling support.
+   Copyright (C) 2019-2020 Free Software Foundation, Inc.
+
+   This file is part of BFD, the Binary File Descriptor library.
+
+   This program 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 of the License, or
+   (at your option) any later version.
+
+   This program 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; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+enum riscv_spec_class
+{
+  /* ISA spec.  */
+  ISA_SPEC_CLASS_NONE = 0,
+  ISA_SPEC_CLASS_2P2,
+  ISA_SPEC_CLASS_20190608,
+  ISA_SPEC_CLASS_20191213,
+  ISA_SPEC_CLASS_DRAFT,
+
+  /* Privileged spec.  */
+  PRIV_SPEC_CLASS_NONE,
+  PRIV_SPEC_CLASS_1P9P1,
+  PRIV_SPEC_CLASS_1P10,
+  PRIV_SPEC_CLASS_1P11,
+  PRIV_SPEC_CLASS_DRAFT,
+};
+
+struct riscv_spec
+{
+  const char *name;
+  enum riscv_spec_class spec_class;
+};
+
+extern const struct riscv_spec riscv_isa_specs[];
+extern const struct riscv_spec riscv_priv_specs[];
+
+#define RISCV_GET_SPEC_CLASS(UTYPE, LTYPE, NAME, CLASS)			\
+  do									\
+    {									\
+      if (NAME == NULL)							\
+	break;								\
+									\
+      int i_spec = UTYPE##_SPEC_CLASS_NONE + 1;				\
+      for (; i_spec < UTYPE##_SPEC_CLASS_DRAFT; i_spec++)		\
+	{								\
+	  int j_spec = i_spec - UTYPE##_SPEC_CLASS_NONE -1;		\
+	  if (riscv_##LTYPE##_specs[j_spec].name			\
+	      && strcmp (riscv_##LTYPE##_specs[j_spec].name, NAME) == 0)\
+	  {								\
+	    CLASS = riscv_##LTYPE##_specs[j_spec].spec_class;		\
+	    break;							\
+	  }								\
+	}								\
+    }									\
+  while (0)
+
+#define RISCV_GET_SPEC_NAME(UTYPE, LTYPE, NAME, CLASS)			\
+  (NAME) = riscv_##LTYPE##_specs[(CLASS) - UTYPE##_SPEC_CLASS_NONE - 1].name
+
+#define RISCV_GET_ISA_SPEC_CLASS(NAME, CLASS)	\
+  RISCV_GET_SPEC_CLASS(ISA, isa, NAME, CLASS)
+#define RISCV_GET_PRIV_SPEC_CLASS(NAME, CLASS)	\
+  RISCV_GET_SPEC_CLASS(PRIV, priv, NAME, CLASS)
+#define RISCV_GET_PRIV_SPEC_NAME(NAME, CLASS)	\
+  RISCV_GET_SPEC_NAME(PRIV, priv, NAME, CLASS)
+
+extern void
+riscv_get_priv_spec_class_from_numbers (unsigned int,
+					unsigned int,
+					unsigned int,
+					enum riscv_spec_class *);
diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 66272f5..8739673 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -32,6 +32,7 @@ 
 #include "elf/riscv.h"
 #include "opcode/riscv.h"
 #include "objalloc.h"
+#include "cpu-riscv.h"
 
 #ifdef HAVE_LIMITS_H
 #include <limits.h>
@@ -3679,8 +3680,8 @@  riscv_merge_attributes (bfd *ibfd, struct bfd_link_info *info)
 	    unsigned int Tag_a = Tag_RISCV_priv_spec;
 	    unsigned int Tag_b = Tag_RISCV_priv_spec_minor;
 	    unsigned int Tag_c = Tag_RISCV_priv_spec_revision;
-	    enum riscv_priv_spec_class in_priv_spec;
-	    enum riscv_priv_spec_class out_priv_spec;
+	    enum riscv_spec_class in_priv_spec = PRIV_SPEC_CLASS_NONE;
+	    enum riscv_spec_class out_priv_spec = PRIV_SPEC_CLASS_NONE;
 
 	    /* Get the privileged spec class from elf attributes.  */
 	    riscv_get_priv_spec_class_from_numbers (in_attr[Tag_a].i,
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index fa7bce9..d3b882b 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -25,9 +25,11 @@ 
 #include "libbfd.h"
 #include "elf-bfd.h"
 #include "elf/riscv.h"
+#include "opcode/riscv.h"
 #include "libiberty.h"
 #include "elfxx-riscv.h"
 #include "safe-ctype.h"
+#include "cpu-riscv.h"
 
 #define MINUS_ONE ((bfd_vma)0 - 1)
 
@@ -1024,12 +1026,13 @@  riscv_elf_add_sub_reloc (bfd *abfd,
   return bfd_reloc_ok;
 }
 
+#define RISCV_UNKNOWN_VERSION -1
+
 /* Array is used to compare the orders of all extensions quickly.
 
    Zero value: Preserved keyword.
    Negative value: Prefixed keyword (s, h, x, z).
    Positive value: Standard extension.  */
-
 static int riscv_ext_order[26] = {0};
 
 /* Similar to the strcmp.  It returns an integer less than, equal to,
diff --git a/bfd/elfxx-riscv.h b/bfd/elfxx-riscv.h
index 87ebaf4..a7d348c 100644
--- a/bfd/elfxx-riscv.h
+++ b/bfd/elfxx-riscv.h
@@ -104,16 +104,4 @@  riscv_isa_ext_class_t
 riscv_get_prefix_class (const char *);
 
 extern int
-riscv_get_priv_spec_class (const char *, enum riscv_priv_spec_class *);
-
-extern int
-riscv_get_priv_spec_class_from_numbers (unsigned int,
-					unsigned int,
-					unsigned int,
-					enum riscv_priv_spec_class *);
-
-extern const char *
-riscv_get_priv_spec_name (enum riscv_priv_spec_class);
-
-extern int
 riscv_compare_subsets (const char *, const char *);
diff --git a/bfd/po/SRC-POTFILES.in b/bfd/po/SRC-POTFILES.in
index 83530b2..c83b86c 100644
--- a/bfd/po/SRC-POTFILES.in
+++ b/bfd/po/SRC-POTFILES.in
@@ -101,6 +101,7 @@  cpu-pj.c
 cpu-powerpc.c
 cpu-pru.c
 cpu-riscv.c
+cpu-riscv.h
 cpu-rl78.c
 cpu-rs6000.c
 cpu-rx.c
diff --git a/gas/ChangeLog b/gas/ChangeLog
index db5b6d4..a90ab78 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,16 @@ 
+2021-02-18  Nelson Chu  <nelson.chu@sifive.com>
+
+	* config/tc-riscv.c: Included cpu-riscv.h.
+	(enum riscv_csr_clas): Moved from include/opcode/riscv.h.
+	(struct riscv_csr_extra): Likewise.
+	(struct riscv_ext_version): Likewise.
+	(ext_version_table): Moved from opcodes/riscv-opc.c.
+	(default_isa_spec): Updated type to riscv_spec_class.
+	(default_priv_spec): Likewise.
+	(riscv_set_default_isa_spec): Updated.
+	(init_ext_version_hash): Likewise.
+	(riscv_init_csr_hash): Likewise, also fixed indent.
+
 2021-02-17  Alan Modra  <amodra@gmail.com>
 
 	* testsuite/gas/elf/section28.d: xfail h8300.
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 44d9cb1..44450d7 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -29,6 +29,7 @@ 
 #include "dwarf2dbg.h"
 #include "dw2gencfi.h"
 
+#include "bfd/cpu-riscv.h"
 #include "bfd/elfxx-riscv.h"
 #include "elf/riscv.h"
 #include "opcode/riscv.h"
@@ -55,6 +56,93 @@  struct riscv_cl_insn
   fixS *fixp;
 };
 
+/* All RISC-V CSR belong to one of these classes.  */
+enum riscv_csr_class
+{
+  CSR_CLASS_NONE,
+
+  CSR_CLASS_I,
+  CSR_CLASS_I_32, /* rv32 only */
+  CSR_CLASS_F, /* f-ext only */
+  CSR_CLASS_DEBUG /* debug CSR */
+};
+
+/* This structure holds all restricted conditions for a CSR.  */
+struct riscv_csr_extra
+{
+  /* Class to which this CSR belongs.  Used to decide whether or
+     not this CSR is legal in the current -march context.  */
+  enum riscv_csr_class csr_class;
+
+  /* CSR may have differnet numbers in the previous priv spec.  */
+  unsigned address;
+
+  /* Record the CSR is defined/valid in which versions.  */
+  enum riscv_spec_class define_version;
+
+  /* Record the CSR is aborted/invalid from which versions.  If it isn't
+     aborted in the current version, then it should be CSR_CLASS_VDRAFT.  */
+  enum riscv_spec_class abort_version;
+
+  /* The CSR may have more than one setting.  */
+  struct riscv_csr_extra *next;
+};
+
+/* All standard/Z* extensions defined in all supported ISA spec.  */
+struct riscv_ext_version
+{
+  const char *name;
+  enum riscv_spec_class isa_spec_class;
+  int major_version;
+  int minor_version;
+};
+
+static const struct riscv_ext_version ext_version_table[] =
+{
+  {"e", ISA_SPEC_CLASS_20191213, 1, 9},
+  {"e", ISA_SPEC_CLASS_20190608, 1, 9},
+  {"e", ISA_SPEC_CLASS_2P2,      1, 9},
+
+  {"i", ISA_SPEC_CLASS_20191213, 2, 1},
+  {"i", ISA_SPEC_CLASS_20190608, 2, 1},
+  {"i", ISA_SPEC_CLASS_2P2,      2, 0},
+
+  {"m", ISA_SPEC_CLASS_20191213, 2, 0},
+  {"m", ISA_SPEC_CLASS_20190608, 2, 0},
+  {"m", ISA_SPEC_CLASS_2P2,      2, 0},
+
+  {"a", ISA_SPEC_CLASS_20191213, 2, 1},
+  {"a", ISA_SPEC_CLASS_20190608, 2, 0},
+  {"a", ISA_SPEC_CLASS_2P2,      2, 0},
+
+  {"f", ISA_SPEC_CLASS_20191213, 2, 2},
+  {"f", ISA_SPEC_CLASS_20190608, 2, 2},
+  {"f", ISA_SPEC_CLASS_2P2,      2, 0},
+
+  {"d", ISA_SPEC_CLASS_20191213, 2, 2},
+  {"d", ISA_SPEC_CLASS_20190608, 2, 2},
+  {"d", ISA_SPEC_CLASS_2P2,      2, 0},
+
+  {"q", ISA_SPEC_CLASS_20191213, 2, 2},
+  {"q", ISA_SPEC_CLASS_20190608, 2, 2},
+  {"q", ISA_SPEC_CLASS_2P2,      2, 0},
+
+  {"c", ISA_SPEC_CLASS_20191213, 2, 0},
+  {"c", ISA_SPEC_CLASS_20190608, 2, 0},
+  {"c", ISA_SPEC_CLASS_2P2,      2, 0},
+
+  {"zicsr", ISA_SPEC_CLASS_20191213, 2, 0},
+  {"zicsr", ISA_SPEC_CLASS_20190608, 2, 0},
+
+  {"zifencei", ISA_SPEC_CLASS_20191213, 2, 0},
+  {"zifencei", ISA_SPEC_CLASS_20190608, 2, 0},
+
+  {"zihintpause", ISA_SPEC_CLASS_DRAFT, 1, 0},
+
+  /* Terminate the list.  */
+  {NULL, 0, 0, 0}
+};
+
 #ifndef DEFAULT_ARCH
 #define DEFAULT_ARCH "riscv64"
 #endif
@@ -79,8 +167,8 @@  struct riscv_cl_insn
 
 static const char default_arch[] = DEFAULT_ARCH;
 static const char *default_arch_with_ext = DEFAULT_RISCV_ARCH_WITH_EXT;
-static enum riscv_isa_spec_class default_isa_spec = ISA_SPEC_CLASS_NONE;
-static enum riscv_priv_spec_class default_priv_spec = PRIV_SPEC_CLASS_NONE;
+static enum riscv_spec_class default_isa_spec = ISA_SPEC_CLASS_NONE;
+static enum riscv_spec_class default_priv_spec = PRIV_SPEC_CLASS_NONE;
 
 static unsigned xlen = 0; /* The width of an x-register.  */
 static unsigned abi_xlen = 0; /* The width of a pointer in the ABI.  */
@@ -106,8 +194,9 @@  static unsigned elf_flags = 0;
 static int
 riscv_set_default_isa_spec (const char *s)
 {
-  enum riscv_isa_spec_class class;
-  if (!riscv_get_isa_spec_class (s, &class))
+  enum riscv_spec_class class = ISA_SPEC_CLASS_NONE;
+  RISCV_GET_ISA_SPEC_CLASS (s, class);
+  if (class == ISA_SPEC_CLASS_NONE)
     {
       as_bad ("unknown default ISA spec `%s' set by "
 	      "-misa-spec or --with-isa-spec", s);
@@ -125,11 +214,12 @@  riscv_set_default_isa_spec (const char *s)
 static int
 riscv_set_default_priv_spec (const char *s)
 {
-  enum riscv_priv_spec_class class;
+  enum riscv_spec_class class = PRIV_SPEC_CLASS_NONE;
   unsigned major, minor, revision;
   obj_attribute *attr;
 
-  if (riscv_get_priv_spec_class (s, &class))
+  RISCV_GET_PRIV_SPEC_CLASS (s, class);
+  if (class != PRIV_SPEC_CLASS_NONE)
     {
       default_priv_spec = class;
       return 1;
@@ -147,15 +237,13 @@  riscv_set_default_priv_spec (const char *s)
   major = (unsigned) attr[Tag_RISCV_priv_spec].i;
   minor = (unsigned) attr[Tag_RISCV_priv_spec_minor].i;
   revision = (unsigned) attr[Tag_RISCV_priv_spec_revision].i;
-  if (riscv_get_priv_spec_class_from_numbers (major,
-					      minor,
-					      revision,
-					      &class))
-    {
-      /* 0.0.0 is meaningless.  */
-      if (class == PRIV_SPEC_CLASS_NONE)
-	return 1;
+  /* Version 0.0.0 is the default value and meningless.  */
+  if (major == 0 && minor == 0 && revision == 0)
+    return 1;
 
+  riscv_get_priv_spec_class_from_numbers (major, minor, revision, &class);
+  if (class != PRIV_SPEC_CLASS_NONE)
+    {
       default_priv_spec = class;
       return 1;
     }
@@ -252,10 +340,11 @@  riscv_multi_subset_supports (enum riscv_insn_class insn_class)
 static htab_t ext_version_hash = NULL;
 
 static htab_t
-init_ext_version_hash (const struct riscv_ext_version *table)
+init_ext_version_hash (void)
 {
-  int i = 0;
+  const struct riscv_ext_version *table = ext_version_table;
   htab_t hash = str_htab_create ();
+  int i = 0;
 
   while (table[i].name)
     {
@@ -687,10 +776,10 @@  hash_reg_names (enum reg_class class, const char * const names[], unsigned n)
 
 static void
 riscv_init_csr_hash (const char *name,
-                    unsigned address,
-                    enum riscv_csr_class class,
-                    enum riscv_priv_spec_class define_version,
-                    enum riscv_priv_spec_class abort_version)
+		     unsigned address,
+		     enum riscv_csr_class class,
+		     enum riscv_spec_class define_version,
+		     enum riscv_spec_class abort_version)
 {
   struct riscv_csr_extra *entry, *pre_entry;
   bfd_boolean need_enrty = TRUE;
@@ -782,8 +871,8 @@  riscv_csr_address (const char *csr_name,
      so use the newly defined value.  */
   if (riscv_opts.csr_check)
     {
-      const char *priv_name = riscv_get_priv_spec_name (default_priv_spec);
-
+      const char *priv_name = NULL;
+      RISCV_GET_PRIV_SPEC_NAME (priv_name, default_priv_spec);
       if (priv_name != NULL)
 	as_warn (_("invalid CSR `%s' for the privileged spec `%s'"),
 		 csr_name, priv_name);
@@ -2812,7 +2901,7 @@  riscv_after_parse_args (void)
     default_arch_with_ext = xlen == 64 ? "rv64g" : "rv32g";
 
   /* Initialize the hash table for extensions with default version.  */
-  ext_version_hash = init_ext_version_hash (riscv_ext_version_table);
+  ext_version_hash = init_ext_version_hash ();
 
   /* Set default specs.  */
   if (default_isa_spec == ISA_SPEC_CLASS_NONE)
@@ -3648,7 +3737,7 @@  riscv_write_out_attrs (void)
   if (!explicit_priv_attr)
     return;
 
-  priv_str = riscv_get_priv_spec_name (default_priv_spec);
+  RISCV_GET_PRIV_SPEC_NAME (priv_str, default_priv_spec);
   p = priv_str;
   for (i = 0; *p; ++p)
     {
diff --git a/include/ChangeLog b/include/ChangeLog
index 6c3a835..0f4936e 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,7 @@ 
+2021-02-18  Nelson Chu  <nelson.chu@sifive.com>
+
+	* opcode/riscv.h: Moved stuff and make the file tidy.
+
 2021-02-15  Andreas Krebbel  <krebbel@linux.ibm.com>
 
 	* opcode/s390.h (enum s390_opcode_cpu_val): Add
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index 5432e6c..9372852 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -349,71 +349,6 @@  struct riscv_opcode
   unsigned long pinfo;
 };
 
-/* The current supported ISA spec versions.  */
-enum riscv_isa_spec_class
-{
-  ISA_SPEC_CLASS_NONE,
-
-  ISA_SPEC_CLASS_2P2,
-  ISA_SPEC_CLASS_20190608,
-  ISA_SPEC_CLASS_20191213,
-  ISA_SPEC_CLASS_DRAFT
-};
-
-#define RISCV_UNKNOWN_VERSION -1
-
-/* This structure holds version information for specific ISA.  */
-struct riscv_ext_version
-{
-  const char *name;
-  enum riscv_isa_spec_class isa_spec_class;
-  int major_version;
-  int minor_version;
-};
-
-/* All RISC-V CSR belong to one of these classes.  */
-enum riscv_csr_class
-{
-  CSR_CLASS_NONE,
-
-  CSR_CLASS_I,
-  CSR_CLASS_I_32, /* RV32 only.  */
-  CSR_CLASS_F, /* F extension only.  */
-  CSR_CLASS_DEBUG /* Debug CSR.  */
-};
-
-/* The current supported privilege spec versions.  */
-enum riscv_priv_spec_class
-{
-  PRIV_SPEC_CLASS_NONE,
-
-  PRIV_SPEC_CLASS_1P9P1,
-  PRIV_SPEC_CLASS_1P10,
-  PRIV_SPEC_CLASS_1P11,
-  PRIV_SPEC_CLASS_DRAFT
-};
-
-/* This structure holds all restricted conditions for a CSR.  */
-struct riscv_csr_extra
-{
-  /* Class to which this CSR belongs.  Used to decide whether or
-     not this CSR is legal in the current -march context.  */
-  enum riscv_csr_class csr_class;
-
-  /* CSR may have differnet numbers in the previous priv spec.  */
-  unsigned address;
-
-  /* Record the CSR is defined/valid in which versions.  */
-  enum riscv_priv_spec_class define_version;
-
-  /* Record the CSR is aborted/invalid from which versions.  If it isn't
-     aborted in the current version, then it should be CSR_CLASS_VDRAFT.  */
-  enum riscv_priv_spec_class abort_version;
-
-  /* The CSR may have more than one setting.  */
-  struct riscv_csr_extra *next;
-};
-
 /* Instruction is a simple alias (e.g. "mv" for "addi").  */
 #define	INSN_ALIAS		0x00000001
 
@@ -488,9 +423,5 @@  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_ext_version riscv_ext_version_table[];
-
-extern int
-riscv_get_isa_spec_class (const char *, enum riscv_isa_spec_class *);
 
 #endif /* _RISCV_H_ */
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 03acd4d..162aafcb 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,10 @@ 
+2021-02-18  Nelson Chu  <nelson.chu@sifive.com>
+
+	* riscv-dis.c: Included cpu-riscv.h, and removed elfxx-riscv.h.
+	(default_priv_spec): Updated type to riscv_spec_class.
+	(parse_riscv_dis_option): Updated.
+	* riscv-opc.c: Moved stuff and make the file tidy.
+
 2021-02-17  Alan Modra  <amodra@gmail.com>
 
 	* wasm32-dis.c: Include limits.h.
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index b5883c3..667dbd8 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -27,12 +27,12 @@ 
 #include "opintl.h"
 #include "elf-bfd.h"
 #include "elf/riscv.h"
-#include "elfxx-riscv.h"
+#include "cpu-riscv.h"
 
 #include "bfd_stdint.h"
 #include <ctype.h>
 
-static enum riscv_priv_spec_class default_priv_spec = PRIV_SPEC_CLASS_NONE;
+static enum riscv_spec_class default_priv_spec = PRIV_SPEC_CLASS_NONE;
 
 struct riscv_private_data
 {
@@ -99,17 +99,22 @@  parse_riscv_dis_option (const char *option)
   value = equal + 1;
   if (strcmp (option, "priv-spec") == 0)
     {
-      enum riscv_priv_spec_class priv_spec = PRIV_SPEC_CLASS_NONE;
-      if (!riscv_get_priv_spec_class (value, &priv_spec))
+      enum riscv_spec_class priv_spec = PRIV_SPEC_CLASS_NONE;
+      const char *name = NULL;
+
+      RISCV_GET_PRIV_SPEC_CLASS (value, priv_spec);
+      if (priv_spec == PRIV_SPEC_CLASS_NONE)
 	opcodes_error_handler (_("unknown privileged spec set by %s=%s"),
 			       option, value);
       else if (default_priv_spec == PRIV_SPEC_CLASS_NONE)
 	default_priv_spec = priv_spec;
       else if (default_priv_spec != priv_spec)
-	opcodes_error_handler (_("mis-matched privilege spec set by %s=%s, "
-				 "the elf privilege attribute is %s"),
-			       option, value,
-			       riscv_get_priv_spec_name (default_priv_spec));
+	{
+	  RISCV_GET_PRIV_SPEC_NAME (name, default_priv_spec);
+	  opcodes_error_handler (_("mis-matched privilege spec set by %s=%s, "
+				   "the elf privilege attribute is %s"),
+				 option, value, name);
+	}
     }
   else
     {
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index b072ee2..50a3f30 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -886,90 +886,3 @@  const struct riscv_opcode riscv_insn_types[] =
 /* Terminate the list.  */
 {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}
 };
-
-/* All standard extensions defined in all supported ISA spec.  */
-const struct riscv_ext_version riscv_ext_version_table[] =
-{
-/* name, ISA spec, major version, minor version.  */
-{"e", ISA_SPEC_CLASS_20191213, 1, 9},
-{"e", ISA_SPEC_CLASS_20190608, 1, 9},
-{"e", ISA_SPEC_CLASS_2P2,      1, 9},
-
-{"i", ISA_SPEC_CLASS_20191213, 2, 1},
-{"i", ISA_SPEC_CLASS_20190608, 2, 1},
-{"i", ISA_SPEC_CLASS_2P2,      2, 0},
-
-{"m", ISA_SPEC_CLASS_20191213, 2, 0},
-{"m", ISA_SPEC_CLASS_20190608, 2, 0},
-{"m", ISA_SPEC_CLASS_2P2,      2, 0},
-
-{"a", ISA_SPEC_CLASS_20191213, 2, 1},
-{"a", ISA_SPEC_CLASS_20190608, 2, 0},
-{"a", ISA_SPEC_CLASS_2P2,      2, 0},
-
-{"f", ISA_SPEC_CLASS_20191213, 2, 2},
-{"f", ISA_SPEC_CLASS_20190608, 2, 2},
-{"f", ISA_SPEC_CLASS_2P2,      2, 0},
-
-{"d", ISA_SPEC_CLASS_20191213, 2, 2},
-{"d", ISA_SPEC_CLASS_20190608, 2, 2},
-{"d", ISA_SPEC_CLASS_2P2,      2, 0},
-
-{"q", ISA_SPEC_CLASS_20191213, 2, 2},
-{"q", ISA_SPEC_CLASS_20190608, 2, 2},
-{"q", ISA_SPEC_CLASS_2P2,      2, 0},
-
-{"c", ISA_SPEC_CLASS_20191213, 2, 0},
-{"c", ISA_SPEC_CLASS_20190608, 2, 0},
-{"c", ISA_SPEC_CLASS_2P2,      2, 0},
-
-{"zicsr", ISA_SPEC_CLASS_20191213, 2, 0},
-{"zicsr", ISA_SPEC_CLASS_20190608, 2, 0},
-
-{"zifencei", ISA_SPEC_CLASS_20191213, 2, 0},
-{"zifencei", ISA_SPEC_CLASS_20190608, 2, 0},
-
-{"zihintpause", ISA_SPEC_CLASS_DRAFT, 1, 0},
-
-/* Terminate the list.  */
-{NULL, 0, 0, 0}
-};
-
-struct isa_spec_t
-{
-  const char *name;
-  enum riscv_isa_spec_class class;
-};
-
-/* List for all supported ISA spec versions.  */
-static const struct isa_spec_t isa_specs[] =
-{
-  {"2.2",      ISA_SPEC_CLASS_2P2},
-  {"20190608", ISA_SPEC_CLASS_20190608},
-  {"20191213", ISA_SPEC_CLASS_20191213},
-
-  /* Terminate the list.  */
-  {NULL, 0}
-};
-
-/* Get the corresponding ISA spec class by giving a ISA spec string.  */
-
-int
-riscv_get_isa_spec_class (const char *s,
-                         enum riscv_isa_spec_class *class)
-{
-  const struct isa_spec_t *version;
-
-  if (s == NULL)
-    return 0;
-
-  for (version = &isa_specs[0]; version->name != NULL; ++version)
-    if (strcmp (version->name, s) == 0)
-      {
-       *class = version->class;
-       return 1;
-      }
-
-  /* Can not find the supported ISA spec.  */
-  return 0;
-}