On Mon, 19 Aug 2024 21:53:54 PDT (-0700), jia...@iscas.ac.cn wrote:
Supports RISC-V profiles[1] in -march option.
Default input set the profile before other formal extensions.
V2: Fixes some format errors and adds code comments for parse function
Thanks for Jeff Law's review and comments.
V3: Update testcases and profiles extensions support.Remove S/M mode Profiles.
Thanks for Christoph Müllner,Palmer Dabbelt's review and comments.
V4: Fix format issue, adjust test name.
[1]https://github.com/riscv/riscv-profiles/blob/main/profiles.adoc
gcc/ChangeLog:
* common/config/riscv/riscv-common.cc (struct riscv_profiles):
* New struct.
(riscv_subset_list::parse_profiles): New function.
(riscv_subset_list::parse_base_ext): New process.
* config/riscv/riscv-subset.h: New protype.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/arch-44.c: New test.
* gcc.target/riscv/arch-45.c: New test.
* gcc.target/riscv/arch-46.c: New test.
---
gcc/common/config/riscv/riscv-common.cc | 75 +++++++++++++++++++++++-
gcc/config/riscv/riscv-subset.h | 2 +
gcc/testsuite/gcc.target/riscv/arch-44.c | 5 ++
gcc/testsuite/gcc.target/riscv/arch-45.c | 12 ++++
gcc/testsuite/gcc.target/riscv/arch-46.c | 12 ++++
5 files changed, 105 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/arch-44.c
create mode 100644 gcc/testsuite/gcc.target/riscv/arch-45.c
create mode 100644 gcc/testsuite/gcc.target/riscv/arch-46.c
diff --git a/gcc/common/config/riscv/riscv-common.cc
b/gcc/common/config/riscv/riscv-common.cc
index 62c6e1dab1f..0bad4426971 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -234,6 +234,12 @@ struct riscv_ext_version
int minor_version;
};
+struct riscv_profiles
+{
+ const char *profile_name;
+ const char *profile_string;
+};
+
/* All standard extensions defined in all supported ISA spec. */
static const struct riscv_ext_version riscv_ext_version_table[] =
{
@@ -449,6 +455,31 @@ static const struct riscv_ext_version riscv_combine_info[]
=
{NULL, ISA_SPEC_CLASS_NONE, 0, 0}
};
+/* This table records the mapping form RISC-V Profiles into march string. */
+static const riscv_profiles riscv_profiles_table[] =
+{
+ /* RVI20U only contains the base extension 'i' as mandatory extension. */
+ {"RVI20U64", "rv64i"},
+ {"RVI20U32", "rv32i"},
+
+ /* RVA20U contains the 'i,m,a,f,d,c,zicsr,zicntr,ziccif,ziccrse,ziccamoa,
+ zicclsm,za128rs' as mandatory extensions. */
+ {"RVA20U64", "rv64imafdc_zicsr_zicntr_ziccif_ziccrse_ziccamoa"
+ "_zicclsm_za128rs"},
+
+ /* RVA22U contains the 'i,m,a,f,d,c,zicsr,zihintpause,zba,zbb,zbs,zicntr,
+ zihpm,ziccif,ziccrse,ziccamoa, zicclsm,zic64b,za64rs,zicbom,zicbop,zicboz,
Except at least the Spacemit stuff that claims RVA22 doesn't actually
have Zicclsm, at least assuming the "supports" in there means "doesn't
trap" (we could just say "supports" includes traps, and thus Zicclsm
means nothing).
I'd argue we should just punt on the profiles until we figure out what
they're actually going to be. The pre-23 profiles were all minor
releases anyway, so it's not like we should be losing much there
(as they're not meant for software). At least if we wait we don't end
up committing to this whole "profiles don't mean anything" spot we're
in, like we did for the other spec flavors.
Though now that I'm writing that it actually just sounds kind of silly
to keep hoping that we're going to get any meaningful compatibility
rules enforced by the RISC-V foundation. There's really just no
incentive for that to happen, as we keep bailing out vendors who ship
broken systems and thus there's no pushback from their members.
So maybe the right answer here is to just break users and tell them to
go complain to someone else? At least that way everyone will be upset,
maybe that'll be enough to get things to change?
+ zfhmin,zkt' as mandatory extensions. */
+ {"RVA22U64", "rv64imafdc_zicsr_zicntr_ziccif_ziccrse_ziccamoa"
+ "_zicclsm_zic64b_za64rs_zihintpause_zba_zbb_zbs_zicbom_zicbop"
+ "_zicboz_zfhmin_zkt"},
+
+ /* Currently we do not define S/M mode Profiles in gcc part. */
+
+ /* Terminate the list. */
+ {NULL, NULL}
+};
+
static const riscv_cpu_info riscv_cpu_tables[] =
{
#define RISCV_CORE(CORE_NAME, ARCH, TUNE) \
@@ -1056,6 +1087,46 @@ riscv_subset_list::parsing_subset_version (const char
*ext,
return p;
}
+/* Parsing RISC-V Profiles in -march string.
+ Return string with mandatory extensions of Profiles. */
+const char *
+riscv_subset_list::parse_profiles (const char *p)
+{
+ /* Checking if input string contains a Profiles.
+ There are two cases use Profiles in -march option:
+
+ 1. Only use Profiles as -march input
+ 2. Mixed Profiles with other extensions
+
+ Use '+' to split Profiles and other extension. */
+ for (int i = 0; riscv_profiles_table[i].profile_name != NULL; ++i)
+ {
+ const char *match = strstr (p, riscv_profiles_table[i].profile_name);
+ const char *plus_ext = strchr (p, '+');
+ /* Find profile at the begin. */
+ if (match != NULL && match == p)
+ {
+ /* If there's no '+' sign, return the profile_string directly. */
+ if (!plus_ext)
+ return riscv_profiles_table[i].profile_string;
+ /* If there's a '+' sign, need to add profiles with other ext. */
+ else
+ {
+ size_t arch_len = strlen (riscv_profiles_table[i].profile_string)
+ + strlen (plus_ext);
+ /* Reset the input string with Profiles mandatory extensions,
+ end with '_' to connect other additional extensions. */
+ char *result = new char[arch_len + 2];
+ strcpy (result, riscv_profiles_table[i].profile_string);
+ strcat (result, "_");
+ strcat (result, plus_ext + 1); /* skip the '+'. */
+ return result;
+ }
+ }
+ }
+ return p;
+}
+
/* Parsing function for base extensions, rv[32|64][i|e|g]
Return Value:
@@ -1070,6 +1141,8 @@ riscv_subset_list::parse_base_ext (const char *p)
unsigned minor_version = 0;
bool explicit_version_p = false;
+ p = parse_profiles(p);
+
if (startswith (p, "rv32"))
{
m_xlen = 32;
@@ -1082,7 +1155,7 @@ riscv_subset_list::parse_base_ext (const char *p)
}
else
{
- error_at (m_loc, "%<-march=%s%>: ISA string must begin with rv32 or
rv64",
+ error_at (m_loc, "%<-march=%s%>: ISA string must begin with rv32, rv64 or
Profile",
m_arch);
return NULL;
}
diff --git a/gcc/config/riscv/riscv-subset.h b/gcc/config/riscv/riscv-subset.h
index dace4de6575..98fd9877f74 100644
--- a/gcc/config/riscv/riscv-subset.h
+++ b/gcc/config/riscv/riscv-subset.h
@@ -80,6 +80,8 @@ private:
const char *parse_single_multiletter_ext (const char *, const char *,
const char *, bool);
+ const char *parse_profiles (const char*);
+
void handle_implied_ext (const char *);
bool check_implied_ext ();
void handle_combine_ext ();
diff --git a/gcc/testsuite/gcc.target/riscv/arch-44.c
b/gcc/testsuite/gcc.target/riscv/arch-44.c
new file mode 100644
index 00000000000..41190bc5939
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/arch-44.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-march=RVI20U64 -mabi=lp64" } */
+int
+foo ()
+{}
diff --git a/gcc/testsuite/gcc.target/riscv/arch-45.c
b/gcc/testsuite/gcc.target/riscv/arch-45.c
new file mode 100644
index 00000000000..273c6abf60d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/arch-45.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-march=RVI20U64+mafdc -mabi=lp64d" } */
+#if !(defined __riscv_mul) || \
+ !(defined __riscv_atomic) || \
+ !(defined __riscv_flen) || \
+ !(defined __riscv_div) || \
+ !(defined __riscv_compressed)
+#error "Feature macros not defined"
+#endif
+int
+foo ()
+{}
diff --git a/gcc/testsuite/gcc.target/riscv/arch-46.c
b/gcc/testsuite/gcc.target/riscv/arch-46.c
new file mode 100644
index 00000000000..1ebf50d3755
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/arch-46.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-march=RVA20U64 -mabi=lp64d" } */
+#if !(defined __riscv_mul) || \
+ !(defined __riscv_atomic) || \
+ !(defined __riscv_flen) || \
+ !(defined __riscv_div) || \
+ !(defined __riscv_compressed)
+#error "Feature macros not defined"
+#endif
+int
+foo ()
+{}