RISC-V: Merged extension string tables and their version tables into one.
authorNelson Chu <nelson.chu@sifive.com>
Thu, 16 Sep 2021 06:36:54 +0000 (14:36 +0800)
committerNelson Chu <nelson.chu@sifive.com>
Fri, 17 Sep 2021 08:33:54 +0000 (16:33 +0800)
There are two main reasons for this patch,

* In the past we had two extension tables, one is used to record all
supported extensions in bfd/elfxx-riscv.c, another is used to get the
default extension versions in gas/config/tc-riscv.c.  It is hard to
maintain lots of tables in different files, but in fact we can merge
them into just one table.  Therefore, we now define many riscv_supported_std*
tables, which record names and versions for all supported extensions.
We not only use these tables to initialize the riscv_ext_order, but
also use them to get the default versions of extensions, and decide if
the extensions should be enbaled by default.

* We add a new filed `default_enable' for the riscv_supported_std* tables,
to decide if the extension should be enabled by default.  For now if the
`default_enable' field of the extension is set to EXT_DEFAULT, then we
should enable the extension when the -march and elf architecture attributes
are not set.  In the future, I suppose the `default_enable' can be set
to lots of EXT_<VENDOR>, each vendor can decide to open which extensions,
when the target triple of vendor is chosen.

The elf/linux regression tests of riscv-gnu-toolchain are passed.

bfd/
* elfnn-riscv.c (cpu-riscv.h): Removed sine it is included in
bfd/elfxx-riscv.h.
(riscv_merge_std_ext): Updated since the field of rpe is changed.
* elfxx-riscv.c (cpu-riscv.h): Removed.
(riscv_implicit_subsets): Added implicit extensions for g.
(struct riscv_supported_ext): Used to be riscv_ext_version.  Moved
from gas/config/tc-riscv.c, and added new field `default_enable' to
decide if the extension should be enabled by default.
(EXT_DEFAULT): Defined for `default_enable' field.
(riscv_supported_std_ext): It used to return the supported standard
architecture string, but now we move ext_version_table from
gas/config/tc-riscv.c to here, and rename it to riscv_supported_std_ext.
Currently we not only use the table to initialize riscv_ext_order, but
also get the default versions of extensions, and decide if the extensions
should be enbaled by default.
(riscv_supported_std_z_ext): Likewise, but is used for z* extensions.
(riscv_supported_std_s_ext): Likewise, but is used for s* extensions.
(riscv_supported_std_h_ext): Likewise, but is used for h* extensions.
(riscv_supported_std_zxm_ext): Likewise, but is used for zxm* extensions.
(riscv_all_supported_ext): Includes all supported extension tables.
(riscv_known_prefixed_ext): Updated.
(riscv_valid_prefixed_ext): Updated.
(riscv_init_ext_order): Init the riscv_ext_order table according to
riscv_supported_std_ext.
(riscv_get_default_ext_version): Moved from gas/config/tc-riscv.c.
Get the versions of extensions from riscv_supported_std* tables.
(riscv_parse_add_subset): Updated.
(riscv_parse_std_ext): Updated.
(riscv_set_default_arch): Set the default subset list according to
the default_enable field of riscv_supported_*ext tables.
(riscv_parse_subset): If the input ARCH is NULL, then we call
riscv_set_default_arch to set the default subset list.
* elfxx-riscv.h (cpu-riscv.h): Included.
(riscv_parse_subset_t): Removed get_default_version field, and added
isa_spec field to replace it.
(extern riscv_supported_std_ext): Removed.
gas/
* (bfd/cpu-riscv.h): Removed.
(struct riscv_ext_version): Renamed and moved to bfd/elfxx-riscv.c.
(ext_version_table): Likewise.
(riscv_get_default_ext_version): Likewise.
(ext_version_hash): Removed.
(init_ext_version_hash): Removed.
(riscv_set_arch): Updated since the field of rps is changed.  Besides,
report error when the architecture string is empty.
(riscv_after_parse_args): Updated.

bfd/elfnn-riscv.c
bfd/elfxx-riscv.c
bfd/elfxx-riscv.h
gas/config/tc-riscv.c

index a10384cd4d3695415c5b5ed416c236afc329ace1..2e8df72fa2a8121f25bc96d7883ac1416f84483a 100644 (file)
@@ -32,7 +32,6 @@
 #include "elf/riscv.h"
 #include "opcode/riscv.h"
 #include "objalloc.h"
-#include "cpu-riscv.h"
 
 #include <limits.h>
 #ifndef CHAR_BIT
@@ -3443,7 +3442,7 @@ riscv_merge_std_ext (bfd *ibfd,
                     struct riscv_subset_t **pin,
                     struct riscv_subset_t **pout)
 {
-  const char *standard_exts = riscv_supported_std_ext ();
+  const char *standard_exts = "mafdqlcbjtpvn";
   const char *p;
   struct riscv_subset_t *in = *pin;
   struct riscv_subset_t *out = *pout;
@@ -3587,13 +3586,13 @@ riscv_merge_arch_attr_info (bfd *ibfd, char *in_arch, char *out_arch)
   rpe_in.subset_list = &in_subsets;
   rpe_in.error_handler = _bfd_error_handler;
   rpe_in.xlen = &xlen_in;
-  rpe_in.get_default_version = NULL;
+  rpe_in.isa_spec = ISA_SPEC_CLASS_NONE;
   rpe_in.check_unknown_prefixed_ext = false;
 
   rpe_out.subset_list = &out_subsets;
   rpe_out.error_handler = _bfd_error_handler;
   rpe_out.xlen = &xlen_out;
-  rpe_out.get_default_version = NULL;
+  rpe_out.isa_spec = ISA_SPEC_CLASS_NONE;
   rpe_out.check_unknown_prefixed_ext = false;
 
   if (in_arch == NULL && out_arch == NULL)
index ddcf872d63c3315301b8be819d78b257362afdfd..b467bceb919de1236b6b878af81e72146e1bffb7 100644 (file)
@@ -29,7 +29,6 @@
 #include "libiberty.h"
 #include "elfxx-riscv.h"
 #include "safe-ctype.h"
-#include "cpu-riscv.h"
 
 #define MINUS_ONE ((bfd_vma)0 - 1)
 
@@ -1066,6 +1065,11 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] =
   {"e", "i",           check_implicit_always},
   {"i", "zicsr",       check_implicit_for_i},
   {"i", "zifencei",    check_implicit_for_i},
+  {"g", "i",           check_implicit_always},
+  {"g", "m",           check_implicit_always},
+  {"g", "a",           check_implicit_always},
+  {"g", "f",           check_implicit_always},
+  {"g", "d",           check_implicit_always},
   {"g", "zicsr",       check_implicit_always},
   {"g", "zifencei",    check_implicit_always},
   {"q", "d",           check_implicit_always},
@@ -1074,31 +1078,98 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] =
   {NULL, NULL, NULL}
 };
 
-/* Lists of prefixed class extensions that binutils should know about.
-   Whether or not a particular entry is in these lists will dictate if
-   gas/ld will accept its presence in the architecture string.
+/* For default_enable field, decide if the extension should
+   be enbaled by default.  */
 
-   Please add the extensions to the lists in lower case.  However, keep
-   these subsets in alphabetical order in these tables is recommended,
-   although there is no impact on the current implementation.  */
+#define EXT_DEFAULT   0x1
 
-static const char * const riscv_std_z_ext_strtab[] =
+/* List all extensions that binutils should know about.  */
+
+struct riscv_supported_ext
 {
-  "zba", "zbb", "zbc", "zicsr", "zifencei", "zihintpause", NULL
+  const char *name;
+  enum riscv_spec_class isa_spec_class;
+  int major_version;
+  int minor_version;
+  unsigned long default_enable;
 };
 
-static const char * const riscv_std_s_ext_strtab[] =
+/* The standard extensions must be added in canonical order.  */
+
+static struct riscv_supported_ext riscv_supported_std_ext[] =
 {
-  NULL
+  {"e",                ISA_SPEC_CLASS_20191213,        1, 9, 0 },
+  {"e",                ISA_SPEC_CLASS_20190608,        1, 9, 0 },
+  {"e",                ISA_SPEC_CLASS_2P2,             1, 9, 0 },
+  {"i",                ISA_SPEC_CLASS_20191213,        2, 1, 0 },
+  {"i",                ISA_SPEC_CLASS_20190608,        2, 1, 0 },
+  {"i",                ISA_SPEC_CLASS_2P2,             2, 0, 0 },
+  /* The g is a special case which we don't want to output it,
+     but still need it when adding implicit extensions.  */
+  {"g",                ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, EXT_DEFAULT },
+  {"m",                ISA_SPEC_CLASS_20191213,        2, 0, 0 },
+  {"m",                ISA_SPEC_CLASS_20190608,        2, 0, 0 },
+  {"m",                ISA_SPEC_CLASS_2P2,             2, 0, 0 },
+  {"a",                ISA_SPEC_CLASS_20191213,        2, 1, 0 },
+  {"a",                ISA_SPEC_CLASS_20190608,        2, 0, 0 },
+  {"a",                ISA_SPEC_CLASS_2P2,             2, 0, 0 },
+  {"f",                ISA_SPEC_CLASS_20191213,        2, 2, 0 },
+  {"f",                ISA_SPEC_CLASS_20190608,        2, 2, 0 },
+  {"f",                ISA_SPEC_CLASS_2P2,             2, 0, 0 },
+  {"d",                ISA_SPEC_CLASS_20191213,        2, 2, 0 },
+  {"d",                ISA_SPEC_CLASS_20190608,        2, 2, 0 },
+  {"d",                ISA_SPEC_CLASS_2P2,             2, 0, 0 },
+  {"q",                ISA_SPEC_CLASS_20191213,        2, 2, 0 },
+  {"q",                ISA_SPEC_CLASS_20190608,        2, 2, 0 },
+  {"q",                ISA_SPEC_CLASS_2P2,             2, 0, 0 },
+  {"l",                ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 },
+  {"c",                ISA_SPEC_CLASS_20191213,        2, 0, 0 },
+  {"c",                ISA_SPEC_CLASS_20190608,        2, 0, 0 },
+  {"c",                ISA_SPEC_CLASS_2P2,             2, 0, 0 },
+  {"b",                ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 },
+  {"j",                ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 },
+  {"t",                ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 },
+  {"p",                ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 },
+  {"v",                ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 },
+  {"n",                ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, 0 },
+  {NULL, 0, 0, 0, 0}
 };
 
-static const char * const riscv_std_h_ext_strtab[] =
+static struct riscv_supported_ext riscv_supported_std_z_ext[] =
 {
-  NULL
+  {"zicsr",            ISA_SPEC_CLASS_20191213,        2, 0,  0 },
+  {"zicsr",            ISA_SPEC_CLASS_20190608,        2, 0,  0 },
+  {"zifencei",         ISA_SPEC_CLASS_20191213,        2, 0,  0 },
+  {"zifencei",         ISA_SPEC_CLASS_20190608,        2, 0,  0 },
+  {"zihintpause",      ISA_SPEC_CLASS_DRAFT,           1, 0,  0 },
+  {"zbb",              ISA_SPEC_CLASS_DRAFT,           0, 93, 0 },
+  {"zba",              ISA_SPEC_CLASS_DRAFT,           0, 93, 0 },
+  {"zbc",              ISA_SPEC_CLASS_DRAFT,           0, 93, 0 },
+  {NULL, 0, 0, 0, 0}
+};
+
+static struct riscv_supported_ext riscv_supported_std_s_ext[] =
+{
+  {NULL, 0, 0, 0, 0}
+};
+
+static struct riscv_supported_ext riscv_supported_std_h_ext[] =
+{
+  {NULL, 0, 0, 0, 0}
 };
 
-static const char * const riscv_std_zxm_ext_strtab[] =
+static struct riscv_supported_ext riscv_supported_std_zxm_ext[] =
 {
+  {NULL, 0, 0, 0, 0}
+};
+
+const struct riscv_supported_ext *riscv_all_supported_ext[] =
+{
+  riscv_supported_std_ext,
+  riscv_supported_std_z_ext,
+  riscv_supported_std_s_ext,
+  riscv_supported_std_h_ext,
+  riscv_supported_std_zxm_ext,
   NULL
 };
 
@@ -1156,11 +1227,11 @@ riscv_get_prefix_class (const char *arch)
 
 static bool
 riscv_known_prefixed_ext (const char *ext,
-                         const char *const *known_exts)
+                         struct riscv_supported_ext *known_exts)
 {
   size_t i;
-  for (i = 0; known_exts[i]; ++i)
-    if (strcmp (ext, known_exts[i]) == 0)
+  for (i = 0; known_exts[i].name != NULL; ++i)
+    if (strcmp (ext, known_exts[i].name) == 0)
       return true;
   return false;
 }
@@ -1175,13 +1246,13 @@ riscv_valid_prefixed_ext (const char *ext)
   switch (class)
   {
   case RV_ISA_CLASS_Z:
-    return riscv_known_prefixed_ext (ext, riscv_std_z_ext_strtab);
+    return riscv_known_prefixed_ext (ext, riscv_supported_std_z_ext);
   case RV_ISA_CLASS_ZXM:
-    return riscv_known_prefixed_ext (ext, riscv_std_zxm_ext_strtab);
+    return riscv_known_prefixed_ext (ext, riscv_supported_std_zxm_ext);
   case RV_ISA_CLASS_S:
-    return riscv_known_prefixed_ext (ext, riscv_std_s_ext_strtab);
+    return riscv_known_prefixed_ext (ext, riscv_supported_std_s_ext);
   case RV_ISA_CLASS_H:
-    return riscv_known_prefixed_ext (ext, riscv_std_h_ext_strtab);
+    return riscv_known_prefixed_ext (ext, riscv_supported_std_h_ext);
   case RV_ISA_CLASS_X:
     /* Only the single x is invalid.  */
     if (strcmp (ext, "x") != 0)
@@ -1201,24 +1272,22 @@ static void
 riscv_init_ext_order (void)
 {
   static bool inited = false;
-  const char *std_base_exts = "eig";
-  const char *std_remain_exts = riscv_supported_std_ext ();
-  const char *ext;
-  int order;
-
   if (inited)
     return;
 
   /* The orders of all standard extensions are positive.  */
-  order = 1;
-
-  /* Init the standard base extensions first.  */
-  for (ext = std_base_exts; *ext; ext++)
-    riscv_ext_order[(*ext - 'a')] = order++;
+  int order = 1;
 
-  /* Init the standard remaining extensions.  */
-  for (ext = std_remain_exts; *ext; ext++)
-    riscv_ext_order[(*ext - 'a')] = order++;
+  int i = 0;
+  while (riscv_supported_std_ext[i].name != NULL)
+    {
+      const char *ext = riscv_supported_std_ext[i].name;
+      riscv_ext_order[(*ext - 'a')] = order++;
+      i++;
+      while (riscv_supported_std_ext[i].name
+            && strcmp (ext, riscv_supported_std_ext[i].name) == 0)
+       i++;
+    }
 
   /* Some of the prefixed keyword are not single letter, so we set
      their prefixed orders in the riscv_compare_subsets directly,
@@ -1345,6 +1414,46 @@ riscv_add_subset (riscv_subset_list_t *subset_list,
     subset_list->tail = new;
 }
 
+/* Get the default versions from the riscv_supported_*ext tables.  */
+
+static void
+riscv_get_default_ext_version (enum riscv_spec_class default_isa_spec,
+                              const char *name,
+                              int *major_version,
+                              int *minor_version)
+{
+  if (name == NULL || default_isa_spec == ISA_SPEC_CLASS_NONE)
+    return;
+
+  struct riscv_supported_ext *table = NULL;
+  enum riscv_prefix_ext_class class = riscv_get_prefix_class (name);
+  switch (class)
+    {
+    case RV_ISA_CLASS_ZXM: table = riscv_supported_std_zxm_ext; break;
+    case RV_ISA_CLASS_Z: table = riscv_supported_std_z_ext; break;
+    case RV_ISA_CLASS_S: table = riscv_supported_std_s_ext; break;
+    case RV_ISA_CLASS_H: table = riscv_supported_std_h_ext; break;
+    case RV_ISA_CLASS_X:
+      break;
+    default:
+      table = riscv_supported_std_ext;
+    }
+
+  int i = 0;
+  while (table != NULL && table[i].name != NULL)
+    {
+      if (strcmp (table[i].name, name) == 0
+         && (table[i].isa_spec_class == ISA_SPEC_CLASS_DRAFT
+             || table[i].isa_spec_class == default_isa_spec))
+       {
+         *major_version = table[i].major_version;
+         *minor_version = table[i].minor_version;
+         return;
+       }
+      i++;
+    }
+}
+
 /* Find the default versions for the extension before adding them to
    the subset list, if their versions are RISCV_UNKNOWN_VERSION.
    Afterwards, report errors if we can not find their default versions.  */
@@ -1359,10 +1468,10 @@ riscv_parse_add_subset (riscv_parse_subset_t *rps,
   int major_version = major;
   int minor_version = minor;
 
-  if ((major_version == RISCV_UNKNOWN_VERSION
+  if (major_version == RISCV_UNKNOWN_VERSION
        || minor_version == RISCV_UNKNOWN_VERSION)
-      && rps->get_default_version != NULL)
-    rps->get_default_version (subset, &major_version, &minor_version);
+    riscv_get_default_ext_version (rps->isa_spec, subset,
+                                  &major_version, &minor_version);
 
   /* We don't care the versions of the implicit extensions.  */
   if (!implicit
@@ -1476,15 +1585,6 @@ riscv_parsing_subset_version (riscv_parse_subset_t *rps,
   return p;
 }
 
-/* Return string which contain all supported standard extensions in
-   canonical order.  */
-
-const char *
-riscv_supported_std_ext (void)
-{
-  return "mafdqlcbjtpvn";
-}
-
 /* Parsing function for standard extensions.
 
    Return Value:
@@ -1500,59 +1600,13 @@ riscv_parse_std_ext (riscv_parse_subset_t *rps,
                     const char *arch,
                     const char *p)
 {
-  const char *all_std_exts = riscv_supported_std_ext ();
-  const char *std_exts = all_std_exts;
-  int major_version;
-  int minor_version;
-  char subset[2] = {0, 0};
-
   /* First letter must start with i, e or g.  */
-  switch (*p)
+  if (*p != 'e' && *p != 'i' && *p != 'g')
     {
-      case 'i':
-       p = riscv_parsing_subset_version (rps, arch, ++p,
-                                         &major_version,
-                                         &minor_version, true);
-       riscv_parse_add_subset (rps, "i",
-                               major_version,
-                               minor_version, false);
-       break;
-
-      case 'e':
-       p = riscv_parsing_subset_version (rps, arch, ++p,
-                                         &major_version,
-                                         &minor_version, true);
-       riscv_parse_add_subset (rps, "e",
-                               major_version,
-                               minor_version, false);
-       break;
-
-      case 'g':
-       p = riscv_parsing_subset_version (rps, arch, ++p,
-                                         &major_version,
-                                         &minor_version, true);
-       /* Expand g to imafd.  */
-       riscv_parse_add_subset (rps, "i",
-                               RISCV_UNKNOWN_VERSION,
-                               RISCV_UNKNOWN_VERSION, false);
-       for ( ; *std_exts != 'q'; std_exts++)
-         {
-           subset[0] = *std_exts;
-           riscv_parse_add_subset (rps, subset,
-                                   RISCV_UNKNOWN_VERSION,
-                                   RISCV_UNKNOWN_VERSION, false);
-         }
-       /* Add g as an implicit extension.  */
-       riscv_parse_add_subset (rps, "g",
-                               RISCV_UNKNOWN_VERSION,
-                               RISCV_UNKNOWN_VERSION, true);
-       break;
-
-      default:
-       rps->error_handler
-         (_("%s: first ISA extension must be `e', `i' or `g'"),
-          arch);
-       return NULL;
+      rps->error_handler
+       (_("%s: first ISA extension must be `e', `i' or `g'"),
+        arch);
+      return NULL;
     }
 
   while (p != NULL && *p != '\0')
@@ -1568,32 +1622,41 @@ riscv_parse_std_ext (riscv_parse_subset_t *rps,
          continue;
        }
 
-      /* Checking canonical order.  */
-      char std_ext = *p;
-      while (*std_exts && std_ext != *std_exts)
-       std_exts++;
+      bool implicit = false;
+      int major = RISCV_UNKNOWN_VERSION;
+      int minor = RISCV_UNKNOWN_VERSION;
+      char subset[2] = {0, 0};
+
+      subset[0] = *p;
 
-      if (std_ext != *std_exts)
+      /* Check if the standard extension is supported.  */
+      if (riscv_ext_order[(subset[0] - 'a')] == 0)
        {
-         if (riscv_ext_order[(std_ext - 'a')] == 0)
-           rps->error_handler
-             (_("%s: unknown standard ISA extension `%c'"),
-              arch, std_ext);
-         else
-           rps->error_handler
-             (_("%s: standard ISA extension `%c' is not "
-                "in canonical order"), arch, std_ext);
+         rps->error_handler
+           (_("%s: unknown standard ISA extension `%c'"),
+            arch, subset[0]);
          return NULL;
        }
 
