summaryrefslogtreecommitdiff
path: root/lib/Target/PowerPC/MCTargetDesc
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-07-28 10:51:19 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-07-28 10:51:19 +0000
commiteb11fae6d08f479c0799db45860a98af528fa6e7 (patch)
tree44d492a50c8c1a7eb8e2d17ea3360ec4d066f042 /lib/Target/PowerPC/MCTargetDesc
parentb8a2042aa938069e862750553db0e4d82d25822c (diff)
Notes
Diffstat (limited to 'lib/Target/PowerPC/MCTargetDesc')
-rw-r--r--lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp52
-rw-r--r--lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp30
-rw-r--r--lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp15
-rw-r--r--lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp12
-rw-r--r--lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h2
-rw-r--r--lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h19
-rw-r--r--lib/Target/PowerPC/MCTargetDesc/PPCMachObjectWriter.cpp10
-rw-r--r--lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h3
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,