diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 10:51:19 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 10:51:19 +0000 |
| commit | eb11fae6d08f479c0799db45860a98af528fa6e7 (patch) | |
| tree | 44d492a50c8c1a7eb8e2d17ea3360ec4d066f042 /lib/Target/PowerPC/MCTargetDesc | |
| parent | b8a2042aa938069e862750553db0e4d82d25822c (diff) | |
Notes
Diffstat (limited to 'lib/Target/PowerPC/MCTargetDesc')
| -rw-r--r-- | lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp | 52 | ||||
| -rw-r--r-- | lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp | 30 | ||||
| -rw-r--r-- | lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp | 15 | ||||
| -rw-r--r-- | lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp | 12 | ||||
| -rw-r--r-- | lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h | 2 | ||||
| -rw-r--r-- | lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h | 19 | ||||
| -rw-r--r-- | lib/Target/PowerPC/MCTargetDesc/PPCMachObjectWriter.cpp | 10 | ||||
| -rw-r--r-- | lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h | 3 |
8 files changed, 85 insertions, 58 deletions
diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp index 2a1de244da92..a405dd70c307 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp +++ b/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp @@ -18,6 +18,7 @@ #include "llvm/MC/MCMachObjectWriter.h" #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCSectionMachO.h" +#include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCSymbolELF.h" #include "llvm/MC/MCValue.h" #include "llvm/Support/ErrorHandling.h" @@ -74,10 +75,9 @@ namespace { class PPCAsmBackend : public MCAsmBackend { const Target &TheTarget; - bool IsLittleEndian; public: - PPCAsmBackend(const Target &T, bool isLittle) : MCAsmBackend(), TheTarget(T), - IsLittleEndian(isLittle) {} + PPCAsmBackend(const Target &T, support::endianness Endian) + : MCAsmBackend(Endian), TheTarget(T) {} unsigned getNumFixupKinds() const override { return PPC::NumTargetFixupKinds; @@ -110,12 +110,15 @@ public: assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && "Invalid kind!"); - return (IsLittleEndian? InfosLE : InfosBE)[Kind - FirstTargetFixupKind]; + return (Endian == support::little + ? InfosLE + : InfosBE)[Kind - FirstTargetFixupKind]; } void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target, MutableArrayRef<char> Data, - uint64_t Value, bool IsResolved) const override { + uint64_t Value, bool IsResolved, + const MCSubtargetInfo *STI) const override { Value = adjustFixupValue(Fixup.getKind(), Value); if (!Value) return; // Doesn't change encoding. @@ -126,7 +129,7 @@ public: // from the fixup value. The Value has been "split up" into the appropriate // bitfields above. for (unsigned i = 0; i != NumBytes; ++i) { - unsigned Idx = IsLittleEndian ? i : (NumBytes - 1 - i); + unsigned Idx = Endian == support::little ? i : (NumBytes - 1 - i); Data[Offset + i] |= uint8_t((Value >> (Idx * 8)) & 0xff); } } @@ -155,7 +158,8 @@ public: } } - bool mayNeedRelaxation(const MCInst &Inst) const override { + bool mayNeedRelaxation(const MCInst &Inst, + const MCSubtargetInfo &STI) const override { // FIXME. return false; } @@ -174,12 +178,12 @@ public: llvm_unreachable("relaxInstruction() unimplemented"); } - bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override { + bool writeNopData(raw_ostream &OS, uint64_t Count) const override { uint64_t NumNops = Count / 4; for (uint64_t i = 0; i != NumNops; ++i) - OW->write32(0x60000000); + support::endian::write<uint32_t>(OS, 0x60000000, Endian); - OW->WriteZeros(Count % 4); + OS.write_zeros(Count % 4); return true; } @@ -190,10 +194,6 @@ public: assert(Name == "ppc32" && "Unknown target name!"); return 4; } - - bool isLittleEndian() const { - return IsLittleEndian; - } }; } // end anonymous namespace @@ -202,13 +202,12 @@ public: namespace { class DarwinPPCAsmBackend : public PPCAsmBackend { public: - DarwinPPCAsmBackend(const Target &T) : PPCAsmBackend(T, false) { } + DarwinPPCAsmBackend(const Target &T) : PPCAsmBackend(T, support::big) { } - std::unique_ptr<MCObjectWriter> - createObjectWriter(raw_pwrite_stream &OS) const override { + std::unique_ptr<MCObjectTargetWriter> + createObjectTargetWriter() const override { bool is64 = getPointerSize() == 8; return createPPCMachObjectWriter( - OS, /*Is64Bit=*/is64, (is64 ? MachO::CPU_TYPE_POWERPC64 : MachO::CPU_TYPE_POWERPC), MachO::CPU_SUBTYPE_POWERPC_ALL); @@ -218,26 +217,29 @@ namespace { class ELFPPCAsmBackend : public PPCAsmBackend { uint8_t OSABI; public: - ELFPPCAsmBackend(const Target &T, bool IsLittleEndian, uint8_t OSABI) : - PPCAsmBackend(T, IsLittleEndian), OSABI(OSABI) { } + ELFPPCAsmBackend(const Target &T, support::endianness Endian, + uint8_t OSABI) + : PPCAsmBackend(T, Endian), OSABI(OSABI) {} - std::unique_ptr<MCObjectWriter> - createObjectWriter(raw_pwrite_stream &OS) const override { + std::unique_ptr<MCObjectTargetWriter> + createObjectTargetWriter() const override { bool is64 = getPointerSize() == 8; - return createPPCELFObjectWriter(OS, is64, isLittleEndian(), OSABI); + return createPPCELFObjectWriter(is64, OSABI); } }; } // end anonymous namespace MCAsmBackend *llvm::createPPCAsmBackend(const Target &T, + const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, - const Triple &TT, StringRef CPU, const MCTargetOptions &Options) { + const Triple &TT = STI.getTargetTriple(); if (TT.isOSDarwin()) return new DarwinPPCAsmBackend(T); uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS()); bool IsLittleEndian = TT.getArch() == Triple::ppc64le; - return new ELFPPCAsmBackend(T, IsLittleEndian, OSABI); + return new ELFPPCAsmBackend( + T, IsLittleEndian ? support::little : support::big, OSABI); } diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp index 44ee9733b16e..a3caf9a7a5ee 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp +++ b/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp @@ -55,6 +55,10 @@ static MCSymbolRefExpr::VariantKind getAccessVariant(const MCValue &Target, return MCSymbolRefExpr::VK_PPC_HI; case PPCMCExpr::VK_PPC_HA: return MCSymbolRefExpr::VK_PPC_HA; + case PPCMCExpr::VK_PPC_HIGH: + return MCSymbolRefExpr::VK_PPC_HIGH; + case PPCMCExpr::VK_PPC_HIGHA: + return MCSymbolRefExpr::VK_PPC_HIGHA; case PPCMCExpr::VK_PPC_HIGHERA: return MCSymbolRefExpr::VK_PPC_HIGHERA; case PPCMCExpr::VK_PPC_HIGHER: @@ -151,6 +155,12 @@ unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target, case MCSymbolRefExpr::VK_PPC_HA: Type = ELF::R_PPC_ADDR16_HA; break; + case MCSymbolRefExpr::VK_PPC_HIGH: + Type = ELF::R_PPC64_ADDR16_HIGH; + break; + case MCSymbolRefExpr::VK_PPC_HIGHA: + Type = ELF::R_PPC64_ADDR16_HIGHA; + break; case MCSymbolRefExpr::VK_PPC_HIGHER: Type = ELF::R_PPC64_ADDR16_HIGHER; break; @@ -199,6 +209,12 @@ unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target, case MCSymbolRefExpr::VK_PPC_TPREL_HA: Type = ELF::R_PPC_TPREL16_HA; break; + case MCSymbolRefExpr::VK_PPC_TPREL_HIGH: + Type = ELF::R_PPC64_TPREL16_HIGH; + break; + case MCSymbolRefExpr::VK_PPC_TPREL_HIGHA: + Type = ELF::R_PPC64_TPREL16_HIGHA; + break; case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER: Type = ELF::R_PPC64_TPREL16_HIGHER; break; @@ -223,6 +239,12 @@ unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target, case MCSymbolRefExpr::VK_PPC_DTPREL_HA: Type = ELF::R_PPC64_DTPREL16_HA; break; + case MCSymbolRefExpr::VK_PPC_DTPREL_HIGH: + Type = ELF::R_PPC64_DTPREL16_HIGH; + break; + case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHA: + Type = ELF::R_PPC64_DTPREL16_HIGHA; + break; case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER: Type = ELF::R_PPC64_DTPREL16_HIGHER; break; @@ -417,9 +439,7 @@ bool PPCELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym, } } -std::unique_ptr<MCObjectWriter> -llvm::createPPCELFObjectWriter(raw_pwrite_stream &OS, bool Is64Bit, - bool IsLittleEndian, uint8_t OSABI) { - auto MOTW = llvm::make_unique<PPCELFObjectWriter>(Is64Bit, OSABI); - return createELFObjectWriter(std::move(MOTW), OS, IsLittleEndian); +std::unique_ptr<MCObjectTargetWriter> +llvm::createPPCELFObjectWriter(bool Is64Bit, uint8_t OSABI) { + return llvm::make_unique<PPCELFObjectWriter>(Is64Bit, OSABI); } diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp index 92c8c224b71b..2b948ca60028 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp +++ b/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp @@ -122,25 +122,18 @@ public: // Output the constant in big/little endian byte order. unsigned Size = Desc.getSize(); + support::endianness E = IsLittleEndian ? support::little : support::big; switch (Size) { case 0: break; case 4: - if (IsLittleEndian) { - support::endian::Writer<support::little>(OS).write<uint32_t>(Bits); - } else { - support::endian::Writer<support::big>(OS).write<uint32_t>(Bits); - } + support::endian::write<uint32_t>(OS, Bits, E); break; case 8: // If we emit a pair of instructions, the first one is // always in the top 32 bits, even on little-endian. - if (IsLittleEndian) { - uint64_t Swapped = (Bits << 32) | (Bits >> 32); - support::endian::Writer<support::little>(OS).write<uint64_t>(Swapped); - } else { - support::endian::Writer<support::big>(OS).write<uint64_t>(Bits); - } + support::endian::write<uint32_t>(OS, Bits >> 32, E); + support::endian::write<uint32_t>(OS, Bits, E); break; default: llvm_unreachable("Invalid instruction size"); diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp index 54f664314578..32e6a0bdd65f 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp +++ b/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp @@ -44,6 +44,8 @@ void PPCMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const { case VK_PPC_LO: OS << "@l"; break; case VK_PPC_HI: OS << "@h"; break; case VK_PPC_HA: OS << "@ha"; break; + case VK_PPC_HIGH: OS << "@high"; break; + case VK_PPC_HIGHA: OS << "@higha"; break; case VK_PPC_HIGHER: OS << "@higher"; break; case VK_PPC_HIGHERA: OS << "@highera"; break; case VK_PPC_HIGHEST: OS << "@highest"; break; @@ -75,6 +77,10 @@ PPCMCExpr::evaluateAsInt64(int64_t Value) const { return (Value >> 16) & 0xffff; case VK_PPC_HA: return ((Value + 0x8000) >> 16) & 0xffff; + case VK_PPC_HIGH: + return (Value >> 16) & 0xffff; + case VK_PPC_HIGHA: + return ((Value + 0x8000) >> 16) & 0xffff; case VK_PPC_HIGHER: return (Value >> 32) & 0xffff; case VK_PPC_HIGHERA: @@ -125,6 +131,12 @@ PPCMCExpr::evaluateAsRelocatableImpl(MCValue &Res, case VK_PPC_HA: Modifier = MCSymbolRefExpr::VK_PPC_HA; break; + case VK_PPC_HIGH: + Modifier = MCSymbolRefExpr::VK_PPC_HIGH; + break; + case VK_PPC_HIGHA: + Modifier = MCSymbolRefExpr::VK_PPC_HIGHA; + break; case VK_PPC_HIGHERA: Modifier = MCSymbolRefExpr::VK_PPC_HIGHERA; break; diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h b/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h index d42a111cc43e..8bb4791d13dd 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h +++ b/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h @@ -23,6 +23,8 @@ public: VK_PPC_LO, VK_PPC_HI, VK_PPC_HA, + VK_PPC_HIGH, + VK_PPC_HIGHA, VK_PPC_HIGHER, VK_PPC_HIGHERA, VK_PPC_HIGHEST, diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h b/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h index 80a74c09a598..316fd2ccf358 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h +++ b/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h @@ -27,8 +27,9 @@ class MCAsmBackend; class MCCodeEmitter; class MCContext; class MCInstrInfo; -class MCObjectWriter; +class MCObjectTargetWriter; class MCRegisterInfo; +class MCSubtargetInfo; class MCTargetOptions; class Target; class Triple; @@ -43,20 +44,16 @@ MCCodeEmitter *createPPCMCCodeEmitter(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, MCContext &Ctx); -MCAsmBackend *createPPCAsmBackend(const Target &T, const MCRegisterInfo &MRI, - const Triple &TT, StringRef CPU, +MCAsmBackend *createPPCAsmBackend(const Target &T, const MCSubtargetInfo &STI, + const MCRegisterInfo &MRI, const MCTargetOptions &Options); /// Construct an PPC ELF object writer. -std::unique_ptr<MCObjectWriter> createPPCELFObjectWriter(raw_pwrite_stream &OS, - bool Is64Bit, - bool IsLittleEndian, - uint8_t OSABI); +std::unique_ptr<MCObjectTargetWriter> createPPCELFObjectWriter(bool Is64Bit, + uint8_t OSABI); /// Construct a PPC Mach-O object writer. -std::unique_ptr<MCObjectWriter> createPPCMachObjectWriter(raw_pwrite_stream &OS, - bool Is64Bit, - uint32_t CPUType, - uint32_t CPUSubtype); +std::unique_ptr<MCObjectTargetWriter> +createPPCMachObjectWriter(bool Is64Bit, uint32_t CPUType, uint32_t CPUSubtype); /// Returns true iff Val consists of one contiguous run of 1s with any number of /// 0s on either side. The 1s are allowed to wrap from LSB to MSB, so diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMachObjectWriter.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCMachObjectWriter.cpp index 4b9055ec7041..ff6cf584da23 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCMachObjectWriter.cpp +++ b/lib/Target/PowerPC/MCTargetDesc/PPCMachObjectWriter.cpp @@ -374,10 +374,8 @@ void PPCMachObjectWriter::RecordPPCRelocation( Writer->addRelocation(RelSymbol, Fragment->getParent(), MRE); } -std::unique_ptr<MCObjectWriter> -llvm::createPPCMachObjectWriter(raw_pwrite_stream &OS, bool Is64Bit, - uint32_t CPUType, uint32_t CPUSubtype) { - return createMachObjectWriter( - llvm::make_unique<PPCMachObjectWriter>(Is64Bit, CPUType, CPUSubtype), OS, - /*IsLittleEndian=*/false); +std::unique_ptr<MCObjectTargetWriter> +llvm::createPPCMachObjectWriter(bool Is64Bit, uint32_t CPUType, + uint32_t CPUSubtype) { + return llvm::make_unique<PPCMachObjectWriter>(Is64Bit, CPUType, CPUSubtype); } diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h b/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h index 603ac960133f..fe7e7aeeb182 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h +++ b/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h @@ -50,6 +50,9 @@ namespace PPC { PRED_UN_PLUS = (3 << 5) | 15, PRED_NU_PLUS = (3 << 5) | 7, + // SPE scalar compare instructions always set the GT bit. + PRED_SPE = PRED_GT, + // When dealing with individual condition-register bits, we have simple set // and unset predicates. PRED_BIT_SET = 1024, |
