[clang] [llvm] Add clang driver changes to support MTI RISC-V (PR #134065)

Djordje Todorovic via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 3 07:58:34 PDT 2025


https://github.com/djtodoro updated https://github.com/llvm/llvm-project/pull/134065

>From 513b1ae05ed6049586a23acab6c0a2f7dbb48454 Mon Sep 17 00:00:00 2001
From: Djordje Todorovic <djordje.todorovic at htecgroup.com>
Date: Wed, 26 Mar 2025 09:24:29 +0100
Subject: [PATCH 1/3] [clang][RISCV] Set default CPU for  vendor

---
 clang/lib/Driver/ToolChains/Arch/RISCV.cpp |  4 ++++
 llvm/lib/Target/RISCV/RISCVSubtarget.cpp   | 13 +++++++++++--
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
index 1c5b5ff5e5b40..d3cc889178d2c 100644
--- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
@@ -365,5 +365,9 @@ std::string riscv::getRISCVTargetCPU(const llvm::opt::ArgList &Args,
   if (!CPU.empty())
     return CPU;
 
+  if (Triple.getVendor() == llvm::Triple::MipsTechnologies &&
+      Triple.isRISCV64())
+    return "p8700";
+
   return Triple.isRISCV64() ? "generic-rv64" : "generic-rv32";
 }
diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp
index 3c996c82fcec4..30aa8c267b484 100644
--- a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp
+++ b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp
@@ -79,8 +79,17 @@ RISCVSubtarget::initializeSubtargetDependencies(const Triple &TT, StringRef CPU,
                                                 StringRef ABIName) {
   // Determine default and user-specified characteristics
   bool Is64Bit = TT.isArch64Bit();
-  if (CPU.empty() || CPU == "generic")
-    CPU = Is64Bit ? "generic-rv64" : "generic-rv32";
+  if (CPU.empty() || CPU == "generic") {
+    if (Is64Bit) {
+      if (TT.getVendor() == llvm::Triple::MipsTechnologies) {
+        CPU = "p8700";
+      } else {
+        CPU = "generic-rv64";
+      }
+    } else {
+      CPU = "generic-rv32";
+    }
+  }
 
   if (TuneCPU.empty())
     TuneCPU = CPU;

>From 8c1ca6afe3b57619ec65640dd6f0f7364bea15cc Mon Sep 17 00:00:00 2001
From: Djordje Todorovic <djordje.todorovic at htecgroup.com>
Date: Wed, 26 Mar 2025 09:26:57 +0100
Subject: [PATCH 2/3] [clang] Add driver support for riscv64-mti toolchains

---
 clang/lib/Driver/ToolChains/Arch/RISCV.cpp    |  6 ++-
 clang/lib/Driver/ToolChains/Gnu.cpp           | 40 +++++++++++++++++--
 clang/lib/Driver/ToolChains/Linux.cpp         | 25 ++++++++++--
 .../lib/Driver/ToolChains/RISCVToolchain.cpp  |  4 ++
 4 files changed, 67 insertions(+), 8 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
index d3cc889178d2c..679387240aa3b 100644
--- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
@@ -337,12 +337,14 @@ std::string riscv::getRISCVArch(const llvm::opt::ArgList &Args,
   // - On `riscv{XLEN}-unknown-elf` we default to `rv{XLEN}imac`
   // - On all other OSs we use `rv{XLEN}imafdc` (equivalent to `rv{XLEN}gc`)
   if (Triple.isRISCV32()) {
-    if (Triple.getOS() == llvm::Triple::UnknownOS)
+    if (Triple.getOS() == llvm::Triple::UnknownOS &&
+        Triple.getVendor() != llvm::Triple::MipsTechnologies)
       return "rv32imac";
     return "rv32imafdc";
   }
 
-  if (Triple.getOS() == llvm::Triple::UnknownOS)
+  if (Triple.getOS() == llvm::Triple::UnknownOS &&
+      Triple.getVendor() != llvm::Triple::MipsTechnologies)
     return "rv64imac";
   if (Triple.isAndroid())
     return "rv64imafdcv_zba_zbb_zbs";
diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp
index a0fa3c66d7dec..5a9e66e975fdc 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -402,6 +402,11 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
     CmdArgs.push_back(Arch == llvm::Triple::aarch64_be ? "-EB" : "-EL");
   }
 
+  if (Triple.isRISCV() &&
+      Triple.getVendor() == llvm::Triple::MipsTechnologies) {
+    CmdArgs.push_back("-EL");
+  }
+
   // Most Android ARM64 targets should enable the linker fix for erratum
   // 843419. Only non-Cortex-A53 devices are allowed to skip this flag.
   if (Arch == llvm::Triple::aarch64 && (isAndroid || isOHOSFamily)) {
@@ -765,7 +770,8 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C,
   }
   case llvm::Triple::riscv32:
   case llvm::Triple::riscv64: {
-    StringRef ABIName = riscv::getRISCVABI(Args, getToolChain().getTriple());
+    const llvm::Triple &Triple = getToolChain().getTriple();
+    StringRef ABIName = riscv::getRISCVABI(Args, Triple);
     CmdArgs.push_back("-mabi");
     CmdArgs.push_back(ABIName.data());
     std::string MArchName =
@@ -774,6 +780,10 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C,
     CmdArgs.push_back(Args.MakeArgString(MArchName));
     if (!Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax, true))
       Args.addOptOutFlag(CmdArgs, options::OPT_mrelax, options::OPT_mno_relax);
+
+    if (Triple.getVendor() == llvm::Triple::MipsTechnologies)
+      CmdArgs.push_back("-EL");
+
     break;
   }
   case llvm::Triple::sparc:
@@ -1824,9 +1834,19 @@ static void findRISCVBareMetalMultilibs(const Driver &D,
             .flag(Twine("-march=", Element.march).str())
             .flag(Twine("-mabi=", Element.mabi).str()));
   }
