X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FMC%2FMCObjectStreamer.h;h=2e3aa7e570668d5e104526dc70ea3774750c3a25;hb=7da5357acaa0e90e6af1a5cbfa88e422d697631c;hp=c4f5e348b23a4e4a001ba8cf223942cbc36cb153;hpb=e23930543c0de0adcfec00cd18e9243ad812a167;p=oota-llvm.git diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h index c4f5e348b23..2e3aa7e5706 100644 --- a/include/llvm/MC/MCObjectStreamer.h +++ b/include/llvm/MC/MCObjectStreamer.h @@ -10,17 +10,21 @@ #ifndef LLVM_MC_MCOBJECTSTREAMER_H #define LLVM_MC_MCOBJECTSTREAMER_H +#include "llvm/ADT/SmallVector.h" +#include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCSection.h" #include "llvm/MC/MCStreamer.h" namespace llvm { class MCAssembler; class MCCodeEmitter; -class MCSectionData; +class MCSubtargetInfo; class MCExpr; class MCFragment; class MCDataFragment; -class TargetAsmBackend; +class MCAsmBackend; class raw_ostream; +class raw_pwrite_stream; /// \brief Streaming object file generation interface. /// @@ -31,46 +35,110 @@ class raw_ostream; /// implementation. class MCObjectStreamer : public MCStreamer { MCAssembler *Assembler; - MCSectionData *CurSectionData; + MCSection::iterator CurInsertionPoint; + bool EmitEHFrame; + bool EmitDebugFrame; + SmallVector PendingLabels; - virtual void EmitInstToData(const MCInst &Inst) = 0; + virtual void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo&) = 0; + void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override; + void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override; protected: - MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB, - raw_ostream &_OS, MCCodeEmitter *_Emitter, - bool _PadSectionToAlignment); - ~MCObjectStreamer(); + MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_pwrite_stream &OS, + MCCodeEmitter *Emitter); + ~MCObjectStreamer() override; - MCSectionData *getCurrentSectionData() const { - return CurSectionData; - } +public: + /// state management + void reset() override; + + /// Object streamers require the integrated assembler. + bool isIntegratedAssemblerRequired() const override { return true; } + void EmitFrames(MCAsmBackend *MAB); + void EmitCFISections(bool EH, bool Debug) override; + +protected: MCFragment *getCurrentFragment() const; + void insert(MCFragment *F) { + flushPendingLabels(F); + MCSection *CurSection = getCurrentSectionOnly(); + CurSection->getFragmentList().insert(CurInsertionPoint, F); + F->setParent(CurSection); + } + /// Get a data fragment to write into, creating a new one if the current /// fragment is not a data fragment. - MCDataFragment *getOrCreateDataFragment() const; + MCDataFragment *getOrCreateDataFragment(); - const MCExpr *AddValueSymbols(const MCExpr *Value); + bool changeSectionImpl(MCSection *Section, const MCExpr *Subsection); + + /// If any labels have been emitted but not assigned fragments, ensure that + /// they get assigned, either to F if possible or to a new data fragment. + /// Optionally, it is also possible to provide an offset \p FOffset, which + /// will be used as a symbol offset within the fragment. + void flushPendingLabels(MCFragment *F, uint64_t FOffset = 0); public: + void visitUsedSymbol(const MCSymbol &Sym) override; + MCAssembler &getAssembler() { return *Assembler; } - /// @name MCStreamer Interface + /// \name MCStreamer Interface /// @{ - virtual void EmitLabel(MCSymbol *Symbol); - virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace); - virtual void EmitULEB128Value(const MCExpr *Value, unsigned AddrSpace = 0); - virtual void EmitSLEB128Value(const MCExpr *Value, unsigned AddrSpace = 0); - virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol); - virtual void SwitchSection(const MCSection *Section); - virtual void EmitInstruction(const MCInst &Inst); - virtual void EmitInstToFragment(const MCInst &Inst); - virtual void EmitValueToOffset(const MCExpr *Offset, unsigned char Value); - virtual void Finish(); - - /// @} + void EmitLabel(MCSymbol *Symbol) override; + void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override; + void EmitValueImpl(const MCExpr *Value, unsigned Size, + SMLoc Loc = SMLoc()) override; + void EmitULEB128Value(const MCExpr *Value) override; + void EmitSLEB128Value(const MCExpr *Value) override; + void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override; + void ChangeSection(MCSection *Section, const MCExpr *Subsection) override; + void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo& STI) override; + + /// \brief Emit an instruction to a special fragment, because this instruction + /// can change its size during relaxation. + virtual void EmitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &); + + void EmitBundleAlignMode(unsigned AlignPow2) override; + void EmitBundleLock(bool AlignToEnd) override; + void EmitBundleUnlock() override; + void EmitBytes(StringRef Data) override; + void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0, + unsigned ValueSize = 1, + unsigned MaxBytesToEmit = 0) override; + void EmitCodeAlignment(unsigned ByteAlignment, + unsigned MaxBytesToEmit = 0) override; + bool EmitValueToOffset(const MCExpr *Offset, unsigned char Value) override; + void EmitDwarfLocDirective(unsigned FileNo, unsigned Line, + unsigned Column, unsigned Flags, + unsigned Isa, unsigned Discriminator, + StringRef FileName) override; + void EmitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, + const MCSymbol *Label, + unsigned PointerSize); + void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, + const MCSymbol *Label); + void EmitGPRel32Value(const MCExpr *Value) override; + void EmitGPRel64Value(const MCExpr *Value) override; + void EmitFill(uint64_t NumBytes, uint8_t FillValue) override; + void EmitZeros(uint64_t NumBytes) override; + void FinishImpl() override; + + /// Emit the absolute difference between two symbols if possible. + /// + /// Emit the absolute difference between \c Hi and \c Lo, as long as we can + /// compute it. Currently, that requires that both symbols are in the same + /// data fragment. Otherwise, do nothing and return \c false. + /// + /// \pre Offset of \c Hi is greater than the offset \c Lo. + void emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo, + unsigned Size) override; + + bool mayHaveInstructions(MCSection &Sec) const override; }; } // end namespace llvm