X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FMC%2FMCStreamer.h;h=b5c8008cd605a70cf3b84c5a1e0c67d3767dfd87;hb=c8fec7e21f5c24303eab8a8592f3b8faff347d86;hp=fce076a57ebc7d34cecf484e7ae37e9de2ca039f;hpb=2303c9dd69476d045af7cee94e112dd77d22fd28;p=oota-llvm.git diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index fce076a57eb..b5c8008cd60 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -16,9 +16,13 @@ #include "llvm/Support/DataTypes.h" #include "llvm/MC/MCDirectives.h" +#include "llvm/MC/MCDwarf.h" +#include "llvm/MC/MCWin64EH.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallVector.h" namespace llvm { - class MCAsmInfo; + class MCAsmBackend; class MCCodeEmitter; class MCContext; class MCExpr; @@ -27,8 +31,6 @@ namespace llvm { class MCSection; class MCSymbol; class StringRef; - class TargetAsmBackend; - class TargetLoweringObjectFile; class Twine; class raw_ostream; class formatted_raw_ostream; @@ -45,25 +47,70 @@ namespace llvm { class MCStreamer { MCContext &Context; - MCStreamer(const MCStreamer&); // DO NOT IMPLEMENT - MCStreamer &operator=(const MCStreamer&); // DO NOT IMPLEMENT + MCStreamer(const MCStreamer&) LLVM_DELETED_FUNCTION; + MCStreamer &operator=(const MCStreamer&) LLVM_DELETED_FUNCTION; + + bool EmitEHFrame; + bool EmitDebugFrame; + + std::vector FrameInfos; + MCDwarfFrameInfo *getCurrentFrameInfo(); + void EnsureValidFrame(); + + std::vector W64UnwindInfos; + MCWin64EHUnwindInfo *CurrentW64UnwindInfo; + void setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame); + void EnsureValidW64UnwindInfo(); + + MCSymbol* LastSymbol; + + /// SectionStack - This is stack of current and previous section + /// values saved by PushSection. + SmallVector, 4> SectionStack; protected: MCStreamer(MCContext &Ctx); - /// CurSection - This is the current section code is being emitted to, it is - /// kept up to date by SwitchSection. - const MCSection *CurSection; + const MCExpr *BuildSymbolDiff(MCContext &Context, const MCSymbol *A, + const MCSymbol *B); + + const MCExpr *ForceExpAbs(const MCExpr* Expr); - /// PrevSection - This is the previous section code is being emitted to, it - /// is kept up to date by SwitchSection. - const MCSection *PrevSection; + void RecordProcStart(MCDwarfFrameInfo &Frame); + virtual void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame); + void RecordProcEnd(MCDwarfFrameInfo &Frame); + virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &CurFrame); + void EmitFrames(bool usingCFI); + + MCWin64EHUnwindInfo *getCurrentW64UnwindInfo(){return CurrentW64UnwindInfo;} + void EmitW64Tables(); public: virtual ~MCStreamer(); MCContext &getContext() const { return Context; } + unsigned getNumFrameInfos() { + return FrameInfos.size(); + } + + const MCDwarfFrameInfo &getFrameInfo(unsigned i) { + return FrameInfos[i]; + } + + ArrayRef getFrameInfos() { + return FrameInfos; + } + + unsigned getNumW64UnwindInfos() { + return W64UnwindInfos.size(); + } + + MCWin64EHUnwindInfo &getW64UnwindInfo(unsigned i) { + return *W64UnwindInfos[i]; + } + /// @name Assembly File Formatting. /// @{ @@ -99,17 +146,72 @@ namespace llvm { /// getCurrentSection - Return the current section that the streamer is /// emitting code to. - const MCSection *getCurrentSection() const { return CurSection; } + const MCSection *getCurrentSection() const { + if (!SectionStack.empty()) + return SectionStack.back().first; + return NULL; + } /// getPreviousSection - Return the previous section that the streamer is /// emitting code to. - const MCSection *getPreviousSection() const { return PrevSection; } + const MCSection *getPreviousSection() const { + if (!SectionStack.empty()) + return SectionStack.back().second; + return NULL; + } + + /// ChangeSection - Update streamer for a new active section. + /// + /// This is called by PopSection and SwitchSection, if the current + /// section changes. + virtual void ChangeSection(const MCSection *) = 0; + + /// pushSection - Save the current and previous section on the + /// section stack. + void PushSection() { + SectionStack.push_back(std::make_pair(getCurrentSection(), + getPreviousSection())); + } + + /// popSection - Restore the current and previous section from + /// the section stack. Calls ChangeSection as needed. + /// + /// Returns false if the stack was empty. + bool PopSection() { + if (SectionStack.size() <= 1) + return false; + const MCSection *oldSection = SectionStack.pop_back_val().first; + const MCSection *curSection = SectionStack.back().first; + + if (oldSection != curSection) + ChangeSection(curSection); + return true; + } /// SwitchSection - Set the current section where code is being emitted to /// @p Section. This is required to update CurSection. /// /// This corresponds to assembler directives like .section, .text, etc. - virtual void SwitchSection(const MCSection *Section) = 0; + void SwitchSection(const MCSection *Section) { + assert(Section && "Cannot switch to a null section!"); + const MCSection *curSection = SectionStack.back().first; + SectionStack.back().second = curSection; + if (Section != curSection) { + SectionStack.back().first = Section; + ChangeSection(Section); + } + } + + /// SwitchSectionNoChange - Set the current section where code is being + /// emitted to @p Section. This is required to update CurSection. This + /// version does not call ChangeSection. + void SwitchSectionNoChange(const MCSection *Section) { + assert(Section && "Cannot switch to a null section!"); + const MCSection *curSection = SectionStack.back().first; + SectionStack.back().second = curSection; + if (Section != curSection) + SectionStack.back().first = Section; + } /// InitSections - Create the default sections and set the initial one. virtual void InitSections() = 0; @@ -122,11 +224,17 @@ namespace llvm { /// @param Symbol - The symbol to emit. A given symbol should only be /// emitted as a label once, and symbols emitted as a label should never be /// used in an assignment. - virtual void EmitLabel(MCSymbol *Symbol) = 0; + virtual void EmitLabel(MCSymbol *Symbol); - /// EmitAssemblerFlag - Note in the output the specified @p Flag + virtual void EmitEHSymAttributes(const MCSymbol *Symbol, + MCSymbol *EHSymbol); + + /// EmitAssemblerFlag - Note in the output the specified @p Flag. virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) = 0; + /// EmitDataRegion - Note in the output the specified region @p Kind. + virtual void EmitDataRegion(MCDataRegionType Kind) {} + /// EmitThumbFunc - Note in the output that the specified @p Func is /// a Thumb mode function (ARM target only). virtual void EmitThumbFunc(MCSymbol *Func) = 0; @@ -181,6 +289,11 @@ namespace llvm { /// EndCOFFSymbolDef - Marks the end of the symbol definition. virtual void EndCOFFSymbolDef() = 0; + /// EmitCOFFSecRel32 - Emits a COFF section relative relocation. + /// + /// @param Symbol - Symbol the section relative realocation should point to. + virtual void EmitCOFFSecRel32(MCSymbol const *Symbol); + /// EmitELFSize - Emit an ELF .size directive. /// /// This corresponds to an assembler statement such as: @@ -201,7 +314,9 @@ namespace llvm { /// /// @param Symbol - The common symbol to emit. /// @param Size - The size of the common symbol. - virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) = 0; + /// @param ByteAlignment - The alignment of the common symbol in bytes. + virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment) = 0; /// EmitZerofill - Emit the zerofill section and an optional symbol. /// @@ -211,7 +326,7 @@ namespace llvm { /// @param ByteAlignment - The alignment of the zerofill symbol if /// non-zero. This must be a power of 2 on some targets. virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, - unsigned Size = 0,unsigned ByteAlignment = 0) = 0; + uint64_t Size = 0,unsigned ByteAlignment = 0) = 0; /// EmitTBSSSymbol - Emit a thread local bss (.tbss) symbol. /// @@ -222,11 +337,12 @@ namespace llvm { /// if non-zero. This must be a power of 2 on some targets. virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment = 0) = 0; + /// @} /// @name Generating Data /// @{ - /// EmitBytes - Emit the bytes in \arg Data into the output. + /// EmitBytes - Emit the bytes in \p Data into the output. /// /// This is used to implement assembler directives such as .byte, .ascii, /// etc. @@ -241,8 +357,10 @@ namespace llvm { /// @param Value - The value to emit. /// @param Size - The size of the integer (in bytes) to emit. This must /// match a native machine width. - virtual void EmitValue(const MCExpr *Value, unsigned Size, - unsigned AddrSpace = 0) = 0; + virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, + unsigned AddrSpace) = 0; + + void EmitValue(const MCExpr *Value, unsigned Size, unsigned AddrSpace = 0); /// EmitIntValue - Special case of EmitValue that avoids the client having /// to pass in a MCExpr for constant integers. @@ -253,17 +371,17 @@ namespace llvm { /// this is done by producing /// foo = value /// .long foo - void EmitAbsValue(const MCExpr *Value, unsigned Size); + void EmitAbsValue(const MCExpr *Value, unsigned Size, + unsigned AddrSpace = 0); - virtual void EmitULEB128Value(const MCExpr *Value, - unsigned AddrSpace = 0) = 0; + virtual void EmitULEB128Value(const MCExpr *Value) = 0; - virtual void EmitSLEB128Value(const MCExpr *Value, - unsigned AddrSpace = 0) = 0; + virtual void EmitSLEB128Value(const MCExpr *Value) = 0; /// EmitULEB128Value - Special case of EmitULEB128Value that avoids the /// client having to pass in a MCExpr for constant integers. - void EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace = 0); + void EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace = 0, + unsigned Padding = 0); /// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the /// client having to pass in a MCExpr for constant integers. @@ -274,6 +392,13 @@ namespace llvm { void EmitSymbolValue(const MCSymbol *Sym, unsigned Size, unsigned AddrSpace = 0); + /// EmitGPRel64Value - Emit the expression @p Value into the output as a + /// gprel64 (64-bit GP relative) value. + /// + /// This is used to implement assembler directives such as .gpdword on + /// targets that support them. + virtual void EmitGPRel64Value(const MCExpr *Value); + /// EmitGPRel32Value - Emit the expression @p Value into the output as a /// gprel32 (32-bit GP relative) value. /// @@ -336,7 +461,8 @@ namespace llvm { /// @param Offset - The offset to reach. This may be an expression, but the /// expression must be associated with the current section. /// @param Value - The value to use when filling bytes. - virtual void EmitValueToOffset(const MCExpr *Offset, + /// @return false on success, true if the offset was invalid. + virtual bool EmitValueToOffset(const MCExpr *Offset, unsigned char Value = 0) = 0; /// @} @@ -348,29 +474,63 @@ namespace llvm { /// EmitDwarfFileDirective - Associate a filename with a specified logical /// file number. This implements the DWARF2 '.file 4 "foo.c"' assembler /// directive. - virtual bool EmitDwarfFileDirective(unsigned FileNo,StringRef Filename); + virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, + StringRef Filename); /// EmitDwarfLocDirective - This implements the DWARF2 // '.loc fileno lineno ...' assembler directive. virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column, unsigned Flags, unsigned Isa, - unsigned Discriminator); + unsigned Discriminator, + StringRef FileName); virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, - const MCSymbol *Label) = 0; + const MCSymbol *Label, + unsigned PointerSize) = 0; + + virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, + const MCSymbol *Label) { + } void EmitDwarfSetLineAddr(int64_t LineDelta, const MCSymbol *Label, int PointerSize); - virtual bool EmitCFIStartProc(); - virtual bool EmitCFIEndProc(); - virtual bool EmitCFIDefCfaOffset(int64_t Offset); - virtual bool EmitCFIDefCfaRegister(int64_t Register); - virtual bool EmitCFIOffset(int64_t Register, int64_t Offset); - virtual bool EmitCFIPersonality(const MCSymbol *Sym); - virtual bool EmitCFILsda(const MCSymbol *Sym); + virtual void EmitCompactUnwindEncoding(uint32_t CompactUnwindEncoding); + virtual void EmitCFISections(bool EH, bool Debug); + void EmitCFIStartProc(); + void EmitCFIEndProc(); + virtual void EmitCFIDefCfa(int64_t Register, int64_t Offset); + virtual void EmitCFIDefCfaOffset(int64_t Offset); + virtual void EmitCFIDefCfaRegister(int64_t Register); + virtual void EmitCFIOffset(int64_t Register, int64_t Offset); + virtual void EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding); + virtual void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding); + virtual void EmitCFIRememberState(); + virtual void EmitCFIRestoreState(); + virtual void EmitCFISameValue(int64_t Register); + virtual void EmitCFIRestore(int64_t Register); + virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset); + virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment); + virtual void EmitCFIEscape(StringRef Values); + virtual void EmitCFISignalFrame(); + virtual void EmitCFIUndefined(int64_t Register); + + virtual void EmitWin64EHStartProc(const MCSymbol *Symbol); + virtual void EmitWin64EHEndProc(); + virtual void EmitWin64EHStartChained(); + virtual void EmitWin64EHEndChained(); + virtual void EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind, + bool Except); + virtual void EmitWin64EHHandlerData(); + virtual void EmitWin64EHPushReg(unsigned Register); + virtual void EmitWin64EHSetFrame(unsigned Register, unsigned Offset); + virtual void EmitWin64EHAllocStack(unsigned Size); + virtual void EmitWin64EHSaveReg(unsigned Register, unsigned Offset); + virtual void EmitWin64EHSaveXMM(unsigned Register, unsigned Offset); + virtual void EmitWin64EHPushFrame(bool Code); + virtual void EmitWin64EHEndProlog(); /// EmitInstruction - Emit the given @p Instruction into the current /// section. @@ -382,8 +542,28 @@ namespace llvm { 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); + + /// PPC-related methods. + /// FIXME: Eventually replace it with some "target MC streamer" and move + /// these methods there. + virtual void EmitTCEntry(const MCSymbol &S); + + /// FinishImpl - Streamer specific finalization. + virtual void FinishImpl() = 0; /// Finish - Finish emission of machine code. - virtual void Finish() = 0; + void Finish(); }; /// createNullStreamer - Create a dummy machine code streamer, which does @@ -399,58 +579,52 @@ namespace llvm { /// InstPrint. /// /// \param CE - If given, a code emitter to use to show the instruction - /// encoding inline with the assembly. This method takes ownership of \arg CE. + /// encoding inline with the assembly. This method takes ownership of \p CE. + /// + /// \param TAB - If given, a target asm backend to use to show the fixup + /// information in conjunction with encoding information. This method takes + /// ownership of \p TAB. /// /// \param ShowInst - Whether to show the MCInst representation inline with /// the assembly. MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, - bool isLittleEndian, bool isVerboseAsm, + bool isVerboseAsm, + bool useLoc, + bool useCFI, + bool useDwarfDirectory, MCInstPrinter *InstPrint = 0, MCCodeEmitter *CE = 0, + MCAsmBackend *TAB = 0, bool ShowInst = false); - MCStreamer *createAsmStreamerNoLoc(MCContext &Ctx, formatted_raw_ostream &OS, - bool isLittleEndian, bool isVerboseAsm, - const TargetLoweringObjectFile *TLOF, - int PointerSize, - MCInstPrinter *InstPrint = 0, - MCCodeEmitter *CE = 0, - bool ShowInst = false); - /// createMachOStreamer - Create a machine code streamer which will generate /// Mach-O format object files. /// - /// Takes ownership of \arg TAB and \arg CE. - MCStreamer *createMachOStreamer(MCContext &Ctx, TargetAsmBackend &TAB, + /// Takes ownership of \p TAB and \p CE. + MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *CE, bool RelaxAll = false); /// createWinCOFFStreamer - Create a machine code streamer which will /// generate Microsoft COFF format object files. /// - /// Takes ownership of \arg TAB and \arg CE. + /// Takes ownership of \p TAB and \p CE. MCStreamer *createWinCOFFStreamer(MCContext &Ctx, - TargetAsmBackend &TAB, + MCAsmBackend &TAB, MCCodeEmitter &CE, raw_ostream &OS, bool RelaxAll = false); /// createELFStreamer - Create a machine code streamer which will generate /// ELF format object files. - MCStreamer *createELFStreamer(MCContext &Ctx, TargetAsmBackend &TAB, - raw_ostream &OS, MCCodeEmitter *CE, - bool RelaxAll = false); - - /// createLoggingStreamer - Create a machine code streamer which just logs the - /// API calls and then dispatches to another streamer. - /// - /// The new streamer takes ownership of the \arg Child. - MCStreamer *createLoggingStreamer(MCStreamer *Child, raw_ostream &OS); + MCStreamer *createELFStreamer(MCContext &Ctx, MCAsmBackend &TAB, + raw_ostream &OS, MCCodeEmitter *CE, + bool RelaxAll, bool NoExecStack); /// createPureStreamer - Create a machine code streamer which will generate /// "pure" MC object files, for use with MC-JIT and testing tools. /// - /// Takes ownership of \arg TAB and \arg CE. - MCStreamer *createPureStreamer(MCContext &Ctx, TargetAsmBackend &TAB, + /// Takes ownership of \p TAB and \p CE. + MCStreamer *createPureStreamer(MCContext &Ctx, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *CE); } // end namespace llvm