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.
This commit is contained in:
Nelson Chu 2020-12-02 17:18:35 +08:00
parent cd6b05c1b2
commit 729a53530e
15 changed files with 179 additions and 53 deletions

View File

@ -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

View File

@ -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. */

View File

@ -1,3 +1,24 @@
2020-12-10 Nelson Chu <nelson.chu@sifive.com>
* 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.
2020-12-08 H.J. Lu <hongjiu.lu@intel.com>
* config/obj-elf.c (SEC_ASSEMBLER_SHF_MASK): New.

View File

@ -237,13 +237,19 @@ riscv_multi_subset_supports (enum riscv_insn_class insn_class)
case INSN_CLASS_M: return riscv_subset_supports ("m");
case INSN_CLASS_F: return riscv_subset_supports ("f");
case INSN_CLASS_D: return riscv_subset_supports ("d");
case INSN_CLASS_D_AND_C:
return riscv_subset_supports ("d") && riscv_subset_supports ("c");
case INSN_CLASS_Q: return riscv_subset_supports ("q");
case INSN_CLASS_F_AND_C:
return riscv_subset_supports ("f") && riscv_subset_supports ("c");
return (riscv_subset_supports ("f")
&& riscv_subset_supports ("c"));
case INSN_CLASS_D_AND_C:
return (riscv_subset_supports ("d")
&& riscv_subset_supports ("c"));
case INSN_CLASS_Q: return riscv_subset_supports ("q");
case INSN_CLASS_ZICSR:
return riscv_subset_supports ("zicsr");
case INSN_CLASS_ZIFENCEI:
return riscv_subset_supports ("zifencei");
default:
as_fatal ("Unreachable");

View File

@ -0,0 +1,24 @@
target:
# zicsr
csrr t0, ustatus
csrwi ustatus, 0x0
csrsi ustatus, 0x0
csrci ustatus, 0x0
csrw ustatus, t0
csrw ustatus, 0x0
csrs ustatus, t0
csrs ustatus, 0x0
csrc ustatus, t0
csrc ustatus, 0x0
csrrwi t0, ustatus, 0x0
csrrsi t0, ustatus, 0x0
csrrci t0, ustatus, 0x0
csrrw t0, ustatus, t0
csrrw t0, ustatus, 0x0
csrrs t0, ustatus, t0
csrrs t0, ustatus, 0x0
csrrc t0, ustatus, t0
csrrc t0, ustatus, 0x0
# zifencei
fence.i

View File

@ -1,6 +1,7 @@
#as: -march=rv32i2p0 -march-attr -misa-spec=20191213
#readelf: -A
#source: empty.s
#source: march-imply-i.s
Attribute Section: riscv
File Attributes
Tag_RISCV_arch: "rv32i2p0_zicsr2p0_zifencei2p0"
#...

View File

@ -0,0 +1,7 @@
#as: -march=rv32i -march-attr -misa-spec=2.2
#readelf: -A
#source: march-imply-i.s
Attribute Section: riscv
File Attributes
Tag_RISCV_arch: "rv32i2p0"
#...

View File

@ -0,0 +1,3 @@
#as: -march=rv32i -march-attr -misa-spec=20191213
#source: march-imply-i.s
#error_output: march-imply-i2p1-01.l

View File

