From: Kito Cheng <kito.cheng@sifive.com>
To: gcc-patches@gcc.gnu.org, kito.cheng@gmail.com,
palmer@dabbelt.com, jeffreyalaw@gmail.com,
rdapp@ventanamicro.com, juzhe.zhong@rivai.ai
Cc: Kito Cheng <kito.cheng@sifive.com>
Subject: [PATCH v2 3/4] RISC-V: Extend riscv_subset_list, preparatory for target attribute support
Date: Mon, 9 Oct 2023 21:13:04 -0700 [thread overview]
Message-ID: <20231010041305.9111-4-kito.cheng@sifive.com> (raw)
In-Reply-To: <20231010041305.9111-1-kito.cheng@sifive.com>
riscv_subset_list only accept a full arch string before, but we need to
parse single extension when supporting target attribute, also we may set
a riscv_subset_list directly rather than re-parsing the ISA string
again.
gcc/ChangeLog:
* config/riscv/riscv-subset.h (riscv_subset_list::parse_single_std_ext):
New.
(riscv_subset_list::parse_single_multiletter_ext): Ditto.
(riscv_subset_list::clone): Ditto.
(riscv_subset_list::parse_single_ext): Ditto.
(riscv_subset_list::set_loc): Ditto.
(riscv_set_arch_by_subset_list): Ditto.
* common/config/riscv/riscv-common.cc
(riscv_subset_list::parse_single_std_ext): New.
(riscv_subset_list::parse_single_multiletter_ext): Ditto.
(riscv_subset_list::clone): Ditto.
(riscv_subset_list::parse_single_ext): Ditto.
(riscv_subset_list::set_loc): Ditto.
(riscv_set_arch_by_subset_list): Ditto.
---
gcc/common/config/riscv/riscv-common.cc | 203 ++++++++++++++++++++++++
gcc/config/riscv/riscv-subset.h | 11 ++
2 files changed, 214 insertions(+)
diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc
index 9a0a68fe5db..25630d5923e 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -1036,6 +1036,41 @@ riscv_subset_list::parse_std_ext (const char *p)
return p;
}
+/* Parsing function for one standard extensions.
+
+ Return Value:
+ Points to the end of extensions.
+
+ Arguments:
+ `p`: Current parsing position. */
+
+const char *
+riscv_subset_list::parse_single_std_ext (const char *p)
+{
+ if (*p == 'x' || *p == 's' || *p == 'z')
+ {
+ error_at (m_loc,
+ "%<-march=%s%>: Not single-letter extension. "
+ "%<%c%>",
+ m_arch, *p);
+ return nullptr;
+ }
+
+ unsigned major_version = 0;
+ unsigned minor_version = 0;
+ bool explicit_version_p = false;
+ char subset[2] = {0, 0};
+
+ subset[0] = *p;
+
+ p++;
+
+ p = parsing_subset_version (subset, p, &major_version, &minor_version,
+ /* std_ext_p= */ true, &explicit_version_p);
+
+ add (subset, major_version, minor_version, explicit_version_p, false);
+ return p;
+}
/* Check any implied extensions for EXT. */
void
@@ -1138,6 +1173,102 @@ riscv_subset_list::handle_combine_ext ()
}
}
+/* Parsing function for multi-letter extensions.
+
+ Return Value:
+ Points to the end of extensions.
+
+ Arguments:
+ `p`: Current parsing position.
+ `ext_type`: What kind of extensions, 's', 'z' or 'x'.
+ `ext_type_str`: Full name for kind of extension. */
+
+
+const char *
+riscv_subset_list::parse_single_multiletter_ext (const char *p,
+ const char *ext_type,
+ const char *ext_type_str)
+{
+ unsigned major_version = 0;
+ unsigned minor_version = 0;
+ size_t ext_type_len = strlen (ext_type);
+
+ if (strncmp (p, ext_type, ext_type_len) != 0)
+ return NULL;
+
+ char *subset = xstrdup (p);
+ const char *end_of_version;
+ bool explicit_version_p = false;
+ char *ext;
+ char backup;
+ size_t len = strlen (p);
+ size_t end_of_version_pos, i;
+ bool found_any_number = false;
+ bool found_minor_version = false;
+
+ end_of_version_pos = len;
+ /* Find the begin of version string. */
+ for (i = len -1; i > 0; --i)
+ {
+ if (ISDIGIT (subset[i]))
+ {
+ found_any_number = true;
+ continue;
+ }
+ /* Might be version seperator, but need to check one more char,
+ we only allow <major>p<minor>, so we could stop parsing if found
+ any more `p`. */
+ if (subset[i] == 'p' &&
+ !found_minor_version &&
+ found_any_number && ISDIGIT (subset[i-1]))
+ {
+ found_minor_version = true;
+ continue;
+ }
+
+ end_of_version_pos = i + 1;
+ break;
+ }
+
+ backup = subset[end_of_version_pos];
+ subset[end_of_version_pos] = '\0';
+ ext = xstrdup (subset);
+ subset[end_of_version_pos] = backup;
+
+ end_of_version
+ = parsing_subset_version (ext, subset + end_of_version_pos, &major_version,
+ &minor_version, /* std_ext_p= */ false,
+ &explicit_version_p);
+ free (ext);
+
+ if (end_of_version == NULL)
+ return NULL;
+
+ subset[end_of_version_pos] = '\0';
+
+ if (strlen (subset) == 1)
+ {
+ error_at (m_loc, "%<-march=%s%>: name of %s must be more than 1 letter",
+ m_arch, ext_type_str);
+ free (subset);
+ return NULL;
+ }
+
+ add (subset, major_version, minor_version, explicit_version_p, false);
+ p += end_of_version - subset;
+ free (subset);
+
+ if (*p != '\0' && *p != '_')
+ {
+ error_at (m_loc, "%<-march=%s%>: %s must separate with %<_%>",
+ m_arch, ext_type_str);
+ return NULL;
+ }
+
+ return p;
+
+}
+
/* Parsing function for multi-letter extensions.
Return Value:
@@ -1250,6 +1381,30 @@ riscv_subset_list::parse_multiletter_ext (const char *p,
return p;
}
+/* Parsing function for a single-letter or multi-letter extensions.
+
+ Return Value:
+ Points to the end of extensions.
+
+ Arguments:
+ `p`: Current parsing position. */
+
+const char *
+riscv_subset_list::parse_single_ext (const char *p)
+{
+ switch (p[0])
+ {
+ case 'x':
+ return parse_single_multiletter_ext (p, "x", "non-standard extension");
+ case 'z':
+ return parse_single_multiletter_ext (p, "z", "sub-extension");
+ case 's':
+ return parse_single_multiletter_ext (p, "s", "supervisor extension");
+ default:
+ return parse_single_std_ext (p);
+ }
+}
+
/* Parsing arch string to subset list, return NULL if parsing failed. */
riscv_subset_list *
@@ -1342,6 +1497,26 @@ fail:
return NULL;
}
+/* Clone whole subset list. */
+
+riscv_subset_list *
+riscv_subset_list::clone () const
+{
+ riscv_subset_list *new_list = new riscv_subset_list (m_arch, m_loc);
+ for (riscv_subset_t *itr = m_head; itr != NULL; itr = itr->next)
+ new_list->add (itr->name.c_str (), itr->major_version, itr->minor_version,
+ itr->explicit_version_p, true);
+
+ new_list->m_xlen = m_xlen;
+ return new_list;
+}
+
+void
+riscv_subset_list::set_loc (location_t loc)
+{
+ m_loc = loc;
+}
+
/* Return the current arch string. */
std::string
@@ -1498,6 +1673,34 @@ static const riscv_ext_flag_table_t riscv_ext_flag_table[] =
{NULL, NULL, 0}
};
+void
+riscv_set_arch_by_subset_list (riscv_subset_list *subset_list,
+ struct gcc_options *opts)
+{
+ if (opts)
+ {
+ const riscv_ext_flag_table_t *arch_ext_flag_tab;
+ /* Clean up target flags before we set. */
+ for (arch_ext_flag_tab = &riscv_ext_flag_table[0]; arch_ext_flag_tab->ext;
+ ++arch_ext_flag_tab)
+ opts->*arch_ext_flag_tab->var_ref &= ~arch_ext_flag_tab->mask;
+
+ if (subset_list->xlen () == 32)
+ opts->x_target_flags &= ~MASK_64BIT;
+ else if (subset_list->xlen () == 64)
+ opts->x_target_flags |= MASK_64BIT;
+
+ for (arch_ext_flag_tab = &riscv_ext_flag_table[0]; arch_ext_flag_tab->ext;
+ ++arch_ext_flag_tab)
+ {
+ if (subset_list->lookup (arch_ext_flag_tab->ext))
+ opts->*arch_ext_flag_tab->var_ref |= arch_ext_flag_tab->mask;
+ }
+ }
+
+ current_subset_list = subset_list;
+}
+
/* Parse a RISC-V ISA string into an option mask. Must clear or set all arch
dependent mask bits, in case more than one -march string is passed. */
diff --git a/gcc/config/riscv/riscv-subset.h b/gcc/config/riscv/riscv-subset.h
index dca07284efa..d2a4bd20530 100644
--- a/gcc/config/riscv/riscv-subset.h
+++ b/gcc/config/riscv/riscv-subset.h
@@ -69,8 +69,12 @@ private:
const char *parse_std_ext (const char *);
+ const char *parse_single_std_ext (const char *);
+
const char *parse_multiletter_ext (const char *, const char *,
const char *);
+ const char *parse_single_multiletter_ext (const char *, const char *,
+ const char *);
void handle_implied_ext (const char *);
bool check_implied_ext ();
@@ -91,14 +95,21 @@ public:
unsigned xlen () const {return m_xlen;};
+ riscv_subset_list *clone () const;
+
static riscv_subset_list *parse (const char *, location_t);
+ const char *parse_single_ext (const char *);
const riscv_subset_t *begin () const {return m_head;};
const riscv_subset_t *end () const {return NULL;};
int match_score (riscv_subset_list *) const;
+
+ void set_loc (location_t);
};
extern const riscv_subset_list *riscv_current_subset_list (void);
+extern void
+riscv_set_arch_by_subset_list (riscv_subset_list *, struct gcc_options *);
#endif /* ! GCC_RISCV_SUBSET_H */
--
2.34.1
next prev parent reply other threads:[~2023-10-10 4:13 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-10 4:13 [PATCH v2 0/4] RISC-V target attribute Kito Cheng
2023-10-10 4:13 ` [PATCH v2 1/4] options: Define TARGET_<NAME>_P and TARGET_<NAME>_OPTS_P macro for Mask and InverseMask Kito Cheng
2023-10-10 13:50 ` Jeff Law
2023-10-11 21:20 ` Kito Cheng
2023-10-11 22:49 ` 钟居哲
2023-10-11 22:50 ` Kito Cheng
2023-10-11 23:23 ` Kito Cheng
2023-10-10 4:13 ` [PATCH v2 2/4] RISC-V: Refactor riscv_option_override and riscv_convert_vector_bits. [NFC] Kito Cheng
2023-10-10 13:51 ` Jeff Law
2023-10-11 21:21 ` Kito Cheng
2023-10-10 4:13 ` Kito Cheng [this message]
2023-10-10 14:00 ` [PATCH v2 3/4] RISC-V: Extend riscv_subset_list, preparatory for target attribute support Jeff Law
2023-10-11 21:19 ` Kito Cheng
2023-10-10 4:13 ` [PATCH v2 4/4] RISC-V: Implement target attribute Kito Cheng
2023-10-10 15:24 ` Jeff Law
2023-10-11 21:29 ` Kito Cheng
2023-10-10 9:56 ` [PATCH v2 0/4] RISC-V " juzhe.zhong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231010041305.9111-4-kito.cheng@sifive.com \
--to=kito.cheng@sifive.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=jeffreyalaw@gmail.com \
--cc=juzhe.zhong@rivai.ai \
--cc=kito.cheng@gmail.com \
--cc=palmer@dabbelt.com \
--cc=rdapp@ventanamicro.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).