1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 10:42:39 +01:00

[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
This commit is contained in:
Brandon Bergren 2021-01-02 12:17:22 -06:00
parent e3a5266640
commit 3adc8af0ca
16 changed files with 62 additions and 18 deletions

3
cmake/config.guess vendored
View File

@ -973,6 +973,9 @@ EOF
ppc:Linux:*:*) ppc:Linux:*:*)
echo powerpc-unknown-linux-gnu echo powerpc-unknown-linux-gnu
exit ;; exit ;;
ppcle:Linux:*:*)
echo powerpcle-unknown-linux-gnu
exit ;;
riscv32:Linux:*:* | riscv64:Linux:*:*) riscv32:Linux:*:* | riscv64:Linux:*:*)
LIBC=gnu LIBC=gnu
eval $set_cc_for_build eval $set_cc_for_build

View File

@ -64,6 +64,7 @@ public:
mips64el, // MIPS64EL: mips64el, mips64r6el, mipsn32el, mipsn32r6el mips64el, // MIPS64EL: mips64el, mips64r6el, mipsn32el, mipsn32r6el
msp430, // MSP430: msp430 msp430, // MSP430: msp430
ppc, // PPC: powerpc ppc, // PPC: powerpc
ppcle, // PPCLE: powerpc (little endian)
ppc64, // PPC64: powerpc64, ppu ppc64, // PPC64: powerpc64, ppu
ppc64le, // PPC64LE: powerpc64le ppc64le, // PPC64LE: powerpc64le
r600, // R600: AMD GPUs HD2XXX - HD6XXX r600, // R600: AMD GPUs HD2XXX - HD6XXX
@ -745,6 +746,17 @@ public:
return isMIPS32() || isMIPS64(); return isMIPS32() || isMIPS64();
} }
/// Tests whether the target is PowerPC (32- or 64-bit LE or BE).
bool isPPC() const {
return getArch() == Triple::ppc || getArch() == Triple::ppc64 ||
getArch() == Triple::ppcle || getArch() == Triple::ppc64le;
}
/// Tests whether the target is 32-bit PowerPC (little and big endian).
bool isPPC32() const {
return getArch() == Triple::ppc || getArch() == Triple::ppcle;
}
/// Tests whether the target is 64-bit PowerPC (little and big endian). /// Tests whether the target is 64-bit PowerPC (little and big endian).
bool isPPC64() const { bool isPPC64() const {
return getArch() == Triple::ppc64 || getArch() == Triple::ppc64le; return getArch() == Triple::ppc64 || getArch() == Triple::ppc64le;

View File

@ -135,7 +135,7 @@ void TargetLoweringBase::InitLibcalls(const Triple &TT) {
setLibcallCallingConv((RTLIB::Libcall)LC, CallingConv::C); setLibcallCallingConv((RTLIB::Libcall)LC, CallingConv::C);
// For IEEE quad-precision libcall names, PPC uses "kf" instead of "tf". // For IEEE quad-precision libcall names, PPC uses "kf" instead of "tf".
if (TT.getArch() == Triple::ppc || TT.isPPC64()) { if (TT.isPPC()) {
setLibcallName(RTLIB::ADD_F128, "__addkf3"); setLibcallName(RTLIB::ADD_F128, "__addkf3");
setLibcallName(RTLIB::SUB_F128, "__subkf3"); setLibcallName(RTLIB::SUB_F128, "__subkf3");
setLibcallName(RTLIB::MUL_F128, "__mulkf3"); setLibcallName(RTLIB::MUL_F128, "__mulkf3");

View File

@ -128,6 +128,7 @@ void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
// Fallthrough if not using EHABI // Fallthrough if not using EHABI
LLVM_FALLTHROUGH; LLVM_FALLTHROUGH;
case Triple::ppc: case Triple::ppc:
case Triple::ppcle:
case Triple::x86: case Triple::x86:
PersonalityEncoding = isPositionIndependent() PersonalityEncoding = isPositionIndependent()
? dwarf::DW_EH_PE_indirect | ? dwarf::DW_EH_PE_indirect |

View File

@ -954,7 +954,8 @@ void RuntimeDyldELF::resolveRelocation(const SectionEntry &Section,
resolveARMRelocation(Section, Offset, (uint32_t)(Value & 0xffffffffL), Type, resolveARMRelocation(Section, Offset, (uint32_t)(Value & 0xffffffffL), Type,
(uint32_t)(Addend & 0xffffffffL)); (uint32_t)(Addend & 0xffffffffL));
break; break;
case Triple::ppc: case Triple::ppc: // Fall through.
case Triple::ppcle:
resolvePPC32Relocation(Section, Offset, Value, Type, Addend); resolvePPC32Relocation(Section, Offset, Value, Type, Addend);
break; break;
case Triple::ppc64: // Fall through. case Triple::ppc64: // Fall through.

View File

@ -54,6 +54,7 @@ StringRef Triple::getArchTypeName(ArchType Kind) {
case ppc64: return "powerpc64"; case ppc64: return "powerpc64";
case ppc64le: return "powerpc64le"; case ppc64le: return "powerpc64le";
case ppc: return "powerpc"; case ppc: return "powerpc";
case ppcle: return "powerpcle";
case r600: return "r600"; case r600: return "r600";
case renderscript32: return "renderscript32"; case renderscript32: return "renderscript32";
case renderscript64: return "renderscript64"; case renderscript64: return "renderscript64";
@ -101,7 +102,8 @@ StringRef Triple::getArchTypePrefix(ArchType Kind) {
case ppc64: case ppc64:
case ppc64le: case ppc64le:
case ppc: return "ppc"; case ppc:
case ppcle: return "ppc";
case mips: case mips:
case mipsel: case mipsel:
@ -286,6 +288,8 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
.Case("ppc64", ppc64) .Case("ppc64", ppc64)
.Case("ppc32", ppc) .Case("ppc32", ppc)
.Case("ppc", ppc) .Case("ppc", ppc)
.Case("ppc32le", ppcle)
.Case("ppcle", ppcle)
.Case("ppc64le", ppc64le) .Case("ppc64le", ppc64le)
.Case("r600", r600) .Case("r600", r600)
.Case("amdgcn", amdgcn) .Case("amdgcn", amdgcn)
@ -397,6 +401,7 @@ static Triple::ArchType parseArch(StringRef ArchName) {
.Cases("i786", "i886", "i986", Triple::x86) .Cases("i786", "i886", "i986", Triple::x86)
.Cases("amd64", "x86_64", "x86_64h", Triple::x86_64) .Cases("amd64", "x86_64", "x86_64h", Triple::x86_64)
.Cases("powerpc", "powerpcspe", "ppc", "ppc32", Triple::ppc) .Cases("powerpc", "powerpcspe", "ppc", "ppc32", Triple::ppc)
.Cases("powerpcle", "ppcle", "ppc32le", Triple::ppcle)
.Cases("powerpc64", "ppu", "ppc64", Triple::ppc64) .Cases("powerpc64", "ppu", "ppc64", Triple::ppc64)
.Cases("powerpc64le", "ppc64le", Triple::ppc64le) .Cases("powerpc64le", "ppc64le", Triple::ppc64le)
.Case("xscale", Triple::arm) .Case("xscale", Triple::arm)
@ -704,6 +709,7 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
case Triple::nvptx64: case Triple::nvptx64:
case Triple::nvptx: case Triple::nvptx:
case Triple::ppc64le: case Triple::ppc64le:
case Triple::ppcle:
case Triple::r600: case Triple::r600:
case Triple::renderscript32: case Triple::renderscript32:
case Triple::renderscript64: case Triple::renderscript64:
@ -1272,6 +1278,7 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
case llvm::Triple::mipsel: case llvm::Triple::mipsel:
case llvm::Triple::nvptx: case llvm::Triple::nvptx:
case llvm::Triple::ppc: case llvm::Triple::ppc:
case llvm::Triple::ppcle:
case llvm::Triple::r600: case llvm::Triple::r600:
case llvm::Triple::renderscript32: case llvm::Triple::renderscript32:
case llvm::Triple::riscv32: case llvm::Triple::riscv32:
@ -1335,7 +1342,6 @@ Triple Triple::get32BitArchVariant() const {
case Triple::bpfeb: case Triple::bpfeb:
case Triple::bpfel: case Triple::bpfel:
case Triple::msp430: case Triple::msp430:
case Triple::ppc64le:
case Triple::systemz: case Triple::systemz:
case Triple::ve: case Triple::ve:
T.setArch(UnknownArch); T.setArch(UnknownArch);
@ -1356,6 +1362,7 @@ Triple Triple::get32BitArchVariant() const {
case Triple::mipsel: case Triple::mipsel:
case Triple::nvptx: case Triple::nvptx:
case Triple::ppc: case Triple::ppc:
case Triple::ppcle:
case Triple::r600: case Triple::r600:
case Triple::renderscript32: case Triple::renderscript32:
case Triple::riscv32: case Triple::riscv32:
@ -1382,6 +1389,7 @@ Triple Triple::get32BitArchVariant() const {
case Triple::mips64el: T.setArch(Triple::mipsel); break; case Triple::mips64el: T.setArch(Triple::mipsel); break;
case Triple::nvptx64: T.setArch(Triple::nvptx); break; case Triple::nvptx64: T.setArch(Triple::nvptx); break;
case Triple::ppc64: T.setArch(Triple::ppc); break; case Triple::ppc64: T.setArch(Triple::ppc); break;
case Triple::ppc64le: T.setArch(Triple::ppcle); break;
case Triple::renderscript64: T.setArch(Triple::renderscript32); break; case Triple::renderscript64: T.setArch(Triple::renderscript32); break;
case Triple::riscv64: T.setArch(Triple::riscv32); break; case Triple::riscv64: T.setArch(Triple::riscv32); break;
case Triple::sparcv9: T.setArch(Triple::sparc); break; case Triple::sparcv9: T.setArch(Triple::sparc); break;
@ -1446,6 +1454,7 @@ Triple Triple::get64BitArchVariant() const {
case Triple::mipsel: T.setArch(Triple::mips64el); break; case Triple::mipsel: T.setArch(Triple::mips64el); break;
case Triple::nvptx: T.setArch(Triple::nvptx64); break; case Triple::nvptx: T.setArch(Triple::nvptx64); break;
case Triple::ppc: T.setArch(Triple::ppc64); break; case Triple::ppc: T.setArch(Triple::ppc64); break;
case Triple::ppcle: T.setArch(Triple::ppc64le); break;
case Triple::renderscript32: T.setArch(Triple::renderscript64); break; case Triple::renderscript32: T.setArch(Triple::renderscript64); break;
case Triple::riscv32: T.setArch(Triple::riscv64); break; case Triple::riscv32: T.setArch(Triple::riscv64); break;
case Triple::sparc: T.setArch(Triple::sparcv9); break; case Triple::sparc: T.setArch(Triple::sparcv9); break;
@ -1505,6 +1514,7 @@ Triple Triple::getBigEndianArchVariant() const {
case Triple::bpfel: T.setArch(Triple::bpfeb); break; case Triple::bpfel: T.setArch(Triple::bpfeb); break;
case Triple::mips64el:T.setArch(Triple::mips64); break; case Triple::mips64el:T.setArch(Triple::mips64); break;
case Triple::mipsel: T.setArch(Triple::mips); break; case Triple::mipsel: T.setArch(Triple::mips); break;
case Triple::ppcle: T.setArch(Triple::ppc); break;
case Triple::ppc64le: T.setArch(Triple::ppc64); break; case Triple::ppc64le: T.setArch(Triple::ppc64); break;
case Triple::sparcel: T.setArch(Triple::sparc); break; case Triple::sparcel: T.setArch(Triple::sparc); break;
case Triple::tcele: T.setArch(Triple::tce); break; case Triple::tcele: T.setArch(Triple::tce); break;
@ -1522,7 +1532,6 @@ Triple Triple::getLittleEndianArchVariant() const {
switch (getArch()) { switch (getArch()) {
case Triple::UnknownArch: case Triple::UnknownArch:
case Triple::lanai: case Triple::lanai:
case Triple::ppc:
case Triple::sparcv9: case Triple::sparcv9:
case Triple::systemz: case Triple::systemz:
@ -1537,6 +1546,7 @@ Triple Triple::getLittleEndianArchVariant() const {
case Triple::bpfeb: T.setArch(Triple::bpfel); break; case Triple::bpfeb: T.setArch(Triple::bpfel); break;
case Triple::mips64: T.setArch(Triple::mips64el); break; case Triple::mips64: T.setArch(Triple::mips64el); break;
case Triple::mips: T.setArch(Triple::mipsel); break; case Triple::mips: T.setArch(Triple::mipsel); break;
case Triple::ppc: T.setArch(Triple::ppcle); break;
case Triple::ppc64: T.setArch(Triple::ppc64le); break; case Triple::ppc64: T.setArch(Triple::ppc64le); break;
case Triple::sparc: T.setArch(Triple::sparcel); break; case Triple::sparc: T.setArch(Triple::sparcel); break;
case Triple::tce: T.setArch(Triple::tcele); break; case Triple::tce: T.setArch(Triple::tcele); break;
@ -1568,6 +1578,7 @@ bool Triple::isLittleEndian() const {
case Triple::msp430: case Triple::msp430:
case Triple::nvptx64: case Triple::nvptx64:
case Triple::nvptx: case Triple::nvptx:
case Triple::ppcle:
case Triple::ppc64le: case Triple::ppc64le:
case Triple::r600: case Triple::r600:
case Triple::renderscript32: case Triple::renderscript32:

View File

@ -1716,8 +1716,9 @@ bool PPCAsmParser::ParseDirectiveLocalEntry(SMLoc L) {
/// Force static initialization. /// Force static initialization.
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmParser() { extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmParser() {
RegisterMCAsmParser<PPCAsmParser> A(getThePPC32Target()); RegisterMCAsmParser<PPCAsmParser> A(getThePPC32Target());
RegisterMCAsmParser<PPCAsmParser> B(getThePPC64Target()); RegisterMCAsmParser<PPCAsmParser> B(getThePPC32LETarget());
RegisterMCAsmParser<PPCAsmParser> C(getThePPC64LETarget()); RegisterMCAsmParser<PPCAsmParser> C(getThePPC64Target());
RegisterMCAsmParser<PPCAsmParser> D(getThePPC64LETarget());
} }
#define GET_REGISTER_MATCHER #define GET_REGISTER_MATCHER

View File

@ -54,6 +54,8 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCDisassembler() {
// Register the disassembler for each target. // Register the disassembler for each target.
TargetRegistry::RegisterMCDisassembler(getThePPC32Target(), TargetRegistry::RegisterMCDisassembler(getThePPC32Target(),
createPPCDisassembler); createPPCDisassembler);
TargetRegistry::RegisterMCDisassembler(getThePPC32LETarget(),
createPPCLEDisassembler);
TargetRegistry::RegisterMCDisassembler(getThePPC64Target(), TargetRegistry::RegisterMCDisassembler(getThePPC64Target(),
createPPCDisassembler); createPPCDisassembler);
TargetRegistry::RegisterMCDisassembler(getThePPC64LETarget(), TargetRegistry::RegisterMCDisassembler(getThePPC64LETarget(),

View File

@ -26,7 +26,8 @@ PPCELFMCAsmInfo::PPCELFMCAsmInfo(bool is64Bit, const Triple& T) {
if (is64Bit) { if (is64Bit) {
CodePointerSize = CalleeSaveStackSlotSize = 8; CodePointerSize = CalleeSaveStackSlotSize = 8;
} }
IsLittleEndian = T.getArch() == Triple::ppc64le; IsLittleEndian =
T.getArch() == Triple::ppc64le || T.getArch() == Triple::ppcle;
// ".comm align is in bytes but .align is pow-2." // ".comm align is in bytes but .align is pow-2."
AlignmentIsInBytes = false; AlignmentIsInBytes = false;
@ -56,7 +57,7 @@ PPCELFMCAsmInfo::PPCELFMCAsmInfo(bool is64Bit, const Triple& T) {
void PPCXCOFFMCAsmInfo::anchor() {} void PPCXCOFFMCAsmInfo::anchor() {}
PPCXCOFFMCAsmInfo::PPCXCOFFMCAsmInfo(bool Is64Bit, const Triple &T) { PPCXCOFFMCAsmInfo::PPCXCOFFMCAsmInfo(bool Is64Bit, const Triple &T) {
if (T.getArch() == Triple::ppc64le) if (T.getArch() == Triple::ppc64le || T.getArch() == Triple::ppcle)
report_fatal_error("XCOFF is not supported for little-endian targets"); report_fatal_error("XCOFF is not supported for little-endian targets");
CodePointerSize = CalleeSaveStackSlotSize = Is64Bit ? 8 : 4; CodePointerSize = CalleeSaveStackSlotSize = Is64Bit ? 8 : 4;

View File

@ -336,8 +336,8 @@ static MCInstPrinter *createPPCMCInstPrinter(const Triple &T,
} }
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCTargetMC() { extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCTargetMC() {
for (Target *T : for (Target *T : {&getThePPC32Target(), &getThePPC32LETarget(),
{&getThePPC32Target(), &getThePPC64Target(), &getThePPC64LETarget()}) { &getThePPC64Target(), &getThePPC64LETarget()}) {
// Register the MC asm info. // Register the MC asm info.
RegisterMCAsmInfoFn C(*T, createPPCMCAsmInfo); RegisterMCAsmInfoFn C(*T, createPPCMCAsmInfo);

View File

@ -2373,6 +2373,8 @@ createPPCAsmPrinterPass(TargetMachine &tm,
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmPrinter() { extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmPrinter() {
TargetRegistry::RegisterAsmPrinter(getThePPC32Target(), TargetRegistry::RegisterAsmPrinter(getThePPC32Target(),
createPPCAsmPrinterPass); createPPCAsmPrinterPass);
TargetRegistry::RegisterAsmPrinter(getThePPC32LETarget(),
createPPCAsmPrinterPass);
TargetRegistry::RegisterAsmPrinter(getThePPC64Target(), TargetRegistry::RegisterAsmPrinter(getThePPC64Target(),
createPPCAsmPrinterPass); createPPCAsmPrinterPass);
TargetRegistry::RegisterAsmPrinter(getThePPC64LETarget(), TargetRegistry::RegisterAsmPrinter(getThePPC64LETarget(),

View File

@ -179,7 +179,8 @@ void PPCSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {
// Determine endianness. // Determine endianness.
// FIXME: Part of the TargetMachine. // FIXME: Part of the TargetMachine.
IsLittleEndian = (TargetTriple.getArch() == Triple::ppc64le); IsLittleEndian = (TargetTriple.getArch() == Triple::ppc64le ||
TargetTriple.getArch() == Triple::ppcle);
} }
bool PPCSubtarget::enableMachineScheduler() const { return true; } bool PPCSubtarget::enableMachineScheduler() const { return true; }

View File

@ -100,8 +100,9 @@ static cl::opt<bool>
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCTarget() { extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCTarget() {
// Register the targets // Register the targets
RegisterTargetMachine<PPCTargetMachine> A(getThePPC32Target()); RegisterTargetMachine<PPCTargetMachine> A(getThePPC32Target());
RegisterTargetMachine<PPCTargetMachine> B(getThePPC64Target()); RegisterTargetMachine<PPCTargetMachine> B(getThePPC32LETarget());
RegisterTargetMachine<PPCTargetMachine> C(getThePPC64LETarget()); RegisterTargetMachine<PPCTargetMachine> C(getThePPC64Target());
RegisterTargetMachine<PPCTargetMachine> D(getThePPC64LETarget());
PassRegistry &PR = *PassRegistry::getPassRegistry(); PassRegistry &PR = *PassRegistry::getPassRegistry();
#ifndef NDEBUG #ifndef NDEBUG
@ -130,8 +131,8 @@ static std::string getDataLayoutString(const Triple &T) {
bool is64Bit = T.getArch() == Triple::ppc64 || T.getArch() == Triple::ppc64le; bool is64Bit = T.getArch() == Triple::ppc64 || T.getArch() == Triple::ppc64le;
std::string Ret; std::string Ret;
// Most PPC* platforms are big endian, PPC64LE is little endian. // Most PPC* platforms are big endian, PPC(64)LE is little endian.
if (T.getArch() == Triple::ppc64le) if (T.getArch() == Triple::ppc64le || T.getArch() == Triple::ppcle)
Ret = "e"; Ret = "e";
else else
Ret = "E"; Ret = "E";

View File

@ -14,6 +14,10 @@ Target &llvm::getThePPC32Target() {
static Target ThePPC32Target; static Target ThePPC32Target;
return ThePPC32Target; return ThePPC32Target;
} }
Target &llvm::getThePPC32LETarget() {
static Target ThePPC32LETarget;
return ThePPC32LETarget;
}
Target &llvm::getThePPC64Target() { Target &llvm::getThePPC64Target() {
static Target ThePPC64Target; static Target ThePPC64Target;
return ThePPC64Target; return ThePPC64Target;
@ -24,9 +28,12 @@ Target &llvm::getThePPC64LETarget() {
} }
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCTargetInfo() { extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCTargetInfo() {
RegisterTarget<Triple::ppc, /*HasJIT=*/true> X(getThePPC32Target(), "ppc32", RegisterTarget<Triple::ppc, /*HasJIT=*/true> W(getThePPC32Target(), "ppc32",
"PowerPC 32", "PPC"); "PowerPC 32", "PPC");
RegisterTarget<Triple::ppcle, /*HasJIT=*/true> X(
getThePPC32LETarget(), "ppc32le", "PowerPC 32 LE", "PPC");
RegisterTarget<Triple::ppc64, /*HasJIT=*/true> Y(getThePPC64Target(), "ppc64", RegisterTarget<Triple::ppc64, /*HasJIT=*/true> Y(getThePPC64Target(), "ppc64",
"PowerPC 64", "PPC"); "PowerPC 64", "PPC");

View File

@ -14,6 +14,7 @@ namespace llvm {
class Target; class Target;
Target &getThePPC32Target(); Target &getThePPC32Target();
Target &getThePPC32LETarget();
Target &getThePPC64Target(); Target &getThePPC64Target();
Target &getThePPC64LETarget(); Target &getThePPC64LETarget();

View File

@ -1111,7 +1111,7 @@ TEST(TripleTest, EndianArchVariants) {
T.setArch(Triple::ppc); T.setArch(Triple::ppc);
EXPECT_EQ(Triple::ppc, T.getBigEndianArchVariant().getArch()); EXPECT_EQ(Triple::ppc, T.getBigEndianArchVariant().getArch());
EXPECT_EQ(Triple::UnknownArch, T.getLittleEndianArchVariant().getArch()); EXPECT_EQ(Triple::ppcle, T.getLittleEndianArchVariant().getArch());
T.setArch(Triple::ppc64); T.setArch(Triple::ppc64);
EXPECT_EQ(Triple::ppc64, T.getBigEndianArchVariant().getArch()); EXPECT_EQ(Triple::ppc64, T.getBigEndianArchVariant().getArch());