aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorNelson Chu <nelson.chu@sifive.com>2021-11-19 17:11:06 +0800
committerNelson Chu <nelson.chu@sifive.com>2021-11-19 18:50:27 +0800
commitd3ffd7f77654adafe5f1989bdfdbe4a337ff2e8b (patch)
tree4175e17a9569dcc539f92e32ed3ec098328217ee /gas
parentfd0ff19bf435b267caae6a1ae04e7b4a4ba64f5b (diff)
downloadgdb-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')
-rw-r--r--gas/config/tc-riscv.c57
-rw-r--r--gas/doc/c-riscv.texi15
-rw-r--r--gas/testsuite/gas/riscv/option-arch-01.s10
-rw-r--r--gas/testsuite/gas/riscv/option-arch-01a.d14
-rw-r--r--gas/testsuite/gas/riscv/option-arch-01b.d8
-rw-r--r--gas/testsuite/gas/riscv/option-arch-02.d8
-rw-r--r--gas/testsuite/gas/riscv/option-arch-02.s8
-rw-r--r--gas/testsuite/gas/riscv/option-arch-03.d8
-rw-r--r--gas/testsuite/gas/riscv/option-arch-03.s3
-rw-r--r--gas/testsuite/gas/riscv/option-arch-fail.d3
-rw-r--r--gas/testsuite/gas/riscv/option-arch-fail.l8
-rw-r--r--gas/testsuite/gas/riscv/option-arch-fail.s10
12 files changed, 134 insertions, 18 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);
diff --git a/gas/doc/c-riscv.texi b/gas/doc/c-riscv.texi
index bfbf61d..697be3a 100644
--- a/gas/doc/c-riscv.texi
+++ b/gas/doc/c-riscv.texi
@@ -194,7 +194,7 @@ command-line options are respected for the bulk of the file being assembled.
@itemx norvc
Enables or disables the generation of compressed instructions. Instructions
are opportunistically compressed by the RISC-V assembler when possible, but
-sometimes this behavior is not desirable.
+sometimes this behavior is not desirable, especially when handling alignments.
@item pic
@itemx nopic
@@ -212,6 +212,19 @@ desirable.
@itemx no-csr-check
Enables or disables the CSR checking.
+@item arch, @var{+extension[version]} [,...,@var{+extension_n[version_n]}]
+@itemx arch, @var{-extension} [,...,@var{-extension_n}]
+@itemx arch, @var{=ISA}
+Enables or disables the extensions for specific code region. For example,
+@samp{.option arch, +m2p0} means add m extension with version 2.0, and
+@samp{.option arch, -f, -d} means remove extensions, f and d, from the
+architecture string. Note that, @samp{.option arch, +c, -c} have the same
+behavior as @samp{.option rvc, norvc}. However, they are also undesirable
+sometimes. Besides, @samp{.option arch, -i} is illegal, since we cannot
+remove the base i extension anytime. If you want to reset the whole ISA
+string, you can also use @samp{.option arch, =rv32imac} to overwrite the
+previous settings.
+
@cindex INSN directives
@item .insn @var{type}, @var{operand} [,...,@var{operand_n}]
@itemx .insn @var{insn_length}, @var{value}
diff --git a/gas/testsuite/gas/riscv/option-arch-01.s b/gas/testsuite/gas/riscv/option-arch-01.s
new file mode 100644
index 0000000..201f9b3
--- /dev/null
+++ b/gas/testsuite/gas/riscv/option-arch-01.s
@@ -0,0 +1,10 @@
+.attribute arch, "rv64ic"
+add a0, a0, a1
+.option push
+.option arch, +d2p0, -c, +xvendor1p0
+add a0, a0, a1
+frcsr a0 # Should add mapping symbol with ISA here, and then dump it to frcsr.
+.option push
+.option arch, +i3p0, +m3p0, +d3p0
+.option pop
+.option pop
diff --git a/gas/testsuite/gas/riscv/option-arch-01a.d b/gas/testsuite/gas/riscv/option-arch-01a.d
new file mode 100644
index 0000000..59bc1d2
--- /dev/null
+++ b/gas/testsuite/gas/riscv/option-arch-01a.d
@@ -0,0 +1,14 @@
+#as:
+#source: option-arch-01.s
+#objdump: -d
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <.text>:
+[ ]+[0-9a-f]+:[ ]+952e[ ]+add[ ]+a0,a0,a1
+[ ]+[0-9a-f]+:[ ]+00b50533[ ]+add[ ]+a0,a0,a1
+[ ]+[0-9a-f]+:[ ]+00302573[ ]+csrr[ ]+a0,fcsr
+#...
diff --git a/gas/testsuite/gas/riscv/option-arch-01b.d b/gas/testsuite/gas/riscv/option-arch-01b.d
new file mode 100644
index 0000000..9a6c2c5
--- /dev/null
+++ b/gas/testsuite/gas/riscv/option-arch-01b.d
@@ -0,0 +1,8 @@
+#as:
+#readelf: -A
+#source: option-arch-01.s
+
+Attribute Section: riscv
+File Attributes
+ Tag_RISCV_arch: "rv64i2p0_c2p0"
+#...
diff --git a/gas/testsuite/gas/riscv/option-arch-02.d b/gas/testsuite/gas/riscv/option-arch-02.d
new file mode 100644
index 0000000..0fe89ec
--- /dev/null
+++ b/gas/testsuite/gas/riscv/option-arch-02.d
@@ -0,0 +1,8 @@
+#as:
+#readelf: -A
+#source: option-arch-02.s
+
+Attribute Section: riscv
+File Attributes
+ Tag_RISCV_arch: "rv64i3p0_m3p0_f2p0_d3p0_c2p0_xvendor32x3p0"
+#...
diff --git a/gas/testsuite/gas/riscv/option-arch-02.s b/gas/testsuite/gas/riscv/option-arch-02.s
new file mode 100644
index 0000000..f4ceee84
--- /dev/null
+++ b/gas/testsuite/gas/riscv/option-arch-02.s
@@ -0,0 +1,8 @@
+.attribute arch, "rv64ic"
+add a0, a0, a1
+.option push
+.option arch, +d2p0, -c, +xvendor1p0
+add a0, a0, a1
+frcsr a0
+.option pop
+.option arch, +i3p0, +m3p0, +d3p0, +xvendor32x3p0
diff --git a/gas/testsuite/gas/riscv/option-arch-03.d b/gas/testsuite/gas/riscv/option-arch-03.d
new file mode 100644
index 0000000..b621d03
--- /dev/null
+++ b/gas/testsuite/gas/riscv/option-arch-03.d
@@ -0,0 +1,8 @@
+#as:
+#readelf: -A
+#source: option-arch-03.s
+
+Attribute Section: riscv
+File Attributes
+ Tag_RISCV_arch: "rv32i2p0_c2p0"
+#...
diff --git a/gas/testsuite/gas/riscv/option-arch-03.s b/gas/testsuite/gas/riscv/option-arch-03.s
new file mode 100644
index 0000000..7183140
--- /dev/null
+++ b/gas/testsuite/gas/riscv/option-arch-03.s
@@ -0,0 +1,3 @@
+.attribute arch, "rv64ic"
+.option arch, +d2p0, -c
+.option arch, =rv32ic
diff --git a/gas/testsuite/gas/riscv/option-arch-fail.d b/gas/testsuite/gas/riscv/option-arch-fail.d
new file mode 100644
index 0000000..bce5d32
--- /dev/null
+++ b/gas/testsuite/gas/riscv/option-arch-fail.d
@@ -0,0 +1,3 @@
+#as:
+#source: option-arch-fail.s
+#error_output: option-arch-fail.l
diff --git a/gas/testsuite/gas/riscv/option-arch-fail.l b/gas/testsuite/gas/riscv/option-arch-fail.l
new file mode 100644
index 0000000..3e0599e
--- /dev/null
+++ b/gas/testsuite/gas/riscv/option-arch-fail.l
@@ -0,0 +1,8 @@
+.*Assembler messages:
+.*Error: extensions must begin with \+/\-/\= in .option arch `m2p0'
+.*Error: cannot remove extension `i' in .option arch `\-i'
+.*Error: unknown ISA extension `zsubset' in .option arch `\+zsubset2p0'
+.*Error: unknown ISA extension `f2p0_d' in .option arch `\+f2p0_d2p0'
+.*Error: unknown ISA extension `' in .option arch `\+'
+.*Error: invalid ISA extension ends with <number>p in .option arch `\+xvendor2p'
+.*Error: .option pop with no .option push
diff --git a/gas/testsuite/gas/riscv/option-arch-fail.s b/gas/testsuite/gas/riscv/option-arch-fail.s
new file mode 100644
index 0000000..a0b1bde
--- /dev/null
+++ b/gas/testsuite/gas/riscv/option-arch-fail.s
@@ -0,0 +1,10 @@
+.attribute arch, "rv64ic"
+.option push
+.option arch, m2p0
+.option arch, -i
+.option arch, +zsubset2p0
+.option arch, +f2p0_d2p0
+.option arch, +
+.option arch, +xvendor2p
+.option pop
+.option pop