diff options
Diffstat (limited to 'llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp')
-rw-r--r-- | llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp | 84 |
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); |