diff options
author | Jush Lu <jush.msn@gmail.com> | 2011-03-09 19:39:16 +0800 |
---|---|---|
committer | Jush Lu <jush.msn@gmail.com> | 2011-03-09 19:39:16 +0800 |
commit | b5530586d68bd25831a6796b5d3199cb0769a35c (patch) | |
tree | fac4a03b53b6a64b0c00f433e4d8b3c9f2bc67cd /include/llvm/MC | |
parent | b4e17c5bf4361bbdeced39aa071150d7fa9c3c10 (diff) | |
parent | d01f50f42ce60207ed6d27fb1778e456d83be06c (diff) | |
download | external_llvm-b5530586d68bd25831a6796b5d3199cb0769a35c.tar.gz external_llvm-b5530586d68bd25831a6796b5d3199cb0769a35c.tar.bz2 external_llvm-b5530586d68bd25831a6796b5d3199cb0769a35c.zip |
Merge upstream r127116
Diffstat (limited to 'include/llvm/MC')
31 files changed, 665 insertions, 458 deletions
diff --git a/include/llvm/MC/EDInstInfo.h b/include/llvm/MC/EDInstInfo.h index dded25521a..83d9e780fe 100644 --- a/include/llvm/MC/EDInstInfo.h +++ b/include/llvm/MC/EDInstInfo.h @@ -9,7 +9,7 @@ #ifndef EDINSTINFO_H #define EDINSTINFO_H -#include "llvm/System/DataTypes.h" +#include "llvm/Support/DataTypes.h" namespace llvm { diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index 0c0a942e1b..7e24a3d1d3 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -25,7 +25,9 @@ namespace llvm { /// MCAsmInfo - This class is intended to be used as a base class for asm /// properties and features specific to the target. - namespace ExceptionHandling { enum ExceptionsType { None, Dwarf, SjLj }; } + namespace ExceptionHandling { + enum ExceptionsType { None, DwarfTable, DwarfCFI, SjLj, ARM }; + } class MCAsmInfo { protected: @@ -51,6 +53,11 @@ namespace llvm { /// emitted in Static relocation model. bool HasStaticCtorDtorReferenceInStaticMode; // Default is false. + /// LinkerRequiresNonEmptyDwarfLines - True if the linker has a bug and + /// requires that the debug_line section be of a minimum size. In practice + /// such a linker requires a non empty line sequence if a file is present. + bool LinkerRequiresNonEmptyDwarfLines; // Default to false. + /// MaxInstLength - This is the maximum possible length of an instruction, /// which is needed to compute the size of an inline asm. unsigned MaxInstLength; // Defaults to 4. @@ -192,6 +199,13 @@ namespace llvm { /// HasSetDirective - True if the assembler supports the .set directive. bool HasSetDirective; // Defaults to true. + /// HasAggressiveSymbolFolding - False if the assembler requires that we use + /// Lc = a - b + /// .long Lc + /// instead of + /// .long a - b + bool HasAggressiveSymbolFolding; // Defaults to true. + /// HasLCOMMDirective - This is true if the target supports the .lcomm /// directive. bool HasLCOMMDirective; // Defaults to false. @@ -212,6 +226,10 @@ namespace llvm { /// directive. bool HasNoDeadStrip; // Defaults to false. + /// HasSymbolResolver - True if this target supports the MachO + /// .symbol_resolver directive. + bool HasSymbolResolver; // Defaults to false. + /// WeakRefDirective - This directive, if non-null, is used to declare a /// global as being a weak undefined symbol. const char *WeakRefDirective; // Defaults to NULL. @@ -228,6 +246,11 @@ namespace llvm { /// declare a symbol as having hidden visibility. MCSymbolAttr HiddenVisibilityAttr; // Defaults to MCSA_Hidden. + /// HiddenDeclarationVisibilityAttr - This attribute, if not MCSA_Invalid, + /// is used to declare an undefined symbol as having hidden visibility. + MCSymbolAttr HiddenDeclarationVisibilityAttr; // Defaults to MCSA_Hidden. + + /// ProtectedVisibilityAttr - This attribute, if not MCSA_Invalid, is used /// to declare a symbol as having protected visibility. MCSymbolAttr ProtectedVisibilityAttr; // Defaults to MCSA_Protected @@ -237,10 +260,6 @@ namespace llvm { /// HasLEB128 - True if target asm supports leb128 directives. bool HasLEB128; // Defaults to false. - /// hasDotLocAndDotFile - True if target asm supports .loc and .file - /// directives for emitting debugging information. - bool HasDotLocAndDotFile; // Defaults to false. - /// SupportsDebugInformation - True if target supports emission of debugging /// information. bool SupportsDebugInformation; // Defaults to false. @@ -322,6 +341,9 @@ namespace llvm { bool hasStaticCtorDtorReferenceInStaticMode() const { return HasStaticCtorDtorReferenceInStaticMode; } + bool getLinkerRequiresNonEmptyDwarfLines() const { + return LinkerRequiresNonEmptyDwarfLines; + } unsigned getMaxInstLength() const { return MaxInstLength; } @@ -392,6 +414,9 @@ namespace llvm { return ExternDirective; } bool hasSetDirective() const { return HasSetDirective; } + bool hasAggressiveSymbolFolding() const { + return HasAggressiveSymbolFolding; + } bool hasLCOMMDirective() const { return HasLCOMMDirective; } bool hasDotTypeDotSizeDirective() const {return HasDotTypeDotSizeDirective;} bool getCOMMDirectiveAlignmentIsInBytes() const { @@ -399,20 +424,21 @@ namespace llvm { } bool hasSingleParameterDotFile() const { return HasSingleParameterDotFile; } bool hasNoDeadStrip() const { return HasNoDeadStrip; } + bool hasSymbolResolver() const { return HasSymbolResolver; } const char *getWeakRefDirective() const { return WeakRefDirective; } const char *getWeakDefDirective() const { return WeakDefDirective; } const char *getLinkOnceDirective() const { return LinkOnceDirective; } MCSymbolAttr getHiddenVisibilityAttr() const { return HiddenVisibilityAttr;} + MCSymbolAttr getHiddenDeclarationVisibilityAttr() const { + return HiddenDeclarationVisibilityAttr; + } MCSymbolAttr getProtectedVisibilityAttr() const { return ProtectedVisibilityAttr; } bool hasLEB128() const { return HasLEB128; } - bool hasDotLocAndDotFile() const { - return HasDotLocAndDotFile; - } bool doesSupportDebugInformation() const { return SupportsDebugInformation; } @@ -422,6 +448,13 @@ namespace llvm { ExceptionHandling::ExceptionsType getExceptionHandlingType() const { return ExceptionsType; } + bool isExceptionHandlingDwarf() const { + return + (ExceptionsType == ExceptionHandling::DwarfTable || + ExceptionsType == ExceptionHandling::DwarfCFI || + ExceptionsType == ExceptionHandling::ARM); + } + bool doesDwarfRequireFrameSection() const { return DwarfRequiresFrameSection; } diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h index b9565ba061..01cb0006b3 100644 --- a/include/llvm/MC/MCAsmLayout.h +++ b/include/llvm/MC/MCAsmLayout.h @@ -39,13 +39,12 @@ private: /// The last fragment which was layed out, or 0 if nothing has been layed /// out. Fragments are always layed out in order, so all fragments with a /// lower ordinal will be up to date. - mutable MCFragment *LastValidFragment; + mutable DenseMap<const MCSectionData*, MCFragment *> LastValidFragment; /// \brief Make sure that the layout for the given fragment is valid, lazily /// computing it if necessary. void EnsureValid(const MCFragment *F) const; - bool isSectionUpToDate(const MCSectionData *SD) const; bool isFragmentUpToDate(const MCFragment *F) const; public: @@ -54,27 +53,15 @@ public: /// Get the assembler object this is a layout for. MCAssembler &getAssembler() const { return Assembler; } - /// \brief Update the layout because a fragment has been resized. The - /// fragments size should have already been updated, the \arg SlideAmount is - /// the delta from the old size. - void UpdateForSlide(MCFragment *F, int SlideAmount); - - /// \brief Update the layout because a fragment has been replaced. - void FragmentReplaced(MCFragment *Src, MCFragment *Dst); - - /// \brief Perform a full layout. - void LayoutFile(); + /// \brief Invalidate all following fragments because a fragment has been + /// resized. The fragments size should have already been updated. + void Invalidate(MCFragment *F); /// \brief Perform layout for a single fragment, assuming that the previous /// fragment has already been layed out correctly, and the parent section has /// been initialized. void LayoutFragment(MCFragment *Fragment); - /// \brief Performs initial layout for a single section, assuming that the - /// previous section (including its fragments) has already been layed out - /// correctly. - void LayoutSection(MCSectionData *SD); - /// @name Section Access (in layout order) /// @{ @@ -89,28 +76,13 @@ public: /// @name Fragment Layout Data /// @{ - /// \brief Get the effective size of the given fragment, as computed in the - /// current layout. - uint64_t getFragmentEffectiveSize(const MCFragment *F) const; - /// \brief Get the offset of the given fragment inside its containing section. uint64_t getFragmentOffset(const MCFragment *F) const; /// @} - /// @name Section Layout Data - /// @{ - - /// \brief Get the computed address of the given section. - uint64_t getSectionAddress(const MCSectionData *SD) const; - - /// @} /// @name Utility Functions /// @{ - /// \brief Get the address of the given fragment, as computed in the current - /// layout. - uint64_t getFragmentAddress(const MCFragment *F) const; - /// \brief Get the address space size of the given section, as it effects /// layout. This may differ from the size reported by \see getSectionSize() by /// not including section tail padding. @@ -120,12 +92,9 @@ public: /// file. This may include additional padding, or be 0 for virtual sections. uint64_t getSectionFileSize(const MCSectionData *SD) const; - /// \brief Get the logical data size of the given section. - uint64_t getSectionSize(const MCSectionData *SD) const; - - /// \brief Get the address of the given symbol, as computed in the current + /// \brief Get the offset of the given symbol, as computed in the current /// layout. - uint64_t getSymbolAddress(const MCSymbolData *SD) const; + uint64_t getSymbolOffset(const MCSymbolData *SD) const; /// @} }; diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index a757a92208..30971c62a9 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -11,13 +11,14 @@ #define LLVM_MC_MCASSEMBLER_H #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/ilist.h" #include "llvm/ADT/ilist_node.h" #include "llvm/Support/Casting.h" #include "llvm/MC/MCFixup.h" #include "llvm/MC/MCInst.h" -#include "llvm/System/DataTypes.h" +#include "llvm/Support/DataTypes.h" #include <vector> // FIXME: Shouldn't be needed. namespace llvm { @@ -51,6 +52,7 @@ public: FT_Inst, FT_Org, FT_Dwarf, + FT_DwarfFrame, FT_LEB }; @@ -74,12 +76,7 @@ private: /// initialized. uint64_t Offset; - /// EffectiveSize - The compute size of this section. This is ~0 until - /// initialized. - uint64_t EffectiveSize; - - /// LayoutOrder - The global layout order of this fragment. This is the index - /// across all fragments in the file, not just within the section. + /// LayoutOrder - The layout order of this fragment. unsigned LayoutOrder; /// @} @@ -236,19 +233,12 @@ class MCAlignFragment : public MCFragment { /// target dependent. bool EmitNops : 1; - /// OnlyAlignAddress - Flag to indicate that this align is only used to adjust - /// the address space size of a section and that it should not be included as - /// part of the section size. This flag can only be used on the last fragment - /// in a section. - bool OnlyAlignAddress : 1; - public: MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize, unsigned _MaxBytesToEmit, MCSectionData *SD = 0) : MCFragment(FT_Align, SD), Alignment(_Alignment), Value(_Value),ValueSize(_ValueSize), - MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false), - OnlyAlignAddress(false) {} + MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false) {} /// @name Accessors /// @{ @@ -264,9 +254,6 @@ public: bool hasEmitNops() const { return EmitNops; } void setEmitNops(bool Value) { EmitNops = Value; } - bool hasOnlyAlignAddress() const { return OnlyAlignAddress; } - void setOnlyAlignAddress(bool Value) { OnlyAlignAddress = Value; } - /// @} static bool classof(const MCFragment *F) { @@ -319,13 +306,10 @@ class MCOrgFragment : public MCFragment { /// Value - Value to use for filling bytes. int8_t Value; - /// Size - The current estimate of the size. - unsigned Size; - public: MCOrgFragment(const MCExpr &_Offset, int8_t _Value, MCSectionData *SD = 0) : MCFragment(FT_Org, SD), - Offset(&_Offset), Value(_Value), Size(0) {} + Offset(&_Offset), Value(_Value) {} /// @name Accessors /// @{ @@ -334,9 +318,6 @@ public: uint8_t getValue() const { return Value; } - unsigned getSize() const { return Size; } - - void setSize(unsigned Size_) { Size = Size_; } /// @} static bool classof(const MCFragment *F) { @@ -352,13 +333,11 @@ class MCLEBFragment : public MCFragment { /// IsSigned - True if this is a sleb128, false if uleb128. bool IsSigned; - /// Size - The current size estimate. - uint64_t Size; - + SmallString<8> Contents; public: MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSectionData *SD) : MCFragment(FT_LEB, SD), - Value(&Value_), IsSigned(IsSigned_), Size(1) {} + Value(&Value_), IsSigned(IsSigned_) { Contents.push_back(0); } /// @name Accessors /// @{ @@ -367,9 +346,8 @@ public: bool isSigned() const { return IsSigned; } - uint64_t getSize() const { return Size; } - - void setSize(uint64_t Size_) { Size = Size_; } + SmallString<8> &getContents() { return Contents; } + const SmallString<8> &getContents() const { return Contents; } /// @} @@ -388,14 +366,13 @@ class MCDwarfLineAddrFragment : public MCFragment { /// make up the address delta between two .loc dwarf directives. const MCExpr *AddrDelta; - /// Size - The current size estimate. - uint64_t Size; + SmallString<8> Contents; public: MCDwarfLineAddrFragment(int64_t _LineDelta, const MCExpr &_AddrDelta, - MCSectionData *SD = 0) + MCSectionData *SD) : MCFragment(FT_Dwarf, SD), - LineDelta(_LineDelta), AddrDelta(&_AddrDelta), Size(1) {} + LineDelta(_LineDelta), AddrDelta(&_AddrDelta) { Contents.push_back(0); } /// @name Accessors /// @{ @@ -404,9 +381,8 @@ public: const MCExpr &getAddrDelta() const { return *AddrDelta; } - uint64_t getSize() const { return Size; } - - void setSize(uint64_t Size_) { Size = Size_; } + SmallString<8> &getContents() { return Contents; } + const SmallString<8> &getContents() const { return Contents; } /// @} @@ -416,6 +392,34 @@ public: static bool classof(const MCDwarfLineAddrFragment *) { return true; } }; +class MCDwarfCallFrameFragment : public MCFragment { + /// AddrDelta - The expression for the difference of the two symbols that + /// make up the address delta between two .cfi_* dwarf directives. + const MCExpr *AddrDelta; + + SmallString<8> Contents; + +public: + MCDwarfCallFrameFragment(const MCExpr &_AddrDelta, MCSectionData *SD) + : MCFragment(FT_DwarfFrame, SD), + AddrDelta(&_AddrDelta) { Contents.push_back(0); } + + /// @name Accessors + /// @{ + + const MCExpr &getAddrDelta() const { return *AddrDelta; } + + SmallString<8> &getContents() { return Contents; } + const SmallString<8> &getContents() const { return Contents; } + + /// @} + + static bool classof(const MCFragment *F) { + return F->getKind() == MCFragment::FT_DwarfFrame; + } + static bool classof(const MCDwarfCallFrameFragment *) { return true; } +}; + // FIXME: Should this be a separate class, or just merged into MCSection? Since // we anticipate the fast path being through an MCAssembler, the only reason to // keep it out is for API abstraction. @@ -452,10 +456,6 @@ private: // // FIXME: This could all be kept private to the assembler implementation. - /// Address - The computed address of this section. This is ~0 until - /// initialized. - uint64_t Address; - /// HasInstructions - Whether this section has had instructions emitted into /// it. unsigned HasInstructions : 1; @@ -664,6 +664,8 @@ private: MCCodeEmitter &Emitter; + MCObjectWriter &Writer; + raw_ostream &OS; iplist<MCSectionData> Sections; @@ -682,9 +684,18 @@ private: std::vector<IndirectSymbolData> IndirectSymbols; + /// The set of function symbols for which a .thumb_func directive has + /// been seen. + // + // FIXME: We really would like this in target specific code rather than + // here. Maybe when the relocation stuff moves to target specific, + // this can go with it? The streamer would need some target specific + // refactoring too. + SmallPtrSet<const MCSymbol*, 64> ThumbFuncs; + unsigned RelaxAll : 1; + unsigned NoExecStack : 1; unsigned SubsectionsViaSymbols : 1; - unsigned PadSectionToAlignment : 1; private: /// Evaluate a fixup to a relocatable expression and the value which should be @@ -700,47 +711,44 @@ private: /// \return Whether the fixup value was fully resolved. This is true if the /// \arg Value result is fixed, otherwise the value may change due to /// relocation. - bool EvaluateFixup(const MCObjectWriter &Writer, const MCAsmLayout &Layout, + bool EvaluateFixup(const MCAsmLayout &Layout, const MCFixup &Fixup, const MCFragment *DF, MCValue &Target, uint64_t &Value) const; /// Check whether a fixup can be satisfied, or whether it needs to be relaxed /// (increased in size, in order to hold its value correctly). - bool FixupNeedsRelaxation(const MCObjectWriter &Writer, - const MCFixup &Fixup, const MCFragment *DF, + bool FixupNeedsRelaxation(const MCFixup &Fixup, const MCFragment *DF, const MCAsmLayout &Layout) const; /// Check whether the given fragment needs relaxation. - bool FragmentNeedsRelaxation(const MCObjectWriter &Writer, - const MCInstFragment *IF, + bool FragmentNeedsRelaxation(const MCInstFragment *IF, const MCAsmLayout &Layout) const; - /// Compute the effective fragment size assuming it is layed out at the given - /// \arg SectionAddress and \arg FragmentOffset. - uint64_t ComputeFragmentSize(MCAsmLayout &Layout, const MCFragment &F, - uint64_t SectionAddress, - uint64_t FragmentOffset) const; - /// LayoutOnce - Perform one layout iteration and return true if any offsets /// were adjusted. - bool LayoutOnce(const MCObjectWriter &Writer, MCAsmLayout &Layout); + bool LayoutOnce(MCAsmLayout &Layout); - bool RelaxInstruction(const MCObjectWriter &Writer, MCAsmLayout &Layout, - MCInstFragment &IF); + bool LayoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD); - bool RelaxOrg(const MCObjectWriter &Writer, MCAsmLayout &Layout, - MCOrgFragment &OF); + bool RelaxInstruction(MCAsmLayout &Layout, MCInstFragment &IF); - bool RelaxLEB(const MCObjectWriter &Writer, MCAsmLayout &Layout, - MCLEBFragment &IF); + bool RelaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF); - bool RelaxDwarfLineAddr(const MCObjectWriter &Writer, MCAsmLayout &Layout, - MCDwarfLineAddrFragment &DF); + bool RelaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF); + bool RelaxDwarfCallFrameFragment(MCAsmLayout &Layout, + MCDwarfCallFrameFragment &DF); /// FinishLayout - Finalize a layout, including fragment lowering. void FinishLayout(MCAsmLayout &Layout); + uint64_t HandleFixup(const MCAsmLayout &Layout, + MCFragment &F, const MCFixup &Fixup); + public: + /// Compute the effective fragment size assuming it is layed out at the given + /// \arg SectionAddress and \arg FragmentOffset. + uint64_t ComputeFragmentSize(const MCAsmLayout &Layout, const MCFragment &F) const; + /// Find the symbol which defines the atom containing the given symbol, or /// null if there is no such symbol. const MCSymbolData *getAtom(const MCSymbolData *Symbol) const; @@ -752,13 +760,16 @@ public: bool isSymbolLinkerVisible(const MCSymbol &SD) const; /// Emit the section contents using the given object writer. - // - // FIXME: Should MCAssembler always have a reference to the object writer? - void WriteSectionData(const MCSectionData *Section, const MCAsmLayout &Layout, - MCObjectWriter *OW) const; + void WriteSectionData(const MCSectionData *Section, + const MCAsmLayout &Layout) const; + + /// Check whether a given symbol has been flagged with .thumb_func. + bool isThumbFunc(const MCSymbol *Func) const { + return ThumbFuncs.count(Func); + } - void AddSectionToTheEnd(const MCObjectWriter &Writer, MCSectionData &SD, - MCAsmLayout &Layout); + /// Flag a function symbol as the target of a .thumb_func directive. + void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); } public: /// Construct a new assembler instance. @@ -769,8 +780,8 @@ public: // concrete and require clients to pass in a target like object. The other // option is to make this abstract, and have targets provide concrete // implementations as we do with AsmParser. - MCAssembler(MCContext &_Context, TargetAsmBackend &_Backend, - MCCodeEmitter &_Emitter, bool _PadSectionToAlignment, + MCAssembler(MCContext &Context_, TargetAsmBackend &Backend_, + MCCodeEmitter &Emitter_, MCObjectWriter &Writer_, raw_ostream &OS); ~MCAssembler(); @@ -780,10 +791,12 @@ public: MCCodeEmitter &getEmitter() const { return Emitter; } + MCObjectWriter &getWriter() const { return Writer; } + /// Finish - Do final processing and write the object to the output stream. /// \arg Writer is used for custom object writer (as the MCJIT does), /// if not specified it is automatically created from backend. - void Finish(MCObjectWriter *Writer = 0); + void Finish(); // FIXME: This does not belong here. bool getSubsectionsViaSymbols() const { @@ -796,6 +809,9 @@ public: bool getRelaxAll() const { return RelaxAll; } void setRelaxAll(bool Value) { RelaxAll = Value; } + bool getNoExecStack() const { return NoExecStack; } + void setNoExecStack(bool Value) { NoExecStack = Value; } + /// @name Section List Access /// @{ diff --git a/include/llvm/MC/MCCodeEmitter.h b/include/llvm/MC/MCCodeEmitter.h index eac06ede2a..bc63241bec 100644 --- a/include/llvm/MC/MCCodeEmitter.h +++ b/include/llvm/MC/MCCodeEmitter.h @@ -20,33 +20,6 @@ class MCInst; class raw_ostream; template<typename T> class SmallVectorImpl; -/// MCFixupKindInfo - Target independent information on a fixup kind. -struct MCFixupKindInfo { - enum FixupKindFlags { - /// Is this fixup kind PCrelative? This is used by the assembler backend to - /// evaluate fixup values in a target independent manner when possible. - FKF_IsPCRel = (1 << 0) - }; - - /// A target specific name for the fixup kind. The names will be unique for - /// distinct kinds on any given target. - const char *Name; - - /// The bit offset to write the relocation into. - // - // FIXME: These two fields are under-specified and not general enough, but it - // covers many things. It's enough to let the AsmStreamer pretty-print - // the encoding. - unsigned TargetOffset; - - /// The number of bits written by this fixup. The bits are assumed to be - /// contiguous. - unsigned TargetSize; - - /// Flags describing additional information on this fixup kind. - unsigned Flags; -}; - /// MCCodeEmitter - Generic instruction encoding interface. class MCCodeEmitter { private: @@ -58,17 +31,6 @@ protected: // Can only create subclasses. public: virtual ~MCCodeEmitter(); - /// @name Target Independent Fixup Information - /// @{ - - /// getNumFixupKinds - Get the number of target specific fixup kinds. - virtual unsigned getNumFixupKinds() const = 0; - - /// getFixupKindInfo - Get information on a fixup kind. - virtual const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const; - - /// @} - /// EncodeInstruction - Encode the given \arg Inst to bytes on the output /// stream \arg OS. virtual void EncodeInstruction(const MCInst &Inst, raw_ostream &OS, diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index cec29fad63..7b26d54937 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -29,6 +29,7 @@ namespace llvm { class MCLineSection; class StringRef; class Twine; + class TargetAsmInfo; class MCSectionMachO; class MCSectionELF; @@ -42,9 +43,15 @@ namespace llvm { /// The MCAsmInfo for this target. const MCAsmInfo &MAI; + const TargetAsmInfo *TAI; + /// Symbols - Bindings of names to symbols. StringMap<MCSymbol*> Symbols; + /// UsedNames - Keeps tracks of names that were used both for used declared + /// and artificial symbols. + StringMap<bool> UsedNames; + /// NextUniqueID - The next ID to dole out to an unnamed assembler temporary /// symbol. unsigned NextUniqueID; @@ -57,8 +64,8 @@ namespace llvm { /// GetInstance() gets the current instance of the directional local label /// for the LocalLabelVal and adds it to the map if needed. unsigned GetInstance(int64_t LocalLabelVal); - - /// The file name of the log file from the enviromment variable + + /// The file name of the log file from the environment variable /// AS_SECURE_LOG_FILE. Which must be set before the .secure_log_unique /// directive is used or it is an error. char *SecureLogFile; @@ -80,29 +87,37 @@ namespace llvm { /// The dwarf line information from the .loc directives for the sections /// with assembled machine instructions have after seeing .loc directives. DenseMap<const MCSection *, MCLineSection *> MCLineSections; + /// We need a deterministic iteration order, so we remember the order + /// the elements were added. + std::vector<const MCSection *> MCLineSectionOrder; /// Allocator - Allocator object used for creating machine code objects. /// /// We use a bump pointer allocator to avoid the need to track all allocated /// objects. BumpPtrAllocator Allocator; - + void *MachOUniquingMap, *ELFUniquingMap, *COFFUniquingMap; + + MCSymbol *CreateSymbol(StringRef Name); + public: - explicit MCContext(const MCAsmInfo &MAI); + explicit MCContext(const MCAsmInfo &MAI, const TargetAsmInfo *TAI); ~MCContext(); - + const MCAsmInfo &getAsmInfo() const { return MAI; } - /// @name Symbol Managment + const TargetAsmInfo &getTargetAsmInfo() const { return *TAI; } + + /// @name Symbol Management /// @{ - + /// CreateTempSymbol - Create and return a new assembler temporary symbol /// with a unique but unspecified name. MCSymbol *CreateTempSymbol(); - /// CreateDirectionalLocalSymbol - Create the defintion of a directional - /// local symbol for numbered label (used for "1:" defintions). + /// CreateDirectionalLocalSymbol - Create the definition of a directional + /// local symbol for numbered label (used for "1:" definitions). MCSymbol *CreateDirectionalLocalSymbol(int64_t LocalLabelVal); /// GetDirectionalLocalSymbol - Create and return a directional local @@ -121,8 +136,8 @@ namespace llvm { MCSymbol *LookupSymbol(StringRef Name) const; /// @} - - /// @name Section Managment + + /// @name Section Management /// @{ /// getMachOSection - Return the MCSection for the specified mach-o section. @@ -156,10 +171,10 @@ namespace llvm { return getCOFFSection (Section, Characteristics, 0, Kind); } - + /// @} - /// @name Dwarf Managment + /// @name Dwarf Management /// @{ /// GetDwarfFile - creates an entry in the dwarf file and directory tables. @@ -167,8 +182,8 @@ namespace llvm { bool isValidDwarfFileNumber(unsigned FileNumber); - bool hasDwarfFiles(void) { - return MCDwarfFiles.size() != 0; + bool hasDwarfFiles() const { + return !MCDwarfFiles.empty(); } const std::vector<MCDwarfFile *> &getMCDwarfFiles() { @@ -177,9 +192,18 @@ namespace llvm { const std::vector<StringRef> &getMCDwarfDirs() { return MCDwarfDirs; } - DenseMap<const MCSection *, MCLineSection *> &getMCLineSections() { + + const DenseMap<const MCSection *, MCLineSection *> + &getMCLineSections() const { return MCLineSections; } + const std::vector<const MCSection *> &getMCLineSectionOrder() const { + return MCLineSectionOrder; + } + void addMCLineSection(const MCSection *Sec, MCLineSection *Line) { + MCLineSections[Sec] = Line; + MCLineSectionOrder.push_back(Sec); + } /// setCurrentDwarfLoc - saves the information from the currently parsed /// dwarf .loc directive and sets DwarfLocSeen. When the next instruction diff --git a/include/llvm/MC/MCDirectives.h b/include/llvm/MC/MCDirectives.h index 03337a9f52..1df55dc252 100644 --- a/include/llvm/MC/MCDirectives.h +++ b/include/llvm/MC/MCDirectives.h @@ -34,6 +34,7 @@ enum MCSymbolAttr { MCSA_LazyReference, ///< .lazy_reference (MachO) MCSA_Local, ///< .local (ELF) MCSA_NoDeadStrip, ///< .no_dead_strip (MachO) + MCSA_SymbolResolver, ///< .symbol_resolver (MachO) MCSA_PrivateExtern, ///< .private_extern (MachO) MCSA_Protected, ///< .protected (ELF) MCSA_Reference, ///< .reference (MachO) diff --git a/include/llvm/MC/MCDisassembler.h b/include/llvm/MC/MCDisassembler.h index dfb8ed5e8a..c9e42eb6c7 100644 --- a/include/llvm/MC/MCDisassembler.h +++ b/include/llvm/MC/MCDisassembler.h @@ -9,7 +9,7 @@ #ifndef MCDISASSEMBLER_H #define MCDISASSEMBLER_H -#include "llvm/System/DataTypes.h" +#include "llvm/Support/DataTypes.h" namespace llvm { diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h index 609d819626..07a7bad15b 100644 --- a/include/llvm/MC/MCDwarf.h +++ b/include/llvm/MC/MCDwarf.h @@ -16,16 +16,19 @@ #define LLVM_MC_MCDWARF_H #include "llvm/ADT/StringRef.h" -#include "llvm/MC/MCStreamer.h" -#include "llvm/MC/MCObjectStreamer.h" +#include "llvm/CodeGen/MachineLocation.h" // FIXME #include "llvm/MC/MCObjectWriter.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Dwarf.h" #include <vector> namespace llvm { + class MachineMove; class MCContext; + class MCExpr; class MCSection; + class MCSectionData; + class MCStreamer; class MCSymbol; class MCObjectStreamer; class raw_ostream; @@ -107,22 +110,22 @@ namespace llvm { public: /// getFileNum - Get the FileNum of this MCDwarfLoc. - unsigned getFileNum() { return FileNum; } + unsigned getFileNum() const { return FileNum; } /// getLine - Get the Line of this MCDwarfLoc. - unsigned getLine() { return Line; } + unsigned getLine() const { return Line; } /// getColumn - Get the Column of this MCDwarfLoc. - unsigned getColumn() { return Column; } + unsigned getColumn() const { return Column; } /// getFlags - Get the Flags of this MCDwarfLoc. - unsigned getFlags() { return Flags; } + unsigned getFlags() const { return Flags; } /// getIsa - Get the Isa of this MCDwarfLoc. - unsigned getIsa() { return Isa; } + unsigned getIsa() const { return Isa; } /// getDiscriminator - Get the Discriminator of this MCDwarfLoc. - unsigned getDiscriminator() { return Discriminator; } + unsigned getDiscriminator() const { return Discriminator; } /// setFileNum - Set the FileNum of this MCDwarfLoc. void setFileNum(unsigned fileNum) { FileNum = fileNum; } @@ -162,12 +165,12 @@ namespace llvm { MCLineEntry(MCSymbol *label, const MCDwarfLoc loc) : MCDwarfLoc(loc), Label(label) {} - MCSymbol *getLabel() { return Label; } + MCSymbol *getLabel() const { return Label; } // This is called when an instruction is assembled into the specified // section and if there is information from the last .loc directive that // has yet to have a line entry made for it is made. - static void Make(MCObjectStreamer *MCOS, const MCSection *Section); + static void Make(MCStreamer *MCOS, const MCSection *Section); }; /// MCLineSection - Instances of this class represent the line information @@ -192,12 +195,15 @@ namespace llvm { typedef std::vector<MCLineEntry> MCLineEntryCollection; typedef MCLineEntryCollection::iterator iterator; + typedef MCLineEntryCollection::const_iterator const_iterator; private: MCLineEntryCollection MCLineEntries; public: - MCLineEntryCollection *getMCLineEntries() { return &MCLineEntries; } + const MCLineEntryCollection *getMCLineEntries() const { + return &MCLineEntries; + } }; class MCDwarfFileTable { @@ -205,7 +211,7 @@ namespace llvm { // // This emits the Dwarf file and the line tables. // - static void Emit(MCObjectStreamer *MCOS, const MCSection *DwarfLineSection); + static void Emit(MCStreamer *MCOS); }; class MCDwarfLineAddr { @@ -214,16 +220,60 @@ namespace llvm { static void Encode(int64_t LineDelta, uint64_t AddrDelta, raw_ostream &OS); /// Utility function to emit the encoding to a streamer. - static void Emit(MCObjectStreamer *MCOS, + static void Emit(MCStreamer *MCOS, int64_t LineDelta,uint64_t AddrDelta); - /// Utility function to compute the size of the encoding. - static uint64_t ComputeSize(int64_t LineDelta, uint64_t AddrDelta); - /// Utility function to write the encoding to an object writer. static void Write(MCObjectWriter *OW, int64_t LineDelta, uint64_t AddrDelta); }; + + class MCCFIInstruction { + public: + enum OpType { Remember, Restore, Move }; + private: + OpType Operation; + MCSymbol *Label; + // Move to & from location. + MachineLocation Destination; + MachineLocation Source; + public: + MCCFIInstruction(OpType Op, MCSymbol *L) + : Operation(Op), Label(L) { + assert(Op == Remember || Op == Restore); + } + MCCFIInstruction(MCSymbol *L, const MachineLocation &D, + const MachineLocation &S) + : Operation(Move), Label(L), Destination(D), Source(S) { + } + OpType getOperation() const { return Operation; } + MCSymbol *getLabel() const { return Label; } + const MachineLocation &getDestination() const { return Destination; } + const MachineLocation &getSource() const { return Source; } + }; + + struct MCDwarfFrameInfo { + MCDwarfFrameInfo() : Begin(0), End(0), Personality(0), Lsda(0), + Instructions(), PersonalityEncoding(0), + LsdaEncoding(0) {} + MCSymbol *Begin; + MCSymbol *End; + const MCSymbol *Personality; + const MCSymbol *Lsda; + std::vector<MCCFIInstruction> Instructions; + unsigned PersonalityEncoding; + unsigned LsdaEncoding; + }; + + class MCDwarfFrameEmitter { + public: + // + // This emits the frame info section. + // + static void Emit(MCStreamer &streamer); + static void EmitAdvanceLoc(MCStreamer &Streamer, uint64_t AddrDelta); + static void EncodeAdvanceLoc(uint64_t AddrDelta, raw_ostream &OS); + }; } // end namespace llvm #endif diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h new file mode 100644 index 0000000000..3c150dca9e --- /dev/null +++ b/include/llvm/MC/MCELFObjectWriter.h @@ -0,0 +1,47 @@ +//===-- llvm/MC/MCELFObjectWriter.h - ELF Object Writer ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCELFOBJECTWRITER_H +#define LLVM_MC_MCELFOBJECTWRITER_H + +#include "llvm/MC/MCObjectWriter.h" +#include "llvm/Support/DataTypes.h" + +namespace llvm { +class MCELFObjectTargetWriter { + const Triple::OSType OSType; + const uint16_t EMachine; + const unsigned HasRelocationAddend : 1; + const unsigned Is64Bit : 1; +protected: + MCELFObjectTargetWriter(bool Is64Bit_, Triple::OSType OSType_, + uint16_t EMachine_, bool HasRelocationAddend_); + +public: + virtual ~MCELFObjectTargetWriter(); + + /// @name Accessors + /// @{ + Triple::OSType getOSType() { return OSType; } + uint16_t getEMachine() { return EMachine; } + bool hasRelocationAddend() { return HasRelocationAddend; } + bool is64Bit() { return Is64Bit; } + /// @} +}; + +/// \brief Construct a new ELF writer instance. +/// +/// \param MOTW - The target specific ELF writer subclass. +/// \param OS - The stream to write to. +/// \returns The constructed object writer. +MCObjectWriter *createELFObjectWriter(MCELFObjectTargetWriter *MOTW, + raw_ostream &OS, bool IsLittleEndian); +} // End llvm namespace + +#endif diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index e8b15284f2..fea5249eab 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -10,17 +10,21 @@ #ifndef LLVM_MC_MCEXPR_H #define LLVM_MC_MCEXPR_H +#include "llvm/ADT/DenseMap.h" #include "llvm/Support/Casting.h" -#include "llvm/System/DataTypes.h" +#include "llvm/Support/DataTypes.h" namespace llvm { class MCAsmInfo; class MCAsmLayout; +class MCAssembler; class MCContext; +class MCSectionData; class MCSymbol; class MCValue; class raw_ostream; class StringRef; +typedef DenseMap<const MCSectionData*, uint64_t> SectionAddrMap; /// MCExpr - Base class for the full range of assembler expressions which are /// needed for parsing. @@ -40,10 +44,15 @@ private: MCExpr(const MCExpr&); // DO NOT IMPLEMENT void operator=(const MCExpr&); // DO NOT IMPLEMENT + bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm, + const MCAsmLayout *Layout, + const SectionAddrMap *Addrs) const; protected: explicit MCExpr(ExprKind _Kind) : Kind(_Kind) {} - bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout, + bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, + const MCAsmLayout *Layout, + const SectionAddrMap *Addrs, bool InSet) const; public: /// @name Accessors @@ -69,7 +78,11 @@ public: /// values. If not given, then only non-symbolic expressions will be /// evaluated. /// @result - True on success. - bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout *Layout = 0) const; + bool EvaluateAsAbsolute(int64_t &Res) const; + bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const; + bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const; + bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout, + const SectionAddrMap &Addrs) const; /// EvaluateAsRelocatable - Try to evaluate the expression to a relocatable /// value, i.e. an expression of the fixed form (a - b + constant). @@ -77,7 +90,7 @@ public: /// @param Res - The relocatable value, if evaluation succeeds. /// @param Layout - The assembler layout object to use for evaluating values. /// @result - True on success. - bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout = 0) const; + bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout &Layout) const; /// @} @@ -142,8 +155,6 @@ public: VK_TPOFF, VK_DTPOFF, VK_TLVP, // Mach-O thread local variable relocation - VK_ARM_HI16, // The R_ARM_MOVT_ABS relocation (:upper16: in the .s file) - VK_ARM_LO16, // The R_ARM_MOVW_ABS_NC relocation (:lower16: in the .w file) // FIXME: We'd really like to use the generic Kinds listed above for these. VK_ARM_PLT, // ARM-style PLT references. i.e., (PLT) instead of @PLT VK_ARM_TLSGD, // ditto for TLSGD, GOT, GOTOFF, TPOFF and GOTTPOFF @@ -151,7 +162,7 @@ public: VK_ARM_GOTOFF, VK_ARM_TPOFF, VK_ARM_GOTTPOFF, - + VK_PPC_TOC, VK_PPC_HA16, // ha16(symbol) VK_PPC_LO16 // lo16(symbol) @@ -179,7 +190,7 @@ public: MCContext &Ctx); static const MCSymbolRefExpr *Create(StringRef Name, VariantKind Kind, MCContext &Ctx); - + /// @} /// @name Accessors /// @{ @@ -408,7 +419,7 @@ public: virtual void PrintImpl(raw_ostream &OS) const = 0; virtual bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout) const = 0; - + virtual void AddValueSymbols(MCAssembler *) const = 0; static bool classof(const MCExpr *E) { return E->getKind() == MCExpr::Target; diff --git a/include/llvm/MC/MCFixup.h b/include/llvm/MC/MCFixup.h index eed4c349e8..6fde797e40 100644 --- a/include/llvm/MC/MCFixup.h +++ b/include/llvm/MC/MCFixup.h @@ -10,7 +10,7 @@ #ifndef LLVM_MC_MCFIXUP_H #define LLVM_MC_MCFIXUP_H -#include "llvm/System/DataTypes.h" +#include "llvm/Support/DataTypes.h" #include <cassert> namespace llvm { @@ -22,6 +22,10 @@ enum MCFixupKind { FK_Data_2, ///< A two-byte fixup. FK_Data_4, ///< A four-byte fixup. FK_Data_8, ///< A eight-byte fixup. + FK_PCRel_1, ///< A one-byte pc relative fixup. + FK_PCRel_2, ///< A two-byte pc relative fixup. + FK_PCRel_4, ///< A four-byte pc relative fixup. + FK_PCRel_8, ///< A eight-byte pc relative fixup. FirstTargetFixupKind = 128, @@ -77,13 +81,13 @@ public: /// getKindForSize - Return the generic fixup kind for a value with the given /// size. It is an error to pass an unsupported size. - static MCFixupKind getKindForSize(unsigned Size) { + static MCFixupKind getKindForSize(unsigned Size, bool isPCRel) { switch (Size) { default: assert(0 && "Invalid generic fixup size!"); - case 1: return FK_Data_1; - case 2: return FK_Data_2; - case 4: return FK_Data_4; - case 8: return FK_Data_8; + case 1: return isPCRel ? FK_PCRel_1 : FK_Data_1; + case 2: return isPCRel ? FK_PCRel_2 : FK_Data_2; + case 4: return isPCRel ? FK_PCRel_4 : FK_Data_4; + case 8: return isPCRel ? FK_PCRel_8 : FK_Data_8; } } }; diff --git a/include/llvm/MC/MCFixupKindInfo.h b/include/llvm/MC/MCFixupKindInfo.h new file mode 100644 index 0000000000..1961687146 --- /dev/null +++ b/include/llvm/MC/MCFixupKindInfo.h @@ -0,0 +1,43 @@ +//===-- llvm/MC/MCFixupKindInfo.h - Fixup Descriptors -----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCFIXUPKINDINFO_H +#define LLVM_MC_MCFIXUPKINDINFO_H + +namespace llvm { + +/// MCFixupKindInfo - Target independent information on a fixup kind. +struct MCFixupKindInfo { + enum FixupKindFlags { + /// Is this fixup kind PCrelative? This is used by the assembler backend to + /// evaluate fixup values in a target independent manner when possible. + FKF_IsPCRel = (1 << 0), + + /// Should this fixup kind force a 4-byte aligned effective PC value? + FKF_IsAlignedDownTo32Bits = (1 << 1) + }; + + /// A target specific name for the fixup kind. The names will be unique for + /// distinct kinds on any given target. + const char *Name; + + /// The bit offset to write the relocation into. + unsigned TargetOffset; + + /// The number of bits written by this fixup. The bits are assumed to be + /// contiguous. + unsigned TargetSize; + + /// Flags describing additional information on this fixup kind. + unsigned Flags; +}; + +} // End llvm namespace + +#endif diff --git a/include/llvm/MC/MCInst.h b/include/llvm/MC/MCInst.h index 2b337e3624..d6ef7b4c33 100644 --- a/include/llvm/MC/MCInst.h +++ b/include/llvm/MC/MCInst.h @@ -18,7 +18,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" -#include "llvm/System/DataTypes.h" +#include "llvm/Support/DataTypes.h" namespace llvm { class raw_ostream; diff --git a/include/llvm/MC/MCInstPrinter.h b/include/llvm/MC/MCInstPrinter.h index 96716c775f..92f06ed09c 100644 --- a/include/llvm/MC/MCInstPrinter.h +++ b/include/llvm/MC/MCInstPrinter.h @@ -41,6 +41,9 @@ public: /// getOpcodeName - Return the name of the specified opcode enum (e.g. /// "MOV32ri") or empty if we can't resolve it. virtual StringRef getOpcodeName(unsigned Opcode) const; + + /// getRegName - Return the assembler register name. + virtual StringRef getRegName(unsigned RegNo) const; }; } // namespace llvm diff --git a/include/llvm/MC/MCMachOSymbolFlags.h b/include/llvm/MC/MCMachOSymbolFlags.h index c938c81f69..696436dffa 100644 --- a/include/llvm/MC/MCMachOSymbolFlags.h +++ b/include/llvm/MC/MCMachOSymbolFlags.h @@ -34,9 +34,11 @@ namespace llvm { SF_ReferenceTypePrivateUndefinedLazy = 0x0005, // Other 'desc' flags. + SF_ThumbFunc = 0x0008, SF_NoDeadStrip = 0x0020, SF_WeakReference = 0x0040, - SF_WeakDefinition = 0x0080 + SF_WeakDefinition = 0x0080, + SF_SymbolResolver = 0x0100 }; } // end namespace llvm diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h new file mode 100644 index 0000000000..ec51031d0b --- /dev/null +++ b/include/llvm/MC/MCMachObjectWriter.h @@ -0,0 +1,65 @@ +//===-- llvm/MC/MCMachObjectWriter.h - Mach Object Writer -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCMACHOBJECTWRITER_H +#define LLVM_MC_MCMACHOBJECTWRITER_H + +#include "llvm/MC/MCObjectWriter.h" +#include "llvm/Support/DataTypes.h" + +namespace llvm { + +class MCMachObjectTargetWriter { + const unsigned Is64Bit : 1; + const uint32_t CPUType; + const uint32_t CPUSubtype; + // FIXME: Remove this, we should just always use it once we no longer care + // about Darwin 'as' compatibility. + const unsigned UseAggressiveSymbolFolding : 1; + unsigned LocalDifference_RIT; + +protected: + MCMachObjectTargetWriter(bool Is64Bit_, uint32_t CPUType_, + uint32_t CPUSubtype_, + bool UseAggressiveSymbolFolding_ = false); + + void setLocalDifferenceRelocationType(unsigned Type) { + LocalDifference_RIT = Type; + } + +public: + virtual ~MCMachObjectTargetWriter(); + + /// @name Accessors + /// @{ + + bool is64Bit() const { return Is64Bit; } + bool useAggressiveSymbolFolding() const { return UseAggressiveSymbolFolding; } + uint32_t getCPUType() const { return CPUType; } + uint32_t getCPUSubtype() const { return CPUSubtype; } + unsigned getLocalDifferenceRelocationType() const { + return LocalDifference_RIT; + } + + /// @} +}; + +/// \brief Construct a new Mach-O writer instance. +/// +/// This routine takes ownership of the target writer subclass. +/// +/// \param MOTW - The target specific Mach-O writer subclass. +/// \param OS - The stream to write to. +/// \returns The constructed object writer. +MCObjectWriter *createMachObjectWriter(MCMachObjectTargetWriter *MOTW, + raw_ostream &OS, bool IsLittleEndian); + +} // End llvm namespace + +#endif diff --git a/include/llvm/MC/MCObjectFormat.h b/include/llvm/MC/MCObjectFormat.h deleted file mode 100644 index 5c3f003696..0000000000 --- a/include/llvm/MC/MCObjectFormat.h +++ /dev/null @@ -1,54 +0,0 @@ -//===-- llvm/MC/MCObjectFormat.h - Object Format Info -----------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_MC_MCOBJECTFORMAT_H -#define LLVM_MC_MCOBJECTFORMAT_H - -namespace llvm { -class MCSymbol; - -class MCObjectFormat { -public: - virtual ~MCObjectFormat(); - - /// isAbsolute - Check if A - B is an absolute value - /// - /// \param InSet - True if this expression is in a set. For example: - /// a: - /// ... - /// b: - /// tmp = a - b - /// .long tmp - /// \param A - LHS - /// \param B - RHS - virtual bool isAbsolute(bool InSet, const MCSymbol &A, - const MCSymbol &B) const = 0; -}; - -class MCELFObjectFormat : public MCObjectFormat { -public: - virtual bool isAbsolute(bool InSet, const MCSymbol &A, - const MCSymbol &B) const; -}; - -class MCMachOObjectFormat : public MCObjectFormat { -public: - virtual bool isAbsolute(bool InSet, const MCSymbol &A, - const MCSymbol &B) const; -}; - -class MCCOFFObjectFormat : public MCObjectFormat { -public: - virtual bool isAbsolute(bool InSet, const MCSymbol &A, - const MCSymbol &B) const; -}; - -} // End llvm namespace - -#endif diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h index 8c21c10522..833341eb97 100644 --- a/include/llvm/MC/MCObjectStreamer.h +++ b/include/llvm/MC/MCObjectStreamer.h @@ -33,13 +33,11 @@ class MCObjectStreamer : public MCStreamer { MCAssembler *Assembler; MCSectionData *CurSectionData; - virtual void EmitInstToFragment(const MCInst &Inst) = 0; virtual void EmitInstToData(const MCInst &Inst) = 0; protected: MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB, - raw_ostream &_OS, MCCodeEmitter *_Emitter, - bool _PadSectionToAlignment); + raw_ostream &_OS, MCCodeEmitter *_Emitter); ~MCObjectStreamer(); MCSectionData *getCurrentSectionData() const { @@ -60,11 +58,21 @@ public: /// @name MCStreamer Interface /// @{ + virtual void EmitLabel(MCSymbol *Symbol); + virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, + bool isPCRel, 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 ChangeSection(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 EmitDwarfAdvanceLineAddr(int64_t LineDelta, + const MCSymbol *LastLabel, + const MCSymbol *Label); + virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, + const MCSymbol *Label); virtual void Finish(); /// @} diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h index 77ab6abed2..782d844598 100644 --- a/include/llvm/MC/MCObjectWriter.h +++ b/include/llvm/MC/MCObjectWriter.h @@ -12,7 +12,7 @@ #include "llvm/ADT/Triple.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/System/DataTypes.h" +#include "llvm/Support/DataTypes.h" #include <cassert> namespace llvm { @@ -20,6 +20,9 @@ class MCAsmLayout; class MCAssembler; class MCFixup; class MCFragment; +class MCSymbol; +class MCSymbolData; +class MCSymbolRefExpr; class MCValue; class raw_ostream; @@ -62,7 +65,8 @@ public: /// /// This routine is called by the assembler after layout and relaxation is /// complete. - virtual void ExecutePostLayoutBinding(MCAssembler &Asm) = 0; + virtual void ExecutePostLayoutBinding(MCAssembler &Asm, + const MCAsmLayout &Layout) = 0; /// Record a relocation entry. /// @@ -76,15 +80,24 @@ public: const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue) = 0; - /// Check if a fixup is fully resolved. + /// \brief Check whether the difference (A - B) between two symbol + /// references is fully resolved. /// - /// This routine is used by the assembler to let the file format decide - /// if a fixup is not fully resolved. For example, one that crosses - /// two sections on ELF. - virtual bool IsFixupFullyResolved(const MCAssembler &Asm, - const MCValue Target, - bool IsPCRel, - const MCFragment *DF) const = 0; + /// Clients are not required to answer precisely and may conservatively return + /// false, even when a difference is fully resolved. + bool + IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm, + const MCSymbolRefExpr *A, + const MCSymbolRefExpr *B, + bool InSet) const; + + virtual bool + IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, + const MCSymbolData &DataA, + const MCFragment &FB, + bool InSet, + bool IsPCRel) const; + /// Write the object file. /// @@ -178,13 +191,6 @@ public: static void EncodeULEB128(uint64_t Value, raw_ostream &OS); }; -MCObjectWriter *createMachObjectWriter(raw_ostream &OS, bool is64Bit, - uint32_t CPUType, uint32_t CPUSubtype, - bool IsLittleEndian); -MCObjectWriter *createELFObjectWriter(raw_ostream &OS, bool is64Bit, - Triple::OSType OSType, uint16_t EMachine, - bool IsLittleEndian, - bool HasRelocationAddend); MCObjectWriter *createWinCOFFObjectWriter(raw_ostream &OS, bool is64Bit); } // End llvm namespace diff --git a/include/llvm/MC/MCParser/AsmLexer.h b/include/llvm/MC/MCParser/AsmLexer.h index 439ecb91e5..252696bec3 100644 --- a/include/llvm/MC/MCParser/AsmLexer.h +++ b/include/llvm/MC/MCParser/AsmLexer.h @@ -17,7 +17,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/MC/MCParser/MCAsmLexer.h" #include "llvm/MC/MCAsmInfo.h" -#include "llvm/System/DataTypes.h" +#include "llvm/Support/DataTypes.h" #include <string> #include <cassert> @@ -29,10 +29,10 @@ class MCAsmInfo; /// AsmLexer - Lexer class for assembly files. class AsmLexer : public MCAsmLexer { const MCAsmInfo &MAI; - + const char *CurPtr; const MemoryBuffer *CurBuf; - + void operator=(const AsmLexer&); // DO NOT IMPLEMENT AsmLexer(const AsmLexer&); // DO NOT IMPLEMENT @@ -43,13 +43,13 @@ protected: public: AsmLexer(const MCAsmInfo &MAI); ~AsmLexer(); - + void setBuffer(const MemoryBuffer *buf, const char *ptr = NULL); - + virtual StringRef LexUntilEndOfStatement(); bool isAtStartOfComment(char Char); - + const MCAsmInfo &getMAI() const { return MAI; } private: @@ -60,10 +60,11 @@ private: AsmToken LexSlash(); AsmToken LexLineComment(); AsmToken LexDigit(); + AsmToken LexSingleQuote(); AsmToken LexQuote(); AsmToken LexFloatLiteral(); }; - + } // end namespace llvm #endif diff --git a/include/llvm/MC/MCParser/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h index b0039fe2ba..606725a985 100644 --- a/include/llvm/MC/MCParser/MCAsmLexer.h +++ b/include/llvm/MC/MCParser/MCAsmLexer.h @@ -11,7 +11,7 @@ #define LLVM_MC_MCASMLEXER_H #include "llvm/ADT/StringRef.h" -#include "llvm/System/DataTypes.h" +#include "llvm/Support/DataTypes.h" #include "llvm/Support/SMLoc.h" namespace llvm { @@ -29,16 +29,16 @@ public: // String values. Identifier, String, - + // Integer values. Integer, - + // Real values. Real, - + // Register values (stored in IntVal). Only used by TargetAsmLexer. Register, - + // No-value. EndOfStatement, Colon, @@ -46,8 +46,8 @@ public: Slash, // '/' LParen, RParen, LBrac, RBrac, LCurly, RCurly, Star, Dot, Comma, Dollar, Equal, EqualEqual, - - Pipe, PipePipe, Caret, + + Pipe, PipePipe, Caret, Amp, AmpAmp, Exclaim, ExclaimEqual, Percent, Hash, Less, LessEqual, LessLess, LessGreater, Greater, GreaterEqual, GreaterGreater, At @@ -73,7 +73,7 @@ public: SMLoc getLoc() const; /// getStringContents - Get the contents of a string token (without quotes). - StringRef getStringContents() const { + StringRef getStringContents() const { assert(Kind == String && "This token isn't a string!"); return Str.slice(1, Str.size() - 1); } @@ -98,11 +98,11 @@ public: // FIXME: Don't compute this in advance, it makes every token larger, and is // also not generally what we want (it is nicer for recovery etc. to lex 123br // as a single token, then diagnose as an invalid number). - int64_t getIntVal() const { + int64_t getIntVal() const { assert(Kind == Integer && "This token isn't an integer!"); - return IntVal; + return IntVal; } - + /// getRegVal - Get the register number for the current token, which should /// be a register. unsigned getRegVal() const { @@ -116,7 +116,7 @@ public: class MCAsmLexer { /// The current token, stored in the base class for faster access. AsmToken CurTok; - + /// The location and description of the current error SMLoc ErrLoc; std::string Err; @@ -129,12 +129,12 @@ protected: // Can only create subclasses. MCAsmLexer(); virtual AsmToken LexToken() = 0; - + void SetError(const SMLoc &errLoc, const std::string &err) { ErrLoc = errLoc; Err = err; } - + public: virtual ~MCAsmLexer(); @@ -155,12 +155,12 @@ public: const AsmToken &getTok() { return CurTok; } - + /// getErrLoc - Get the current error location const SMLoc &getErrLoc() { return ErrLoc; } - + /// getErr - Get the current error string const std::string &getErr() { return Err; diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h index 6e1e2e3ece..54979d977d 100644 --- a/include/llvm/MC/MCParser/MCAsmParser.h +++ b/include/llvm/MC/MCParser/MCAsmParser.h @@ -10,7 +10,7 @@ #ifndef LLVM_MC_MCASMPARSER_H #define LLVM_MC_MCASMPARSER_H -#include "llvm/System/DataTypes.h" +#include "llvm/Support/DataTypes.h" namespace llvm { class AsmToken; @@ -102,7 +102,7 @@ public: /// EatToEndOfStatement - Skip to the end of the current statement, for error /// recovery. virtual void EatToEndOfStatement() = 0; - + /// ParseExpression - Parse an arbitrary expression. /// /// @param Res - The value of the expression. The result is undefined diff --git a/include/llvm/MC/MCParser/MCAsmParserExtension.h b/include/llvm/MC/MCParser/MCAsmParserExtension.h index 95184cdfcf..ceb57f57e9 100644 --- a/include/llvm/MC/MCParser/MCAsmParserExtension.h +++ b/include/llvm/MC/MCParser/MCAsmParserExtension.h @@ -38,6 +38,8 @@ protected: return (Obj->*Handler)(Directive, DirectiveLoc); } + bool BracketExpressionsSupported; + public: virtual ~MCAsmParserExtension(); @@ -68,6 +70,8 @@ public: const AsmToken &getTok() { return getParser().getTok(); } + bool HasBracketExpressions() const { return BracketExpressionsSupported; } + /// @} }; diff --git a/include/llvm/MC/MCParser/MCParsedAsmOperand.h b/include/llvm/MC/MCParser/MCParsedAsmOperand.h index 99fa5adae9..91f5773b8d 100644 --- a/include/llvm/MC/MCParser/MCParsedAsmOperand.h +++ b/include/llvm/MC/MCParser/MCParsedAsmOperand.h @@ -19,10 +19,10 @@ class raw_ostream; /// base class is used by target-independent clients and is the interface /// between parsing an asm instruction and recognizing it. class MCParsedAsmOperand { -public: +public: MCParsedAsmOperand() {} virtual ~MCParsedAsmOperand() {} - + /// getStartLoc - Get the location of the first token of this operand. virtual SMLoc getStartLoc() const = 0; /// getEndLoc - Get the location of the last token of this operand. diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h index b741216f94..1c01b2f8f3 100644 --- a/include/llvm/MC/MCSection.h +++ b/include/llvm/MC/MCSection.h @@ -64,6 +64,10 @@ namespace llvm { // "optimized nops" to fill instead of 0s. virtual bool UseCodeAlign() const = 0; + /// isVirtualSection - Check whether this section is "virtual", that is + /// has no actual object file contents. + virtual bool isVirtualSection() const = 0; + static bool classof(const MCSection *) { return true; } }; diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h index 8bf7f448ec..b154cf59d1 100644 --- a/include/llvm/MC/MCSectionCOFF.h +++ b/include/llvm/MC/MCSectionCOFF.h @@ -56,6 +56,7 @@ namespace llvm { virtual void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS) const; virtual bool UseCodeAlign() const; + virtual bool isVirtualSection() const; static bool classof(const MCSection *S) { return S->getVariant() == SV_COFF; diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h index 5af538557e..c82de71282 100644 --- a/include/llvm/MC/MCSectionELF.h +++ b/include/llvm/MC/MCSectionELF.h @@ -15,6 +15,7 @@ #define LLVM_MC_MCSECTIONELF_H #include "llvm/MC/MCSection.h" +#include "llvm/Support/ELF.h" namespace llvm { @@ -54,131 +55,6 @@ public: /// should be printed before the section name bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const; - /// HasCommonSymbols - True if this section holds common symbols, this is - /// indicated on the ELF object file by a symbol with SHN_COMMON section - /// header index. - bool HasCommonSymbols() const; - - /// These are the section type and flags fields. An ELF section can have - /// only one Type, but can have more than one of the flags specified. - /// - /// Valid section types. - enum { - // This value marks the section header as inactive. - SHT_NULL = 0x00U, - - // Holds information defined by the program, with custom format and meaning. - SHT_PROGBITS = 0x01U, - - // This section holds a symbol table. - SHT_SYMTAB = 0x02U, - - // The section holds a string table. - SHT_STRTAB = 0x03U, - - // The section holds relocation entries with explicit addends. - SHT_RELA = 0x04U, - - // The section holds a symbol hash table. - SHT_HASH = 0x05U, - - // Information for dynamic linking. - SHT_DYNAMIC = 0x06U, - - // The section holds information that marks the file in some way. - SHT_NOTE = 0x07U, - - // A section of this type occupies no space in the file. - SHT_NOBITS = 0x08U, - - // The section holds relocation entries without explicit addends. - SHT_REL = 0x09U, - - // This section type is reserved but has unspecified semantics. - SHT_SHLIB = 0x0AU, - - // This section holds a symbol table. - SHT_DYNSYM = 0x0BU, - - // This section contains an array of pointers to initialization functions. - SHT_INIT_ARRAY = 0x0EU, - - // This section contains an array of pointers to termination functions. - SHT_FINI_ARRAY = 0x0FU, - - // This section contains an array of pointers to functions that are invoked - // before all other initialization functions. - SHT_PREINIT_ARRAY = 0x10U, - - // A section group is a set of sections that are related and that must be - // treated specially by the linker. - SHT_GROUP = 0x11U, - - // This section is associated with a section of type SHT_SYMTAB, when the - // referenced symbol table contain the escape value SHN_XINDEX - SHT_SYMTAB_SHNDX = 0x12U, - - // Start of target-specific flags. - - // Exception Index table - SHT_ARM_EXIDX = 0x70000001U, - // BPABI DLL dynamic linking pre-emption map - SHT_ARM_PREEMPTMAP = 0x70000002U, - // Object file compatibility attributes - SHT_ARM_ATTRIBUTES = 0x70000003U, - SHT_ARM_DEBUGOVERLAY = 0x70000004U, - SHT_ARM_OVERLAYSECTION = 0x70000005U, - - LAST_KNOWN_SECTION_TYPE = SHT_ARM_OVERLAYSECTION - }; - - /// Valid section flags. - enum { - // The section contains data that should be writable. - SHF_WRITE = 0x1U, - - // The section occupies memory during execution. - SHF_ALLOC = 0x2U, - - // The section contains executable machine instructions. - SHF_EXECINSTR = 0x4U, - - // The data in the section may be merged to eliminate duplication. - SHF_MERGE = 0x10U, - - // Elements in the section consist of null-terminated character strings. - SHF_STRINGS = 0x20U, - - // A field in this section holds a section header table index. - SHF_INFO_LINK = 0x40U, - - // Adds special ordering requirements for link editors. - SHF_LINK_ORDER = 0x80U, - - // This section requires special OS-specific processing to avoid incorrect - // behavior. - SHF_OS_NONCONFORMING = 0x100U, - - // This section is a member of a section group. - SHF_GROUP = 0x200U, - - // This section holds Thread-Local Storage. - SHF_TLS = 0x400U, - - - // Start of target-specific flags. - - /// XCORE_SHF_CP_SECTION - All sections with the "c" flag are grouped - /// together by the linker to form the constant pool and the cp register is - /// set to the start of the constant pool by the boot code. - XCORE_SHF_CP_SECTION = 0x800U, - - /// XCORE_SHF_DP_SECTION - All sections with the "d" flag are grouped - /// together by the linker to form the data section and the dp register is - /// set to the start of the section by the boot code. - XCORE_SHF_DP_SECTION = 0x1000U - }; - StringRef getSectionName() const { return SectionName; } unsigned getType() const { return Type; } unsigned getFlags() const { return Flags; } @@ -188,11 +64,12 @@ public: void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS) const; virtual bool UseCodeAlign() const; + virtual bool isVirtualSection() const; /// isBaseAddressKnownZero - We know that non-allocatable sections (like /// debug info) have a base of zero. virtual bool isBaseAddressKnownZero() const { - return (getFlags() & SHF_ALLOC) == 0; + return (getFlags() & ELF::SHF_ALLOC) == 0; } static bool classof(const MCSection *S) { diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h index f409f3253b..7633515f27 100644 --- a/include/llvm/MC/MCSectionMachO.h +++ b/include/llvm/MC/MCSectionMachO.h @@ -166,6 +166,7 @@ public: virtual void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS) const; virtual bool UseCodeAlign() const; + virtual bool isVirtualSection() const; static bool classof(const MCSection *S) { return S->getVariant() == SV_MachO; diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 089650cb88..4fdbc44b25 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -14,8 +14,10 @@ #ifndef LLVM_MC_MCSTREAMER_H #define LLVM_MC_MCSTREAMER_H -#include "llvm/System/DataTypes.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/DataTypes.h" #include "llvm/MC/MCDirectives.h" +#include "llvm/MC/MCDwarf.h" namespace llvm { class MCAsmInfo; @@ -28,6 +30,7 @@ namespace llvm { class MCSymbol; class StringRef; class TargetAsmBackend; + class TargetLoweringObjectFile; class Twine; class raw_ostream; class formatted_raw_ostream; @@ -47,22 +50,34 @@ namespace llvm { MCStreamer(const MCStreamer&); // DO NOT IMPLEMENT MCStreamer &operator=(const MCStreamer&); // DO NOT IMPLEMENT - protected: - MCStreamer(MCContext &Ctx); + void EmitSymbolValue(const MCSymbol *Sym, unsigned Size, + bool isPCRel, unsigned AddrSpace); - /// CurSection - This is the current section code is being emitted to, it is - /// kept up to date by SwitchSection. - const MCSection *CurSection; + std::vector<MCDwarfFrameInfo> FrameInfos; + MCDwarfFrameInfo *getCurrentFrameInfo(); + void EnsureValidFrame(); - /// PrevSection - This is the previous section code is being emitted to, it - /// is kept up to date by SwitchSection. - const MCSection *PrevSection; + /// SectionStack - This is stack of current and previous section + /// values saved by PushSection. + SmallVector<std::pair<const MCSection *, + const MCSection *>, 4> SectionStack; + + protected: + MCStreamer(MCContext &Ctx); public: virtual ~MCStreamer(); MCContext &getContext() const { return Context; } + unsigned getNumFrameInfos() { + return FrameInfos.size(); + } + + const MCDwarfFrameInfo &getFrameInfo(unsigned i) { + return FrameInfos[i]; + } + /// @name Assembly File Formatting. /// @{ @@ -98,17 +113,61 @@ 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); + } + } /// InitSections - Create the default sections and set the initial one. virtual void InitSections() = 0; @@ -240,14 +299,25 @@ 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, + bool isPCRel, unsigned AddrSpace) = 0; + + void EmitValue(const MCExpr *Value, unsigned Size, unsigned AddrSpace = 0); + + void EmitPCRelValue(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. virtual void EmitIntValue(uint64_t Value, unsigned Size, unsigned AddrSpace = 0); + /// EmitAbsValue - Emit the Value, but try to avoid relocations. On MachO + /// this is done by producing + /// foo = value + /// .long foo + void EmitAbsValue(const MCExpr *Value, unsigned Size, + unsigned AddrSpace = 0); virtual void EmitULEB128Value(const MCExpr *Value, unsigned AddrSpace = 0) = 0; @@ -257,23 +327,26 @@ namespace llvm { /// EmitULEB128Value - Special case of EmitULEB128Value that avoids the /// client having to pass in a MCExpr for constant integers. - virtual void EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace = 0); + void EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace = 0); /// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the /// client having to pass in a MCExpr for constant integers. - virtual void EmitSLEB128IntValue(int64_t Value, unsigned AddrSpace = 0); + void EmitSLEB128IntValue(int64_t Value, unsigned AddrSpace = 0); /// EmitSymbolValue - Special case of EmitValue that avoids the client /// having to pass in a MCExpr for MCSymbols. - virtual void EmitSymbolValue(const MCSymbol *Sym, unsigned Size, - unsigned AddrSpace = 0); + void EmitSymbolValue(const MCSymbol *Sym, unsigned Size, + unsigned AddrSpace = 0); + + void EmitPCRelSymbolValue(const MCSymbol *Sym, unsigned Size, + unsigned AddrSpace = 0); /// EmitGPRel32Value - Emit the expression @p Value into the output as a /// gprel32 (32-bit GP relative) value. /// /// This is used to implement assembler directives such as .gprel32 on /// targets that support them. - virtual void EmitGPRel32Value(const MCExpr *Value) = 0; + virtual void EmitGPRel32Value(const MCExpr *Value); /// EmitFill - Emit NumBytes bytes worth of the value specified by /// FillValue. This implements directives such as '.space'. @@ -342,7 +415,37 @@ namespace llvm { /// EmitDwarfFileDirective - Associate a filename with a specified logical /// file number. This implements the DWARF2 '.file 4 "foo.c"' assembler /// directive. - virtual void EmitDwarfFileDirective(unsigned FileNo,StringRef Filename) = 0; + virtual bool EmitDwarfFileDirective(unsigned FileNo,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); + + virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta, + const MCSymbol *LastLabel, + const MCSymbol *Label) = 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 EmitCFIDefCfa(int64_t Register, int64_t Offset); + 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, + unsigned Encoding); + virtual bool EmitCFILsda(const MCSymbol *Sym, unsigned Encoding); + virtual bool EmitCFIRememberState(); + virtual bool EmitCFIRestoreState(); /// EmitInstruction - Emit the given @p Instruction into the current /// section. @@ -354,6 +457,19 @@ 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<unsigned> &RegList, + bool isVector); + /// Finish - Finish emission of machine code. virtual void Finish() = 0; }; @@ -373,12 +489,18 @@ namespace llvm { /// \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. /// + /// \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 \arg 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, MCInstPrinter *InstPrint = 0, MCCodeEmitter *CE = 0, + TargetAsmBackend *TAB = 0, bool ShowInst = false); /// createMachOStreamer - Create a machine code streamer which will generate @@ -402,7 +524,7 @@ namespace llvm { /// ELF format object files. MCStreamer *createELFStreamer(MCContext &Ctx, TargetAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *CE, - bool RelaxAll = false); + bool RelaxAll, bool NoExecStack); /// createLoggingStreamer - Create a machine code streamer which just logs the /// API calls and then dispatches to another streamer. @@ -410,6 +532,13 @@ namespace llvm { /// The new streamer takes ownership of the \arg Child. MCStreamer *createLoggingStreamer(MCStreamer *Child, raw_ostream &OS); + /// 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, + raw_ostream &OS, MCCodeEmitter *CE); + } // end namespace llvm #endif diff --git a/include/llvm/MC/MCValue.h b/include/llvm/MC/MCValue.h index 11b6c2a17b..df8dbd930b 100644 --- a/include/llvm/MC/MCValue.h +++ b/include/llvm/MC/MCValue.h @@ -14,7 +14,7 @@ #ifndef LLVM_MC_MCVALUE_H #define LLVM_MC_MCVALUE_H -#include "llvm/System/DataTypes.h" +#include "llvm/Support/DataTypes.h" #include "llvm/MC/MCSymbol.h" #include <cassert> |