diff options
author | Nelson Chu <nelson.chu@sifive.com> | 2021-11-19 17:11:06 +0800 |
---|---|---|
committer | Nelson Chu <nelson.chu@sifive.com> | 2021-11-19 18:50:27 +0800 |
commit | d3ffd7f77654adafe5f1989bdfdbe4a337ff2e8b (patch) | |
tree | 4175e17a9569dcc539f92e32ed3ec098328217ee /gas/config | |
parent | fd0ff19bf435b267caae6a1ae04e7b4a4ba64f5b (diff) | |
download | gdb-d3ffd7f77654adafe5f1989bdfdbe4a337ff2e8b.zip gdb-d3ffd7f77654adafe5f1989bdfdbe4a337ff2e8b.tar.gz gdb-d3ffd7f77654adafe5f1989bdfdbe4a337ff2e8b.tar.bz2 |
RISC-V: Support new .option arch directive.
https://github.com/riscv/riscv-asm-manual/pull/67
Format:
.option arch, +<extension><version>, ...
.option arch, -<extension>
.option arch, =<ISA string>
The new direcitve is used to enable/disable extensions for the specific
code region. For example,
.attribute arch, "rv64ic" # arch = rv64i2p0_c2p0
.option push
.option arch, +d2p0, -c # arch = rv64i2p0_f2p0_d2p0, f is added implied
.option arch, =rv32gc # arch = rv32i2p0_m2p0_a2p0_f2p0_d2p0_c2p0
.option pop # arch = rv64i2p0_c2p0
Note that,
1. ".option rvc/norvc" have the same behavior as ".option arch +c/-c".
2. ".option arch -i" is illegal, since we cannot remove base i extension.
3. If arch=rv64i2p0, then ".option arch, +i3p0" will update the i's version
from 2.0 to 3.0.
4. If arch=rv64i3p0, then ".option arch, +i" will update the i's version
from 2.0 to the default one according to the chosen isa spec.
bfd/
* elfxx-riscv.c (riscv_add_subset): If the subset is already added,
and the new versions are not RISCV_UNKNOWN_VERSION, then update the
versions to the subset list.
(riscv_copy_subset): New function. Copy the subset from list.
(riscv_copy_subset_list): New function. Return the new copyed list.
(riscv_update_subset): Updated to make .option arch directives workable.
* elfxx-riscv.h: Updated.
gas/
* config/tc-riscv.c (riscv_subsets): Defined as a pointer.
(riscv_rps_as): Init the subset_list to NULL, we will set it later
once riscv_opts_stack is created or updated.
(struct riscv_option_stack, riscv_opts_stack): Moved forward.
(riscv_set_arch): Updated.
(s_riscv_option): Support new .option arch directive, to add, remove
or update subsets for the specific code region.
(riscv_write_out_attrs): Updated.
* doc/c-riscv.texi: Added document for new .option arch directive.
* testsuite/gas/riscv/option-arch-01a.d: New testcase.
* testsuite/gas/riscv/option-arch-01b.d: Likewise.
* testsuite/gas/riscv/option-arch-01.s: Likewise..
* testsuite/gas/riscv/option-arch-02.d: Likewise.
* testsuite/gas/riscv/option-arch-02.s: Likewise.
* testsuite/gas/riscv/option-arch-fail.d: Likewise.
* testsuite/gas/riscv/option-arch-fail.l: Likewise.
* testsuite/gas/riscv/option-arch-fail.s: Likewise.
Diffstat (limited to 'gas/config')
-rw-r--r-- | gas/config/tc-riscv.c | 57 |
1 files changed, 40 insertions, 17 deletions
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c index 930cfb2..da3d911 100644 --- a/gas/config/tc-riscv.c +++ b/gas/config/tc-riscv.c @@ -235,16 +235,27 @@ riscv_set_rvc (bool rvc_value) the architecture string. The architecture string can be set by the -march option, the elf architecture attributes, and the --with-arch configure option. */ -static riscv_subset_list_t riscv_subsets; +static riscv_subset_list_t *riscv_subsets = NULL; static riscv_parse_subset_t riscv_rps_as = { - &riscv_subsets, /* subset_list. */ + NULL, /* subset_list, we will set it later once + riscv_opts_stack is created or updated. */ as_bad, /* error_handler. */ &xlen, /* xlen. */ &default_isa_spec, /* isa_spec. */ true, /* check_unknown_prefixed_ext. */ }; +/* This structure is used to hold a stack of .option values. */ +struct riscv_option_stack +{ + struct riscv_option_stack *next; + struct riscv_set_options options; + riscv_subset_list_t *subset_list; +}; + +static struct riscv_option_stack *riscv_opts_stack = NULL; + /* Set which ISA and extensions are available. */ static void @@ -257,7 +268,14 @@ riscv_set_arch (const char *s) return; } - riscv_release_subset_list (&riscv_subsets); + if (riscv_subsets == NULL) + { + riscv_subsets = XNEW (riscv_subset_list_t); + riscv_subsets->head = NULL; + riscv_subsets->tail = NULL; + riscv_rps_as.subset_list = riscv_subsets; + } + riscv_release_subset_list (riscv_subsets); riscv_parse_subset (&riscv_rps_as, s); riscv_set_rvc (false); @@ -3715,15 +3733,6 @@ riscv_pre_output_hook (void) subseg_set (seg, subseg); } -/* This structure is used to hold a stack of .option values. */ -struct riscv_option_stack -{ - struct riscv_option_stack *next; - struct riscv_set_options options; -}; - -static struct riscv_option_stack *riscv_opts_stack; - /* Handle the .option pseudo-op. */ static void @@ -3738,12 +3747,12 @@ s_riscv_option (int x ATTRIBUTE_UNUSED) if (strcmp (name, "rvc") == 0) { - riscv_update_subset (&riscv_rps_as, "c", false); + riscv_update_subset (&riscv_rps_as, "+c"); riscv_set_rvc (true); } else if (strcmp (name, "norvc") == 0) { - riscv_update_subset (&riscv_rps_as, "c", true); + riscv_update_subset (&riscv_rps_as, "-c"); riscv_set_rvc (false); } else if (strcmp (name, "pic") == 0) @@ -3758,14 +3767,24 @@ s_riscv_option (int x ATTRIBUTE_UNUSED) riscv_opts.csr_check = true; else if (strcmp (name, "no-csr-check") == 0) riscv_opts.csr_check = false; + else if (strncmp (name, "arch,", 5) == 0) + { + name += 5; + if (ISSPACE (*name) && *name != '\0') + name++; + riscv_update_subset (&riscv_rps_as, name); + } else if (strcmp (name, "push") == 0) { struct riscv_option_stack *s; - s = (struct riscv_option_stack *) xmalloc (sizeof *s); + s = XNEW (struct riscv_option_stack); s->next = riscv_opts_stack; s->options = riscv_opts; + s->subset_list = riscv_subsets; riscv_opts_stack = s; + riscv_subsets = riscv_copy_subset_list (s->subset_list); + riscv_rps_as.subset_list = riscv_subsets; } else if (strcmp (name, "pop") == 0) { @@ -3776,8 +3795,12 @@ s_riscv_option (int x ATTRIBUTE_UNUSED) as_bad (_(".option pop with no .option push")); else { - riscv_opts = s->options; + riscv_subset_list_t *release_subsets = riscv_subsets; riscv_opts_stack = s->next; + riscv_opts = s->options; + riscv_subsets = s->subset_list; + riscv_rps_as.subset_list = riscv_subsets; + riscv_release_subset_list (release_subsets); free (s); } } @@ -4262,7 +4285,7 @@ riscv_write_out_attrs (void) unsigned int i; /* Re-write architecture elf attribute. */ - arch_str = riscv_arch_str (xlen, &riscv_subsets); + arch_str = riscv_arch_str (xlen, riscv_subsets); bfd_elf_add_proc_attr_string (stdoutput, Tag_RISCV_arch, arch_str); xfree ((void *) arch_str); |