RISC-V: Implement RISC-V profile macro support

Message ID 20250911120917.8678-1-chenzhongyao.hit@gmail.com
State Superseded
Headers
Series 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

Zhongyao Chen Sept. 11, 2025, 12:09 p.m. UTC
  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

Kito Cheng Sept. 11, 2025, 1:16 p.m. UTC | #1
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
>
>
  

Patch

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 *);