-      std_exts++;
-      subset[0] = std_ext;
-      p = riscv_parsing_subset_version (rps, arch, ++p,
-                                       &major_version,
-                                       &minor_version, true);
-      riscv_parse_add_subset (rps, subset,
-                             major_version,
-                             minor_version, false);
+      /* Checking canonical order.  */
+      if (rps->subset_list->tail != NULL
+         && riscv_compare_subsets (rps->subset_list->tail->name, subset) > 0)
+       {
+         rps->error_handler
+           (_("%s: standard ISA extension `%c' is not "
+              "in canonical order"), arch, subset[0]);
+         return NULL;
+       }
+
+      p = riscv_parsing_subset_version (rps, arch, ++p, &major, &minor, true);
+      /* Added g as an implicit extension.  */
+      if (subset[0] == 'g')
+       {
+         implicit = true;
+         major = RISCV_UNKNOWN_VERSION;
+         minor = RISCV_UNKNOWN_VERSION;
+       }
+      riscv_parse_add_subset (rps, subset, major, minor, implicit);
     }
 
   return p;
@@ -1761,6 +1824,30 @@ riscv_parse_check_conflicts (riscv_parse_subset_t *rps)
   return no_conflict;
 }
 
+/* Set the default subset list according to the default_enable field
+   of riscv_supported_*ext tables.  */
+
+static void
+riscv_set_default_arch (riscv_parse_subset_t *rps)
+{
+  unsigned long enable = EXT_DEFAULT;
+  int i, j;
+  for (i = 0; riscv_all_supported_ext[i] != NULL; i++)
+    {
+      const struct riscv_supported_ext *table = riscv_all_supported_ext[i];
+      for (j = 0; table[j].name != NULL; j++)
+       {
+         bool implicit = false;
+         if (strcmp (table[j].name, "g") == 0)
+           implicit = true;
+         if (table[j].default_enable & enable)
+           riscv_parse_add_subset (rps, table[j].name,
+                                   RISCV_UNKNOWN_VERSION,
+                                   RISCV_UNKNOWN_VERSION, implicit);
+       }
+    }
+}
+
 /* Function for parsing ISA string.
 
    Return Value:
@@ -1776,6 +1863,17 @@ riscv_parse_subset (riscv_parse_subset_t *rps,
 {
   const char *p;
 
+  /* Init the riscv_ext_order array to compare the order of extensions
+     quickly.  */
+  riscv_init_ext_order ();
+
+  if (arch == NULL)
+    {
+      riscv_set_default_arch (rps);
+      riscv_parse_add_implicit_subsets (rps);
+      return riscv_parse_check_conflicts (rps);
+    }
+
   for (p = arch; *p != '\0'; p++)
     {
       if (ISUPPER (*p))
@@ -1800,11 +1898,13 @@ riscv_parse_subset (riscv_parse_subset_t *rps,
     }
   else
     {
-      /* ISA string shouldn't be NULL or empty here.  However,
-        it might be empty only when we failed to merge the ISA
-        string in the riscv_merge_attributes.  We have already
-        issued the correct error message in another side, so do
-        not issue this error when the ISA string is empty.  */
+      /* ISA string shouldn't be NULL or empty here.  For linker,
+        it might be empty when we failed to merge the ISA string
+        in the riscv_merge_attributes.  For assembler, we might
+        give an empty string by .attribute arch, "" or -march=.
+        However, We have already issued the correct error message
+        in another side, so do not issue this error when the ISA
+        string is empty.  */
       if (strlen (arch))
        rps->error_handler (
          _("%s: ISA string must begin with rv32 or rv64"),
@@ -1812,10 +1912,6 @@ riscv_parse_subset (riscv_parse_subset_t *rps,
       return false;
     }
 
-  /* Init the riscv_ext_order array to compare the order of extensions
-     quickly.  */
-  riscv_init_ext_order ();
-
   /* Parsing standard extension.  */
   p = riscv_parse_std_ext (rps, arch, p);
 
index 6a2501b7be80065e4531b7fd91b3d004d6eb5f00..e691a97ecda8e4b842d654abbfb0acdb2d2d8707 100644 (file)
@@ -23,6 +23,7 @@
 #include "elf/common.h"
 #include "elf/internal.h"
 #include "opcode/riscv.h"
+#include "cpu-riscv.h"
 
 #define RISCV_UNKNOWN_VERSION -1
 
@@ -71,9 +72,7 @@ typedef struct
   void (*error_handler) (const char *,
                         ...) ATTRIBUTE_PRINTF_1;
   unsigned *xlen;
-  void (*get_default_version) (const char *,
-                              int *,
-                              int *);
+  enum riscv_spec_class isa_spec;
   bool check_unknown_prefixed_ext;
 } riscv_parse_subset_t;
 
@@ -81,9 +80,6 @@ extern bool
 riscv_parse_subset (riscv_parse_subset_t *,
                    const char *);
 
-extern const char *
-riscv_supported_std_ext (void);
-
 extern void
 riscv_release_subset_list (riscv_subset_list_t *);
 
index 1dbc4d85b86f44670217157268ff68633a84919f..e7b733a4e6dd8b0dac37bf22e277c40063e24e9c 100644 (file)
@@ -29,7 +29,6 @@
 #include "dwarf2dbg.h"
 #include "dw2gencfi.h"
 
-#include "bfd/cpu-riscv.h"
 #include "bfd/elfxx-riscv.h"
 #include "elf/riscv.h"
 #include "opcode/riscv.h"
@@ -88,65 +87,6 @@ struct riscv_csr_extra
   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},
-
-  {"zbb",   ISA_SPEC_CLASS_DRAFT, 0, 93},
-  {"zba",   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
@@ -349,57 +289,6 @@ riscv_multi_subset_supports (enum riscv_insn_class insn_class)
     }
 }
 
