public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] RISC-V: Add bfd/cpu-riscv.h to support all spec versions controling.
@ 2021-01-28  4:46 Nelson Chu
  2021-02-17  2:05 ` Nelson Chu
  0 siblings, 1 reply; 5+ messages in thread
From: Nelson Chu @ 2021-01-28  4:46 UTC (permalink / raw)
  To: binutils, jimw, amodra, nickc, kito.cheng

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.
    * doc/Makefile.in: Regenerated.
    * po/SRC-POTFILES.in: Regenerated.
    * cpu-riscv.h: Added to support spec versions controling.  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/Makefile.am        |   2 +-
 bfd/Makefile.in        |   3 +-
 bfd/cpu-riscv.c        | 123 ++++++++++++++----------------------------
 bfd/cpu-riscv.h        |  81 ++++++++++++++++++++++++++++
 bfd/doc/Makefile.in    |   1 +
 bfd/elfnn-riscv.c      |   5 +-
 bfd/elfxx-riscv.c      |   5 +-
 bfd/elfxx-riscv.h      |  12 -----
 bfd/po/SRC-POTFILES.in |   1 +
 gas/config/tc-riscv.c  | 141 ++++++++++++++++++++++++++++++++++++++++---------
 include/opcode/riscv.h |  69 ------------------------
 opcodes/riscv-dis.c    |  21 +++++---
 opcodes/riscv-opc.c    |  91 -------------------------------
 13 files changed, 262 insertions(+), 293 deletions(-)
 create mode 100644 bfd/cpu-riscv.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..3c98317 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -440,6 +440,7 @@ pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -1099,7 +1100,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..aff0fcf
--- /dev/null
+++ b/bfd/cpu-riscv.h
@@ -0,0 +1,81 @@
+/* RISC-V spec version controling 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/doc/Makefile.in b/bfd/doc/Makefile.in
index 1902697..129cadc 100644
--- a/bfd/doc/Makefile.in
+++ b/bfd/doc/Makefile.in
@@ -377,6 +377,7 @@ pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index d7ffb8f..9152f93 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 152e382..25ac679 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/config/tc-riscv.c b/gas/config/tc-riscv.c
index db8520a..978cd74 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,97 @@ 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},
+
+  {"zba", ISA_SPEC_CLASS_DRAFT, 0, 93},
+  {"zbb", ISA_SPEC_CLASS_DRAFT, 0, 93},
+  {"zbc", ISA_SPEC_CLASS_DRAFT, 0, 93},
+
+  /* Terminate the list.  */
+  {NULL, 0, 0, 0}
+};
+
 #ifndef DEFAULT_ARCH
 #define DEFAULT_ARCH "riscv64"
 #endif
@@ -79,8 +171,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 +198,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 +218,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 +241,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 meaningless.  */
+  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;
     }
@@ -262,10 +354,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)
     {
@@ -697,10 +790,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;
@@ -792,8 +885,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);
@@ -2825,7 +2918,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)
@@ -3661,7 +3754,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/opcode/riscv.h b/include/opcode/riscv.h
index 04d23a7..08aa5dc 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -362,71 +362,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
 
@@ -501,9 +436,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/riscv-dis.c b/opcodes/riscv-dis.c
index a6a78ba..cc80d90 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 9e73e75..3b4523b 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -941,94 +941,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},
-
-{"zba", ISA_SPEC_CLASS_DRAFT, 0, 93},
-{"zbb", ISA_SPEC_CLASS_DRAFT, 0, 93},
-{"zbc", ISA_SPEC_CLASS_DRAFT, 0, 93},
-
-/* 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;
-}
-- 
2.7.4


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

* Re: [PATCH] RISC-V: Add bfd/cpu-riscv.h to support all spec versions controling.
  2021-01-28  4:46 [PATCH] RISC-V: Add bfd/cpu-riscv.h to support all spec versions controling Nelson Chu
@ 2021-02-17  2:05 ` Nelson Chu
  2021-02-17 10:56   ` Nick Clifton
  2021-02-17 22:49   ` Jim Wilson
  0 siblings, 2 replies; 5+ messages in thread
From: Nelson Chu @ 2021-02-17  2:05 UTC (permalink / raw)
  To: Binutils, Jim Wilson, Alan Modra, Nick Clifton, Kito Cheng

Hi Guys,

Ping!  Since I add the new file bfd/cpu-riscv.h to support all spec
versions controlling, this should require approval.

Thanks
Nelson