@ -0,0 +1,21 @@
.*Assembler messages:
.*Error: unrecognized opcode `csrr t0,ustatus'
.*Error: unrecognized opcode `csrwi ustatus,0x0'
.*Error: unrecognized opcode `csrsi ustatus,0x0'
.*Error: unrecognized opcode `csrci ustatus,0x0'
.*Error: unrecognized opcode `csrw ustatus,t0'
.*Error: unrecognized opcode `csrw ustatus,0x0'
.*Error: unrecognized opcode `csrs ustatus,t0'
.*Error: unrecognized opcode `csrs ustatus,0x0'
.*Error: unrecognized opcode `csrc ustatus,t0'
.*Error: unrecognized opcode `csrc ustatus,0x0'
.*Error: unrecognized opcode `csrrwi t0,ustatus,0x0'
.*Error: unrecognized opcode `csrrsi t0,ustatus,0x0'
.*Error: unrecognized opcode `csrrci t0,ustatus,0x0'
.*Error: unrecognized opcode `csrrw t0,ustatus,t0'
.*Error: unrecognized opcode `csrrw t0,ustatus,0x0'
.*Error: unrecognized opcode `csrrs t0,ustatus,t0'
.*Error: unrecognized opcode `csrrs t0,ustatus,0x0'
.*Error: unrecognized opcode `csrrc t0,ustatus,t0'
.*Error: unrecognized opcode `csrrc t0,ustatus,0x0'
.*Error: unrecognized opcode `fence.i'

View File

@ -0,0 +1,7 @@
#as: -march=rv32i_zicsr_zifencei -march-attr -misa-spec=20191213
#readelf: -A
#source: march-imply-i.s
Attribute Section: riscv
File Attributes
Tag_RISCV_arch: "rv32i2p1_zicsr2p0_zifencei2p0"
#...

View File

@ -1,6 +0,0 @@
#as: -march=rv32i -march-attr -misa-spec=20191213
#readelf: -A
#source: empty.s
Attribute Section: riscv
File Attributes
Tag_RISCV_arch: "rv32i2p1"

View File

@ -1,3 +1,7 @@
2020-12-10 Nelson Chu <nelson.chu@sifive.com>
* opcode/riscv.h: Add INSN_CLASS_ZICSR and INSN_CLASS_ZIFENCEI.
2020-12-07 Nick Clifton <nickc@redhat.com>
* elf/common.h (SHF_GNU_BUILD_NOTE): Delete.

View File

@ -306,9 +306,11 @@ enum riscv_insn_class
INSN_CLASS_M,
INSN_CLASS_F,
INSN_CLASS_D,
INSN_CLASS_D_AND_C,
INSN_CLASS_F_AND_C,
INSN_CLASS_Q,
INSN_CLASS_F_AND_C,
INSN_CLASS_D_AND_C,
INSN_CLASS_ZICSR,
INSN_CLASS_ZIFENCEI,
};
/* This structure holds information for a particular instruction. */

View File

@ -1,3 +1,8 @@
2020-12-10 Nelson Chu <nelson.chu@sifive.com>
* riscv-opc.c (riscv_opcodes): Control fence.i and csr instructions by
zifencei and zicsr.
2020-12-04 Andreas Krebbel <krebbel@linux.ibm.com>
* s390-opc.txt: Add risbgz and risbgnz.

View File