+  SmallVector<MultilibBuilder, 2> Endian;
+  bool IsMIPS = TargetTriple.getVendor() == llvm::Triple::MipsTechnologies;
+  if (IsMIPS) {
+    Endian.push_back(
+        MultilibBuilder("/riscv").flag("-EL").flag("-EB", /*Disallow=*/true));
+    Endian.push_back(
+        MultilibBuilder("/riscveb").flag("-EB").flag("-EL", /*Disallow=*/true));
+  }
   MultilibSet RISCVMultilibs =
       MultilibSetBuilder()
           .Either(Ms)
+          .Either(Endian)
+          .Either(ArrayRef<MultilibBuilder>(Ms))
           .makeMultilibSet()
           .FilterOut(NonExistent)
           .setFilePathsCallback([](const Multilib &M) {
@@ -1850,6 +1870,8 @@ static void findRISCVBareMetalMultilibs(const Driver &D,
     }
   }
 
+  addMultilibFlag(IsMIPS, "-EL", Flags);
+
   if (selectRISCVMultilib(D, RISCVMultilibs, MArch, Flags,
                           Result.SelectedMultilibs))
     Result.Multilibs = RISCVMultilibs;
@@ -1874,8 +1896,18 @@ static void findRISCVMultilibs(const Driver &D,
       MultilibBuilder("lib64/lp64f").flag("-m64").flag("-mabi=lp64f");
   MultilibBuilder Lp64d =
       MultilibBuilder("lib64/lp64d").flag("-m64").flag("-mabi=lp64d");
+
+  SmallVector<MultilibBuilder, 2> Endian;
+  if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies) {
+    Endian.push_back(
+        MultilibBuilder("/riscv").flag("-EL").flag("-EB", /*Disallow=*/true));
+    Endian.push_back(
+        MultilibBuilder("/riscveb").flag("-EB").flag("-EL", /*Disallow=*/true));
+  }
+
   MultilibSet RISCVMultilibs =
       MultilibSetBuilder()
+          .Either(Endian)
           .Either({Ilp32, Ilp32f, Ilp32d, Lp64, Lp64f, Lp64d})
           .makeMultilibSet()
           .FilterOut(NonExistent);
@@ -1883,6 +1915,7 @@ static void findRISCVMultilibs(const Driver &D,
   Multilib::flags_list Flags;
   bool IsRV64 = TargetTriple.getArch() == llvm::Triple::riscv64;
   StringRef ABIName = tools::riscv::getRISCVABI(Args, TargetTriple);
+  bool IsMIPS = TargetTriple.getVendor() == llvm::Triple::MipsTechnologies;
 
   addMultilibFlag(!IsRV64, "-m32", Flags);
   addMultilibFlag(IsRV64, "-m64", Flags);
@@ -1892,6 +1925,7 @@ static void findRISCVMultilibs(const Driver &D,
   addMultilibFlag(ABIName == "lp64", "-mabi=lp64", Flags);
   addMultilibFlag(ABIName == "lp64f", "-mabi=lp64f", Flags);
   addMultilibFlag(ABIName == "lp64d", "-mabi=lp64d", Flags);
+  addMultilibFlag(IsMIPS, "-EL", Flags);
 
   if (RISCVMultilibs.select(D, Flags, Result.SelectedMultilibs))
     Result.Multilibs = RISCVMultilibs;
@@ -2516,8 +2550,8 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(
   static const char *const RISCV32Triples[] = {"riscv32-unknown-linux-gnu",
                                                "riscv32-unknown-elf"};
   static const char *const RISCV64LibDirs[] = {"/lib64", "/lib"};
-  static const char *const RISCV64Triples[] = {"riscv64-unknown-linux-gnu",
-                                               "riscv64-unknown-elf"};
+  static const char *const RISCV64Triples[] = {
+      "riscv64-unknown-linux-gnu", "riscv64-unknown-elf", "riscv64-mti-elf"};
 
   static const char *const SPARCv8LibDirs[] = {"/lib32", "/lib"};
   static const char *const SPARCv8Triples[] = {"sparc-linux-gnu",
diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp
index 1e9bd3de75f04..4622acf2c57e3 100644
--- a/clang/lib/Driver/ToolChains/Linux.cpp
+++ b/clang/lib/Driver/ToolChains/Linux.cpp
@@ -283,11 +283,14 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
   const bool IsHexagon = Arch == llvm::Triple::hexagon;
   const bool IsRISCV = Triple.isRISCV();
   const bool IsCSKY = Triple.isCSKY();
+  const bool IsMipsSysRoot =
+      IsMips ||
+      (IsRISCV && Triple.getVendor() == llvm::Triple::MipsTechnologies);
 
   if (IsCSKY && !SelectedMultilibs.empty())
     SysRoot = SysRoot + SelectedMultilibs.back().osSuffix();
 
-  if ((IsMips || IsCSKY) && !SysRoot.empty())
+  if ((IsMipsSysRoot || IsCSKY) && !SysRoot.empty())
     ExtraOpts.push_back("--sysroot=" + SysRoot);
 
   // Do not use 'gnu' hash style for Mips targets because .gnu.hash
@@ -414,7 +417,12 @@ std::string Linux::computeSysRoot() const {
     return std::string();
   }
 
-  if (!GCCInstallation.isValid() || !getTriple().isMIPS())
+  const bool IsMipsSysRoot =
+      getTriple().isMIPS() ||
+      (getTriple().isRISCV() &&
+       getTriple().getVendor() == llvm::Triple::MipsTechnologies);
+
+  if (!GCCInstallation.isValid() || !IsMipsSysRoot)
     return std::string();
 
   // Standalone MIPS toolchains use different names for sysroot folder
@@ -424,8 +432,19 @@ std::string Linux::computeSysRoot() const {
   const StringRef InstallDir = GCCInstallation.getInstallPath();
   const StringRef TripleStr = GCCInstallation.getTriple().str();
   const Multilib &Multilib = GCCInstallation.getMultilib();
+  std::string Path;
+  if (getTriple().isRISCV()) {
+    Path =
+        (InstallDir + "/../../../../sysroot" + Multilib.osSuffix() + "/../..")
+            .str();
+
+    if (getVFS().exists(Path))
+      return Path;
+
+    return std::string();
+  }
 
-  std::string Path =
+  Path =
       (InstallDir + "/../../../../" + TripleStr + "/libc" + Multilib.osSuffix())
           .str();
 
diff --git a/clang/lib/Driver/ToolChains/RISCVToolchain.cpp b/clang/lib/Driver/ToolChains/RISCVToolchain.cpp
index 624099d21ae12..cf26b7eef1c63 100644
--- a/clang/lib/Driver/ToolChains/RISCVToolchain.cpp
+++ b/clang/lib/Driver/ToolChains/RISCVToolchain.cpp
@@ -173,6 +173,9 @@ void RISCV::Linker::ConstructJob(Compilation &C, const JobAction &JA,
   }
   CmdArgs.push_back("-X");
 
+  if (ToolChain.getTriple().getVendor() == llvm::Triple::MipsTechnologies)
+    CmdArgs.push_back("-EL");
+
   std::string Linker = getToolChain().GetLinkerPath();
 
   bool WantCRTs =
@@ -229,4 +232,5 @@ void RISCV::Linker::ConstructJob(Compilation &C, const JobAction &JA,
       JA, *this, ResponseFileSupport::AtFileCurCP(), Args.MakeArgString(Linker),
       CmdArgs, Inputs, Output));
 }
+
 // RISCV tools end.

>From bf3b7d4ccc50370f8ab4059f9b82d93eff7e370d Mon Sep 17 00:00:00 2001
From: Djordje Todorovic <djordje.todorovic at htecgroup.com>
Date: Thu, 3 Apr 2025 16:32:31 +0200
Subject: [PATCH 3/3] followup: Add test and minor fixes

---
 clang/lib/Driver/ToolChains/Arch/RISCV.cpp |  4 +++-
 clang/test/Driver/riscv-cpus.c             | 14 ++++++++++++++
 llvm/lib/Target/RISCV/RISCVSubtarget.cpp   |  2 +-
 3 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
index 679387240aa3b..fb8b85c7ab961 100644
--- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
@@ -346,6 +346,8 @@ std::string riscv::getRISCVArch(const llvm::opt::ArgList &Args,
   if (Triple.getOS() == llvm::Triple::UnknownOS &&
       Triple.getVendor() != llvm::Triple::MipsTechnologies)
     return "rv64imac";
+  if (Triple.getVendor() == llvm::Triple::MipsTechnologies)
+    return "rv64imafdc_zba_zbb_zicsr_zifencei";
   if (Triple.isAndroid())
     return "rv64imafdcv_zba_zbb_zbs";
   if (Triple.isOSFuchsia())
@@ -369,7 +371,7 @@ std::string riscv::getRISCVTargetCPU(const llvm::opt::ArgList &Args,
 
   if (Triple.getVendor() == llvm::Triple::MipsTechnologies &&
       Triple.isRISCV64())
-    return "p8700";
+    return "mips-p8700";
 
   return Triple.isRISCV64() ? "generic-rv64" : "generic-rv32";
 }
diff --git a/clang/test/Driver/riscv-cpus.c b/clang/test/Driver/riscv-cpus.c
index e97b6940662d9..25eb1e141ac89 100644
--- a/clang/test/Driver/riscv-cpus.c
+++ b/clang/test/Driver/riscv-cpus.c
@@ -115,6 +115,20 @@
 // MCPU-MIPS-P8700-SAME: "-target-feature" "+zba"
 // MCPU-MIPS-P8700-SAME: "-target-feature" "+zbb"
 
+// RUN: %clang --target=riscv64-mti-linux-gnu -### -c %s 2>&1| FileCheck -check-prefix=MCPU-MTI-P8700 %s
+// MCPU-MTI-P8700: "-target-cpu" "mips-p8700"
+// MCPU-MTI-P8700-SAME: "-target-feature" "+m"
+// MCPU-MTI-P8700-SAME: "-target-feature" "+a"
+// MCPU-MTI-P8700-SAME: "-target-feature" "+f"
+// MCPU-MTI-P8700-SAME: "-target-feature" "+d"
+// MCPU-MTI-P8700-SAME: "-target-feature" "+c"
+// MCPU-MTI-P8700-SAME: "-target-feature" "+zicsr"
+// MCPU-MTI-P8700-SAME: "-target-feature" "+zifencei"
+// MCPU-MTI-P8700-SAME: "-target-feature" "+zaamo"
+// MCPU-MTI-P8700-SAME: "-target-feature" "+zalrsc"
+// MCPU-MTI-P8700-SAME: "-target-feature" "+zba"
+// MCPU-MTI-P8700-SAME: "-target-feature" "+zbb"
+
 // RUN: %clang --target=riscv32 -### -c %s 2>&1 -mtune=syntacore-scr1-base | FileCheck -check-prefix=MTUNE-SYNTACORE-SCR1-BASE %s
 // MTUNE-SYNTACORE-SCR1-BASE: "-tune-cpu" "syntacore-scr1-base"
 
diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp
index 30aa8c267b484..7a6026779106e 100644
--- a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp
+++ b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp
@@ -82,7 +82,7 @@ RISCVSubtarget::initializeSubtargetDependencies(const Triple &TT, StringRef CPU,
   if (CPU.empty() || CPU == "generic") {
     if (Is64Bit) {
       if (TT.getVendor() == llvm::Triple::MipsTechnologies) {
-        CPU = "p8700";
+        CPU = "mips-p8700";
       } else {
         CPU = "generic-rv64";
       }



More information about the llvm-commits mailing list