From 7671eff8f08de314d8c9837225eba95ed5ea053b Mon Sep 17 00:00:00 2001 From: Nelson Chu Date: Thu, 13 May 2021 11:48:26 +0800 Subject: [PATCH] RISC-V: Record implicit subsets in a table, to avoid repeated codes. 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 fcb692bdb35..8dbe40c474d 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,15 @@ +2021-05-13 Nelson Chu + + * 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 PR 27858 diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c index 3b381925758..7206ec8573b 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.30.2