-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[llvm-objcopy][libObject] Add RISC-V big-endian support #146913
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) ChangesAdd support for big-endian RISC-V ELF files:
This is a subset of a bigger RISC-V big-endian support patch, containing only the llvm-objcopy and libObject changes. Other changes will be added later. Full diff: https://github.com/llvm/llvm-project/pull/146913.diff 8 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/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..0b983e9f7a3bc 100644
--- a/llvm/include/llvm/TargetParser/Triple.h
+++ b/llvm/include/llvm/TargetParser/Triple.h
@@ -74,8 +74,10 @@ class Triple {
ppc64le, // PPC64LE: powerpc64le
r600, // R600: AMD GPUs HD2XXX - HD6XXX
amdgcn, // AMDGCN: AMD GCN GPUs
- riscv32, // RISC-V (32-bit): riscv32
- riscv64, // RISC-V (64-bit): riscv64
+ riscv32, // RISC-V (32-bit, little endian): riscv32
+ riscv64, // RISC-V (64-bit, little endian): 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/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/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp
index a348640d75f26..19f30631196d4 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)
+ .Case("riscv64be", Triple::riscv64be)
.Case("hexagon", Triple::hexagon)
.Cases("s390x", "systemz", Triple::systemz)
.Case("sparc", Triple::sparc)
@@ -967,6 +975,8 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
case Triple::renderscript64:
case Triple::riscv32:
case Triple::riscv64:
+ case Triple::riscv32be:
+ case Triple::riscv64be:
case Triple::shave:
case Triple::sparc:
case Triple::sparcel:
@@ -1689,6 +1699,7 @@ unsigned Triple::getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
case llvm::Triple::r600:
case llvm::Triple::renderscript32:
case llvm::Triple::riscv32:
+ case llvm::Triple::riscv32be:
case llvm::Triple::shave:
case llvm::Triple::sparc:
case llvm::Triple::sparcel:
@@ -1719,6 +1730,7 @@ unsigned Triple::getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
case llvm::Triple::ppc64le:
case llvm::Triple::renderscript64:
case llvm::Triple::riscv64:
+ case llvm::Triple::riscv64be:
case llvm::Triple::sparcv9:
case llvm::Triple::spirv:
case llvm::Triple::spir64:
@@ -1797,6 +1809,7 @@ Triple Triple::get32BitArchVariant() const {
case Triple::r600:
case Triple::renderscript32:
case Triple::riscv32:
+ case Triple::riscv32be:
case Triple::shave:
case Triple::sparc:
case Triple::sparcel:
@@ -1829,6 +1842,7 @@ Triple Triple::get32BitArchVariant() const {
case Triple::ppc64le: T.setArch(Triple::ppcle); break;
case Triple::renderscript64: T.setArch(Triple::renderscript32); break;
case Triple::riscv64: T.setArch(Triple::riscv32); break;
+ case Triple::riscv64be: T.setArch(Triple::riscv32be); break;
case Triple::sparcv9: T.setArch(Triple::sparc); break;
case Triple::spir64: T.setArch(Triple::spir); break;
case Triple::spirv:
@@ -1879,6 +1893,7 @@ Triple Triple::get64BitArchVariant() const {
case Triple::ppc64le:
case Triple::renderscript64:
case Triple::riscv64:
+ case Triple::riscv64be:
case Triple::sparcv9:
case Triple::spir64:
case Triple::spirv64:
@@ -1906,6 +1921,7 @@ Triple Triple::get64BitArchVariant() const {
case Triple::ppcle: T.setArch(Triple::ppc64le); break;
case Triple::renderscript32: T.setArch(Triple::renderscript64); break;
case Triple::riscv32: T.setArch(Triple::riscv64); break;
+ case Triple::riscv32be: T.setArch(Triple::riscv64be); break;
case Triple::sparc: T.setArch(Triple::sparcv9); break;
case Triple::spir: T.setArch(Triple::spir64); break;
case Triple::spirv:
@@ -1944,8 +1960,8 @@ Triple Triple::getBigEndianArchVariant() const {
case Triple::r600:
case Triple::renderscript32:
case Triple::renderscript64:
- case Triple::riscv32:
- case Triple::riscv64:
+ case Triple::riscv32be:
+ case Triple::riscv64be:
case Triple::shave:
case Triple::spir64:
case Triple::spir:
@@ -1978,6 +1994,8 @@ Triple Triple::getBigEndianArchVariant() const {
break;
case Triple::ppcle: T.setArch(Triple::ppc); break;
case Triple::ppc64le: T.setArch(Triple::ppc64); break;
+ case Triple::riscv32: T.setArch(Triple::riscv32be); break;
+ case Triple::riscv64: T.setArch(Triple::riscv64be); break;
case Triple::sparcel: T.setArch(Triple::sparc); break;
case Triple::tcele: T.setArch(Triple::tce); break;
default:
@@ -2015,6 +2033,8 @@ Triple Triple::getLittleEndianArchVariant() const {
break;
case Triple::ppc: T.setArch(Triple::ppcle); break;
case Triple::ppc64: T.setArch(Triple::ppc64le); break;
+ case Triple::riscv32be: T.setArch(Triple::riscv32); break;
+ case Triple::riscv64be: T.setArch(Triple::riscv64); break;
case Triple::sparc: T.setArch(Triple::sparcel); break;
case Triple::tce: T.setArch(Triple::tcele); break;
default:
@@ -2053,6 +2073,8 @@ bool Triple::isLittleEndian() const {
case Triple::renderscript64:
case Triple::riscv32:
case Triple::riscv64:
+ case Triple::riscv32be:
+ case Triple::riscv64be:
case Triple::shave:
case Triple::sparcel:
case Triple::spir64:
diff --git a/llvm/test/tools/llvm-objcopy/ELF/binary-output-target.test b/llvm/test/tools/llvm-objcopy/ELF/binary-output-target.test
index f88b7575002a9..3547b728a426d 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/binary-output-target.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/binary-output-target.test
@@ -33,6 +33,12 @@
# RUN: llvm-objcopy -I binary -O elf64-littleriscv %t.txt %t.rv64.o
# RUN: llvm-readobj --file-headers %t.rv64.o | FileCheck %s --check-prefixes=CHECK,LE,RISCV64,64
+# RUN: llvm-objcopy -I binary -O elf32-bigriscv %t.txt %t.rv32.o
+# RUN: llvm-readobj --file-headers %t.rv32.o | FileCheck %s --check-prefixes=CHECK,BE,RISCV32,32
+
+# RUN: llvm-objcopy -I binary -O elf64-bigriscv %t.txt %t.rv64.o
+# RUN: llvm-readobj --file-headers %t.rv64.o | FileCheck %s --check-prefixes=CHECK,BE,RISCV64,64
+
# RUN: llvm-objcopy -I binary -O elf32-sparc %t.txt %t.sparc.o
# RUN: llvm-readobj --file-headers %t.sparc.o | FileCheck %s --check-prefixes=CHECK,BE,SPARC,32
diff --git a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
index 0d209590655ef..175f77c894825 100644
--- a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
+++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
@@ -308,6 +308,8 @@ static const StringMap<MachineInfo> TargetMap{
// RISC-V
{"elf32-littleriscv", {ELF::EM_RISCV, false, true}},
{"elf64-littleriscv", {ELF::EM_RISCV, true, true}},
+ {"elf32-bigriscv", {ELF::EM_RISCV, false, false}},
+ {"elf64-bigriscv", {ELF::EM_RISCV, true, false}},
// PowerPC
{"elf32-powerpc", {ELF::EM_PPC, false, false}},
{"elf32-powerpcle", {ELF::EM_PPC, false, true}},
diff --git a/llvm/unittests/Object/ELFObjectFileTest.cpp b/llvm/unittests/Object/ELFObjectFileTest.cpp
index 423f92ea07b39..650de9dde7145 100644
--- a/llvm/unittests/Object/ELFObjectFileTest.cpp
+++ b/llvm/unittests/Object/ELFObjectFileTest.cpp
@@ -177,10 +177,10 @@ TEST(ELFObjectFileTest, MachineTestForPPC) {
}
TEST(ELFObjectFileTest, MachineTestForRISCV) {
- std::array<StringRef, 4> Formats = {"elf32-littleriscv", "elf32-littleriscv",
- "elf64-littleriscv", "elf64-littleriscv"};
- std::array<Triple::ArchType, 4> Archs = {Triple::riscv32, Triple::riscv32,
- Triple::riscv64, Triple::riscv64};
+ std::array<StringRef, 4> Formats = {"elf32-littleriscv", "elf32-bigriscv",
+ "elf64-littleriscv", "elf64-bigriscv"};
+ std::array<Triple::ArchType, 4> Archs = {Triple::riscv32, Triple::riscv32be,
+ Triple::riscv64, Triple::riscv64be};
for (auto [Idx, Data] : enumerate(generateData(ELF::EM_RISCV)))
checkFormatAndArch(Data, Formats[Idx], Archs[Idx]);
}
|
@llvm/pr-subscribers-clang Author: Djordje Todorovic (djtodoro) ChangesAdd support for big-endian RISC-V ELF files:
This is a subset of a bigger RISC-V big-endian support patch, containing only the llvm-objcopy and libObject changes. Other changes will be added later. Full diff: https://github.com/llvm/llvm-project/pull/146913.diff 8 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/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..0b983e9f7a3bc 100644
--- a/llvm/include/llvm/TargetParser/Triple.h
+++ b/llvm/include/llvm/TargetParser/Triple.h
@@ -74,8 +74,10 @@ class Triple {
ppc64le, // PPC64LE: powerpc64le
r600, // R600: AMD GPUs HD2XXX - HD6XXX
amdgcn, // AMDGCN: AMD GCN GPUs
- riscv32, // RISC-V (32-bit): riscv32
- riscv64, // RISC-V (64-bit): riscv64
+ riscv32, // RISC-V (32-bit, little endian): riscv32
+ riscv64, // RISC-V (64-bit, little endian): 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/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/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp
index a348640d75f26..19f30631196d4 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)
+ .Case("riscv64be", Triple::riscv64be)
.Case("hexagon", Triple::hexagon)
.Cases("s390x", "systemz", Triple::systemz)
.Case("sparc", Triple::sparc)
@@ -967,6 +975,8 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
case Triple::renderscript64:
case Triple::riscv32:
case Triple::riscv64:
+ case Triple::riscv32be:
+ case Triple::riscv64be:
case Triple::shave:
case Triple::sparc:
case Triple::sparcel:
@@ -1689,6 +1699,7 @@ unsigned Triple::getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
case llvm::Triple::r600:
case llvm::Triple::renderscript32:
case llvm::Triple::riscv32:
+ case llvm::Triple::riscv32be:
case llvm::Triple::shave:
case llvm::Triple::sparc:
case llvm::Triple::sparcel:
@@ -1719,6 +1730,7 @@ unsigned Triple::getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
case llvm::Triple::ppc64le:
case llvm::Triple::renderscript64:
case llvm::Triple::riscv64:
+ case llvm::Triple::riscv64be:
case llvm::Triple::sparcv9:
case llvm::Triple::spirv:
case llvm::Triple::spir64:
@@ -1797,6 +1809,7 @@ Triple Triple::get32BitArchVariant() const {
case Triple::r600:
case Triple::renderscript32:
case Triple::riscv32:
+ case Triple::riscv32be:
case Triple::shave:
case Triple::sparc:
case Triple::sparcel:
@@ -1829,6 +1842,7 @@ Triple Triple::get32BitArchVariant() const {
case Triple::ppc64le: T.setArch(Triple::ppcle); break;
case Triple::renderscript64: T.setArch(Triple::renderscript32); break;
case Triple::riscv64: T.setArch(Triple::riscv32); break;
+ case Triple::riscv64be: T.setArch(Triple::riscv32be); break;
case Triple::sparcv9: T.setArch(Triple::sparc); break;
case Triple::spir64: T.setArch(Triple::spir); break;
case Triple::spirv:
@@ -1879,6 +1893,7 @@ Triple Triple::get64BitArchVariant() const {
case Triple::ppc64le:
case Triple::renderscript64:
case Triple::riscv64:
+ case Triple::riscv64be:
case Triple::sparcv9:
case Triple::spir64:
case Triple::spirv64:
@@ -1906,6 +1921,7 @@ Triple Triple::get64BitArchVariant() const {
case Triple::ppcle: T.setArch(Triple::ppc64le); break;
case Triple::renderscript32: T.setArch(Triple::renderscript64); break;
case Triple::riscv32: T.setArch(Triple::riscv64); break;
+ case Triple::riscv32be: T.setArch(Triple::riscv64be); break;
case Triple::sparc: T.setArch(Triple::sparcv9); break;
case Triple::spir: T.setArch(Triple::spir64); break;
case Triple::spirv:
@@ -1944,8 +1960,8 @@ Triple Triple::getBigEndianArchVariant() const {
case Triple::r600:
case Triple::renderscript32:
case Triple::renderscript64:
- case Triple::riscv32:
- case Triple::riscv64:
+ case Triple::riscv32be:
+ case Triple::riscv64be:
case Triple::shave:
case Triple::spir64:
case Triple::spir:
@@ -1978,6 +1994,8 @@ Triple Triple::getBigEndianArchVariant() const {
break;
case Triple::ppcle: T.setArch(Triple::ppc); break;
case Triple::ppc64le: T.setArch(Triple::ppc64); break;
+ case Triple::riscv32: T.setArch(Triple::riscv32be); break;
+ case Triple::riscv64: T.setArch(Triple::riscv64be); break;
case Triple::sparcel: T.setArch(Triple::sparc); break;
case Triple::tcele: T.setArch(Triple::tce); break;
default:
@@ -2015,6 +2033,8 @@ Triple Triple::getLittleEndianArchVariant() const {
break;
case Triple::ppc: T.setArch(Triple::ppcle); break;
case Triple::ppc64: T.setArch(Triple::ppc64le); break;
+ case Triple::riscv32be: T.setArch(Triple::riscv32); break;
+ case Triple::riscv64be: T.setArch(Triple::riscv64); break;
case Triple::sparc: T.setArch(Triple::sparcel); break;
case Triple::tce: T.setArch(Triple::tcele); break;
default:
@@ -2053,6 +2073,8 @@ bool Triple::isLittleEndian() const {
case Triple::renderscript64:
case Triple::riscv32:
case Triple::riscv64:
+ case Triple::riscv32be:
+ case Triple::riscv64be:
case Triple::shave:
case Triple::sparcel:
case Triple::spir64:
diff --git a/llvm/test/tools/llvm-objcopy/ELF/binary-output-target.test b/llvm/test/tools/llvm-objcopy/ELF/binary-output-target.test
index f88b7575002a9..3547b728a426d 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/binary-output-target.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/binary-output-target.test
@@ -33,6 +33,12 @@
# RUN: llvm-objcopy -I binary -O elf64-littleriscv %t.txt %t.rv64.o
# RUN: llvm-readobj --file-headers %t.rv64.o | FileCheck %s --check-prefixes=CHECK,LE,RISCV64,64
+# RUN: llvm-objcopy -I binary -O elf32-bigriscv %t.txt %t.rv32.o
+# RUN: llvm-readobj --file-headers %t.rv32.o | FileCheck %s --check-prefixes=CHECK,BE,RISCV32,32
+
+# RUN: llvm-objcopy -I binary -O elf64-bigriscv %t.txt %t.rv64.o
+# RUN: llvm-readobj --file-headers %t.rv64.o | FileCheck %s --check-prefixes=CHECK,BE,RISCV64,64
+
# RUN: llvm-objcopy -I binary -O elf32-sparc %t.txt %t.sparc.o
# RUN: llvm-readobj --file-headers %t.sparc.o | FileCheck %s --check-prefixes=CHECK,BE,SPARC,32
diff --git a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
index 0d209590655ef..175f77c894825 100644
--- a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
+++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
@@ -308,6 +308,8 @@ static const StringMap<MachineInfo> TargetMap{
// RISC-V
{"elf32-littleriscv", {ELF::EM_RISCV, false, true}},
{"elf64-littleriscv", {ELF::EM_RISCV, true, true}},
+ {"elf32-bigriscv", {ELF::EM_RISCV, false, false}},
+ {"elf64-bigriscv", {ELF::EM_RISCV, true, false}},
// PowerPC
{"elf32-powerpc", {ELF::EM_PPC, false, false}},
{"elf32-powerpcle", {ELF::EM_PPC, false, true}},
diff --git a/llvm/unittests/Object/ELFObjectFileTest.cpp b/llvm/unittests/Object/ELFObjectFileTest.cpp
index 423f92ea07b39..650de9dde7145 100644
--- a/llvm/unittests/Object/ELFObjectFileTest.cpp
+++ b/llvm/unittests/Object/ELFObjectFileTest.cpp
@@ -177,10 +177,10 @@ TEST(ELFObjectFileTest, MachineTestForPPC) {
}
TEST(ELFObjectFileTest, MachineTestForRISCV) {
- std::array<StringRef, 4> Formats = {"elf32-littleriscv", "elf32-littleriscv",
- "elf64-littleriscv", "elf64-littleriscv"};
- std::array<Triple::ArchType, 4> Archs = {Triple::riscv32, Triple::riscv32,
- Triple::riscv64, Triple::riscv64};
+ std::array<StringRef, 4> Formats = {"elf32-littleriscv", "elf32-bigriscv",
+ "elf64-littleriscv", "elf64-bigriscv"};
+ std::array<Triple::ArchType, 4> Archs = {Triple::riscv32, Triple::riscv32be,
+ Triple::riscv64, Triple::riscv64be};
for (auto [Idx, Data] : enumerate(generateData(ELF::EM_RISCV)))
checkFormatAndArch(Data, Formats[Idx], Archs[Idx]);
}
|
You can test this locally with the following command:git-clang-format --diff HEAD~1 HEAD --extensions cpp,c,h -- clang/test/Driver/frame-pointer-elim.c llvm/include/llvm/Object/ELFObjectFile.h llvm/include/llvm/TargetParser/Triple.h llvm/lib/Object/RelocationResolver.cpp llvm/lib/TargetParser/Triple.cpp llvm/tools/llvm-objcopy/ObjcopyOptions.cpp llvm/unittests/Object/ELFObjectFileTest.cpp View the diff from clang-format here.diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp
index 4cf04fe9f..a1fad5aa5 100644
--- a/llvm/lib/TargetParser/Triple.cpp
+++ b/llvm/lib/TargetParser/Triple.cpp
@@ -64,8 +64,10 @@ 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 riscv32be:
+ return "riscv32be";
+ case riscv64be:
+ return "riscv64be";
case shave: return "shave";
case sparc: return "sparc";
case sparcel: return "sparcel";
@@ -242,7 +244,8 @@ StringRef Triple::getArchTypePrefix(ArchType Kind) {
case riscv32:
case riscv64:
case riscv32be:
- case riscv64be: return "riscv";
+ case riscv64be:
+ return "riscv";
case ve: return "ve";
case csky: return "csky";
@@ -1842,7 +1845,9 @@ Triple Triple::get32BitArchVariant() const {
case Triple::ppc64le: T.setArch(Triple::ppcle); break;
case Triple::renderscript64: T.setArch(Triple::renderscript32); break;
case Triple::riscv64: T.setArch(Triple::riscv32); break;
- case Triple::riscv64be: T.setArch(Triple::riscv32be); break;
+ case Triple::riscv64be:
+ T.setArch(Triple::riscv32be);
+ break;
case Triple::sparcv9: T.setArch(Triple::sparc); break;
case Triple::spir64: T.setArch(Triple::spir); break;
case Triple::spirv:
@@ -1921,7 +1926,9 @@ Triple Triple::get64BitArchVariant() const {
case Triple::ppcle: T.setArch(Triple::ppc64le); break;
case Triple::renderscript32: T.setArch(Triple::renderscript64); break;
case Triple::riscv32: T.setArch(Triple::riscv64); break;
- case Triple::riscv32be: T.setArch(Triple::riscv64be); break;
+ case Triple::riscv32be:
+ T.setArch(Triple::riscv64be);
+ break;
case Triple::sparc: T.setArch(Triple::sparcv9); break;
case Triple::spir: T.setArch(Triple::spir64); break;
case Triple::spirv:
|
Add support for big-endian RISC-V ELF files: - Add riscv32be/riscv64be target architectures to Triple - Support elf32-bigriscv and elf64-bigriscv output targets in llvm-objcopy - Update ELFObjectFile to handle BE RISC-V format strings and architecture detection - Add BE RISC-V support to RelocationResolver - Add tests for new functionality This is a subset of a bigger RISC-V big-endian support patch, containing only the llvm-objcopy and libObject changes. Other changes will be added later.
c53974a
to
a3b50d1
Compare
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.
Some inline comments.
P.S. Please use fixup commits, not force pushes, per LLVM policy, to update the PR now that I'm reviewing it.
riscv32, // RISC-V (32-bit, little endian): riscv32 | ||
riscv64, // RISC-V (64-bit, little endian): riscv64 | ||
riscv32be, // RISC-V (32-bit, big endian): riscv32be | ||
riscv64be, // RISC-V (64-bit, big endian): riscv64be |
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.
I'd love to know why clang-format disagrees with this formatting...
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.
Strange...
llvm/lib/TargetParser/Triple.cpp
Outdated
@@ -452,6 +457,8 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) { | |||
.Case("amdgcn", amdgcn) | |||
.Case("riscv32", riscv32) | |||
.Case("riscv64", riscv64) | |||
.Case("riscv32be", riscv32be) |
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.
Here and in the similar case below, we should probably abide by clang-format's formatting.
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.
yeah... I agree
llvm/lib/TargetParser/Triple.cpp
Outdated
@@ -63,6 +63,10 @@ StringRef Triple::getArchTypeName(ArchType Kind) { | |||
case renderscript64: return "renderscript64"; | |||
case riscv32: return "riscv32"; | |||
case riscv64: return "riscv64"; | |||
case riscv32be: |
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.
Follow the existing formatting?
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.
Let me try, but I think that clang-format
from CI/CD will complain...
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.
Indeed...
llvm/lib/TargetParser/Triple.cpp
Outdated
case riscv64: | ||
case riscv32be: | ||
case riscv64be: | ||
return "riscv"; |
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.
Follow the existing formatting?
llvm/lib/TargetParser/Triple.cpp
Outdated
@@ -1829,6 +1844,9 @@ Triple Triple::get32BitArchVariant() const { | |||
case Triple::ppc64le: T.setArch(Triple::ppcle); break; | |||
case Triple::renderscript64: T.setArch(Triple::renderscript32); break; | |||
case Triple::riscv64: T.setArch(Triple::riscv32); break; | |||
case Triple::riscv64be: |
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.
Follow the existing single line formatting
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.
Looks good from my point of view, once the remaining formatting comments have been addressed. Probably should have a separate person with RISC-V knowledge take a look at this too though.
Add support for big-endian RISC-V ELF files:
This is a subset of a bigger RISC-V big-endian support patch, containing only the llvm-objcopy and libObject changes. Other changes will be added later.