From 337f91f990070b6a3251550c682fec5ffcce478c Mon Sep 17 00:00:00 2001
From: Alex Fan <alex.fan.q@gmail.com>
Date: Fri, 29 Jul 2022 12:44:14 +1000
Subject: [PATCH] llvmpipe: add riscv support in orcjit

assume cpu supports extension +i,+m,+a,+f,+d,+c
---
 .../auxiliary/gallivm/lp_bld_init_orc.cpp     | 58 ++++++++++++++++++-
 src/util/detect_arch.h                        | 16 +++++
 2 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init_orc.cpp b/src/gallium/auxiliary/gallivm/lp_bld_init_orc.cpp
index b245edc5586..eaacebd65d6 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_init_orc.cpp
+++ b/src/gallium/auxiliary/gallivm/lp_bld_init_orc.cpp
@@ -48,7 +48,7 @@
 /* conflict with ObjectLinkingLayer.h */
 #include "util/u_memory.h"
 
-#if (defined(_WIN32) && LLVM_VERSION_MAJOR >= 15)
+#if DETECT_ARCH_RISCV64 || DETECT_ARCH_RISCV32 || (defined(_WIN32) && LLVM_VERSION_MAJOR >= 15)
 /* use ObjectLinkingLayer (JITLINK backend) */
 #define USE_JITLINK
 #endif
@@ -521,6 +521,30 @@ llvm::orc::JITTargetMachineBuilder LPJit::create_jtdb() {
    options.StackAlignmentOverride = 4;
 #endif
 
+#if DETECT_ARCH_RISCV64
+#if defined(__riscv_float_abi_soft)
+   options.MCOptions.ABIName = "lp64";
+#elif defined(__riscv_float_abi_single)
+   options.MCOptions.ABIName = "lp64f";
+#elif defined(__riscv_float_abi_double)
+   options.MCOptions.ABIName = "lp64d";
+#else
+#error "GALLIVM: unknown target riscv float abi"
+#endif
+#endif
+
+#if DETECT_ARCH_RISCV32
+#if defined(__riscv_float_abi_soft)
+   options.MCOptions.ABIName = "ilp32";
+#elif defined(__riscv_float_abi_single)
+   options.MCOptions.ABIName = "ilp32f";
+#elif defined(__riscv_float_abi_double)
+   options.MCOptions.ABIName = "ilp32d";
+#else
+#error "GALLIVM: unknown target riscv float abi"
+#endif
+#endif
+
    JTMB.setOptions(options);
 
    std::vector<std::string> MAttrs;
@@ -619,6 +643,14 @@ llvm::orc::JITTargetMachineBuilder LPJit::create_jtdb() {
    MAttrs.push_back("+fp64");
 #endif
 
+#if DETECT_ARCH_RISCV64
+   /* Before riscv is more matured and util_get_cpu_caps() is implemented,
+    * assume this for now since most of linux capable riscv machine are
+    * riscv64gc
+    */
+   MAttrs = {"+m","+c","+a","+d","+f"};
+#endif
+
    JTMB.addFeatures(MAttrs);
 
    if (gallivm_debug & (GALLIVM_DEBUG_IR | GALLIVM_DEBUG_ASM | GALLIVM_DEBUG_DUMP_BC)) {
@@ -686,6 +718,30 @@ llvm::orc::JITTargetMachineBuilder LPJit::create_jtdb() {
       MCPU = util_get_cpu_caps()->has_msa ? "mips64r5" : "mips64r2";
 #endif
 
+#if DETECT_ARCH_RISCV64
+   /**
+    * should be fixed with https://reviews.llvm.org/D121149 in llvm 15,
+    * set it anyway for llvm 14
+    */
+   if (MCPU == "generic")
+      MCPU = "generic-rv64";
+
+   JTMB.setCodeModel(CodeModel::Medium);
+   JTMB.setRelocationModel(Reloc::PIC_);
+#endif
+
+#if DETECT_ARCH_RISCV32
+   /**
+    * should be fixed with https://reviews.llvm.org/D121149 in llvm 15,
+    * set it anyway for llvm 14
+    */
+   if (MCPU == "generic")
+      MCPU = "generic-rv32";
+
+   JTMB.setCodeModel(CodeModel::Medium);
+   JTMB.setRelocationModel(Reloc::PIC_);
+#endif
+
    JTMB.setCPU(MCPU);
    if (gallivm_debug & (GALLIVM_DEBUG_IR | GALLIVM_DEBUG_ASM | GALLIVM_DEBUG_DUMP_BC)) {
       debug_printf("llc -mcpu option: %s\n", MCPU.c_str());
diff --git a/src/util/detect_arch.h b/src/util/detect_arch.h
index 334358fcc26..34c0928216d 100644
--- a/src/util/detect_arch.h
+++ b/src/util/detect_arch.h
@@ -97,6 +97,14 @@
 #define DETECT_ARCH_MIPS 1
 #endif
 
+#if defined(__riscv)
+#if __riscv_xlen == 64
+#define DETECT_ARCH_RISCV64 1
+#elif __riscv_xlen == 32
+#define DETECT_ARCH_RISCV32 1
+#endif
+#endif
+
 #ifndef DETECT_ARCH_X86
 #define DETECT_ARCH_X86 0
 #endif
@@ -137,4 +145,12 @@
 #define DETECT_ARCH_MIPS 0
 #endif
 
+#ifndef DETECT_ARCH_RISCV32
+#define DETECT_ARCH_RISCV32 0
+#endif
+
+#ifndef DETECT_ARCH_RISCV64
+#define DETECT_ARCH_RISCV64 0
+#endif
+
 #endif /* UTIL_DETECT_ARCH_H_ */
-- 
2.41.0