@ -345,7 +345,7 @@ const struct riscv_opcode riscv_opcodes[] =
{"sw", 0, INSN_CLASS_I, "t,A,s", 0, (int) M_SW, match_never, INSN_MACRO },
{"fence", 0, INSN_CLASS_I, "", MATCH_FENCE | MASK_PRED | MASK_SUCC, MASK_FENCE | MASK_RD | MASK_RS1 | MASK_IMM, match_opcode, INSN_ALIAS },
{"fence", 0, INSN_CLASS_I, "P,Q", MATCH_FENCE, MASK_FENCE | MASK_RD | MASK_RS1 | (MASK_IMM & ~MASK_PRED & ~MASK_SUCC), match_opcode, 0 },
{"fence.i", 0, INSN_CLASS_I, "", MATCH_FENCE_I, MASK_FENCE | MASK_RD | MASK_RS1 | MASK_IMM, match_opcode, 0 },
{"fence.i", 0, INSN_CLASS_ZIFENCEI, "", MATCH_FENCE_I, MASK_FENCE | MASK_RD | MASK_RS1 | MASK_IMM, match_opcode, 0 },
{"fence.tso", 0, INSN_CLASS_I, "", MATCH_FENCE_TSO, MASK_FENCE_TSO | MASK_RD | MASK_RS1, match_opcode, INSN_ALIAS },
{"rdcycle", 0, INSN_CLASS_I, "d", MATCH_RDCYCLE, MASK_RDCYCLE, match_opcode, INSN_ALIAS },
{"rdinstret", 0, INSN_CLASS_I, "d", MATCH_RDINSTRET, MASK_RDINSTRET, match_opcode, INSN_ALIAS },
@ -749,25 +749,25 @@ const struct riscv_opcode riscv_opcodes[] =
{"c.fsw", 32, INSN_CLASS_F_AND_C, "CD,Ck(Cs)", MATCH_C_FSW, MASK_C_FSW, match_opcode, INSN_DREF|INSN_4_BYTE },
/* Supervisor instructions */
{"csrr", 0, INSN_CLASS_I, "d,E", MATCH_CSRRS, MASK_CSRRS | MASK_RS1, match_opcode, INSN_ALIAS },
{"csrwi", 0, INSN_CLASS_I, "E,Z", MATCH_CSRRWI, MASK_CSRRWI | MASK_RD, match_opcode, INSN_ALIAS },
{"csrsi", 0, INSN_CLASS_I, "E,Z", MATCH_CSRRSI, MASK_CSRRSI | MASK_RD, match_opcode, INSN_ALIAS },
{"csrci", 0, INSN_CLASS_I, "E,Z", MATCH_CSRRCI, MASK_CSRRCI | MASK_RD, match_opcode, INSN_ALIAS },
{"csrw", 0, INSN_CLASS_I, "E,s", MATCH_CSRRW, MASK_CSRRW | MASK_RD, match_opcode, INSN_ALIAS },
{"csrw", 0, INSN_CLASS_I, "E,Z", MATCH_CSRRWI, MASK_CSRRWI | MASK_RD, match_opcode, INSN_ALIAS },
{"csrs", 0, INSN_CLASS_I, "E,s", MATCH_CSRRS, MASK_CSRRS | MASK_RD, match_opcode, INSN_ALIAS },
{"csrs", 0, INSN_CLASS_I, "E,Z", MATCH_CSRRSI, MASK_CSRRSI | MASK_RD, match_opcode, INSN_ALIAS },
{"csrc", 0, INSN_CLASS_I, "E,s", MATCH_CSRRC, MASK_CSRRC | MASK_RD, match_opcode, INSN_ALIAS },
{"csrc", 0, INSN_CLASS_I, "E,Z", MATCH_CSRRCI, MASK_CSRRCI | MASK_RD, match_opcode, INSN_ALIAS },
{"csrrwi", 0, INSN_CLASS_I, "d,E,Z", MATCH_CSRRWI, MASK_CSRRWI, match_opcode, 0 },
{"csrrsi", 0, INSN_CLASS_I, "d,E,Z", MATCH_CSRRSI, MASK_CSRRSI, match_opcode, 0 },
{"csrrci", 0, INSN_CLASS_I, "d,E,Z", MATCH_CSRRCI, MASK_CSRRCI, match_opcode, 0 },
{"csrrw", 0, INSN_CLASS_I, "d,E,s", MATCH_CSRRW, MASK_CSRRW, match_opcode, 0 },
{"csrrw", 0, INSN_CLASS_I, "d,E,Z", MATCH_CSRRWI, MASK_CSRRWI, match_opcode, INSN_ALIAS },
{"csrrs", 0, INSN_CLASS_I, "d,E,s", MATCH_CSRRS, MASK_CSRRS, match_opcode, 0 },
{"csrrs", 0, INSN_CLASS_I, "d,E,Z", MATCH_CSRRSI, MASK_CSRRSI, match_opcode, INSN_ALIAS },
{"csrrc", 0, INSN_CLASS_I, "d,E,s", MATCH_CSRRC, MASK_CSRRC, match_opcode, 0 },
{"csrrc", 0, INSN_CLASS_I, "d,E,Z", MATCH_CSRRCI, MASK_CSRRCI, match_opcode, INSN_ALIAS },
{"csrr", 0, INSN_CLASS_ZICSR, "d,E", MATCH_CSRRS, MASK_CSRRS | MASK_RS1, match_opcode, INSN_ALIAS },
{"csrwi", 0, INSN_CLASS_ZICSR, "E,Z", MATCH_CSRRWI, MASK_CSRRWI | MASK_RD, match_opcode, INSN_ALIAS },
{"csrsi", 0, INSN_CLASS_ZICSR, "E,Z", MATCH_CSRRSI, MASK_CSRRSI | MASK_RD, match_opcode, INSN_ALIAS },
{"csrci", 0, INSN_CLASS_ZICSR, "E,Z", MATCH_CSRRCI, MASK_CSRRCI | MASK_RD, match_opcode, INSN_ALIAS },
{"csrw", 0, INSN_CLASS_ZICSR, "E,s", MATCH_CSRRW, MASK_CSRRW | MASK_RD, match_opcode, INSN_ALIAS },
{"csrw", 0, INSN_CLASS_ZICSR, "E,Z", MATCH_CSRRWI, MASK_CSRRWI | MASK_RD, match_opcode, INSN_ALIAS },
{"csrs", 0, INSN_CLASS_ZICSR, "E,s", MATCH_CSRRS, MASK_CSRRS | MASK_RD, match_opcode, INSN_ALIAS },
{"csrs", 0, INSN_CLASS_ZICSR, "E,Z", MATCH_CSRRSI, MASK_CSRRSI | MASK_RD, match_opcode, INSN_ALIAS },
{"csrc", 0, INSN_CLASS_ZICSR, "E,s", MATCH_CSRRC, MASK_CSRRC | MASK_RD, match_opcode, INSN_ALIAS },
{"csrc", 0, INSN_CLASS_ZICSR, "E,Z", MATCH_CSRRCI, MASK_CSRRCI | MASK_RD, match_opcode, INSN_ALIAS },
{"csrrwi", 0, INSN_CLASS_ZICSR, "d,E,Z", MATCH_CSRRWI, MASK_CSRRWI, match_opcode, 0 },
{"csrrsi", 0, INSN_CLASS_ZICSR, "d,E,Z", MATCH_CSRRSI, MASK_CSRRSI, match_opcode, 0 },
{"csrrci", 0, INSN_CLASS_ZICSR, "d,E,Z", MATCH_CSRRCI, MASK_CSRRCI, match_opcode, 0 },
{"csrrw", 0, INSN_CLASS_ZICSR, "d,E,s", MATCH_CSRRW, MASK_CSRRW, match_opcode, 0 },
{"csrrw", 0, INSN_CLASS_ZICSR, "d,E,Z", MATCH_CSRRWI, MASK_CSRRWI, match_opcode, INSN_ALIAS },
{"csrrs", 0, INSN_CLASS_ZICSR, "d,E,s", MATCH_CSRRS, MASK_CSRRS, match_opcode, 0 },
{"csrrs", 0, INSN_CLASS_ZICSR, "d,E,Z", MATCH_CSRRSI, MASK_CSRRSI, match_opcode, INSN_ALIAS },
{"csrrc", 0, INSN_CLASS_ZICSR, "d,E,s", MATCH_CSRRC, MASK_CSRRC, match_opcode, 0 },
{"csrrc", 0, INSN_CLASS_ZICSR, "d,E,Z", MATCH_CSRRCI, MASK_CSRRCI, match_opcode, INSN_ALIAS },
{"uret", 0, INSN_CLASS_I, "", MATCH_URET, MASK_URET, match_opcode, 0 },
{"sret", 0, INSN_CLASS_I, "", MATCH_SRET, MASK_SRET, match_opcode, 0 },
{"hret", 0, INSN_CLASS_I, "", MATCH_HRET, MASK_HRET, match_opcode, 0 },