[committed] RISC-V: Record implicit subsets in a table, to avoid repeated codes.

Nelson Chu nelson.chu@sifive.com
Thu May 13 07:47:11 GMT 2021


Add a new table, riscv_implicit_subsets, to record all implicit information.
So that we add all implicit subsets according to the table, to avoid too
many repeated codes in the riscv_parse_add_implicit_subsets.  Besides, the
check_func is used to check whether we should add this implicit subset.
For example, check_implicit_for_i checks the version of i, and we only add
zicsr and zifencei implicitly only when the version less than 2.1.

bfd/
    * elfxx-riscv.c (check_implicit_always): The check_func, always add
    the implicit subset without checking.
    (check_implicit_for_i): The check_func for i, only add zicsr and
    zifencei when the version of i less than 2.1.
    (struct riscv_implicit_subset): Record the subsets and their
    corresponding implicit subsets.
    (riscv_implicit_subsets): Table records all implicit informations.
    (riscv_parse_add_implicit_subsets): Updated and add implicit subsets
    according to riscv_implicit_subsets.  Remove the redundant codes.
---
 bfd/ChangeLog     |  12 +++++++
 bfd/elfxx-riscv.c | 103 ++++++++++++++++++++++++++----------------------------
 2 files changed, 61 insertions(+), 54 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index fcb692b..8dbe40c 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,15 @@
+2021-05-13  Nelson Chu  <nelson.chu@sifive.com>
+
+	* elfxx-riscv.c (check_implicit_always): The check_func, always add
+	the implicit subset without checking.
+	(check_implicit_for_i): The check_func for i, only add zicsr and
+	zifencei when the version of i less than 2.1.
+	(struct riscv_implicit_subset): Record the subsets and their
+	corresponding implicit subsets.
+	(riscv_implicit_subsets): Table records all implicit informations.
+	(riscv_parse_add_implicit_subsets): Updated and add implicit subsets
+	according to riscv_implicit_subsets.  Remove the redundant codes.
+
 2021-05-13  Alan Modra  <amodra@gmail.com>
 
 	PR 27858
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 3b38192..7206ec8 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1026,6 +1026,47 @@ riscv_elf_add_sub_reloc (bfd *abfd,
   return bfd_reloc_ok;
 }
 
+/* Always add the IMPLICIT for the SUBSET.  */
+
+static bool
+check_implicit_always (const char *implicit ATTRIBUTE_UNUSED,
+		       riscv_subset_t *subset ATTRIBUTE_UNUSED)
+{
+  return true;
+}
+
+/* Add the IMPLICIT only when the version of SUBSET less than 2.1.  */
+
+static bool
+check_implicit_for_i (const char *implicit ATTRIBUTE_UNUSED,
+		      riscv_subset_t *subset)
+{
+  return (subset->major_version < 2
+	  || (subset->major_version == 2
+	      && subset->minor_version < 1));
+}
+
+/* Record all implicit information for the subsets.  */
+struct riscv_implicit_subset
+{
+  const char *subset_name;
+  const char *implicit_name;
+  /* A function to determine if we need to add the implicit subset.  */
+  bool (*check_func) (const char *, riscv_subset_t *);
+};
+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", "zicsr",	check_implicit_always},
+  {"g", "zifencei",	check_implicit_always},
+  {"q", "d",		check_implicit_always},
+  {"d", "f",		check_implicit_always},
+  {"f", "zicsr",	check_implicit_always},
+  {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.
@@ -1694,61 +1735,15 @@ riscv_parse_prefixed_ext (riscv_parse_subset_t *rps,
 static void
 riscv_parse_add_implicit_subsets (riscv_parse_subset_t *rps)
 {
-  riscv_subset_t *subset = NULL;
-
-  if (riscv_lookup_subset (rps->subset_list, "e", &subset))
-    riscv_parse_add_subset (rps, "i",
-			    RISCV_UNKNOWN_VERSION,
-			    RISCV_UNKNOWN_VERSION, true);
-
-  /* Add the zicsr and zifencei only when the i's version less than 2.1.  */
-  if (riscv_lookup_subset (rps->subset_list, "i", &subset)
-      && (subset->major_version < 2
-	  || (subset->major_version == 2
-	      && subset->minor_version < 1)))
-    {
-      riscv_parse_add_subset (rps, "zicsr",
-			      RISCV_UNKNOWN_VERSION,
-			      RISCV_UNKNOWN_VERSION, true);
-      riscv_parse_add_subset (rps, "zifencei",
-			      RISCV_UNKNOWN_VERSION,
-			      RISCV_UNKNOWN_VERSION, true);
-    }
-
-  if (riscv_lookup_subset (rps->subset_list, "q", &subset))
+  struct riscv_implicit_subset *t = riscv_implicit_subsets;
+  for (; t->subset_name; t++)
     {
-      riscv_parse_add_subset (rps, "d",
-			      RISCV_UNKNOWN_VERSION,
-			      RISCV_UNKNOWN_VERSION, true);
-      riscv_parse_add_subset (rps, "f",
-			      RISCV_UNKNOWN_VERSION,
-			      RISCV_UNKNOWN_VERSION, true);
-      riscv_parse_add_subset (rps, "zicsr",
-			      RISCV_UNKNOWN_VERSION,
-			      RISCV_UNKNOWN_VERSION, true);
-    }
-  else if (riscv_lookup_subset (rps->subset_list, "d", &subset))
-    {
-      riscv_parse_add_subset (rps, "f",
-			      RISCV_UNKNOWN_VERSION,
-			      RISCV_UNKNOWN_VERSION, true);
-      riscv_parse_add_subset (rps, "zicsr",
-			      RISCV_UNKNOWN_VERSION,
-			      RISCV_UNKNOWN_VERSION, true);
-    }
-  else if (riscv_lookup_subset (rps->subset_list, "f", &subset))
-    riscv_parse_add_subset (rps, "zicsr",
-			    RISCV_UNKNOWN_VERSION,
-			    RISCV_UNKNOWN_VERSION, true);
-
-  if (riscv_lookup_subset (rps->subset_list, "g", &subset))
-    {
-      riscv_parse_add_subset (rps, "zicsr",
-			      RISCV_UNKNOWN_VERSION,
-			      RISCV_UNKNOWN_VERSION, true);
-      riscv_parse_add_subset (rps, "zifencei",
-			      RISCV_UNKNOWN_VERSION,
-			      RISCV_UNKNOWN_VERSION, true);
+      riscv_subset_t *subset = NULL;
+      if (riscv_lookup_subset (rps->subset_list, t->subset_name, &subset)
+	  && t->check_func (t->implicit_name, subset))
+	riscv_parse_add_subset (rps, t->implicit_name,
+				RISCV_UNKNOWN_VERSION,
+				RISCV_UNKNOWN_VERSION, true);
     }
 }
 
-- 
2.7.4



More information about the Binutils mailing list