summaryrefslogtreecommitdiff
path: root/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp')
-rw-r--r--llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp84
1 files changed, 64 insertions, 20 deletions
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
index cbfb8e2ff2825..3092d56da1c59 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
@@ -13,6 +13,7 @@
#include "MCTargetDesc/PPCMCTargetDesc.h"
#include "MCTargetDesc/PPCInstPrinter.h"
#include "MCTargetDesc/PPCMCAsmInfo.h"
+#include "PPCELFStreamer.h"
#include "PPCTargetStreamer.h"
#include "TargetInfo/PowerPCTargetInfo.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -20,11 +21,14 @@
#include "llvm/ADT/Triple.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCELFStreamer.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
@@ -91,12 +95,21 @@ static MCAsmInfo *createPPCMCAsmInfo(const MCRegisterInfo &MRI,
// Initial state of the frame pointer is R1.
unsigned Reg = isPPC64 ? PPC::X1 : PPC::R1;
MCCFIInstruction Inst =
- MCCFIInstruction::createDefCfa(nullptr, MRI.getDwarfRegNum(Reg, true), 0);
+ MCCFIInstruction::cfiDefCfa(nullptr, MRI.getDwarfRegNum(Reg, true), 0);
MAI->addInitialFrameState(Inst);
return MAI;
}
+static MCStreamer *createPPCMCStreamer(const Triple &T, MCContext &Context,
+ std::unique_ptr<MCAsmBackend> &&MAB,
+ std::unique_ptr<MCObjectWriter> &&OW,
+ std::unique_ptr<MCCodeEmitter> &&Emitter,
+ bool RelaxAll) {
+ return createPPCELFStreamer(Context, std::move(MAB), std::move(OW),
+ std::move(Emitter));
+}
+
namespace {
class PPCTargetAsmStreamer : public PPCTargetStreamer {
@@ -107,14 +120,17 @@ public:
: PPCTargetStreamer(S), OS(OS) {}
void emitTCEntry(const MCSymbol &S) override {
- const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();
- OS << "\t.tc ";
- OS << (MAI->getSymbolsHaveSMC()
- ? cast<MCSymbolXCOFF>(S).getUnqualifiedName()
- : S.getName());
- OS << "[TC],";
- OS << S.getName();
- OS << '\n';
+ if (const MCSymbolXCOFF *XSym = dyn_cast<MCSymbolXCOFF>(&S)) {
+ MCSymbolXCOFF *TCSym =
+ cast<MCSymbolXCOFF>(Streamer.getContext().getOrCreateSymbol(
+ XSym->getSymbolTableName() + "[TC]"));
+ if (TCSym->hasRename())
+ Streamer.emitXCOFFRenameDirective(TCSym, TCSym->getSymbolTableName());
+ OS << "\t.tc " << TCSym->getName() << "," << XSym->getName() << '\n';
+ return;
+ }
+
+ OS << "\t.tc " << S.getName() << "[TC]," << S.getName() << '\n';
}
void emitMachine(StringRef CPU) override {
@@ -146,8 +162,8 @@ public:
void emitTCEntry(const MCSymbol &S) override {
// Creates a R_PPC64_TOC relocation
- Streamer.EmitValueToAlignment(8);
- Streamer.EmitSymbolValue(&S, 8);
+ Streamer.emitValueToAlignment(8);
+ Streamer.emitSymbolValue(&S, 8);
}
void emitMachine(StringRef CPU) override {
@@ -166,13 +182,9 @@ public:
void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset) override {
MCAssembler &MCA = getStreamer().getAssembler();
- int64_t Res;
- if (!LocalOffset->evaluateAsAbsolute(Res, MCA))
- report_fatal_error(".localentry expression must be absolute.");
-
- unsigned Encoded = ELF::encodePPC64LocalEntryOffset(Res);
- if (Res != ELF::decodePPC64LocalEntryOffset(Encoded))
- report_fatal_error(".localentry expression cannot be encoded.");
+ // encodePPC64LocalEntryOffset will report an error if it cannot
+ // encode LocalOffset.
+ unsigned Encoded = encodePPC64LocalEntryOffset(LocalOffset);
unsigned Other = S->getOther();
Other &= ~ELF::STO_PPC64_LOCAL_MASK;
@@ -201,6 +213,10 @@ public:
for (auto *Sym : UpdateOther)
if (Sym->isVariable())
copyLocalEntry(Sym, Sym->getVariableValue());
+
+ // Clear the set of symbols that needs to be updated so the streamer can
+ // be reused without issues.
+ UpdateOther.clear();
}
private:
@@ -217,6 +233,31 @@ private:
D->setOther(Other);
return true;
}
+
+ unsigned encodePPC64LocalEntryOffset(const MCExpr *LocalOffset) {
+ MCAssembler &MCA = getStreamer().getAssembler();
+ int64_t Offset;
+ if (!LocalOffset->evaluateAsAbsolute(Offset, MCA))
+ MCA.getContext().reportFatalError(
+ LocalOffset->getLoc(), ".localentry expression must be absolute.");
+
+ switch (Offset) {
+ default:
+ MCA.getContext().reportFatalError(
+ LocalOffset->getLoc(),
+ ".localentry expression is not a valid power of 2.");
+ case 0:
+ return 0;
+ case 1:
+ return 1 << ELF::STO_PPC64_LOCAL_BIT;
+ case 4:
+ case 8:
+ case 16:
+ case 32:
+ case 64:
+ return (int)Log2(Offset) << (int)ELF::STO_PPC64_LOCAL_BIT;
+ }
+ }
};
class PPCTargetMachOStreamer : public PPCTargetStreamer {
@@ -248,8 +289,8 @@ public:
void emitTCEntry(const MCSymbol &S) override {
const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();
const unsigned PointerSize = MAI->getCodePointerSize();
- Streamer.EmitValueToAlignment(PointerSize);
- Streamer.EmitSymbolValue(&S, PointerSize);
+ Streamer.emitValueToAlignment(PointerSize);
+ Streamer.emitSymbolValue(&S, PointerSize);
}
void emitMachine(StringRef CPU) override {
@@ -313,6 +354,9 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCTargetMC() {
// Register the asm backend.
TargetRegistry::RegisterMCAsmBackend(*T, createPPCAsmBackend);
+ // Register the elf streamer.
+ TargetRegistry::RegisterELFStreamer(*T, createPPCMCStreamer);
+
// Register the object target streamer.
TargetRegistry::RegisterObjectTargetStreamer(*T,
createObjectTargetStreamer);