On Thu, Jan 28, 2021 at 12:46 PM Nelson Chu <nelson.chu@sifive.com> wrote:
>
> 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.
>     * doc/Makefile.in: Regenerated.
>     * po/SRC-POTFILES.in: Regenerated.
>     * cpu-riscv.h: Added to support spec versions controling.  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/Makefile.am        |   2 +-
>  bfd/Makefile.in        |   3 +-
>  bfd/cpu-riscv.c        | 123 ++++++++++++++----------------------------
>  bfd/cpu-riscv.h        |  81 ++++++++++++++++++++++++++++
>  bfd/doc/Makefile.in    |   1 +
>  bfd/elfnn-riscv.c      |   5 +-
>  bfd/elfxx-riscv.c      |   5 +-
>  bfd/elfxx-riscv.h      |  12 -----
>  bfd/po/SRC-POTFILES.in |   1 +
>  gas/config/tc-riscv.c  | 141 ++++++++++++++++++++++++++++++++++++++++---------
>  include/opcode/riscv.h |  69 ------------------------
>  opcodes/riscv-dis.c    |  21 +++++---
>  opcodes/riscv-opc.c    |  91 -------------------------------
>  13 files changed, 262 insertions(+), 293 deletions(-)
>  create mode 100644 bfd/cpu-riscv.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..3c98317 100644
> --- a/bfd/Makefile.in
> +++ b/bfd/Makefile.in
> @@ -440,6 +440,7 @@ pdfdir = @pdfdir@
>  prefix = @prefix@
>  program_transform_name = @program_transform_name@
>  psdir = @psdir@
> +runstatedir = @runstatedir@
>  sbindir = @sbindir@
>  sharedstatedir = @sharedstatedir@
>  srcdir = @srcdir@
> @@ -1099,7 +1100,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..aff0fcf
> --- /dev/null
> +++ b/bfd/cpu-riscv.h
> @@ -0,0 +1,81 @@
> +/* RISC-V spec version controling 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/doc/Makefile.in b/bfd/doc/Makefile.in
> index 1902697..129cadc 100644
> --- a/bfd/doc/Makefile.in
> +++ b/bfd/doc/Makefile.in
> @@ -377,6 +377,7 @@ pdfdir = @pdfdir@
>  prefix = @prefix@
>  program_transform_name = @program_transform_name@
>  psdir = @psdir@
> +runstatedir = @runstatedir@
>  sbindir = @sbindir@
>  sharedstatedir = @sharedstatedir@
>  srcdir = @srcdir@
> diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
> index d7ffb8f..9152f93 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 152e382..25ac679 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/config/tc-riscv.c b/gas/config/tc-riscv.c
> index db8520a..978cd74 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,97 @@ 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},
> +
> +  {"zba", ISA_SPEC_CLASS_DRAFT, 0, 93},
> +  {"zbb", ISA_SPEC_CLASS_DRAFT, 0, 93},
> +  {"zbc", ISA_SPEC_CLASS_DRAFT, 0, 93},
> +
> +  /* Terminate the list.  */
> +  {NULL, 0, 0, 0}
> +};
> +
>  #ifndef DEFAULT_ARCH
>  #define DEFAULT_ARCH "riscv64"
>  #endif
> @@ -79,8 +171,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 +198,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 +218,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 +241,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 meaningless.  */
> +  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;
>      }
> @@ -262,10 +354,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)
>      {
> @@ -697,10 +790,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;
> @@ -792,8 +885,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);
> @@ -2825,7 +2918,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)
> @@ -3661,7 +3754,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/opcode/riscv.h b/include/opcode/riscv.h
> index 04d23a7..08aa5dc 100644
> --- a/include/opcode/riscv.h
> +++ b/include/opcode/riscv.h
> @@ -362,71 +362,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
>
> @@ -501,9 +436,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/riscv-dis.c b/opcodes/riscv-dis.c
> index a6a78ba..cc80d90 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 9e73e75..3b4523b 100644
> --- a/opcodes/riscv-opc.c
> +++ b/opcodes/riscv-opc.c
> @@ -941,94 +941,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},
> -
> -{"zba", ISA_SPEC_CLASS_DRAFT, 0, 93},
> -{"zbb", ISA_SPEC_CLASS_DRAFT, 0, 93},
> -{"zbc", ISA_SPEC_CLASS_DRAFT, 0, 93},
> -
> -/* 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;
> -}
> --
> 2.7.4
>

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

* Re: [PATCH] RISC-V: Add bfd/cpu-riscv.h to support all spec versions controling.
  2021-02-17  2:05 ` Nelson Chu
@ 2021-02-17 10:56   ` Nick Clifton
  2021-02-17 22:49   ` Jim Wilson
  1 sibling, 0 replies; 5+ messages in thread
From: Nick Clifton @ 2021-02-17 10:56 UTC (permalink / raw)
  To: Nelson Chu, Binutils, Jim Wilson, Alan Modra, Kito Cheng

Hi Nelson,

>> bfd/
>>      * Makefile.am: Added cpu-riscv.h.
>>      * Makefile.in: Regenerated.
>>      * doc/Makefile.in: Regenerated.
>>      * po/SRC-POTFILES.in: Regenerated.
>>      * cpu-riscv.h: Added to support spec versions controling.  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.

Patch approved - please apply.

Cheers
   Nick


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

* Re: [PATCH] RISC-V: Add bfd/cpu-riscv.h to support all spec versions controling.
  2021-02-17  2:05 ` Nelson Chu
  2021-02-17 10:56   ` Nick Clifton
@ 2021-02-17 22:49   ` Jim Wilson
  2021-02-18  7:43     ` Nelson Chu
  1 sibling, 1 reply; 5+ messages in thread
From: Jim Wilson @ 2021-02-17 22:49 UTC (permalink / raw)
  To: Nelson Chu; +Cc: Binutils, Alan Modra, Nick Clifton, Kito Cheng

On Tue, Feb 16, 2021 at 6:05 PM Nelson Chu <nelson.chu@sifive.com> wrote:

> > diff --git a/bfd/doc/Makefile.in b/bfd/doc/Makefile.in
> > index 1902697..129cadc 100644
> > --- a/bfd/doc/Makefile.in
> > +++ b/bfd/doc/Makefile.in
> > @@ -377,6 +377,7 @@ pdfdir = @pdfdir@
> >  prefix = @prefix@
> >  program_transform_name = @program_transform_name@
> >  psdir = @psdir@
> > +runstatedir = @runstatedir@
> >  sbindir = @sbindir@
> >  sharedstatedir = @sharedstatedir@
> >  srcdir = @srcdir@
>
> FYI  This runstatedir stuff is a feature not in the last FSF autoconf
release from 2012, but present in some linux distros.  To avoid this
problem, you shouldn't use /usr/bin/autoconf or automake.  Rather, you
should build them directly from FSF autoconf/automake sources, using the
same version that is mentioned in the comments at the top of the generated
files, and then use your own programs when regenerating toolchain files.
If you did that, then you wouldn't have a change for this file.  The same
change would also be missing from other Makefile.in files.  But this is a
minor issue, and will likely be fixed next time someone regenerates the
files.

The autoconf-2.69 we use was released in 2012.  There are now autoconf 2.70
(Dec 2020) and 2.71 (Jan 2021) releases.  If we upgraded to a newer
autoconf release that would fix this problem.  Though of course it might
cause other problems.  A lot of stuff could have changed in the last 9
years.

The patches look OK to me also.

Jim

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

* Re: [PATCH] RISC-V: Add bfd/cpu-riscv.h to support all spec versions controling.
  2021-02-17 22:49   ` Jim Wilson
@ 2021-02-18  7:43     ` Nelson Chu
  0 siblings, 0 replies; 5+ messages in thread
From: Nelson Chu @ 2021-02-18  7:43 UTC (permalink / raw)
  To: Jim Wilson, Nick Clifton; +Cc: Binutils, Alan Modra, Kito Cheng

Hi Nick and Jim,

Thanks for the reviews and approvals!  I have commited the v2 patch,
and also fixed some conflicts and typos.

On Thu, Feb 18, 2021 at 6:50 AM Jim Wilson <jimw@sifive.com> wrote:
>
> On Tue, Feb 16, 2021 at 6:05 PM Nelson Chu <nelson.chu@sifive.com> wrote:
>>
>> > diff --git a/bfd/doc/Makefile.in b/bfd/doc/Makefile.in
>> > index 1902697..129cadc 100644
>> > --- a/bfd/doc/Makefile.in
>> > +++ b/bfd/doc/Makefile.in
>> > @@ -377,6 +377,7 @@ pdfdir = @pdfdir@
>> >  prefix = @prefix@
>> >  program_transform_name = @program_transform_name@
>> >  psdir = @psdir@
>> > +runstatedir = @runstatedir@
>> >  sbindir = @sbindir@
>> >  sharedstatedir = @sharedstatedir@
>> >  srcdir = @srcdir@
>>
> FYI  This runstatedir stuff is a feature not in the last FSF autoconf release from 2012, but present in some linux distros.  To avoid this problem, you shouldn't use /usr/bin/autoconf or automake.  Rather, you should build them directly from FSF autoconf/automake sources, using the same version that is mentioned in the comments at the top of the generated files, and then use your own programs when regenerating toolchain files.  If you did that, then you wouldn't have a change for this file.  The same change would also be missing from other Makefile.in files.  But this is a minor issue, and will likely be fixed next time someone regenerates the files.
>
> The autoconf-2.69 we use was released in 2012.  There are now autoconf 2.70 (Dec 2020) and 2.71 (Jan 2021) releases.  If we upgraded to a newer autoconf release that would fix this problem.  Though of course it might cause other problems.  A lot of stuff could have changed in the last 9 years.

That's weird, even if I have switched to the approved versions of auto
tools (autoconf 2.69 and automake 1.15.1), I still get the
"runstatedir" in my Makefile.in.  I guess that is because I used to
regenerate the files by running autoconf and automake separately.
Kito suggests that using the "export PATH" to set the auto tools, and
then run autoreconf should be better.  After that, I can regenerate
the expected files without the "runstatedir".

Thanks for all
Nelson

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

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

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-28  4:46 [PATCH] RISC-V: Add bfd/cpu-riscv.h to support all spec versions controling Nelson Chu
2021-02-17  2:05 ` Nelson Chu
2021-02-17 10:56   ` Nick Clifton
2021-02-17 22:49   ` Jim Wilson
2021-02-18  7:43     ` Nelson Chu

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