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.
This commit is contained in:
parent
4e8fef35f7
commit
006ad3e7f7
4 changed files with 68 additions and 41 deletions
|
@ -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");
|
||||
|
||||
if (p == NULL)
|
||||
goto fail;
|
||||
|
||||
if (*p != '\0')
|
||||
while (p && *p)
|
||||
{
|
||||
error_at (loc, "%<-march=%s%>: unexpected ISA string at end: %qs",
|
||||
arch, p);
|
||||
goto fail;
|
||||
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;
|
||||
|
||||
for (itr = subset_list->m_head; itr != NULL; itr = itr->next)
|
||||
{
|
||||
subset_list->handle_implied_ext (itr->name.c_str ());
|
||||
|
|
|
@ -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;};
|
||||
|
|
5
gcc/testsuite/gcc.target/riscv/arch-33.c
Normal file
5
gcc/testsuite/gcc.target/riscv/arch-33.c
Normal file
|
@ -0,0 +1,5 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-march=rv64i_zba____zbs_mac_d -mabi=lp64d" } */
|
||||
int foo()
|
||||
{
|
||||
}
|
5
gcc/testsuite/gcc.target/riscv/arch-34.c
Normal file
5
gcc/testsuite/gcc.target/riscv/arch-34.c
Normal file
|
@ -0,0 +1,5 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-march=rv64i_xtheadbs_zba_fcd -mabi=lp64d" } */
|
||||
int foo()
|
||||
{
|
||||
}
|
Loading…
Add table
Reference in a new issue