aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorKito Cheng <kito.cheng@sifive.com>2024-01-05 22:08:34 +0800
committerKito Cheng <kito.cheng@sifive.com>2024-01-19 15:19:39 +0800
commit006ad3e7f7847eb53c837aa1a581af0f822b7616 (patch)
treebe5880d33549c426cb57a0ee47e0318990a7b196 /gcc
parent4e8fef35f7c4553529e92a0d9f501b94481ede0b (diff)
downloadgcc-006ad3e7f7847eb53c837aa1a581af0f822b7616.zip
gcc-006ad3e7f7847eb53c837aa1a581af0f822b7616.tar.gz
gcc-006ad3e7f7847eb53c837aa1a581af0f822b7616.tar.bz2
RISC-V: Relax the -march string for accept any order
-march was require canonical order before, however it's not easy for most user when we have so many extension, so this patch is relax the constraint, -march accept the ISA string in any order, it only has few requirement: 1. Must start with rv[32|64][e|i|g]. 2. Multi-letter and single letter extension must be separated by at least one underscore(`_`). gcc/ChangeLog: * common/config/riscv/riscv-common.cc (riscv_subset_list::parse_single_std_ext): New parameter. (riscv_subset_list::parse_single_multiletter_ext): Ditto. (riscv_subset_list::parse_single_ext): Ditto. (riscv_subset_list::parse): Relax the order for the input of ISA string. * config/riscv/riscv-subset.h (riscv_subset_list::parse_single_std_ext): New parameter. (riscv_subset_list::parse_single_multiletter_ext): Ditto. (riscv_subset_list::parse_single_ext): Ditto. gcc/testsuite/ChangeLog: * gcc.target/riscv/arch-33.c: New. * gcc.target/riscv/arch-34.c: New.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/common/config/riscv/riscv-common.cc91
-rw-r--r--gcc/config/riscv/riscv-subset.h6
-rw-r--r--gcc/testsuite/gcc.target/riscv/arch-33.c5
-rw-r--r--gcc/testsuite/gcc.target/riscv/arch-34.c5
4 files changed, 67 insertions, 40 deletions
diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc
index 0ffbb5f..e0236f1 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -1132,10 +1132,12 @@ riscv_subset_list::parse_std_ext (const char *p)
Points to the end of extensions.
Arguments:
- `p`: Current parsing position. */
+ `p`: Current parsing position.
+ `exact_single_p`: True if input string is exactly an extension and end
+ with '\0'. */
const char *
-riscv_subset_list::parse_single_std_ext (const char *p)
+riscv_subset_list::parse_single_std_ext (const char *p, bool exact_single_p)
{
if (*p == 'x' || *p == 's' || *p == 'z')
{
@@ -1146,6 +1148,11 @@ riscv_subset_list::parse_single_std_ext (const char *p)
return nullptr;
}
+ if (exact_single_p && strlen (p) > 1)
+ {
+ return nullptr;
+ }
+
unsigned major_version = 0;
unsigned minor_version = 0;
bool explicit_version_p = false;
@@ -1305,13 +1312,16 @@ riscv_subset_list::check_conflict_ext ()
Arguments:
`p`: Current parsing position.
`ext_type`: What kind of extensions, 's', 'z' or 'x'.
- `ext_type_str`: Full name for kind of extension. */
+ `ext_type_str`: Full name for kind of extension.
+ `exact_single_p`: True if input string is exactly an extension and end
+ with '\0'. */
const char *
riscv_subset_list::parse_single_multiletter_ext (const char *p,
const char *ext_type,
- const char *ext_type_str)
+ const char *ext_type_str,
+ bool exact_single_p)
{
unsigned major_version = 0;
unsigned minor_version = 0;
@@ -1323,6 +1333,7 @@ riscv_subset_list::parse_single_multiletter_ext (const char *p,
char *subset = xstrdup (p);
const char *end_of_version;
bool explicit_version_p = false;
+ char *q = subset;
char *ext;
char backup;
size_t len = strlen (p);
@@ -1330,6 +1341,17 @@ riscv_subset_list::parse_single_multiletter_ext (const char *p,
bool found_any_number = false;
bool found_minor_version = false;
+ if (!exact_single_p)
+ {
+ /* Extension may not ended with '\0', may come with another extension
+ which concat by '_' */
+ /* Parse until end of this extension including version number. */
+ while (*++q != '\0' && *q != '_')
+ ;
+
+ len = q - subset;
+ }
+
end_of_version_pos = len;
/* Find the begin of version string. */
for (i = len -1; i > 0; --i)
@@ -1514,21 +1536,26 @@ riscv_subset_list::parse_multiletter_ext (const char *p,
Points to the end of extensions.
Arguments:
- `p`: Current parsing position. */
+ `p`: Current parsing position.
+ `exact_single_p`: True if input string is exactly an extension and end
+ with '\0'. */
const char *
-riscv_subset_list::parse_single_ext (const char *p)
+riscv_subset_list::parse_single_ext (const char *p, bool exact_single_p)
{
switch (p[0])
{
case 'x':
- return parse_single_multiletter_ext (p, "x", "non-standard extension");
+ return parse_single_multiletter_ext (p, "x", "non-standard extension",
+ exact_single_p);
case 'z':
- return parse_single_multiletter_ext (p, "z", "sub-extension");
+ return parse_single_multiletter_ext (p, "z", "sub-extension",
+ exact_single_p);
case 's':
- return parse_single_multiletter_ext (p, "s", "supervisor extension");
+ return parse_single_multiletter_ext (p, "s", "supervisor extension",
+ exact_single_p);
default:
- return parse_single_std_ext (p);
+ return parse_single_std_ext (p, exact_single_p);
}
}
@@ -1547,37 +1574,27 @@ riscv_subset_list::parse (const char *arch, location_t loc)
if (p == NULL)
goto fail;
- /* Parsing standard extension. */
- p = subset_list->parse_std_ext (p);
-
- if (p == NULL)
- goto fail;
-
- /* Parsing sub-extensions. */
- p = subset_list->parse_multiletter_ext (p, "z", "sub-extension");
-
- if (p == NULL)
- goto fail;
-
- /* Parsing supervisor extension. */
- p = subset_list->parse_multiletter_ext (p, "s", "supervisor extension");
-
- if (p == NULL)
- goto fail;
-
- /* Parsing non-standard extension. */
- p = subset_list->parse_multiletter_ext (p, "x", "non-standard extension");
+ while (p && *p)
+ {
+ switch (*p)
+ {
+ case '_':
+ ++p;
+ continue;
+ case 'e':
+ case 'i':
+ case 'g':
+ error_at (loc, "%<-march=%s%>: i, e or g must be the first extension",
+ arch);
+ goto fail;
+ default:
+ p = subset_list->parse_single_ext (p, /*exact_single_p=*/ false);
+ }
+ }
if (p == NULL)
goto fail;
- if (*p != '\0')
- {
- error_at (loc, "%<-march=%s%>: unexpected ISA string at end: %qs",
- arch, p);
- goto fail;
- }
-
for (itr = subset_list->m_head; itr != NULL; itr = itr->next)
{
subset_list->handle_implied_ext (itr->name.c_str ());
diff --git a/gcc/config/riscv/riscv-subset.h b/gcc/config/riscv/riscv-subset.h
index c8117d8..a80f913 100644
--- a/gcc/config/riscv/riscv-subset.h
+++ b/gcc/config/riscv/riscv-subset.h
@@ -71,12 +71,12 @@ private:
const char *parse_std_ext (const char *);
- const char *parse_single_std_ext (const char *);
+ const char *parse_single_std_ext (const char *, bool);
const char *parse_multiletter_ext (const char *, const char *,
const char *);
const char *parse_single_multiletter_ext (const char *, const char *,
- const char *);
+ const char *, bool);
void handle_implied_ext (const char *);
bool check_implied_ext ();
@@ -101,7 +101,7 @@ public:
riscv_subset_list *clone () const;
static riscv_subset_list *parse (const char *, location_t);
- const char *parse_single_ext (const char *);
+ const char *parse_single_ext (const char *, bool exact_single_p = true);
const riscv_subset_t *begin () const {return m_head;};
const riscv_subset_t *end () const {return NULL;};
diff --git a/gcc/testsuite/gcc.target/riscv/arch-33.c b/gcc/testsuite/gcc.target/riscv/arch-33.c
new file mode 100644
index 0000000..3fac928
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/arch-33.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64i_zba____zbs_mac_d -mabi=lp64d" } */
+int foo()
+{
+}
diff --git a/gcc/testsuite/gcc.target/riscv/arch-34.c b/gcc/testsuite/gcc.target/riscv/arch-34.c
new file mode 100644
index 0000000..9b9f1a7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/arch-34.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64i_xtheadbs_zba_fcd -mabi=lp64d" } */
+int foo()
+{
+}