diff options
author | Nelson Chu <nelson.chu@sifive.com> | 2021-11-04 14:31:48 +0800 |
---|---|---|
committer | Nelson Chu <nelson.chu@sifive.com> | 2021-11-04 17:46:09 +0800 |
commit | edc77c591add0a9c7740a9ed9f7e40358bf65dbf (patch) | |
tree | c2775cd5aa98985296420ce901ffc6df91f2e7e1 /bfd | |
parent | e5c9e53c9b8d5c8519b251f91de7bc453d1086be (diff) | |
download | gdb-edc77c591add0a9c7740a9ed9f7e40358bf65dbf.zip gdb-edc77c591add0a9c7740a9ed9f7e40358bf65dbf.tar.gz gdb-edc77c591add0a9c7740a9ed9f7e40358bf65dbf.tar.bz2 |
RISC-V: Clarify the behavior of .option rvc or norvc.
Add/Remove the rvc extension to/from the riscv_subsets once the
.option rvc/norvc is set. So that we don't need to always check
the riscv_opts.rvc in the riscv_subset_supports, just call the
riscv_lookup_subset to search the subset list is enough.
Besides, we will need to dump the instructions according to the
elf architecture attributes. That means the dis-assembler needs
to parse the architecture string from the elf attribute before
dumping any instructions, and also needs to recognized the
INSN_CLASS* classes from riscv_opcodes. Therefore, I suppose
some functions will need to be moved from gas/config/tc-riscv.c
to bfd/elfxx-riscv.c, including riscv_multi_subset_supports and
riscv_subset_supports. This is one of the reasons why we need
this patch.
This patch passes the gcc/binutils regressions of rv32emc-elf,
rv32i-elf, rv64gc-elf and rv64gc-linux toolchains.
bfd/
* elfxx-riscv.c (riscv_remove_subset): Remove the extension
from the subset list.
(riscv_update_subset): Add/Remove an extension to/from the
subset list. This is used for the .option rvc or norvc.
* elfxx-riscv.h: Added the extern bool riscv_update_subset.
gas/
* config/tc-riscv.c (riscv_set_options): Removed the unused
rve flag.
(riscv_opts): Likewise.
(riscv_set_rve): Removed.
(riscv_subset_supports): Removed the riscv_opts.rvc check.
(riscv_set_arch): Don't need to call riscv_set_rve.
(reg_lookup_internal): Call riscv_subset_supports to check
whether the rve is supported.
(s_riscv_option): Add/Remove the rvc extension to/from the
subset list once the .option rvc/norvc is set.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/elfxx-riscv.c | 65 | ||||
-rw-r--r-- | bfd/elfxx-riscv.h | 3 |
2 files changed, 68 insertions, 0 deletions
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c index cdb4fa0..65bb1ca 100644 --- a/bfd/elfxx-riscv.c +++ b/bfd/elfxx-riscv.c @@ -2030,3 +2030,68 @@ riscv_arch_str (unsigned xlen, const riscv_subset_list_t *subset) return attr_str; } + +/* Remove the SUBSET from the subset list. */ + +static void +riscv_remove_subset (riscv_subset_list_t *subset_list, + const char *subset) +{ + riscv_subset_t *current = subset_list->head; + riscv_subset_t *pre = NULL; + for (; current != NULL; pre = current, current = current->next) + { + if (strcmp (current->name, subset) == 0) + { + if (pre == NULL) + subset_list->head = current->next; + else + pre->next = current->next; + if (current->next == NULL) + subset_list->tail = pre; + free ((void *) current->name); + free (current); + break; + } + } +} + +/* Add/Remove an extension to/from the subset list. This is used for + the .option rvc or norvc. */ + +bool +riscv_update_subset (riscv_parse_subset_t *rps, + const char *subset, + bool removed) +{ + if (strlen (subset) == 0 + || (strlen (subset) == 1 + && riscv_ext_order[(*subset - 'a')] == 0) + || (strlen (subset) > 1 + && rps->check_unknown_prefixed_ext + && !riscv_recognized_prefixed_ext (subset))) + { + rps->error_handler + (_("riscv_update_subset: unknown ISA extension `%s'"), subset); + return false; + } + + if (removed) + { + if (strcmp (subset, "i") == 0) + { + rps->error_handler + (_("riscv_update_subset: cannot remove extension i from " + "the subset list")); + return false; + } + riscv_remove_subset (rps->subset_list, subset); + } + else + riscv_parse_add_subset (rps, subset, + RISCV_UNKNOWN_VERSION, + RISCV_UNKNOWN_VERSION, true); + + riscv_parse_add_implicit_subsets (rps); + return riscv_parse_check_conflicts (rps); +} diff --git a/bfd/elfxx-riscv.h b/bfd/elfxx-riscv.h index 3af8fd9..17620fd 100644 --- a/bfd/elfxx-riscv.h +++ b/bfd/elfxx-riscv.h @@ -92,6 +92,9 @@ riscv_estimate_digit (unsigned); extern int riscv_compare_subsets (const char *, const char *); +extern bool +riscv_update_subset (riscv_parse_subset_t *, const char *, bool); + extern void bfd_elf32_riscv_set_data_segment_info (struct bfd_link_info *, int *); extern void |