From 320296a4cfe414ce59f406b8a5ce15272f563103 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Tue, 8 Oct 2013 13:08:17 +0000 Subject: Add a MCTargetStreamer interface. This patch fixes an old FIXME by creating a MCTargetStreamer interface and moving the target specific functions for ARM, Mips and PPC to it. The ARM streamer is still declared in a common place because it is used from lib/CodeGen/ARMException.cpp, but the Mips and PPC are completely hidden in the corresponding Target directories. I will send an email to llvmdev with instructions on how to use this. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192181 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCELFStreamer.h | 20 +-- include/llvm/MC/MCObjectStreamer.h | 8 +- include/llvm/MC/MCStreamer.h | 91 +++++++--- include/llvm/Support/TargetRegistry.h | 32 ++-- lib/CodeGen/AsmPrinter/ARMException.cpp | 16 +- lib/CodeGen/AsmPrinter/DwarfException.h | 3 + lib/LTO/LTOModule.cpp | 2 +- lib/MC/MCAsmStreamer.cpp | 139 ++------------- lib/MC/MCELFStreamer.cpp | 15 +- lib/MC/MCMachOStreamer.cpp | 2 +- lib/MC/MCNullStreamer.cpp | 2 +- lib/MC/MCObjectStreamer.cpp | 17 +- lib/MC/MCPureStreamer.cpp | 2 +- lib/MC/MCStreamer.cpp | 61 +------ lib/MC/WinCOFFStreamer.cpp | 2 +- .../AArch64/MCTargetDesc/AArch64ELFStreamer.cpp | 9 +- lib/Target/ARM/ARMAsmPrinter.cpp | 8 +- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 25 +-- lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp | 198 ++++++++++++++++----- lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp | 4 + lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h | 9 + lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 10 +- lib/Target/Mips/MCTargetDesc/CMakeLists.txt | 1 - lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp | 55 ------ lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp | 98 +++++++++- lib/Target/Mips/MipsAsmPrinter.cpp | 17 +- lib/Target/Mips/MipsAsmPrinter.h | 2 + lib/Target/Mips/MipsTargetStreamer.h | 23 +++ .../PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp | 46 ++++- lib/Target/PowerPC/PPCAsmPrinter.cpp | 6 +- lib/Target/PowerPC/PPCTargetStreamer.h | 22 +++ .../R600/MCTargetDesc/AMDGPUMCTargetDesc.cpp | 2 +- .../SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp | 2 +- lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp | 2 +- 34 files changed, 558 insertions(+), 393 deletions(-) delete mode 100644 lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp create mode 100644 lib/Target/Mips/MipsTargetStreamer.h create mode 100644 lib/Target/PowerPC/PPCTargetStreamer.h diff --git a/include/llvm/MC/MCELFStreamer.h b/include/llvm/MC/MCELFStreamer.h index 0f45a93f95..8dbe337b0f 100644 --- a/include/llvm/MC/MCELFStreamer.h +++ b/include/llvm/MC/MCELFStreamer.h @@ -29,13 +29,15 @@ class raw_ostream; class MCELFStreamer : public MCObjectStreamer { public: - MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, - MCCodeEmitter *Emitter) - : MCObjectStreamer(Context, TAB, OS, Emitter) {} + MCELFStreamer(MCContext &Context, MCTargetStreamer *TargetStreamer, + MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter) + : MCObjectStreamer(Context, TargetStreamer, TAB, OS, Emitter) {} - MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, - MCCodeEmitter *Emitter, MCAssembler *Assembler) - : MCObjectStreamer(Context, TAB, OS, Emitter, Assembler) {} + MCELFStreamer(MCContext &Context, MCTargetStreamer *TargetStreamer, + MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter, + MCAssembler *Assembler) + : MCObjectStreamer(Context, TargetStreamer, TAB, OS, Emitter, Assembler) { + } virtual ~MCELFStreamer(); @@ -75,8 +77,6 @@ public: virtual void EmitFileDirective(StringRef Filename); - virtual void EmitTCEntry(const MCSymbol &S); - virtual void EmitValueToAlignment(unsigned, int64_t, unsigned, unsigned); virtual void Flush(); @@ -111,10 +111,6 @@ private: void SetSectionBss(); }; -MCELFStreamer *createMipsELFStreamer(MCContext &Context, MCAsmBackend &TAB, - raw_ostream &OS, MCCodeEmitter *Emitter, - bool RelaxAll, bool NoExecStack); - MCELFStreamer *createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter, bool RelaxAll, bool NoExecStack, diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h index f6a7e713c4..5667544301 100644 --- a/include/llvm/MC/MCObjectStreamer.h +++ b/include/llvm/MC/MCObjectStreamer.h @@ -40,10 +40,12 @@ class MCObjectStreamer : public MCStreamer { virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame); protected: - MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &_OS, + MCObjectStreamer(MCContext &Context, MCTargetStreamer *TargetStreamer, + MCAsmBackend &TAB, raw_ostream &_OS, MCCodeEmitter *_Emitter); - MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &_OS, - MCCodeEmitter *_Emitter, MCAssembler *_Assembler); + MCObjectStreamer(MCContext &Context, MCTargetStreamer *TargetStreamer, + MCAsmBackend &TAB, raw_ostream &_OS, MCCodeEmitter *_Emitter, + MCAssembler *_Assembler); ~MCObjectStreamer(); public: diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 3cd5c773c1..10fc69ef84 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -31,6 +31,7 @@ class MCExpr; class MCInst; class MCInstPrinter; class MCSection; +class MCStreamer; class MCSymbol; class StringRef; class Twine; @@ -39,6 +40,55 @@ class formatted_raw_ostream; typedef std::pair MCSectionSubPair; +/// Target specific streamer interface. This is used so that targets can +/// implement support for target specific assembly directives. +/// +/// If target foo wants to use this, it should implement 3 classes: +/// * FooTargetStreamer : public MCTargetStreamer +/// * FooTargetAsmSreamer : public FooTargetStreamer +/// * FooTargetELFStreamer : public FooTargetStreamer +/// +/// FooTargetStreamer should have a pure virtual method for each directive. For +/// example, for a ".bar symbol_name" directive, it should have +/// virtual emitBar(const MCSymbol &Symbol) = 0; +/// +/// The FooTargetAsmSreamer and FooTargetELFStreamer classes implement the +/// method. The assembly streamer just prints ".bar symbol_name". The object +/// streamer does whatever is needed to implement .bar in the object file. +/// +/// In the assembly printer and parser the target streamer can be used by +/// calling getTargetStreamer and casting it to FooTargetStreamer: +/// +/// MCTargetStreamer &TS = OutStreamer.getTargetStreamer(); +/// FooTargetStreamer &ATS = static_cast(TS); +/// +/// The base classes FooTargetAsmSreamer and FooTargetELFStreamer should *never* +/// be treated differently. Callers should always talk to a FooTargetStreamer. +class MCTargetStreamer { +protected: + OwningPtr Streamer; + +public: + virtual ~MCTargetStreamer(); + void setStreamer(MCStreamer *S) { Streamer.reset(S); } +}; + +// FIXME: declared here because it is used from +// lib/CodeGen/AsmPrinter/ARMException.cpp. +class ARMTargetStreamer : public MCTargetStreamer { +public: + virtual void emitFnStart() = 0; + virtual void emitFnEnd() = 0; + virtual void emitCantUnwind() = 0; + virtual void emitPersonality(const MCSymbol *Personality) = 0; + virtual void emitHandlerData() = 0; + virtual void emitSetFP(unsigned FpReg, unsigned SpReg, + int64_t Offset = 0) = 0; + virtual void emitPad(int64_t Offset) = 0; + virtual void emitRegSave(const SmallVectorImpl &RegList, + bool isVector) = 0; +}; + /// MCStreamer - Streaming machine code generation interface. This interface /// is intended to provide a programatic interface that is very similar to the /// level that an assembler .s file provides. It has callbacks to emit bytes, @@ -50,6 +100,7 @@ typedef std::pair MCSectionSubPair; /// class MCStreamer { MCContext &Context; + MCTargetStreamer *TargetStreamer; MCStreamer(const MCStreamer &) LLVM_DELETED_FUNCTION; MCStreamer &operator=(const MCStreamer &) LLVM_DELETED_FUNCTION; @@ -80,7 +131,7 @@ class MCStreamer { bool AutoInitSections; protected: - MCStreamer(MCContext &Ctx); + MCStreamer(MCContext &Ctx, MCTargetStreamer *TargetStreamer); const MCExpr *BuildSymbolDiff(MCContext &Context, const MCSymbol *A, const MCSymbol *B); @@ -107,6 +158,11 @@ public: MCContext &getContext() const { return Context; } + MCTargetStreamer &getTargetStreamer() { + assert(TargetStreamer); + return *TargetStreamer; + } + unsigned getNumFrameInfos() { return FrameInfos.size(); } const MCDwarfFrameInfo &getFrameInfo(unsigned i) { return FrameInfos[i]; } @@ -600,28 +656,6 @@ public: virtual void EmitRawText(StringRef String); void EmitRawText(const Twine &String); - /// ARM-related methods. - /// FIXME: Eventually we should have some "target MC streamer" and move - /// these methods there. - virtual void EmitFnStart(); - virtual void EmitFnEnd(); - virtual void EmitCantUnwind(); - virtual void EmitPersonality(const MCSymbol *Personality); - virtual void EmitHandlerData(); - virtual void EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0); - virtual void EmitPad(int64_t Offset); - virtual void EmitRegSave(const SmallVectorImpl &RegList, - bool isVector); - - /// Mips-related methods. - virtual void emitMipsHackELFFlags(unsigned Flags); - virtual void emitMipsHackSTOCG(MCSymbol *Sym, unsigned Val); - - /// PPC-related methods. - /// FIXME: Eventually replace it with some "target MC streamer" and move - /// these methods there. - virtual void EmitTCEntry(const MCSymbol &S); - /// Flush - Causes any cached state to be written out. virtual void Flush() {} @@ -652,9 +686,9 @@ MCStreamer *createNullStreamer(MCContext &Ctx); /// /// \param ShowInst - Whether to show the MCInst representation inline with /// the assembly. -MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, - bool isVerboseAsm, bool useLoc, bool useCFI, - bool useDwarfDirectory, +MCStreamer *createAsmStreamer(MCContext &Ctx, MCTargetStreamer *TargetStreamer, + formatted_raw_ostream &OS, bool isVerboseAsm, + bool useLoc, bool useCFI, bool useDwarfDirectory, MCInstPrinter *InstPrint = 0, MCCodeEmitter *CE = 0, MCAsmBackend *TAB = 0, bool ShowInst = false); @@ -677,8 +711,9 @@ MCStreamer *createWinCOFFStreamer(MCContext &Ctx, MCAsmBackend &TAB, /// createELFStreamer - Create a machine code streamer which will generate /// ELF format object files. -MCStreamer *createELFStreamer(MCContext &Ctx, MCAsmBackend &TAB, - raw_ostream &OS, MCCodeEmitter *CE, bool RelaxAll, +MCStreamer *createELFStreamer(MCContext &Ctx, MCTargetStreamer *TargetStreamer, + MCAsmBackend &TAB, raw_ostream &OS, + MCCodeEmitter *CE, bool RelaxAll, bool NoExecStack); /// createPureStreamer - Create a machine code streamer which will generate diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h index 05f7cf2f6f..8c9a9174a9 100644 --- a/include/llvm/Support/TargetRegistry.h +++ b/include/llvm/Support/TargetRegistry.h @@ -46,18 +46,18 @@ namespace llvm { class MCRelocationInfo; class MCTargetAsmParser; class TargetMachine; + class MCTargetStreamer; class TargetOptions; class raw_ostream; class formatted_raw_ostream; - MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, - bool isVerboseAsm, + MCStreamer *createAsmStreamer(MCContext &Ctx, + MCTargetStreamer *TargetStreamer, + formatted_raw_ostream &OS, bool isVerboseAsm, bool useLoc, bool useCFI, bool useDwarfDirectory, - MCInstPrinter *InstPrint, - MCCodeEmitter *CE, - MCAsmBackend *TAB, - bool ShowInst); + MCInstPrinter *InstPrint, MCCodeEmitter *CE, + MCAsmBackend *TAB, bool ShowInst); MCRelocationInfo *createMCRelocationInfo(StringRef TT, MCContext &Ctx); @@ -235,10 +235,22 @@ namespace llvm { /// MCSymbolizer, if registered (default = llvm::createMCSymbolizer) MCSymbolizerCtorTy MCSymbolizerCtorFn; + static MCStreamer * + createDefaultAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, + bool isVerboseAsm, bool useLoc, bool useCFI, + bool useDwarfDirectory, MCInstPrinter *InstPrint, + MCCodeEmitter *CE, MCAsmBackend *TAB, + bool ShowInst) { + return llvm::createAsmStreamer(Ctx, 0, OS, isVerboseAsm, useLoc, useCFI, + useDwarfDirectory, InstPrint, CE, TAB, + ShowInst); + } + public: - Target() : AsmStreamerCtorFn(llvm::createAsmStreamer), - MCRelocationInfoCtorFn(llvm::createMCRelocationInfo), - MCSymbolizerCtorFn(llvm::createMCSymbolizer) {} + Target() + : AsmStreamerCtorFn(createDefaultAsmStreamer), + MCRelocationInfoCtorFn(llvm::createMCRelocationInfo), + MCSymbolizerCtorFn(llvm::createMCSymbolizer) {} /// @name Target Information /// @{ @@ -816,7 +828,7 @@ namespace llvm { /// @param T - The target being registered. /// @param Fn - A function to construct an MCStreamer for the target. static void RegisterAsmStreamer(Target &T, Target::AsmStreamerCtorTy Fn) { - if (T.AsmStreamerCtorFn == createAsmStreamer) + if (T.AsmStreamerCtorFn == Target::createDefaultAsmStreamer) T.AsmStreamerCtorFn = Fn; } diff --git a/lib/CodeGen/AsmPrinter/ARMException.cpp b/lib/CodeGen/AsmPrinter/ARMException.cpp index 188047d94f..f7d6f3b5f2 100644 --- a/lib/CodeGen/AsmPrinter/ARMException.cpp +++ b/lib/CodeGen/AsmPrinter/ARMException.cpp @@ -47,13 +47,18 @@ ARMException::ARMException(AsmPrinter *A) ARMException::~ARMException() {} +ARMTargetStreamer &ARMException::getTargetStreamer() { + MCTargetStreamer &TS = Asm->OutStreamer.getTargetStreamer(); + return static_cast(TS); +} + void ARMException::EndModule() { } /// BeginFunction - Gather pre-function exception information. Assumes it's /// being emitted immediately after the function entry point. void ARMException::BeginFunction(const MachineFunction *MF) { - Asm->OutStreamer.EmitFnStart(); + getTargetStreamer().emitFnStart(); if (Asm->MF->getFunction()->needsUnwindTableEntry()) Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_begin", Asm->getFunctionNumber())); @@ -62,8 +67,9 @@ void ARMException::BeginFunction(const MachineFunction *MF) { /// EndFunction - Gather and emit post-function exception information. /// void ARMException::EndFunction() { + ARMTargetStreamer &ATS = getTargetStreamer(); if (!Asm->MF->getFunction()->needsUnwindTableEntry()) - Asm->OutStreamer.EmitCantUnwind(); + ATS.emitCantUnwind(); else { Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_end", Asm->getFunctionNumber())); @@ -78,11 +84,11 @@ void ARMException::EndFunction() { MMI->getPersonalities()[MMI->getPersonalityIndex()]) { MCSymbol *PerSym = Asm->Mang->getSymbol(Personality); Asm->OutStreamer.EmitSymbolAttribute(PerSym, MCSA_Global); - Asm->OutStreamer.EmitPersonality(PerSym); + ATS.emitPersonality(PerSym); } // Emit .handlerdata directive. - Asm->OutStreamer.EmitHandlerData(); + ATS.emitHandlerData(); // Emit actual exception table EmitExceptionTable(); @@ -90,7 +96,7 @@ void ARMException::EndFunction() { } } - Asm->OutStreamer.EmitFnEnd(); + ATS.emitFnEnd(); } void ARMException::EmitTypeInfos(unsigned TTypeEncoding) { diff --git a/lib/CodeGen/AsmPrinter/DwarfException.h b/lib/CodeGen/AsmPrinter/DwarfException.h index 49a85d81b4..15751615b7 100644 --- a/lib/CodeGen/AsmPrinter/DwarfException.h +++ b/lib/CodeGen/AsmPrinter/DwarfException.h @@ -29,6 +29,7 @@ class MCAsmInfo; class MCExpr; class MCSymbol; class Function; +class ARMTargetStreamer; class AsmPrinter; //===----------------------------------------------------------------------===// @@ -177,6 +178,8 @@ public: class ARMException : public DwarfException { void EmitTypeInfos(unsigned TTypeEncoding); + ARMTargetStreamer &getTargetStreamer(); + public: //===--------------------------------------------------------------------===// // Main entry points. diff --git a/lib/LTO/LTOModule.cpp b/lib/LTO/LTOModule.cpp index 207e85c1c9..98c5416d8d 100644 --- a/lib/LTO/LTOModule.cpp +++ b/lib/LTO/LTOModule.cpp @@ -591,7 +591,7 @@ namespace { return Symbols.end(); } - RecordStreamer(MCContext &Context) : MCStreamer(Context) {} + RecordStreamer(MCContext &Context) : MCStreamer(Context, 0) {} virtual void EmitInstruction(const MCInst &Inst) { // Scan for values. diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index 0f9a327a48..e735344a69 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -34,9 +34,6 @@ #include using namespace llvm; -static cl::opt PrintHackDirectives("print-hack-directives", - cl::init(false), cl::Hidden); - namespace { class MCAsmStreamer : public MCStreamer { @@ -69,17 +66,15 @@ private: virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame); public: - MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os, - bool isVerboseAsm, bool useLoc, bool useCFI, - bool useDwarfDirectory, - MCInstPrinter *printer, MCCodeEmitter *emitter, - MCAsmBackend *asmbackend, - bool showInst) - : MCStreamer(Context), OS(os), MAI(Context.getAsmInfo()), - InstPrinter(printer), Emitter(emitter), AsmBackend(asmbackend), - CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm), - ShowInst(showInst), UseLoc(useLoc), UseCFI(useCFI), - UseDwarfDirectory(useDwarfDirectory) { + MCAsmStreamer(MCContext &Context, MCTargetStreamer *TargetStreamer, + formatted_raw_ostream &os, bool isVerboseAsm, bool useLoc, + bool useCFI, bool useDwarfDirectory, MCInstPrinter *printer, + MCCodeEmitter *emitter, MCAsmBackend *asmbackend, bool showInst) + : MCStreamer(Context, TargetStreamer), OS(os), MAI(Context.getAsmInfo()), + InstPrinter(printer), Emitter(emitter), AsmBackend(asmbackend), + CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm), + ShowInst(showInst), UseLoc(useLoc), UseCFI(useCFI), + UseDwarfDirectory(useDwarfDirectory) { if (InstPrinter && IsVerboseAsm) InstPrinter->setCommentStream(CommentStream); } @@ -250,22 +245,6 @@ public: virtual void EmitWin64EHPushFrame(bool Code); virtual void EmitWin64EHEndProlog(); - virtual void EmitFnStart(); - virtual void EmitFnEnd(); - virtual void EmitCantUnwind(); - virtual void EmitPersonality(const MCSymbol *Personality); - virtual void EmitHandlerData(); - virtual void EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0); - virtual void EmitPad(int64_t Offset); - virtual void EmitRegSave(const SmallVectorImpl &RegList, bool); - - /// Mips-related methods. - virtual void emitMipsHackELFFlags(unsigned Flags); - virtual void emitMipsHackSTOCG(MCSymbol *Sym, unsigned Val); - - - virtual void EmitTCEntry(const MCSymbol &S); - virtual void EmitInstruction(const MCInst &Inst); virtual void EmitBundleAlignMode(unsigned AlignPow2); @@ -1317,93 +1296,6 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) { } } -void MCAsmStreamer::EmitFnStart() { - OS << "\t.fnstart"; - EmitEOL(); -} - -void MCAsmStreamer::EmitFnEnd() { - OS << "\t.fnend"; - EmitEOL(); -} - -void MCAsmStreamer::EmitCantUnwind() { - OS << "\t.cantunwind"; - EmitEOL(); -} - -void MCAsmStreamer::EmitHandlerData() { - OS << "\t.handlerdata"; - EmitEOL(); -} - -void MCAsmStreamer::EmitPersonality(const MCSymbol *Personality) { - OS << "\t.personality " << Personality->getName(); - EmitEOL(); -} - -void MCAsmStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) { - OS << "\t.setfp\t"; - InstPrinter->printRegName(OS, FpReg); - OS << ", "; - InstPrinter->printRegName(OS, SpReg); - if (Offset) - OS << ", #" << Offset; - EmitEOL(); -} - -void MCAsmStreamer::EmitPad(int64_t Offset) { - OS << "\t.pad\t#" << Offset; - EmitEOL(); -} - -void MCAsmStreamer::EmitRegSave(const SmallVectorImpl &RegList, - bool isVector) { - assert(RegList.size() && "RegList should not be empty"); - if (isVector) - OS << "\t.vsave\t{"; - else - OS << "\t.save\t{"; - - InstPrinter->printRegName(OS, RegList[0]); - - for (unsigned i = 1, e = RegList.size(); i != e; ++i) { - OS << ", "; - InstPrinter->printRegName(OS, RegList[i]); - } - - OS << "}"; - EmitEOL(); -} - -void MCAsmStreamer::emitMipsHackSTOCG(MCSymbol *Sym, unsigned Val) { - if (!PrintHackDirectives) - return; - - OS << "\t.mips_hack_stocg "; - OS << Sym->getName(); - OS << ", "; - OS << Val; - EmitEOL(); -} - -void MCAsmStreamer::emitMipsHackELFFlags(unsigned Flags) { - if (!PrintHackDirectives) - return; - - OS << "\t.mips_hack_elf_flags 0x"; - OS.write_hex(Flags); - EmitEOL(); -} - -void MCAsmStreamer::EmitTCEntry(const MCSymbol &S) { - OS << "\t.tc "; - OS << S.getName(); - OS << "[TC],"; - OS << S.getName(); - EmitEOL(); -} - void MCAsmStreamer::EmitInstruction(const MCInst &Inst) { assert(getCurrentSection().first && "Cannot emit contents before setting section!"); @@ -1469,11 +1361,12 @@ void MCAsmStreamer::FinishImpl() { } MCStreamer *llvm::createAsmStreamer(MCContext &Context, + MCTargetStreamer *TargetStreamer, formatted_raw_ostream &OS, - bool isVerboseAsm, bool useLoc, - bool useCFI, bool useDwarfDirectory, - MCInstPrinter *IP, MCCodeEmitter *CE, - MCAsmBackend *MAB, bool ShowInst) { - return new MCAsmStreamer(Context, OS, isVerboseAsm, useLoc, useCFI, - useDwarfDirectory, IP, CE, MAB, ShowInst); + bool isVerboseAsm, bool useLoc, bool useCFI, + bool useDwarfDirectory, MCInstPrinter *IP, + MCCodeEmitter *CE, MCAsmBackend *MAB, + bool ShowInst) { + return new MCAsmStreamer(Context, TargetStreamer, OS, isVerboseAsm, useLoc, + useCFI, useDwarfDirectory, IP, CE, MAB, ShowInst); } diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp index 0ed040d5be..c16a61d2b6 100644 --- a/lib/MC/MCELFStreamer.cpp +++ b/lib/MC/MCELFStreamer.cpp @@ -560,15 +560,12 @@ void MCELFStreamer::FinishImpl() { this->MCObjectStreamer::FinishImpl(); } -void MCELFStreamer::EmitTCEntry(const MCSymbol &S) { - // Creates a R_PPC64_TOC relocation - MCObjectStreamer::EmitSymbolValue(&S, 8); -} - -MCStreamer *llvm::createELFStreamer(MCContext &Context, MCAsmBackend &MAB, - raw_ostream &OS, MCCodeEmitter *CE, - bool RelaxAll, bool NoExecStack) { - MCELFStreamer *S = new MCELFStreamer(Context, MAB, OS, CE); +MCStreamer *llvm::createELFStreamer(MCContext &Context, + MCTargetStreamer *Streamer, + MCAsmBackend &MAB, raw_ostream &OS, + MCCodeEmitter *CE, bool RelaxAll, + bool NoExecStack) { + MCELFStreamer *S = new MCELFStreamer(Context, Streamer, MAB, OS, CE); if (RelaxAll) S->getAssembler().setRelaxAll(true); if (NoExecStack) diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp index 8eaa254cd5..78c009423c 100644 --- a/lib/MC/MCMachOStreamer.cpp +++ b/lib/MC/MCMachOStreamer.cpp @@ -37,7 +37,7 @@ private: public: MCMachOStreamer(MCContext &Context, MCAsmBackend &MAB, raw_ostream &OS, MCCodeEmitter *Emitter) - : MCObjectStreamer(Context, MAB, OS, Emitter) {} + : MCObjectStreamer(Context, 0, MAB, OS, Emitter) {} /// @name MCStreamer Interface /// @{ diff --git a/lib/MC/MCNullStreamer.cpp b/lib/MC/MCNullStreamer.cpp index 8d5da44a06..9b9c4aa2a0 100644 --- a/lib/MC/MCNullStreamer.cpp +++ b/lib/MC/MCNullStreamer.cpp @@ -19,7 +19,7 @@ namespace { class MCNullStreamer : public MCStreamer { public: - MCNullStreamer(MCContext &Context) : MCStreamer(Context) {} + MCNullStreamer(MCContext &Context) : MCStreamer(Context, 0) {} /// @name MCStreamer Interface /// @{ diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp index cbcd5fd021..7fa6695253 100644 --- a/lib/MC/MCObjectStreamer.cpp +++ b/lib/MC/MCObjectStreamer.cpp @@ -22,17 +22,22 @@ #include "llvm/Support/ErrorHandling.h" using namespace llvm; -MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, - raw_ostream &OS, MCCodeEmitter *Emitter_) - : MCStreamer(Context), +MCObjectStreamer::MCObjectStreamer(MCContext &Context, + MCTargetStreamer *TargetStreamer, + MCAsmBackend &TAB, raw_ostream &OS, + MCCodeEmitter *Emitter_) + : MCStreamer(Context, TargetStreamer), Assembler(new MCAssembler(Context, TAB, *Emitter_, *TAB.createObjectWriter(OS), OS)), CurSectionData(0) {} -MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, - raw_ostream &OS, MCCodeEmitter *Emitter_, +MCObjectStreamer::MCObjectStreamer(MCContext &Context, + MCTargetStreamer *TargetStreamer, + MCAsmBackend &TAB, raw_ostream &OS, + MCCodeEmitter *Emitter_, MCAssembler *_Assembler) - : MCStreamer(Context), Assembler(_Assembler), CurSectionData(0) {} + : MCStreamer(Context, TargetStreamer), Assembler(_Assembler), + CurSectionData(0) {} MCObjectStreamer::~MCObjectStreamer() { delete &Assembler->getBackend(); diff --git a/lib/MC/MCPureStreamer.cpp b/lib/MC/MCPureStreamer.cpp index f64aa0caba..e5843b3da5 100644 --- a/lib/MC/MCPureStreamer.cpp +++ b/lib/MC/MCPureStreamer.cpp @@ -29,7 +29,7 @@ private: public: MCPureStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter) - : MCObjectStreamer(Context, TAB, OS, Emitter) {} + : MCObjectStreamer(Context, 0, TAB, OS, Emitter) {} /// @name MCStreamer Interface /// @{ diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp index bac58063a4..04e36bedc0 100644 --- a/lib/MC/MCStreamer.cpp +++ b/lib/MC/MCStreamer.cpp @@ -22,10 +22,15 @@ #include using namespace llvm; -MCStreamer::MCStreamer(MCContext &Ctx) - : Context(Ctx), EmitEHFrame(true), EmitDebugFrame(false), - CurrentW64UnwindInfo(0), LastSymbol(0), AutoInitSections(false) { +MCTargetStreamer::~MCTargetStreamer() {} + +MCStreamer::MCStreamer(MCContext &Ctx, MCTargetStreamer *TargetStreamer) + : Context(Ctx), TargetStreamer(TargetStreamer), EmitEHFrame(true), + EmitDebugFrame(false), CurrentW64UnwindInfo(0), LastSymbol(0), + AutoInitSections(false) { SectionStack.push_back(std::pair()); + if (TargetStreamer) + TargetStreamer->setStreamer(this); } MCStreamer::~MCStreamer() { @@ -563,56 +568,6 @@ void MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) { llvm_unreachable("This file format doesn't support this directive"); } -void MCStreamer::EmitFnStart() { - errs() << "Not implemented yet\n"; - abort(); -} - -void MCStreamer::EmitFnEnd() { - errs() << "Not implemented yet\n"; - abort(); -} - -void MCStreamer::EmitCantUnwind() { - errs() << "Not implemented yet\n"; - abort(); -} - -void MCStreamer::EmitHandlerData() { - errs() << "Not implemented yet\n"; - abort(); -} - -void MCStreamer::EmitPersonality(const MCSymbol *Personality) { - errs() << "Not implemented yet\n"; - abort(); -} - -void MCStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) { - errs() << "Not implemented yet\n"; - abort(); -} - -void MCStreamer::EmitPad(int64_t Offset) { - errs() << "Not implemented yet\n"; - abort(); -} - -void MCStreamer::EmitRegSave(const SmallVectorImpl &RegList, bool) { - errs() << "Not implemented yet\n"; - abort(); -} - -void MCStreamer::emitMipsHackELFFlags(unsigned Flags) { -} - -void MCStreamer::emitMipsHackSTOCG(MCSymbol *Sym, unsigned Val) { -} - -void MCStreamer::EmitTCEntry(const MCSymbol &S) { - llvm_unreachable("Unsupported method"); -} - /// EmitRawText - If this file is backed by an assembly streamer, this dumps /// the specified string in the output .s file. This capability is /// indicated by the hasRawTextSupport() predicate. diff --git a/lib/MC/WinCOFFStreamer.cpp b/lib/MC/WinCOFFStreamer.cpp index 5f3bf3b73b..8d42d5a579 100644 --- a/lib/MC/WinCOFFStreamer.cpp +++ b/lib/MC/WinCOFFStreamer.cpp @@ -130,7 +130,7 @@ private: WinCOFFStreamer::WinCOFFStreamer(MCContext &Context, MCAsmBackend &MAB, MCCodeEmitter &CE, raw_ostream &OS) - : MCObjectStreamer(Context, MAB, OS, &CE), CurSymbol(NULL) {} + : MCObjectStreamer(Context, 0, MAB, OS, &CE), CurSymbol(NULL) {} void WinCOFFStreamer::AddCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment, bool External) { diff --git a/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp b/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp index 8e2be8185e..a64c463f9e 100644 --- a/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp +++ b/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp @@ -55,11 +55,10 @@ namespace { /// by MachO. Beware! class AArch64ELFStreamer : public MCELFStreamer { public: - AArch64ELFStreamer(MCContext &Context, MCAsmBackend &TAB, - raw_ostream &OS, MCCodeEmitter *Emitter) - : MCELFStreamer(Context, TAB, OS, Emitter), - MappingSymbolCounter(0), LastEMS(EMS_None) { - } + AArch64ELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, + MCCodeEmitter *Emitter) + : MCELFStreamer(Context, 0, TAB, OS, Emitter), MappingSymbolCounter(0), + LastEMS(EMS_None) {} ~AArch64ELFStreamer() {} diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp index 896f1d4a56..ed235f6a4f 100644 --- a/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/ARMAsmPrinter.cpp @@ -1152,6 +1152,8 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) { assert(MI->getFlag(MachineInstr::FrameSetup) && "Only instruction which are involved into frame setup code are allowed"); + MCTargetStreamer &TS = OutStreamer.getTargetStreamer(); + ARMTargetStreamer &ATS = static_cast(TS); const MachineFunction &MF = *MI->getParent()->getParent(); const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo(); const ARMFunctionInfo &AFI = *MF.getInfo(); @@ -1214,7 +1216,7 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) { RegList.push_back(SrcReg); break; } - OutStreamer.EmitRegSave(RegList, Opc == ARM::VSTMDDB_UPD); + ATS.emitRegSave(RegList, Opc == ARM::VSTMDDB_UPD); } else { // Changes of stack / frame pointer. if (SrcReg == ARM::SP) { @@ -1262,11 +1264,11 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) { if (DstReg == FramePtr && FramePtr != ARM::SP) // Set-up of the frame pointer. Positive values correspond to "add" // instruction. - OutStreamer.EmitSetFP(FramePtr, ARM::SP, -Offset); + ATS.emitSetFP(FramePtr, ARM::SP, -Offset); else if (DstReg == ARM::SP) { // Change of SP by an offset. Positive values correspond to "sub" // instruction. - OutStreamer.EmitPad(Offset); + ATS.emitPad(Offset); } else { MI->dump(); llvm_unreachable("Unsupported opcode for unwinding information"); diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 1e090d97da..084ac9b0a1 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -52,6 +52,11 @@ class ARMAsmParser : public MCTargetAsmParser { const MCInstrInfo &MII; const MCRegisterInfo *MRI; + ARMTargetStreamer &getTargetStreamer() { + MCTargetStreamer &TS = getParser().getStreamer().getTargetStreamer(); + return static_cast(TS); + } + // Unwind directives state SMLoc FnStartLoc; SMLoc CantUnwindLoc; @@ -7961,7 +7966,7 @@ bool ARMAsmParser::parseDirectiveFnStart(SMLoc L) { } FnStartLoc = L; - getParser().getStreamer().EmitFnStart(); + getTargetStreamer().emitFnStart(); return false; } @@ -7974,8 +7979,7 @@ bool ARMAsmParser::parseDirectiveFnEnd(SMLoc L) { // Reset the unwind directives parser state resetUnwindDirectiveParserState(); - - getParser().getStreamer().EmitFnEnd(); + getTargetStreamer().emitFnEnd(); return false; } @@ -7997,7 +8001,7 @@ bool ARMAsmParser::parseDirectiveCantUnwind(SMLoc L) { return true; } - getParser().getStreamer().EmitCantUnwind(); + getTargetStreamer().emitCantUnwind(); return false; } @@ -8028,7 +8032,7 @@ bool ARMAsmParser::parseDirectivePersonality(SMLoc L) { Parser.Lex(); MCSymbol *PR = getParser().getContext().GetOrCreateSymbol(Name); - getParser().getStreamer().EmitPersonality(PR); + getTargetStreamer().emitPersonality(PR); return false; } @@ -8045,7 +8049,7 @@ bool ARMAsmParser::parseDirectiveHandlerData(SMLoc L) { return true; } - getParser().getStreamer().EmitHandlerData(); + getTargetStreamer().emitHandlerData(); return false; } @@ -8105,9 +8109,8 @@ bool ARMAsmParser::parseDirectiveSetFP(SMLoc L) { Offset = CE->getValue(); } - getParser().getStreamer().EmitSetFP(static_cast(NewFPReg), - static_cast(NewSPReg), - Offset); + getTargetStreamer().emitSetFP(static_cast(NewFPReg), + static_cast(NewSPReg), Offset); return false; } @@ -8136,7 +8139,7 @@ bool ARMAsmParser::parseDirectivePad(SMLoc L) { if (!CE) return Error(ExLoc, "pad offset must be an immediate"); - getParser().getStreamer().EmitPad(CE->getValue()); + getTargetStreamer().emitPad(CE->getValue()); return false; } @@ -8168,7 +8171,7 @@ bool ARMAsmParser::parseDirectiveRegSave(SMLoc L, bool IsVector) { if (IsVector && !Op->isDPRRegList()) return Error(L, ".vsave expects DPR registers"); - getParser().getStreamer().EmitRegSave(Op->getRegList(), IsVector); + getTargetStreamer().emitRegSave(Op->getRegList(), IsVector); return false; } diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp index d38fde1564..867782b791 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp @@ -27,6 +27,7 @@ #include "llvm/MC/MCELFSymbolFlags.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstPrinter.h" #include "llvm/MC/MCObjectStreamer.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSection.h" @@ -36,6 +37,7 @@ #include "llvm/MC/MCValue.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ELF.h" +#include "llvm/Support/FormattedStream.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -47,6 +49,80 @@ static std::string GetAEABIUnwindPersonalityName(unsigned Index) { namespace { +class ARMELFStreamer; + +class ARMTargetAsmStreamer : public ARMTargetStreamer { + formatted_raw_ostream &OS; + MCInstPrinter &InstPrinter; + + virtual void emitFnStart(); + virtual void emitFnEnd(); + virtual void emitCantUnwind(); + virtual void emitPersonality(const MCSymbol *Personality); + virtual void emitHandlerData(); + virtual void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0); + virtual void emitPad(int64_t Offset); + virtual void emitRegSave(const SmallVectorImpl &RegList, + bool isVector); + +public: + ARMTargetAsmStreamer(formatted_raw_ostream &OS, MCInstPrinter &InstPrinter); +}; + +ARMTargetAsmStreamer::ARMTargetAsmStreamer(formatted_raw_ostream &OS, + MCInstPrinter &InstPrinter) + : OS(OS), InstPrinter(InstPrinter) {} +void ARMTargetAsmStreamer::emitFnStart() { OS << "\t.fnstart\n"; } +void ARMTargetAsmStreamer::emitFnEnd() { OS << "\t.fnend\n"; } +void ARMTargetAsmStreamer::emitCantUnwind() { OS << "\t.cantunwind\n"; } +void ARMTargetAsmStreamer::emitPersonality(const MCSymbol *Personality) { + OS << "\t.personality " << Personality->getName() << '\n'; +} +void ARMTargetAsmStreamer::emitHandlerData() { OS << "\t.handlerdata\n"; } +void ARMTargetAsmStreamer::emitSetFP(unsigned FpReg, unsigned SpReg, + int64_t Offset) { + OS << "\t.setfp\t"; + InstPrinter.printRegName(OS, FpReg); + OS << ", "; + InstPrinter.printRegName(OS, SpReg); + if (Offset) + OS << ", #" << Offset; + OS << '\n'; +} +void ARMTargetAsmStreamer::emitPad(int64_t Offset) { + OS << "\t.pad\t#" << Offset << '\n'; +} +void ARMTargetAsmStreamer::emitRegSave(const SmallVectorImpl &RegList, + bool isVector) { + assert(RegList.size() && "RegList should not be empty"); + if (isVector) + OS << "\t.vsave\t{"; + else + OS << "\t.save\t{"; + + InstPrinter.printRegName(OS, RegList[0]); + + for (unsigned i = 1, e = RegList.size(); i != e; ++i) { + OS << ", "; + InstPrinter.printRegName(OS, RegList[i]); + } + + OS << "}\n"; +} + +class ARMTargetELFStreamer : public ARMTargetStreamer { + ARMELFStreamer &getStreamer(); + virtual void emitFnStart(); + virtual void emitFnEnd(); + virtual void emitCantUnwind(); + virtual void emitPersonality(const MCSymbol *Personality); + virtual void emitHandlerData(); + virtual void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0); + virtual void emitPad(int64_t Offset); + virtual void emitRegSave(const SmallVectorImpl &RegList, + bool isVector); +}; + /// Extend the generic ELFStreamer class so that it can emit mapping symbols at /// the appropriate points in the object files. These symbols are defined in the /// ARM ELF ABI: infocenter.arm.com/help/topic/com.arm.../IHI0044D_aaelf.pdf. @@ -61,27 +137,27 @@ namespace { /// by MachO. Beware! class ARMELFStreamer : public MCELFStreamer { public: - ARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, - MCCodeEmitter *Emitter, bool IsThumb) - : MCELFStreamer(Context, TAB, OS, Emitter), IsThumb(IsThumb), - MappingSymbolCounter(0), LastEMS(EMS_None) { + friend class ARMTargetELFStreamer; + + ARMELFStreamer(MCContext &Context, MCTargetStreamer *TargetStreamer, + MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter, + bool IsThumb) + : MCELFStreamer(Context, TargetStreamer, TAB, OS, Emitter), + IsThumb(IsThumb), MappingSymbolCounter(0), LastEMS(EMS_None) { Reset(); } ~ARMELFStreamer() {} // ARM exception handling directives - virtual void EmitFnStart(); - virtual void EmitFnEnd(); - virtual void EmitCantUnwind(); - virtual void EmitPersonality(const MCSymbol *Per); - virtual void EmitHandlerData(); - virtual void EmitSetFP(unsigned NewFpReg, - unsigned NewSpReg, - int64_t Offset = 0); - virtual void EmitPad(int64_t Offset); - virtual void EmitRegSave(const SmallVectorImpl &RegList, - bool isVector); + void emitFnStart(); + void emitFnEnd(); + void emitCantUnwind(); + void emitPersonality(const MCSymbol *Per); + void emitHandlerData(); + void emitSetFP(unsigned NewFpReg, unsigned NewSpReg, int64_t Offset = 0); + void emitPad(int64_t Offset); + void emitRegSave(const SmallVectorImpl &RegList, bool isVector); virtual void ChangeSection(const MCSection *Section, const MCExpr *Subsection) { @@ -228,6 +304,32 @@ private: }; } // end anonymous namespace +ARMELFStreamer &ARMTargetELFStreamer::getStreamer() { + ARMELFStreamer *S = static_cast(Streamer.get()); + return *S; +} + +void ARMTargetELFStreamer::emitFnStart() { getStreamer().emitFnStart(); } +void ARMTargetELFStreamer::emitFnEnd() { getStreamer().emitFnEnd(); } +void ARMTargetELFStreamer::emitCantUnwind() { getStreamer().emitCantUnwind(); } +void ARMTargetELFStreamer::emitPersonality(const MCSymbol *Personality) { + getStreamer().emitPersonality(Personality); +} +void ARMTargetELFStreamer::emitHandlerData() { + getStreamer().emitHandlerData(); +} +void ARMTargetELFStreamer::emitSetFP(unsigned FpReg, unsigned SpReg, + int64_t Offset) { + getStreamer().emitSetFP(FpReg, SpReg, Offset); +} +void ARMTargetELFStreamer::emitPad(int64_t Offset) { + getStreamer().emitPad(Offset); +} +void ARMTargetELFStreamer::emitRegSave(const SmallVectorImpl &RegList, + bool isVector) { + getStreamer().emitRegSave(RegList, isVector); +} + inline void ARMELFStreamer::SwitchToEHSection(const char *Prefix, unsigned Type, unsigned Flags, @@ -291,29 +393,13 @@ void ARMELFStreamer::Reset() { UnwindOpAsm.Reset(); } -// Add the R_ARM_NONE fixup at the same position -void ARMELFStreamer::EmitPersonalityFixup(StringRef Name) { - const MCSymbol *PersonalitySym = getContext().GetOrCreateSymbol(Name); - - const MCSymbolRefExpr *PersonalityRef = - MCSymbolRefExpr::Create(PersonalitySym, - MCSymbolRefExpr::VK_ARM_NONE, - getContext()); - - AddValueSymbols(PersonalityRef); - MCDataFragment *DF = getOrCreateDataFragment(); - DF->getFixups().push_back( - MCFixup::Create(DF->getContents().size(), PersonalityRef, - MCFixup::getKindForSize(4, false))); -} - -void ARMELFStreamer::EmitFnStart() { +void ARMELFStreamer::emitFnStart() { assert(FnStart == 0); FnStart = getContext().CreateTempSymbol(); EmitLabel(FnStart); } -void ARMELFStreamer::EmitFnEnd() { +void ARMELFStreamer::emitFnEnd() { assert(FnStart && ".fnstart must preceeds .fnend"); // Emit unwind opcodes if there is no .handlerdata directive @@ -361,8 +447,20 @@ void ARMELFStreamer::EmitFnEnd() { Reset(); } -void ARMELFStreamer::EmitCantUnwind() { - CantUnwind = true; +void ARMELFStreamer::emitCantUnwind() { CantUnwind = true; } + +// Add the R_ARM_NONE fixup at the same position +void ARMELFStreamer::EmitPersonalityFixup(StringRef Name) { + const MCSymbol *PersonalitySym = getContext().GetOrCreateSymbol(Name); + + const MCSymbolRefExpr *PersonalityRef = MCSymbolRefExpr::Create( + PersonalitySym, MCSymbolRefExpr::VK_ARM_NONE, getContext()); + + AddValueSymbols(PersonalityRef); + MCDataFragment *DF = getOrCreateDataFragment(); + DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(), + PersonalityRef, + MCFixup::getKindForSize(4, false))); } void ARMELFStreamer::FlushPendingOffset() { @@ -425,17 +523,14 @@ void ARMELFStreamer::FlushUnwindOpcodes(bool NoHandlerData) { EmitIntValue(0, 4); } -void ARMELFStreamer::EmitHandlerData() { - FlushUnwindOpcodes(false); -} +void ARMELFStreamer::emitHandlerData() { FlushUnwindOpcodes(false); } -void ARMELFStreamer::EmitPersonality(const MCSymbol *Per) { +void ARMELFStreamer::emitPersonality(const MCSymbol *Per) { Personality = Per; UnwindOpAsm.setPersonality(Per); } -void ARMELFStreamer::EmitSetFP(unsigned NewFPReg, - unsigned NewSPReg, +void ARMELFStreamer::emitSetFP(unsigned NewFPReg, unsigned NewSPReg, int64_t Offset) { assert((NewSPReg == ARM::SP || NewSPReg == FPReg) && "the operand of .setfp directive should be either $sp or $fp"); @@ -449,7 +544,7 @@ void ARMELFStreamer::EmitSetFP(unsigned NewFPReg, FPOffset += Offset; } -void ARMELFStreamer::EmitPad(int64_t Offset) { +void ARMELFStreamer::emitPad(int64_t Offset) { // Track the change of the $sp offset SPOffset -= Offset; @@ -458,7 +553,7 @@ void ARMELFStreamer::EmitPad(int64_t Offset) { PendingOffset -= Offset; } -void ARMELFStreamer::EmitRegSave(const SmallVectorImpl &RegList, +void ARMELFStreamer::emitRegSave(const SmallVectorImpl &RegList, bool IsVector) { // Collect the registers in the register list unsigned Count = 0; @@ -489,11 +584,26 @@ void ARMELFStreamer::EmitRegSave(const SmallVectorImpl &RegList, } namespace llvm { + +MCStreamer *createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, + bool isVerboseAsm, bool useLoc, bool useCFI, + bool useDwarfDirectory, + MCInstPrinter *InstPrint, MCCodeEmitter *CE, + MCAsmBackend *TAB, bool ShowInst) { + ARMTargetAsmStreamer *S = new ARMTargetAsmStreamer(OS, *InstPrint); + + return llvm::createAsmStreamer(Ctx, S, OS, isVerboseAsm, useLoc, useCFI, + useDwarfDirectory, InstPrint, CE, TAB, + ShowInst); +} + MCELFStreamer* createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter, bool RelaxAll, bool NoExecStack, bool IsThumb) { - ARMELFStreamer *S = new ARMELFStreamer(Context, TAB, OS, Emitter, IsThumb); + ARMTargetELFStreamer *TS = new ARMTargetELFStreamer(); + ARMELFStreamer *S = + new ARMELFStreamer(Context, TS, TAB, OS, Emitter, IsThumb); // FIXME: This should eventually end up somewhere else where more // intelligent flag decisions can be made. For now we are just maintaining // the status quo for ARM and setting EF_ARM_EABI_VER5 as the default. diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp index de8e3f8b88..dc388ecdd6 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp @@ -350,6 +350,10 @@ extern "C" void LLVMInitializeARMTargetMC() { TargetRegistry::RegisterMCObjectStreamer(TheARMTarget, createMCStreamer); TargetRegistry::RegisterMCObjectStreamer(TheThumbTarget, createMCStreamer); + // Register the asm streamer. + TargetRegistry::RegisterAsmStreamer(TheARMTarget, createMCAsmStreamer); + TargetRegistry::RegisterAsmStreamer(TheThumbTarget, createMCAsmStreamer); + // Register the MCInstPrinter. TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter); TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter); diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h index a571907de6..959be8b55c 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h +++ b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h @@ -18,13 +18,16 @@ #include namespace llvm { +class formatted_raw_ostream; class MCAsmBackend; class MCCodeEmitter; class MCContext; class MCInstrInfo; +class MCInstPrinter; class MCObjectWriter; class MCRegisterInfo; class MCSubtargetInfo; +class MCStreamer; class MCRelocationInfo; class StringRef; class Target; @@ -42,6 +45,12 @@ namespace ARM_MC { StringRef FS); } +MCStreamer *createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, + bool isVerboseAsm, bool useLoc, bool useCFI, + bool useDwarfDirectory, + MCInstPrinter *InstPrint, MCCodeEmitter *CE, + MCAsmBackend *TAB, bool ShowInst); + MCCodeEmitter *createARMMCCodeEmitter(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, const MCSubtargetInfo &STI, diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 1f39f48259..ae9d2764fb 100644 --- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -9,6 +9,7 @@ #include "MCTargetDesc/MipsMCTargetDesc.h" #include "MipsRegisterInfo.h" +#include "MipsTargetStreamer.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" @@ -56,6 +57,11 @@ private: namespace { class MipsAsmParser : public MCTargetAsmParser { + MipsTargetStreamer &getTargetStreamer() { + MCTargetStreamer &TS = Parser.getStreamer().getTargetStreamer(); + return static_cast(TS); + } + MCSubtargetInfo &STI; MCAsmParser &Parser; MipsAssemblerOptions Options; @@ -2115,7 +2121,7 @@ bool MipsAsmParser::parseDirectiveMipsHackStocg() { if (Parser.parseAbsoluteExpression(Flags)) return TokError("unexpected token"); - Parser.getStreamer().emitMipsHackSTOCG(Sym, Flags); + getTargetStreamer().emitMipsHackSTOCG(Sym, Flags); return false; } @@ -2124,7 +2130,7 @@ bool MipsAsmParser::parseDirectiveMipsHackELFFlags() { if (Parser.parseAbsoluteExpression(Flags)) return TokError("unexpected token"); - Parser.getStreamer().emitMipsHackELFFlags(Flags); + getTargetStreamer().emitMipsHackELFFlags(Flags); return false; } diff --git a/lib/Target/Mips/MCTargetDesc/CMakeLists.txt b/lib/Target/Mips/MCTargetDesc/CMakeLists.txt index 1f08789d12..80ca5f3794 100644 --- a/lib/Target/Mips/MCTargetDesc/CMakeLists.txt +++ b/lib/Target/Mips/MCTargetDesc/CMakeLists.txt @@ -5,7 +5,6 @@ add_llvm_library(LLVMMipsDesc MipsMCTargetDesc.cpp MipsELFObjectWriter.cpp MipsReginfo.cpp - MipsELFStreamer.cpp ) add_dependencies(LLVMMipsDesc MipsCommonTableGen) diff --git a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp deleted file mode 100644 index 1779b92f10..0000000000 --- a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp +++ /dev/null @@ -1,55 +0,0 @@ -//===-- MipsELFStreamer.cpp - MipsELFStreamer ---------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===-------------------------------------------------------------------===// -#include "MipsSubtarget.h" -#include "llvm/MC/MCAssembler.h" -#include "llvm/MC/MCELF.h" -#include "llvm/MC/MCELFStreamer.h" -#include "llvm/MC/MCELFSymbolFlags.h" -#include "llvm/MC/MCSymbol.h" -#include "llvm/Support/ELF.h" -#include "llvm/Support/ErrorHandling.h" -using namespace llvm; - -namespace { -class MipsELFStreamer : public MCELFStreamer { -public: - MipsELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, - MCCodeEmitter *Emitter, bool RelaxAll, bool NoExecStack) - : MCELFStreamer(Context, TAB, OS, Emitter) {} - - ~MipsELFStreamer() {} - void emitMipsHackELFFlags(unsigned Flags); - void emitMipsHackSTOCG(MCSymbol *Sym, unsigned Val); -}; -} - -namespace llvm { -MCELFStreamer *createMipsELFStreamer(MCContext &Context, MCAsmBackend &TAB, - raw_ostream &OS, MCCodeEmitter *Emitter, - bool RelaxAll, bool NoExecStack) { - MipsELFStreamer *S = - new MipsELFStreamer(Context, TAB, OS, Emitter, RelaxAll, NoExecStack); - return S; -} -} // namespace llvm - -void MipsELFStreamer::emitMipsHackELFFlags(unsigned Flags) { - MCAssembler &MCA = getAssembler(); - - MCA.setELFHeaderEFlags(Flags); -} - -// Set a symbol's STO flags -void MipsELFStreamer::emitMipsHackSTOCG(MCSymbol *Sym, unsigned Val) { - MCSymbolData &Data = getOrCreateSymbolData(Sym); - // The "other" values are stored in the last 6 bits of the second byte - // The traditional defines for STO values assume the full byte and thus - // the shift to pack it. - MCELF::setOther(Data, Val >> 2); -} diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp index e0284c684c..6c48053615 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp @@ -14,13 +14,18 @@ #include "MipsMCTargetDesc.h" #include "InstPrinter/MipsInstPrinter.h" #include "MipsMCAsmInfo.h" +#include "MipsTargetStreamer.h" #include "llvm/MC/MCCodeGenInfo.h" +#include "llvm/MC/MCELF.h" #include "llvm/MC/MCELFStreamer.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/MC/MCSymbol.h" #include "llvm/MC/MachineLocation.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FormattedStream.h" #include "llvm/Support/TargetRegistry.h" #define GET_INSTRINFO_MC_DESC @@ -34,6 +39,9 @@ using namespace llvm; +static cl::opt PrintHackDirectives("print-hack-directives", + cl::init(false), cl::Hidden); + static std::string ParseMipsTriple(StringRef TT, StringRef CPU) { std::string MipsArchFeature; size_t DashPosition = 0; @@ -123,15 +131,85 @@ static MCInstPrinter *createMipsMCInstPrinter(const Target &T, return new MipsInstPrinter(MAI, MII, MRI); } +namespace { +class MipsTargetAsmStreamer : public MipsTargetStreamer { + formatted_raw_ostream &OS; + +public: + MipsTargetAsmStreamer(formatted_raw_ostream &OS); + virtual void emitMipsHackELFFlags(unsigned Flags); + virtual void emitMipsHackSTOCG(MCSymbol *Sym, unsigned Val); +}; + +MipsTargetAsmStreamer::MipsTargetAsmStreamer(formatted_raw_ostream &OS) + : OS(OS) {} + +void MipsTargetAsmStreamer::emitMipsHackELFFlags(unsigned Flags) { + if (!PrintHackDirectives) + return; + + OS << "\t.mips_hack_elf_flags 0x"; + OS.write_hex(Flags); + OS << '\n'; +} +void MipsTargetAsmStreamer::emitMipsHackSTOCG(MCSymbol *Sym, unsigned Val) { + if (!PrintHackDirectives) + return; + + OS << "\t.mips_hack_stocg "; + OS << Sym->getName(); + OS << ", "; + OS << Val; + OS << '\n'; +} + +class MipsTargetELFStreamer : public MipsTargetStreamer { +public: + MCELFStreamer &getStreamer(); + MipsTargetELFStreamer(); + virtual void emitMipsHackELFFlags(unsigned Flags); + virtual void emitMipsHackSTOCG(MCSymbol *Sym, unsigned Val); +}; + +MipsTargetELFStreamer::MipsTargetELFStreamer() {} + +MCELFStreamer &MipsTargetELFStreamer::getStreamer() { + return static_cast(*Streamer); +} + +void MipsTargetELFStreamer::emitMipsHackELFFlags(unsigned Flags) { + MCAssembler &MCA = getStreamer().getAssembler(); + MCA.setELFHeaderEFlags(Flags); +} + +// Set a symbol's STO flags +void MipsTargetELFStreamer::emitMipsHackSTOCG(MCSymbol *Sym, unsigned Val) { + MCSymbolData &Data = getStreamer().getOrCreateSymbolData(Sym); + // The "other" values are stored in the last 6 bits of the second byte + // The traditional defines for STO values assume the full byte and thus + // the shift to pack it. + MCELF::setOther(Data, Val >> 2); +} +} + static MCStreamer *createMCStreamer(const Target &T, StringRef TT, - MCContext &Ctx, MCAsmBackend &MAB, - raw_ostream &_OS, - MCCodeEmitter *_Emitter, - bool RelaxAll, - bool NoExecStack) { - Triple TheTriple(TT); + MCContext &Context, MCAsmBackend &MAB, + raw_ostream &OS, MCCodeEmitter *Emitter, + bool RelaxAll, bool NoExecStack) { + MipsTargetELFStreamer *S = new MipsTargetELFStreamer(); + return createELFStreamer(Context, S, MAB, OS, Emitter, RelaxAll, NoExecStack); +} - return createMipsELFStreamer(Ctx, MAB, _OS, _Emitter, RelaxAll, NoExecStack); +static MCStreamer * +createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, + bool isVerboseAsm, bool useLoc, bool useCFI, + bool useDwarfDirectory, MCInstPrinter *InstPrint, + MCCodeEmitter *CE, MCAsmBackend *TAB, bool ShowInst) { + MipsTargetAsmStreamer *S = new MipsTargetAsmStreamer(OS); + + return llvm::createAsmStreamer(Ctx, S, OS, isVerboseAsm, useLoc, useCFI, + useDwarfDirectory, InstPrint, CE, TAB, + ShowInst); } extern "C" void LLVMInitializeMipsTargetMC() { @@ -182,6 +260,12 @@ extern "C" void LLVMInitializeMipsTargetMC() { TargetRegistry::RegisterMCObjectStreamer(TheMips64elTarget, createMCStreamer); + // Register the asm streamer. + TargetRegistry::RegisterAsmStreamer(TheMipsTarget, createMCAsmStreamer); + TargetRegistry::RegisterAsmStreamer(TheMipselTarget, createMCAsmStreamer); + TargetRegistry::RegisterAsmStreamer(TheMips64Target, createMCAsmStreamer); + TargetRegistry::RegisterAsmStreamer(TheMips64elTarget, createMCAsmStreamer); + // Register the asm backend. TargetRegistry::RegisterMCAsmBackend(TheMipsTarget, createMipsAsmBackendEB32); diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp index b32c2597c5..b6afc174e8 100644 --- a/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/lib/Target/Mips/MipsAsmPrinter.cpp @@ -19,6 +19,7 @@ #include "MipsAsmPrinter.h" #include "MipsInstrInfo.h" #include "MipsMCInstLower.h" +#include "MipsTargetStreamer.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Twine.h" @@ -44,6 +45,10 @@ using namespace llvm; +MipsTargetStreamer &MipsAsmPrinter::getTargetStreamer() { + return static_cast(OutStreamer.getTargetStreamer()); +} + bool MipsAsmPrinter::runOnMachineFunction(MachineFunction &MF) { // Initialize TargetLoweringObjectFile. if (Subtarget->allowMixed16_32()) @@ -237,8 +242,8 @@ void MipsAsmPrinter::EmitFunctionEntryLabel() { } if (Subtarget->inMicroMipsMode()) - OutStreamer.emitMipsHackSTOCG(CurrentFnSym, - (unsigned)ELF::STO_MIPS_MICROMIPS); + getTargetStreamer().emitMipsHackSTOCG(CurrentFnSym, + (unsigned)ELF::STO_MIPS_MICROMIPS); OutStreamer.EmitLabel(CurrentFnSym); } @@ -585,8 +590,8 @@ void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) { } -static void -emitELFHeaderFlagsCG(MCStreamer &Streamer, const MipsSubtarget &Subtarget) { +static void emitELFHeaderFlagsCG(MipsTargetStreamer &TargetStreamer, + const MipsSubtarget &Subtarget) { // Update e_header flags unsigned EFlags = 0; @@ -625,14 +630,14 @@ emitELFHeaderFlagsCG(MCStreamer &Streamer, const MipsSubtarget &Subtarget) { else llvm_unreachable("Unsupported relocation model for e_flags"); - Streamer.emitMipsHackELFFlags(EFlags); + TargetStreamer.emitMipsHackELFFlags(EFlags); } void MipsAsmPrinter::EmitEndOfAsmFile(Module &M) { // Emit Mips ELF register info Subtarget->getMReginfo().emitMipsReginfoSectionCG( OutStreamer, getObjFileLowering(), *Subtarget); - emitELFHeaderFlagsCG(OutStreamer, *Subtarget); + emitELFHeaderFlagsCG(getTargetStreamer(), *Subtarget); } void MipsAsmPrinter::PrintDebugValueComment(const MachineInstr *MI, diff --git a/lib/Target/Mips/MipsAsmPrinter.h b/lib/Target/Mips/MipsAsmPrinter.h index 4d1d624e09..5f6cac8f21 100644 --- a/lib/Target/Mips/MipsAsmPrinter.h +++ b/lib/Target/Mips/MipsAsmPrinter.h @@ -25,10 +25,12 @@ namespace llvm { class MCStreamer; class MachineInstr; class MachineBasicBlock; +class MipsTargetStreamer; class Module; class raw_ostream; class LLVM_LIBRARY_VISIBILITY MipsAsmPrinter : public AsmPrinter { + MipsTargetStreamer &getTargetStreamer(); void EmitInstrWithMacroNoAT(const MachineInstr *MI); diff --git a/lib/Target/Mips/MipsTargetStreamer.h b/lib/Target/Mips/MipsTargetStreamer.h new file mode 100644 index 0000000000..fb9f5ef9e0 --- /dev/null +++ b/lib/Target/Mips/MipsTargetStreamer.h @@ -0,0 +1,23 @@ +//===-- MipsTargetStreamer.h - Mips Target Streamer ------------*- C++ -*--===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef MIPSTARGETSTREAMER_H +#define MIPSTARGETSTREAMER_H + +#include "llvm/MC/MCStreamer.h" + +namespace llvm { +class MipsTargetStreamer : public MCTargetStreamer { +public: + virtual void emitMipsHackELFFlags(unsigned Flags) = 0; + virtual void emitMipsHackSTOCG(MCSymbol *Sym, unsigned Val) = 0; +}; +} + +#endif diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp index 5f7a39a368..5c08de1ccf 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp +++ b/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp @@ -14,13 +14,16 @@ #include "PPCMCTargetDesc.h" #include "InstPrinter/PPCInstPrinter.h" #include "PPCMCAsmInfo.h" +#include "PPCTargetStreamer.h" #include "llvm/MC/MCCodeGenInfo.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/MC/MCSymbol.h" #include "llvm/MC/MachineLocation.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FormattedStream.h" #include "llvm/Support/TargetRegistry.h" #define GET_INSTRINFO_MC_DESC @@ -101,6 +104,29 @@ static MCCodeGenInfo *createPPCMCCodeGenInfo(StringRef TT, Reloc::Model RM, return X; } +namespace { +class PPCTargetAsmStreamer : public PPCTargetStreamer { + formatted_raw_ostream &OS; + +public: + PPCTargetAsmStreamer(formatted_raw_ostream &OS) : OS(OS) {} + virtual void emitTCEntry(const MCSymbol &S) { + OS << "\t.tc "; + OS << S.getName(); + OS << "[TC],"; + OS << S.getName(); + OS << '\n'; + } +}; + +class PPCTargetELFStreamer : public PPCTargetStreamer { + virtual void emitTCEntry(const MCSymbol &S) { + // Creates a R_PPC64_TOC relocation + Streamer->EmitSymbolValue(&S, 8); + } +}; +} + // This is duplicated code. Refactor this. static MCStreamer *createMCStreamer(const Target &T, StringRef TT, MCContext &Ctx, MCAsmBackend &MAB, @@ -111,7 +137,20 @@ static MCStreamer *createMCStreamer(const Target &T, StringRef TT, if (Triple(TT).isOSDarwin()) return createMachOStreamer(Ctx, MAB, OS, Emitter, RelaxAll); - return createELFStreamer(Ctx, MAB, OS, Emitter, RelaxAll, NoExecStack); + PPCTargetStreamer *S = new PPCTargetELFStreamer(); + return createELFStreamer(Ctx, S, MAB, OS, Emitter, RelaxAll, NoExecStack); +} + +static MCStreamer * +createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, + bool isVerboseAsm, bool useLoc, bool useCFI, + bool useDwarfDirectory, MCInstPrinter *InstPrint, + MCCodeEmitter *CE, MCAsmBackend *TAB, bool ShowInst) { + PPCTargetStreamer *S = new PPCTargetAsmStreamer(OS); + + return llvm::createAsmStreamer(Ctx, S, OS, isVerboseAsm, useLoc, useCFI, + useDwarfDirectory, InstPrint, CE, TAB, + ShowInst); } static MCInstPrinter *createPPCMCInstPrinter(const Target &T, @@ -171,6 +210,11 @@ extern "C" void LLVMInitializePowerPCTargetMC() { TargetRegistry::RegisterMCObjectStreamer(ThePPC64Target, createMCStreamer); TargetRegistry::RegisterMCObjectStreamer(ThePPC64LETarget, createMCStreamer); + // Register the asm streamer. + TargetRegistry::RegisterAsmStreamer(ThePPC32Target, createMCAsmStreamer); + TargetRegistry::RegisterAsmStreamer(ThePPC64Target, createMCAsmStreamer); + TargetRegistry::RegisterAsmStreamer(ThePPC64LETarget, createMCAsmStreamer); + // Register the MCInstPrinter. TargetRegistry::RegisterMCInstPrinter(ThePPC32Target, createPPCMCInstPrinter); TargetRegistry::RegisterMCInstPrinter(ThePPC64Target, createPPCMCInstPrinter); diff --git a/lib/Target/PowerPC/PPCAsmPrinter.cpp b/lib/Target/PowerPC/PPCAsmPrinter.cpp index f4fd1387b9..c86badf57f 100644 --- a/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -23,6 +23,7 @@ #include "MCTargetDesc/PPCMCExpr.h" #include "PPCSubtarget.h" #include "PPCTargetMachine.h" +#include "PPCTargetStreamer.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" @@ -771,6 +772,9 @@ bool PPCLinuxAsmPrinter::doFinalization(Module &M) { bool isPPC64 = TD->getPointerSizeInBits() == 64; + PPCTargetStreamer &TS = + static_cast(OutStreamer.getTargetStreamer()); + if (isPPC64 && !TOC.empty()) { const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".toc", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC, @@ -781,7 +785,7 @@ bool PPCLinuxAsmPrinter::doFinalization(Module &M) { E = TOC.end(); I != E; ++I) { OutStreamer.EmitLabel(I->second); MCSymbol *S = OutContext.GetOrCreateSymbol(I->first->getName()); - OutStreamer.EmitTCEntry(*S); + TS.emitTCEntry(*S); } } diff --git a/lib/Target/PowerPC/PPCTargetStreamer.h b/lib/Target/PowerPC/PPCTargetStreamer.h new file mode 100644 index 0000000000..3ecd8a8b0a --- /dev/null +++ b/lib/Target/PowerPC/PPCTargetStreamer.h @@ -0,0 +1,22 @@ +//===-- PPCTargetStreamer.h - PPC Target Streamer --s-----------*- C++ -*--===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef PPCTARGETSTREAMER_H +#define PPCTARGETSTREAMER_H + +#include "llvm/MC/MCStreamer.h" + +namespace llvm { +class PPCTargetStreamer : public MCTargetStreamer { +public: + virtual void emitTCEntry(const MCSymbol &S) = 0; +}; +} + +#endif diff --git a/lib/Target/R600/MCTargetDesc/AMDGPUMCTargetDesc.cpp b/lib/Target/R600/MCTargetDesc/AMDGPUMCTargetDesc.cpp index 61d70bb342..a1bec28276 100644 --- a/lib/Target/R600/MCTargetDesc/AMDGPUMCTargetDesc.cpp +++ b/lib/Target/R600/MCTargetDesc/AMDGPUMCTargetDesc.cpp @@ -88,7 +88,7 @@ static MCStreamer *createMCStreamer(const Target &T, StringRef TT, MCCodeEmitter *_Emitter, bool RelaxAll, bool NoExecStack) { - return createELFStreamer(Ctx, MAB, _OS, _Emitter, false, false); + return createELFStreamer(Ctx, 0, MAB, _OS, _Emitter, false, false); } extern "C" void LLVMInitializeR600TargetMC() { diff --git a/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp b/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp index 19b2bcb921..9e1296b912 100644 --- a/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp +++ b/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp @@ -187,7 +187,7 @@ static MCStreamer *createSystemZMCObjectStreamer(const Target &T, StringRef TT, MCCodeEmitter *Emitter, bool RelaxAll, bool NoExecStack) { - return createELFStreamer(Ctx, MAB, OS, Emitter, RelaxAll, NoExecStack); + return createELFStreamer(Ctx, 0, MAB, OS, Emitter, RelaxAll, NoExecStack); } extern "C" void LLVMInitializeSystemZTargetMC() { diff --git a/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp b/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp index bd23ce40ec..1cbdafdf15 100644 --- a/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp +++ b/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp @@ -368,7 +368,7 @@ static MCStreamer *createMCStreamer(const Target &T, StringRef TT, if (TheTriple.isOSWindows() && TheTriple.getEnvironment() != Triple::ELF) return createWinCOFFStreamer(Ctx, MAB, *_Emitter, _OS, RelaxAll); - return createELFStreamer(Ctx, MAB, _OS, _Emitter, RelaxAll, NoExecStack); + return createELFStreamer(Ctx, 0, MAB, _OS, _Emitter, RelaxAll, NoExecStack); } static MCInstPrinter *createX86MCInstPrinter(const Target &T, -- cgit v1.2.3