From 2beec86ea1c51d5a06f05ae78cc7271b36302405 Mon Sep 17 00:00:00 2001 From: Tsukasa OI Date: Wed, 26 Jul 2023 00:29:47 +0000 Subject: [PATCH] RISC-V: Base for complex extension implications Thanks to the commit 48558a5e5471 ("RISC-V: Allow nested implications for extensions"), we can write complex extension implications in theory. However, to actually do that, we need to pass more information to check_func. For example, we want to imply 'Zcf' from 'F' if and only if the 'Zce' extension is also enabled and XLEN is 32. Passing rps is a way to enable this. This commit prepares for such complex extension implications. bfd/ChangeLog: * elfxx-riscv.c (struct riscv_implicit_subset) Move around and change check_func function prototype. (check_implicit_always): New arguments. (check_implicit_for_i): Likewise. (riscv_implicit_subsets): Add comment for this variable. (riscv_parse_add_implicit_subsets): Call check_func with new arguments. --- bfd/elfxx-riscv.c | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c index 9cc0c7b1c10..3c477481e50 100644 --- a/bfd/elfxx-riscv.c +++ b/bfd/elfxx-riscv.c @@ -1064,11 +1064,25 @@ riscv_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED, return bfd_reloc_ok; } +/* Record all implicit information for the subsets. */ + +typedef 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) (riscv_parse_subset_t *, + const struct riscv_implicit_subset *, + const riscv_subset_t *); +} riscv_implicit_subset_t; + /* Always add the IMPLICIT for the SUBSET. */ static bool -check_implicit_always (const char *implicit ATTRIBUTE_UNUSED, - riscv_subset_t *subset ATTRIBUTE_UNUSED) +check_implicit_always (riscv_parse_subset_t *rps ATTRIBUTE_UNUSED, + const riscv_implicit_subset_t *implicit + ATTRIBUTE_UNUSED, + const riscv_subset_t *subset ATTRIBUTE_UNUSED) { return true; } @@ -1076,23 +1090,18 @@ check_implicit_always (const char *implicit ATTRIBUTE_UNUSED, /* 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) +check_implicit_for_i (riscv_parse_subset_t *rps ATTRIBUTE_UNUSED, + const riscv_implicit_subset_t *implicit ATTRIBUTE_UNUSED, + const 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[] = +/* All extension implications. */ + +static riscv_implicit_subset_t riscv_implicit_subsets[] = { {"e", "i", check_implicit_always}, {"i", "zicsr", check_implicit_for_i}, @@ -1905,7 +1914,7 @@ riscv_parse_extensions (riscv_parse_subset_t *rps, static void riscv_parse_add_implicit_subsets (riscv_parse_subset_t *rps) { - struct riscv_implicit_subset *t = riscv_implicit_subsets; + riscv_implicit_subset_t *t = riscv_implicit_subsets; bool finished = false; while (!finished) { @@ -1917,7 +1926,7 @@ riscv_parse_add_implicit_subsets (riscv_parse_subset_t *rps) 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)) + && t->check_func (rps, t, subset)) { riscv_parse_add_subset (rps, t->implicit_name, RISCV_UNKNOWN_VERSION,