Commit e0a6deae by Kito Cheng

RISC-V: Preserve arch version info during normalizing arch string

- Arch version should preserved if user explicitly specified the version.
  e.g.
    After normalize, -march=rv32if3d should be -march=rv32i_f3p0d
    instead of-march=rv32ifd.

gcc/ChangeLog:

	* common/config/riscv/riscv-common.c (riscv_subset_t): New field
	added.
	(riscv_subset_list::parsing_subset_version): Add parameter for
	indicate explicitly version, and handle explicitly version.
	(riscv_subset_list::handle_implied_ext): Ditto.
	(riscv_subset_list::add): Ditto.
	(riscv_subset_t::riscv_subset_t): Init new field.
	(riscv_subset_list::to_string): Always output version info if version
	explicitly specified.
	(riscv_subset_list::parsing_subset_version): Handle explicitly
	arch version.
	(riscv_subset_list::parse_std_ext): Ditto.
	(riscv_subset_list::parse_multiletter_ext): Ditto.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/attribute-13.c: New.
parent 02f99327
...@@ -42,6 +42,8 @@ struct riscv_subset_t ...@@ -42,6 +42,8 @@ struct riscv_subset_t
int major_version; int major_version;
int minor_version; int minor_version;
struct riscv_subset_t *next; struct riscv_subset_t *next;
bool explicit_version_p;
}; };
/* Type for implied ISA info. */ /* Type for implied ISA info. */
...@@ -80,19 +82,19 @@ private: ...@@ -80,19 +82,19 @@ private:
riscv_subset_list (const char *, location_t); riscv_subset_list (const char *, location_t);
const char *parsing_subset_version (const char *, unsigned *, unsigned *, const char *parsing_subset_version (const char *, unsigned *, unsigned *,
unsigned, unsigned, bool); unsigned, unsigned, bool, bool *);
const char *parse_std_ext (const char *); const char *parse_std_ext (const char *);
const char *parse_multiletter_ext (const char *, const char *, const char *parse_multiletter_ext (const char *, const char *,
const char *); const char *);
void handle_implied_ext (const char *, int, int); void handle_implied_ext (const char *, int, int, bool);
public: public:
~riscv_subset_list (); ~riscv_subset_list ();
void add (const char *, int, int); void add (const char *, int, int, bool);
riscv_subset_t *lookup (const char *, riscv_subset_t *lookup (const char *,
int major_version = RISCV_DONT_CARE_VERSION, int major_version = RISCV_DONT_CARE_VERSION,
...@@ -111,7 +113,8 @@ static const char *riscv_supported_std_ext (void); ...@@ -111,7 +113,8 @@ static const char *riscv_supported_std_ext (void);
static riscv_subset_list *current_subset_list = NULL; static riscv_subset_list *current_subset_list = NULL;
riscv_subset_t::riscv_subset_t () riscv_subset_t::riscv_subset_t ()
: name (), major_version (0), minor_version (0), next (NULL) : name (), major_version (0), minor_version (0), next (NULL),
explicit_version_p (false)
{ {
} }
...@@ -138,7 +141,7 @@ riscv_subset_list::~riscv_subset_list () ...@@ -138,7 +141,7 @@ riscv_subset_list::~riscv_subset_list ()
void void
riscv_subset_list::add (const char *subset, int major_version, riscv_subset_list::add (const char *subset, int major_version,
int minor_version) int minor_version, bool explicit_version_p)
{ {
riscv_subset_t *s = new riscv_subset_t (); riscv_subset_t *s = new riscv_subset_t ();
...@@ -148,6 +151,7 @@ riscv_subset_list::add (const char *subset, int major_version, ...@@ -148,6 +151,7 @@ riscv_subset_list::add (const char *subset, int major_version,
s->name = subset; s->name = subset;
s->major_version = major_version; s->major_version = major_version;
s->minor_version = minor_version; s->minor_version = minor_version;
s->explicit_version_p = explicit_version_p;
s->next = NULL; s->next = NULL;
if (m_tail != NULL) if (m_tail != NULL)
...@@ -173,13 +177,15 @@ riscv_subset_list::to_string (bool version_p) const ...@@ -173,13 +177,15 @@ riscv_subset_list::to_string (bool version_p) const
/* For !version_p, we only separate extension with underline for /* For !version_p, we only separate extension with underline for
multi-letter extension. */ multi-letter extension. */
if (!first && if (!first &&
(version_p || subset->name.length() > 1)) (version_p
|| subset->explicit_version_p
|| subset->name.length() > 1))
oss << '_'; oss << '_';
first = false; first = false;
oss << subset->name; oss << subset->name;
if (version_p) if (version_p || subset->explicit_version_p)
oss << subset->major_version oss << subset->major_version
<< 'p' << 'p'
<< subset->minor_version; << subset->minor_version;
...@@ -240,7 +246,8 @@ riscv_supported_std_ext (void) ...@@ -240,7 +246,8 @@ riscv_supported_std_ext (void)
`major_version` using default_major_version. `major_version` using default_major_version.
`default_major_version`: Default major version. `default_major_version`: Default major version.
`default_minor_version`: Default minor version. `default_minor_version`: Default minor version.
`std_ext_p`: True if parsing std extension. */ `std_ext_p`: True if parsing std extension.
`explicit_version_p`: True if this subset is not using default version. */
const char * const char *
riscv_subset_list::parsing_subset_version (const char *p, riscv_subset_list::parsing_subset_version (const char *p,
...@@ -248,13 +255,15 @@ riscv_subset_list::parsing_subset_version (const char *p, ...@@ -248,13 +255,15 @@ riscv_subset_list::parsing_subset_version (const char *p,
unsigned *minor_version, unsigned *minor_version,
unsigned default_major_version, unsigned default_major_version,
unsigned default_minor_version, unsigned default_minor_version,
bool std_ext_p) bool std_ext_p,
bool *explicit_version_p)
{ {
bool major_p = true; bool major_p = true;
unsigned version = 0; unsigned version = 0;
unsigned major = 0; unsigned major = 0;
unsigned minor = 0; unsigned minor = 0;
char np; char np;
*explicit_version_p = false;
for (; *p; ++p) for (; *p; ++p)
{ {
...@@ -269,6 +278,7 @@ riscv_subset_list::parsing_subset_version (const char *p, ...@@ -269,6 +278,7 @@ riscv_subset_list::parsing_subset_version (const char *p,
{ {
*major_version = version; *major_version = version;
*minor_version = 0; *minor_version = 0;
*explicit_version_p = true;
return p; return p;
} }
else else
...@@ -302,6 +312,7 @@ riscv_subset_list::parsing_subset_version (const char *p, ...@@ -302,6 +312,7 @@ riscv_subset_list::parsing_subset_version (const char *p,
} }
else else
{ {
*explicit_version_p = true;
*major_version = major; *major_version = major;
*minor_version = minor; *minor_version = minor;
} }
...@@ -325,6 +336,7 @@ riscv_subset_list::parse_std_ext (const char *p) ...@@ -325,6 +336,7 @@ riscv_subset_list::parse_std_ext (const char *p)
unsigned major_version = 0; unsigned major_version = 0;
unsigned minor_version = 0; unsigned minor_version = 0;
char std_ext = '\0'; char std_ext = '\0';
bool explicit_version_p = false;
/* First letter must start with i, e or g. */ /* First letter must start with i, e or g. */
switch (*p) switch (*p)
...@@ -334,8 +346,9 @@ riscv_subset_list::parse_std_ext (const char *p) ...@@ -334,8 +346,9 @@ riscv_subset_list::parse_std_ext (const char *p)
p = parsing_subset_version (p, &major_version, &minor_version, p = parsing_subset_version (p, &major_version, &minor_version,
/* default_major_version= */ 2, /* default_major_version= */ 2,
/* default_minor_version= */ 0, /* default_minor_version= */ 0,
/* std_ext_p= */ true); /* std_ext_p= */ true,
add ("i", major_version, minor_version); &explicit_version_p);
add ("i", major_version, minor_version, explicit_version_p);
break; break;
case 'e': case 'e':
...@@ -343,9 +356,10 @@ riscv_subset_list::parse_std_ext (const char *p) ...@@ -343,9 +356,10 @@ riscv_subset_list::parse_std_ext (const char *p)
p = parsing_subset_version (p, &major_version, &minor_version, p = parsing_subset_version (p, &major_version, &minor_version,
/* default_major_version= */ 1, /* default_major_version= */ 1,
/* default_minor_version= */ 9, /* default_minor_version= */ 9,
/* std_ext_p= */ true); /* std_ext_p= */ true,
&explicit_version_p);
add ("e", major_version, minor_version); add ("e", major_version, minor_version, explicit_version_p);
if (m_xlen > 32) if (m_xlen > 32)
{ {
...@@ -360,13 +374,14 @@ riscv_subset_list::parse_std_ext (const char *p) ...@@ -360,13 +374,14 @@ riscv_subset_list::parse_std_ext (const char *p)
p = parsing_subset_version (p, &major_version, &minor_version, p = parsing_subset_version (p, &major_version, &minor_version,
/* default_major_version= */ 2, /* default_major_version= */ 2,
/* default_minor_version= */ 0, /* default_minor_version= */ 0,
/* std_ext_p= */ true); /* std_ext_p= */ true,
add ("i", major_version, minor_version); &explicit_version_p);
add ("i", major_version, minor_version, explicit_version_p);
for (; *std_exts != 'q'; std_exts++) for (; *std_exts != 'q'; std_exts++)
{ {
const char subset[] = {*std_exts, '\0'}; const char subset[] = {*std_exts, '\0'};
add (subset, major_version, minor_version); add (subset, major_version, minor_version, explicit_version_p);
} }
break; break;
...@@ -413,24 +428,28 @@ riscv_subset_list::parse_std_ext (const char *p) ...@@ -413,24 +428,28 @@ riscv_subset_list::parse_std_ext (const char *p)
p = parsing_subset_version (p, &major_version, &minor_version, p = parsing_subset_version (p, &major_version, &minor_version,
/* default_major_version= */ 2, /* default_major_version= */ 2,
/* default_minor_version= */ 0, /* default_minor_version= */ 0,
/* std_ext_p= */ true); /* std_ext_p= */ true,
&explicit_version_p);
subset[0] = std_ext; subset[0] = std_ext;
handle_implied_ext (subset, major_version, minor_version); handle_implied_ext (subset, major_version,
minor_version, explicit_version_p);
add (subset, major_version, minor_version); add (subset, major_version, minor_version, explicit_version_p);
} }
return p; return p;
} }
/* Check any implied extensions for EXT with version /* Check any implied extensions for EXT with version
MAJOR_VERSION.MINOR_VERSION. */ MAJOR_VERSION.MINOR_VERSION, EXPLICIT_VERSION_P indicate the version is
explicitly given by user or not. */
void void
riscv_subset_list::handle_implied_ext (const char *ext, riscv_subset_list::handle_implied_ext (const char *ext,
int major_version, int major_version,
int minor_version) int minor_version,
bool explicit_version_p)
{ {
riscv_implied_info_t *implied_info; riscv_implied_info_t *implied_info;
for (implied_info = &riscv_implied_info[0]; for (implied_info = &riscv_implied_info[0];
...@@ -445,7 +464,8 @@ riscv_subset_list::handle_implied_ext (const char *ext, ...@@ -445,7 +464,8 @@ riscv_subset_list::handle_implied_ext (const char *ext,
continue; continue;
/* TODO: Implied extension might use different version. */ /* TODO: Implied extension might use different version. */
add (implied_info->implied_ext, major_version, minor_version); add (implied_info->implied_ext, major_version, minor_version,
explicit_version_p);
} }
} }
...@@ -482,6 +502,7 @@ riscv_subset_list::parse_multiletter_ext (const char *p, ...@@ -482,6 +502,7 @@ riscv_subset_list::parse_multiletter_ext (const char *p,
char *subset = xstrdup (p); char *subset = xstrdup (p);
char *q = subset; char *q = subset;
const char *end_of_version; const char *end_of_version;
bool explicit_version_p = false;
while (*++q != '\0' && *q != '_' && !ISDIGIT (*q)) while (*++q != '\0' && *q != '_' && !ISDIGIT (*q))
; ;
...@@ -490,11 +511,12 @@ riscv_subset_list::parse_multiletter_ext (const char *p, ...@@ -490,11 +511,12 @@ riscv_subset_list::parse_multiletter_ext (const char *p,
= parsing_subset_version (q, &major_version, &minor_version, = parsing_subset_version (q, &major_version, &minor_version,
/* default_major_version= */ 2, /* default_major_version= */ 2,
/* default_minor_version= */ 0, /* default_minor_version= */ 0,
/* std_ext_p= */ FALSE); /* std_ext_p= */ FALSE,
&explicit_version_p);
*q = '\0'; *q = '\0';
add (subset, major_version, minor_version); add (subset, major_version, minor_version, explicit_version_p);
free (subset); free (subset);
p += end_of_version - subset; p += end_of_version - subset;
......
/* { dg-do compile } */
/* { dg-options "-O -mriscv-attribute -march=rv32if3d -mabi=ilp32" } */
int foo()
{
}
/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p0_f3p0_d2p0\"" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment