[v6,09/15] RISC-V: Allow nested implications for extensions

Message ID 20230701052104.4018352-10-christoph.muellner@vrull.eu
State Accepted
Headers
Series RISC-V: Add support for vector crypto extensions |

Checks

Context Check Description
snail/binutils-gdb-check success Github commit url

Commit Message

Christoph Müllner July 1, 2023, 5:20 a.m. UTC
  From: Nathan Huckleberry via Binutils <binutils@sourceware.org>

Certain extensions require two levels of implications.  For example,
zvkng implies zvkn and zvkn implies zvkned.  Enabling zvkng should also
enable zvkned.

This patch fixes this behavior.

bfd/ChangeLog:

	* elfxx-riscv.c (riscv_parse_add_implicit_subsets): Allow nested
	implications for extensions.

Signed-off-by: Nathan Huckleberry <nhuck@google.com>
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
---
 bfd/elfxx-riscv.c | 29 ++++++++++++++++++++++-------
 1 file changed, 22 insertions(+), 7 deletions(-)
  

Patch

diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 426139d4960..f7fb7d88d76 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1873,14 +1873,29 @@  static void
 riscv_parse_add_implicit_subsets (riscv_parse_subset_t *rps)
 {
   struct riscv_implicit_subset *t = riscv_implicit_subsets;
-  for (; t->subset_name; t++)
+  bool finished = false;
+  while (!finished)
     {
-      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);
+      finished = true;
+      for (; t->subset_name; t++)
+	{
+	  riscv_subset_t *subset = NULL;
+	  riscv_subset_t *implicit_subset = NULL;
+	  if (riscv_lookup_subset (rps->subset_list, t->subset_name, &subset)
+	      && !riscv_lookup_subset (rps->subset_list, t->implicit_name,
+				       &implicit_subset)
+	      && t->check_func (t->implicit_name, subset))
+	    {
+	      riscv_parse_add_subset (rps, t->implicit_name,
+				      RISCV_UNKNOWN_VERSION,
+				      RISCV_UNKNOWN_VERSION, true);
+
+	      /* Restart the loop and pick up any new implications.  */
+	      finished = false;
+	      t = riscv_implicit_subsets;
+	      break;
+	    }
+	}
     }
 }