]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PATCH v3] RISC-V: Implement RISC-V profile macro support
authorZhongyao Chen <chenzhongyao.hit@gmail.com>
Tue, 14 Oct 2025 02:55:40 +0000 (20:55 -0600)
committerJeff Law <jlaw@ventanamicro.com>
Tue, 14 Oct 2025 02:56:07 +0000 (20:56 -0600)
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
```

Changes from v2:
- clarify get_profile_name comment

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.

gcc/testsuite/
* gcc.target/riscv/predef-profiles-1.c: New test for __riscv_rvi20u64.
* gcc.target/riscv/predef-profiles-2.c: New test for __riscv_rvi20u32.
* gcc.target/riscv/predef-profiles-3.c: New test for __riscv_rva20u64.
* gcc.target/riscv/predef-profiles-4.c: New test for __riscv_rva22u64.
* gcc.target/riscv/predef-profiles-5.c: New test for __riscv_rva23u64.
* gcc.target/riscv/predef-profiles-6.c: New test for __riscv_rva23s64.
* gcc.target/riscv/predef-profiles-7.c: New test for __riscv_rvb23u64.
* gcc.target/riscv/predef-profiles-8.c: New test for __riscv_rvb23s64.

gcc/common/config/riscv/riscv-common.cc
gcc/config/riscv/riscv-c.cc
gcc/config/riscv/riscv-subset.h
gcc/testsuite/gcc.target/riscv/predef-profiles-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/predef-profiles-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/predef-profiles-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/predef-profiles-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/predef-profiles-5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/predef-profiles-6.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/predef-profiles-7.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/predef-profiles-8.c [new file with mode: 0644]

index efa2a45a6404de217e15542f0f5bfd343257e669..adfd22019a92f444de0091cd46f9c563ec2c3017 100644 (file)
@@ -1404,6 +1404,47 @@ fail:
   return NULL;
 }
 
+/* Get the profile that best matches the current architecture string,
+   where best is defined as the most expansive profile.  */
+
+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 *
index 4fc05281782458495103aa923b235b0898ac3431..d497326e06118f656487afd7f2ebb980209dc155 100644 (file)
@@ -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.   */
index 4cd860fee59bd7b48514d8dacbed23a855880f38..1887ed7cc1c33933d1bbf9b16eb2e3724e389f3d 100644 (file)
@@ -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 *);
diff --git a/gcc/testsuite/gcc.target/riscv/predef-profiles-1.c b/gcc/testsuite/gcc.target/riscv/predef-profiles-1.c
new file mode 100644 (file)
index 0000000..5fc17ab
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rvi20u64 -mabi=lp64" } */
+
+int main () {
+
+#ifndef __riscv_rvi20u64
+#error "__riscv_rvi20u64"
+#endif
+
+  return 0;
+}
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/predef-profiles-2.c b/gcc/testsuite/gcc.target/riscv/predef-profiles-2.c
new file mode 100644 (file)
index 0000000..86f2771
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rvi20u32 -mabi=ilp32" } */
+
+int main () {
+
+#ifndef __riscv_rvi20u32
+#error "__riscv_rvi20u32"
+#endif
+
+  return 0;
+}
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/predef-profiles-3.c b/gcc/testsuite/gcc.target/riscv/predef-profiles-3.c
new file mode 100644 (file)
index 0000000..7787549
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rva20u64 -mabi=lp64d" } */
+
+int main () {
+
+#ifndef __riscv_rva20u64
+#error "__riscv_rva20u64"
+#endif
+
+  return 0;
+}
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/predef-profiles-4.c b/gcc/testsuite/gcc.target/riscv/predef-profiles-4.c
new file mode 100644 (file)
index 0000000..abb20b7
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rva22u64 -mabi=lp64d" } */
+
+int main () {
+
+#ifndef __riscv_rva22u64
+#error "__riscv_rva22u64"
+#endif
+
+  return 0;
+}
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/predef-profiles-5.c b/gcc/testsuite/gcc.target/riscv/predef-profiles-5.c
new file mode 100644 (file)
index 0000000..0840cdc
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rva23u64 -mabi=lp64d" } */
+
+int main () {
+
+#ifndef __riscv_rva23u64
+#error "__riscv_rva23u64"
+#endif
+
+  return 0;
+}
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/predef-profiles-6.c b/gcc/testsuite/gcc.target/riscv/predef-profiles-6.c
new file mode 100644 (file)
index 0000000..7159780
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rva23s64 -mabi=lp64d" } */
+
+int main () {
+
+#ifndef __riscv_rva23s64
+#error "__riscv_rva23s64"
+#endif
+
+  return 0;
+}
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/predef-profiles-7.c b/gcc/testsuite/gcc.target/riscv/predef-profiles-7.c
new file mode 100644 (file)
index 0000000..1366159
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rvb23u64 -mabi=lp64d" } */
+
+int main () {
+
+#ifndef __riscv_rvb23u64
+#error "__riscv_rvb23u64"
+#endif
+
+  return 0;
+}
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/predef-profiles-8.c b/gcc/testsuite/gcc.target/riscv/predef-profiles-8.c
new file mode 100644 (file)
index 0000000..c0c5003
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rvb23s64 -mabi=lp64d" } */
+
+int main () {
+
+#ifndef __riscv_rvb23s64
+#error "__riscv_rvb23s64"
+#endif
+
+  return 0;
+}
\ No newline at end of file