Skip to content

Commit a3b50d1

Browse files
committed
[llvm-objcopy][libObject] Add RISC-V big-endian support
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.
1 parent cd10ded commit a3b50d1

File tree

8 files changed

+70
-17
lines changed

8 files changed

+70
-17
lines changed

clang/test/Driver/frame-pointer-elim.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@
160160
// RUN: FileCheck --check-prefix=KEEP-ALL %s
161161
// RUN: %clang -### --target=riscv64-linux-android -O1 -S %s 2>&1 | \
162162
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
163-
// RUN: not %clang -### --target=riscv64-linux-android -mbig-endian -O1 -S %s 2>&1 | \
163+
// RUN: %clang -### --target=riscv64-linux-android -mbig-endian -O1 -S %s 2>&1 | \
164164
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
165165

166166
// On ARM backend bare metal targets, frame pointer is omitted

llvm/include/llvm/Object/ELFObjectFile.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1312,7 +1312,7 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
13121312
case ELF::EM_PPC:
13131313
return (IsLittleEndian ? "elf32-powerpcle" : "elf32-powerpc");
13141314
case ELF::EM_RISCV:
1315-
return "elf32-littleriscv";
1315+
return (IsLittleEndian ? "elf32-littleriscv" : "elf32-bigriscv");
13161316
case ELF::EM_CSKY:
13171317
return "elf32-csky";
13181318
case ELF::EM_SPARC:
@@ -1338,7 +1338,7 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
13381338
case ELF::EM_PPC64:
13391339
return (IsLittleEndian ? "elf64-powerpcle" : "elf64-powerpc");
13401340
case ELF::EM_RISCV:
1341-
return "elf64-littleriscv";
1341+
return (IsLittleEndian ? "elf64-littleriscv" : "elf64-bigriscv");
13421342
case ELF::EM_S390:
13431343
return "elf64-s390";
13441344
case ELF::EM_SPARCV9:
@@ -1400,9 +1400,9 @@ template <class ELFT> Triple::ArchType ELFObjectFile<ELFT>::getArch() const {
14001400
case ELF::EM_RISCV:
14011401
switch (EF.getHeader().e_ident[ELF::EI_CLASS]) {
14021402
case ELF::ELFCLASS32:
1403-
return Triple::riscv32;
1403+
return IsLittleEndian ? Triple::riscv32 : Triple::riscv32be;
14041404
case ELF::ELFCLASS64:
1405-
return Triple::riscv64;
1405+
return IsLittleEndian ? Triple::riscv64 : Triple::riscv64be;
14061406
default:
14071407
report_fatal_error("Invalid ELFCLASS!");
14081408
}

llvm/include/llvm/TargetParser/Triple.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,10 @@ class Triple {
7474
ppc64le, // PPC64LE: powerpc64le
7575
r600, // R600: AMD GPUs HD2XXX - HD6XXX
7676
amdgcn, // AMDGCN: AMD GCN GPUs
77-
riscv32, // RISC-V (32-bit): riscv32
78-
riscv64, // RISC-V (64-bit): riscv64
77+
riscv32, // RISC-V (32-bit, little endian): riscv32
78+
riscv64, // RISC-V (64-bit, little endian): riscv64
79+
riscv32be, // RISC-V (32-bit, big endian): riscv32be
80+
riscv64be, // RISC-V (64-bit, big endian): riscv64be
7981
sparc, // Sparc: sparc
8082
sparcv9, // Sparcv9: Sparcv9
8183
sparcel, // Sparc: (endianness = little). NB: 'Sparcle' is a CPU variant
@@ -1069,10 +1071,14 @@ class Triple {
10691071
}
10701072

10711073
/// Tests whether the target is 32-bit RISC-V.
1072-
bool isRISCV32() const { return getArch() == Triple::riscv32; }
1074+
bool isRISCV32() const {
1075+
return getArch() == Triple::riscv32 || getArch() == Triple::riscv32be;
1076+
}
10731077

10741078
/// Tests whether the target is 64-bit RISC-V.
1075-
bool isRISCV64() const { return getArch() == Triple::riscv64; }
1079+
bool isRISCV64() const {
1080+
return getArch() == Triple::riscv64 || getArch() == Triple::riscv64be;
1081+
}
10761082

10771083
/// Tests whether the target is RISC-V (32- and 64-bit).
10781084
bool isRISCV() const { return isRISCV32() || isRISCV64(); }

llvm/lib/Object/RelocationResolver.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -812,6 +812,7 @@ getRelocationResolver(const ObjectFile &Obj) {
812812
case Triple::amdgcn:
813813
return {supportsAmdgpu, resolveAmdgpu};
814814
case Triple::riscv64:
815+
case Triple::riscv64be:
815816
return {supportsRISCV, resolveRISCV};
816817
default:
817818
if (isAMDGPU(Obj))
@@ -851,6 +852,7 @@ getRelocationResolver(const ObjectFile &Obj) {
851852
case Triple::r600:
852853
return {supportsAmdgpu, resolveAmdgpu};
853854
case Triple::riscv32:
855+
case Triple::riscv32be:
854856
return {supportsRISCV, resolveRISCV};
855857
case Triple::csky:
856858
return {supportsCSKY, resolveCSKY};
@@ -897,7 +899,9 @@ uint64_t resolveRelocation(RelocationResolver Resolver, const RelocationRef &R,
897899
if (Obj->getArch() != Triple::loongarch32 &&
898900
Obj->getArch() != Triple::loongarch64 &&
899901
Obj->getArch() != Triple::riscv32 &&
900-
Obj->getArch() != Triple::riscv64)
902+
Obj->getArch() != Triple::riscv64 &&
903+
Obj->getArch() != Triple::riscv32be &&
904+
Obj->getArch() != Triple::riscv64be)
901905
LocData = 0;
902906
}
903907
}

llvm/lib/TargetParser/Triple.cpp

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ StringRef Triple::getArchTypeName(ArchType Kind) {
6363
case renderscript64: return "renderscript64";
6464
case riscv32: return "riscv32";
6565
case riscv64: return "riscv64";
66+
case riscv32be: return "riscv32be";
67+
case riscv64be: return "riscv64be";
6668
case shave: return "shave";
6769
case sparc: return "sparc";
6870
case sparcel: return "sparcel";
@@ -237,7 +239,10 @@ StringRef Triple::getArchTypePrefix(ArchType Kind) {
237239
case wasm64: return "wasm";
238240

239241
case riscv32:
240-
case riscv64: return "riscv";
242+
case riscv64:
243+
case riscv32be:
244+
case riscv64be:
245+
return "riscv";
241246

242247
case ve: return "ve";
243248
case csky: return "csky";
@@ -452,6 +457,8 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
452457
.Case("amdgcn", amdgcn)
453458
.Case("riscv32", riscv32)
454459
.Case("riscv64", riscv64)
460+
.Case("riscv32be", riscv32be)
461+
.Case("riscv64be", riscv64be)
455462
.Case("hexagon", hexagon)
456463
.Case("sparc", sparc)
457464
.Case("sparcel", sparcel)
@@ -598,6 +605,8 @@ static Triple::ArchType parseArch(StringRef ArchName) {
598605
.Case("amdgcn", Triple::amdgcn)
599606
.Case("riscv32", Triple::riscv32)
600607
.Case("riscv64", Triple::riscv64)
608+
.Case("riscv32be", Triple::riscv32be)
609+
.Case("riscv64be", Triple::riscv64be)
601610
.Case("hexagon", Triple::hexagon)
602611
.Cases("s390x", "systemz", Triple::systemz)
603612
.Case("sparc", Triple::sparc)
@@ -967,6 +976,8 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
967976
case Triple::renderscript64:
968977
case Triple::riscv32:
969978
case Triple::riscv64:
979+
case Triple::riscv32be:
980+
case Triple::riscv64be:
970981
case Triple::shave:
971982
case Triple::sparc:
972983
case Triple::sparcel:
@@ -1689,6 +1700,7 @@ unsigned Triple::getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
16891700
case llvm::Triple::r600:
16901701
case llvm::Triple::renderscript32:
16911702
case llvm::Triple::riscv32:
1703+
case llvm::Triple::riscv32be:
16921704
case llvm::Triple::shave:
16931705
case llvm::Triple::sparc:
16941706
case llvm::Triple::sparcel:
@@ -1719,6 +1731,7 @@ unsigned Triple::getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
17191731
case llvm::Triple::ppc64le:
17201732
case llvm::Triple::renderscript64:
17211733
case llvm::Triple::riscv64:
1734+
case llvm::Triple::riscv64be:
17221735
case llvm::Triple::sparcv9:
17231736
case llvm::Triple::spirv:
17241737
case llvm::Triple::spir64:
@@ -1797,6 +1810,7 @@ Triple Triple::get32BitArchVariant() const {
17971810
case Triple::r600:
17981811
case Triple::renderscript32:
17991812
case Triple::riscv32:
1813+
case Triple::riscv32be:
18001814
case Triple::shave:
18011815
case Triple::sparc:
18021816
case Triple::sparcel:
@@ -1829,6 +1843,9 @@ Triple Triple::get32BitArchVariant() const {
18291843
case Triple::ppc64le: T.setArch(Triple::ppcle); break;
18301844
case Triple::renderscript64: T.setArch(Triple::renderscript32); break;
18311845
case Triple::riscv64: T.setArch(Triple::riscv32); break;
1846+
case Triple::riscv64be:
1847+
T.setArch(Triple::riscv32be);
1848+
break;
18321849
case Triple::sparcv9: T.setArch(Triple::sparc); break;
18331850
case Triple::spir64: T.setArch(Triple::spir); break;
18341851
case Triple::spirv:
@@ -1879,6 +1896,7 @@ Triple Triple::get64BitArchVariant() const {
18791896
case Triple::ppc64le:
18801897
case Triple::renderscript64:
18811898
case Triple::riscv64:
1899+
case Triple::riscv64be:
18821900
case Triple::sparcv9:
18831901
case Triple::spir64:
18841902
case Triple::spirv64:
@@ -1906,6 +1924,9 @@ Triple Triple::get64BitArchVariant() const {
19061924
case Triple::ppcle: T.setArch(Triple::ppc64le); break;
19071925
case Triple::renderscript32: T.setArch(Triple::renderscript64); break;
19081926
case Triple::riscv32: T.setArch(Triple::riscv64); break;
1927+
case Triple::riscv32be:
1928+
T.setArch(Triple::riscv64be);
1929+
break;
19091930
case Triple::sparc: T.setArch(Triple::sparcv9); break;
19101931
case Triple::spir: T.setArch(Triple::spir64); break;
19111932
case Triple::spirv:
@@ -1944,8 +1965,8 @@ Triple Triple::getBigEndianArchVariant() const {
19441965
case Triple::r600:
19451966
case Triple::renderscript32:
19461967
case Triple::renderscript64:
1947-
case Triple::riscv32:
1948-
case Triple::riscv64:
1968+
case Triple::riscv32be:
1969+
case Triple::riscv64be:
19491970
case Triple::shave:
19501971
case Triple::spir64:
19511972
case Triple::spir:
@@ -1978,6 +1999,12 @@ Triple Triple::getBigEndianArchVariant() const {
19781999
break;
19792000
case Triple::ppcle: T.setArch(Triple::ppc); break;
19802001
case Triple::ppc64le: T.setArch(Triple::ppc64); break;
2002+
case Triple::riscv32:
2003+
T.setArch(Triple::riscv32be);
2004+
break;
2005+
case Triple::riscv64:
2006+
T.setArch(Triple::riscv64be);
2007+
break;
19812008
case Triple::sparcel: T.setArch(Triple::sparc); break;
19822009
case Triple::tcele: T.setArch(Triple::tce); break;
19832010
default:
@@ -2015,6 +2042,12 @@ Triple Triple::getLittleEndianArchVariant() const {
20152042
break;
20162043
case Triple::ppc: T.setArch(Triple::ppcle); break;
20172044
case Triple::ppc64: T.setArch(Triple::ppc64le); break;
2045+
case Triple::riscv32be:
2046+
T.setArch(Triple::riscv32);
2047+
break;
2048+
case Triple::riscv64be:
2049+
T.setArch(Triple::riscv64);
2050+
break;
20182051
case Triple::sparc: T.setArch(Triple::sparcel); break;
20192052
case Triple::tce: T.setArch(Triple::tcele); break;
20202053
default:
@@ -2053,6 +2086,8 @@ bool Triple::isLittleEndian() const {
20532086
case Triple::renderscript64:
20542087
case Triple::riscv32:
20552088
case Triple::riscv64:
2089+
case Triple::riscv32be:
2090+
case Triple::riscv64be:
20562091
case Triple::shave:
20572092
case Triple::sparcel:
20582093
case Triple::spir64:

llvm/test/tools/llvm-objcopy/ELF/binary-output-target.test

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@
3333
# RUN: llvm-objcopy -I binary -O elf64-littleriscv %t.txt %t.rv64.o
3434
# RUN: llvm-readobj --file-headers %t.rv64.o | FileCheck %s --check-prefixes=CHECK,LE,RISCV64,64
3535

36+
# RUN: llvm-objcopy -I binary -O elf32-bigriscv %t.txt %t.rv32.o
37+
# RUN: llvm-readobj --file-headers %t.rv32.o | FileCheck %s --check-prefixes=CHECK,BE,RISCV32,32
38+
39+
# RUN: llvm-objcopy -I binary -O elf64-bigriscv %t.txt %t.rv64.o
40+
# RUN: llvm-readobj --file-headers %t.rv64.o | FileCheck %s --check-prefixes=CHECK,BE,RISCV64,64
41+
3642
# RUN: llvm-objcopy -I binary -O elf32-sparc %t.txt %t.sparc.o
3743
# RUN: llvm-readobj --file-headers %t.sparc.o | FileCheck %s --check-prefixes=CHECK,BE,SPARC,32
3844

llvm/tools/llvm-objcopy/ObjcopyOptions.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,8 @@ static const StringMap<MachineInfo> TargetMap{
308308
// RISC-V
309309
{"elf32-littleriscv", {ELF::EM_RISCV, false, true}},
310310
{"elf64-littleriscv", {ELF::EM_RISCV, true, true}},
311+
{"elf32-bigriscv", {ELF::EM_RISCV, false, false}},
312+
{"elf64-bigriscv", {ELF::EM_RISCV, true, false}},
311313
// PowerPC
312314
{"elf32-powerpc", {ELF::EM_PPC, false, false}},
313315
{"elf32-powerpcle", {ELF::EM_PPC, false, true}},

llvm/unittests/Object/ELFObjectFileTest.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,10 +177,10 @@ TEST(ELFObjectFileTest, MachineTestForPPC) {
177177
}
178178

179179
TEST(ELFObjectFileTest, MachineTestForRISCV) {
180-
std::array<StringRef, 4> Formats = {"elf32-littleriscv", "elf32-littleriscv",
181-
"elf64-littleriscv", "elf64-littleriscv"};
182-
std::array<Triple::ArchType, 4> Archs = {Triple::riscv32, Triple::riscv32,
183-
Triple::riscv64, Triple::riscv64};
180+
std::array<StringRef, 4> Formats = {"elf32-littleriscv", "elf32-bigriscv",
181+
"elf64-littleriscv", "elf64-bigriscv"};
182+
std::array<Triple::ArchType, 4> Archs = {Triple::riscv32, Triple::riscv32be,
183+
Triple::riscv64, Triple::riscv64be};
184184
for (auto [Idx, Data] : enumerate(generateData(ELF::EM_RISCV)))
185185
checkFormatAndArch(Data, Formats[Idx], Archs[Idx]);
186186
}

0 commit comments

Comments
 (0)