diff options
Diffstat (limited to 'include/llvm/MC')
-rw-r--r-- | include/llvm/MC/MCAsmInfo.h | 9 | ||||
-rw-r--r-- | include/llvm/MC/MCAsmLayout.h | 36 | ||||
-rw-r--r-- | include/llvm/MC/MCAssembler.h | 100 | ||||
-rw-r--r-- | include/llvm/MC/MCContext.h | 20 | ||||
-rw-r--r-- | include/llvm/MC/MCExpr.h | 66 | ||||
-rw-r--r-- | include/llvm/MC/MCParser/AsmParser.h | 3 | ||||
-rw-r--r-- | include/llvm/MC/MCParser/MCAsmParser.h | 1 | ||||
-rw-r--r-- | include/llvm/MC/MCSection.h | 2 | ||||
-rw-r--r-- | include/llvm/MC/MCSectionELF.h | 11 | ||||
-rw-r--r-- | include/llvm/MC/MCSectionMachO.h | 8 | ||||
-rw-r--r-- | include/llvm/MC/MCStreamer.h | 16 | ||||
-rw-r--r-- | include/llvm/MC/MCSymbol.h | 13 |
12 files changed, 238 insertions, 47 deletions
diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index 7e0c8a5..4dfe9f0 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -145,6 +145,11 @@ namespace llvm { /// which doesn't support the '.bss' directive only. bool UsesELFSectionDirectiveForBSS; // Defaults to false. + /// HasMicrosoftFastStdCallMangling - True if this target uses microsoft + /// style mangling for functions with X86_StdCall/X86_FastCall calling + /// convention. + bool HasMicrosoftFastStdCallMangling; // Defaults to false. + //===--- Alignment Information ----------------------------------------===// /// AlignDirective - The directive used to emit round up to an alignment @@ -295,6 +300,10 @@ namespace llvm { return UsesELFSectionDirectiveForBSS; } + bool hasMicrosoftFastStdCallMangling() const { + return HasMicrosoftFastStdCallMangling; + } + // Accessors. // bool hasMachoZeroFillDirective() const { return HasMachoZeroFillDirective; } diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h new file mode 100644 index 0000000..27bdbe9 --- /dev/null +++ b/include/llvm/MC/MCAsmLayout.h @@ -0,0 +1,36 @@ +//===- MCAsmLayout.h - Assembly Layout Object -------------------*- 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_MCASMLAYOUT_H +#define LLVM_MC_MCASMLAYOUT_H + +namespace llvm { +class MCAssembler; + +/// Encapsulates the layout of an assembly file at a particular point in time. +/// +/// Assembly may requiring compute multiple layouts for a particular assembly +/// file as part of the relaxation process. This class encapsulates the layout +/// at a single point in time in such a way that it is always possible to +/// efficiently compute the exact addresses of any symbol in the assembly file, +/// even during the relaxation process. +class MCAsmLayout { +private: + MCAssembler &Assembler; + +public: + MCAsmLayout(MCAssembler &_Assembler) : Assembler(_Assembler) {} + + /// Get the assembler object this is a layout for. + MCAssembler &getAssembler() const { return Assembler; } +}; + +} // end namespace llvm + +#endif diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index 882929f..1d8051f 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -10,6 +10,7 @@ #ifndef LLVM_MC_MCASSEMBLER_H #define LLVM_MC_MCASSEMBLER_H +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/ilist.h" #include "llvm/ADT/ilist_node.h" @@ -20,6 +21,7 @@ namespace llvm { class raw_ostream; +class MCAsmLayout; class MCAssembler; class MCContext; class MCExpr; @@ -27,6 +29,8 @@ class MCFragment; class MCSection; class MCSectionData; class MCSymbol; +class MCValue; +class TargetAsmBackend; /// MCAsmFixup - Represent a fixed size region of bytes inside some fragment /// which needs to be rewritten. This region will either be rewritten by the @@ -160,6 +164,13 @@ public: /// @name Fixup Access /// @{ + void addFixup(MCAsmFixup Fixup) { + // Enforce invariant that fixups are in offset order. + assert((Fixups.empty() || Fixup.Offset > Fixups.back().Offset) && + "Fixups must be added in order!"); + Fixups.push_back(Fixup); + } + std::vector<MCAsmFixup> &getFixups() { return Fixups; } const std::vector<MCAsmFixup> &getFixups() const { return Fixups; } @@ -195,7 +206,8 @@ class MCAlignFragment : public MCFragment { /// cannot be satisfied in this width then this fragment is ignored. unsigned MaxBytesToEmit; - /// EmitNops - true when aligning code and optimal nops to be used for filling + /// EmitNops - true when aligning code and optimal nops to be used for + /// filling. bool EmitNops; public: @@ -505,6 +517,11 @@ public: uint64_t getOffset() const { return Offset; } void setOffset(uint64_t Value) { Offset = Value; } + uint64_t getAddress() const { + assert(getFragment() && "Invalid getAddress() on undefined symbol!"); + return getFragment()->getAddress() + getOffset(); + } + /// @} /// @name Symbol Attributes /// @{ @@ -581,22 +598,61 @@ private: MCContext &Context; + TargetAsmBackend &Backend; + raw_ostream &OS; iplist<MCSectionData> Sections; iplist<MCSymbolData> Symbols; + /// The map of sections to their associated assembler backend data. + // + // FIXME: Avoid this indirection? + DenseMap<const MCSection*, MCSectionData*> SectionMap; + + /// The map of symbols to their associated assembler backend data. + // + // FIXME: Avoid this indirection? + DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap; + std::vector<IndirectSymbolData> IndirectSymbols; unsigned SubsectionsViaSymbols : 1; private: + /// 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(MCAsmFixup &Fixup, MCDataFragment *DF); + /// LayoutSection - Assign offsets and sizes to the fragments in the section /// \arg SD, and update the section size. The section file offset should /// already have been computed. void LayoutSection(MCSectionData &SD); + /// LayoutOnce - Perform one layout iteration and return true if any offsets + /// were adjusted. + bool LayoutOnce(); + + // FIXME: Make protected once we factor out object writer classes. +public: + /// Evaluate a fixup to a relocatable expression and the value which should be + /// placed into the fixup. + /// + /// \param Layout The layout to use for evaluation. + /// \param Fixup The fixup to evaluate. + /// \param DF The fragment the fixup is inside. + /// \param Target [out] On return, the relocatable expression the fixup + /// evaluates to. + /// \param Value [out] On return, the value of the fixup as currently layed + /// out. + /// \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 MCAsmLayout &Layout, + MCAsmFixup &Fixup, MCDataFragment *DF, + MCValue &Target, uint64_t &Value) const; + public: /// Construct a new assembler instance. /// @@ -606,11 +662,13 @@ 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, raw_ostream &OS); + MCAssembler(MCContext &_Context, TargetAsmBackend &_Backend, raw_ostream &OS); ~MCAssembler(); MCContext &getContext() const { return Context; } + TargetAsmBackend &getBackend() const { return Backend; } + /// Finish - Do final processing and write the object to the output stream. void Finish(); @@ -673,6 +731,44 @@ public: size_t indirect_symbol_size() const { return IndirectSymbols.size(); } /// @} + /// @name Backend Data Access + /// @{ + + MCSectionData &getSectionData(const MCSection &Section) const { + MCSectionData *Entry = SectionMap.lookup(&Section); + assert(Entry && "Missing section data!"); + return *Entry; + } + + MCSectionData &getOrCreateSectionData(const MCSection &Section, + bool *Created = 0) { + MCSectionData *&Entry = SectionMap[&Section]; + + if (Created) *Created = !Entry; + if (!Entry) + Entry = new MCSectionData(Section, this); + + return *Entry; + } + + MCSymbolData &getSymbolData(const MCSymbol &Symbol) const { + MCSymbolData *Entry = SymbolMap.lookup(&Symbol); + assert(Entry && "Missing symbol data!"); + return *Entry; + } + + MCSymbolData &getOrCreateSymbolData(const MCSymbol &Symbol, + bool *Created = 0) { + MCSymbolData *&Entry = SymbolMap[&Symbol]; + + if (Created) *Created = !Entry; + if (!Entry) + Entry = new MCSymbolData(Symbol, 0, 0, this); + + return *Entry; + } + + /// @} void dump(); }; diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index f2f1456..85114e3 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -15,6 +15,7 @@ #include "llvm/Support/Allocator.h" namespace llvm { + class MCAsmInfo; class MCExpr; class MCSection; class MCSymbol; @@ -28,31 +29,44 @@ namespace llvm { MCContext(const MCContext&); // DO NOT IMPLEMENT MCContext &operator=(const MCContext&); // DO NOT IMPLEMENT + /// The MCAsmInfo for this target. + const MCAsmInfo &MAI; + /// Sections - Bindings of names to allocated sections. StringMap<MCSection*> Sections; /// Symbols - Bindings of names to symbols. StringMap<MCSymbol*> Symbols; + /// NextUniqueID - The next ID to dole out to an unnamed assembler temporary + /// symbol. + unsigned NextUniqueID; + /// 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; public: - MCContext(); + explicit MCContext(const MCAsmInfo &MAI); ~MCContext(); + + const MCAsmInfo &getAsmInfo() const { return MAI; } /// @name Symbol Managment /// @{ + + /// CreateTempSymbol - Create and return a new assembler temporary symbol + /// with a unique but unspecified name. + MCSymbol *CreateTempSymbol(); /// GetOrCreateSymbol - Lookup the symbol inside with the specified /// @p Name. If it exists, return it. If not, create a forward /// reference and return it. /// /// @param Name - The symbol name, which must be unique across all symbols. - MCSymbol *GetOrCreateSymbol(StringRef Name); - MCSymbol *GetOrCreateSymbol(const Twine &Name); + MCSymbol *GetOrCreateSymbol(StringRef Name, bool isTemporary = false); + MCSymbol *GetOrCreateSymbol(const Twine &Name, bool isTemporary = false); /// GetOrCreateTemporarySymbol - Create a new assembler temporary symbol /// with the specified @p Name if it doesn't exist or return the existing diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index 3f17492..6efec52 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -15,6 +15,7 @@ namespace llvm { class MCAsmInfo; +class MCAsmLayout; class MCContext; class MCSymbol; class MCValue; @@ -62,21 +63,25 @@ public: /// EvaluateAsAbsolute - Try to evaluate the expression to an absolute value. /// /// @param Res - The absolute value, if evaluation succeeds. + /// @param Layout - The assembler layout object to use for evaluating symbol + /// values. If not given, then only non-symbolic expressions will be + /// evaluated. /// @result - True on success. - bool EvaluateAsAbsolute(int64_t &Res) const; + bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout *Layout = 0) const; /// EvaluateAsRelocatable - Try to evaluate the expression to a relocatable /// value, i.e. an expression of the fixed form (a - b + constant). /// /// @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; + bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout = 0) const; /// @} static bool classof(const MCExpr *) { return true; } }; - + inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) { E.print(OS); return OS; @@ -116,21 +121,49 @@ public: /// assembler variable (defined constant), or constitute an implicit definition /// of the symbol as external. class MCSymbolRefExpr : public MCExpr { +public: + enum VariantKind { + VK_None, + VK_Invalid, + + VK_GOT, + VK_GOTOFF, + VK_GOTPCREL, + VK_GOTTPOFF, + VK_INDNTPOFF, + VK_NTPOFF, + VK_PLT, + VK_TLSGD, + VK_TPOFF + }; + +private: + /// The symbol being referenced. const MCSymbol *Symbol; - explicit MCSymbolRefExpr(const MCSymbol *_Symbol) - : MCExpr(MCExpr::SymbolRef), Symbol(_Symbol) {} + /// The symbol reference modifier. + const VariantKind Kind; + + explicit MCSymbolRefExpr(const MCSymbol *_Symbol, VariantKind _Kind) + : MCExpr(MCExpr::SymbolRef), Symbol(_Symbol), Kind(_Kind) {} public: /// @name Construction /// @{ - static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, MCContext &Ctx); - static const MCSymbolRefExpr *Create(StringRef Name, MCContext &Ctx); + static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, MCContext &Ctx) { + return MCSymbolRefExpr::Create(Symbol, VK_None, Ctx); + } + + static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, VariantKind Kind, + MCContext &Ctx); + static const MCSymbolRefExpr *Create(StringRef Name, VariantKind Kind, + MCContext &Ctx); /// CreateTemp - Create a reference to an assembler temporary label with the /// specified name. - static const MCSymbolRefExpr *CreateTemp(StringRef Name, MCContext &Ctx); + static const MCSymbolRefExpr *CreateTemp(StringRef Name, VariantKind Kind, + MCContext &Ctx); /// @} /// @name Accessors @@ -138,6 +171,16 @@ public: const MCSymbol &getSymbol() const { return *Symbol; } + VariantKind getKind() const { return Kind; } + + /// @} + /// @name Static Utility Functions + /// @{ + + static StringRef getVariantKindName(VariantKind Kind); + + static VariantKind getVariantKindForName(StringRef Name); + /// @} static bool classof(const MCExpr *E) { @@ -346,11 +389,12 @@ protected: MCTargetExpr() : MCExpr(Target) {} virtual ~MCTargetExpr() {} public: - + virtual void PrintImpl(raw_ostream &OS) const = 0; - virtual bool EvaluateAsRelocatableImpl(MCValue &Res) const = 0; + virtual bool EvaluateAsRelocatableImpl(MCValue &Res, + const MCAsmLayout *Layout) const = 0; + - static bool classof(const MCExpr *E) { return E->getKind() == MCExpr::Target; } diff --git a/include/llvm/MC/MCParser/AsmParser.h b/include/llvm/MC/MCParser/AsmParser.h index 829604c..06e0920 100644 --- a/include/llvm/MC/MCParser/AsmParser.h +++ b/include/llvm/MC/MCParser/AsmParser.h @@ -31,7 +31,6 @@ class MCExpr; class MCInst; class MCStreamer; class MCAsmInfo; -class MCValue; class SourceMgr; class TargetAsmParser; class Twine; @@ -65,7 +64,7 @@ public: const MCAsmInfo &MAI); ~AsmParser(); - bool Run(); + bool Run(bool NoInitialTextSection); void AddDirectiveHandler(StringRef Directive, diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h index 843c692..7f7f1b6 100644 --- a/include/llvm/MC/MCParser/MCAsmParser.h +++ b/include/llvm/MC/MCParser/MCAsmParser.h @@ -18,7 +18,6 @@ class MCAsmLexer; class MCContext; class MCExpr; class MCStreamer; -class MCValue; class SMLoc; class Twine; diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h index ceb6d27..3d8815a 100644 --- a/include/llvm/MC/MCSection.h +++ b/include/llvm/MC/MCSection.h @@ -42,6 +42,8 @@ namespace llvm { }; class MCSectionCOFF : public MCSection { + // FIXME: This memory is leaked because MCSectionCOFF is bump pointer + // allocated and this never gets freed. std::string Name; /// IsDirective - This is true if the section name is a directive, not diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h index 2dccf5c..cdd2f73 100644 --- a/include/llvm/MC/MCSectionELF.h +++ b/include/llvm/MC/MCSectionELF.h @@ -21,7 +21,9 @@ namespace llvm { /// MCSectionELF - This represents a section on linux, lots of unix variants /// and some bare metal systems. class MCSectionELF : public MCSection { - std::string SectionName; + /// SectionName - This is the name of the section. The referenced memory is + /// owned by TargetLoweringObjectFileELF's ELFUniqueMap. + StringRef SectionName; /// Type - This is the sh_type field of a section, drawn from the enums below. unsigned Type; @@ -37,7 +39,7 @@ class MCSectionELF : public MCSection { protected: MCSectionELF(StringRef Section, unsigned type, unsigned flags, SectionKind K, bool isExplicit) - : MCSection(K), SectionName(Section.str()), Type(type), Flags(flags), + : MCSection(K), SectionName(Section), Type(type), Flags(flags), IsExplicit(isExplicit) {} public: @@ -163,10 +165,7 @@ public: TARGET_INDEP_SHF = FIRST_TARGET_DEP_FLAG-1U }; - StringRef getSectionName() const { - return StringRef(SectionName); - } - + StringRef getSectionName() const { return SectionName; } unsigned getType() const { return Type; } unsigned getFlags() const { return Flags; } diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h index 6156819..5839c28 100644 --- a/include/llvm/MC/MCSectionMachO.h +++ b/include/llvm/MC/MCSectionMachO.h @@ -151,10 +151,12 @@ public: return StringRef(SectionName, 16); return StringRef(SectionName); } - + unsigned getTypeAndAttributes() const { return TypeAndAttributes; } unsigned getStubSize() const { return Reserved2; } - + + unsigned getType() const { return TypeAndAttributes & SECTION_TYPE; } + /// ParseSectionSpecifier - Parse the section specifier indicated by "Spec". /// This is a string that can appear after a .section directive in a mach-o /// flavored .s file. If successful, this fills in the specified Out @@ -165,7 +167,7 @@ public: StringRef &Section, // Out. unsigned &TAA, // Out. unsigned &StubSize); // Out. - + virtual void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS) const; }; diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 6359cce..47befca 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -27,6 +27,7 @@ namespace llvm { class MCSection; class MCSymbol; class StringRef; +class TargetAsmBackend; class Twine; class raw_ostream; class formatted_raw_ostream; @@ -298,24 +299,15 @@ namespace llvm { /// \param ShowInst - Whether to show the MCInst representation inline with /// the assembly. MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, - const MCAsmInfo &MAI, bool isLittleEndian, - bool isVerboseAsm, + bool isLittleEndian, bool isVerboseAsm, MCInstPrinter *InstPrint = 0, MCCodeEmitter *CE = 0, bool ShowInst = false); - // FIXME: These two may end up getting rolled into a single - // createObjectStreamer interface, which implements the assembler backend, and - // is parameterized on an output object file writer. - /// createMachOStream - Create a machine code streamer which will generative /// Mach-O format object files. - MCStreamer *createMachOStreamer(MCContext &Ctx, raw_ostream &OS, - MCCodeEmitter *CE); - - /// createELFStreamer - Create a machine code streamer which will generative - /// ELF format object files. - MCStreamer *createELFStreamer(MCContext &Ctx, raw_ostream &OS); + MCStreamer *createMachOStreamer(MCContext &Ctx, TargetAsmBackend &TAB, + raw_ostream &OS, MCCodeEmitter *CE); } // end namespace llvm diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h index d5c4d95..e41eb2a 100644 --- a/include/llvm/MC/MCSymbol.h +++ b/include/llvm/MC/MCSymbol.h @@ -14,9 +14,7 @@ #ifndef LLVM_MC_MCSYMBOL_H #define LLVM_MC_MCSYMBOL_H -#include <string> #include "llvm/ADT/StringRef.h" -#include "llvm/System/DataTypes.h" namespace llvm { class MCExpr; @@ -38,8 +36,9 @@ namespace llvm { // FIXME: Use a PointerInt wrapper for this? static const MCSection *AbsolutePseudoSection; - /// Name - The name of the symbol. - std::string Name; + /// Name - The name of the symbol. The referred-to string data is actually + /// held by the StringMap that lives in MCContext. + StringRef Name; /// Section - The section the symbol is defined in. This is null for /// undefined symbols, and the special AbsolutePseudoSection value for @@ -56,14 +55,14 @@ namespace llvm { private: // MCContext creates and uniques these. friend class MCContext; - MCSymbol(StringRef _Name, bool _IsTemporary) - : Name(_Name), Section(0), Value(0), IsTemporary(_IsTemporary) {} + MCSymbol(StringRef name, bool isTemporary) + : Name(name), Section(0), Value(0), IsTemporary(isTemporary) {} MCSymbol(const MCSymbol&); // DO NOT IMPLEMENT void operator=(const MCSymbol&); // DO NOT IMPLEMENT public: /// getName - Get the symbol name. - const std::string &getName() const { return Name; } + StringRef getName() const { return Name; } /// @name Symbol Type /// @{ |