forked from OSchip/llvm-project
[PowerPC] Support powerpc64le as a syntax-checking target.
This patch provides basic support for powerpc64le as an LLVM target. However, use of this target will not actually generate little-endian code. Instead, use of the target will cause the correct little-endian built-in defines to be generated, so that code that tests for __LITTLE_ENDIAN__, for example, will be correctly parsed for syntax-only testing. Code generation will otherwise be the same as powerpc64 (big-endian), for now. The patch leaves open the possibility of creating a little-endian PowerPC64 back end, but there is no immediate intent to create such a thing. The LLVM portions of this patch simply add ppc64le coverage everywhere that ppc64 coverage currently exists. There is nothing of any import worth testing until such time as little-endian code generation is implemented. In the corresponding Clang patch, there is a new test case variant to ensure that correct built-in defines for little-endian code are generated. llvm-svn: 187179
This commit is contained in:
parent
db8ea01c43
commit
0a9170d931
|
@ -965,6 +965,9 @@ EOF
|
|||
ppc64:Linux:*:*)
|
||||
echo powerpc64-unknown-linux-gnu
|
||||
exit ;;
|
||||
ppc64le:Linux:*:*)
|
||||
echo powerpc64le-unknown-linux-gnu
|
||||
exit ;;
|
||||
ppc:Linux:*:*)
|
||||
echo powerpc-unknown-linux-gnu
|
||||
exit ;;
|
||||
|
|
|
@ -530,7 +530,7 @@ x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
|
|||
x86_64-*linux*)
|
||||
LD="${LD-ld} -m elf_i386"
|
||||
;;
|
||||
ppc64-*linux*|powerpc64-*linux*)
|
||||
ppc64-*linux*|powerpc64-*linux*|ppc64le-*linux*|powerpc64le-*linux*)
|
||||
LD="${LD-ld} -m elf32ppclinux"
|
||||
;;
|
||||
s390x-*linux*)
|
||||
|
|
|
@ -55,6 +55,7 @@ public:
|
|||
msp430, // MSP430: msp430
|
||||
ppc, // PPC: powerpc
|
||||
ppc64, // PPC64: powerpc64, ppu
|
||||
ppc64le, // PPC64LE: powerpc64le
|
||||
r600, // R600: AMD GPUs HD2XXX - HD6XXX
|
||||
sparc, // Sparc: sparc
|
||||
sparcv9, // Sparcv9: Sparcv9
|
||||
|
|
|
@ -2796,7 +2796,8 @@ unsigned ELFObjectFile<ELFT>::getArch() const {
|
|||
return (ELFT::TargetEndianness == support::little) ?
|
||||
Triple::mipsel : Triple::mips;
|
||||
case ELF::EM_PPC64:
|
||||
return Triple::ppc64;
|
||||
return (ELFT::TargetEndianness == support::little) ?
|
||||
Triple::ppc64le : Triple::ppc64;
|
||||
case ELF::EM_S390:
|
||||
return Triple::systemz;
|
||||
default:
|
||||
|
|
|
@ -396,7 +396,7 @@ uint8_t *RuntimeDyldImpl::createStubFunction(uint8_t *Addr) {
|
|||
StubAddr++;
|
||||
*StubAddr = NopInstr;
|
||||
return Addr;
|
||||
} else if (Arch == Triple::ppc64) {
|
||||
} else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le) {
|
||||
// PowerPC64 stub: the address points to a function descriptor
|
||||
// instead of the function itself. Load the function address
|
||||
// on r11 and sets it to control register. Also loads the function
|
||||
|
|
|
@ -770,7 +770,8 @@ void RuntimeDyldELF::resolveRelocation(const SectionEntry &Section,
|
|||
(uint32_t)(Value & 0xffffffffL), Type,
|
||||
(uint32_t)(Addend & 0xffffffffL));
|
||||
break;
|
||||
case Triple::ppc64:
|
||||
case Triple::ppc64: // Fall through.
|
||||
case Triple::ppc64le:
|
||||
resolvePPC64Relocation(Section, Offset, Value, Type, Addend);
|
||||
break;
|
||||
case Triple::systemz:
|
||||
|
@ -985,7 +986,7 @@ void RuntimeDyldELF::processRelocationRef(unsigned SectionID,
|
|||
RelType, 0);
|
||||
Section.StubOffset += getMaxStubSize();
|
||||
}
|
||||
} else if (Arch == Triple::ppc64) {
|
||||
} else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le) {
|
||||
if (RelType == ELF::R_PPC64_REL24) {
|
||||
// A PPC branch relocation will need a stub function if the target is
|
||||
// an external symbol (Symbol::ST_Unknown) or if the target address
|
||||
|
|
|
@ -172,7 +172,7 @@ protected:
|
|||
return 8; // 32-bit instruction and 32-bit address
|
||||
else if (Arch == Triple::mipsel || Arch == Triple::mips)
|
||||
return 16;
|
||||
else if (Arch == Triple::ppc64)
|
||||
else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le)
|
||||
return 44;
|
||||
else if (Arch == Triple::x86_64)
|
||||
return 8; // GOT
|
||||
|
|
|
@ -79,7 +79,8 @@ void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) {
|
|||
// to using it in -static mode.
|
||||
SixteenByteConstantSection = 0;
|
||||
if (RelocM != Reloc::Static &&
|
||||
T.getArch() != Triple::x86_64 && T.getArch() != Triple::ppc64)
|
||||
T.getArch() != Triple::x86_64 && T.getArch() != Triple::ppc64 &&
|
||||
T.getArch() != Triple::ppc64le)
|
||||
SixteenByteConstantSection = // .literal16
|
||||
Ctx->getMachOSection("__TEXT", "__literal16",
|
||||
MCSectionMachO::S_16BYTE_LITERALS,
|
||||
|
@ -288,7 +289,7 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
|
|||
FDEEncoding = dwarf::DW_EH_PE_udata4;
|
||||
TTypeEncoding = dwarf::DW_EH_PE_absptr;
|
||||
}
|
||||
} else if (T.getArch() == Triple::ppc64) {
|
||||
} else if (T.getArch() == Triple::ppc64 || T.getArch() == Triple::ppc64le) {
|
||||
PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
|
||||
dwarf::DW_EH_PE_udata8;
|
||||
LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8;
|
||||
|
|
|
@ -28,6 +28,7 @@ const char *Triple::getArchTypeName(ArchType Kind) {
|
|||
case mips64el:return "mips64el";
|
||||
case msp430: return "msp430";
|
||||
case ppc64: return "powerpc64";
|
||||
case ppc64le: return "powerpc64le";
|
||||
case ppc: return "powerpc";
|
||||
case r600: return "r600";
|
||||
case sparc: return "sparc";
|
||||
|
@ -60,6 +61,7 @@ const char *Triple::getArchTypePrefix(ArchType Kind) {
|
|||
case thumb: return "arm";
|
||||
|
||||
case ppc64:
|
||||
case ppc64le:
|
||||
case ppc: return "ppc";
|
||||
|
||||
case mips:
|
||||
|
@ -168,6 +170,7 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
|
|||
.Case("ppc64", ppc64)
|
||||
.Case("ppc32", ppc)
|
||||
.Case("ppc", ppc)
|
||||
.Case("ppc64le", ppc64le)
|
||||
.Case("r600", r600)
|
||||
.Case("hexagon", hexagon)
|
||||
.Case("sparc", sparc)
|
||||
|
@ -197,6 +200,7 @@ const char *Triple::getArchNameForAssembler() {
|
|||
.Case("x86_64", "x86_64")
|
||||
.Case("powerpc", "ppc")
|
||||
.Case("powerpc64", "ppc64")
|
||||
.Case("powerpc64le", "ppc64le")
|
||||
.Case("arm", "arm")
|
||||
.Cases("armv4t", "thumbv4t", "armv4t")
|
||||
.Cases("armv5", "armv5e", "thumbv5", "thumbv5e", "armv5")
|
||||
|
@ -220,6 +224,7 @@ static Triple::ArchType parseArch(StringRef ArchName) {
|
|||
.Cases("amd64", "x86_64", Triple::x86_64)
|
||||
.Case("powerpc", Triple::ppc)
|
||||
.Cases("powerpc64", "ppu", Triple::ppc64)
|
||||
.Case("powerpc64le", Triple::ppc64le)
|
||||
.Case("aarch64", Triple::aarch64)
|
||||
.Cases("arm", "xscale", Triple::arm)
|
||||
// FIXME: It would be good to replace these with explicit names for all the
|
||||
|
@ -690,6 +695,7 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
|
|||
case llvm::Triple::mips64el:
|
||||
case llvm::Triple::nvptx64:
|
||||
case llvm::Triple::ppc64:
|
||||
case llvm::Triple::ppc64le:
|
||||
case llvm::Triple::sparcv9:
|
||||
case llvm::Triple::systemz:
|
||||
case llvm::Triple::x86_64:
|
||||
|
@ -718,6 +724,7 @@ Triple Triple::get32BitArchVariant() const {
|
|||
case Triple::aarch64:
|
||||
case Triple::msp430:
|
||||
case Triple::systemz:
|
||||
case Triple::ppc64le:
|
||||
T.setArch(UnknownArch);
|
||||
break;
|
||||
|
||||
|
@ -772,6 +779,7 @@ Triple Triple::get64BitArchVariant() const {
|
|||
case Triple::mips64el:
|
||||
case Triple::nvptx64:
|
||||
case Triple::ppc64:
|
||||
case Triple::ppc64le:
|
||||
case Triple::sparcv9:
|
||||
case Triple::systemz:
|
||||
case Triple::x86_64:
|
||||
|
|
|
@ -222,7 +222,8 @@ public:
|
|||
: MCTargetAsmParser(), STI(_STI), Parser(_Parser) {
|
||||
// Check for 64-bit vs. 32-bit pointer mode.
|
||||
Triple TheTriple(STI.getTargetTriple());
|
||||
IsPPC64 = TheTriple.getArch() == Triple::ppc64;
|
||||
IsPPC64 = (TheTriple.getArch() == Triple::ppc64 ||
|
||||
TheTriple.getArch() == Triple::ppc64le);
|
||||
// Initialize the set of available features.
|
||||
setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
|
||||
}
|
||||
|
@ -1313,6 +1314,7 @@ bool PPCAsmParser::ParseDirectiveMachine(SMLoc L) {
|
|||
extern "C" void LLVMInitializePowerPCAsmParser() {
|
||||
RegisterMCAsmParser<PPCAsmParser> A(ThePPC32Target);
|
||||
RegisterMCAsmParser<PPCAsmParser> B(ThePPC64Target);
|
||||
RegisterMCAsmParser<PPCAsmParser> C(ThePPC64LETarget);
|
||||
}
|
||||
|
||||
#define GET_REGISTER_MATCHER
|
||||
|
|
|
@ -158,7 +158,7 @@ public:
|
|||
|
||||
unsigned getPointerSize() const {
|
||||
StringRef Name = TheTarget.getName();
|
||||
if (Name == "ppc64") return 8;
|
||||
if (Name == "ppc64" || Name == "ppc64le") return 8;
|
||||
assert(Name == "ppc32" && "Unknown target name!");
|
||||
return 4;
|
||||
}
|
||||
|
|
|
@ -42,7 +42,8 @@ static MCInstrInfo *createPPCMCInstrInfo() {
|
|||
|
||||
static MCRegisterInfo *createPPCMCRegisterInfo(StringRef TT) {
|
||||
Triple TheTriple(TT);
|
||||
bool isPPC64 = (TheTriple.getArch() == Triple::ppc64);
|
||||
bool isPPC64 = (TheTriple.getArch() == Triple::ppc64 ||
|
||||
TheTriple.getArch() == Triple::ppc64le);
|
||||
unsigned Flavour = isPPC64 ? 0 : 1;
|
||||
unsigned RA = isPPC64 ? PPC::LR8 : PPC::LR;
|
||||
|
||||
|
@ -60,7 +61,8 @@ static MCSubtargetInfo *createPPCMCSubtargetInfo(StringRef TT, StringRef CPU,
|
|||
|
||||
static MCAsmInfo *createPPCMCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) {
|
||||
Triple TheTriple(TT);
|
||||
bool isPPC64 = TheTriple.getArch() == Triple::ppc64;
|
||||
bool isPPC64 = (TheTriple.getArch() == Triple::ppc64 ||
|
||||
TheTriple.getArch() == Triple::ppc64le);
|
||||
|
||||
MCAsmInfo *MAI;
|
||||
if (TheTriple.isOSDarwin())
|
||||
|
@ -91,7 +93,8 @@ static MCCodeGenInfo *createPPCMCCodeGenInfo(StringRef TT, Reloc::Model RM,
|
|||
}
|
||||
if (CM == CodeModel::Default) {
|
||||
Triple T(TT);
|
||||
if (!T.isOSDarwin() && T.getArch() == Triple::ppc64)
|
||||
if (!T.isOSDarwin() &&
|
||||
(T.getArch() == Triple::ppc64 || T.getArch() == Triple::ppc64le))
|
||||
CM = CodeModel::Medium;
|
||||
}
|
||||
X->InitMCCodeGenInfo(RM, CM, OL);
|
||||
|
@ -125,38 +128,52 @@ extern "C" void LLVMInitializePowerPCTargetMC() {
|
|||
// Register the MC asm info.
|
||||
RegisterMCAsmInfoFn C(ThePPC32Target, createPPCMCAsmInfo);
|
||||
RegisterMCAsmInfoFn D(ThePPC64Target, createPPCMCAsmInfo);
|
||||
RegisterMCAsmInfoFn E(ThePPC64LETarget, createPPCMCAsmInfo);
|
||||
|
||||
// Register the MC codegen info.
|
||||
TargetRegistry::RegisterMCCodeGenInfo(ThePPC32Target, createPPCMCCodeGenInfo);
|
||||
TargetRegistry::RegisterMCCodeGenInfo(ThePPC64Target, createPPCMCCodeGenInfo);
|
||||
TargetRegistry::RegisterMCCodeGenInfo(ThePPC64LETarget,
|
||||
createPPCMCCodeGenInfo);
|
||||
|
||||
// Register the MC instruction info.
|
||||
TargetRegistry::RegisterMCInstrInfo(ThePPC32Target, createPPCMCInstrInfo);
|
||||
TargetRegistry::RegisterMCInstrInfo(ThePPC64Target, createPPCMCInstrInfo);
|
||||
TargetRegistry::RegisterMCInstrInfo(ThePPC64LETarget,
|
||||
createPPCMCInstrInfo);
|
||||
|
||||
// Register the MC register info.
|
||||
TargetRegistry::RegisterMCRegInfo(ThePPC32Target, createPPCMCRegisterInfo);
|
||||
TargetRegistry::RegisterMCRegInfo(ThePPC64Target, createPPCMCRegisterInfo);
|
||||
TargetRegistry::RegisterMCRegInfo(ThePPC64LETarget, createPPCMCRegisterInfo);
|
||||
|
||||
// Register the MC subtarget info.
|
||||
TargetRegistry::RegisterMCSubtargetInfo(ThePPC32Target,
|
||||
createPPCMCSubtargetInfo);
|
||||
TargetRegistry::RegisterMCSubtargetInfo(ThePPC64Target,
|
||||
createPPCMCSubtargetInfo);
|
||||
TargetRegistry::RegisterMCSubtargetInfo(ThePPC64LETarget,
|
||||
createPPCMCSubtargetInfo);
|
||||
|
||||
// Register the MC Code Emitter
|
||||
TargetRegistry::RegisterMCCodeEmitter(ThePPC32Target, createPPCMCCodeEmitter);
|
||||
TargetRegistry::RegisterMCCodeEmitter(ThePPC64Target, createPPCMCCodeEmitter);
|
||||
TargetRegistry::RegisterMCCodeEmitter(ThePPC64LETarget,
|
||||
createPPCMCCodeEmitter);
|
||||
|
||||
// Register the asm backend.
|
||||
TargetRegistry::RegisterMCAsmBackend(ThePPC32Target, createPPCAsmBackend);
|
||||
TargetRegistry::RegisterMCAsmBackend(ThePPC64Target, createPPCAsmBackend);
|
||||
TargetRegistry::RegisterMCAsmBackend(ThePPC64LETarget, createPPCAsmBackend);
|
||||
|
||||
// Register the object streamer.
|
||||
TargetRegistry::RegisterMCObjectStreamer(ThePPC32Target, createMCStreamer);
|
||||
TargetRegistry::RegisterMCObjectStreamer(ThePPC64Target, createMCStreamer);
|
||||
TargetRegistry::RegisterMCObjectStreamer(ThePPC64LETarget, createMCStreamer);
|
||||
|
||||
// Register the MCInstPrinter.
|
||||
TargetRegistry::RegisterMCInstPrinter(ThePPC32Target, createPPCMCInstPrinter);
|
||||
TargetRegistry::RegisterMCInstPrinter(ThePPC64Target, createPPCMCInstPrinter);
|
||||
TargetRegistry::RegisterMCInstPrinter(ThePPC64LETarget,
|
||||
createPPCMCInstPrinter);
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ class raw_ostream;
|
|||
|
||||
extern Target ThePPC32Target;
|
||||
extern Target ThePPC64Target;
|
||||
extern Target ThePPC64LETarget;
|
||||
|
||||
MCCodeEmitter *createPPCMCCodeEmitter(const MCInstrInfo &MCII,
|
||||
const MCRegisterInfo &MRI,
|
||||
|
|
|
@ -252,6 +252,11 @@ def : ProcessorModel<"ppc64", G5Model,
|
|||
FeatureMFOCRF, FeatureFSqrt, FeatureFRES,
|
||||
FeatureFRSQRTE, FeatureSTFIWX,
|
||||
Feature64Bit /*, Feature64BitRegs */]>;
|
||||
def : ProcessorModel<"ppc64le", G5Model,
|
||||
[Directive64, FeatureAltivec,
|
||||
FeatureMFOCRF, FeatureFSqrt, FeatureFRES,
|
||||
FeatureFRSQRTE, FeatureSTFIWX,
|
||||
Feature64Bit /*, Feature64BitRegs */]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Calling Conventions
|
||||
|
|
|
@ -839,7 +839,8 @@ void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) {
|
|||
"power6",
|
||||
"power6x",
|
||||
"power7",
|
||||
"ppc64"
|
||||
"ppc64",
|
||||
"ppc64le"
|
||||
};
|
||||
|
||||
unsigned Directive = Subtarget.getDarwinDirective();
|
||||
|
|
|
@ -137,6 +137,9 @@ void PPCSubtarget::resetSubtargetFeatures(StringRef CPU, StringRef FS) {
|
|||
// is enabled because external functions will assume this alignment.
|
||||
if (hasQPX() || isBGQ())
|
||||
StackAlignment = 32;
|
||||
|
||||
// Determine endianness.
|
||||
IsLittleEndian = (TargetTriple.getArch() == Triple::ppc64le);
|
||||
}
|
||||
|
||||
/// hasLazyResolverStub - Return true if accesses to the specified global have
|
||||
|
|
|
@ -89,6 +89,7 @@ protected:
|
|||
bool IsBookE;
|
||||
bool HasLazyResolverStubs;
|
||||
bool IsJITCodeModel;
|
||||
bool IsLittleEndian;
|
||||
|
||||
/// TargetTriple - What processor and OS we're targeting.
|
||||
Triple TargetTriple;
|
||||
|
@ -166,6 +167,9 @@ public:
|
|||
// isJITCodeModel - True if we're generating code for the JIT
|
||||
bool isJITCodeModel() const { return IsJITCodeModel; }
|
||||
|
||||
// isLittleEndian - True if generating little-endian code
|
||||
bool isLittleEndian() const { return IsLittleEndian; }
|
||||
|
||||
// Specific obvious features.
|
||||
bool hasFSQRT() const { return HasFSQRT; }
|
||||
bool hasFRE() const { return HasFRE; }
|
||||
|
|
|
@ -30,6 +30,7 @@ extern "C" void LLVMInitializePowerPCTarget() {
|
|||
// Register the targets
|
||||
RegisterTargetMachine<PPC32TargetMachine> A(ThePPC32Target);
|
||||
RegisterTargetMachine<PPC64TargetMachine> B(ThePPC64Target);
|
||||
RegisterTargetMachine<PPC64TargetMachine> C(ThePPC64LETarget);
|
||||
}
|
||||
|
||||
PPCTargetMachine::PPCTargetMachine(const Target &T, StringRef TT,
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include "llvm/Support/TargetRegistry.h"
|
||||
using namespace llvm;
|
||||
|
||||
Target llvm::ThePPC32Target, llvm::ThePPC64Target;
|
||||
Target llvm::ThePPC32Target, llvm::ThePPC64Target, llvm::ThePPC64LETarget;
|
||||
|
||||
extern "C" void LLVMInitializePowerPCTargetInfo() {
|
||||
RegisterTarget<Triple::ppc, /*HasJIT=*/true>
|
||||
|
@ -20,4 +20,7 @@ extern "C" void LLVMInitializePowerPCTargetInfo() {
|
|||
|
||||
RegisterTarget<Triple::ppc64, /*HasJIT=*/true>
|
||||
Y(ThePPC64Target, "ppc64", "PowerPC 64");
|
||||
|
||||
RegisterTarget<Triple::ppc64le, /*HasJIT=*/true>
|
||||
Z(ThePPC64LETarget, "ppc64le", "PowerPC 64 LE");
|
||||
}
|
||||
|
|
|
@ -222,7 +222,8 @@ static ShadowMapping getShadowMapping(const Module &M, int LongSize,
|
|||
llvm::Triple TargetTriple(M.getTargetTriple());
|
||||
bool IsAndroid = TargetTriple.getEnvironment() == llvm::Triple::Android;
|
||||
bool IsMacOSX = TargetTriple.getOS() == llvm::Triple::MacOSX;
|
||||
bool IsPPC64 = TargetTriple.getArch() == llvm::Triple::ppc64;
|
||||
bool IsPPC64 = TargetTriple.getArch() == llvm::Triple::ppc64 ||
|
||||
TargetTriple.getArch() == llvm::Triple::ppc64le;
|
||||
bool IsX86_64 = TargetTriple.getArch() == llvm::Triple::x86_64;
|
||||
bool IsMIPS32 = TargetTriple.getArch() == llvm::Triple::mips ||
|
||||
TargetTriple.getArch() == llvm::Triple::mipsel;
|
||||
|
|
|
@ -961,6 +961,9 @@ EOF
|
|||
ppc64:Linux:*:*)
|
||||
echo powerpc64-unknown-linux-gnu
|
||||
exit ;;
|
||||
ppc64le:Linux:*:*)
|
||||
echo powerpc64le-unknown-linux-gnu
|
||||
exit ;;
|
||||
ppc:Linux:*:*)
|
||||
echo powerpc-unknown-linux-gnu
|
||||
exit ;;
|
||||
|
|
|
@ -530,7 +530,7 @@ x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
|
|||
x86_64-*linux*)
|
||||
LD="${LD-ld} -m elf_i386"
|
||||
;;
|
||||
ppc64-*linux*|powerpc64-*linux*)
|
||||
ppc64-*linux*|powerpc64-*linux*|ppc64le-$linux*|powerpc64le-*linux*)
|
||||
LD="${LD-ld} -m elf32ppclinux"
|
||||
;;
|
||||
s390x-*linux*)
|
||||
|
|
Loading…
Reference in New Issue