-/* Handle of the extension with version hash table.  */
-static htab_t ext_version_hash = NULL;
-
-static htab_t
-init_ext_version_hash (void)
-{
-  const struct riscv_ext_version *table = ext_version_table;
-  htab_t hash = str_htab_create ();
-  int i = 0;
-
-  while (table[i].name)
-    {
-      const char *name = table[i].name;
-      if (str_hash_insert (hash, name, &table[i], 0) != NULL)
-       as_fatal (_("internal: duplicate %s"), name);
-
-      i++;
-      while (table[i].name
-            && strcmp (table[i].name, name) == 0)
-       i++;
-    }
-
-  return hash;
-}
-
-static void
-riscv_get_default_ext_version (const char *name,
-                              int *major_version,
-                              int *minor_version)
-{
-  struct riscv_ext_version *ext;
-
-  if (name == NULL || default_isa_spec == ISA_SPEC_CLASS_NONE)
-    return;
-
-  ext = (struct riscv_ext_version *) str_hash_find (ext_version_hash, name);
-  while (ext
-        && ext->name
-        && strcmp (ext->name, name) == 0)
-    {
-      if (ext->isa_spec_class == ISA_SPEC_CLASS_DRAFT
-         || ext->isa_spec_class == default_isa_spec)
-       {
-         *major_version = ext->major_version;
-         *minor_version = ext->minor_version;
-         return;
-       }
-      ext++;
-    }
-}
-
 /* Set which ISA and extensions are available.  */
 
 static void
@@ -409,11 +298,15 @@ riscv_set_arch (const char *s)
   rps.subset_list = &riscv_subsets;
   rps.error_handler = as_bad;
   rps.xlen = &xlen;
-  rps.get_default_version = riscv_get_default_ext_version;
+  rps.isa_spec = default_isa_spec;
   rps.check_unknown_prefixed_ext = true;
 
-  if (s == NULL)
-    return;
+  if (s != NULL && strcmp (s, "") == 0)
+    {
+      as_bad (_("the architecture string of -march and elf architecture "
+               "attributes cannot be empty"));
+      return;
+    }
 
   riscv_release_subset_list (&riscv_subsets);
   riscv_parse_subset (&rps, s);
@@ -3137,11 +3030,6 @@ riscv_after_parse_args (void)
       else
        as_bad ("unknown default architecture `%s'", default_arch);
     }
-  if (default_arch_with_ext == NULL)
-    default_arch_with_ext = xlen == 64 ? "rv64g" : "rv32g";
-
-  /* Initialize the hash table for extensions with default version.  */
-  ext_version_hash = init_ext_version_hash ();
 
   /* Set default specs.  */
   if (default_isa_spec == ISA_SPEC_CLASS_NONE)