Skip to content

Commit 8f00447

Browse files
committed
[PowerPC] Add the LLVM triple for powerpcle [1/5]
Add a triple for powerpcle-*-*. This is a little-endian encoding of the 32-bit PowerPC ABI, useful in certain niche situations: 1) A loader such as the FreeBSD loader which will be loading a little endian kernel. This is required for PowerPC64LE to load properly in pseries VMs. Such a loader is implemented as a freestanding ELF32 LSB binary. 2) Userspace emulation of a 32-bit LE architecture such as x86 on 64-bit hosts such as PowerPC64LE with tools like box86 requires having a 32-bit LE toolchain and library set, as they operate by translating only the main binary and switching to native code when making library calls. 3) The Void Linux for PowerPC project is experimenting with running an entire powerpcle userland. Reviewed By: MaskRay Differential Revision: https://reviews.llvm.org/D93918
1 parent d5317b4 commit 8f00447

File tree

16 files changed

+62
-18
lines changed

16 files changed

+62
-18
lines changed

llvm/cmake/config.guess

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -973,6 +973,9 @@ EOF
973973
ppc:Linux:*:*)
974974
echo powerpc-unknown-linux-gnu
975975
exit ;;
976+
ppcle:Linux:*:*)
977+
echo powerpcle-unknown-linux-gnu
978+
exit ;;
976979
riscv32:Linux:*:* | riscv64:Linux:*:*)
977980
LIBC=gnu
978981
eval $set_cc_for_build

