Newer
Older
minerva / Toolchain / Patches / llvm / 0006-RISCV-Implement-__init_riscv_feature_bits-for-Sereni.patch
@minerva minerva on 13 Jul 3 KB Initial commit
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=B6nke=20Holz?= <sholz8530@gmail.com>
Date: Wed, 28 May 2025 12:27:55 +0200
Subject: [PATCH] [RISCV] Implement __init_riscv_feature_bits for Minerva

The Minerva dynamic linker provides a magic function
"__get_riscv_feature_bits" that populates __riscv_feature_bits
and __riscv_cpu_model.
---
 .../clang/Basic/DiagnosticFrontendKinds.td    |  2 +-
 clang/lib/CodeGen/CodeGenFunction.cpp         |  5 +++--
 compiler-rt/lib/builtins/cpu_model/riscv.c    | 22 +++++++++++++++++--
 3 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
index f3593f5313340b4425907cb0dcc09afdba105bda..69b2472d95dc5bd19bd4e922a6402cb2017589cd 100644
--- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -380,7 +380,7 @@ def err_ast_action_on_llvm_ir : Error<
   DefaultFatal;
 
 def err_os_unsupport_riscv_fmv : Error<
-  "function multiversioning is currently only supported on Linux">;
+  "function multiversioning is currently only supported on Linux and Minerva">;
 
 def warn_hlsl_langstd_minimal :
   Warning<"support for HLSL language version %0 is incomplete, "
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 08165e0b28406a0c1f6534852629294677874ff2..f56ebdb738dd513fb72046bd6d6bac4c541632e8 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -2937,8 +2937,9 @@ void CodeGenFunction::EmitMultiVersionResolver(
 void CodeGenFunction::EmitRISCVMultiVersionResolver(
     llvm::Function *Resolver, ArrayRef<FMVResolverOption> Options) {
 
-  if (getContext().getTargetInfo().getTriple().getOS() !=
-      llvm::Triple::OSType::Linux) {
+  llvm::Triple::OSType OS = getContext().getTargetInfo().getTriple().getOS();
+  if (OS != llvm::Triple::OSType::Linux &&
+      OS != llvm::Triple::OSType::Minerva) {
     CGM.getDiags().Report(diag::err_os_unsupport_riscv_fmv);
     return;
   }
diff --git a/compiler-rt/lib/builtins/cpu_model/riscv.c b/compiler-rt/lib/builtins/cpu_model/riscv.c
index 6879c2ad482641aad783afc0b44e431c988909cd..bb5bdb3249051b6161c433e412af9f54ad8e7d6c 100644
--- a/compiler-rt/lib/builtins/cpu_model/riscv.c
+++ b/compiler-rt/lib/builtins/cpu_model/riscv.c
@@ -325,7 +325,23 @@ static void initRISCVFeature(struct riscv_hwprobe Hwprobes[]) {
     __riscv_feature_bits.features[i] = features[i];
 }
 
-#endif // defined(__linux__)
+#elif defined(__minerva__)
+
+extern void __get_riscv_feature_bits(void *, void *) __attribute__((weak));
+
+static void initRISCVFeature(void) {
+  if (__get_riscv_feature_bits) {
+    __riscv_feature_bits.length = RISCV_FEATURE_BITS_LENGTH;
+    __get_riscv_feature_bits(&__riscv_feature_bits, &__riscv_cpu_model);
+  } else {
+    __riscv_feature_bits.length = 0;
+    __riscv_cpu_model.mvendorid = 0;
+    __riscv_cpu_model.marchid = 0;
+    __riscv_cpu_model.mimpid = 0;
+  }
+}
+
+#endif
 
 static int FeaturesBitCached = 0;
 
@@ -362,7 +378,9 @@ void __init_riscv_feature_bits(void *PlatformArgs) {
     return;
 
   initRISCVFeature(Hwprobes);
-#endif // defined(__linux__)
+#elif defined(__minerva__)
+  initRISCVFeature();
+#endif
 
   FeaturesBitCached = 1;
 }