RISC-V: Implement RISC-V profile macro support
Checks
| Context |
Check |
Description |
| rivoscibot/toolchain-ci-rivos-apply-patch |
success
|
Patch applied
|
| rivoscibot/toolchain-ci-rivos-lint |
success
|
Lint passed
|
| rivoscibot/toolchain-ci-rivos-build--newlib-rv64gcv-lp64d-multilib |
success
|
Build passed
|
| rivoscibot/toolchain-ci-rivos-build--linux-rv64gc_zba_zbb_zbc_zbs-lp64d-multilib |
success
|
Build passed
|
| rivoscibot/toolchain-ci-rivos-build--linux-rv64gcv-lp64d-multilib |
success
|
Build passed
|
| rivoscibot/toolchain-ci-rivos-test |
success
|
Testing passed
|
Commit Message
From: Zhongyao Chen <chen.zhongyao@zte.com.cn>
users can now write code like the following to adapt to the
current RISC-V profile selected at compile time:
```c
#ifdef __riscv_rva23u64
// Code specific to the rva23u64 profile
#endif
```
gcc/
* common/config/riscv/riscv-common.cc (riscv_subset_list::get_profile_name):
New function.
* config/riscv/riscv-c.cc (riscv_cpu_cpp_builtins): Define
profile macro if a profile is detected.
* config/riscv/riscv-subset.h (riscv_subset_list::get_profile_name): Declare.
Signed-off-by: Zhongyao Chen <chen.zhongyao@zte.com.cn>
---
gcc/common/config/riscv/riscv-common.cc | 40 +++++++++++++++++++++++++
gcc/config/riscv/riscv-c.cc | 9 ++++++
gcc/config/riscv/riscv-subset.h | 2 ++
3 files changed, 51 insertions(+)
Comments
need add testcases
Zhongyao Chen <chenzhongyao.hit@gmail.com>於 2025年9月11日 週四,20:10寫道:
> From: Zhongyao Chen <chen.zhongyao@zte.com.cn>
>
> users can now write code like the following to adapt to the
> current RISC-V profile selected at compile time:
>
> ```c
> #ifdef __riscv_rva23u64
> // Code specific to the rva23u64 profile
> #endif
> ```
>
> gcc/
> * common/config/riscv/riscv-common.cc
> (riscv_subset_list::get_profile_name):
> New function.
> * config/riscv/riscv-c.cc (riscv_cpu_cpp_builtins): Define
> profile macro if a profile is detected.
> * config/riscv/riscv-subset.h
> (riscv_subset_list::get_profile_name): Declare.
>
> Signed-off-by: Zhongyao Chen <chen.zhongyao@zte.com.cn>
> ---
> gcc/common/config/riscv/riscv-common.cc | 40 +++++++++++++++++++++++++
> gcc/config/riscv/riscv-c.cc | 9 ++++++
> gcc/config/riscv/riscv-subset.h | 2 ++
> 3 files changed, 51 insertions(+)
>
> diff --git a/gcc/common/config/riscv/riscv-common.cc
> b/gcc/common/config/riscv/riscv-common.cc
> index a165506f4..e7536edab 100644
> --- a/gcc/common/config/riscv/riscv-common.cc
> +++ b/gcc/common/config/riscv/riscv-common.cc
> @@ -1450,6 +1450,46 @@ fail:
> return NULL;
> }
>
> +/* Get profile name from the subset_list. */
> +
> +const char *
> +riscv_subset_list::get_profile_name () const
> +{
> + const char *best_profile = NULL;
> + int max_ext_count = -1;
> +
> + for (int i = 0; riscv_profiles_table[i].profile_name != nullptr; ++i)
> + {
> + riscv_subset_list *subset_list = riscv_subset_list::parse (
> + riscv_profiles_table[i].profile_string, NULL);
> + if (!subset_list)
> + continue;
> + if (subset_list->xlen () == this->xlen ())
> + {
> + int ext_count = 0;
> + bool all_found = true;
> + for (riscv_subset_t *p = subset_list->m_head; p != NULL;
> + p = p->next, ++ext_count)
> + {
> + if (!this->lookup (p->name.c_str (),
> + p->major_version,
> + p->minor_version))
> + {
> + all_found = false;
> + break;
> + }
> + }
> + if (all_found && ext_count > max_ext_count)
> + {
> + max_ext_count = ext_count;
> + best_profile = riscv_profiles_table[i].profile_name;
> + }
> + }
> + delete subset_list;
> + }
> + return best_profile;
> +}
> +
> /* Clone whole subset list. */
>
> riscv_subset_list *
> diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc
> index 4fc052817..d497326e0 100644
> --- a/gcc/config/riscv/riscv-c.cc
> +++ b/gcc/config/riscv/riscv-c.cc
> @@ -165,6 +165,15 @@ riscv_cpu_cpp_builtins (cpp_reader *pfile)
> if (!subset_list)
> return;
>
> + /* Define profile macro if a profile was used. */
> + const char *profile_name = subset_list->get_profile_name ();
> + if (profile_name)
> + {
> + char *profile_macro = (char *)alloca (strlen (profile_name) + 10);
> + sprintf (profile_macro, "__riscv_%s", profile_name);
> + builtin_define (profile_macro);
> + }
> +
> size_t max_ext_len = 0;
>
> /* Figure out the max length of extension name for reserving buffer.
> */
> diff --git a/gcc/config/riscv/riscv-subset.h
> b/gcc/config/riscv/riscv-subset.h
> index 4cd860fee..1887ed7cc 100644
> --- a/gcc/config/riscv/riscv-subset.h
> +++ b/gcc/config/riscv/riscv-subset.h
> @@ -105,6 +105,8 @@ public:
>
> unsigned xlen () const {return m_xlen;};
>
> + const char *get_profile_name () const;
> +
> riscv_subset_list *clone () const;
>
> static riscv_subset_list *parse (const char *, location_t *);
> --
> 2.43.0
>
>
@@ -1450,6 +1450,46 @@ fail:
return NULL;
}
+/* Get profile name from the subset_list. */
+
+const char *
+riscv_subset_list::get_profile_name () const
+{
+ const char *best_profile = NULL;
+ int max_ext_count = -1;
+
+ for (int i = 0; riscv_profiles_table[i].profile_name != nullptr; ++i)
+ {
+ riscv_subset_list *subset_list = riscv_subset_list::parse (
+ riscv_profiles_table[i].profile_string, NULL);
+ if (!subset_list)
+ continue;
+ if (subset_list->xlen () == this->xlen ())
+ {
+ int ext_count = 0;
+ bool all_found = true;
+ for (riscv_subset_t *p = subset_list->m_head; p != NULL;
+ p = p->next, ++ext_count)
+ {
+ if (!this->lookup (p->name.c_str (),
+ p->major_version,
+ p->minor_version))
+ {
+ all_found = false;
+ break;
+ }
+ }
+ if (all_found && ext_count > max_ext_count)
+ {
+ max_ext_count = ext_count;
+ best_profile = riscv_profiles_table[i].profile_name;
+ }
+ }
+ delete subset_list;
+ }
+ return best_profile;
+}
+
/* Clone whole subset list. */
riscv_subset_list *
@@ -165,6 +165,15 @@ riscv_cpu_cpp_builtins (cpp_reader *pfile)
if (!subset_list)
return;
+ /* Define profile macro if a profile was used. */
+ const char *profile_name = subset_list->get_profile_name ();
+ if (profile_name)
+ {
+ char *profile_macro = (char *)alloca (strlen (profile_name) + 10);
+ sprintf (profile_macro, "__riscv_%s", profile_name);
+ builtin_define (profile_macro);
+ }
+
size_t max_ext_len = 0;
/* Figure out the max length of extension name for reserving buffer. */
@@ -105,6 +105,8 @@ public:
unsigned xlen () const {return m_xlen;};
+ const char *get_profile_name () const;
+
riscv_subset_list *clone () const;
static riscv_subset_list *parse (const char *, location_t *);