[committed] RISC-V: Minor updates for architecture parser.

Message ID 20210720100654.28472-1-nelson.chu@sifive.com
State New
Headers show
Series
  • [committed] RISC-V: Minor updates for architecture parser.
Related show

Commit Message

Nelson Chu July 20, 2021, 10:06 a.m.
* Two add subset functions is redundant.  Keep the riscv_add_implicit_subset,
and renamed it to riscv_add_subset.  Besides, if the subset is added in order,
then we just add it at the tail of the subset list.

* Removed the "-march:" prefix from the error messages.  Since not only the
-march= option will use the parser, but also the architecture elf attributes,
the default architecture setting and linker will use the same parser.

* Use a function, riscv_parse_check_conflicts, to check the conflicts
of extensions, including the rv64e and rv32q.

The rv32emc-elf/rv32i-elf/rv32gc-linux/rv64gc-elf/rv64gc-linux regressions
are tested and passed.

bfd/
	* elfxx-riscv.c (riscv_lookup_subset): Check the subset tail list
	first.  If the subset is added in order, then we can just add it to
	the tail without searching the whole list.
	(riscv_add_subset): Replaced by riscv_add_implicit_subset.
	(riscv_add_implicit_subset): Renamed to riscv_add_subset.
	(riscv_parse_add_subset): Updated.
	(riscv_parsing_subset_version): Removed the "-march:" prefix from
	the error message.
	(riscv_parse_prefixed_ext): Likewise.
	(riscv_parse_std_ext): Likewise.  And move the rv<xlen>e check
	to riscv_parse_check_conflicts.
	(riscv_parse_check_conflicts): New function used to check conflicts.
	(riscv_parse_subset): Updated.
gas/
	* testsuite/gas/riscv/march-fail-base-02.l: Updated.
	* testsuite/gas/riscv/march-fail-unknown-std.l: Likewise.
---
 bfd/elfxx-riscv.c                             | 176 ++++++++----------
 gas/testsuite/gas/riscv/march-fail-base-02.l  |   2 +-
 .../gas/riscv/march-fail-unknown-std.l        |   2 +-
 3 files changed, 84 insertions(+), 96 deletions(-)

-- 
2.30.2

Patch

diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 39b69e2b0a5..2b8f60caf32 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1277,6 +1277,14 @@  riscv_lookup_subset (const riscv_subset_list_t *subset_list,
 {
   riscv_subset_t *s, *pre_s = NULL;
 
+  /* If the subset is added in order, then just add it at the tail.  */
+  if (subset_list->tail != NULL
+      && riscv_compare_subsets (subset_list->tail->name, subset) < 0)
+    {
+      *current = subset_list->tail;
+      return false;
+    }
+
   for (s = subset_list->head;
        s != NULL;
        pre_s = s, s = s->next)
@@ -1291,40 +1299,18 @@  riscv_lookup_subset (const riscv_subset_list_t *subset_list,
 	break;
     }
   *current = pre_s;
+
   return false;
 }
 
-/* Add extension from ISA string to the last of the subset list.  */
+/* Add the extension to the subset list.  Search the
+   list first, and then find the right place to add.  */
 
 void
 riscv_add_subset (riscv_subset_list_t *subset_list,
 		  const char *subset,
 		  int major,
 		  int minor)
-{
-  riscv_subset_t *s = xmalloc (sizeof *s);
-
-  if (subset_list->head == NULL)
-    subset_list->head = s;
-
-  s->name = xstrdup (subset);
-  s->major_version = major;
-  s->minor_version = minor;
-  s->next = NULL;
-
-  if (subset_list->tail != NULL)
-    subset_list->tail->next = s;
-  subset_list->tail = s;
-}
-
-/* Add the implicit extension to the subset list.  Search the
-   list first, and then find the right place to add.  */
-
-static void
-riscv_add_implicit_subset (riscv_subset_list_t *subset_list,
-			   const char *subset,
-			   int major,
-			   int minor)
 {
   riscv_subset_t *current, *new;
 
@@ -1347,14 +1333,12 @@  riscv_add_implicit_subset (riscv_subset_list_t *subset_list,
       new->next = subset_list->head;
       subset_list->head = new;
     }
-}
 
-/* We have to add all extensions from ISA string first, and then start to
-   add their implicit extensions.  The extensions from ISA string must be
-   set in order, so we can add them to the last of the subset list
-   directly, without searching.
+  if (new->next == NULL)
+    subset_list->tail = new;
+}
 
-   Find the default versions for the extension before adding them to
+/* 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.  */
 
@@ -1389,12 +1373,8 @@  riscv_parse_add_subset (riscv_parse_subset_t *rps,
       return;
     }
 
-  if (!implicit)
-    riscv_add_subset (rps->subset_list, subset,
-		      major_version, minor_version);
-  else
-    riscv_add_implicit_subset (rps->subset_list, subset,
-			       major_version, minor_version);
+  riscv_add_subset (rps->subset_list, subset,
+		    major_version, minor_version);
 }
 
 /* Release subset list.  */