llvm/include/llvm/ADT/Triple.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class Triple {
6464
mips64el, // MIPS64EL: mips64el, mips64r6el, mipsn32el, mipsn32r6el
6565
msp430, // MSP430: msp430
6666
ppc, // PPC: powerpc
67+
ppcle, // PPCLE: powerpc (little endian)
6768
ppc64, // PPC64: powerpc64, ppu
6869
ppc64le, // PPC64LE: powerpc64le
6970
r600, // R600: AMD GPUs HD2XXX - HD6XXX
@@ -745,6 +746,17 @@ class Triple {
745746
return isMIPS32() || isMIPS64();
746747
}
747748

749+
/// Tests whether the target is PowerPC (32- or 64-bit LE or BE).
750+
bool isPPC() const {
751+
return getArch() == Triple::ppc || getArch() == Triple::ppc64 ||
752+
getArch() == Triple::ppcle || getArch() == Triple::ppc64le;
753+
}
754+
755+
/// Tests whether the target is 32-bit PowerPC (little and big endian).
756+
bool isPPC32() const {
757+
return getArch() == Triple::ppc || getArch() == Triple::ppcle;
758+
}
759+
748760
/// Tests whether the target is 64-bit PowerPC (little and big endian).
749761
bool isPPC64() const {
750762
return getArch() == Triple::ppc64 || getArch() == Triple::ppc64le;

llvm/lib/CodeGen/TargetLoweringBase.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ void TargetLoweringBase::InitLibcalls(const Triple &TT) {
135135
setLibcallCallingConv((RTLIB::Libcall)LC, CallingConv::C);
136136

137137
// For IEEE quad-precision libcall names, PPC uses "kf" instead of "tf".
138-
if (TT.getArch() == Triple::ppc || TT.isPPC64()) {
138+
if (TT.isPPC()) {
139139
setLibcallName(RTLIB::ADD_F128, "__addkf3");
140140
setLibcallName(RTLIB::SUB_F128, "__subkf3");
141141
setLibcallName(RTLIB::MUL_F128, "__mulkf3");

llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
128128
// Fallthrough if not using EHABI
129129
LLVM_FALLTHROUGH;
130130
case Triple::ppc:
131+
case Triple::ppcle:
131132
case Triple::x86:
132133
PersonalityEncoding = isPositionIndependent()
133134
? dwarf::DW_EH_PE_indirect |

llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -954,7 +954,8 @@ void RuntimeDyldELF::resolveRelocation(const SectionEntry &Section,
954954
resolveARMRelocation(Section, Offset, (uint32_t)(Value & 0xffffffffL), Type,
955955
(uint32_t)(Addend & 0xffffffffL));
956956
break;
957-
case Triple::ppc:
957+
case Triple::ppc: // Fall through.
958+
case Triple::ppcle:
958959
resolvePPC32Relocation(Section, Offset, Value, Type, Addend);
959960
break;
960961
case Triple::ppc64: // Fall through.

llvm/lib/Support/Triple.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ StringRef Triple::getArchTypeName(ArchType Kind) {
5454
case ppc64: return "powerpc64";
5555
case ppc64le: return "powerpc64le";
5656
case ppc: return "powerpc";
57+
case ppcle: return "powerpcle";
5758
case r600: return "r600";
5859
case renderscript32: return "renderscript32";
5960
case renderscript64: return "renderscript64";
@@ -101,7 +102,8 @@ StringRef Triple::getArchTypePrefix(ArchType Kind) {
101102

102103
case ppc64:
103104
case ppc64le:
104-
case ppc: return "ppc";
105+
case ppc:
106+
case ppcle: return "ppc";
105107

106108
case mips:
107109
case mipsel:
@@ -286,6 +288,8 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
286288
.Case("ppc64", ppc64)
287289
.Case("ppc32", ppc)
288290
.Case("ppc", ppc)
291+
.Case("ppc32le", ppcle)
292+
.Case("ppcle", ppcle)
289293
.Case("ppc64le", ppc64le)
290294
.Case("r600", r600)
291295
.Case("amdgcn", amdgcn)
@@ -397,6 +401,7 @@ static Triple::ArchType parseArch(StringRef ArchName) {
397401
.Cases("i786", "i886", "i986", Triple::x86)
398402
.Cases("amd64", "x86_64", "x86_64h", Triple::x86_64)
399403
.Cases("powerpc", "powerpcspe", "ppc", "ppc32", Triple::ppc)
404+
.Cases("powerpcle", "ppcle", "ppc32le", Triple::ppcle)
400405
.Cases("powerpc64", "ppu", "ppc64", Triple::ppc64)
401406
.Cases("powerpc64le", "ppc64le", Triple::ppc64le)
402407
.Case("xscale", Triple::arm)
@@ -704,6 +709,7 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
704709
case Triple::nvptx64:
705710
case Triple::nvptx:
706711
case Triple::ppc64le:
712+
case Triple::ppcle:
707713
case Triple::r600:
708714
case Triple::renderscript32:
709715
case Triple::renderscript64:
@@ -1272,6 +1278,7 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
12721278
case llvm::Triple::mipsel:
12731279
case llvm::Triple::nvptx:
12741280
case llvm::Triple::ppc:
1281+
case llvm::Triple::ppcle:
12751282
case llvm::Triple::r600:
12761283
case llvm::Triple::renderscript32:
12771284
case llvm::Triple::riscv32:
@@ -1335,7 +1342,6 @@ Triple Triple::get32BitArchVariant() const {
13351342
case Triple::bpfeb:
13361343
case Triple::bpfel:
13371344
case Triple::msp430:
1338-
case Triple::ppc64le:
13391345
case Triple::systemz:
13401346
case Triple::ve:
13411347
T.setArch(UnknownArch);
@@ -1356,6 +1362,7 @@ Triple Triple::get32BitArchVariant() const {
13561362
case Triple::mipsel:
13571363
case Triple::nvptx:
13581364
case Triple::ppc:
1365+
case Triple::ppcle:
13591366
case Triple::r600:
13601367
case Triple::renderscript32:
13611368
case Triple::riscv32:
@@ -1382,6 +1389,7 @@ Triple Triple::get32BitArchVariant() const {
13821389
case Triple::mips64el: T.setArch(Triple::mipsel); break;
13831390
case Triple::nvptx64: T.setArch(Triple::nvptx); break;
13841391
case Triple::ppc64: T.setArch(Triple::ppc); break;
1392+
case Triple::ppc64le: T.setArch(Triple::ppcle); break;
13851393
case Triple::renderscript64: T.setArch(Triple::renderscript32); break;
13861394
case Triple::riscv64: T.setArch(Triple::riscv32); break;
13871395
case Triple::sparcv9: T.setArch(Triple::sparc); break;
@@ -1446,6 +1454,7 @@ Triple Triple::get64BitArchVariant() const {
14461454
case Triple::mipsel: T.setArch(Triple::mips64el); break;
14471455
case Triple::nvptx: T.setArch(Triple::nvptx64); break;
14481456
case Triple::ppc: T.setArch(Triple::ppc64); break;
1457+
case Triple::ppcle: T.setArch(Triple::ppc64le); break;
14491458
case Triple::renderscript32: T.setArch(Triple::renderscript64); break;
14501459
case Triple::riscv32: T.setArch(Triple::riscv64); break;
14511460
case Triple::sparc: T.setArch(Triple::sparcv9); break;
@@ -1505,6 +1514,7 @@ Triple Triple::getBigEndianArchVariant() const {
15051514
case Triple::bpfel: T.setArch(Triple::bpfeb); break;
15061515
case Triple::mips64el:T.setArch(Triple::mips64); break;
15071516
case Triple::mipsel: T.setArch(Triple::mips); break;
1517+
case Triple::ppcle: T.setArch(Triple::ppc); break;
15081518
case Triple::ppc64le: T.setArch(Triple::ppc64); break;
15091519
case Triple::sparcel: T.setArch(Triple::sparc); break;
15101520
case Triple::tcele: T.setArch(Triple::tce); break;
@@ -1522,7 +1532,6 @@ Triple Triple::getLittleEndianArchVariant() const {
15221532
switch (getArch()) {
15231533
case Triple::UnknownArch:
15241534
case Triple::lanai:
1525-
case Triple::ppc:
15261535
case Triple::sparcv9:
15271536
case Triple::systemz:
15281537

@@ -1537,6 +1546,7 @@ Triple Triple::getLittleEndianArchVariant() const {
15371546
case Triple::bpfeb: T.setArch(Triple::bpfel); break;
15381547
case Triple::mips64: T.setArch(Triple::mips64el); break;
15391548
case Triple::mips: T.setArch(Triple::mipsel); break;
1549+
case Triple::ppc: T.setArch(Triple::ppcle); break;
15401550
case Triple::ppc64: T.setArch(Triple::ppc64le); break;
15411551
case Triple::sparc: T.setArch(Triple::sparcel); break;
15421552
case Triple::tce: T.setArch(Triple::tcele); break;
@@ -1568,6 +1578,7 @@ bool Triple::isLittleEndian() const {
15681578
case Triple::msp430:
15691579
case Triple::nvptx64:
15701580
case Triple::nvptx:
1581+
case Triple::ppcle:
15711582
case Triple::ppc64le:
15721583
case Triple::r600:
15731584
case Triple::renderscript32:

llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1716,8 +1716,9 @@ bool PPCAsmParser::ParseDirectiveLocalEntry(SMLoc L) {
17161716
/// Force static initialization.
17171717
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmParser() {
17181718
RegisterMCAsmParser<PPCAsmParser> A(getThePPC32Target());
1719-
RegisterMCAsmParser<PPCAsmParser> B(getThePPC64Target());
1720-
RegisterMCAsmParser<PPCAsmParser> C(getThePPC64LETarget());
1719+
RegisterMCAsmParser<PPCAsmParser> B(getThePPC32LETarget());
1720+
RegisterMCAsmParser<PPCAsmParser> C(getThePPC64Target());
1721+
RegisterMCAsmParser<PPCAsmParser> D(getThePPC64LETarget());
17211722
}
17221723

17231724
#define GET_REGISTER_MATCHER

llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCDisassembler() {
5454
// Register the disassembler for each target.
5555
TargetRegistry::RegisterMCDisassembler(getThePPC32Target(),
5656
createPPCDisassembler);
57+
TargetRegistry::RegisterMCDisassembler(getThePPC32LETarget(),
58+
createPPCLEDisassembler);
5759
TargetRegistry::RegisterMCDisassembler(getThePPC64Target(),
5860
createPPCDisassembler);
5961
TargetRegistry::RegisterMCDisassembler(getThePPC64LETarget(),

llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ PPCELFMCAsmInfo::PPCELFMCAsmInfo(bool is64Bit, const Triple& T) {
2626
if (is64Bit) {
2727
CodePointerSize = CalleeSaveStackSlotSize = 8;
2828
}
29-
IsLittleEndian = T.getArch() == Triple::ppc64le;
29+
IsLittleEndian =
30+
T.getArch() == Triple::ppc64le || T.getArch() == Triple::ppcle;
3031

3132
// ".comm align is in bytes but .align is pow-2."
3233
AlignmentIsInBytes = false;
@@ -56,7 +57,7 @@ PPCELFMCAsmInfo::PPCELFMCAsmInfo(bool is64Bit, const Triple& T) {
5657
void PPCXCOFFMCAsmInfo::anchor() {}
5758

5859
PPCXCOFFMCAsmInfo::PPCXCOFFMCAsmInfo(bool Is64Bit, const Triple &T) {
59-
if (T.getArch() == Triple::ppc64le)
60+
if (T.getArch() == Triple::ppc64le || T.getArch() == Triple::ppcle)
6061
report_fatal_error("XCOFF is not supported for little-endian targets");
6162
CodePointerSize = CalleeSaveStackSlotSize = Is64Bit ? 8 : 4;
6263

llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,8 +336,8 @@ static MCInstPrinter *createPPCMCInstPrinter(const Triple &T,
336336
}
337337

338338
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCTargetMC() {
339-
for (Target *T :
340-
{&getThePPC32Target(), &getThePPC64Target(), &getThePPC64LETarget()}) {
339+
for (Target *T : {&getThePPC32Target(), &getThePPC32LETarget(),
340+
&getThePPC64Target(), &getThePPC64LETarget()}) {
341341
// Register the MC asm info.
342342
RegisterMCAsmInfoFn C(*T, createPPCMCAsmInfo);
343343

llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2373,6 +2373,8 @@ createPPCAsmPrinterPass(TargetMachine &tm,
23732373
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmPrinter() {
23742374
TargetRegistry::RegisterAsmPrinter(getThePPC32Target(),
23752375
createPPCAsmPrinterPass);
2376+
TargetRegistry::RegisterAsmPrinter(getThePPC32LETarget(),
2377+
createPPCAsmPrinterPass);
23762378
TargetRegistry::RegisterAsmPrinter(getThePPC64Target(),
23772379
createPPCAsmPrinterPass);
23782380
TargetRegistry::RegisterAsmPrinter(getThePPC64LETarget(),

llvm/lib/Target/PowerPC/PPCSubtarget.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,8 @@ void PPCSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {
179179

180180
// Determine endianness.
181181
// FIXME: Part of the TargetMachine.
182-
IsLittleEndian = (TargetTriple.getArch() == Triple::ppc64le);
182+
IsLittleEndian = (TargetTriple.getArch() == Triple::ppc64le ||
183+
TargetTriple.getArch() == Triple::ppcle);
183184
}
184185

185186
bool PPCSubtarget::enableMachineScheduler() const { return true; }

llvm/lib/Target/PowerPC/PPCTargetMachine.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,9 @@ static cl::opt<bool>
100100
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCTarget() {
101101
// Register the targets
102102
RegisterTargetMachine<PPCTargetMachine> A(getThePPC32Target());
103-
RegisterTargetMachine<PPCTargetMachine> B(getThePPC64Target());
104-
RegisterTargetMachine<PPCTargetMachine> C(getThePPC64LETarget());
103+
RegisterTargetMachine<PPCTargetMachine> B(getThePPC32LETarget());
104+
RegisterTargetMachine<PPCTargetMachine> C(getThePPC64Target());
105+
RegisterTargetMachine<PPCTargetMachine> D(getThePPC64LETarget());
105106

106107
PassRegistry &PR = *PassRegistry::getPassRegistry();
107108
#ifndef NDEBUG
@@ -130,8 +131,8 @@ static std::string getDataLayoutString(const Triple &T) {
130131
bool is64Bit = T.getArch() == Triple::ppc64 || T.getArch() == Triple::ppc64le;
131132
std::string Ret;
132133

133-
// Most PPC* platforms are big endian, PPC64LE is little endian.
134-
if (T.getArch() == Triple::ppc64le)
134+
// Most PPC* platforms are big endian, PPC(64)LE is little endian.
135+
if (T.getArch() == Triple::ppc64le || T.getArch() == Triple::ppcle)
135136
Ret = "e";
136137
else
137138
Ret = "E";

llvm/lib/Target/PowerPC/TargetInfo/PowerPCTargetInfo.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ Target &llvm::getThePPC32Target() {
1414
static Target ThePPC32Target;
1515
return ThePPC32Target;
1616
}
17+
Target &llvm::getThePPC32LETarget() {
18+
static Target ThePPC32LETarget;
19+
return ThePPC32LETarget;
20+
}
1721
Target &llvm::getThePPC64Target() {
1822
static Target ThePPC64Target;
1923
return ThePPC64Target;
@@ -24,9 +28,12 @@ Target &llvm::getThePPC64LETarget() {
2428
}
2529

2630
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCTargetInfo() {
27-
RegisterTarget<Triple::ppc, /*HasJIT=*/true> X(getThePPC32Target(), "ppc32",
31+
RegisterTarget<Triple::ppc, /*HasJIT=*/true> W(getThePPC32Target(), "ppc32",
2832
"PowerPC 32", "PPC");
2933

34+
RegisterTarget<Triple::ppcle, /*HasJIT=*/true> X(
35+
getThePPC32LETarget(), "ppc32le", "PowerPC 32 LE", "PPC");
36+
3037
RegisterTarget<Triple::ppc64, /*HasJIT=*/true> Y(getThePPC64Target(), "ppc64",
3138
"PowerPC 64", "PPC");
3239

llvm/lib/Target/PowerPC/TargetInfo/PowerPCTargetInfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ namespace llvm {
1414
class Target;
1515

1616
Target &getThePPC32Target();
17+
Target &getThePPC32LETarget();
1718
Target &getThePPC64Target();
1819
Target &getThePPC64LETarget();
1920

llvm/unittests/ADT/TripleTest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1111,7 +1111,7 @@ TEST(TripleTest, EndianArchVariants) {
11111111

11121112
T.setArch(Triple::ppc);
11131113
EXPECT_EQ(Triple::ppc, T.getBigEndianArchVariant().getArch());
1114-
EXPECT_EQ(Triple::UnknownArch, T.getLittleEndianArchVariant().getArch());
1114+
EXPECT_EQ(Triple::ppcle, T.getLittleEndianArchVariant().getArch());
11151115

11161116
T.setArch(Triple::ppc64);
11171117
EXPECT_EQ(Triple::ppc64, T.getBigEndianArchVariant().getArch());

0 commit comments

Comments
 (0)