summaryrefslogtreecommitdiff
path: root/bfd/elfxx-riscv.c
diff options
context:
space:
mode:
authorNelson Chu <nelson.chu@sifive.com>2021-05-13 11:48:26 +0800
committerNelson Chu <nelson.chu@sifive.com>2021-05-13 15:21:38 +0800
commit7671eff8f08de314d8c9837225eba95ed5ea053b (patch)
tree4bfdac07f53e9d347866344421f5a85c2e7d8e6e /bfd/elfxx-riscv.c
parentcf893b0ef7482ec11df3787772f35e820ef2592a (diff)
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.c103
1 files changed, 49 insertions, 54 deletions
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 3b38192575..7206ec8573 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);
}
}