From e4d4e27cab9c06aeb9c519b51a1058dee023cb4e Mon Sep 17 00:00:00 2001 From: Tsukasa OI Date: Wed, 26 Jul 2023 00:29:47 +0000 Subject: [PATCH 1/3] RISC-V: Base for complex extension implications Thanks to the commit 48558a5e5471 ("RISC-V: Allow nested implications for extensions"), we can write complex extension implications in theory. However, to actually do that, we need to pass more information to check_func. For example, we want to imply 'Zcf' from 'F' if and only if the 'Zce' extension is also enabled and XLEN is 32. Passing rps is a way to enable this. This commit prepares for such complex extension implications. bfd/ChangeLog: * elfxx-riscv.c (struct riscv_implicit_subset): Move around and change check_func function prototype. (check_implicit_always): New arguments. (check_implicit_for_i): Likewise. (riscv_implicit_subsets): Add comment for this variable. (riscv_parse_add_implicit_subsets): Call check_func with new arguments. --- bfd/elfxx-riscv.c | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c index c070394a366..95836b3296f 100644 --- a/bfd/elfxx-riscv.c +++ b/bfd/elfxx-riscv.c @@ -1064,11 +1064,25 @@ riscv_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED, return bfd_reloc_ok; } +/* Record all implicit information for the subsets. */ + +typedef struct riscv_implicit_subset +{ + const char *subset_name; + const char *implicit_name; + /* A function to determine if we need to add the implicit subset. */ + bool (*check_func) (riscv_parse_subset_t *, + const struct riscv_implicit_subset *, + const riscv_subset_t *); +} riscv_implicit_subset_t; + /* Always add the IMPLICIT for the SUBSET. */ static bool -check_implicit_always (const char *implicit ATTRIBUTE_UNUSED, - riscv_subset_t *subset ATTRIBUTE_UNUSED) +check_implicit_always (riscv_parse_subset_t *rps ATTRIBUTE_UNUSED, + const riscv_implicit_subset_t *implicit + ATTRIBUTE_UNUSED, + const riscv_subset_t *subset ATTRIBUTE_UNUSED) { return true; } @@ -1076,23 +1090,18 @@ check_implicit_always (const char *implicit ATTRIBUTE_UNUSED, /* Add the IMPLICIT only when the version of SUBSET less than 2.1. */ static bool -check_implicit_for_i (const char *implicit ATTRIBUTE_UNUSED, - riscv_subset_t *subset) +check_implicit_for_i (riscv_parse_subset_t *rps ATTRIBUTE_UNUSED, + const riscv_implicit_subset_t *implicit ATTRIBUTE_UNUSED, + const riscv_subset_t *subset) { return (subset->major_version < 2 || (subset->major_version == 2 && subset->minor_version < 1)); } -/* Record all implicit information for the subsets. */ -struct riscv_implicit_subset -{ - const char *subset_name; - const char *implicit_name; - /* A function to determine if we need to add the implicit subset. */ - bool (*check_func) (const char *, riscv_subset_t *); -}; -static struct riscv_implicit_subset riscv_implicit_subsets[] = +/* All extension implications. */ + +static riscv_implicit_subset_t riscv_implicit_subsets[] = { {"e", "i", check_implicit_always}, {"i", "zicsr", check_implicit_for_i}, @@ -1909,7 +1918,7 @@ riscv_parse_extensions (riscv_parse_subset_t *rps, static void riscv_parse_add_implicit_subsets (riscv_parse_subset_t *rps) { - struct riscv_implicit_subset *t = riscv_implicit_subsets; + riscv_implicit_subset_t *t = riscv_implicit_subsets; bool finished = false; while (!finished) { @@ -1921,7 +1930,7 @@ riscv_parse_add_implicit_subsets (riscv_parse_subset_t *rps) if (riscv_lookup_subset (rps->subset_list, t->subset_name, &subset) && !riscv_lookup_subset (rps->subset_list, t->implicit_name, &implicit_subset) - && t->check_func (t->implicit_name, subset)) + && t->check_func (rps, t, subset)) { riscv_parse_add_subset (rps, t->implicit_name, RISCV_UNKNOWN_VERSION, From cad45cd3f91c4f57cd1edcf3fe00ec277b2fb3f7 Mon Sep 17 00:00:00 2001 From: Tsukasa OI Date: Sat, 29 Jul 2023 01:08:08 +0000 Subject: [PATCH 2/3] MOCK: RISC-V: Add 'Zce' extension support It adds a support for the 'Zce' superset compressed instruction extension for embedded systems. **THIS IS A MOCKUP** Since 'Zcmp' and 'Zcmt' are not added to GNU Binutils yet, this commit is just a mockup. However, it outlines what will be required on the 'Zce' support along with new complex implication design. bfd/ChangeLog: * elfxx-riscv.c (check_implicit_for_f_zce): New function to check whether adding implication 'F' -> 'Zcf' is appropriate. (riscv_implicit_subsets): Add conditional implication from 'F' -> 'Zcf'. (riscv_supported_std_z_ext): [MOCK] Add 'Zce' to the supported 'Z' extension list. --- bfd/elfxx-riscv.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c index 95836b3296f..fb3b856881e 100644 --- a/bfd/elfxx-riscv.c +++ b/bfd/elfxx-riscv.c @@ -1099,6 +1099,19 @@ check_implicit_for_i (riscv_parse_subset_t *rps ATTRIBUTE_UNUSED, && subset->minor_version < 1)); } +/* Add the IMPLICIT only when the 'Zce' extension is also available + and XLEN is 32. */ + +static bool +check_implicit_for_f_zce (riscv_parse_subset_t *rps, + const riscv_implicit_subset_t *implicit + ATTRIBUTE_UNUSED, + const riscv_subset_t *subset ATTRIBUTE_UNUSED) +{ + return *rps->xlen == 32 + && riscv_subset_supports (rps, "zce"); +} + /* All extension implications. */ static riscv_implicit_subset_t riscv_implicit_subsets[] = @@ -1188,6 +1201,10 @@ static riscv_implicit_subset_t riscv_implicit_subsets[] = {"zvksg", "zvkg", check_implicit_always}, {"zvksc", "zvks", check_implicit_always}, {"zvksc", "zvbc", check_implicit_always}, + {"zce", "zca", check_implicit_always}, + {"zce", "zcb", check_implicit_always}, + {"zce", "zcmp", check_implicit_always}, + {"zce", "zcmt", check_implicit_always}, {"zcf", "zca", check_implicit_always}, {"zcd", "zca", check_implicit_always}, {"zcb", "zca", check_implicit_always}, @@ -1200,6 +1217,9 @@ static riscv_implicit_subset_t riscv_implicit_subsets[] = {"ssstateen", "zicsr", check_implicit_always}, {"sstc", "zicsr", check_implicit_always}, {"svadu", "zicsr", check_implicit_always}, + /* Complex implications (that should be checked after others). */ + {"f", "zcf", check_implicit_for_f_zce}, + /* Tail of the list. */ {NULL, NULL, NULL} }; @@ -1333,6 +1353,10 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] = {"zcb", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zcf", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zcd", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + /* MOCK: uncomment those lines once ready. */ + // {"zce", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + // {"zcmp", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + // {"zcmt", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {NULL, 0, 0, 0, 0} }; From 7dd9c0b567229538840541a79cd92fd191ec8830 Mon Sep 17 00:00:00 2001 From: Tsukasa OI Date: Sat, 29 Jul 2023 01:19:48 +0000 Subject: [PATCH 3/3] MOCK: RISC-V: Tests for 'Zce' implications **NEVER COMMIT THIS.** This commit is intended to be merged to the previous patch once 'Zcmp' and 'Zcmt' extensions are ready. It adds several tests related to 'Zce' implications. bfd/ChangeLog: * elfxx-riscv.c: [MOCK] Uncomment mock lines to pass the test. gas/ChangeLog: * testsuite/gas/riscv/march-imply-zce.d: New test. * testsuite/gas/riscv/march-imply-zce-f-32.d: Likewise. * testsuite/gas/riscv/march-imply-zce-f-64.d: Likewise. --- bfd/elfxx-riscv.c | 7 +++---- gas/testsuite/gas/riscv/march-imply-zce-f-32.d | 6 ++++++ gas/testsuite/gas/riscv/march-imply-zce-f-64.d | 6 ++++++ gas/testsuite/gas/riscv/march-imply-zce.d | 6 ++++++ 4 files changed, 21 insertions(+), 4 deletions(-) create mode 100644 gas/testsuite/gas/riscv/march-imply-zce-f-32.d create mode 100644 gas/testsuite/gas/riscv/march-imply-zce-f-64.d create mode 100644 gas/testsuite/gas/riscv/march-imply-zce.d diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c index fb3b856881e..76636d3267f 100644 --- a/bfd/elfxx-riscv.c +++ b/bfd/elfxx-riscv.c @@ -1353,10 +1353,9 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] = {"zcb", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zcf", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zcd", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, - /* MOCK: uncomment those lines once ready. */ - // {"zce", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, - // {"zcmp", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, - // {"zcmt", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zce", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zcmp", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zcmt", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {NULL, 0, 0, 0, 0} }; diff --git a/gas/testsuite/gas/riscv/march-imply-zce-f-32.d b/gas/testsuite/gas/riscv/march-imply-zce-f-32.d new file mode 100644 index 00000000000..e0cca82e0a0 --- /dev/null +++ b/gas/testsuite/gas/riscv/march-imply-zce-f-32.d @@ -0,0 +1,6 @@ +#as: -march=rv32if_zce -march-attr -misa-spec=20191213 +#readelf: -A +#source: empty.s +Attribute Section: riscv +File Attributes + Tag_RISCV_arch: "rv32i2p1_f2p2_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcf1p0_zcmp1p0_zcmt1p0" diff --git a/gas/testsuite/gas/riscv/march-imply-zce-f-64.d b/gas/testsuite/gas/riscv/march-imply-zce-f-64.d new file mode 100644 index 00000000000..f0ccd7a3fce --- /dev/null +++ b/gas/testsuite/gas/riscv/march-imply-zce-f-64.d @@ -0,0 +1,6 @@ +#as: -march=rv64if_zce -march-attr -misa-spec=20191213 +#readelf: -A +#source: empty.s +Attribute Section: riscv +File Attributes + Tag_RISCV_arch: "rv64i2p1_f2p2_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcmp1p0_zcmt1p0" diff --git a/gas/testsuite/gas/riscv/march-imply-zce.d b/gas/testsuite/gas/riscv/march-imply-zce.d new file mode 100644 index 00000000000..2a4ab4e1b63 --- /dev/null +++ b/gas/testsuite/gas/riscv/march-imply-zce.d @@ -0,0 +1,6 @@ +#as: -march=rv32i_zce -march-attr -misa-spec=20191213 +#readelf: -A +#source: empty.s +Attribute Section: riscv +File Attributes + Tag_RISCV_arch: "rv32i2p1_zca1p0_zcb1p0_zce1p0_zcmp1p0_zcmt1p0"