[clang] [clang][RISCV] Add big-endian RISC-V target support (PR #165599)
Djordje Todorovic via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 29 10:15:29 PDT 2025
https://github.com/djtodoro created https://github.com/llvm/llvm-project/pull/165599
We proceed with frontend/clang changes, until we figure out how ABI should for BE should look like. Once it is final, we will proceed with codegen changes.
In this patch several things addressed:
- Define riscv32be/riscv64be target triples
- Set correct data layout for BE targets
- Handle BE-specific ABI details
- Emit warning for BE case since it is still experimental
>From 8656877a01466069a2b147d5a9646a52b94e7a2d Mon Sep 17 00:00:00 2001
From: Djordje Todorovic <djordje.todorovic at htecgroup.com>
Date: Mon, 9 Jun 2025 14:39:10 +0200
Subject: [PATCH] [clang][RISCV] Add big-endian RISC-V target support
Several things addressed:
- Define riscv32be/riscv64be target triples
- Set correct data layout for BE targets
- Handle BE-specific ABI details
- Emit warning for BE case since it is still experimental
---
clang/include/clang/Basic/Attr.td | 2 +-
.../clang/Basic/DiagnosticDriverKinds.td | 2 +
clang/include/clang/Basic/ObjCRuntime.h | 1 +
clang/lib/Basic/Targets.cpp | 2 +
clang/lib/Basic/Targets/OSTargets.h | 4 ++
clang/lib/Basic/Targets/RISCV.h | 16 ++++++--
clang/lib/CodeGen/CGBuiltin.cpp | 2 +
clang/lib/CodeGen/CodeGenFunction.cpp | 2 +
clang/lib/CodeGen/CodeGenModule.cpp | 4 +-
clang/lib/Driver/Driver.cpp | 26 ++++++++++--
clang/lib/Driver/ToolChain.cpp | 2 +
clang/lib/Driver/ToolChains/BareMetal.cpp | 3 +-
clang/lib/Driver/ToolChains/Clang.cpp | 9 ++++-
clang/lib/Driver/ToolChains/CommonArgs.cpp | 10 +++++
clang/lib/Driver/ToolChains/FreeBSD.cpp | 8 ++++
clang/lib/Driver/ToolChains/Gnu.cpp | 40 ++++++++++++++++---
clang/lib/Driver/ToolChains/Linux.cpp | 18 ++++++++-
clang/lib/Sema/SemaChecking.cpp | 2 +
clang/lib/Sema/SemaDeclAttr.cpp | 2 +
clang/test/CodeGen/riscv-be-data-layout.c | 12 ++++++
clang/test/Driver/riscv-be.c | 10 +++++
clang/test/Misc/warning-flags.c | 3 +-
22 files changed, 160 insertions(+), 20 deletions(-)
create mode 100644 clang/test/CodeGen/riscv-be-data-layout.c
create mode 100644 clang/test/Driver/riscv-be.c
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 3cde249e286fa..c3bed838d0538 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -476,7 +476,7 @@ def TargetMips32 : TargetArch<["mips", "mipsel"]>;
def TargetAnyMips : TargetArch<["mips", "mipsel", "mips64", "mips64el"]>;
def TargetMSP430 : TargetArch<["msp430"]>;
def TargetM68k : TargetArch<["m68k"]>;
-def TargetRISCV : TargetArch<["riscv32", "riscv64"]>;
+def TargetRISCV : TargetArch<["riscv32", "riscv64", "riscv32be", "riscv64be"]>;
def TargetX86 : TargetArch<["x86"]>;
def TargetX86_64 : TargetArch<["x86_64"]>;
def TargetAnyX86 : TargetArch<["x86", "x86_64"]>;
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 0581bf353d936..90dc69c601928 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -419,6 +419,8 @@ def warn_ignored_clang_option : Warning<"the flag '%0' has been deprecated and w
def warn_drv_unsupported_opt_for_target : Warning<
"optimization flag '%0' is not supported for target '%1'">,
InGroup<IgnoredOptimizationArgument>;
+def warn_drv_riscv_be_experimental : Warning<
+ "big-endian RISC-V target support is experimental">;
def warn_drv_unsupported_debug_info_opt_for_target : Warning<
"debug information option '%0' is not supported for target '%1'">,
InGroup<UnsupportedTargetOpt>;
diff --git a/clang/include/clang/Basic/ObjCRuntime.h b/clang/include/clang/Basic/ObjCRuntime.h
index df42b43898611..efb7c6692bfcf 100644
--- a/clang/include/clang/Basic/ObjCRuntime.h
+++ b/clang/include/clang/Basic/ObjCRuntime.h
@@ -110,6 +110,7 @@ class ObjCRuntime {
case llvm::Triple::mips64:
return !(getVersion() >= VersionTuple(1, 9));
case llvm::Triple::riscv64:
+ case llvm::Triple::riscv64be:
return !(getVersion() >= VersionTuple(2, 2));
default:
return true;
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
index b7e8bad4f404b..5c94a4693ef7a 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/lib/Basic/Targets.cpp
@@ -428,6 +428,7 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple,
return std::make_unique<AMDGPUTargetInfo>(Triple, Opts);
case llvm::Triple::riscv32:
+ case llvm::Triple::riscv32be:
switch (os) {
case llvm::Triple::NetBSD:
return std::make_unique<NetBSDTargetInfo<RISCV32TargetInfo>>(Triple,
@@ -439,6 +440,7 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple,
}
case llvm::Triple::riscv64:
+ case llvm::Triple::riscv64be:
switch (os) {
case llvm::Triple::FreeBSD:
return std::make_unique<FreeBSDTargetInfo<RISCV64TargetInfo>>(Triple,
diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h
index bd6ffcf3173ab..58783c91187d9 100644
--- a/clang/lib/Basic/Targets/OSTargets.h
+++ b/clang/lib/Basic/Targets/OSTargets.h
@@ -255,6 +255,8 @@ class LLVM_LIBRARY_VISIBILITY FreeBSDTargetInfo : public OSTargetInfo<Target> {
break;
case llvm::Triple::loongarch64:
case llvm::Triple::riscv64:
+ case llvm::Triple::riscv32be:
+ case llvm::Triple::riscv64be:
break;
}
}
@@ -513,6 +515,8 @@ class LLVM_LIBRARY_VISIBILITY OpenBSDTargetInfo : public OSTargetInfo<Target> {
break;
case llvm::Triple::loongarch64:
case llvm::Triple::riscv64:
+ case llvm::Triple::riscv32be:
+ case llvm::Triple::riscv64be:
break;
}
}
diff --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h
index d8b0e64c90dd6..b92e36d65df1f 100644
--- a/clang/lib/Basic/Targets/RISCV.h
+++ b/clang/lib/Basic/Targets/RISCV.h
@@ -175,13 +175,17 @@ class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo {
IntPtrType = SignedInt;
PtrDiffType = SignedInt;
SizeType = UnsignedInt;
- resetDataLayout("e-m:e-p:32:32-i64:64-n32-S128");
+ resetDataLayout((Twine(Triple.isLittleEndian() ? "e" : "E") +
+ "-m:e-p:32:32-i64:64-n32-S128")
+ .str());
}
bool setABI(const std::string &Name) override {
if (Name == "ilp32e") {
ABI = Name;
- resetDataLayout("e-m:e-p:32:32-i64:64-n32-S32");
+ resetDataLayout((Twine(getTriple().isLittleEndian() ? "e" : "E") +
+ "-m:e-p:32:32-i64:64-n32-S32")
+ .str());
return true;
}
@@ -205,13 +209,17 @@ class LLVM_LIBRARY_VISIBILITY RISCV64TargetInfo : public RISCVTargetInfo {
: RISCVTargetInfo(Triple, Opts) {
LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
IntMaxType = Int64Type = SignedLong;
- resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n32:64-S128");
+ resetDataLayout((Twine(Triple.isLittleEndian() ? "e" : "E") +
+ "-m:e-p:64:64-i64:64-i128:128-n32:64-S128")
+ .str());
}
bool setABI(const std::string &Name) override {
if (Name == "lp64e") {
ABI = Name;
- resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n32:64-S64");
+ resetDataLayout((Twine(getTriple().isLittleEndian() ? "e" : "E") +
+ "-m:e-p:64:64-i64:64-i128:128-n32:64-S64")
+ .str());
return true;
}
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 9ee810c9d5775..c72ed5f33b92c 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -121,6 +121,8 @@ static Value *EmitTargetArchBuiltinExpr(CodeGenFunction *CGF,
return CGF->EmitHexagonBuiltinExpr(BuiltinID, E);
case llvm::Triple::riscv32:
case llvm::Triple::riscv64:
+ case llvm::Triple::riscv32be:
+ case llvm::Triple::riscv64be:
return CGF->EmitRISCVBuiltinExpr(BuiltinID, E, ReturnValue);
case llvm::Triple::spirv32:
case llvm::Triple::spirv64:
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 88628530cf66b..aaf90826d17c2 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -2989,6 +2989,8 @@ void CodeGenFunction::EmitMultiVersionResolver(
return;
case llvm::Triple::riscv32:
case llvm::Triple::riscv64:
+ case llvm::Triple::riscv32be:
+ case llvm::Triple::riscv64be:
EmitRISCVMultiVersionResolver(Resolver, Options);
return;
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 8d019d4b2da25..f2708bd119f69 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -223,7 +223,9 @@ createTargetCodeGenInfo(CodeGenModule &CGM) {
return createMSP430TargetCodeGenInfo(CGM);
case llvm::Triple::riscv32:
- case llvm::Triple::riscv64: {
+ case llvm::Triple::riscv64:
+ case llvm::Triple::riscv32be:
+ case llvm::Triple::riscv64be: {
StringRef ABIStr = Target.getABI();
unsigned XLen = Target.getPointerWidth(LangAS::Default);
unsigned ABIFLen = 0;
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 40ea513e85427..1785abced4023 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -822,14 +822,30 @@ static llvm::Triple computeTargetTriple(const Driver &D,
ArchName, /*EnableExperimentalExtensions=*/true);
if (!llvm::errorToBool(ISAInfo.takeError())) {
unsigned XLen = (*ISAInfo)->getXLen();
- if (XLen == 32)
- Target.setArch(llvm::Triple::riscv32);
- else if (XLen == 64)
- Target.setArch(llvm::Triple::riscv64);
+ if (XLen == 32) {
+ if (Target.isLittleEndian())
+ Target.setArch(llvm::Triple::riscv32);
+ else
+ Target.setArch(llvm::Triple::riscv32be);
+ } else if (XLen == 64) {
+ if (Target.isLittleEndian())
+ Target.setArch(llvm::Triple::riscv64);
+ else
+ Target.setArch(llvm::Triple::riscv64be);
+ }
}
}
}
+ if (Target.getArch() == llvm::Triple::riscv32be ||
+ Target.getArch() == llvm::Triple::riscv64be) {
+ static bool WarnedRISCVBE = false;
+ if (!WarnedRISCVBE) {
+ D.Diag(diag::warn_drv_riscv_be_experimental);
+ WarnedRISCVBE = true;
+ }
+ }
+
return Target;
}
@@ -6957,6 +6973,8 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
break;
case llvm::Triple::riscv32:
case llvm::Triple::riscv64:
+ case llvm::Triple::riscv32be:
+ case llvm::Triple::riscv64be:
TC = std::make_unique<toolchains::BareMetal>(*this, Target, Args);
break;
case llvm::Triple::ve:
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 3d5cac62afe01..21b1ab65ffcef 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -370,6 +370,8 @@ ToolChain::getMultilibFlags(const llvm::opt::ArgList &Args) const {
break;
case llvm::Triple::riscv32:
case llvm::Triple::riscv64:
+ case llvm::Triple::riscv32be:
+ case llvm::Triple::riscv64be:
getRISCVMultilibFlags(D, Triple, Args, Result);
break;
default:
diff --git a/clang/lib/Driver/ToolChains/BareMetal.cpp b/clang/lib/Driver/ToolChains/BareMetal.cpp
index 9b7f58c392885..f1de107534299 100644
--- a/clang/lib/Driver/ToolChains/BareMetal.cpp
+++ b/clang/lib/Driver/ToolChains/BareMetal.cpp
@@ -714,7 +714,8 @@ SanitizerMask BareMetal::getSupportedSanitizers() const {
const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
const bool IsAArch64 = getTriple().getArch() == llvm::Triple::aarch64 ||
getTriple().getArch() == llvm::Triple::aarch64_be;
- const bool IsRISCV64 = getTriple().getArch() == llvm::Triple::riscv64;
+ const bool IsRISCV64 = getTriple().getArch() == llvm::Triple::riscv64 ||
+ getTriple().getArch() == llvm::Triple::riscv64be;
SanitizerMask Res = ToolChain::getSupportedSanitizers();
Res |= SanitizerKind::Address;
Res |= SanitizerKind::KernelAddress;
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index bf755739760c0..5d8448dacc171 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -1195,6 +1195,8 @@ static bool isSignedCharDefault(const llvm::Triple &Triple) {
case llvm::Triple::ppc64le:
case llvm::Triple::riscv32:
case llvm::Triple::riscv64:
+ case llvm::Triple::riscv32be:
+ case llvm::Triple::riscv64be:
case llvm::Triple::systemz:
case llvm::Triple::xcore:
case llvm::Triple::xtensa:
@@ -1593,6 +1595,8 @@ void Clang::RenderTargetOptions(const llvm::Triple &EffectiveTriple,
case llvm::Triple::riscv32:
case llvm::Triple::riscv64:
+ case llvm::Triple::riscv32be:
+ case llvm::Triple::riscv64be:
AddRISCVTargetArgs(Args, CmdArgs);
break;
@@ -5644,7 +5648,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
} else if (Name == "SLEEF" || Name == "ArmPL") {
if (Triple.getArch() != llvm::Triple::aarch64 &&
Triple.getArch() != llvm::Triple::aarch64_be &&
- Triple.getArch() != llvm::Triple::riscv64)
+ Triple.getArch() != llvm::Triple::riscv64 &&
+ Triple.getArch() != llvm::Triple::riscv64be)
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< Name << Triple.getArchName();
}
@@ -8718,6 +8723,8 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
case llvm::Triple::riscv32:
case llvm::Triple::riscv64:
+ case llvm::Triple::riscv32be:
+ case llvm::Triple::riscv64be:
AddRISCVTargetArgs(Args, CmdArgs);
break;
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 99400ac701fbe..42d7f883550dd 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -90,6 +90,8 @@ static bool useFramePointerForTargetByDefault(const llvm::opt::ArgList &Args,
case llvm::Triple::ppc64le:
case llvm::Triple::riscv32:
case llvm::Triple::riscv64:
+ case llvm::Triple::riscv32be:
+ case llvm::Triple::riscv64be:
case llvm::Triple::sparc:
case llvm::Triple::sparcel:
case llvm::Triple::sparcv9:
@@ -590,6 +592,10 @@ const char *tools::getLDMOption(const llvm::Triple &T, const ArgList &Args) {
return "elf32lriscv";
case llvm::Triple::riscv64:
return "elf64lriscv";
+ case llvm::Triple::riscv32be:
+ return "elf32briscv";
+ case llvm::Triple::riscv64be:
+ return "elf64briscv";
case llvm::Triple::sparc:
case llvm::Triple::sparcel:
return "elf32_sparc";
@@ -767,6 +773,8 @@ std::string tools::getCPUName(const Driver &D, const ArgList &Args,
return "ck810";
case llvm::Triple::riscv32:
case llvm::Triple::riscv64:
+ case llvm::Triple::riscv32be:
+ case llvm::Triple::riscv64be:
return riscv::getRISCVTargetCPU(Args, T);
case llvm::Triple::bpfel:
@@ -848,6 +856,8 @@ void tools::getTargetFeatures(const Driver &D, const llvm::Triple &Triple,
break;
case llvm::Triple::riscv32:
case llvm::Triple::riscv64:
+ case llvm::Triple::riscv32be:
+ case llvm::Triple::riscv64be:
riscv::getRISCVTargetFeatures(D, Triple, Args, Features);
break;
case llvm::Triple::systemz:
diff --git a/clang/lib/Driver/ToolChains/FreeBSD.cpp b/clang/lib/Driver/ToolChains/FreeBSD.cpp
index b17b76233ad30..02ca676e02735 100644
--- a/clang/lib/Driver/ToolChains/FreeBSD.cpp
+++ b/clang/lib/Driver/ToolChains/FreeBSD.cpp
@@ -212,6 +212,14 @@ void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-m");
CmdArgs.push_back("elf64lriscv");
break;
+ case llvm::Triple::riscv32be:
+ CmdArgs.push_back("-m");
+ CmdArgs.push_back("elf32briscv");
+ break;
+ case llvm::Triple::riscv64be:
+ CmdArgs.push_back("-m");
+ CmdArgs.push_back("elf64briscv");
+ break;
case llvm::Triple::loongarch64:
CmdArgs.push_back("-m");
CmdArgs.push_back("elf64loongarch");
diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp
index 7616076847a2c..b1e6b91640261 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -672,7 +672,9 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C,
break;
}
case llvm::Triple::riscv32:
- case llvm::Triple::riscv64: {
+ case llvm::Triple::riscv64:
+ case llvm::Triple::riscv32be:
+ case llvm::Triple::riscv64be: {
StringRef ABIName = riscv::getRISCVABI(Args, getToolChain().getTriple());
CmdArgs.push_back("-mabi");
CmdArgs.push_back(ABIName.data());
@@ -1732,16 +1734,20 @@ static void findRISCVBareMetalMultilibs(const Driver &D,
.flag(Twine("-march=", Element.march).str())
.flag(Twine("-mabi=", Element.mabi).str()));
}
+
+ std::string EndiannessSuffix = TargetTriple.isLittleEndian() ? "" : "be";
MultilibSet RISCVMultilibs =
MultilibSetBuilder()
.Either(Ms)
.makeMultilibSet()
.FilterOut(NonExistent)
- .setFilePathsCallback([](const Multilib &M) {
+ .setFilePathsCallback([EndiannessSuffix](const Multilib &M) {
return std::vector<std::string>(
{M.gccSuffix(),
- "/../../../../riscv64-unknown-elf/lib" + M.gccSuffix(),
- "/../../../../riscv32-unknown-elf/lib" + M.gccSuffix()});
+ "/../../../../riscv64" + EndiannessSuffix +
+ "-unknown-elf/lib" + M.gccSuffix(),
+ "/../../../../riscv32" + EndiannessSuffix +
+ "-unknown-elf/lib" + M.gccSuffix()});
});
Multilib::flags_list Flags;
@@ -1789,7 +1795,8 @@ static void findRISCVMultilibs(const Driver &D,
.FilterOut(NonExistent);
Multilib::flags_list Flags;
- bool IsRV64 = TargetTriple.getArch() == llvm::Triple::riscv64;
+ bool IsRV64 = (TargetTriple.getArch() == llvm::Triple::riscv64 ||
+ TargetTriple.getArch() == llvm::Triple::riscv64be);
StringRef ABIName = tools::riscv::getRISCVABI(Args, TargetTriple);
addMultilibFlag(!IsRV64, "-m32", Flags);
@@ -2431,6 +2438,15 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(
static const char *const RISCV64Triples[] = {"riscv64-unknown-linux-gnu",
"riscv64-unknown-elf"};
+ static const char *const RISCV32beLibDirs[] = {"/lib32", "/lib"};
+ static const char *const RISCV32beTriples[] = {"riscv32be-unknown-linux-gnu",
+ "riscv32be-linux-gnu",
+ "riscv32be-unknown-elf"};
+ static const char *const RISCV64beLibDirs[] = {"/lib64", "/lib"};
+ static const char *const RISCV64beTriples[] = {"riscv64be-unknown-linux-gnu",
+ "riscv64be-linux-gnu",
+ "riscv64be-unknown-elf"};
+
static const char *const SPARCv8LibDirs[] = {"/lib32", "/lib"};
static const char *const SPARCv8Triples[] = {"sparc-linux-gnu",
"sparcv8-linux-gnu"};
@@ -2723,6 +2739,18 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(
BiarchLibDirs.append(begin(RISCV32LibDirs), end(RISCV32LibDirs));
BiarchTripleAliases.append(begin(RISCV32Triples), end(RISCV32Triples));
break;
+ case llvm::Triple::riscv32be:
+ LibDirs.append(begin(RISCV32beLibDirs), end(RISCV32beLibDirs));
+ TripleAliases.append(begin(RISCV32beTriples), end(RISCV32beTriples));
+ BiarchLibDirs.append(begin(RISCV64beLibDirs), end(RISCV64beLibDirs));
+ BiarchTripleAliases.append(begin(RISCV64beTriples), end(RISCV64beTriples));
+ break;
+ case llvm::Triple::riscv64be:
+ LibDirs.append(begin(RISCV64beLibDirs), end(RISCV64beLibDirs));
+ TripleAliases.append(begin(RISCV64beTriples), end(RISCV64beTriples));
+ BiarchLibDirs.append(begin(RISCV32beLibDirs), end(RISCV32beLibDirs));
+ BiarchTripleAliases.append(begin(RISCV32beTriples), end(RISCV32beTriples));
+ break;
case llvm::Triple::sparc:
case llvm::Triple::sparcel:
LibDirs.append(begin(SPARCv8LibDirs), end(SPARCv8LibDirs));
@@ -3038,6 +3066,8 @@ Generic_GCC::getDefaultUnwindTableLevel(const ArgList &Args) const {
case llvm::Triple::ppc64le:
case llvm::Triple::riscv32:
case llvm::Triple::riscv64:
+ case llvm::Triple::riscv32be:
+ case llvm::Triple::riscv64be:
case llvm::Triple::x86:
case llvm::Triple::x86_64:
return UnwindTableLevel::Asynchronous;
diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp
index 8eb4d34e0827a..f4145e0c3aef9 100644
--- a/clang/lib/Driver/ToolChains/Linux.cpp
+++ b/clang/lib/Driver/ToolChains/Linux.cpp
@@ -203,7 +203,8 @@ static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) {
if (Triple.getArch() == llvm::Triple::x86_64 && Triple.isX32())
return "libx32";
- if (Triple.getArch() == llvm::Triple::riscv32)
+ if (Triple.getArch() == llvm::Triple::riscv32 ||
+ Triple.getArch() == llvm::Triple::riscv32be)
return "lib32";
return Triple.isArch32Bit() ? "lib" : "lib64";
@@ -590,6 +591,18 @@ std::string Linux::getDynamicLinker(const ArgList &Args) const {
Loader = ("ld-linux-" + ArchName + "-" + ABIName + ".so.1").str();
break;
}
+ case llvm::Triple::riscv32be: {
+ StringRef ABIName = tools::riscv::getRISCVABI(Args, Triple);
+ LibDir = "lib";
+ Loader = ("ld-linux-riscv32be-" + ABIName + ".so.1").str();
+ break;
+ }
+ case llvm::Triple::riscv64be: {
+ StringRef ABIName = tools::riscv::getRISCVABI(Args, Triple);
+ LibDir = "lib";
+ Loader = ("ld-linux-riscv64be-" + ABIName + ".so.1").str();
+ break;
+ }
case llvm::Triple::sparc:
case llvm::Triple::sparcel:
LibDir = "lib";
@@ -804,7 +817,8 @@ SanitizerMask Linux::getSupportedSanitizers() const {
getTriple().getArch() == llvm::Triple::armeb ||
getTriple().getArch() == llvm::Triple::thumbeb;
const bool IsLoongArch64 = getTriple().getArch() == llvm::Triple::loongarch64;
- const bool IsRISCV64 = getTriple().getArch() == llvm::Triple::riscv64;
+ const bool IsRISCV64 = (getTriple().getArch() == llvm::Triple::riscv64 ||
+ getTriple().getArch() == llvm::Triple::riscv64be);
const bool IsSystemZ = getTriple().getArch() == llvm::Triple::systemz;
const bool IsHexagon = getTriple().getArch() == llvm::Triple::hexagon;
const bool IsAndroid = getTriple().isAndroid();
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 063db05665af1..fa745880e11a5 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -2095,6 +2095,8 @@ bool Sema::CheckTSBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
return AMDGPU().CheckAMDGCNBuiltinFunctionCall(BuiltinID, TheCall);
case llvm::Triple::riscv32:
case llvm::Triple::riscv64:
+ case llvm::Triple::riscv32be:
+ case llvm::Triple::riscv64be:
return RISCV().CheckBuiltinFunctionCall(TI, BuiltinID, TheCall);
case llvm::Triple::loongarch32:
case llvm::Triple::loongarch64:
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 328ccf6694073..ce5253ef8bfa0 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -6066,6 +6066,8 @@ static void handleInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
break;
case llvm::Triple::riscv32:
case llvm::Triple::riscv64:
+ case llvm::Triple::riscv32be:
+ case llvm::Triple::riscv64be:
S.RISCV().handleInterruptAttr(D, AL);
break;
default:
diff --git a/clang/test/CodeGen/riscv-be-data-layout.c b/clang/test/CodeGen/riscv-be-data-layout.c
new file mode 100644
index 0000000000000..9f88464da7587
--- /dev/null
+++ b/clang/test/CodeGen/riscv-be-data-layout.c
@@ -0,0 +1,12 @@
+// REQUIRES: riscv-registered-target
+// RUN: %clang_cc1 -triple riscv64be-unknown-elf -emit-llvm %s -o - \
+// RUN: | FileCheck %s --check-prefix=RV64
+// RUN: %clang_cc1 -triple riscv32be-unknown-elf -emit-llvm %s -o - \
+// RUN: | FileCheck %s --check-prefix=RV32
+
+// RV64: target datalayout = "E-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
+// RV32: target datalayout = "E-m:e-p:32:32-i64:64-n32-S128"
+
+int foo(void) {
+ return 0;
+}
diff --git a/clang/test/Driver/riscv-be.c b/clang/test/Driver/riscv-be.c
new file mode 100644
index 0000000000000..9a5deaa5b9157
--- /dev/null
+++ b/clang/test/Driver/riscv-be.c
@@ -0,0 +1,10 @@
+// REQUIRES: riscv-registered-target
+// RUN: %clang -target riscv64be-unknown-elf -### %s 2>&1 \
+// RUN: | FileCheck %s
+
+// CHECK: warning: big-endian RISC-V target support is experimental
+// CHECK: "-triple" "riscv64be-unknown-unknown-elf"
+
+int foo(void) {
+ return 0;
+}
diff --git a/clang/test/Misc/warning-flags.c b/clang/test/Misc/warning-flags.c
index 3dc4bb55aa69c..bb7b1c7ea67f5 100644
--- a/clang/test/Misc/warning-flags.c
+++ b/clang/test/Misc/warning-flags.c
@@ -18,7 +18,7 @@ This test serves two purposes:
The list of warnings below should NEVER grow. It should gradually shrink to 0.
-CHECK: Warnings without flags (56):
+CHECK: Warnings without flags (57):
CHECK-NEXT: ext_expected_semi_decl_list
CHECK-NEXT: ext_missing_whitespace_after_macro_name
@@ -43,6 +43,7 @@ CHECK-NEXT: warn_double_const_requires_fp64
CHECK-NEXT: warn_drv_assuming_mfloat_abi_is
CHECK-NEXT: warn_drv_clang_unsupported
CHECK-NEXT: warn_drv_pch_not_first_include
+CHECK-NEXT: warn_drv_riscv_be_experimental
CHECK-NEXT: warn_expected_qualified_after_typename
CHECK-NEXT: warn_fe_backend_unsupported
CHECK-NEXT: warn_fe_cc_log_diagnostics_failure
More information about the cfe-commits
mailing list