diff options
author | Nelson Chu <nelson.chu@sifive.com> | 2021-05-13 11:48:26 +0800 |
---|---|---|
committer | Nelson Chu <nelson.chu@sifive.com> | 2021-05-13 15:21:38 +0800 |
commit | 7671eff8f08de314d8c9837225eba95ed5ea053b (patch) | |
tree | 4bfdac07f53e9d347866344421f5a85c2e7d8e6e /bfd/elfxx-riscv.c | |
parent | cf893b0ef7482ec11df3787772f35e820ef2592a (diff) | |
download | gdb-7671eff8f08de314d8c9837225eba95ed5ea053b.zip gdb-7671eff8f08de314d8c9837225eba95ed5ea053b.tar.gz gdb-7671eff8f08de314d8c9837225eba95ed5ea053b.tar.bz2 |
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.
Diffstat (limited to 'bfd/elfxx-riscv.c')
-rw-r--r-- | bfd/elfxx-riscv.c | 103 |
1 files changed, 49 insertions, 54 deletions
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); } } |