diff options
Diffstat (limited to 'include/llvm/MC')
40 files changed, 1314 insertions, 457 deletions
diff --git a/include/llvm/MC/EDInstInfo.h b/include/llvm/MC/EDInstInfo.h deleted file mode 100644 index 5b02467..0000000 --- a/include/llvm/MC/EDInstInfo.h +++ /dev/null @@ -1,29 +0,0 @@ -//===-- llvm/MC/EDInstInfo.h - EDis instruction info ------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -#ifndef EDINSTINFO_H -#define EDINSTINFO_H - -#include "llvm/Support/DataTypes.h" - -namespace llvm { - -#define EDIS_MAX_OPERANDS 13 -#define EDIS_MAX_SYNTAXES 2 - -struct EDInstInfo { - uint8_t instructionType; - uint8_t numOperands; - uint8_t operandTypes[EDIS_MAX_OPERANDS]; - uint8_t operandFlags[EDIS_MAX_OPERANDS]; - const signed char operandOrders[EDIS_MAX_SYNTAXES][EDIS_MAX_OPERANDS]; -}; - -} // namespace llvm - -#endif diff --git a/include/llvm/MC/MCAsmBackend.h b/include/llvm/MC/MCAsmBackend.h index 1c45090..9a6b703 100644 --- a/include/llvm/MC/MCAsmBackend.h +++ b/include/llvm/MC/MCAsmBackend.h @@ -22,7 +22,7 @@ class MCELFObjectTargetWriter; struct MCFixupKindInfo; class MCFragment; class MCInst; -class MCInstFragment; +class MCRelaxableFragment; class MCObjectWriter; class MCSection; class MCValue; @@ -36,10 +36,14 @@ protected: // Can only create subclasses. MCAsmBackend(); unsigned HasReliableSymbolDifference : 1; + unsigned HasDataInCodeSupport : 1; public: virtual ~MCAsmBackend(); + /// lifetime management + virtual void reset() { } + /// createObjectWriter - Create a new MCObjectWriter instance for use by the /// assembler backend to emit the final object file. virtual MCObjectWriter *createObjectWriter(raw_ostream &OS) const = 0; @@ -65,6 +69,12 @@ public: return HasReliableSymbolDifference; } + /// hasDataInCodeSupport - Check whether this target implements data-in-code + /// markers. If not, data region directives will be ignored. + bool hasDataInCodeSupport() const { + return HasDataInCodeSupport; + } + /// doesSectionRequireSymbols - Check whether the given section requires that /// all symbols (even temporaries) have symbol table entries. virtual bool doesSectionRequireSymbols(const MCSection &Section) const { @@ -99,7 +109,7 @@ public: /// @} - /// applyFixup - Apply the \arg Value for given \arg Fixup into the provided + /// applyFixup - Apply the \p Value for given \p Fixup into the provided /// data fragment, at the offset specified by the fixup and following the /// fixup kind as appropriate. virtual void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, @@ -120,15 +130,15 @@ public: /// fixup requires the associated instruction to be relaxed. virtual bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, - const MCInstFragment *DF, + const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const = 0; /// RelaxInstruction - Relax the instruction in the given fragment to the next /// wider instruction. /// - /// \param Inst - The instruction to relax, which may be the same as the + /// \param Inst The instruction to relax, which may be the same as the /// output. - /// \parm Res [output] - On return, the relaxed instruction. + /// \param [out] Res On return, the relaxed instruction. virtual void relaxInstruction(const MCInst &Inst, MCInst &Res) const = 0; /// @} diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index 97aad71..38cf060 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -16,8 +16,8 @@ #ifndef LLVM_TARGET_ASM_INFO_H #define LLVM_TARGET_ASM_INFO_H -#include "llvm/MC/MachineLocation.h" #include "llvm/MC/MCDirectives.h" +#include "llvm/MC/MachineLocation.h" #include <cassert> #include <vector> @@ -102,6 +102,9 @@ namespace llvm { /// LabelSuffix - This is appended to emitted labels. const char *LabelSuffix; // Defaults to ":" + /// LabelSuffix - This is appended to emitted labels. + const char *DebugLabelSuffix; // Defaults to ":" + /// GlobalPrefix - If this is set to a non-empty string, it is prepended /// onto all global symbols. This is often used for "_" or ".". const char *GlobalPrefix; // Defaults to "" @@ -426,6 +429,11 @@ namespace llvm { const char *getLabelSuffix() const { return LabelSuffix; } + + const char *getDebugLabelSuffix() const { + return DebugLabelSuffix; + } + const char *getGlobalPrefix() const { return GlobalPrefix; } diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h index cf79216..8cb4601 100644 --- a/include/llvm/MC/MCAsmLayout.h +++ b/include/llvm/MC/MCAsmLayout.h @@ -21,10 +21,10 @@ class MCSymbolData; /// Encapsulates the layout of an assembly file at a particular point in time. /// -/// Assembly may requiring compute multiple layouts for a particular assembly +/// Assembly may require computing 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, +/// efficiently compute the exact address of any symbol in the assembly file, /// even during the relaxation process. class MCAsmLayout { public: @@ -39,14 +39,20 @@ private: /// The last fragment which was laid out, or 0 if nothing has been laid /// out. Fragments are always laid out in order, so all fragments with a - /// lower ordinal will be up to date. - mutable DenseMap<const MCSectionData*, MCFragment *> LastValidFragment; + /// lower ordinal will be valid. + 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; + void ensureValid(const MCFragment *F) const; - bool isFragmentUpToDate(const MCFragment *F) const; + /// \brief Is the layout for this fragment valid? + bool isFragmentValid(const MCFragment *F) const; + + /// \brief Compute the amount of padding required before this fragment to + /// obey bundling restrictions. + uint64_t computeBundlePadding(const MCFragment *F, + uint64_t FOffset, uint64_t FSize); public: MCAsmLayout(MCAssembler &_Assembler); @@ -54,14 +60,14 @@ public: /// Get the assembler object this is a layout for. MCAssembler &getAssembler() const { return Assembler; } - /// \brief Invalidate all following fragments because a fragment has been - /// resized. The fragments size should have already been updated. - void Invalidate(MCFragment *F); + /// \brief Invalidate the fragments after F because it has been resized. + /// The fragment's size should have already been updated. + void invalidateFragmentsAfter(MCFragment *F); /// \brief Perform layout for a single fragment, assuming that the previous /// fragment has already been laid out correctly, and the parent section has /// been initialized. - void LayoutFragment(MCFragment *Fragment); + void layoutFragment(MCFragment *Fragment); /// @name Section Access (in layout order) /// @{ diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index 1858349..40766b4 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -10,13 +10,13 @@ #ifndef LLVM_MC_MCASSEMBLER_H #define LLVM_MC_MCASSEMBLER_H -#include "llvm/MC/MCFixup.h" -#include "llvm/MC/MCInst.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/MC/MCFixup.h" +#include "llvm/MC/MCInst.h" #include "llvm/Support/Casting.h" #include "llvm/Support/DataTypes.h" #include <vector> // FIXME: Shouldn't be needed. @@ -53,7 +53,7 @@ public: FT_Align, FT_Data, FT_Fill, - FT_Inst, + FT_Relaxable, FT_Org, FT_Dwarf, FT_DwarfFrame, @@ -107,44 +107,107 @@ public: unsigned getLayoutOrder() const { return LayoutOrder; } void setLayoutOrder(unsigned Value) { LayoutOrder = Value; } - static bool classof(const MCFragment *O) { return true; } + /// \brief Does this fragment have instructions emitted into it? By default + /// this is false, but specific fragment types may set it to true. + virtual bool hasInstructions() const { return false; } + + /// \brief Should this fragment be placed at the end of an aligned bundle? + virtual bool alignToBundleEnd() const { return false; } + + /// \brief Get the padding size that must be inserted before this fragment. + /// Used for bundling. By default, no padding is inserted. + /// Note that padding size is restricted to 8 bits. This is an optimization + /// to reduce the amount of space used for each fragment. In practice, larger + /// padding should never be required. + virtual uint8_t getBundlePadding() const { + return 0; + } + + /// \brief Set the padding size for this fragment. By default it's a no-op, + /// and only some fragments have a meaningful implementation. + virtual void setBundlePadding(uint8_t N) { + } void dump(); }; -class MCDataFragment : public MCFragment { +class MCEncodedFragment : public MCFragment { virtual void anchor(); - SmallString<32> Contents; - - /// Fixups - The list of fixups in this fragment. - std::vector<MCFixup> Fixups; + uint8_t BundlePadding; public: - typedef std::vector<MCFixup>::const_iterator const_fixup_iterator; - typedef std::vector<MCFixup>::iterator fixup_iterator; + MCEncodedFragment(MCFragment::FragmentType FType, MCSectionData *SD = 0) + : MCFragment(FType, SD), BundlePadding(0) + { + } + virtual ~MCEncodedFragment(); -public: - MCDataFragment(MCSectionData *SD = 0) : MCFragment(FT_Data, SD) {} + typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator; + typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator; - /// @name Accessors - /// @{ + virtual SmallVectorImpl<char> &getContents() = 0; + virtual const SmallVectorImpl<char> &getContents() const = 0; - SmallString<32> &getContents() { return Contents; } - const SmallString<32> &getContents() const { return Contents; } + virtual SmallVectorImpl<MCFixup> &getFixups() = 0; + virtual const SmallVectorImpl<MCFixup> &getFixups() const = 0; - /// @} - /// @name Fixup Access - /// @{ + virtual fixup_iterator fixup_begin() = 0; + virtual const_fixup_iterator fixup_begin() const = 0; + virtual fixup_iterator fixup_end() = 0; + virtual const_fixup_iterator fixup_end() const = 0; + + virtual uint8_t getBundlePadding() const { + return BundlePadding; + } - void addFixup(MCFixup Fixup) { - // Enforce invariant that fixups are in offset order. - assert((Fixups.empty() || Fixup.getOffset() >= Fixups.back().getOffset()) && - "Fixups must be added in order!"); - Fixups.push_back(Fixup); + virtual void setBundlePadding(uint8_t N) { + BundlePadding = N; } - std::vector<MCFixup> &getFixups() { return Fixups; } - const std::vector<MCFixup> &getFixups() const { return Fixups; } + static bool classof(const MCFragment *F) { + MCFragment::FragmentType Kind = F->getKind(); + return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data; + } +}; + +/// Fragment for data and encoded instructions. +/// +class MCDataFragment : public MCEncodedFragment { + virtual void anchor(); + + /// \brief Does this fragment contain encoded instructions anywhere in it? + bool HasInstructions; + + /// \brief Should this fragment be aligned to the end of a bundle? + bool AlignToBundleEnd; + + SmallVector<char, 32> Contents; + + /// Fixups - The list of fixups in this fragment. + SmallVector<MCFixup, 4> Fixups; +public: + MCDataFragment(MCSectionData *SD = 0) + : MCEncodedFragment(FT_Data, SD), + HasInstructions(false), AlignToBundleEnd(false) + { + } + + virtual SmallVectorImpl<char> &getContents() { return Contents; } + virtual const SmallVectorImpl<char> &getContents() const { return Contents; } + + SmallVectorImpl<MCFixup> &getFixups() { + return Fixups; + } + + const SmallVectorImpl<MCFixup> &getFixups() const { + return Fixups; + } + + virtual bool hasInstructions() const { return HasInstructions; } + virtual void setHasInstructions(bool V) { HasInstructions = V; } + + virtual bool alignToBundleEnd() const { return AlignToBundleEnd; } + virtual void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; } fixup_iterator fixup_begin() { return Fixups.begin(); } const_fixup_iterator fixup_begin() const { return Fixups.begin(); } @@ -152,61 +215,46 @@ public: fixup_iterator fixup_end() {return Fixups.end();} const_fixup_iterator fixup_end() const {return Fixups.end();} - size_t fixup_size() const { return Fixups.size(); } - - /// @} - static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_Data; } - static bool classof(const MCDataFragment *) { return true; } }; -// FIXME: This current incarnation of MCInstFragment doesn't make much sense, as -// it is almost entirely a duplicate of MCDataFragment. If we decide to stick -// with this approach (as opposed to making MCInstFragment a very light weight -// object with just the MCInst and a code size, then we should just change -// MCDataFragment to have an optional MCInst at its end. -class MCInstFragment : public MCFragment { +/// A relaxable fragment holds on to its MCInst, since it may need to be +/// relaxed during the assembler layout and relaxation stage. +/// +class MCRelaxableFragment : public MCEncodedFragment { virtual void anchor(); /// Inst - The instruction this is a fragment for. MCInst Inst; - /// Code - Binary data for the currently encoded instruction. - SmallString<8> Code; + /// Contents - Binary data for the currently encoded instruction. + SmallVector<char, 8> Contents; /// Fixups - The list of fixups in this fragment. SmallVector<MCFixup, 1> Fixups; public: - typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator; - typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator; - -public: - MCInstFragment(const MCInst &_Inst, MCSectionData *SD = 0) - : MCFragment(FT_Inst, SD), Inst(_Inst) { + MCRelaxableFragment(const MCInst &_Inst, MCSectionData *SD = 0) + : MCEncodedFragment(FT_Relaxable, SD), Inst(_Inst) { } - /// @name Accessors - /// @{ - - SmallVectorImpl<char> &getCode() { return Code; } - const SmallVectorImpl<char> &getCode() const { return Code; } - - unsigned getInstSize() const { return Code.size(); } + virtual SmallVectorImpl<char> &getContents() { return Contents; } + virtual const SmallVectorImpl<char> &getContents() const { return Contents; } - MCInst &getInst() { return Inst; } const MCInst &getInst() const { return Inst; } - void setInst(const MCInst& Value) { Inst = Value; } - /// @} - /// @name Fixup Access - /// @{ + SmallVectorImpl<MCFixup> &getFixups() { + return Fixups; + } - SmallVectorImpl<MCFixup> &getFixups() { return Fixups; } - const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; } + const SmallVectorImpl<MCFixup> &getFixups() const { + return Fixups; + } + + virtual bool hasInstructions() const { return true; } fixup_iterator fixup_begin() { return Fixups.begin(); } const_fixup_iterator fixup_begin() const { return Fixups.begin(); } @@ -214,14 +262,9 @@ public: fixup_iterator fixup_end() {return Fixups.end();} const_fixup_iterator fixup_end() const {return Fixups.end();} - size_t fixup_size() const { return Fixups.size(); } - - /// @} - static bool classof(const MCFragment *F) { - return F->getKind() == MCFragment::FT_Inst; + return F->getKind() == MCFragment::FT_Relaxable; } - static bool classof(const MCInstFragment *) { return true; } }; class MCAlignFragment : public MCFragment { @@ -233,7 +276,7 @@ class MCAlignFragment : public MCFragment { /// Value - Value to use for filling padding bytes. int64_t Value; - /// ValueSize - The size of the integer (in bytes) of \arg Value. + /// ValueSize - The size of the integer (in bytes) of \p Value. unsigned ValueSize; /// MaxBytesToEmit - The maximum number of bytes to emit; if the alignment @@ -271,7 +314,6 @@ public: static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_Align; } - static bool classof(const MCAlignFragment *) { return true; } }; class MCFillFragment : public MCFragment { @@ -280,7 +322,7 @@ class MCFillFragment : public MCFragment { /// Value - Value to use for filling bytes. int64_t Value; - /// ValueSize - The size (in bytes) of \arg Value to use when filling, or 0 if + /// ValueSize - The size (in bytes) of \p Value to use when filling, or 0 if /// this is a virtual fill fragment. unsigned ValueSize; @@ -310,7 +352,6 @@ public: static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_Fill; } - static bool classof(const MCFillFragment *) { return true; } }; class MCOrgFragment : public MCFragment { @@ -339,7 +380,6 @@ public: static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_Org; } - static bool classof(const MCOrgFragment *) { return true; } }; class MCLEBFragment : public MCFragment { @@ -372,7 +412,6 @@ public: static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_LEB; } - static bool classof(const MCLEBFragment *) { return true; } }; class MCDwarfLineAddrFragment : public MCFragment { @@ -409,7 +448,6 @@ public: static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_Dwarf; } - static bool classof(const MCDwarfLineAddrFragment *) { return true; } }; class MCDwarfCallFrameFragment : public MCFragment { @@ -439,7 +477,6 @@ public: 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 @@ -448,8 +485,8 @@ public: class MCSectionData : public ilist_node<MCSectionData> { friend class MCAsmLayout; - MCSectionData(const MCSectionData&); // DO NOT IMPLEMENT - void operator=(const MCSectionData&); // DO NOT IMPLEMENT + MCSectionData(const MCSectionData&) LLVM_DELETED_FUNCTION; + void operator=(const MCSectionData&) LLVM_DELETED_FUNCTION; public: typedef iplist<MCFragment> FragmentListType; @@ -460,6 +497,12 @@ public: typedef FragmentListType::const_reverse_iterator const_reverse_iterator; typedef FragmentListType::reverse_iterator reverse_iterator; + /// \brief Express the state of bundle locked groups while emitting code. + enum BundleLockStateType { + NotBundleLocked, + BundleLocked, + BundleLockedAlignToEnd + }; private: FragmentListType Fragments; const MCSection *Section; @@ -473,6 +516,13 @@ private: /// Alignment - The maximum alignment seen in this section. unsigned Alignment; + /// \brief Keeping track of bundle-locked state. + BundleLockStateType BundleLockState; + + /// \brief We've seen a bundle_lock directive but not its first instruction + /// yet. + bool BundleGroupBeforeFirstInst; + /// @name Assembler Backend Data /// @{ // @@ -525,6 +575,26 @@ public: bool empty() const { return Fragments.empty(); } + bool isBundleLocked() const { + return BundleLockState != NotBundleLocked; + } + + BundleLockStateType getBundleLockState() const { + return BundleLockState; + } + + void setBundleLockState(BundleLockStateType NewState) { + BundleLockState = NewState; + } + + bool isBundleGroupBeforeFirstInst() const { + return BundleGroupBeforeFirstInst; + } + + void setBundleGroupBeforeFirstInst(bool IsFirst) { + BundleGroupBeforeFirstInst = IsFirst; + } + void dump(); /// @} @@ -691,8 +761,8 @@ public: typedef std::vector<DataRegionData>::iterator data_region_iterator; private: - MCAssembler(const MCAssembler&); // DO NOT IMPLEMENT - void operator=(const MCAssembler&); // DO NOT IMPLEMENT + MCAssembler(const MCAssembler&) LLVM_DELETED_FUNCTION; + void operator=(const MCAssembler&) LLVM_DELETED_FUNCTION; MCContext &Context; @@ -730,6 +800,11 @@ private: // refactoring too. SmallPtrSet<const MCSymbol*, 64> ThumbFuncs; + /// \brief The bundle alignment size currently set in the assembler. + /// + /// By default it's 0, which means bundling is disabled. + unsigned BundleAlignSize; + unsigned RelaxAll : 1; unsigned NoExecStack : 1; unsigned SubsectionsViaSymbols : 1; @@ -746,7 +821,7 @@ private: /// \param Value [out] On return, the value of the fixup as currently laid /// 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 + /// \p Value result is fixed, otherwise the value may change due to /// relocation. bool evaluateFixup(const MCAsmLayout &Layout, const MCFixup &Fixup, const MCFragment *DF, @@ -754,20 +829,22 @@ 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(const MCFixup &Fixup, const MCInstFragment *DF, + bool fixupNeedsRelaxation(const MCFixup &Fixup, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const; /// Check whether the given fragment needs relaxation. - bool fragmentNeedsRelaxation(const MCInstFragment *IF, + bool fragmentNeedsRelaxation(const MCRelaxableFragment *IF, const MCAsmLayout &Layout) const; - /// layoutOnce - Perform one layout iteration and return true if any offsets + /// \brief Perform one layout iteration and return true if any offsets /// were adjusted. bool layoutOnce(MCAsmLayout &Layout); + /// \brief Perform one layout iteration of the given section and return true + /// if any offsets were adjusted. bool layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD); - bool relaxInstruction(MCAsmLayout &Layout, MCInstFragment &IF); + bool relaxInstruction(MCAsmLayout &Layout, MCRelaxableFragment &IF); bool relaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF); @@ -783,7 +860,7 @@ private: public: /// Compute the effective fragment size assuming it is laid out at the given - /// \arg SectionAddress and \arg FragmentOffset. + /// \p SectionAddress and \p FragmentOffset. uint64_t computeFragmentSize(const MCAsmLayout &Layout, const MCFragment &F) const; @@ -812,7 +889,7 @@ public: public: /// Construct a new assembler instance. /// - /// \arg OS - The stream to output to. + /// \param OS The stream to output to. // // FIXME: How are we going to parameterize this? Two obvious options are stay // concrete and require clients to pass in a target like object. The other @@ -823,6 +900,10 @@ public: raw_ostream &OS); ~MCAssembler(); + /// Reuse an assembler instance + /// + void reset(); + MCContext &getContext() const { return Context; } MCAsmBackend &getBackend() const { return Backend; } @@ -834,7 +915,7 @@ public: void setWriter(MCObjectWriter &ObjectWriter); /// Finish - Do final processing and write the object to the output stream. - /// \arg Writer is used for custom object writer (as the MCJIT does), + /// \p Writer is used for custom object writer (as the MCJIT does), /// if not specified it is automatically created from backend. void Finish(); @@ -852,6 +933,20 @@ public: bool getNoExecStack() const { return NoExecStack; } void setNoExecStack(bool Value) { NoExecStack = Value; } + bool isBundlingEnabled() const { + return BundleAlignSize != 0; + } + + unsigned getBundleAlignSize() const { + return BundleAlignSize; + } + + void setBundleAlignSize(unsigned Size) { + assert((Size == 0 || !(Size & (Size - 1))) && + "Expect a power-of-two bundle align size"); + BundleAlignSize = Size; + } + /// @name Section List Access /// @{ diff --git a/include/llvm/MC/MCCodeEmitter.h b/include/llvm/MC/MCCodeEmitter.h index 4f7d103..9bfa08e 100644 --- a/include/llvm/MC/MCCodeEmitter.h +++ b/include/llvm/MC/MCCodeEmitter.h @@ -29,8 +29,11 @@ protected: // Can only create subclasses. public: virtual ~MCCodeEmitter(); - /// EncodeInstruction - Encode the given \arg Inst to bytes on the output - /// stream \arg OS. + /// Lifetime management + virtual void reset() { } + + /// EncodeInstruction - Encode the given \p Inst to bytes on the output + /// stream \p OS. virtual void EncodeInstruction(const MCInst &Inst, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups) const = 0; }; diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index 23652f0..e92d3b9 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -10,10 +10,10 @@ #ifndef LLVM_MC_MCCONTEXT_H #define LLVM_MC_MCCONTEXT_H -#include "llvm/MC/SectionKind.h" -#include "llvm/MC/MCDwarf.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringMap.h" +#include "llvm/MC/MCDwarf.h" +#include "llvm/MC/SectionKind.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/raw_ostream.h" @@ -94,6 +94,12 @@ namespace llvm { /// .secure_log_reset appearing between them. bool SecureLogUsed; + /// The compilation directory to use for DW_AT_comp_dir. + std::string CompilationDir; + + /// The main file name if passed in explicitly. + std::string MainFileName; + /// The dwarf file and directory tables from the dwarf .file directive. std::vector<MCDwarfFile *> MCDwarfFiles; std::vector<StringRef> MCDwarfDirs; @@ -137,11 +143,15 @@ namespace llvm { void *MachOUniquingMap, *ELFUniquingMap, *COFFUniquingMap; + /// Do automatic reset in destructor + bool AutoReset; + MCSymbol *CreateSymbol(StringRef Name); public: explicit MCContext(const MCAsmInfo &MAI, const MCRegisterInfo &MRI, - const MCObjectFileInfo *MOFI, const SourceMgr *Mgr = 0); + const MCObjectFileInfo *MOFI, const SourceMgr *Mgr = 0, + bool DoAutoReset = true); ~MCContext(); const SourceMgr *getSourceManager() const { return SrcMgr; } @@ -154,6 +164,15 @@ namespace llvm { void setAllowTemporaryLabels(bool Value) { AllowTemporaryLabels = Value; } + /// @name Module Lifetime Management + /// @{ + + /// reset - return object to right after construction state to prepare + /// to process a new module + void reset(); + + /// @} + /// @name Symbol Management /// @{ @@ -183,6 +202,7 @@ namespace llvm { /// LookupSymbol - Get the symbol for \p Name, or null. MCSymbol *LookupSymbol(StringRef Name) const; + MCSymbol *LookupSymbol(const Twine &Name) const; /// getSymbols - Get a reference for the symbol table for clients that /// want to, for example, iterate over all symbols. 'const' because we @@ -234,6 +254,24 @@ namespace llvm { /// @name Dwarf Management /// @{ + /// \brief Get the compilation directory for DW_AT_comp_dir + /// This can be overridden by clients which want to control the reported + /// compilation directory and have it be something other than the current + /// working directory. + const std::string &getCompilationDir() const { return CompilationDir; } + + /// \brief Set the compilation directory for DW_AT_comp_dir + /// Override the default (CWD) compilation directory. + void setCompilationDir(StringRef S) { CompilationDir = S.str(); } + + /// \brief Get the main file name for use in error messages and debug + /// info. This can be set to ensure we've got the correct file name + /// after preprocessing or for -save-temps. + const std::string &getMainFileName() const { return MainFileName; } + + /// \brief Set the main file name and override the default. + void setMainFileName(StringRef S) { MainFileName = S.str(); } + /// GetDwarfFile - creates an entry in the dwarf file and directory tables. unsigned GetDwarfFile(StringRef Directory, StringRef FileName, unsigned FileNumber); diff --git a/include/llvm/MC/MCDisassembler.h b/include/llvm/MC/MCDisassembler.h index 53a9ce0..1b6beb2 100644 --- a/include/llvm/MC/MCDisassembler.h +++ b/include/llvm/MC/MCDisassembler.h @@ -9,8 +9,8 @@ #ifndef MCDISASSEMBLER_H #define MCDISASSEMBLER_H -#include "llvm/Support/DataTypes.h" #include "llvm-c/Disassembler.h" +#include "llvm/Support/DataTypes.h" namespace llvm { @@ -20,8 +20,6 @@ class MemoryObject; class raw_ostream; class MCContext; -struct EDInstInfo; - /// MCDisassembler - Superclass for all disassemblers. Consumes a memory region /// and provides an array of assembly instructions. class MCDisassembler { @@ -84,14 +82,6 @@ public: raw_ostream &vStream, raw_ostream &cStream) const = 0; - /// getEDInfo - Returns the enhanced instruction information corresponding to - /// the disassembler. - /// - /// @return - An array of instruction information, with one entry for - /// each MCInst opcode this disassembler returns. - /// NULL if there is no info for this target. - virtual const EDInstInfo *getEDInfo() const { return (EDInstInfo*)0; } - private: // // Hooks for symbolic disassembly via the public 'C' interface. diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h index 9e09ddf..3160b61 100644 --- a/include/llvm/MC/MCDwarf.h +++ b/include/llvm/MC/MCDwarf.h @@ -16,10 +16,9 @@ #define LLVM_MC_MCDWARF_H #include "llvm/ADT/StringRef.h" -#include "llvm/MC/MachineLocation.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/Dwarf.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/Dwarf.h" +#include "llvm/Support/raw_ostream.h" #include <vector> namespace llvm { @@ -59,7 +58,7 @@ namespace llvm { unsigned getDirIndex() const { return DirIndex; } - /// print - Print the value to the stream \arg OS. + /// print - Print the value to the stream \p OS. void print(raw_ostream &OS) const; /// dump - Print the value to stderr. @@ -178,8 +177,8 @@ namespace llvm { class MCLineSection { private: - MCLineSection(const MCLineSection&); // DO NOT IMPLEMENT - void operator=(const MCLineSection&); // DO NOT IMPLEMENT + MCLineSection(const MCLineSection&) LLVM_DELETED_FUNCTION; + void operator=(const MCLineSection&) LLVM_DELETED_FUNCTION; public: // Constructor to create an MCLineSection with an empty MCLineEntries @@ -266,42 +265,115 @@ namespace llvm { class MCCFIInstruction { public: - enum OpType { SameValue, RememberState, RestoreState, Move, RelMove, Escape, - Restore}; + enum OpType { OpSameValue, OpRememberState, OpRestoreState, OpOffset, + OpDefCfaRegister, OpDefCfaOffset, OpDefCfa, OpRelOffset, + OpAdjustCfaOffset, OpEscape, OpRestore, OpUndefined, + OpRegister }; private: OpType Operation; MCSymbol *Label; - // Move to & from location. - MachineLocation Destination; - MachineLocation Source; + unsigned Register; + union { + int Offset; + unsigned Register2; + }; std::vector<char> Values; + + MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R, int O, StringRef V) : + Operation(Op), Label(L), Register(R), Offset(O), + Values(V.begin(), V.end()) { + assert(Op != OpRegister); + } + + MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R1, unsigned R2) : + Operation(Op), Label(L), Register(R1), Register2(R2) { + assert(Op == OpRegister); + } + public: - MCCFIInstruction(OpType Op, MCSymbol *L) - : Operation(Op), Label(L) { - assert(Op == RememberState || Op == RestoreState); + static MCCFIInstruction + createOffset(MCSymbol *L, unsigned Register, int Offset) { + return MCCFIInstruction(OpOffset, L, Register, Offset, ""); } - MCCFIInstruction(OpType Op, MCSymbol *L, unsigned Register) - : Operation(Op), Label(L), Destination(Register) { - assert(Op == SameValue || Op == Restore); + + static MCCFIInstruction + createDefCfaRegister(MCSymbol *L, unsigned Register) { + return MCCFIInstruction(OpDefCfaRegister, L, Register, 0, ""); } - MCCFIInstruction(MCSymbol *L, const MachineLocation &D, - const MachineLocation &S) - : Operation(Move), Label(L), Destination(D), Source(S) { + + static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset) { + return MCCFIInstruction(OpDefCfaOffset, L, 0, -Offset, ""); } - MCCFIInstruction(OpType Op, MCSymbol *L, const MachineLocation &D, - const MachineLocation &S) - : Operation(Op), Label(L), Destination(D), Source(S) { - assert(Op == RelMove); + + static MCCFIInstruction + createDefCfa(MCSymbol *L, unsigned Register, int Offset) { + return MCCFIInstruction(OpDefCfa, L, Register, -Offset, ""); } - MCCFIInstruction(OpType Op, MCSymbol *L, StringRef Vals) - : Operation(Op), Label(L), Values(Vals.begin(), Vals.end()) { - assert(Op == Escape); + + static MCCFIInstruction createUndefined(MCSymbol *L, unsigned Register) { + return MCCFIInstruction(OpUndefined, L, Register, 0, ""); + } + + static MCCFIInstruction createRestore(MCSymbol *L, unsigned Register) { + return MCCFIInstruction(OpRestore, L, Register, 0, ""); + } + + static MCCFIInstruction createSameValue(MCSymbol *L, unsigned Register) { + return MCCFIInstruction(OpSameValue, L, Register, 0, ""); + } + + static MCCFIInstruction createRestoreState(MCSymbol *L) { + return MCCFIInstruction(OpRestoreState, L, 0, 0, ""); } + + static MCCFIInstruction createRememberState(MCSymbol *L) { + return MCCFIInstruction(OpRememberState, L, 0, 0, ""); + } + + static MCCFIInstruction + createRelOffset(MCSymbol *L, unsigned Register, int Offset) { + return MCCFIInstruction(OpRelOffset, L, Register, Offset, ""); + } + + static MCCFIInstruction + createAdjustCfaOffset(MCSymbol *L, int Adjustment) { + return MCCFIInstruction(OpAdjustCfaOffset, L, 0, Adjustment, ""); + } + + static MCCFIInstruction createEscape(MCSymbol *L, StringRef Vals) { + return MCCFIInstruction(OpEscape, L, 0, 0, Vals); + } + + static MCCFIInstruction + createRegister(MCSymbol *L, unsigned Register1, unsigned Register2) { + return MCCFIInstruction(OpRegister, L, Register1, Register2); + } + OpType getOperation() const { return Operation; } MCSymbol *getLabel() const { return Label; } - const MachineLocation &getDestination() const { return Destination; } - const MachineLocation &getSource() const { return Source; } + + unsigned getRegister() const { + assert(Operation == OpDefCfa || Operation == OpOffset || + Operation == OpRestore || Operation == OpUndefined || + Operation == OpSameValue || Operation == OpDefCfaRegister || + Operation == OpRelOffset || Operation == OpRegister); + return Register; + } + + unsigned getRegister2() const { + assert(Operation == OpRegister); + return Register2; + } + + int getOffset() const { + assert(Operation == OpDefCfa || Operation == OpOffset || + Operation == OpRelOffset || Operation == OpDefCfaOffset || + Operation == OpAdjustCfaOffset); + return Offset; + } + const StringRef getValues() const { + assert(Operation == OpEscape); return StringRef(&Values[0], Values.size()); } }; diff --git a/include/llvm/MC/MCELF.h b/include/llvm/MC/MCELF.h new file mode 100644 index 0000000..e08f1e6 --- /dev/null +++ b/include/llvm/MC/MCELF.h @@ -0,0 +1,35 @@ +//===- lib/MC/MCELF.h - ELF MC --------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains some support functions used by the ELF Streamer and +// ObjectWriter. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCELF_H +#define LLVM_MC_MCELF_H + +#include "llvm/MC/MCExpr.h" + +namespace llvm { +class MCSymbolData; + +class MCELF { + public: + static void SetBinding(MCSymbolData &SD, unsigned Binding); + static unsigned GetBinding(const MCSymbolData &SD); + static void SetType(MCSymbolData &SD, unsigned Type); + static unsigned GetType(const MCSymbolData &SD); + static void SetVisibility(MCSymbolData &SD, unsigned Visibility); + static unsigned GetVisibility(MCSymbolData &SD); +}; + +} + +#endif diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h index abbe188..38cdc72 100644 --- a/include/llvm/MC/MCELFObjectWriter.h +++ b/include/llvm/MC/MCELFObjectWriter.h @@ -85,6 +85,9 @@ public: const MCFragment &F, const MCFixup &Fixup, bool IsPCRel) const; + virtual const MCSymbol *undefinedExplicitRelSym(const MCValue &Target, + const MCFixup &Fixup, + bool IsPCRel) const; virtual void adjustFixupOffset(const MCFixup &Fixup, uint64_t &RelocOffset); @@ -93,9 +96,9 @@ public: /// @name Accessors /// @{ - uint8_t getOSABI() { return OSABI; } - uint16_t getEMachine() { return EMachine; } - bool hasRelocationAddend() { return HasRelocationAddend; } + uint8_t getOSABI() const { return OSABI; } + uint16_t getEMachine() const { return EMachine; } + bool hasRelocationAddend() const { return HasRelocationAddend; } bool is64Bit() const { return Is64Bit; } bool isN64() const { return IsN64; } /// @} diff --git a/include/llvm/MC/MCELFStreamer.h b/include/llvm/MC/MCELFStreamer.h new file mode 100644 index 0000000..ab20ee8 --- /dev/null +++ b/include/llvm/MC/MCELFStreamer.h @@ -0,0 +1,113 @@ +//===- MCELFStreamer.h - MCStreamer ELF Object File Interface ---*- 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_MCELFSTREAMER_H +#define LLVM_MC_MCELFSTREAMER_H + +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/MC/MCDirectives.h" +#include "llvm/MC/MCObjectStreamer.h" +#include "llvm/MC/SectionKind.h" +#include "llvm/Support/DataTypes.h" +#include <vector> + +namespace llvm { +class MCAsmBackend; +class MCAssembler; +class MCCodeEmitter; +class MCExpr; +class MCInst; +class MCSymbol; +class MCSymbolData; +class raw_ostream; + +class MCELFStreamer : public MCObjectStreamer { +public: + MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, + raw_ostream &OS, MCCodeEmitter *Emitter) + : MCObjectStreamer(Context, TAB, OS, Emitter) {} + + MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, + raw_ostream &OS, MCCodeEmitter *Emitter, + MCAssembler *Assembler) + : MCObjectStreamer(Context, TAB, OS, Emitter, Assembler) {} + + virtual ~MCELFStreamer(); + + /// @name MCStreamer Interface + /// @{ + + virtual void InitSections(); + virtual void ChangeSection(const MCSection *Section); + virtual void EmitLabel(MCSymbol *Symbol); + virtual void EmitDebugLabel(MCSymbol *Symbol); + virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); + virtual void EmitThumbFunc(MCSymbol *Func); + virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol); + virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute); + virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue); + virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment); + virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol); + virtual void EmitCOFFSymbolStorageClass(int StorageClass); + virtual void EmitCOFFSymbolType(int Type); + virtual void EndCOFFSymbolDef(); + + virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value); + + virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment); + + virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, + uint64_t Size = 0, unsigned ByteAlignment = 0); + virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, + uint64_t Size, unsigned ByteAlignment = 0); + virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, + unsigned AddrSpace); + + virtual void EmitFileDirective(StringRef Filename); + + virtual void EmitTCEntry(const MCSymbol &S); + + virtual void EmitValueToAlignment(unsigned, int64_t, unsigned, unsigned); + + virtual void FinishImpl(); + /// @} + +private: + virtual void EmitInstToFragment(const MCInst &Inst); + virtual void EmitInstToData(const MCInst &Inst); + + virtual void EmitBundleAlignMode(unsigned AlignPow2); + virtual void EmitBundleLock(bool AlignToEnd); + virtual void EmitBundleUnlock(); + + void fixSymbolsInTLSFixups(const MCExpr *expr); + + struct LocalCommon { + MCSymbolData *SD; + uint64_t Size; + unsigned ByteAlignment; + }; + + std::vector<LocalCommon> LocalCommons; + + SmallPtrSet<MCSymbol *, 16> BindingExplicitlySet; + + + void SetSection(StringRef Section, unsigned Type, unsigned Flags, + SectionKind Kind); + void SetSectionData(); + void SetSectionText(); + void SetSectionBss(); +}; + +} // end namespace llvm + +#endif diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index f36db3c..475981f 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -99,8 +99,6 @@ public: const MCSection *FindAssociatedSection() const; /// @} - - static bool classof(const MCExpr *) { return true; } }; inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) { @@ -132,7 +130,6 @@ public: static bool classof(const MCExpr *E) { return E->getKind() == MCExpr::Constant; } - static bool classof(const MCConstantExpr *) { return true; } }; /// MCSymbolRefExpr - Represent a reference to a symbol from inside an @@ -163,6 +160,7 @@ public: VK_TLVP, // Mach-O thread local variable relocation VK_SECREL, // FIXME: We'd really like to use the generic Kinds listed above for these. + VK_ARM_NONE, VK_ARM_PLT, // ARM-style PLT references. i.e., (PLT) instead of @PLT VK_ARM_TLSGD, // ditto for TLSGD, GOT, GOTOFF, TPOFF and GOTTPOFF VK_ARM_GOT, @@ -170,15 +168,30 @@ public: VK_ARM_TPOFF, VK_ARM_GOTTPOFF, VK_ARM_TARGET1, + VK_ARM_TARGET2, + VK_ARM_PREL31, VK_PPC_TOC, // TOC base VK_PPC_TOC_ENTRY, // TOC entry VK_PPC_DARWIN_HA16, // ha16(symbol) VK_PPC_DARWIN_LO16, // lo16(symbol) VK_PPC_GAS_HA16, // symbol@ha - VK_PPC_GAS_LO16, // symbol@l + VK_PPC_GAS_LO16, // symbol@l VK_PPC_TPREL16_HA, // symbol@tprel@ha VK_PPC_TPREL16_LO, // symbol@tprel@l + VK_PPC_DTPREL16_HA, // symbol@dtprel@ha + VK_PPC_DTPREL16_LO, // symbol@dtprel@l + VK_PPC_TOC16_HA, // symbol@toc@ha + VK_PPC_TOC16_LO, // symbol@toc@l + VK_PPC_GOT_TPREL16_HA, // symbol@got@tprel@ha + VK_PPC_GOT_TPREL16_LO, // symbol@got@tprel@l + VK_PPC_TLS, // symbol@tls + VK_PPC_GOT_TLSGD16_HA, // symbol@got@tlsgd@ha + VK_PPC_GOT_TLSGD16_LO, // symbol@got@tlsgd@l + VK_PPC_TLSGD, // symbol@tlsgd + VK_PPC_GOT_TLSLD16_HA, // symbol@got@tlsld@ha + VK_PPC_GOT_TLSLD16_LO, // symbol@got@tlsld@l + VK_PPC_TLSLD, // symbol@tlsld VK_Mips_GPREL, VK_Mips_GOT_CALL, @@ -199,7 +212,11 @@ public: VK_Mips_GOT_PAGE, VK_Mips_GOT_OFST, VK_Mips_HIGHER, - VK_Mips_HIGHEST + VK_Mips_HIGHEST, + VK_Mips_GOT_HI16, + VK_Mips_GOT_LO16, + VK_Mips_CALL_HI16, + VK_Mips_CALL_LO16 }; private: @@ -248,7 +265,6 @@ public: static bool classof(const MCExpr *E) { return E->getKind() == MCExpr::SymbolRef; } - static bool classof(const MCSymbolRefExpr *) { return true; } }; /// MCUnaryExpr - Unary assembler expressions. @@ -302,7 +318,6 @@ public: static bool classof(const MCExpr *E) { return E->getKind() == MCExpr::Unary; } - static bool classof(const MCUnaryExpr *) { return true; } }; /// MCBinaryExpr - Binary assembler expressions. @@ -437,7 +452,6 @@ public: static bool classof(const MCExpr *E) { return E->getKind() == MCExpr::Binary; } - static bool classof(const MCBinaryExpr *) { return true; } }; /// MCTargetExpr - This is an extension point for target-specific MCExpr @@ -446,7 +460,7 @@ public: /// NOTE: All subclasses are required to have trivial destructors because /// MCExprs are bump pointer allocated and not destructed. class MCTargetExpr : public MCExpr { - virtual void Anchor(); + virtual void anchor(); protected: MCTargetExpr() : MCExpr(Target) {} virtual ~MCTargetExpr() {} @@ -461,7 +475,6 @@ public: static bool classof(const MCExpr *E) { return E->getKind() == MCExpr::Target; } - static bool classof(const MCTargetExpr *) { return true; } }; } // end namespace llvm diff --git a/include/llvm/MC/MCInst.h b/include/llvm/MC/MCInst.h index 397a37d..e91c6a2 100644 --- a/include/llvm/MC/MCInst.h +++ b/include/llvm/MC/MCInst.h @@ -182,7 +182,7 @@ public: void dump() const; /// \brief Dump the MCInst as prettily as possible using the additional MC - /// structures, if given. Operators are separated by the \arg Separator + /// structures, if given. Operators are separated by the \p Separator /// string. void dump_pretty(raw_ostream &OS, const MCAsmInfo *MAI = 0, const MCInstPrinter *Printer = 0, diff --git a/include/llvm/MC/MCInstBuilder.h b/include/llvm/MC/MCInstBuilder.h new file mode 100644 index 0000000..c5acb26 --- /dev/null +++ b/include/llvm/MC/MCInstBuilder.h @@ -0,0 +1,68 @@ +//===-- llvm/MC/MCInstBuilder.h - Simplify creation of MCInsts --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the MCInstBuilder class for convenient creation of +// MCInsts. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCINSTBUILDER_H +#define LLVM_MC_MCINSTBUILDER_H + +#include "llvm/MC/MCInst.h" + +namespace llvm { + +class MCInstBuilder { + MCInst Inst; + +public: + /// \brief Create a new MCInstBuilder for an MCInst with a specific opcode. + MCInstBuilder(unsigned Opcode) { + Inst.setOpcode(Opcode); + } + + /// \brief Add a new register operand. + MCInstBuilder &addReg(unsigned Reg) { + Inst.addOperand(MCOperand::CreateReg(Reg)); + return *this; + } + + /// \brief Add a new integer immediate operand. + MCInstBuilder &addImm(int64_t Val) { + Inst.addOperand(MCOperand::CreateImm(Val)); + return *this; + } + + /// \brief Add a new floating point immediate operand. + MCInstBuilder &addFPImm(double Val) { + Inst.addOperand(MCOperand::CreateFPImm(Val)); + return *this; + } + + /// \brief Add a new MCExpr operand. + MCInstBuilder &addExpr(const MCExpr *Val) { + Inst.addOperand(MCOperand::CreateExpr(Val)); + return *this; + } + + /// \brief Add a new MCInst operand. + MCInstBuilder &addInst(const MCInst *Val) { + Inst.addOperand(MCOperand::CreateInst(Val)); + return *this; + } + + operator MCInst&() { + return Inst; + } +}; + +} // end namespace llvm + +#endif diff --git a/include/llvm/MC/MCInstPrinter.h b/include/llvm/MC/MCInstPrinter.h index 3c4f28b..a18cbd9 100644 --- a/include/llvm/MC/MCInstPrinter.h +++ b/include/llvm/MC/MCInstPrinter.h @@ -10,6 +10,9 @@ #ifndef LLVM_MC_MCINSTPRINTER_H #define LLVM_MC_MCINSTPRINTER_H +#include "llvm/Support/DataTypes.h" +#include "llvm/Support/Format.h" + namespace llvm { class MCInst; class raw_ostream; @@ -33,12 +36,19 @@ protected: /// The current set of available features. unsigned AvailableFeatures; + /// True if we are printing marked up assembly. + bool UseMarkup; + + /// True if we are printing immediates as hex. + bool PrintImmHex; + /// Utility function for printing annotations. void printAnnotation(raw_ostream &OS, StringRef Annot); public: MCInstPrinter(const MCAsmInfo &mai, const MCInstrInfo &mii, const MCRegisterInfo &mri) - : CommentStream(0), MAI(mai), MII(mii), MRI(mri), AvailableFeatures(0) {} + : CommentStream(0), MAI(mai), MII(mii), MRI(mri), AvailableFeatures(0), + UseMarkup(0), PrintImmHex(0) {} virtual ~MCInstPrinter(); @@ -59,6 +69,19 @@ public: unsigned getAvailableFeatures() const { return AvailableFeatures; } void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; } + + bool getUseMarkup() const { return UseMarkup; } + void setUseMarkup(bool Value) { UseMarkup = Value; } + + /// Utility functions to make adding mark ups simpler. + StringRef markup(StringRef s) const; + StringRef markup(StringRef a, StringRef b) const; + + bool getPrintImmHex() const { return PrintImmHex; } + void setPrintImmHex(bool Value) { PrintImmHex = Value; } + + /// Utility function to print immediates in decimal or hex. + format_object1<int64_t> formatImm(const int64_t Value) const; }; } // namespace llvm diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h index dbf16d8..9b5415a 100644 --- a/include/llvm/MC/MCInstrDesc.h +++ b/include/llvm/MC/MCInstrDesc.h @@ -1,4 +1,4 @@ -//===-- llvm/Mc/McInstrDesc.h - Instruction Descriptors -*- C++ -*-===// +//===-- llvm/MC/MCInstrDesc.h - Instruction Descriptors -*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -15,6 +15,8 @@ #ifndef LLVM_MC_MCINSTRDESC_H #define LLVM_MC_MCINSTRDESC_H +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCRegisterInfo.h" #include "llvm/Support/DataTypes.h" namespace llvm { @@ -144,7 +146,7 @@ public: const uint16_t *ImplicitDefs; // Registers implicitly defined by this instr const MCOperandInfo *OpInfo; // 'NumOperands' entries about operands - /// getOperandConstraint - Returns the value of the specific constraint if + /// \brief Returns the value of the specific constraint if /// it is set. Returns -1 if it is not set. int getOperandConstraint(unsigned OpNum, MCOI::OperandConstraint Constraint) const { @@ -156,12 +158,12 @@ public: return -1; } - /// getOpcode - Return the opcode number for this descriptor. + /// \brief Return the opcode number for this descriptor. unsigned getOpcode() const { return Opcode; } - /// getNumOperands - Return the number of declared MachineOperands for this + /// \brief Return the number of declared MachineOperands for this /// MachineInstruction. Note that variadic (isVariadic() returns true) /// instructions may have additional operands at the end of the list, and note /// that the machine instruction may include implicit register def/uses as @@ -170,7 +172,7 @@ public: return NumOperands; } - /// getNumDefs - Return the number of MachineOperands that are register + /// \brief Return the number of MachineOperands that are register /// definitions. Register definitions always occur at the start of the /// machine operand list. This is the number of "outs" in the .td file, /// and does not include implicit defs. @@ -178,11 +180,10 @@ public: return NumDefs; } - /// getFlags - Return flags of this instruction. - /// + /// \brief Return flags of this instruction. unsigned getFlags() const { return Flags; } - /// isVariadic - Return true if this instruction can have a variable number of + /// \brief Return true if this instruction can have a variable number of /// operands. In this case, the variable operands will be after the normal /// operands but before the implicit definitions and uses (if any are /// present). @@ -190,35 +191,37 @@ public: return Flags & (1 << MCID::Variadic); } - /// hasOptionalDef - Set if this instruction has an optional definition, e.g. + /// \brief Set if this instruction has an optional definition, e.g. /// ARM instructions which can set condition code if 's' bit is set. bool hasOptionalDef() const { return Flags & (1 << MCID::HasOptionalDef); } - /// isPseudo - Return true if this is a pseudo instruction that doesn't + /// \brief Return true if this is a pseudo instruction that doesn't /// correspond to a real machine instruction. /// bool isPseudo() const { return Flags & (1 << MCID::Pseudo); } + /// \brief Return true if the instruction is a return. bool isReturn() const { return Flags & (1 << MCID::Return); } + /// \brief Return true if the instruction is a call. bool isCall() const { return Flags & (1 << MCID::Call); } - /// isBarrier - Returns true if the specified instruction stops control flow + /// \brief Returns true if the specified instruction stops control flow /// from executing the instruction immediately following it. Examples include /// unconditional branches and return instructions. bool isBarrier() const { return Flags & (1 << MCID::Barrier); } - /// isTerminator - Returns true if this instruction part of the terminator for + /// \brief Returns true if this instruction part of the terminator for /// a basic block. Typically this is things like return and branch /// instructions. /// @@ -228,7 +231,7 @@ public: return Flags & (1 << MCID::Terminator); } - /// isBranch - Returns true if this is a conditional, unconditional, or + /// \brief Returns true if this is a conditional, unconditional, or /// indirect branch. Predicates below can be used to discriminate between /// these cases, and the TargetInstrInfo::AnalyzeBranch method can be used to /// get more information. @@ -236,13 +239,13 @@ public: return Flags & (1 << MCID::Branch); } - /// isIndirectBranch - Return true if this is an indirect branch, such as a + /// \brief Return true if this is an indirect branch, such as a /// branch through a register. bool isIndirectBranch() const { return Flags & (1 << MCID::IndirectBranch); } - /// isConditionalBranch - Return true if this is a branch which may fall + /// \brief Return true if this is a branch which may fall /// through to the next instruction or may transfer control flow to some other /// block. The TargetInstrInfo::AnalyzeBranch method can be used to get more /// information about this branch. @@ -250,7 +253,7 @@ public: return isBranch() & !isBarrier() & !isIndirectBranch(); } - /// isUnconditionalBranch - Return true if this is a branch which always + /// \brief Return true if this is a branch which always /// transfers control flow to some other block. The /// TargetInstrInfo::AnalyzeBranch method can be used to get more information /// about this branch. @@ -258,38 +261,47 @@ public: return isBranch() & isBarrier() & !isIndirectBranch(); } - // isPredicable - Return true if this instruction has a predicate operand that - // controls execution. It may be set to 'always', or may be set to other - /// values. There are various methods in TargetInstrInfo that can be used to + /// \brief Return true if this is a branch or an instruction which directly + /// writes to the program counter. Considered 'may' affect rather than + /// 'does' affect as things like predication are not taken into account. + bool mayAffectControlFlow(const MCInst &MI, const MCRegisterInfo &RI) const { + if (isBranch() || isCall() || isReturn() || isIndirectBranch()) + return true; + unsigned PC = RI.getProgramCounter(); + if (PC == 0) return false; + return hasDefOfPhysReg(MI, PC, RI); + } + + /// \brief Return true if this instruction has a predicate operand + /// that controls execution. It may be set to 'always', or may be set to other + /// values. There are various methods in TargetInstrInfo that can be used to /// control and modify the predicate in this instruction. bool isPredicable() const { return Flags & (1 << MCID::Predicable); } - /// isCompare - Return true if this instruction is a comparison. + /// \brief Return true if this instruction is a comparison. bool isCompare() const { return Flags & (1 << MCID::Compare); } - /// isMoveImmediate - Return true if this instruction is a move immediate + /// \brief Return true if this instruction is a move immediate /// (including conditional moves) instruction. bool isMoveImmediate() const { return Flags & (1 << MCID::MoveImm); } - /// isBitcast - Return true if this instruction is a bitcast instruction. - /// + /// \brief Return true if this instruction is a bitcast instruction. bool isBitcast() const { return Flags & (1 << MCID::Bitcast); } - /// isSelect - Return true if this is a select instruction. - /// + /// \brief Return true if this is a select instruction. bool isSelect() const { return Flags & (1 << MCID::Select); } - /// isNotDuplicable - Return true if this instruction cannot be safely + /// \brief Return true if this instruction cannot be safely /// duplicated. For example, if the instruction has a unique labels attached /// to it, duplicating it would cause multiple definition errors. bool isNotDuplicable() const { @@ -318,7 +330,7 @@ public: // Side Effect Analysis //===--------------------------------------------------------------------===// - /// mayLoad - Return true if this instruction could possibly read memory. + /// \brief Return true if this instruction could possibly read memory. /// Instructions with this flag set are not necessarily simple load /// instructions, they may load a value and modify it, for example. bool mayLoad() const { @@ -326,7 +338,7 @@ public: } - /// mayStore - Return true if this instruction could possibly modify memory. + /// \brief Return true if this instruction could possibly modify memory. /// Instructions with this flag set are not necessarily simple store /// instructions, they may store a modified value based on their operands, or /// may not actually modify anything, for example. @@ -459,8 +471,7 @@ public: return ImplicitUses; } - /// getNumImplicitUses - Return the number of implicit uses this instruction - /// has. + /// \brief Return the number of implicit uses this instruction has. unsigned getNumImplicitUses() const { if (ImplicitUses == 0) return 0; unsigned i = 0; @@ -482,8 +493,7 @@ public: return ImplicitDefs; } - /// getNumImplicitDefs - Return the number of implicit defs this instruction - /// has. + /// \brief Return the number of implicit defs this instruct has. unsigned getNumImplicitDefs() const { if (ImplicitDefs == 0) return 0; unsigned i = 0; @@ -491,7 +501,7 @@ public: return i; } - /// hasImplicitUseOfPhysReg - Return true if this instruction implicitly + /// \brief Return true if this instruction implicitly /// uses the specified physical register. bool hasImplicitUseOfPhysReg(unsigned Reg) const { if (const uint16_t *ImpUses = ImplicitUses) @@ -500,31 +510,43 @@ public: return false; } - /// hasImplicitDefOfPhysReg - Return true if this instruction implicitly + /// \brief Return true if this instruction implicitly /// defines the specified physical register. - bool hasImplicitDefOfPhysReg(unsigned Reg) const { + bool hasImplicitDefOfPhysReg(unsigned Reg, + const MCRegisterInfo *MRI = 0) const { if (const uint16_t *ImpDefs = ImplicitDefs) for (; *ImpDefs; ++ImpDefs) - if (*ImpDefs == Reg) return true; + if (*ImpDefs == Reg || (MRI && MRI->isSubRegister(Reg, *ImpDefs))) + return true; return false; } - /// getSchedClass - Return the scheduling class for this instruction. The + /// \brief Return true if this instruction defines the specified physical + /// register, either explicitly or implicitly. + bool hasDefOfPhysReg(const MCInst &MI, unsigned Reg, + const MCRegisterInfo &RI) const { + for (int i = 0, e = NumDefs; i != e; ++i) + if (MI.getOperand(i).isReg() && + RI.isSubRegisterEq(Reg, MI.getOperand(i).getReg())) + return true; + return hasImplicitDefOfPhysReg(Reg, &RI); + } + + /// \brief Return the scheduling class for this instruction. The /// scheduling class is an index into the InstrItineraryData table. This /// returns zero if there is no known scheduling information for the /// instruction. - /// unsigned getSchedClass() const { return SchedClass; } - /// getSize - Return the number of bytes in the encoding of this instruction, + /// \brief Return the number of bytes in the encoding of this instruction, /// or zero if the encoding size cannot be known from the opcode. unsigned getSize() const { return Size; } - /// findFirstPredOperandIdx() - Find the index of the first operand in the + /// \brief Find the index of the first operand in the /// operand list that is used to represent the predicate. It returns -1 if /// none is found. int findFirstPredOperandIdx() const { diff --git a/include/llvm/MC/MCLabel.h b/include/llvm/MC/MCLabel.h index c72aabd..f531de8 100644 --- a/include/llvm/MC/MCLabel.h +++ b/include/llvm/MC/MCLabel.h @@ -42,7 +42,7 @@ namespace llvm { /// Label. unsigned incInstance() { return ++Instance; } - /// print - Print the value to the stream \arg OS. + /// print - Print the value to the stream \p OS. void print(raw_ostream &OS) const; /// dump - Print the value to stderr. diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h index 949d907..3cd278e 100644 --- a/include/llvm/MC/MCMachObjectWriter.h +++ b/include/llvm/MC/MCMachObjectWriter.h @@ -45,6 +45,13 @@ protected: public: virtual ~MCMachObjectTargetWriter(); + /// @name Lifetime Management + /// @{ + + virtual void reset() {}; + + /// @} + /// @name Accessors /// @{ @@ -111,6 +118,13 @@ public: : MCObjectWriter(_OS, _IsLittleEndian), TargetObjectWriter(MOTW) { } + /// @name Lifetime management Methods + /// @{ + + virtual void reset(); + + /// @} + /// @name Utility Methods /// @{ @@ -153,8 +167,8 @@ public: /// WriteSegmentLoadCommand - Write a segment load command. /// - /// \arg NumSections - The number of sections in this segment. - /// \arg SectionDataSize - The total size of the sections. + /// \param NumSections The number of sections in this segment. + /// \param SectionDataSize The total size of the sections. void WriteSegmentLoadCommand(unsigned NumSections, uint64_t VMSize, uint64_t SectionDataStartOffset, @@ -223,8 +237,6 @@ public: /// ComputeSymbolTable - Compute the symbol table data /// /// \param StringTable [out] - The string table data. - /// \param StringIndexMap [out] - Map from symbol names to offsets in the - /// string table. void ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable, std::vector<MachSymbolData> &LocalSymbolData, std::vector<MachSymbolData> &ExternalSymbolData, @@ -233,6 +245,8 @@ public: void computeSectionAddresses(const MCAssembler &Asm, const MCAsmLayout &Layout); + void markAbsoluteVariableSymbols(MCAssembler &Asm, + const MCAsmLayout &Layout); void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout); virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h index 74e2263..c8444fd 100644 --- a/include/llvm/MC/MCObjectFileInfo.h +++ b/include/llvm/MC/MCObjectFileInfo.h @@ -84,14 +84,6 @@ protected: /// this is the section to emit them into. const MCSection *CompactUnwindSection; - /// DwarfAccelNamesSection, DwarfAccelObjCSection - /// If we use the DWARF accelerated hash tables then we want toe emit these - /// sections. - const MCSection *DwarfAccelNamesSection; - const MCSection *DwarfAccelObjCSection; - const MCSection *DwarfAccelNamespaceSection; - const MCSection *DwarfAccelTypesSection; - // Dwarf sections for debug info. If a target supports debug info, these must // be set. const MCSection *DwarfAbbrevSection; @@ -106,6 +98,24 @@ protected: const MCSection *DwarfRangesSection; const MCSection *DwarfMacroInfoSection; + // DWARF5 Experimental Debug Info Sections + /// DwarfAccelNamesSection, DwarfAccelObjCSection, + /// DwarfAccelNamespaceSection, DwarfAccelTypesSection - + /// If we use the DWARF accelerated hash tables then we want to emit these + /// sections. + const MCSection *DwarfAccelNamesSection; + const MCSection *DwarfAccelObjCSection; + const MCSection *DwarfAccelNamespaceSection; + const MCSection *DwarfAccelTypesSection; + + /// These are used for the Fission separate debug information files. + const MCSection *DwarfInfoDWOSection; + const MCSection *DwarfAbbrevDWOSection; + const MCSection *DwarfStrDWOSection; + const MCSection *DwarfLineDWOSection; + const MCSection *DwarfLocDWOSection; + const MCSection *DwarfStrOffDWOSection; + // Extra TLS Variable Data section. If the target needs to put additional // information for a TLS variable, it'll go here. const MCSection *TLSExtraDataSection; @@ -194,18 +204,6 @@ public: const MCSection *getCompactUnwindSection() const{ return CompactUnwindSection; } - const MCSection *getDwarfAccelNamesSection() const { - return DwarfAccelNamesSection; - } - const MCSection *getDwarfAccelObjCSection() const { - return DwarfAccelObjCSection; - } - const MCSection *getDwarfAccelNamespaceSection() const { - return DwarfAccelNamespaceSection; - } - const MCSection *getDwarfAccelTypesSection() const { - return DwarfAccelTypesSection; - } const MCSection *getDwarfAbbrevSection() const { return DwarfAbbrevSection; } const MCSection *getDwarfInfoSection() const { return DwarfInfoSection; } const MCSection *getDwarfLineSection() const { return DwarfLineSection; } @@ -221,6 +219,39 @@ public: const MCSection *getDwarfMacroInfoSection() const { return DwarfMacroInfoSection; } + + // DWARF5 Experimental Debug Info Sections + const MCSection *getDwarfAccelNamesSection() const { + return DwarfAccelNamesSection; + } + const MCSection *getDwarfAccelObjCSection() const { + return DwarfAccelObjCSection; + } + const MCSection *getDwarfAccelNamespaceSection() const { + return DwarfAccelNamespaceSection; + } + const MCSection *getDwarfAccelTypesSection() const { + return DwarfAccelTypesSection; + } + const MCSection *getDwarfInfoDWOSection() const { + return DwarfInfoDWOSection; + } + const MCSection *getDwarfAbbrevDWOSection() const { + return DwarfAbbrevDWOSection; + } + const MCSection *getDwarfStrDWOSection() const { + return DwarfStrDWOSection; + } + const MCSection *getDwarfLineDWOSection() const { + return DwarfLineDWOSection; + } + const MCSection *getDwarfLocDWOSection() const { + return DwarfLocDWOSection; + } + const MCSection *getDwarfStrOffDWOSection() const { + return DwarfStrOffDWOSection; + } + const MCSection *getTLSExtraDataSection() const { return TLSExtraDataSection; } diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h index b59b76c..0ece092 100644 --- a/include/llvm/MC/MCObjectStreamer.h +++ b/include/llvm/MC/MCObjectStreamer.h @@ -45,6 +45,11 @@ protected: MCAssembler *_Assembler); ~MCObjectStreamer(); +public: + /// state management + virtual void reset(); + +protected: MCSectionData *getCurrentSectionData() const { return CurSectionData; } @@ -64,6 +69,8 @@ public: /// @{ virtual void EmitLabel(MCSymbol *Symbol); + virtual void EmitDebugLabel(MCSymbol *Symbol); + virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value); virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, unsigned AddrSpace); virtual void EmitULEB128Value(const MCExpr *Value); @@ -71,7 +78,21 @@ public: virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol); virtual void ChangeSection(const MCSection *Section); virtual void EmitInstruction(const MCInst &Inst); + + /// \brief Emit an instruction to a special fragment, because this instruction + /// can change its size during relaxation. virtual void EmitInstToFragment(const MCInst &Inst); + + virtual void EmitBundleAlignMode(unsigned AlignPow2); + virtual void EmitBundleLock(bool AlignToEnd); + virtual void EmitBundleUnlock(); + virtual void EmitBytes(StringRef Data, unsigned AddrSpace); + virtual void EmitValueToAlignment(unsigned ByteAlignment, + int64_t Value = 0, + unsigned ValueSize = 1, + unsigned MaxBytesToEmit = 0); + virtual void EmitCodeAlignment(unsigned ByteAlignment, + unsigned MaxBytesToEmit = 0); virtual bool EmitValueToOffset(const MCExpr *Offset, unsigned char Value); virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, @@ -81,6 +102,8 @@ public: const MCSymbol *Label); virtual void EmitGPRel32Value(const MCExpr *Value); virtual void EmitGPRel64Value(const MCExpr *Value); + virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue, + unsigned AddrSpace); virtual void FinishImpl(); /// @} diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h index 14fe75f..9d5c1a7 100644 --- a/include/llvm/MC/MCObjectWriter.h +++ b/include/llvm/MC/MCObjectWriter.h @@ -10,9 +10,9 @@ #ifndef LLVM_MC_MCOBJECTWRITER_H #define LLVM_MC_MCOBJECTWRITER_H -#include "llvm/Support/raw_ostream.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/raw_ostream.h" #include <cassert> namespace llvm { @@ -51,6 +51,9 @@ protected: // Can only create subclasses. public: virtual ~MCObjectWriter(); + /// lifetime management + virtual void reset() { } + bool isLittleEndian() const { return IsLittleEndian; } raw_ostream &getStream() { return OS; } @@ -173,7 +176,13 @@ public: OS << StringRef(Zeros, N % 16); } + void WriteBytes(SmallVectorImpl<char> &ByteVec, unsigned ZeroFillSize = 0) { + WriteBytes(StringRef(ByteVec.data(), ByteVec.size()), ZeroFillSize); + } + void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) { + // TODO: this version may need to go away once all fragment contents are + // converted to SmallVector<char, N> assert((ZeroFillSize == 0 || Str.size () <= ZeroFillSize) && "data size greater than fill size, unexpected large write will occur"); OS << Str; diff --git a/include/llvm/MC/MCParser/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h index ca163c5..37a69e2 100644 --- a/include/llvm/MC/MCParser/MCAsmLexer.h +++ b/include/llvm/MC/MCParser/MCAsmLexer.h @@ -34,12 +34,10 @@ public: // Real values. Real, - // Register values (stored in IntVal). Only used by MCTargetAsmLexer. - Register, - // No-value. EndOfStatement, Colon, + Space, Plus, Minus, Tilde, Slash, // '/' BackSlash, // '\' @@ -103,13 +101,6 @@ public: assert(Kind == Integer && "This token isn't an integer!"); return IntVal; } - - /// getRegVal - Get the register number for the current token, which should - /// be a register. - unsigned getRegVal() const { - assert(Kind == Register && "This token isn't a register!"); - return static_cast<unsigned>(IntVal); - } }; /// MCAsmLexer - Generic assembler lexer interface, for use by target specific @@ -126,6 +117,7 @@ class MCAsmLexer { void operator=(const MCAsmLexer &) LLVM_DELETED_FUNCTION; protected: // Can only create subclasses. const char *TokStart; + bool SkipSpace; MCAsmLexer(); @@ -170,11 +162,14 @@ public: /// getKind - Get the kind of current token. AsmToken::TokenKind getKind() const { return CurTok.getKind(); } - /// is - Check if the current token has kind \arg K. + /// is - Check if the current token has kind \p K. bool is(AsmToken::TokenKind K) const { return CurTok.is(K); } - /// isNot - Check if the current token has kind \arg K. + /// isNot - Check if the current token has kind \p K. bool isNot(AsmToken::TokenKind K) const { return CurTok.isNot(K); } + + /// setSkipSpace - Set whether spaces should be ignored by the lexer + void setSkipSpace(bool val) { SkipSpace = val; } }; } // End llvm namespace diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h index c673a79..b9490fa 100644 --- a/include/llvm/MC/MCParser/MCAsmParser.h +++ b/include/llvm/MC/MCParser/MCAsmParser.h @@ -10,8 +10,8 @@ #ifndef LLVM_MC_MCASMPARSER_H #define LLVM_MC_MCASMPARSER_H -#include "llvm/Support/DataTypes.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/DataTypes.h" namespace llvm { class AsmToken; @@ -20,6 +20,9 @@ class MCAsmLexer; class MCAsmParserExtension; class MCContext; class MCExpr; +class MCInstPrinter; +class MCInstrInfo; +class MCParsedAsmOperand; class MCStreamer; class MCTargetAsmParser; class SMLoc; @@ -28,6 +31,16 @@ class SourceMgr; class StringRef; class Twine; +/// MCAsmParserSemaCallback - Generic Sema callback for assembly parser. +class MCAsmParserSemaCallback { +public: + virtual ~MCAsmParserSemaCallback(); + virtual void *LookupInlineAsmIdentifier(StringRef Name, void *Loc, + unsigned &Size) = 0; + virtual bool LookupInlineAsmField(StringRef Base, StringRef Member, + unsigned &Offset) = 0; +}; + /// MCAsmParser - Generic assembler parser interface, for use by target specific /// assembly parsers. class MCAsmParser { @@ -73,15 +86,26 @@ public: /// Run - Run the parser on the input source buffer. virtual bool Run(bool NoInitialTextSection, bool NoFinalize = false) = 0; - /// Warning - Emit a warning at the location \arg L, with the message \arg - /// Msg. + virtual void setParsingInlineAsm(bool V) = 0; + virtual bool isParsingInlineAsm() = 0; + + /// ParseMSInlineAsm - Parse ms-style inline assembly. + virtual bool ParseMSInlineAsm(void *AsmLoc, std::string &AsmString, + unsigned &NumOutputs, unsigned &NumInputs, + SmallVectorImpl<std::pair<void *, bool> > &OpDecls, + SmallVectorImpl<std::string> &Constraints, + SmallVectorImpl<std::string> &Clobbers, + const MCInstrInfo *MII, + const MCInstPrinter *IP, + MCAsmParserSemaCallback &SI) = 0; + + /// Warning - Emit a warning at the location \p L, with the message \p Msg. /// /// \return The return value is true, if warnings are fatal. virtual bool Warning(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) = 0; - /// Error - Emit an error at the location \arg L, with the message \arg - /// Msg. + /// Error - Emit an error at the location \p L, with the message \p Msg. /// /// \return The return value is always true, as an idiomatic convenience to /// clients. @@ -100,7 +124,7 @@ public: ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()); /// ParseIdentifier - Parse an identifier or string (as a quoted identifier) - /// and set \arg Res to the identifier contents. + /// and set \p Res to the identifier contents. virtual bool ParseIdentifier(StringRef &Res) = 0; /// \brief Parse up to the end of statement and return the contents from the diff --git a/include/llvm/MC/MCParser/MCAsmParserExtension.h b/include/llvm/MC/MCParser/MCAsmParserExtension.h index 59593a8..84b33b5 100644 --- a/include/llvm/MC/MCParser/MCAsmParserExtension.h +++ b/include/llvm/MC/MCParser/MCAsmParserExtension.h @@ -10,8 +10,8 @@ #ifndef LLVM_MC_MCASMPARSEREXTENSION_H #define LLVM_MC_MCASMPARSEREXTENSION_H -#include "llvm/MC/MCParser/MCAsmParser.h" #include "llvm/ADT/StringRef.h" +#include "llvm/MC/MCParser/MCAsmParser.h" #include "llvm/Support/SMLoc.h" namespace llvm { @@ -43,8 +43,8 @@ protected: public: virtual ~MCAsmParserExtension(); - /// \brief Initialize the extension for parsing using the given \arg - /// Parser. The extension should use the AsmParser interfaces to register its + /// \brief Initialize the extension for parsing using the given \p Parser. + /// The extension should use the AsmParser interfaces to register its /// parsing routines. virtual void Initialize(MCAsmParser &Parser); diff --git a/include/llvm/MC/MCParser/MCParsedAsmOperand.h b/include/llvm/MC/MCParser/MCParsedAsmOperand.h index 2556e5f..60e7887 100644 --- a/include/llvm/MC/MCParser/MCParsedAsmOperand.h +++ b/include/llvm/MC/MCParser/MCParsedAsmOperand.h @@ -19,15 +19,69 @@ 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 { + /// MCOperandNum - The corresponding MCInst operand number. Only valid when + /// parsing MS-style inline assembly. + unsigned MCOperandNum; + + /// Constraint - The constraint on this operand. Only valid when parsing + /// MS-style inline assembly. + std::string Constraint; + public: MCParsedAsmOperand() {} virtual ~MCParsedAsmOperand() {} + void setConstraint(StringRef C) { Constraint = C.str(); } + StringRef getConstraint() { return Constraint; } + + void setMCOperandNum (unsigned OpNum) { MCOperandNum = OpNum; } + unsigned getMCOperandNum() { return MCOperandNum; } + + unsigned getNameLen() { + assert (getStartLoc().isValid() && "Invalid StartLoc!"); + assert (getEndLoc().isValid() && "Invalid EndLoc!"); + return getEndLoc().getPointer() - getStartLoc().getPointer(); + } + + StringRef getName() { + return StringRef(getStartLoc().getPointer(), getNameLen()); + } + + /// isToken - Is this a token operand? + virtual bool isToken() const = 0; + /// isImm - Is this an immediate operand? + virtual bool isImm() const = 0; + /// isReg - Is this a register operand? + virtual bool isReg() const = 0; + virtual unsigned getReg() const = 0; + + /// isMem - Is this a memory operand? + virtual bool isMem() const = 0; + virtual unsigned getMemSize() const { return 0; } + /// 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. virtual SMLoc getEndLoc() const = 0; + /// needAsmRewrite - AsmRewrites happen in both the target-independent and + /// target-dependent parsers. The target-independent parser calls this + /// function to determine if the target-dependent parser has already taken + /// care of the rewrites. Only valid when parsing MS-style inline assembly. + virtual bool needAsmRewrite() const { return true; } + + /// isOffsetOf - Do we need to emit code to get the offset of the variable, + /// rather then the value of the variable? Only valid when parsing MS-style + /// inline assembly. + virtual bool isOffsetOf() const { return false; } + + /// getOffsetOfLoc - Get the location of the offset operator. + virtual SMLoc getOffsetOfLoc() const { return SMLoc(); } + + /// needSizeDirective - Do we need to emit a sizing directive for this + /// operand? Only valid when parsing MS-style inline assembly. + virtual bool needSizeDirective() const { return false; } + /// print - Print a debug representation of the operand to the given stream. virtual void print(raw_ostream &OS) const = 0; /// dump - Print to the debug stream. diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h index 46a9d71..f5b4ddd 100644 --- a/include/llvm/MC/MCRegisterInfo.h +++ b/include/llvm/MC/MCRegisterInfo.h @@ -22,11 +22,15 @@ namespace llvm { +/// An unsigned integer type large enough to represent all physical registers, +/// but not necessarily virtual registers. +typedef uint16_t MCPhysReg; + /// MCRegisterClass - Base class of TargetRegisterClass. class MCRegisterClass { public: - typedef const uint16_t* iterator; - typedef const uint16_t* const_iterator; + typedef const MCPhysReg* iterator; + typedef const MCPhysReg* const_iterator; const char *Name; const iterator RegsBegin; @@ -148,11 +152,12 @@ private: const MCRegisterDesc *Desc; // Pointer to the descriptor array unsigned NumRegs; // Number of entries in the array unsigned RAReg; // Return address register + unsigned PCReg; // Program counter register const MCRegisterClass *Classes; // Pointer to the regclass array unsigned NumClasses; // Number of entries in the array unsigned NumRegUnits; // Number of regunits. const uint16_t (*RegUnitRoots)[2]; // Pointer to regunit root table. - const uint16_t *DiffLists; // Pointer to the difflists array + const MCPhysReg *DiffLists; // Pointer to the difflists array const char *RegStrings; // Pointer to the string table. const uint16_t *SubRegIndices; // Pointer to the subreg lookup // array. @@ -177,7 +182,7 @@ public: /// defined below. class DiffListIterator { uint16_t Val; - const uint16_t *List; + const MCPhysReg *List; protected: /// Create an invalid iterator. Call init() to point to something useful. @@ -186,7 +191,7 @@ public: /// init - Point the iterator to InitVal, decoding subsequent values from /// DiffList. The iterator will initially point to InitVal, sub-classes are /// responsible for skipping the seed value if it is not part of the list. - void init(uint16_t InitVal, const uint16_t *DiffList) { + void init(MCPhysReg InitVal, const MCPhysReg *DiffList) { Val = InitVal; List = DiffList; } @@ -196,7 +201,7 @@ public: /// is the caller's responsibility (by checking for a 0 return value). unsigned advance() { assert(isValid() && "Cannot move off the end of the list."); - uint16_t D = *List++; + MCPhysReg D = *List++; Val += D; return D; } @@ -225,13 +230,14 @@ public: friend class MCRegUnitIterator; friend class MCRegUnitRootIterator; - /// InitMCRegisterInfo - Initialize MCRegisterInfo, called by TableGen + /// \brief Initialize MCRegisterInfo, called by TableGen /// auto-generated routines. *DO NOT USE*. void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR, unsigned RA, + unsigned PC, const MCRegisterClass *C, unsigned NC, const uint16_t (*RURoots)[2], unsigned NRU, - const uint16_t *DL, + const MCPhysReg *DL, const char *Strings, const uint16_t *SubIndices, unsigned NumIndices, @@ -239,6 +245,7 @@ public: Desc = D; NumRegs = NR; RAReg = RA; + PCReg = PC; Classes = C; DiffLists = DL; RegStrings = Strings; @@ -250,7 +257,7 @@ public: RegEncodingTable = RET; } - /// mapLLVMRegsToDwarfRegs - Used to initialize LLVM register to Dwarf + /// \brief Used to initialize LLVM register to Dwarf /// register number mapping. Called by TableGen auto-generated routines. /// *DO NOT USE*. void mapLLVMRegsToDwarfRegs(const DwarfLLVMRegPair *Map, unsigned Size, @@ -264,7 +271,7 @@ public: } } - /// mapDwarfRegsToLLVMRegs - Used to initialize Dwarf register to LLVM + /// \brief Used to initialize Dwarf register to LLVM /// register number mapping. Called by TableGen auto-generated routines. /// *DO NOT USE*. void mapDwarfRegsToLLVMRegs(const DwarfLLVMRegPair *Map, unsigned Size, @@ -287,70 +294,80 @@ public: L2SEHRegs[LLVMReg] = SEHReg; } - /// getRARegister - This method should return the register where the return + /// \brief This method should return the register where the return /// address can be found. unsigned getRARegister() const { return RAReg; } + /// Return the register which is the program counter. + unsigned getProgramCounter() const { + return PCReg; + } + const MCRegisterDesc &operator[](unsigned RegNo) const { assert(RegNo < NumRegs && "Attempting to access record for invalid register number!"); return Desc[RegNo]; } - /// Provide a get method, equivalent to [], but more useful if we have a + /// \brief Provide a get method, equivalent to [], but more useful with a /// pointer to this object. - /// const MCRegisterDesc &get(unsigned RegNo) const { return operator[](RegNo); } - /// getSubReg - Returns the physical register number of sub-register "Index" + /// \brief Returns the physical register number of sub-register "Index" /// for physical register RegNo. Return zero if the sub-register does not /// exist. unsigned getSubReg(unsigned Reg, unsigned Idx) const; - /// getMatchingSuperReg - Return a super-register of the specified register + /// \brief Return a super-register of the specified register /// Reg so its sub-register of index SubIdx is Reg. unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx, const MCRegisterClass *RC) const; - /// getSubRegIndex - For a given register pair, return the sub-register index + /// \brief For a given register pair, return the sub-register index /// if the second register is a sub-register of the first. Return zero /// otherwise. unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const; - /// getName - Return the human-readable symbolic target-specific name for the + /// \brief Return the human-readable symbolic target-specific name for the /// specified physical register. const char *getName(unsigned RegNo) const { return RegStrings + get(RegNo).Name; } - /// getNumRegs - Return the number of registers this target has (useful for + /// \brief Return the number of registers this target has (useful for /// sizing arrays holding per register information) unsigned getNumRegs() const { return NumRegs; } - /// getNumRegUnits - Return the number of (native) register units in the + /// \brief Return the number of sub-register indices + /// understood by the target. Index 0 is reserved for the no-op sub-register, + /// while 1 to getNumSubRegIndices() - 1 represent real sub-registers. + unsigned getNumSubRegIndices() const { + return NumSubRegIndices; + } + + /// \brief Return the number of (native) register units in the /// target. Register units are numbered from 0 to getNumRegUnits() - 1. They /// can be accessed through MCRegUnitIterator defined below. unsigned getNumRegUnits() const { return NumRegUnits; } - /// getDwarfRegNum - Map a target register to an equivalent dwarf register + /// \brief Map a target register to an equivalent dwarf register /// number. Returns -1 if there is no equivalent value. The second /// parameter allows targets to use different numberings for EH info and /// debugging info. int getDwarfRegNum(unsigned RegNum, bool isEH) const; - /// getLLVMRegNum - Map a dwarf register back to a target register. - /// + /// \brief Map a dwarf register back to a target register. int getLLVMRegNum(unsigned RegNum, bool isEH) const; - /// getSEHRegNum - Map a target register to an equivalent SEH register + /// \brief Map a target register to an equivalent SEH register /// number. Returns LLVM register number if there is no equivalent value. int getSEHRegNum(unsigned RegNum) const; @@ -361,20 +378,39 @@ public: return (unsigned)(regclass_end()-regclass_begin()); } - /// getRegClass - Returns the register class associated with the enumeration + /// \brief Returns the register class associated with the enumeration /// value. See class MCOperandInfo. - const MCRegisterClass getRegClass(unsigned i) const { + const MCRegisterClass& getRegClass(unsigned i) const { assert(i < getNumRegClasses() && "Register Class ID out of range"); return Classes[i]; } - /// getEncodingValue - Returns the encoding for RegNo + /// \brief Returns the encoding for RegNo uint16_t getEncodingValue(unsigned RegNo) const { assert(RegNo < NumRegs && "Attempting to get encoding for invalid register number!"); return RegEncodingTable[RegNo]; } + /// \brief Returns true if RegB is a sub-register of RegA. + bool isSubRegister(unsigned RegA, unsigned RegB) const { + return isSuperRegister(RegB, RegA); + } + + /// \brief Returns true if RegB is a super-register of RegA. + bool isSuperRegister(unsigned RegA, unsigned RegB) const; + + /// \brief Returns true if RegB is a sub-register of RegA or if RegB == RegA. + bool isSubRegisterEq(unsigned RegA, unsigned RegB) const { + return isSuperRegisterEq(RegB, RegA); + } + + /// \brief Returns true if RegB is a super-register of RegA or if + /// RegB == RegA. + bool isSuperRegisterEq(unsigned RegA, unsigned RegB) const { + return RegA == RegB || isSuperRegister(RegA, RegB); + } + }; //===----------------------------------------------------------------------===// @@ -415,6 +451,15 @@ public: } }; +// Definition for isSuperRegister. Put it down here since it needs the +// iterator defined above in addition to the MCRegisterInfo class itself. +inline bool MCRegisterInfo::isSuperRegister(unsigned RegA, unsigned RegB) const{ + for (MCSuperRegIterator I(RegA, this); I.isValid(); ++I) + if (*I == RegB) + return true; + return false; +} + //===----------------------------------------------------------------------===// // Register Units //===----------------------------------------------------------------------===// @@ -434,6 +479,7 @@ public: /// MCRegUnitIterator - Create an iterator that traverses the register units /// in Reg. MCRegUnitIterator(unsigned Reg, const MCRegisterInfo *MCRI) { + assert(Reg && "Null register has no regunits"); // Decode the RegUnits MCRegisterDesc field. unsigned RU = MCRI->get(Reg).RegUnits; unsigned Scale = RU & 15; @@ -473,17 +519,17 @@ public: Reg1 = MCRI->RegUnitRoots[RegUnit][1]; } - /// Dereference to get the current root register. + /// \brief Dereference to get the current root register. unsigned operator*() const { return Reg0; } - /// isValid - Check if the iterator is at the end of the list. + /// \brief Check if the iterator is at the end of the list. bool isValid() const { return Reg0; } - /// Preincrement to move to the next root register. + /// \brief Preincrement to move to the next root register. void operator++() { assert(isValid() && "Cannot move off the end of the list."); Reg0 = Reg1; diff --git a/include/llvm/MC/MCSchedule.h b/include/llvm/MC/MCSchedule.h index 3b1cdf1..0c71ee5 100644 --- a/include/llvm/MC/MCSchedule.h +++ b/include/llvm/MC/MCSchedule.h @@ -16,17 +16,111 @@ #define LLVM_MC_MCSCHEDMODEL_H #include "llvm/Support/DataTypes.h" +#include <cassert> namespace llvm { struct InstrItinerary; +/// Define a kind of processor resource that will be modeled by the scheduler. +struct MCProcResourceDesc { +#ifndef NDEBUG + const char *Name; +#endif + unsigned NumUnits; // Number of resource of this kind + unsigned SuperIdx; // Index of the resources kind that contains this kind. + + // Buffered resources may be consumed at some indeterminate cycle after + // dispatch (e.g. for instructions that may issue out-of-order). Unbuffered + // resources always consume their resource some fixed number of cycles after + // dispatch (e.g. for instruction interlocking that may stall the pipeline). + bool IsBuffered; + + bool operator==(const MCProcResourceDesc &Other) const { + return NumUnits == Other.NumUnits && SuperIdx == Other.SuperIdx + && IsBuffered == Other.IsBuffered; + } +}; + +/// Identify one of the processor resource kinds consumed by a particular +/// scheduling class for the specified number of cycles. +struct MCWriteProcResEntry { + unsigned ProcResourceIdx; + unsigned Cycles; + + bool operator==(const MCWriteProcResEntry &Other) const { + return ProcResourceIdx == Other.ProcResourceIdx && Cycles == Other.Cycles; + } +}; + +/// Specify the latency in cpu cycles for a particular scheduling class and def +/// index. -1 indicates an invalid latency. Heuristics would typically consider +/// an instruction with invalid latency to have infinite latency. Also identify +/// the WriteResources of this def. When the operand expands to a sequence of +/// writes, this ID is the last write in the sequence. +struct MCWriteLatencyEntry { + int Cycles; + unsigned WriteResourceID; + + bool operator==(const MCWriteLatencyEntry &Other) const { + return Cycles == Other.Cycles && WriteResourceID == Other.WriteResourceID; + } +}; + +/// Specify the number of cycles allowed after instruction issue before a +/// particular use operand reads its registers. This effectively reduces the +/// write's latency. Here we allow negative cycles for corner cases where +/// latency increases. This rule only applies when the entry's WriteResource +/// matches the write's WriteResource. +/// +/// MCReadAdvanceEntries are sorted first by operand index (UseIdx), then by +/// WriteResourceIdx. +struct MCReadAdvanceEntry { + unsigned UseIdx; + unsigned WriteResourceID; + int Cycles; + + bool operator==(const MCReadAdvanceEntry &Other) const { + return UseIdx == Other.UseIdx && WriteResourceID == Other.WriteResourceID + && Cycles == Other.Cycles; + } +}; + +/// Summarize the scheduling resources required for an instruction of a +/// particular scheduling class. +/// +/// Defined as an aggregate struct for creating tables with initializer lists. +struct MCSchedClassDesc { + static const unsigned short InvalidNumMicroOps = UINT16_MAX; + static const unsigned short VariantNumMicroOps = UINT16_MAX - 1; + +#ifndef NDEBUG + const char* Name; +#endif + unsigned short NumMicroOps; + bool BeginGroup; + bool EndGroup; + unsigned WriteProcResIdx; // First index into WriteProcResTable. + unsigned NumWriteProcResEntries; + unsigned WriteLatencyIdx; // First index into WriteLatencyTable. + unsigned NumWriteLatencyEntries; + unsigned ReadAdvanceIdx; // First index into ReadAdvanceTable. + unsigned NumReadAdvanceEntries; + + bool isValid() const { + return NumMicroOps != InvalidNumMicroOps; + } + bool isVariant() const { + return NumMicroOps == VariantNumMicroOps; + } +}; + /// Machine model for scheduling, bundling, and heuristics. /// /// The machine model directly provides basic information about the /// microarchitecture to the scheduler in the form of properties. It also -/// optionally refers to scheduler resources tables and itinerary -/// tables. Scheduler resources tables model the latency and cost for each +/// optionally refers to scheduler resource tables and itinerary +/// tables. Scheduler resource tables model the latency and cost for each /// instruction type. Itinerary tables are an independant mechanism that /// provides a detailed reservation table describing each cycle of instruction /// execution. Subtargets may define any or all of the above categories of data @@ -84,8 +178,11 @@ public: static const unsigned DefaultMispredictPenalty = 10; private: - // TODO: Add a reference to proc resource types and sched resource tables. - + unsigned ProcID; + const MCProcResourceDesc *ProcResourceTable; + const MCSchedClassDesc *SchedClassTable; + unsigned NumProcResourceKinds; + unsigned NumSchedClasses; // Instruction itinerary tables used by InstrItineraryData. friend class InstrItineraryData; const InstrItinerary *InstrItineraries; @@ -100,13 +197,45 @@ public: LoadLatency(DefaultLoadLatency), HighLatency(DefaultHighLatency), MispredictPenalty(DefaultMispredictPenalty), - InstrItineraries(0) {} + ProcID(0), ProcResourceTable(0), SchedClassTable(0), + NumProcResourceKinds(0), NumSchedClasses(0), + InstrItineraries(0) { + (void)NumProcResourceKinds; + (void)NumSchedClasses; + } // Table-gen driven ctor. MCSchedModel(unsigned iw, int ml, unsigned ll, unsigned hl, unsigned mp, + unsigned pi, const MCProcResourceDesc *pr, + const MCSchedClassDesc *sc, unsigned npr, unsigned nsc, const InstrItinerary *ii): IssueWidth(iw), MinLatency(ml), LoadLatency(ll), HighLatency(hl), - MispredictPenalty(mp), InstrItineraries(ii){} + MispredictPenalty(mp), ProcID(pi), ProcResourceTable(pr), + SchedClassTable(sc), NumProcResourceKinds(npr), NumSchedClasses(nsc), + InstrItineraries(ii) {} + + unsigned getProcessorID() const { return ProcID; } + + /// Does this machine model include instruction-level scheduling. + bool hasInstrSchedModel() const { return SchedClassTable; } + + unsigned getNumProcResourceKinds() const { + return NumProcResourceKinds; + } + + const MCProcResourceDesc *getProcResource(unsigned ProcResourceIdx) const { + assert(hasInstrSchedModel() && "No scheduling machine model"); + + assert(ProcResourceIdx < NumProcResourceKinds && "bad proc resource idx"); + return &ProcResourceTable[ProcResourceIdx]; + } + + const MCSchedClassDesc *getSchedClassDesc(unsigned SchedClassIdx) const { + assert(hasInstrSchedModel() && "No scheduling machine model"); + + assert(SchedClassIdx < NumSchedClasses && "bad scheduling class idx"); + return &SchedClassTable[SchedClassIdx]; + } }; } // End llvm namespace diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h index f90ad6a..5d6cac2 100644 --- a/include/llvm/MC/MCSection.h +++ b/include/llvm/MC/MCSection.h @@ -14,6 +14,7 @@ #ifndef LLVM_MC_MCSECTION_H #define LLVM_MC_MCSECTION_H +#include "llvm/ADT/StringRef.h" #include "llvm/MC/SectionKind.h" #include "llvm/Support/Compiler.h" @@ -50,6 +51,11 @@ namespace llvm { virtual void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS) const = 0; + // Convenience routines to get label names for the beginning/end of a + // section. + virtual std::string getLabelBeginName() const = 0; + virtual std::string getLabelEndName() const = 0; + /// isBaseAddressKnownZero - Return true if we know that this section will /// get a base address of zero. In cases where we know that this is true we /// can emit section offsets as direct references to avoid a subtraction @@ -65,8 +71,6 @@ namespace llvm { /// 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; } }; } // end namespace llvm diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h index 7eacde5..07c4714 100644 --- a/include/llvm/MC/MCSectionCOFF.h +++ b/include/llvm/MC/MCSectionCOFF.h @@ -14,9 +14,9 @@ #ifndef LLVM_MC_MCSECTIONCOFF_H #define LLVM_MC_MCSECTIONCOFF_H +#include "llvm/ADT/StringRef.h" #include "llvm/MC/MCSection.h" #include "llvm/Support/COFF.h" -#include "llvm/ADT/StringRef.h" namespace llvm { @@ -50,6 +50,12 @@ namespace llvm { bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const; StringRef getSectionName() const { return SectionName; } + virtual std::string getLabelBeginName() const { + return SectionName.str() + "_begin"; + } + virtual std::string getLabelEndName() const { + return SectionName.str() + "_end"; + } unsigned getCharacteristics() const { return Characteristics; } int getSelection () const { return Selection; } @@ -61,7 +67,6 @@ namespace llvm { static bool classof(const MCSection *S) { return S->getVariant() == SV_COFF; } - static bool classof(const MCSectionCOFF *) { return true; } }; } // end namespace llvm diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h index 7321ca8..4b8b849 100644 --- a/include/llvm/MC/MCSectionELF.h +++ b/include/llvm/MC/MCSectionELF.h @@ -14,9 +14,11 @@ #ifndef LLVM_MC_MCSECTIONELF_H #define LLVM_MC_MCSECTIONELF_H +#include "llvm/ADT/StringRef.h" #include "llvm/MC/MCSection.h" +#include "llvm/Support/Debug.h" #include "llvm/Support/ELF.h" -#include "llvm/ADT/StringRef.h" +#include "llvm/Support/raw_ostream.h" namespace llvm { @@ -57,6 +59,11 @@ public: bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const; StringRef getSectionName() const { return SectionName; } + virtual std::string getLabelBeginName() const { + return SectionName.str() + "_begin"; } + virtual std::string getLabelEndName() const { + return SectionName.str() + "_end"; + } unsigned getType() const { return Type; } unsigned getFlags() const { return Flags; } unsigned getEntrySize() const { return EntrySize; } @@ -76,7 +83,6 @@ public: static bool classof(const MCSection *S) { return S->getVariant() == SV_ELF; } - static bool classof(const MCSectionELF *) { return true; } // Return the entry size for sections with fixed-width data. static unsigned DetermineEntrySize(SectionKind Kind); diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h index 15eb4f4..898f571 100644 --- a/include/llvm/MC/MCSectionMachO.h +++ b/include/llvm/MC/MCSectionMachO.h @@ -14,8 +14,8 @@ #ifndef LLVM_MC_MCSECTIONMACHO_H #define LLVM_MC_MCSECTIONMACHO_H -#include "llvm/MC/MCSection.h" #include "llvm/ADT/StringRef.h" +#include "llvm/MC/MCSection.h" namespace llvm { @@ -145,6 +145,14 @@ public: return StringRef(SectionName); } + virtual std::string getLabelBeginName() const { + return StringRef(getSegmentName().str() + getSectionName().str() + "_begin"); + } + + virtual std::string getLabelEndName() const { + return StringRef(getSegmentName().str() + getSectionName().str() + "_end"); + } + unsigned getTypeAndAttributes() const { return TypeAndAttributes; } unsigned getStubSize() const { return Reserved2; } @@ -174,7 +182,6 @@ public: static bool classof(const MCSection *S) { return S->getVariant() == SV_MachO; } - static bool classof(const MCSectionMachO *) { return true; } }; } // end namespace llvm diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 91593b9..05a33c5 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -14,12 +14,12 @@ #ifndef LLVM_MC_MCSTREAMER_H #define LLVM_MC_MCSTREAMER_H -#include "llvm/Support/DataTypes.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/MC/MCDirectives.h" #include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCWin64EH.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/DataTypes.h" namespace llvm { class MCAsmBackend; @@ -55,6 +55,7 @@ namespace llvm { std::vector<MCDwarfFrameInfo> FrameInfos; MCDwarfFrameInfo *getCurrentFrameInfo(); + MCSymbol *EmitCFICommon(); void EnsureValidFrame(); std::vector<MCWin64EHUnwindInfo *> W64UnwindInfos; @@ -69,6 +70,8 @@ namespace llvm { SmallVector<std::pair<const MCSection *, const MCSection *>, 4> SectionStack; + bool AutoInitSections; + protected: MCStreamer(MCContext &Ctx); @@ -89,6 +92,10 @@ namespace llvm { public: virtual ~MCStreamer(); + /// State management + /// + virtual void reset(); + MCContext &getContext() const { return Context; } unsigned getNumFrameInfos() { @@ -213,6 +220,17 @@ namespace llvm { SectionStack.back().first = Section; } + /// Initialize the streamer. + void InitStreamer() { + if (AutoInitSections) + InitSections(); + } + + /// Tell this MCStreamer to call InitSections upon initialization. + void setAutoInitSections(bool AutoInitSections) { + this->AutoInitSections = AutoInitSections; + } + /// InitSections - Create the default sections and set the initial one. virtual void InitSections() = 0; @@ -226,6 +244,8 @@ namespace llvm { /// used in an assignment. virtual void EmitLabel(MCSymbol *Symbol); + virtual void EmitDebugLabel(MCSymbol *Symbol); + virtual void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol); @@ -342,7 +362,7 @@ namespace llvm { /// @name Generating Data /// @{ - /// EmitBytes - Emit the bytes in \arg Data into the output. + /// EmitBytes - Emit the bytes in \p Data into the output. /// /// This is used to implement assembler directives such as .byte, .ascii, /// etc. @@ -417,7 +437,6 @@ namespace llvm { EmitFill(NumBytes, 0, AddrSpace); } - /// EmitValueToAlignment - Emit some number of copies of @p Value until /// the byte alignment @p ByteAlignment is reached. /// @@ -515,6 +534,8 @@ namespace llvm { virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment); virtual void EmitCFIEscape(StringRef Values); virtual void EmitCFISignalFrame(); + virtual void EmitCFIUndefined(int64_t Register); + virtual void EmitCFIRegister(int64_t Register1, int64_t Register2); virtual void EmitWin64EHStartProc(const MCSymbol *Symbol); virtual void EmitWin64EHEndProc(); @@ -535,6 +556,20 @@ namespace llvm { /// section. virtual void EmitInstruction(const MCInst &Inst) = 0; + /// \brief Set the bundle alignment mode from now on in the section. + /// The argument is the power of 2 to which the alignment is set. The + /// value 0 means turn the bundle alignment off. + virtual void EmitBundleAlignMode(unsigned AlignPow2) = 0; + + /// \brief The following instructions are a bundle-locked group. + /// + /// \param AlignToEnd - If true, the bundle-locked group will be aligned to + /// the end of a bundle. + virtual void EmitBundleLock(bool AlignToEnd) = 0; + + /// \brief Ends a bundle-locked group. + virtual void EmitBundleUnlock() = 0; + /// EmitRawText - If this file is backed by a assembly streamer, this dumps /// the specified string in the output .s file. This capability is /// indicated by the hasRawTextSupport() predicate. By default this aborts. @@ -554,6 +589,11 @@ namespace llvm { virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool isVector); + /// PPC-related methods. + /// FIXME: Eventually replace it with some "target MC streamer" and move + /// these methods there. + virtual void EmitTCEntry(const MCSymbol &S); + /// FinishImpl - Streamer specific finalization. virtual void FinishImpl() = 0; /// Finish - Finish emission of machine code. @@ -573,11 +613,11 @@ namespace llvm { /// InstPrint. /// /// \param CE - If given, a code emitter to use to show the instruction - /// encoding inline with the assembly. This method takes ownership of \arg CE. + /// encoding inline with the assembly. This method takes ownership of \p CE. /// /// \param TAB - If given, a target asm backend to use to show the fixup /// information in conjunction with encoding information. This method takes - /// ownership of \arg TAB. + /// ownership of \p TAB. /// /// \param ShowInst - Whether to show the MCInst representation inline with /// the assembly. @@ -594,7 +634,7 @@ namespace llvm { /// createMachOStreamer - Create a machine code streamer which will generate /// Mach-O format object files. /// - /// Takes ownership of \arg TAB and \arg CE. + /// Takes ownership of \p TAB and \p CE. MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *CE, bool RelaxAll = false); @@ -602,7 +642,7 @@ namespace llvm { /// createWinCOFFStreamer - Create a machine code streamer which will /// generate Microsoft COFF format object files. /// - /// Takes ownership of \arg TAB and \arg CE. + /// Takes ownership of \p TAB and \p CE. MCStreamer *createWinCOFFStreamer(MCContext &Ctx, MCAsmBackend &TAB, MCCodeEmitter &CE, raw_ostream &OS, @@ -617,7 +657,7 @@ namespace llvm { /// 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. + /// Takes ownership of \p TAB and \p CE. MCStreamer *createPureStreamer(MCContext &Ctx, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *CE); diff --git a/include/llvm/MC/MCSubtargetInfo.h b/include/llvm/MC/MCSubtargetInfo.h index 6c96f49..346fb2d 100644 --- a/include/llvm/MC/MCSubtargetInfo.h +++ b/include/llvm/MC/MCSubtargetInfo.h @@ -14,8 +14,8 @@ #ifndef LLVM_MC_MCSUBTARGET_H #define LLVM_MC_MCSUBTARGET_H -#include "llvm/MC/SubtargetFeature.h" #include "llvm/MC/MCInstrItineraries.h" +#include "llvm/MC/SubtargetFeature.h" #include <string> namespace llvm { @@ -30,7 +30,14 @@ class MCSubtargetInfo { std::string TargetTriple; // Target triple const SubtargetFeatureKV *ProcFeatures; // Processor feature list const SubtargetFeatureKV *ProcDesc; // Processor descriptions - const SubtargetInfoKV *ProcSchedModel; // Scheduler machine model + + // Scheduler machine model + const SubtargetInfoKV *ProcSchedModels; + const MCWriteProcResEntry *WriteProcResTable; + const MCWriteLatencyEntry *WriteLatencyTable; + const MCReadAdvanceEntry *ReadAdvanceTable; + const MCSchedModel *CPUSchedModel; + const InstrStage *Stages; // Instruction itinerary stages const unsigned *OperandCycles; // Itinerary operand cycles const unsigned *ForwardingPaths; // Forwarding paths @@ -43,6 +50,9 @@ public: const SubtargetFeatureKV *PF, const SubtargetFeatureKV *PD, const SubtargetInfoKV *ProcSched, + const MCWriteProcResEntry *WPR, + const MCWriteLatencyEntry *WL, + const MCReadAdvanceEntry *RA, const InstrStage *IS, const unsigned *OC, const unsigned *FP, unsigned NF, unsigned NP); @@ -58,9 +68,9 @@ public: return FeatureBits; } - /// ReInitMCSubtargetInfo - Change CPU (and optionally supplemented with - /// feature string), recompute and return feature bits. - uint64_t ReInitMCSubtargetInfo(StringRef CPU, StringRef FS); + /// InitMCProcessorInfo - Set or change the CPU (optionally supplemented with + /// feature string). Recompute feature bits and scheduling model. + void InitMCProcessorInfo(StringRef CPU, StringRef FS); /// ToggleFeature - Toggle a feature and returns the re-computed feature /// bits. This version does not change the implied bits. @@ -74,9 +84,54 @@ public: /// const MCSchedModel *getSchedModelForCPU(StringRef CPU) const; + /// getSchedModel - Get the machine model for this subtarget's CPU. + /// + const MCSchedModel *getSchedModel() const { return CPUSchedModel; } + + /// Return an iterator at the first process resource consumed by the given + /// scheduling class. + const MCWriteProcResEntry *getWriteProcResBegin( + const MCSchedClassDesc *SC) const { + return &WriteProcResTable[SC->WriteProcResIdx]; + } + const MCWriteProcResEntry *getWriteProcResEnd( + const MCSchedClassDesc *SC) const { + return getWriteProcResBegin(SC) + SC->NumWriteProcResEntries; + } + + const MCWriteLatencyEntry *getWriteLatencyEntry(const MCSchedClassDesc *SC, + unsigned DefIdx) const { + assert(DefIdx < SC->NumWriteLatencyEntries && + "MachineModel does not specify a WriteResource for DefIdx"); + + return &WriteLatencyTable[SC->WriteLatencyIdx + DefIdx]; + } + + int getReadAdvanceCycles(const MCSchedClassDesc *SC, unsigned UseIdx, + unsigned WriteResID) const { + // TODO: The number of read advance entries in a class can be significant + // (~50). Consider compressing the WriteID into a dense ID of those that are + // used by ReadAdvance and representing them as a bitset. + for (const MCReadAdvanceEntry *I = &ReadAdvanceTable[SC->ReadAdvanceIdx], + *E = I + SC->NumReadAdvanceEntries; I != E; ++I) { + if (I->UseIdx < UseIdx) + continue; + if (I->UseIdx > UseIdx) + break; + // Find the first WriteResIdx match, which has the highest cycle count. + if (!I->WriteResourceID || I->WriteResourceID == WriteResID) { + return I->Cycles; + } + } + return 0; + } + /// getInstrItineraryForCPU - Get scheduling itinerary of a CPU. /// InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const; + + /// Initialize an InstrItineraryData instance. + void initInstrItins(InstrItineraryData &InstrItins) const; }; } // End llvm namespace diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h index 4c9e7f5..fe92755 100644 --- a/include/llvm/MC/MCSymbol.h +++ b/include/llvm/MC/MCSymbol.h @@ -113,7 +113,7 @@ namespace llvm { return *Section; } - /// setSection - Mark the symbol as defined in the section \arg S. + /// setSection - Mark the symbol as defined in the section \p S. void setSection(const MCSection &S) { Section = &S; } /// setUndefined - Mark the symbol as undefined. @@ -133,7 +133,7 @@ namespace llvm { return Value != 0; } - /// getValue() - Get the value for variable symbols. + /// getVariableValue() - Get the value for variable symbols. const MCExpr *getVariableValue() const { assert(isVariable() && "Invalid accessor!"); IsUsed = true; @@ -149,7 +149,7 @@ namespace llvm { /// @} - /// print - Print the value to the stream \arg OS. + /// print - Print the value to the stream \p OS. void print(raw_ostream &OS) const; /// dump - Print the value to stderr. diff --git a/include/llvm/MC/MCTargetAsmLexer.h b/include/llvm/MC/MCTargetAsmLexer.h deleted file mode 100644 index d09fe04..0000000 --- a/include/llvm/MC/MCTargetAsmLexer.h +++ /dev/null @@ -1,89 +0,0 @@ -//===-- llvm/MC/MCTargetAsmLexer.h - Target Assembly Lexer ------*- 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_MCTARGETASMLEXER_H -#define LLVM_MC_MCTARGETASMLEXER_H - -#include "llvm/MC/MCParser/MCAsmLexer.h" - -namespace llvm { -class Target; - -/// MCTargetAsmLexer - Generic interface to target specific assembly lexers. -class MCTargetAsmLexer { - /// The current token - AsmToken CurTok; - - /// The location and description of the current error - SMLoc ErrLoc; - std::string Err; - - MCTargetAsmLexer(const MCTargetAsmLexer &) LLVM_DELETED_FUNCTION; - void operator=(const MCTargetAsmLexer &) LLVM_DELETED_FUNCTION; -protected: // Can only create subclasses. - MCTargetAsmLexer(const Target &); - - virtual AsmToken LexToken() = 0; - - void SetError(const SMLoc &errLoc, const std::string &err) { - ErrLoc = errLoc; - Err = err; - } - - /// TheTarget - The Target that this machine was created for. - const Target &TheTarget; - MCAsmLexer *Lexer; - -public: - virtual ~MCTargetAsmLexer(); - - const Target &getTarget() const { return TheTarget; } - - /// InstallLexer - Set the lexer to get tokens from lower-level lexer \arg L. - void InstallLexer(MCAsmLexer &L) { - Lexer = &L; - } - - MCAsmLexer *getLexer() { - return Lexer; - } - - /// Lex - Consume the next token from the input stream and return it. - const AsmToken &Lex() { - return CurTok = LexToken(); - } - - /// getTok - Get the current (last) lexed token. - 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; - } - - /// getKind - Get the kind of current token. - AsmToken::TokenKind getKind() const { return CurTok.getKind(); } - - /// is - Check if the current token has kind \arg K. - bool is(AsmToken::TokenKind K) const { return CurTok.is(K); } - - /// isNot - Check if the current token has kind \arg K. - bool isNot(AsmToken::TokenKind K) const { return CurTok.isNot(K); } -}; - -} // End llvm namespace - -#endif diff --git a/include/llvm/MC/MCTargetAsmParser.h b/include/llvm/MC/MCTargetAsmParser.h index 709c2d2..483a80b 100644 --- a/include/llvm/MC/MCTargetAsmParser.h +++ b/include/llvm/MC/MCTargetAsmParser.h @@ -21,6 +21,39 @@ class MCParsedAsmOperand; class MCInst; template <typename T> class SmallVectorImpl; +enum AsmRewriteKind { + AOK_DotOperator, // Rewrite a dot operator expression as an immediate. + // E.g., [eax].foo.bar -> [eax].8 + AOK_Emit, // Rewrite _emit as .byte. + AOK_Imm, // Rewrite as $$N. + AOK_ImmPrefix, // Add $$ before a parsed Imm. + AOK_Input, // Rewrite in terms of $N. + AOK_Output, // Rewrite in terms of $N. + AOK_SizeDirective, // Add a sizing directive (e.g., dword ptr). + AOK_Skip // Skip emission (e.g., offset/type operators). +}; + +struct AsmRewrite { + AsmRewriteKind Kind; + SMLoc Loc; + unsigned Len; + unsigned Val; +public: + AsmRewrite(AsmRewriteKind kind, SMLoc loc, unsigned len = 0, unsigned val = 0) + : Kind(kind), Loc(loc), Len(len), Val(val) {} +}; + +struct ParseInstructionInfo { + + SmallVectorImpl<AsmRewrite> *AsmRewrites; + + ParseInstructionInfo() : AsmRewrites(0) {} + ParseInstructionInfo(SmallVectorImpl<AsmRewrite> *rewrites) + : AsmRewrites(rewrites) {} + + ~ParseInstructionInfo() {} +}; + /// MCTargetAsmParser - Generic interface to target specific assembly parsers. class MCTargetAsmParser : public MCAsmParserExtension { public: @@ -41,12 +74,26 @@ protected: // Can only create subclasses. /// AvailableFeatures - The current set of available features. unsigned AvailableFeatures; + /// ParsingInlineAsm - Are we parsing ms-style inline assembly? + bool ParsingInlineAsm; + + /// SemaCallback - The Sema callback implementation. Must be set when parsing + /// ms-style inline assembly. + MCAsmParserSemaCallback *SemaCallback; + public: virtual ~MCTargetAsmParser(); unsigned getAvailableFeatures() const { return AvailableFeatures; } void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; } + bool isParsingInlineAsm () { return ParsingInlineAsm; } + void setParsingInlineAsm (bool Value) { ParsingInlineAsm = Value; } + + void setSemaCallback(MCAsmParserSemaCallback *Callback) { + SemaCallback = Callback; + } + virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) = 0; @@ -63,7 +110,8 @@ public: /// \param Operands [out] - The list of parsed operands, this returns /// ownership of them to the caller. /// \return True on failure. - virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc, + virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, + SMLoc NameLoc, SmallVectorImpl<MCParsedAsmOperand*> &Operands) = 0; /// ParseDirective - Parse a target specific assembler directive @@ -78,21 +126,9 @@ public: /// \param DirectiveID - the identifier token of the directive. virtual bool ParseDirective(AsmToken DirectiveID) = 0; - /// MatchInstruction - Recognize a series of operands of a parsed instruction - /// as an actual MCInst. This returns false on success and returns true on - /// failure to match. - /// - /// On failure, the target parser is responsible for emitting a diagnostic - /// explaining the match failure. - virtual bool - MatchInstruction(SMLoc IDLoc, unsigned &Kind, - SmallVectorImpl<MCParsedAsmOperand*> &Operands, - SmallVectorImpl<MCInst> &MCInsts, - unsigned &OrigErrorInfo, - bool matchingInlineAsm = false) { - OrigErrorInfo = ~0x0; - return true; - } + /// mnemonicIsValid - This returns true if this is a valid mnemonic and false + /// otherwise. + virtual bool mnemonicIsValid(StringRef Mnemonic) = 0; /// MatchAndEmitInstruction - Recognize a series of operands of a parsed /// instruction as an actual MCInst and emit it to the specified MCStreamer. @@ -101,9 +137,10 @@ public: /// On failure, the target parser is responsible for emitting a diagnostic /// explaining the match failure. virtual bool - MatchAndEmitInstruction(SMLoc IDLoc, + MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, SmallVectorImpl<MCParsedAsmOperand*> &Operands, - MCStreamer &Out) = 0; + MCStreamer &Out, unsigned &ErrorInfo, + bool MatchingInlineAsm) = 0; /// checkTargetMatchPredicate - Validate the instruction match against /// any complex target predicates not expressible via match classes. @@ -111,10 +148,8 @@ public: return Match_Success; } - virtual unsigned getMCInstOperandNum(unsigned Kind, MCInst &Inst, - const SmallVectorImpl<MCParsedAsmOperand*> &Operands, - unsigned OperandNum, - unsigned &NumMCOperands) = 0; + virtual void convertToMapAndConstraints(unsigned Kind, + const SmallVectorImpl<MCParsedAsmOperand*> &Operands) = 0; }; } // End llvm namespace diff --git a/include/llvm/MC/MCValue.h b/include/llvm/MC/MCValue.h index 8352ed1..a4e7301 100644 --- a/include/llvm/MC/MCValue.h +++ b/include/llvm/MC/MCValue.h @@ -14,8 +14,8 @@ #ifndef LLVM_MC_MCVALUE_H #define LLVM_MC_MCVALUE_H -#include "llvm/Support/DataTypes.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/Support/DataTypes.h" #include <cassert> namespace llvm { @@ -46,7 +46,7 @@ public: /// isAbsolute - Is this an absolute (as opposed to relocatable) value. bool isAbsolute() const { return !SymA && !SymB; } - /// print - Print the value to the stream \arg OS. + /// print - Print the value to the stream \p OS. void print(raw_ostream &OS, const MCAsmInfo *MAI) const; /// dump - Print the value to stderr. diff --git a/include/llvm/MC/MCWinCOFFObjectWriter.h b/include/llvm/MC/MCWinCOFFObjectWriter.h index 7a0b1ff..11df574 100644 --- a/include/llvm/MC/MCWinCOFFObjectWriter.h +++ b/include/llvm/MC/MCWinCOFFObjectWriter.h @@ -11,6 +11,9 @@ #define LLVM_MC_MCWINCOFFOBJECTWRITER_H namespace llvm { + class MCObjectWriter; + class raw_ostream; + class MCWinCOFFObjectTargetWriter { const unsigned Machine; diff --git a/include/llvm/MC/SubtargetFeature.h b/include/llvm/MC/SubtargetFeature.h index 87c5fd3..37ae03b 100644 --- a/include/llvm/MC/SubtargetFeature.h +++ b/include/llvm/MC/SubtargetFeature.h @@ -18,9 +18,9 @@ #ifndef LLVM_MC_SUBTARGETFEATURE_H #define LLVM_MC_SUBTARGETFEATURE_H -#include <vector> #include "llvm/ADT/Triple.h" #include "llvm/Support/DataTypes.h" +#include <vector> namespace llvm { class raw_ostream; @@ -95,10 +95,6 @@ public: const SubtargetFeatureKV *FeatureTable, size_t FeatureTableSize); - /// Get scheduling itinerary of a CPU. - const void *getItinerary(const StringRef CPU, - const SubtargetInfoKV *Table, size_t TableSize); - /// Print feature string. void print(raw_ostream &OS) const; |