@@ -1420,7 +1400,7 @@  riscv_release_subset_list (riscv_subset_list_t *subset_list)
 
    Arguments:
      `rps`: Hooks and status for parsing extensions.
-     `march`: Full ISA string.
+     `arch`: Full ISA string.
      `p`: Curent parsing position.
      `major_version`: Parsed major version.
      `minor_version`: Parsed minor version.
@@ -1428,7 +1408,7 @@  riscv_release_subset_list (riscv_subset_list_t *subset_list)
 
 static const char *
 riscv_parsing_subset_version (riscv_parse_subset_t *rps,
-			      const char *march,
+			      const char *arch,
 			      const char *p,
 			      int *major_version,
 			      int *minor_version,
@@ -1458,8 +1438,8 @@  riscv_parsing_subset_version (riscv_parse_subset_t *rps,
 	      else
 		{
 		  rps->error_handler
-		    (_("-march=%s: expect number after `%dp'"),
-		     march, version);
+		    (_("%s: expect number after `%dp'"),
+		     arch, version);
 		  return NULL;
 		}
 	    }
@@ -1505,12 +1485,12 @@  riscv_supported_std_ext (void)
 
    Arguments:
      `rps`: Hooks and status for parsing extensions.
-     `march`: Full ISA string.
+     `arch`: Full ISA string.
      `p`: Curent parsing position.  */
 
 static const char *
 riscv_parse_std_ext (riscv_parse_subset_t *rps,
-		     const char *march,
+		     const char *arch,
 		     const char *p)
 {
   const char *all_std_exts = riscv_supported_std_ext ();
@@ -1523,7 +1503,7 @@  riscv_parse_std_ext (riscv_parse_subset_t *rps,
   switch (*p)
     {
       case 'i':
-	p = riscv_parsing_subset_version (rps, march, ++p,
+	p = riscv_parsing_subset_version (rps, arch, ++p,
 					  &major_version,
 					  &minor_version, true);
 	riscv_parse_add_subset (rps, "i",
@@ -1532,23 +1512,16 @@  riscv_parse_std_ext (riscv_parse_subset_t *rps,
 	break;
 
       case 'e':
-	p = riscv_parsing_subset_version (rps, march, ++p,
+	p = riscv_parsing_subset_version (rps, arch, ++p,
 					  &major_version,
 					  &minor_version, true);
 	riscv_parse_add_subset (rps, "e",
 				major_version,
 				minor_version, false);
-	if (*rps->xlen > 32)
-	  {
-	    rps->error_handler
-	      (_("-march=%s: rv%de is not a valid base ISA"),
-	       march, *rps->xlen);
-	    return NULL;
-	  }
 	break;
 
       case 'g':
-	p = riscv_parsing_subset_version (rps, march, ++p,
+	p = riscv_parsing_subset_version (rps, arch, ++p,
 					  &major_version,
 					  &minor_version, true);
 	/* Expand g to imafd.  */
@@ -1570,8 +1543,8 @@  riscv_parse_std_ext (riscv_parse_subset_t *rps,
 
       default:
 	rps->error_handler
-	  (_("-march=%s: first ISA extension must be `e', `i' or `g'"),
-	   march);
+	  (_("%s: first ISA extension must be `e', `i' or `g'"),
+	   arch);
 	return NULL;
     }
 
@@ -1597,18 +1570,18 @@  riscv_parse_std_ext (riscv_parse_subset_t *rps,
 	{
 	  if (riscv_ext_order[(std_ext - 'a')] == 0)
 	    rps->error_handler
-	      (_("-march=%s: unknown standard and prefixed ISA "
-		 "extension `%s'"), march, p);
+	      (_("%s: unknown standard ISA extension `%c'"),
+	       arch, std_ext);
 	  else
 	    rps->error_handler
-	      (_("-march=%s: standard ISA extension `%c' is not "
-		 "in canonical order"), march, std_ext);
+	      (_("%s: standard ISA extension `%c' is not "
+		 "in canonical order"), arch, std_ext);
 	  return NULL;
 	}
 
       std_exts++;
       subset[0] = std_ext;
-      p = riscv_parsing_subset_version (rps, march, ++p,
+      p = riscv_parsing_subset_version (rps, arch, ++p,
 					&major_version,
 					&minor_version, true);
       riscv_parse_add_subset (rps, subset,
@@ -1626,12 +1599,12 @@  riscv_parse_std_ext (riscv_parse_subset_t *rps,
 
    Arguments:
      `rps`: Hooks and status for parsing extensions.
-     `march`: Full ISA string.
+     `arch`: Full ISA string.
      `p`: Curent parsing position.  */
 
 static const char *
 riscv_parse_prefixed_ext (riscv_parse_subset_t *rps,
-			  const char *march,
+			  const char *arch,
 			  const char *p)
 {
   int major_version;
@@ -1651,8 +1624,8 @@  riscv_parse_prefixed_ext (riscv_parse_subset_t *rps,
       if (class == RV_ISA_CLASS_UNKNOWN)
 	{
 	  rps->error_handler
-	    (_("-march=%s: unknown prefix class for the ISA extension `%s'"),
-	     march, p);
+	    (_("%s: unknown prefix class for the ISA extension `%s'"),
+	     arch, p);
 	  return NULL;
 	}
 
@@ -1664,7 +1637,7 @@  riscv_parse_prefixed_ext (riscv_parse_subset_t *rps,
 	;
 
       end_of_version =
-	riscv_parsing_subset_version (rps, march, q,
+	riscv_parsing_subset_version (rps, arch, q,
 				      &major_version,
 				      &minor_version, false);
       *q = '\0';
@@ -1685,8 +1658,8 @@  riscv_parse_prefixed_ext (riscv_parse_subset_t *rps,
 	  && !riscv_valid_prefixed_ext (subset))
 	{
 	  rps->error_handler
-	    (_("-march=%s: unknown prefixed ISA extension `%s'"),
-	     march, subset);
+	    (_("%s: unknown prefixed ISA extension `%s'"),
+	     arch, subset);
 	  free (subset);
 	  return NULL;
 	}
@@ -1696,8 +1669,8 @@  riscv_parse_prefixed_ext (riscv_parse_subset_t *rps,
       if (!strcasecmp (last_name, subset))
 	{
 	  rps->error_handler
-	    (_("-march=%s: duplicate prefixed ISA extension `%s'"),
-	     march, subset);
+	    (_("%s: duplicate prefixed ISA extension `%s'"),
+	     arch, subset);
 	  free (subset);
 	  return NULL;
 	}
@@ -1706,9 +1679,9 @@  riscv_parse_prefixed_ext (riscv_parse_subset_t *rps,
       if (riscv_compare_subsets (last_name, subset) > 0)
 	{
 	  rps->error_handler
-	    (_("-march=%s: prefixed ISA extension `%s' is not in expected "
+	    (_("%s: prefixed ISA extension `%s' is not in expected "
 	       "order.  It must come before `%s'"),
-	     march, subset, last_name);
+	     arch, subset, last_name);
 	  free (subset);
 	  return NULL;
 	}
@@ -1722,8 +1695,8 @@  riscv_parse_prefixed_ext (riscv_parse_subset_t *rps,
       if (*p != '\0' && *p != '_')
 	{
 	  rps->error_handler
-	    (_("-march=%s: prefixed ISA extension must separate with _"),
-	     march);
+	    (_("%s: prefixed ISA extension must separate with _"),
+	     arch);
 	  return NULL;
 	}
     }
@@ -1748,6 +1721,39 @@  riscv_parse_add_implicit_subsets (riscv_parse_subset_t *rps)
     }
 }
 
+/* Check extensions conflicts.  */
+
+static bool
+riscv_parse_check_conflicts (riscv_parse_subset_t *rps)
+{
+  riscv_subset_t *subset = NULL;
+  int xlen = *rps->xlen;
+  bool no_conflict = true;
+
+  if (riscv_lookup_subset (rps->subset_list, "e", &subset)
+      && xlen > 32)
+    {
+      rps->error_handler
+	(_("rv%d does not support the `e' extension"), xlen);
+      no_conflict = false;
+    }
+  if (riscv_lookup_subset (rps->subset_list, "q", &subset)
+      && xlen < 64)
+    {
+      rps->error_handler
+        (_("rv%d does not support the `q' extension"), xlen);
+      no_conflict = false;
+    }
+  if (riscv_lookup_subset (rps->subset_list, "e", &subset)
+      && riscv_lookup_subset (rps->subset_list, "f", &subset))
+    {
+      rps->error_handler
+        (_("rv32e does not support the `f' extension"));
+      no_conflict = false;
+    }
+  return no_conflict;
+}
+
 /* Function for parsing ISA string.
 
    Return Value:
@@ -1761,16 +1767,14 @@  bool
 riscv_parse_subset (riscv_parse_subset_t *rps,
 		    const char *arch)
 {
-  riscv_subset_t *subset = NULL;
   const char *p;
-  bool no_conflict = true;
 
   for (p = arch; *p != '\0'; p++)
     {
       if (ISUPPER (*p))
 	{
 	  rps->error_handler
-	    (_("-march=%s: ISA string cannot contain uppercase letters"),
+	    (_("%s: ISA string cannot contain uppercase letters"),
 	     arch);
 	  return false;
 	}
@@ -1796,7 +1800,7 @@  riscv_parse_subset (riscv_parse_subset_t *rps,
 	 not issue this error when the ISA string is empty.  */
       if (strlen (arch))
 	rps->error_handler (
-	  _("-march=%s: ISA string must begin with rv32 or rv64"),
+	  _("%s: ISA string must begin with rv32 or rv64"),
 	  arch);
       return false;
     }
@@ -1825,23 +1829,7 @@  riscv_parse_subset (riscv_parse_subset_t *rps,
   riscv_parse_add_implicit_subsets (rps);
 
   /* Check the conflicts.  */
-  if (riscv_lookup_subset (rps->subset_list, "e", &subset)
-      && riscv_lookup_subset (rps->subset_list, "f", &subset))
-    {
-      rps->error_handler
-	(_("-march=%s: rv32e does not support the `f' extension"),
-	 arch);
-      no_conflict = false;
-    }
-  if (riscv_lookup_subset (rps->subset_list, "q", &subset)
-      && *rps->xlen < 64)
-    {
-      rps->error_handler
-	(_("-march=%s: rv32 does not support the `q' extension"),
-	 arch);
-      no_conflict = false;
-    }
-  return no_conflict;
+  return riscv_parse_check_conflicts (rps);
 }
 
 /* Return the number of digits for the input.  */
diff --git a/gas/testsuite/gas/riscv/march-fail-base-02.l b/gas/testsuite/gas/riscv/march-fail-base-02.l
index f6a3c1dc51c..52fee96af36 100644
--- a/gas/testsuite/gas/riscv/march-fail-base-02.l
+++ b/gas/testsuite/gas/riscv/march-fail-base-02.l
@@ -1,2 +1,2 @@ 
 .*Assembler messages:
-.*Error: .*rv64e is not a valid base ISA
+.*Error: rv64 does not support the `e' extension
diff --git a/gas/testsuite/gas/riscv/march-fail-unknown-std.l b/gas/testsuite/gas/riscv/march-fail-unknown-std.l
index 0e9add79056..834a4857c58 100644
--- a/gas/testsuite/gas/riscv/march-fail-unknown-std.l
+++ b/gas/testsuite/gas/riscv/march-fail-unknown-std.l
@@ -1,2 +1,2 @@ 
 .*Assembler messages:
-.*Error: .*unknown standard and prefixed ISA extension `y'
+.*Error: .*unknown standard ISA extension `y'