From 83c25f27c442ce567829491fc1b4703f51b9bea6 Mon Sep 17 00:00:00 2001 From: Kito Cheng Date: Mon, 29 Jun 2020 17:52:42 +0800 Subject: [PATCH] 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. --- gcc/common/config/riscv/riscv-common.c | 70 ++++++++++++------- gcc/testsuite/gcc.target/riscv/attribute-13.c | 6 ++ 2 files changed, 52 insertions(+), 24 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/attribute-13.c diff --git a/gcc/common/config/riscv/riscv-common.c b/gcc/common/config/riscv/riscv-common.c index 2df93460165..82c5154b611 100644 --- a/gcc/common/config/riscv/riscv-common.c +++ b/gcc/common/config/riscv/riscv-common.c @@ -42,6 +42,8 @@ struct riscv_subset_t int major_version; int minor_version; struct riscv_subset_t *next; + + bool explicit_version_p; }; /* Type for implied ISA info. */ @@ -80,19 +82,19 @@ private: riscv_subset_list (const char *, location_t); 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_multiletter_ext (const char *, const char *, const char *); - void handle_implied_ext (const char *, int, int); + void handle_implied_ext (const char *, int, int, bool); public: ~riscv_subset_list (); - void add (const char *, int, int); + void add (const char *, int, int, bool); riscv_subset_t *lookup (const char *, int major_version = RISCV_DONT_CARE_VERSION, @@ -111,7 +113,8 @@ static const char *riscv_supported_std_ext (void); static riscv_subset_list *current_subset_list = NULL; 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 () void 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 (); @@ -148,6 +151,7 @@ riscv_subset_list::add (const char *subset, int major_version, s->name = subset; s->major_version = major_version; s->minor_version = minor_version; + s->explicit_version_p = explicit_version_p; s->next = NULL; if (m_tail != NULL) @@ -173,13 +177,15 @@ riscv_subset_list::to_string (bool version_p) const /* For !version_p, we only separate extension with underline for multi-letter extension. */ if (!first && - (version_p || subset->name.length() > 1)) + (version_p + || subset->explicit_version_p + || subset->name.length() > 1)) oss << '_'; first = false; oss << subset->name; - if (version_p) + if (version_p || subset->explicit_version_p) oss << subset->major_version << 'p' << subset->minor_version; @@ -240,7 +246,8 @@ riscv_supported_std_ext (void) `major_version` using default_major_version. `default_major_version`: Default major 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 * 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 default_major_version, unsigned default_minor_version, - bool std_ext_p) + bool std_ext_p, + bool *explicit_version_p) { bool major_p = true; unsigned version = 0; unsigned major = 0; unsigned minor = 0; char np; + *explicit_version_p = false; for (; *p; ++p) { @@ -269,6 +278,7 @@ riscv_subset_list::parsing_subset_version (const char *p, { *major_version = version; *minor_version = 0; + *explicit_version_p = true; return p; } else @@ -302,6 +312,7 @@ riscv_subset_list::parsing_subset_version (const char *p, } else { + *explicit_version_p = true; *major_version = major; *minor_version = minor; } @@ -325,6 +336,7 @@ riscv_subset_list::parse_std_ext (const char *p) unsigned major_version = 0; unsigned minor_version = 0; char std_ext = '\0'; + bool explicit_version_p = false; /* First letter must start with i, e or g. */ switch (*p) @@ -334,8 +346,9 @@ riscv_subset_list::parse_std_ext (const char *p) p = parsing_subset_version (p, &major_version, &minor_version, /* default_major_version= */ 2, /* default_minor_version= */ 0, - /* std_ext_p= */ true); - add ("i", major_version, minor_version); + /* std_ext_p= */ true, + &explicit_version_p); + add ("i", major_version, minor_version, explicit_version_p); break; case 'e': @@ -343,9 +356,10 @@ riscv_subset_list::parse_std_ext (const char *p) p = parsing_subset_version (p, &major_version, &minor_version, /* default_major_version= */ 1, /* 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) { @@ -360,13 +374,14 @@ riscv_subset_list::parse_std_ext (const char *p) p = parsing_subset_version (p, &major_version, &minor_version, /* default_major_version= */ 2, /* default_minor_version= */ 0, - /* std_ext_p= */ true); - add ("i", major_version, minor_version); + /* std_ext_p= */ true, + &explicit_version_p); + add ("i", major_version, minor_version, explicit_version_p); for (; *std_exts != 'q'; std_exts++) { const char subset[] = {*std_exts, '\0'}; - add (subset, major_version, minor_version); + add (subset, major_version, minor_version, explicit_version_p); } break; @@ -413,24 +428,28 @@ riscv_subset_list::parse_std_ext (const char *p) p = parsing_subset_version (p, &major_version, &minor_version, /* default_major_version= */ 2, /* default_minor_version= */ 0, - /* std_ext_p= */ true); + /* std_ext_p= */ true, + &explicit_version_p); 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; } /* 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 riscv_subset_list::handle_implied_ext (const char *ext, int major_version, - int minor_version) + int minor_version, + bool explicit_version_p) { riscv_implied_info_t *implied_info; for (implied_info = &riscv_implied_info[0]; @@ -445,7 +464,8 @@ riscv_subset_list::handle_implied_ext (const char *ext, continue; /* 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, char *subset = xstrdup (p); char *q = subset; const char *end_of_version; + bool explicit_version_p = false; while (*++q != '\0' && *q != '_' && !ISDIGIT (*q)) ; @@ -490,11 +511,12 @@ riscv_subset_list::parse_multiletter_ext (const char *p, = parsing_subset_version (q, &major_version, &minor_version, /* default_major_version= */ 2, /* default_minor_version= */ 0, - /* std_ext_p= */ FALSE); + /* std_ext_p= */ FALSE, + &explicit_version_p); *q = '\0'; - add (subset, major_version, minor_version); + add (subset, major_version, minor_version, explicit_version_p); free (subset); p += end_of_version - subset; diff --git a/gcc/testsuite/gcc.target/riscv/attribute-13.c b/gcc/testsuite/gcc.target/riscv/attribute-13.c new file mode 100644 index 00000000000..1e860013293 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/attribute-13.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-O -mriscv-attribute -march=rv32if3d -mabi=ilp32" } */ +int foo() +{ +} +/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p0_f3p0_d2p0\"" } } */ -- 2.30.2