aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorNelson Chu <nelson.chu@sifive.com>2020-12-02 17:18:35 +0800
committerNelson Chu <nelson.chu@sifive.com>2020-12-10 10:37:43 +0800
commit729a53530e86972d1143553a415db34e6e01d5d2 (patch)
treee8a27c9d6d7f0cd468a089616450dca0ef0e7e4e /bfd
parentcd6b05c1b2321cafe3ad9335aaa734a28f2a058e (diff)
downloadfsf-binutils-gdb-729a53530e86972d1143553a415db34e6e01d5d2.zip
fsf-binutils-gdb-729a53530e86972d1143553a415db34e6e01d5d2.tar.gz
fsf-binutils-gdb-729a53530e86972d1143553a415db34e6e01d5d2.tar.bz2
RISC-V: Control fence.i and csr instructions by zifencei and zicsr.
bfd/ * elfxx-riscv.c (riscv_ext_dont_care_version): New function. Return TRUE if we don't care the versions of the extensions. These extensions are added to the subset list for special purposes, with the explicit versions or the RISCV_UNKNOWN_VERSION versions. (riscv_parse_add_subset): If we do care the versions of the extension, and the versions are unknown, then report errors for the non-implicit extensions, and return directly for the implicit one. (riscv_arch_str1): Do not output i extension after e, and the extensions which versions are unknown. gas/ * config/tc-riscv.c (riscv_multi_subset_supports): Handle INSN_CLASS_ZICSR and INSN_CLASS_ZIFENCEI. * testsuite/gas/riscv/march-imply-i.s: New testcase. * testsuite/gas/riscv/march-imply-i2p0-01.d: New testcase. The version of i is less than 2.1, and zi* are supported in the chosen spec, so enable the fence.i and csr instructions, also output the implicit zi* to the arch string. * testsuite/gas/riscv/march-imply-i2p0-02.d: Likewise, but the zi* are not supported in the spec 2.2. Enable the related instructions since i's version is less than 2.1, but do not output them. * testsuite/gas/riscv/march-imply-i2p1-01.d: New testcase. The version of i is 2.1, so don't add it's implicit zi*, and disable the related instructions. * testsuite/gas/riscv/march-imply-i2p1-01.l: Likewise. * testsuite/gas/riscv/march-imply-i2p1-02.d: Likewise, and set the zi* explicitly, so enable the related instructions. * testsuite/gas/riscv/march-imply-i2p0.d: Removed. * testsuite/gas/riscv/march-imply-i2p1.d: Removed. include/ * opcode/riscv.h: Add INSN_CLASS_ZICSR and INSN_CLASS_ZIFENCEI. opcodes/ * riscv-opc.c (riscv_opcodes): Control fence.i and csr instructions by zifencei and zicsr.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog12
-rw-r--r--bfd/elfxx-riscv.c59
2 files changed, 51 insertions, 20 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 99c275c..8be4018 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,15 @@
+2020-12-10 Nelson Chu <nelson.chu@sifive.com>
+
+ * elfxx-riscv.c (riscv_ext_dont_care_version): New function. Return
+ TRUE if we don't care the versions of the extensions. These extensions
+ are added to the subset list for special purposes, with the explicit
+ versions or the RISCV_UNKNOWN_VERSION versions.
+ (riscv_parse_add_subset): If we do care the versions of the extension,
+ and the versions are unknown, then report errors for the non-implicit
+ extensions, and return directly for the implicit one.
+ (riscv_arch_str1): Do not output i extension after e, and the extensions
+ which versions are unknown.
+
2020-12-07 Siddhesh Poyarekar <siddhesh@sourceware.org>
PR 26945
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 0696780..35e46fa 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1148,6 +1148,21 @@ riscv_add_implicit_subset (riscv_subset_list_t *subset_list,
}
}
+/* These extensions are added to the subset list for special purposes,
+ with the explicit versions or the RISCV_UNKNOWN_VERSION versions.
+ Therefore, we won't output them to the output arch string in the
+ riscv_arch_str1, if the versions are unknown. */
+
+static bfd_boolean
+riscv_ext_dont_care_version (const char *subset)
+{
+ if (strcmp (subset, "g") == 0
+ || strcmp (subset, "zicsr") == 0
+ || strcmp (subset, "zifencei") == 0)
+ return TRUE;
+ return FALSE;
+}
+
/* We have to add all arch string extensions first, and then start to
add their implicit extensions. The arch string extensions must be
set in order, so we can add them to the last of the subset list
@@ -1172,11 +1187,15 @@ riscv_parse_add_subset (riscv_parse_subset_t *rps,
&& rps->get_default_version != NULL)
rps->get_default_version (subset, &major_version, &minor_version);
- if (!implicit
- && strcmp (subset, "g") != 0
+ if (!riscv_ext_dont_care_version (subset)
&& (major_version == RISCV_UNKNOWN_VERSION
|| minor_version == RISCV_UNKNOWN_VERSION))
{
+ /* We only add the implicit extension if it is supported in the
+ chosen ISA spec. */
+ if (implicit)
+ return;
+
if (subset[0] == 'x')
rps->error_handler
(_("x ISA extension `%s' must be set with the versions"),
@@ -1191,10 +1210,7 @@ riscv_parse_add_subset (riscv_parse_subset_t *rps,
if (!implicit)
riscv_add_subset (rps->subset_list, subset,
major_version, minor_version);
- else if (major_version != RISCV_UNKNOWN_VERSION
- && minor_version != RISCV_UNKNOWN_VERSION)
- /* We only add the implicit extension if it is supported in the
- chosen ISA spec. */
+ else
riscv_add_implicit_subset (rps->subset_list, subset,
major_version, minor_version);
}
@@ -1907,31 +1923,34 @@ riscv_arch_str1 (riscv_subset_t *subset,
char *attr_str, char *buf, size_t bufsz)
{
const char *underline = "_";
+ riscv_subset_t *subset_t = subset;
- if (subset == NULL)
+ if (subset_t == NULL)
return;
/* No underline between rvXX and i/e. */
- if ((strcasecmp (subset->name, "i") == 0)
- || (strcasecmp (subset->name, "e") == 0))
+ if ((strcasecmp (subset_t->name, "i") == 0)
+ || (strcasecmp (subset_t->name, "e") == 0))
underline = "";
snprintf (buf, bufsz, "%s%s%dp%d",
underline,
- subset->name,
- subset->major_version,
- subset->minor_version);
+ subset_t->name,
+ subset_t->major_version,
+ subset_t->minor_version);
strncat (attr_str, buf, bufsz);
- /* Skip 'i' extension after 'e', and skip 'g' extension. */
- if (subset->next
- && ((strcmp (subset->name, "e") == 0
- && strcmp (subset->next->name, "i") == 0)
- || strcmp (subset->next->name, "g") == 0))
- riscv_arch_str1 (subset->next->next, attr_str, buf, bufsz);
- else
- riscv_arch_str1 (subset->next, attr_str, buf, bufsz);
+ /* Skip 'i' extension after 'e', or skip extensions which
+ versions are unknown. */
+ while (subset_t->next
+ && ((strcmp (subset_t->name, "e") == 0
+ && strcmp (subset_t->next->name, "i") == 0)
+ || subset_t->next->major_version == RISCV_UNKNOWN_VERSION
+ || subset_t->next->minor_version == RISCV_UNKNOWN_VERSION))
+ subset_t = subset_t->next;
+
+ riscv_arch_str1 (subset_t->next, attr_str, buf, bufsz);
}
/* Convert subset info to string with explicit version info. */