-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[RISCV] Add big-endian support to RISC-V backend #146534
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-llvm-binary-utilities @llvm/pr-subscribers-clang-driver Author: Djordje Todorovic (djtodoro) ChangesInitial big-endian RISC-V support:
Patch is 27.37 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/146534.diff 21 Files Affected:
diff --git a/clang/test/Driver/frame-pointer-elim.c b/clang/test/Driver/frame-pointer-elim.c
index f64ff6efc7261..416afce81050a 100644
--- a/clang/test/Driver/frame-pointer-elim.c
+++ b/clang/test/Driver/frame-pointer-elim.c
@@ -160,7 +160,7 @@
// RUN: FileCheck --check-prefix=KEEP-ALL %s
// RUN: %clang -### --target=riscv64-linux-android -O1 -S %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
-// RUN: not %clang -### --target=riscv64-linux-android -mbig-endian -O1 -S %s 2>&1 | \
+// RUN: %clang -### --target=riscv64-linux-android -mbig-endian -O1 -S %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// On ARM backend bare metal targets, frame pointer is omitted
diff --git a/llvm/cmake/config.guess b/llvm/cmake/config.guess
index 96cc554f181ab..27b55bd166edc 100644
--- a/llvm/cmake/config.guess
+++ b/llvm/cmake/config.guess
@@ -1003,7 +1003,7 @@ EOF
ppcle:Linux:*:*)
echo powerpcle-unknown-linux-gnu
exit ;;
- riscv32:Linux:*:* | riscv64:Linux:*:*)
+ riscv32:Linux:*:* | riscv64:Linux:*:* | riscv32be:Linux:*:* | riscv64be:Linux:*:*)
LIBC=gnu
eval $set_cc_for_build
# Do not check for __GLIBC__ because uclibc defines it too
diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h
index 103686884e705..a3aa0d9c137a2 100644
--- a/llvm/include/llvm/Object/ELFObjectFile.h
+++ b/llvm/include/llvm/Object/ELFObjectFile.h
@@ -1312,7 +1312,7 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
case ELF::EM_PPC:
return (IsLittleEndian ? "elf32-powerpcle" : "elf32-powerpc");
case ELF::EM_RISCV:
- return "elf32-littleriscv";
+ return (IsLittleEndian ? "elf32-littleriscv" : "elf32-bigriscv");
case ELF::EM_CSKY:
return "elf32-csky";
case ELF::EM_SPARC:
@@ -1338,7 +1338,7 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
case ELF::EM_PPC64:
return (IsLittleEndian ? "elf64-powerpcle" : "elf64-powerpc");
case ELF::EM_RISCV:
- return "elf64-littleriscv";
+ return (IsLittleEndian ? "elf64-littleriscv" : "elf64-bigriscv");
case ELF::EM_S390:
return "elf64-s390";
case ELF::EM_SPARCV9:
@@ -1400,9 +1400,9 @@ template <class ELFT> Triple::ArchType ELFObjectFile<ELFT>::getArch() const {
case ELF::EM_RISCV:
switch (EF.getHeader().e_ident[ELF::EI_CLASS]) {
case ELF::ELFCLASS32:
- return Triple::riscv32;
+ return IsLittleEndian ? Triple::riscv32 : Triple::riscv32be;
case ELF::ELFCLASS64:
- return Triple::riscv64;
+ return IsLittleEndian ? Triple::riscv64 : Triple::riscv64be;
default:
report_fatal_error("Invalid ELFCLASS!");
}
diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h
index cbf85b2ff74f5..c28838e41ded0 100644
--- a/llvm/include/llvm/TargetParser/Triple.h
+++ b/llvm/include/llvm/TargetParser/Triple.h
@@ -76,6 +76,8 @@ class Triple {
amdgcn, // AMDGCN: AMD GCN GPUs
riscv32, // RISC-V (32-bit): riscv32
riscv64, // RISC-V (64-bit): riscv64
+ riscv32be, // RISC-V (32-bit, big endian): riscv32be
+ riscv64be, // RISC-V (64-bit, big endian): riscv64be
sparc, // Sparc: sparc
sparcv9, // Sparcv9: Sparcv9
sparcel, // Sparc: (endianness = little). NB: 'Sparcle' is a CPU variant
@@ -1069,10 +1071,14 @@ class Triple {
}
/// Tests whether the target is 32-bit RISC-V.
- bool isRISCV32() const { return getArch() == Triple::riscv32; }
+ bool isRISCV32() const {
+ return getArch() == Triple::riscv32 || getArch() == Triple::riscv32be;
+ }
/// Tests whether the target is 64-bit RISC-V.
- bool isRISCV64() const { return getArch() == Triple::riscv64; }
+ bool isRISCV64() const {
+ return getArch() == Triple::riscv64 || getArch() == Triple::riscv64be;
+ }
/// Tests whether the target is RISC-V (32- and 64-bit).
bool isRISCV() const { return isRISCV32() || isRISCV64(); }
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 5454cd475f5ed..6c99bd030ec96 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -248,6 +248,8 @@ void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
break;
case Triple::riscv32:
case Triple::riscv64:
+ case Triple::riscv32be:
+ case Triple::riscv64be:
LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
dwarf::DW_EH_PE_sdata4;
diff --git a/llvm/lib/Object/RelocationResolver.cpp b/llvm/lib/Object/RelocationResolver.cpp
index b6318bbe3ab74..d81899334b2b1 100644
--- a/llvm/lib/Object/RelocationResolver.cpp
+++ b/llvm/lib/Object/RelocationResolver.cpp
@@ -812,6 +812,7 @@ getRelocationResolver(const ObjectFile &Obj) {
case Triple::amdgcn:
return {supportsAmdgpu, resolveAmdgpu};
case Triple::riscv64:
+ case Triple::riscv64be:
return {supportsRISCV, resolveRISCV};
default:
if (isAMDGPU(Obj))
@@ -851,6 +852,7 @@ getRelocationResolver(const ObjectFile &Obj) {
case Triple::r600:
return {supportsAmdgpu, resolveAmdgpu};
case Triple::riscv32:
+ case Triple::riscv32be:
return {supportsRISCV, resolveRISCV};
case Triple::csky:
return {supportsCSKY, resolveCSKY};
@@ -897,7 +899,9 @@ uint64_t resolveRelocation(RelocationResolver Resolver, const RelocationRef &R,
if (Obj->getArch() != Triple::loongarch32 &&
Obj->getArch() != Triple::loongarch64 &&
Obj->getArch() != Triple::riscv32 &&
- Obj->getArch() != Triple::riscv64)
+ Obj->getArch() != Triple::riscv64 &&
+ Obj->getArch() != Triple::riscv32be &&
+ Obj->getArch() != Triple::riscv64be)
LocData = 0;
}
}
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index bb0f9df2032fd..890067e270998 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -4031,4 +4031,6 @@ extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
LLVMInitializeRISCVAsmParser() {
RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target());
RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target());
+ RegisterMCAsmParser<RISCVAsmParser> A(getTheRISCV32beTarget());
+ RegisterMCAsmParser<RISCVAsmParser> B(getTheRISCV64beTarget());
}
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 27e04c0cb1f8b..1efc7a896552d 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -72,6 +72,10 @@ LLVMInitializeRISCVDisassembler() {
createRISCVDisassembler);
TargetRegistry::RegisterMCDisassembler(getTheRISCV64Target(),
createRISCVDisassembler);
+ TargetRegistry::RegisterMCDisassembler(getTheRISCV32beTarget(),
+ createRISCVDisassembler);
+ TargetRegistry::RegisterMCDisassembler(getTheRISCV64beTarget(),
+ createRISCVDisassembler);
}
static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint32_t RegNo,
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
index 75ef861d58a1c..7719ab4d95d16 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
@@ -33,9 +33,11 @@ static cl::opt<bool> ULEB128Reloc(
cl::desc("Emit R_RISCV_SET_ULEB128/E_RISCV_SUB_ULEB128 if appropriate"));
RISCVAsmBackend::RISCVAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI,
- bool Is64Bit, const MCTargetOptions &Options)
- : MCAsmBackend(llvm::endianness::little), STI(STI), OSABI(OSABI),
- Is64Bit(Is64Bit), TargetOptions(Options) {
+ bool Is64Bit, bool IsLittleEndian,
+ const MCTargetOptions &Options)
+ : MCAsmBackend(IsLittleEndian ? llvm::endianness::little
+ : llvm::endianness::big),
+ STI(STI), OSABI(OSABI), Is64Bit(Is64Bit), TargetOptions(Options) {
RISCVFeatures::validate(STI.getTargetTriple(), STI.getFeatureBits());
}
@@ -313,7 +315,7 @@ bool RISCVAsmBackend::relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF,
OS << uint8_t(dwarf::DW_LNS_fixed_advance_pc);
Offset = OS.tell();
Fixup = RISCV::getRelocPairForSize(2);
- support::endian::write<uint16_t>(OS, 0, llvm::endianness::little);
+ support::endian::write<uint16_t>(OS, 0, Endian);
}
const MCBinaryExpr &MBE = cast<MCBinaryExpr>(AddrDelta);
@@ -370,15 +372,15 @@ bool RISCVAsmBackend::relaxDwarfCFA(MCDwarfCallFrameFragment &DF,
AddFixups(0, {ELF::R_RISCV_SET6, ELF::R_RISCV_SUB6});
} else if (isUInt<8>(Value)) {
OS << uint8_t(dwarf::DW_CFA_advance_loc1);
- support::endian::write<uint8_t>(OS, 0, llvm::endianness::little);
+ support::endian::write<uint8_t>(OS, 0, Endian);
AddFixups(1, {ELF::R_RISCV_SET8, ELF::R_RISCV_SUB8});
} else if (isUInt<16>(Value)) {
OS << uint8_t(dwarf::DW_CFA_advance_loc2);
- support::endian::write<uint16_t>(OS, 0, llvm::endianness::little);
+ support::endian::write<uint16_t>(OS, 0, Endian);
AddFixups(1, {ELF::R_RISCV_SET16, ELF::R_RISCV_SUB16});
} else if (isUInt<32>(Value)) {
OS << uint8_t(dwarf::DW_CFA_advance_loc4);
- support::endian::write<uint32_t>(OS, 0, llvm::endianness::little);
+ support::endian::write<uint32_t>(OS, 0, Endian);
AddFixups(1, {ELF::R_RISCV_SET32, ELF::R_RISCV_SUB32});
} else {
llvm_unreachable("unsupported CFA encoding");
@@ -815,6 +817,34 @@ bool RISCVAsmBackend::addReloc(const MCFragment &F, const MCFixup &Fixup,
return false;
}
+// Data should be swapped for big endian cores.
+static bool isDataFixup(unsigned Kind) {
+ switch (Kind) {
+ default:
+ llvm_unreachable("Unknown fixup kind!");
+
+ case FK_Data_1:
+ case FK_Data_2:
+ case FK_Data_4:
+ case FK_Data_8:
+ return true;
+
+ case RISCV::fixup_riscv_hi20:
+ case RISCV::fixup_riscv_lo12_i:
+ case RISCV::fixup_riscv_lo12_s:
+ case RISCV::fixup_riscv_pcrel_hi20:
+ case RISCV::fixup_riscv_pcrel_lo12_i:
+ case RISCV::fixup_riscv_pcrel_lo12_s:
+ case RISCV::fixup_riscv_jal:
+ case RISCV::fixup_riscv_branch:
+ case RISCV::fixup_riscv_call:
+ case RISCV::fixup_riscv_call_plt:
+ case RISCV::fixup_riscv_rvc_jump:
+ case RISCV::fixup_riscv_rvc_branch:
+ return false;
+ }
+}
+
void RISCVAsmBackend::applyFixup(const MCFragment &, const MCFixup &Fixup,
const MCValue &Target,
MutableArrayRef<char> Data, uint64_t Value,
@@ -839,8 +869,11 @@ void RISCVAsmBackend::applyFixup(const MCFragment &, const MCFixup &Fixup,
// For each byte of the fragment that the fixup touches, mask in the
// bits from the fixup value.
+ // For big endian cores, data fixup should be swapped.
+ bool SwapValue = (Endian == llvm::endianness::big) && isDataFixup(Kind);
for (unsigned i = 0; i != NumBytes; ++i) {
- Data[Offset + i] |= uint8_t((Value >> (i * 8)) & 0xff);
+ unsigned Idx = SwapValue ? (NumBytes - 1 - i) : i;
+ Data[Offset + Idx] |= uint8_t((Value >> (i * 8)) & 0xff);
}
}
@@ -905,5 +938,6 @@ MCAsmBackend *llvm::createRISCVAsmBackend(const Target &T,
const MCTargetOptions &Options) {
const Triple &TT = STI.getTargetTriple();
uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS());
- return new RISCVAsmBackend(STI, OSABI, TT.isArch64Bit(), Options);
+ return new RISCVAsmBackend(STI, OSABI, TT.isArch64Bit(), TT.isLittleEndian(),
+ Options);
}
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
index 91efd44547509..9c03c7aaa98e2 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
@@ -36,7 +36,7 @@ class RISCVAsmBackend : public MCAsmBackend {
public:
RISCVAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI, bool Is64Bit,
- const MCTargetOptions &Options);
+ bool IsLittleEndian, const MCTargetOptions &Options);
~RISCVAsmBackend() override = default;
// Return Size with extra Nop Bytes for alignment directive in code section.
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp
index 090d331d99cab..77f65d814ce7a 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp
@@ -21,6 +21,7 @@ using namespace llvm;
void RISCVMCAsmInfo::anchor() {}
RISCVMCAsmInfo::RISCVMCAsmInfo(const Triple &TT) {
+ IsLittleEndian = TT.isLittleEndian();
CodePointerSize = CalleeSaveStackSlotSize = TT.isArch64Bit() ? 8 : 4;
CommentString = "#";
AlignmentIsInBytes = false;
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp
index f66c2d5f99cb3..88e564580dc5e 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp
@@ -334,7 +334,8 @@ static MCInstrAnalysis *createRISCVInstrAnalysis(const MCInstrInfo *Info) {
extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
LLVMInitializeRISCVTargetMC() {
- for (Target *T : {&getTheRISCV32Target(), &getTheRISCV64Target()}) {
+ for (Target *T : {&getTheRISCV32Target(), &getTheRISCV64Target(),
+ &getTheRISCV32beTarget(), &getTheRISCV64beTarget()}) {
TargetRegistry::RegisterMCAsmInfo(*T, createRISCVMCAsmInfo);
TargetRegistry::RegisterMCObjectFileInfo(*T, createRISCVMCObjectFileInfo);
TargetRegistry::RegisterMCInstrInfo(*T, createRISCVMCInstrInfo);
diff --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
index b078b9268c984..02a6cbdb9f80d 100644
--- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
+++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
@@ -615,6 +615,8 @@ extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
LLVMInitializeRISCVAsmPrinter() {
RegisterAsmPrinter<RISCVAsmPrinter> X(getTheRISCV32Target());
RegisterAsmPrinter<RISCVAsmPrinter> Y(getTheRISCV64Target());
+ RegisterAsmPrinter<RISCVAsmPrinter> A(getTheRISCV32beTarget());
+ RegisterAsmPrinter<RISCVAsmPrinter> B(getTheRISCV64beTarget());
}
void RISCVAsmPrinter::LowerHWASAN_CHECK_MEMACCESS(const MachineInstr &MI) {
diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
index b43b915d0ad4f..32177fe06e889 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
@@ -122,6 +122,8 @@ static cl::opt<bool>
extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() {
RegisterTargetMachine<RISCVTargetMachine> X(getTheRISCV32Target());
RegisterTargetMachine<RISCVTargetMachine> Y(getTheRISCV64Target());
+ RegisterTargetMachine<RISCVTargetMachine> A(getTheRISCV32beTarget());
+ RegisterTargetMachine<RISCVTargetMachine> B(getTheRISCV64beTarget());
auto *PR = PassRegistry::getPassRegistry();
initializeGlobalISel(*PR);
initializeRISCVO0PreLegalizerCombinerPass(*PR);
@@ -155,21 +157,23 @@ extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() {
initializeRISCVAsmPrinterPass(*PR);
}
-static StringRef computeDataLayout(const Triple &TT,
- const TargetOptions &Options) {
- StringRef ABIName = Options.MCOptions.getABIName();
- if (TT.isArch64Bit()) {
- if (ABIName == "lp64e")
- return "e-m:e-p:64:64-i64:64-i128:128-n32:64-S64";
+static std::string computeDataLayout(const Triple &TT,
+ const TargetOptions &Opts) {
+ const bool IsLittle = TT.isLittleEndian();
+ StringRef ABI = Opts.MCOptions.getABIName();
+ std::string DL;
- return "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128";
+ if (TT.isArch64Bit()) {
+ DL = (Twine(IsLittle ? "e" : "E") + "-m:e-p:64:64-i64:64-i128:128-n32:64-" +
+ (ABI == "lp64e" ? "S64" : "S128"))
+ .str();
+ } else {
+ assert(TT.isArch32Bit() && "only RV32 and RV64 are currently supported");
+ DL = (Twine(IsLittle ? "e" : "E") + "-m:e-p:32:32-i64:64-n32-" +
+ (ABI == "ilp32e" ? "S32" : "S128"))
+ .str();
}
- assert(TT.isArch32Bit() && "only RV32 and RV64 are currently supported");
-
- if (ABIName == "ilp32e")
- return "e-m:e-p:32:32-i64:64-n32-S32";
-
- return "e-m:e-p:32:32-i64:64-n32-S128";
+ return DL;
}
static Reloc::Model getEffectiveRelocModel(const Triple &TT,
diff --git a/llvm/lib/Target/RISCV/TargetInfo/RISCVTargetInfo.cpp b/llvm/lib/Target/RISCV/TargetInfo/RISCVTargetInfo.cpp
index fc0965d263a8a..7b0afe46971a3 100644
--- a/llvm/lib/Target/RISCV/TargetInfo/RISCVTargetInfo.cpp
+++ b/llvm/lib/Target/RISCV/TargetInfo/RISCVTargetInfo.cpp
@@ -21,10 +21,24 @@ Target &llvm::getTheRISCV64Target() {
return TheRISCV64Target;
}
+Target &llvm::getTheRISCV32beTarget() {
+ static Target TheRISCV32beTarget;
+ return TheRISCV32beTarget;
+}
+
+Target &llvm::getTheRISCV64beTarget() {
+ static Target TheRISCV64beTarget;
+ return TheRISCV64beTarget;
+}
+
extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
LLVMInitializeRISCVTargetInfo() {
RegisterTarget<Triple::riscv32, /*HasJIT=*/true> X(
getTheRISCV32Target(), "riscv32", "32-bit RISC-V", "RISCV");
RegisterTarget<Triple::riscv64, /*HasJIT=*/true> Y(
getTheRISCV64Target(), "riscv64", "64-bit RISC-V", "RISCV");
+ RegisterTarget<Triple::riscv32be> A(getTheRISCV32beTarget(), "riscv32be",
+ "32-bit big endian RISC-V", "RISCV");
+ RegisterTarget<Triple::riscv64be> B(getTheRISCV64beTarget(), "riscv64be",
+ "64-bit big endian RISC-V", "RISCV");
}
diff --git a/llvm/lib/Target/RISCV/TargetInfo/RISCVTargetInfo.h b/llvm/lib/Target/RISCV/TargetInfo/RISCVTargetInfo.h
index ed00a01fa1a2a..9b9fd2cca2fd0 100644
--- a/llvm/lib/Target/RISCV/TargetInfo/RISCVTargetInfo.h
+++ b/llvm/lib/Target/RISCV/TargetInfo/RISCVTargetInfo.h
@@ -15,6 +15,8 @@ class Target;
Target &getTheRISCV32Target();
Target &getTheRISCV64Target();
+Target &getTheRISCV32beTarget();
+Target &getTheRISCV64beTarget();
} // namespace llvm
diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp
index a348640d75f26..47d6150a04365 100644
--- a/llvm/lib/TargetParser/Triple.cpp
+++ b/llvm/lib/TargetParser/Triple.cpp
@@ -63,6 +63,8 @@ StringRef Triple::getArchTypeName(ArchType Kind) {
case renderscript64: return "renderscript64";
case riscv32: return "riscv32";
case riscv64: return "riscv64";
+ case riscv32be: return "riscv32be";
+ case riscv64be: return "riscv64be";
case shave: return "shave";
case sparc: return "sparc";
case sparcel: return "sparcel";
@@ -237,7 +239,9 @@ StringRef Triple::getArchTypePrefix(ArchType Kind) {
case wasm64: return "wasm";
case riscv32:
- case riscv64: return "riscv";
+ case riscv64:
+ case riscv32be:
+ case riscv64be: return "riscv";
case ve: return "ve";
case csky: return "csky";
@@ -452,6 +456,8 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
.Case("amdgcn", amdgcn)
.Case("riscv32", riscv32)
.Case("riscv64", riscv64)
+ .Case("riscv32be", riscv32be)
+ .Case("riscv64be", riscv64be)
.Case("hexagon", hexagon)
.Case("sparc", sparc)
.Case("sparcel", sparcel)
@@ -598,6 +604,8 @@ static Triple::ArchType parseArch(StringRef ArchName) {
.Case("amdgcn", Triple::amdgcn)
.Case("riscv32", Triple::riscv32)
.Case("riscv64", Triple::riscv64)
+ .Case("riscv32be", Triple::riscv32be)
+ ...
[truncated]
|
@llvm/pr-subscribers-backend-risc-v Author: Djordje Todorovic (djtodoro) ChangesInitial big-endian RISC-V support:
Patch is 27.37 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/146534.diff 21 Files Affected:
diff --git a/clang/test/Driver/frame-pointer-elim.c b/clang/test/Driver/frame-pointer-elim.c
index f64ff6efc7261..416afce81050a 100644
--- a/clang/test/Driver/frame-pointer-elim.c
+++ b/clang/test/Driver/frame-pointer-elim.c
@@ -160,7 +160,7 @@
// RUN: FileCheck --check-prefix=KEEP-ALL %s
// RUN: %clang -### --target=riscv64-linux-android -O1 -S %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
-// RUN: not %clang -### --target=riscv64-linux-android -mbig-endian -O1 -S %s 2>&1 | \
+// RUN: %clang -### --target=riscv64-linux-android -mbig-endian -O1 -S %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// On ARM backend bare metal targets, frame pointer is omitted
diff --git a/llvm/cmake/config.guess b/llvm/cmake/config.guess
index 96cc554f181ab..27b55bd166edc 100644
--- a/llvm/cmake/config.guess
+++ b/llvm/cmake/config.guess
@@ -1003,7 +1003,7 @@ EOF
ppcle:Linux:*:*)
echo powerpcle-unknown-linux-gnu
exit ;;
- riscv32:Linux:*:* | riscv64:Linux:*:*)
+ riscv32:Linux:*:* | riscv64:Linux:*:* | riscv32be:Linux:*:* | riscv64be:Linux:*:*)
LIBC=gnu
eval $set_cc_for_build
# Do not check for __GLIBC__ because uclibc defines it too
diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h
index 103686884e705..a3aa0d9c137a2 100644
--- a/llvm/include/llvm/Object/ELFObjectFile.h
+++ b/llvm/include/llvm/Object/ELFObjectFile.h
@@ -1312,7 +1312,7 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
case ELF::EM_PPC:
return (IsLittleEndian ? "elf32-powerpcle" : "elf32-powerpc");
case ELF::EM_RISCV:
- return "elf32-littleriscv";
+ return (IsLittleEndian ? "elf32-littleriscv" : "elf32-bigriscv");
case ELF::EM_CSKY:
return "elf32-csky";
case ELF::EM_SPARC:
@@ -1338,7 +1338,7 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
case ELF::EM_PPC64:
return (IsLittleEndian ? "elf64-powerpcle" : "elf64-powerpc");
case ELF::EM_RISCV:
- return "elf64-littleriscv";
+ return (IsLittleEndian ? "elf64-littleriscv" : "elf64-bigriscv");
case ELF::EM_S390:
return "elf64-s390";
case ELF::EM_SPARCV9:
@@ -1400,9 +1400,9 @@ template <class ELFT> Triple::ArchType ELFObjectFile<ELFT>::getArch() const {
case ELF::EM_RISCV:
switch (EF.getHeader().e_ident[ELF::EI_CLASS]) {
case ELF::ELFCLASS32:
- return Triple::riscv32;
+ return IsLittleEndian ? Triple::riscv32 : Triple::riscv32be;
case ELF::ELFCLASS64:
- return Triple::riscv64;
+ return IsLittleEndian ? Triple::riscv64 : Triple::riscv64be;
default:
report_fatal_error("Invalid ELFCLASS!");
}
diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h
index cbf85b2ff74f5..c28838e41ded0 100644
--- a/llvm/include/llvm/TargetParser/Triple.h
+++ b/llvm/include/llvm/TargetParser/Triple.h
@@ -76,6 +76,8 @@ class Triple {
amdgcn, // AMDGCN: AMD GCN GPUs
riscv32, // RISC-V (32-bit): riscv32
riscv64, // RISC-V (64-bit): riscv64
+ riscv32be, // RISC-V (32-bit, big endian): riscv32be
+ riscv64be, // RISC-V (64-bit, big endian): riscv64be
sparc, // Sparc: sparc
sparcv9, // Sparcv9: Sparcv9
sparcel, // Sparc: (endianness = little). NB: 'Sparcle' is a CPU variant
@@ -1069,10 +1071,14 @@ class Triple {
}
/// Tests whether the target is 32-bit RISC-V.
- bool isRISCV32() const { return getArch() == Triple::riscv32; }
+ bool isRISCV32() const {
+ return getArch() == Triple::riscv32 || getArch() == Triple::riscv32be;
+ }
/// Tests whether the target is 64-bit RISC-V.
- bool isRISCV64() const { return getArch() == Triple::riscv64; }
+ bool isRISCV64() const {
+ return getArch() == Triple::riscv64 || getArch() == Triple::riscv64be;
+ }
/// Tests whether the target is RISC-V (32- and 64-bit).
bool isRISCV() const { return isRISCV32() || isRISCV64(); }
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 5454cd475f5ed..6c99bd030ec96 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -248,6 +248,8 @@ void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
break;
case Triple::riscv32:
case Triple::riscv64:
+ case Triple::riscv32be:
+ case Triple::riscv64be:
LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
dwarf::DW_EH_PE_sdata4;
diff --git a/llvm/lib/Object/RelocationResolver.cpp b/llvm/lib/Object/RelocationResolver.cpp
index b6318bbe3ab74..d81899334b2b1 100644
--- a/llvm/lib/Object/RelocationResolver.cpp
+++ b/llvm/lib/Object/RelocationResolver.cpp
@@ -812,6 +812,7 @@ getRelocationResolver(const ObjectFile &Obj) {
case Triple::amdgcn:
return {supportsAmdgpu, resolveAmdgpu};
case Triple::riscv64:
+ case Triple::riscv64be:
return {supportsRISCV, resolveRISCV};
default:
if (isAMDGPU(Obj))
@@ -851,6 +852,7 @@ getRelocationResolver(const ObjectFile &Obj) {
case Triple::r600:
return {supportsAmdgpu, resolveAmdgpu};
case Triple::riscv32:
+ case Triple::riscv32be:
return {supportsRISCV, resolveRISCV};
case Triple::csky:
return {supportsCSKY, resolveCSKY};
@@ -897,7 +899,9 @@ uint64_t resolveRelocation(RelocationResolver Resolver, const RelocationRef &R,
if (Obj->getArch() != Triple::loongarch32 &&
Obj->getArch() != Triple::loongarch64 &&
Obj->getArch() != Triple::riscv32 &&
- Obj->getArch() != Triple::riscv64)
+ Obj->getArch() != Triple::riscv64 &&
+ Obj->getArch() != Triple::riscv32be &&
+ Obj->getArch() != Triple::riscv64be)
LocData = 0;
}
}
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index bb0f9df2032fd..890067e270998 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -4031,4 +4031,6 @@ extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
LLVMInitializeRISCVAsmParser() {
RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target());
RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target());
+ RegisterMCAsmParser<RISCVAsmParser> A(getTheRISCV32beTarget());
+ RegisterMCAsmParser<RISCVAsmParser> B(getTheRISCV64beTarget());
}
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 27e04c0cb1f8b..1efc7a896552d 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -72,6 +72,10 @@ LLVMInitializeRISCVDisassembler() {
createRISCVDisassembler);
TargetRegistry::RegisterMCDisassembler(getTheRISCV64Target(),
createRISCVDisassembler);
+ TargetRegistry::RegisterMCDisassembler(getTheRISCV32beTarget(),
+ createRISCVDisassembler);
+ TargetRegistry::RegisterMCDisassembler(getTheRISCV64beTarget(),
+ createRISCVDisassembler);
}
static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint32_t RegNo,
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
index 75ef861d58a1c..7719ab4d95d16 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
@@ -33,9 +33,11 @@ static cl::opt<bool> ULEB128Reloc(
cl::desc("Emit R_RISCV_SET_ULEB128/E_RISCV_SUB_ULEB128 if appropriate"));
RISCVAsmBackend::RISCVAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI,
- bool Is64Bit, const MCTargetOptions &Options)
- : MCAsmBackend(llvm::endianness::little), STI(STI), OSABI(OSABI),
- Is64Bit(Is64Bit), TargetOptions(Options) {
+ bool Is64Bit, bool IsLittleEndian,
+ const MCTargetOptions &Options)
+ : MCAsmBackend(IsLittleEndian ? llvm::endianness::little
+ : llvm::endianness::big),
+ STI(STI), OSABI(OSABI), Is64Bit(Is64Bit), TargetOptions(Options) {
RISCVFeatures::validate(STI.getTargetTriple(), STI.getFeatureBits());
}
@@ -313,7 +315,7 @@ bool RISCVAsmBackend::relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF,
OS << uint8_t(dwarf::DW_LNS_fixed_advance_pc);
Offset = OS.tell();
Fixup = RISCV::getRelocPairForSize(2);
- support::endian::write<uint16_t>(OS, 0, llvm::endianness::little);
+ support::endian::write<uint16_t>(OS, 0, Endian);
}
const MCBinaryExpr &MBE = cast<MCBinaryExpr>(AddrDelta);
@@ -370,15 +372,15 @@ bool RISCVAsmBackend::relaxDwarfCFA(MCDwarfCallFrameFragment &DF,
AddFixups(0, {ELF::R_RISCV_SET6, ELF::R_RISCV_SUB6});
} else if (isUInt<8>(Value)) {
OS << uint8_t(dwarf::DW_CFA_advance_loc1);
- support::endian::write<uint8_t>(OS, 0, llvm::endianness::little);
+ support::endian::write<uint8_t>(OS, 0, Endian);
AddFixups(1, {ELF::R_RISCV_SET8, ELF::R_RISCV_SUB8});
} else if (isUInt<16>(Value)) {
OS << uint8_t(dwarf::DW_CFA_advance_loc2);
- support::endian::write<uint16_t>(OS, 0, llvm::endianness::little);
+ support::endian::write<uint16_t>(OS, 0, Endian);
AddFixups(1, {ELF::R_RISCV_SET16, ELF::R_RISCV_SUB16});
} else if (isUInt<32>(Value)) {
OS << uint8_t(dwarf::DW_CFA_advance_loc4);
- support::endian::write<uint32_t>(OS, 0, llvm::endianness::little);
+ support::endian::write<uint32_t>(OS, 0, Endian);
AddFixups(1, {ELF::R_RISCV_SET32, ELF::R_RISCV_SUB32});
} else {
llvm_unreachable("unsupported CFA encoding");
@@ -815,6 +817,34 @@ bool RISCVAsmBackend::addReloc(const MCFragment &F, const MCFixup &Fixup,
return false;
}
+// Data should be swapped for big endian cores.
+static bool isDataFixup(unsigned Kind) {
+ switch (Kind) {
+ default:
+ llvm_unreachable("Unknown fixup kind!");
+
+ case FK_Data_1:
+ case FK_Data_2:
+ case FK_Data_4:
+ case FK_Data_8:
+ return true;
+
+ case RISCV::fixup_riscv_hi20:
+ case RISCV::fixup_riscv_lo12_i:
+ case RISCV::fixup_riscv_lo12_s:
+ case RISCV::fixup_riscv_pcrel_hi20:
+ case RISCV::fixup_riscv_pcrel_lo12_i:
+ case RISCV::fixup_riscv_pcrel_lo12_s:
+ case RISCV::fixup_riscv_jal:
+ case RISCV::fixup_riscv_branch:
+ case RISCV::fixup_riscv_call:
+ case RISCV::fixup_riscv_call_plt:
+ case RISCV::fixup_riscv_rvc_jump:
+ case RISCV::fixup_riscv_rvc_branch:
+ return false;
+ }
+}
+
void RISCVAsmBackend::applyFixup(const MCFragment &, const MCFixup &Fixup,
const MCValue &Target,
MutableArrayRef<char> Data, uint64_t Value,
@@ -839,8 +869,11 @@ void RISCVAsmBackend::applyFixup(const MCFragment &, const MCFixup &Fixup,
// For each byte of the fragment that the fixup touches, mask in the
// bits from the fixup value.
+ // For big endian cores, data fixup should be swapped.
+ bool SwapValue = (Endian == llvm::endianness::big) && isDataFixup(Kind);
for (unsigned i = 0; i != NumBytes; ++i) {
- Data[Offset + i] |= uint8_t((Value >> (i * 8)) & 0xff);
+ unsigned Idx = SwapValue ? (NumBytes - 1 - i) : i;
+ Data[Offset + Idx] |= uint8_t((Value >> (i * 8)) & 0xff);
}
}
@@ -905,5 +938,6 @@ MCAsmBackend *llvm::createRISCVAsmBackend(const Target &T,
const MCTargetOptions &Options) {
const Triple &TT = STI.getTargetTriple();
uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS());
- return new RISCVAsmBackend(STI, OSABI, TT.isArch64Bit(), Options);
+ return new RISCVAsmBackend(STI, OSABI, TT.isArch64Bit(), TT.isLittleEndian(),
+ Options);
}
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
index 91efd44547509..9c03c7aaa98e2 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
@@ -36,7 +36,7 @@ class RISCVAsmBackend : public MCAsmBackend {
public:
RISCVAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI, bool Is64Bit,
- const MCTargetOptions &Options);
+ bool IsLittleEndian, const MCTargetOptions &Options);
~RISCVAsmBackend() override = default;
// Return Size with extra Nop Bytes for alignment directive in code section.
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp
index 090d331d99cab..77f65d814ce7a 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp
@@ -21,6 +21,7 @@ using namespace llvm;
void RISCVMCAsmInfo::anchor() {}
RISCVMCAsmInfo::RISCVMCAsmInfo(const Triple &TT) {
+ IsLittleEndian = TT.isLittleEndian();
CodePointerSize = CalleeSaveStackSlotSize = TT.isArch64Bit() ? 8 : 4;
CommentString = "#";
AlignmentIsInBytes = false;
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp
index f66c2d5f99cb3..88e564580dc5e 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp
@@ -334,7 +334,8 @@ static MCInstrAnalysis *createRISCVInstrAnalysis(const MCInstrInfo *Info) {
extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
LLVMInitializeRISCVTargetMC() {
- for (Target *T : {&getTheRISCV32Target(), &getTheRISCV64Target()}) {
+ for (Target *T : {&getTheRISCV32Target(), &getTheRISCV64Target(),
+ &getTheRISCV32beTarget(), &getTheRISCV64beTarget()}) {
TargetRegistry::RegisterMCAsmInfo(*T, createRISCVMCAsmInfo);
TargetRegistry::RegisterMCObjectFileInfo(*T, createRISCVMCObjectFileInfo);
TargetRegistry::RegisterMCInstrInfo(*T, createRISCVMCInstrInfo);
diff --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
index b078b9268c984..02a6cbdb9f80d 100644
--- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
+++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
@@ -615,6 +615,8 @@ extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
LLVMInitializeRISCVAsmPrinter() {
RegisterAsmPrinter<RISCVAsmPrinter> X(getTheRISCV32Target());
RegisterAsmPrinter<RISCVAsmPrinter> Y(getTheRISCV64Target());
+ RegisterAsmPrinter<RISCVAsmPrinter> A(getTheRISCV32beTarget());
+ RegisterAsmPrinter<RISCVAsmPrinter> B(getTheRISCV64beTarget());
}
void RISCVAsmPrinter::LowerHWASAN_CHECK_MEMACCESS(const MachineInstr &MI) {
diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
index b43b915d0ad4f..32177fe06e889 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
@@ -122,6 +122,8 @@ static cl::opt<bool>
extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() {
RegisterTargetMachine<RISCVTargetMachine> X(getTheRISCV32Target());
RegisterTargetMachine<RISCVTargetMachine> Y(getTheRISCV64Target());
+ RegisterTargetMachine<RISCVTargetMachine> A(getTheRISCV32beTarget());
+ RegisterTargetMachine<RISCVTargetMachine> B(getTheRISCV64beTarget());
auto *PR = PassRegistry::getPassRegistry();
initializeGlobalISel(*PR);
initializeRISCVO0PreLegalizerCombinerPass(*PR);
@@ -155,21 +157,23 @@ extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() {
initializeRISCVAsmPrinterPass(*PR);
}
-static StringRef computeDataLayout(const Triple &TT,
- const TargetOptions &Options) {
- StringRef ABIName = Options.MCOptions.getABIName();
- if (TT.isArch64Bit()) {
- if (ABIName == "lp64e")
- return "e-m:e-p:64:64-i64:64-i128:128-n32:64-S64";
+static std::string computeDataLayout(const Triple &TT,
+ const TargetOptions &Opts) {
+ const bool IsLittle = TT.isLittleEndian();
+ StringRef ABI = Opts.MCOptions.getABIName();
+ std::string DL;
- return "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128";
+ if (TT.isArch64Bit()) {
+ DL = (Twine(IsLittle ? "e" : "E") + "-m:e-p:64:64-i64:64-i128:128-n32:64-" +
+ (ABI == "lp64e" ? "S64" : "S128"))
+ .str();
+ } else {
+ assert(TT.isArch32Bit() && "only RV32 and RV64 are currently supported");
+ DL = (Twine(IsLittle ? "e" : "E") + "-m:e-p:32:32-i64:64-n32-" +
+ (ABI == "ilp32e" ? "S32" : "S128"))
+ .str();
}
- assert(TT.isArch32Bit() && "only RV32 and RV64 are currently supported");
-
- if (ABIName == "ilp32e")
- return "e-m:e-p:32:32-i64:64-n32-S32";
-
- return "e-m:e-p:32:32-i64:64-n32-S128";
+ return DL;
}
static Reloc::Model getEffectiveRelocModel(const Triple &TT,
diff --git a/llvm/lib/Target/RISCV/TargetInfo/RISCVTargetInfo.cpp b/llvm/lib/Target/RISCV/TargetInfo/RISCVTargetInfo.cpp
index fc0965d263a8a..7b0afe46971a3 100644
--- a/llvm/lib/Target/RISCV/TargetInfo/RISCVTargetInfo.cpp
+++ b/llvm/lib/Target/RISCV/TargetInfo/RISCVTargetInfo.cpp
@@ -21,10 +21,24 @@ Target &llvm::getTheRISCV64Target() {
return TheRISCV64Target;
}
+Target &llvm::getTheRISCV32beTarget() {
+ static Target TheRISCV32beTarget;
+ return TheRISCV32beTarget;
+}
+
+Target &llvm::getTheRISCV64beTarget() {
+ static Target TheRISCV64beTarget;
+ return TheRISCV64beTarget;
+}
+
extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
LLVMInitializeRISCVTargetInfo() {
RegisterTarget<Triple::riscv32, /*HasJIT=*/true> X(
getTheRISCV32Target(), "riscv32", "32-bit RISC-V", "RISCV");
RegisterTarget<Triple::riscv64, /*HasJIT=*/true> Y(
getTheRISCV64Target(), "riscv64", "64-bit RISC-V", "RISCV");
+ RegisterTarget<Triple::riscv32be> A(getTheRISCV32beTarget(), "riscv32be",
+ "32-bit big endian RISC-V", "RISCV");
+ RegisterTarget<Triple::riscv64be> B(getTheRISCV64beTarget(), "riscv64be",
+ "64-bit big endian RISC-V", "RISCV");
}
diff --git a/llvm/lib/Target/RISCV/TargetInfo/RISCVTargetInfo.h b/llvm/lib/Target/RISCV/TargetInfo/RISCVTargetInfo.h
index ed00a01fa1a2a..9b9fd2cca2fd0 100644
--- a/llvm/lib/Target/RISCV/TargetInfo/RISCVTargetInfo.h
+++ b/llvm/lib/Target/RISCV/TargetInfo/RISCVTargetInfo.h
@@ -15,6 +15,8 @@ class Target;
Target &getTheRISCV32Target();
Target &getTheRISCV64Target();
+Target &getTheRISCV32beTarget();
+Target &getTheRISCV64beTarget();
} // namespace llvm
diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp
index a348640d75f26..47d6150a04365 100644
--- a/llvm/lib/TargetParser/Triple.cpp
+++ b/llvm/lib/TargetParser/Triple.cpp
@@ -63,6 +63,8 @@ StringRef Triple::getArchTypeName(ArchType Kind) {
case renderscript64: return "renderscript64";
case riscv32: return "riscv32";
case riscv64: return "riscv64";
+ case riscv32be: return "riscv32be";
+ case riscv64be: return "riscv64be";
case shave: return "shave";
case sparc: return "sparc";
case sparcel: return "sparcel";
@@ -237,7 +239,9 @@ StringRef Triple::getArchTypePrefix(ArchType Kind) {
case wasm64: return "wasm";
case riscv32:
- case riscv64: return "riscv";
+ case riscv64:
+ case riscv32be:
+ case riscv64be: return "riscv";
case ve: return "ve";
case csky: return "csky";
@@ -452,6 +456,8 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
.Case("amdgcn", amdgcn)
.Case("riscv32", riscv32)
.Case("riscv64", riscv64)
+ .Case("riscv32be", riscv32be)
+ .Case("riscv64be", riscv64be)
.Case("hexagon", hexagon)
.Case("sparc", sparc)
.Case("sparcel", sparcel)
@@ -598,6 +604,8 @@ static Triple::ArchType parseArch(StringRef ArchName) {
.Case("amdgcn", Triple::amdgcn)
.Case("riscv32", Triple::riscv32)
.Case("riscv64", Triple::riscv64)
+ .Case("riscv32be", Triple::riscv32be)
+ ...
[truncated]
|
Support for Basically, this brings into life the https://reviews.llvm.org/D128612. |
✅ With the latest revision this PR passed the C/C++ code formatter. |
Initial big-endian RISC-V support: - Add riscv32be/riscv64be target triples - Implement BE-aware codegen patterns - Handle endianness in load/store operations - Add BE target feature and subtarget info
A PR in psABI repo is here: riscv-non-isa/riscv-elf-psabi-doc#470. |
This seems to only implement the first bullet point in your commit message, and assembler/relocation/fixup support, right? Please update the PR description. I presume there will be follow-ups for the codegen/load-store support, plus subtarget info. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
llvm-objcopy and libObject changes look fine to me. If you split the llvm-objcopy changes into a separate PR, I'd be happy to approve directly.
lanai, // Lanai: Lanai 32-bit | ||
wasm32, // WebAssembly with 32-bit pointers | ||
wasm64, // WebAssembly with 64-bit pointers | ||
arm, // ARM (little endian): arm, armv.*, xscale |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This reformatting looks off to me. I'd expect the comments to line up the whole way down, but the renderscript comment and onwards is not at the same column.
riscv32, // RISC-V (32-bit): riscv32 | ||
riscv64, // RISC-V (64-bit): riscv64 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Worth specifying little endian here, to contrast with the big endian comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How are we going to verify the correctness? Does qemu support big-endian riscv64?
Good question. We have an initial support for it developed internally inside MIPS, for both qemu and Linux kernel, but team from Codethink is trying to upstream similar effort already, so please check it here https://gitlab.com/CodethinkLabs/riscv_bigendian. I am not sure how we merged Big Endian support for RISC-V in GNU GCC, but we should have agreed on convention first I think (effort initiated at riscv-non-isa/riscv-elf-psabi-doc#470.) |
What is your intention here around the LLVM 21 release cycle, knowing this is a big feature and we are ~2 weeks from the branch date |
Hey @lenary, thanks for mentioning that. I agree it is a big feature, so no need to rush to include it in the release. |
Initial big-endian RISC-V support: