diff options
Diffstat (limited to 'include/llvm/MC')
31 files changed, 740 insertions, 304 deletions
diff --git a/include/llvm/MC/MCAsmBackend.h b/include/llvm/MC/MCAsmBackend.h index 4a0cf37..05e6286 100644 --- a/include/llvm/MC/MCAsmBackend.h +++ b/include/llvm/MC/MCAsmBackend.h @@ -12,17 +12,20 @@ #include "llvm/MC/MCDirectives.h" #include "llvm/MC/MCFixup.h" -#include "llvm/MC/MCFixupKindInfo.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/ErrorHandling.h" namespace llvm { +class MCAsmLayout; +class MCAssembler; class MCELFObjectTargetWriter; -class MCFixup; +struct MCFixupKindInfo; +class MCFragment; class MCInst; +class MCInstFragment; class MCObjectWriter; class MCSection; -template<typename T> -class SmallVectorImpl; +class MCValue; class raw_ostream; /// MCAsmBackend - Generic interface to target specific assembler backends. @@ -44,8 +47,8 @@ public: /// createELFObjectTargetWriter - Create a new ELFObjectTargetWriter to enable /// non-standard ELFObjectWriters. virtual MCELFObjectTargetWriter *createELFObjectTargetWriter() const { - assert(0 && "createELFObjectTargetWriter is not supported by asm backend"); - return 0; + llvm_unreachable("createELFObjectTargetWriter is not supported by asm " + "backend"); } /// hasReliableSymbolDifference - Check whether this target implements @@ -85,12 +88,21 @@ public: /// getFixupKindInfo - Get information on a fixup kind. virtual const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const; + /// processFixupValue - Target hook to adjust the literal value of a fixup + /// if necessary. IsResolved signals whether the caller believes a relocation + /// is needed; the target can modify the value. The default does nothing. + virtual void processFixupValue(const MCAssembler &Asm, + const MCAsmLayout &Layout, + const MCFixup &Fixup, const MCFragment *DF, + MCValue &Target, uint64_t &Value, + bool &IsResolved) {} + /// @} - /// ApplyFixup - Apply the \arg Value for given \arg Fixup into the provided + /// applyFixup - Apply the \arg Value for given \arg 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, + virtual void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, uint64_t Value) const = 0; /// @} @@ -98,11 +110,18 @@ public: /// @name Target Relaxation Interfaces /// @{ - /// MayNeedRelaxation - Check whether the given instruction may need + /// mayNeedRelaxation - Check whether the given instruction may need /// relaxation. /// /// \param Inst - The instruction to test. - virtual bool MayNeedRelaxation(const MCInst &Inst) const = 0; + virtual bool mayNeedRelaxation(const MCInst &Inst) const = 0; + + /// fixupNeedsRelaxation - Target specific predicate for whether a given + /// fixup requires the associated instruction to be relaxed. + virtual bool fixupNeedsRelaxation(const MCFixup &Fixup, + uint64_t Value, + const MCInstFragment *DF, + const MCAsmLayout &Layout) const = 0; /// RelaxInstruction - Relax the instruction in the given fragment to the next /// wider instruction. @@ -110,20 +129,20 @@ public: /// \param Inst - The instruction to relax, which may be the same as the /// output. /// \parm Res [output] - On return, the relaxed instruction. - virtual void RelaxInstruction(const MCInst &Inst, MCInst &Res) const = 0; + virtual void relaxInstruction(const MCInst &Inst, MCInst &Res) const = 0; /// @} - /// WriteNopData - Write an (optimal) nop sequence of Count bytes to the given + /// writeNopData - Write an (optimal) nop sequence of Count bytes to the given /// output. If the target cannot generate such a sequence, it should return an /// error. /// /// \return - True on success. - virtual bool WriteNopData(uint64_t Count, MCObjectWriter *OW) const = 0; + virtual bool writeNopData(uint64_t Count, MCObjectWriter *OW) const = 0; - /// HandleAssemblerFlag - Handle any target-specific assembler flags. + /// handleAssemblerFlag - Handle any target-specific assembler flags. /// By default, do nothing. - virtual void HandleAssemblerFlag(MCAssemblerFlag Flag) {} + virtual void handleAssemblerFlag(MCAssemblerFlag Flag) {} }; } // End llvm namespace diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index c3c296e..0f67c99 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -36,10 +36,6 @@ namespace llvm { enum LCOMMType { None, NoAlignment, ByteAlignment }; } - namespace Structors { - enum OutputOrder { None, PriorityOrder, ReversePriorityOrder }; - } - /// MCAsmInfo - This class is intended to be used as a base class for asm /// properties and features specific to the target. class MCAsmInfo { @@ -47,7 +43,7 @@ namespace llvm { //===------------------------------------------------------------------===// // Properties to be set by the target writer, used to configure asm printer. // - + /// PointerSize - Pointer size in bytes. /// Default is 4. unsigned PointerSize; @@ -72,11 +68,6 @@ namespace llvm { /// the macho-specific .tbss directive for emitting thread local BSS Symbols bool HasMachoTBSSDirective; // Default is false. - /// StructorOutputOrder - Whether the static ctor/dtor list should be output - /// in no particular order, in order of increasing priority or the reverse: - /// in order of decreasing priority (the default). - Structors::OutputOrder StructorOutputOrder; // Default is reverse order. - /// HasStaticCtorDtorReferenceInStaticMode - True if the compiler should /// emit a ".reference .constructors_used" or ".reference .destructors_used" /// directive after the a static ctor/dtor list. This directive is only @@ -152,6 +143,10 @@ namespace llvm { /// symbol names. This defaults to true. bool AllowPeriodsInName; + /// AllowUTF8 - This is true if the assembler accepts UTF-8 input. + // FIXME: Make this a more general encoding setting? + bool AllowUTF8; + //===--- Data Emission Directives -------------------------------------===// /// ZeroDirective - this should be set to the directive used to get some @@ -189,6 +184,11 @@ namespace llvm { const char *JT32Begin; // Defaults to "$a." bool SupportsDataRegions; + /// GPRel64Directive - if non-null, a directive that is used to emit a word + /// which should be relocated as a 64-bit GP-relative offset, e.g. .gpdword + /// on Mips. + const char *GPRel64Directive; // Defaults to NULL. + /// GPRel32Directive - if non-null, a directive that is used to emit a word /// which should be relocated as a 32-bit GP-relative offset, e.g. .gpword /// on Mips or .gprel32 on Alpha. @@ -323,13 +323,17 @@ namespace llvm { const char* DwarfSectionOffsetDirective; // Defaults to NULL /// DwarfRequiresRelocationForSectionOffset - True if we need to produce a - // relocation when we want a section offset in dwarf. + /// relocation when we want a section offset in dwarf. bool DwarfRequiresRelocationForSectionOffset; // Defaults to true; - // DwarfUsesLabelOffsetDifference - True if Dwarf2 output can - // use EmitLabelOffsetDifference. + /// DwarfUsesLabelOffsetDifference - True if Dwarf2 output can + /// use EmitLabelOffsetDifference. bool DwarfUsesLabelOffsetForRanges; + /// DwarfUsesRelocationsForStringPool - True if this Dwarf output must use + /// relocations to refer to entries in the string pool. + bool DwarfUsesRelocationsForStringPool; + /// DwarfRegNumForCFI - True if dwarf register numbers are printed /// instead of symbolic register names in .cfi_* directives. bool DwarfRegNumForCFI; // Defaults to false; @@ -381,6 +385,7 @@ namespace llvm { const char *getData64bitsDirective(unsigned AS = 0) const { return AS == 0 ? Data64bitsDirective : getDataASDirective(64, AS); } + const char *getGPRel64Directive() const { return GPRel64Directive; } const char *getGPRel32Directive() const { return GPRel32Directive; } /// [Code|Data]Begin label name accessors. @@ -424,9 +429,6 @@ namespace llvm { // bool hasMachoZeroFillDirective() const { return HasMachoZeroFillDirective; } bool hasMachoTBSSDirective() const { return HasMachoTBSSDirective; } - Structors::OutputOrder getStructorOutputOrder() const { - return StructorOutputOrder; - } bool hasStaticCtorDtorReferenceInStaticMode() const { return HasStaticCtorDtorReferenceInStaticMode; } @@ -487,6 +489,9 @@ namespace llvm { bool doesAllowPeriodsInName() const { return AllowPeriodsInName; } + bool doesAllowUTF8() const { + return AllowUTF8; + } const char *getZeroDirective() const { return ZeroDirective; } @@ -554,7 +559,7 @@ namespace llvm { ExceptionsType == ExceptionHandling::ARM || ExceptionsType == ExceptionHandling::Win64); } - bool doesDwarfUsesInlineInfoSection() const { + bool doesDwarfUseInlineInfoSection() const { return DwarfUsesInlineInfoSection; } const char *getDwarfSectionOffsetDirective() const { @@ -563,9 +568,12 @@ namespace llvm { bool doesDwarfRequireRelocationForSectionOffset() const { return DwarfRequiresRelocationForSectionOffset; } - bool doesDwarfUsesLabelOffsetForRanges() const { + bool doesDwarfUseLabelOffsetForRanges() const { return DwarfUsesLabelOffsetForRanges; } + bool doesDwarfUseRelocationsForStringPool() const { + return DwarfUsesRelocationsForStringPool; + } bool useDwarfRegNumForCFI() const { return DwarfRegNumForCFI; } diff --git a/include/llvm/MC/MCAsmInfoCOFF.h b/include/llvm/MC/MCAsmInfoCOFF.h index a3ee159..0ff3e12 100644 --- a/include/llvm/MC/MCAsmInfoCOFF.h +++ b/include/llvm/MC/MCAsmInfoCOFF.h @@ -14,9 +14,21 @@ namespace llvm { class MCAsmInfoCOFF : public MCAsmInfo { + virtual void anchor(); protected: explicit MCAsmInfoCOFF(); - + }; + + class MCAsmInfoMicrosoft : public MCAsmInfoCOFF { + virtual void anchor(); + protected: + explicit MCAsmInfoMicrosoft(); + }; + + class MCAsmInfoGNUCOFF : public MCAsmInfoCOFF { + virtual void anchor(); + protected: + explicit MCAsmInfoGNUCOFF(); }; } diff --git a/include/llvm/MC/MCAsmInfoDarwin.h b/include/llvm/MC/MCAsmInfoDarwin.h index 1f6c499..af552de 100644 --- a/include/llvm/MC/MCAsmInfoDarwin.h +++ b/include/llvm/MC/MCAsmInfoDarwin.h @@ -18,7 +18,9 @@ #include "llvm/MC/MCAsmInfo.h" namespace llvm { - struct MCAsmInfoDarwin : public MCAsmInfo { + class MCAsmInfoDarwin : public MCAsmInfo { + virtual void anchor(); + public: explicit MCAsmInfoDarwin(); }; } diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h index a4585d1..cf79216 100644 --- a/include/llvm/MC/MCAsmLayout.h +++ b/include/llvm/MC/MCAsmLayout.h @@ -10,6 +10,7 @@ #ifndef LLVM_MC_MCASMLAYOUT_H #define LLVM_MC_MCASMLAYOUT_H +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" namespace llvm { diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index b8f8cc4..d139173 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -25,7 +25,6 @@ namespace llvm { class raw_ostream; class MCAsmLayout; class MCAssembler; -class MCBinaryExpr; class MCContext; class MCCodeEmitter; class MCExpr; @@ -106,6 +105,7 @@ public: }; class MCDataFragment : public MCFragment { + virtual void anchor(); SmallString<32> Contents; /// Fixups - The list of fixups in this fragment. @@ -160,6 +160,8 @@ public: // 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 { + virtual void anchor(); + /// Inst - The instruction this is a fragment for. MCInst Inst; @@ -215,6 +217,8 @@ public: }; class MCAlignFragment : public MCFragment { + virtual void anchor(); + /// Alignment - The alignment to ensure, in bytes. unsigned Alignment; @@ -263,6 +267,8 @@ public: }; class MCFillFragment : public MCFragment { + virtual void anchor(); + /// Value - Value to use for filling bytes. int64_t Value; @@ -300,6 +306,8 @@ public: }; class MCOrgFragment : public MCFragment { + virtual void anchor(); + /// Offset - The offset this fragment should start at. const MCExpr *Offset; @@ -327,6 +335,8 @@ public: }; class MCLEBFragment : public MCFragment { + virtual void anchor(); + /// Value - The value this fragment should contain. const MCExpr *Value; @@ -358,6 +368,8 @@ public: }; class MCDwarfLineAddrFragment : public MCFragment { + virtual void anchor(); + /// LineDelta - the value of the difference between the two line numbers /// between two .loc dwarf directives. int64_t LineDelta; @@ -393,6 +405,8 @@ public: }; class MCDwarfCallFrameFragment : public MCFragment { + virtual void anchor(); + /// AddrDelta - The expression for the difference of the two symbols that /// make up the address delta between two .cfi_* dwarf directives. const MCExpr *AddrDelta; @@ -711,43 +725,44 @@ private: /// \return Whether the fixup value was fully resolved. This is true if the /// \arg Value result is fixed, otherwise the value may change due to /// relocation. - bool EvaluateFixup(const MCAsmLayout &Layout, + bool evaluateFixup(const MCAsmLayout &Layout, const MCFixup &Fixup, const MCFragment *DF, MCValue &Target, uint64_t &Value) const; /// Check whether a fixup can be satisfied, or whether it needs to be relaxed /// (increased in size, in order to hold its value correctly). - bool FixupNeedsRelaxation(const MCFixup &Fixup, const MCFragment *DF, + bool fixupNeedsRelaxation(const MCFixup &Fixup, const MCInstFragment *DF, const MCAsmLayout &Layout) const; /// Check whether the given fragment needs relaxation. - bool FragmentNeedsRelaxation(const MCInstFragment *IF, + bool fragmentNeedsRelaxation(const MCInstFragment *IF, const MCAsmLayout &Layout) const; - /// LayoutOnce - Perform one layout iteration and return true if any offsets + /// layoutOnce - Perform one layout iteration and return true if any offsets /// were adjusted. - bool LayoutOnce(MCAsmLayout &Layout); + bool layoutOnce(MCAsmLayout &Layout); - bool LayoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD); + bool layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD); - bool RelaxInstruction(MCAsmLayout &Layout, MCInstFragment &IF); + bool relaxInstruction(MCAsmLayout &Layout, MCInstFragment &IF); - bool RelaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF); + bool relaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF); - bool RelaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF); - bool RelaxDwarfCallFrameFragment(MCAsmLayout &Layout, + bool relaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF); + bool relaxDwarfCallFrameFragment(MCAsmLayout &Layout, MCDwarfCallFrameFragment &DF); - /// FinishLayout - Finalize a layout, including fragment lowering. - void FinishLayout(MCAsmLayout &Layout); + /// finishLayout - Finalize a layout, including fragment lowering. + void finishLayout(MCAsmLayout &Layout); - uint64_t HandleFixup(const MCAsmLayout &Layout, + uint64_t handleFixup(const MCAsmLayout &Layout, MCFragment &F, const MCFixup &Fixup); public: /// Compute the effective fragment size assuming it is laid out at the given /// \arg SectionAddress and \arg FragmentOffset. - uint64_t ComputeFragmentSize(const MCAsmLayout &Layout, const MCFragment &F) const; + uint64_t computeFragmentSize(const MCAsmLayout &Layout, + const MCFragment &F) const; /// Find the symbol which defines the atom containing the given symbol, or /// null if there is no such symbol. @@ -760,7 +775,7 @@ public: bool isSymbolLinkerVisible(const MCSymbol &SD) const; /// Emit the section contents using the given object writer. - void WriteSectionData(const MCSectionData *Section, + void writeSectionData(const MCSectionData *Section, const MCAsmLayout &Layout) const; /// Check whether a given symbol has been flagged with .thumb_func. diff --git a/include/llvm/MC/MCCodeEmitter.h b/include/llvm/MC/MCCodeEmitter.h index bc63241..934ef69 100644 --- a/include/llvm/MC/MCCodeEmitter.h +++ b/include/llvm/MC/MCCodeEmitter.h @@ -10,12 +10,8 @@ #ifndef LLVM_MC_MCCODEEMITTER_H #define LLVM_MC_MCCODEEMITTER_H -#include "llvm/MC/MCFixup.h" - -#include <cassert> - namespace llvm { -class MCExpr; +class MCFixup; class MCInst; class raw_ostream; template<typename T> class SmallVectorImpl; diff --git a/include/llvm/MC/MCCodeGenInfo.h b/include/llvm/MC/MCCodeGenInfo.h index 1c54c47..d1765e1 100644 --- a/include/llvm/MC/MCCodeGenInfo.h +++ b/include/llvm/MC/MCCodeGenInfo.h @@ -20,7 +20,7 @@ namespace llvm { class MCCodeGenInfo { - /// RelocationModel - Relocation model: statcic, pic, etc. + /// RelocationModel - Relocation model: static, pic, etc. /// Reloc::Model RelocationModel; @@ -28,13 +28,20 @@ namespace llvm { /// CodeModel::Model CMModel; + /// OptLevel - Optimization level. + /// + CodeGenOpt::Level OptLevel; + public: void InitMCCodeGenInfo(Reloc::Model RM = Reloc::Default, - CodeModel::Model CM = CodeModel::Default); + CodeModel::Model CM = CodeModel::Default, + CodeGenOpt::Level OL = CodeGenOpt::Default); Reloc::Model getRelocationModel() const { return RelocationModel; } CodeModel::Model getCodeModel() const { return CMModel; } + + CodeGenOpt::Level getOptLevel() const { return OptLevel; } }; } // namespace llvm diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index a49a35c..b586319 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -15,6 +15,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringMap.h" #include "llvm/Support/Allocator.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/raw_ostream.h" #include <vector> // FIXME: Shouldn't be needed. @@ -29,6 +30,7 @@ namespace llvm { class MCObjectFileInfo; class MCRegisterInfo; class MCLineSection; + class SMLoc; class StringRef; class Twine; class MCSectionMachO; @@ -43,6 +45,8 @@ namespace llvm { public: typedef StringMap<MCSymbol*, BumpPtrAllocator&> SymbolTable; private: + /// The SourceMgr for this object, if any. + const SourceMgr *SrcMgr; /// The MCAsmInfo for this target. const MCAsmInfo &MAI; @@ -98,6 +102,27 @@ namespace llvm { MCDwarfLoc CurrentDwarfLoc; bool DwarfLocSeen; + /// Generate dwarf debugging info for assembly source files. + bool GenDwarfForAssembly; + + /// The current dwarf file number when generate dwarf debugging info for + /// assembly source files. + unsigned GenDwarfFileNumber; + + /// The default initial text section that we generate dwarf debugging line + /// info for when generating dwarf assembly source files. + const MCSection *GenDwarfSection; + /// Symbols created for the start and end of this section. + MCSymbol *GenDwarfSectionStartSym, *GenDwarfSectionEndSym; + + /// The information gathered from labels that will have dwarf label + /// entries when generating dwarf assembly source files. + std::vector<const MCGenDwarfLabelEntry *> MCGenDwarfLabelEntries; + + /// The string to embed in the debug information for the compile unit, if + /// non-empty. + StringRef DwarfDebugFlags; + /// Honor temporary labels, this is useful for debugging semantic /// differences between temporary and non-temporary labels (primarily on /// Darwin). @@ -116,9 +141,11 @@ namespace llvm { public: explicit MCContext(const MCAsmInfo &MAI, const MCRegisterInfo &MRI, - const MCObjectFileInfo *MOFI); + const MCObjectFileInfo *MOFI, const SourceMgr *Mgr = 0); ~MCContext(); + const SourceMgr *getSourceManager() const { return SrcMgr; } + const MCAsmInfo &getAsmInfo() const { return MAI; } const MCRegisterInfo &getRegisterInfo() const { return MRI; } @@ -204,7 +231,8 @@ namespace llvm { /// @{ /// GetDwarfFile - creates an entry in the dwarf file and directory tables. - unsigned GetDwarfFile(StringRef FileName, unsigned FileNumber); + unsigned GetDwarfFile(StringRef Directory, StringRef FileName, + unsigned FileNumber); bool isValidDwarfFileNumber(unsigned FileNumber); @@ -251,6 +279,31 @@ namespace llvm { bool getDwarfLocSeen() { return DwarfLocSeen; } const MCDwarfLoc &getCurrentDwarfLoc() { return CurrentDwarfLoc; } + bool getGenDwarfForAssembly() { return GenDwarfForAssembly; } + void setGenDwarfForAssembly(bool Value) { GenDwarfForAssembly = Value; } + unsigned getGenDwarfFileNumber() { return GenDwarfFileNumber; } + unsigned nextGenDwarfFileNumber() { return ++GenDwarfFileNumber; } + const MCSection *getGenDwarfSection() { return GenDwarfSection; } + void setGenDwarfSection(const MCSection *Sec) { GenDwarfSection = Sec; } + MCSymbol *getGenDwarfSectionStartSym() { return GenDwarfSectionStartSym; } + void setGenDwarfSectionStartSym(MCSymbol *Sym) { + GenDwarfSectionStartSym = Sym; + } + MCSymbol *getGenDwarfSectionEndSym() { return GenDwarfSectionEndSym; } + void setGenDwarfSectionEndSym(MCSymbol *Sym) { + GenDwarfSectionEndSym = Sym; + } + const std::vector<const MCGenDwarfLabelEntry *> + &getMCGenDwarfLabelEntries() const { + return MCGenDwarfLabelEntries; + } + void addMCGenDwarfLabelEntry(const MCGenDwarfLabelEntry *E) { + MCGenDwarfLabelEntries.push_back(E); + } + + void setDwarfDebugFlags(StringRef S) { DwarfDebugFlags = S; } + StringRef getDwarfDebugFlags() { return DwarfDebugFlags; } + /// @} char *getSecureLogFile() { return SecureLogFile; } @@ -268,6 +321,11 @@ namespace llvm { } void Deallocate(void *Ptr) { } + + // Unrecoverable error has occured. Display the best diagnostic we can + // and bail via exit(1). For now, most MC backend errors are unrecoverable. + // FIXME: We should really do something about that. + LLVM_ATTRIBUTE_NORETURN void FatalError(SMLoc L, const Twine &Msg); }; } // end namespace llvm diff --git a/include/llvm/MC/MCDisassembler.h b/include/llvm/MC/MCDisassembler.h index 454277d..4b5fbec 100644 --- a/include/llvm/MC/MCDisassembler.h +++ b/include/llvm/MC/MCDisassembler.h @@ -90,7 +90,7 @@ public: /// @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 EDInstInfo *getEDInfo() const { return (EDInstInfo*)0; } + virtual const EDInstInfo *getEDInfo() const { return (EDInstInfo*)0; } private: // diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h index 431e3c4..fdb7ab2 100644 --- a/include/llvm/MC/MCDwarf.h +++ b/include/llvm/MC/MCDwarf.h @@ -17,20 +17,18 @@ #include "llvm/ADT/StringRef.h" #include "llvm/MC/MachineLocation.h" -#include "llvm/MC/MCObjectWriter.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Dwarf.h" #include <vector> namespace llvm { class MCContext; - class MCExpr; + class MCObjectWriter; class MCSection; - class MCSectionData; class MCStreamer; class MCSymbol; - class MCObjectStreamer; - class raw_ostream; + class SourceMgr; + class SMLoc; /// MCDwarfFile - Instances of this class represent the name of the dwarf /// .file directive and its associated dwarf file number in the MC file, @@ -210,7 +208,7 @@ namespace llvm { // // This emits the Dwarf file and the line tables. // - static void Emit(MCStreamer *MCOS); + static const MCSymbol *Emit(MCStreamer *MCOS); }; class MCDwarfLineAddr { @@ -227,23 +225,63 @@ namespace llvm { int64_t LineDelta, uint64_t AddrDelta); }; + class MCGenDwarfInfo { + public: + // + // When generating dwarf for assembly source files this emits the Dwarf + // sections. + // + static void Emit(MCStreamer *MCOS, const MCSymbol *LineSectionSymbol); + }; + + // When generating dwarf for assembly source files this is the info that is + // needed to be gathered for each symbol that will have a dwarf label. + class MCGenDwarfLabelEntry { + private: + // Name of the symbol without a leading underbar, if any. + StringRef Name; + // The dwarf file number this symbol is in. + unsigned FileNumber; + // The line number this symbol is at. + unsigned LineNumber; + // The low_pc for the dwarf label is taken from this symbol. + MCSymbol *Label; + + public: + MCGenDwarfLabelEntry(StringRef name, unsigned fileNumber, + unsigned lineNumber, MCSymbol *label) : + Name(name), FileNumber(fileNumber), LineNumber(lineNumber), Label(label){} + + StringRef getName() const { return Name; } + unsigned getFileNumber() const { return FileNumber; } + unsigned getLineNumber() const { return LineNumber; } + MCSymbol *getLabel() const { return Label; } + + // This is called when label is created when we are generating dwarf for + // assembly source files. + static void Make(MCSymbol *Symbol, MCStreamer *MCOS, SourceMgr &SrcMgr, + SMLoc &Loc); + }; + class MCCFIInstruction { public: - enum OpType { SameValue, Remember, Restore, Move, RelMove }; + enum OpType { SameValue, RememberState, RestoreState, Move, RelMove, Escape, + Restore}; private: OpType Operation; MCSymbol *Label; // Move to & from location. MachineLocation Destination; MachineLocation Source; + std::vector<char> Values; public: MCCFIInstruction(OpType Op, MCSymbol *L) : Operation(Op), Label(L) { - assert(Op == Remember || Op == Restore); + assert(Op == RememberState || Op == RestoreState); } MCCFIInstruction(OpType Op, MCSymbol *L, unsigned Register) : Operation(Op), Label(L), Destination(Register) { - assert(Op == SameValue); + assert(Op == SameValue || Op == Restore); } MCCFIInstruction(MCSymbol *L, const MachineLocation &D, const MachineLocation &S) @@ -254,16 +292,24 @@ namespace llvm { : Operation(Op), Label(L), Destination(D), Source(S) { assert(Op == RelMove); } + MCCFIInstruction(OpType Op, MCSymbol *L, StringRef Vals) + : Operation(Op), Label(L), Values(Vals.begin(), Vals.end()) { + assert(Op == Escape); + } OpType getOperation() const { return Operation; } MCSymbol *getLabel() const { return Label; } const MachineLocation &getDestination() const { return Destination; } const MachineLocation &getSource() const { return Source; } + const StringRef getValues() const { + return StringRef(&Values[0], Values.size()); + } }; struct MCDwarfFrameInfo { MCDwarfFrameInfo() : Begin(0), End(0), Personality(0), Lsda(0), Function(0), Instructions(), PersonalityEncoding(), - LsdaEncoding(0), CompactUnwindEncoding(0) {} + LsdaEncoding(0), CompactUnwindEncoding(0), + IsSignalFrame(false) {} MCSymbol *Begin; MCSymbol *End; const MCSymbol *Personality; @@ -273,6 +319,7 @@ namespace llvm { unsigned PersonalityEncoding; unsigned LsdaEncoding; uint32_t CompactUnwindEncoding; + bool IsSignalFrame; }; class MCDwarfFrameEmitter { diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h index 3c150dc..f153cb0 100644 --- a/include/llvm/MC/MCELFObjectWriter.h +++ b/include/llvm/MC/MCELFObjectWriter.h @@ -10,28 +10,91 @@ #ifndef LLVM_MC_MCELFOBJECTWRITER_H #define LLVM_MC_MCELFOBJECTWRITER_H -#include "llvm/MC/MCObjectWriter.h" +#include "llvm/ADT/Triple.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/ELF.h" +#include <vector> namespace llvm { +class MCAssembler; +class MCFixup; +class MCFragment; +class MCObjectWriter; +class MCSymbol; +class MCValue; + +/// @name Relocation Data +/// @{ + +struct ELFRelocationEntry { + // Make these big enough for both 32-bit and 64-bit + uint64_t r_offset; + int Index; + unsigned Type; + const MCSymbol *Symbol; + uint64_t r_addend; + const MCFixup *Fixup; + + ELFRelocationEntry() + : r_offset(0), Index(0), Type(0), Symbol(0), r_addend(0), Fixup(0) {} + + ELFRelocationEntry(uint64_t RelocOffset, int Idx, unsigned RelType, + const MCSymbol *Sym, uint64_t Addend, const MCFixup &Fixup) + : r_offset(RelocOffset), Index(Idx), Type(RelType), Symbol(Sym), + r_addend(Addend), Fixup(&Fixup) {} + + // Support lexicographic sorting. + bool operator<(const ELFRelocationEntry &RE) const { + return RE.r_offset < r_offset; + } +}; + class MCELFObjectTargetWriter { - const Triple::OSType OSType; + const uint8_t OSABI; const uint16_t EMachine; const unsigned HasRelocationAddend : 1; const unsigned Is64Bit : 1; + protected: - MCELFObjectTargetWriter(bool Is64Bit_, Triple::OSType OSType_, + + MCELFObjectTargetWriter(bool Is64Bit_, uint8_t OSABI_, uint16_t EMachine_, bool HasRelocationAddend_); public: - virtual ~MCELFObjectTargetWriter(); + static uint8_t getOSABI(Triple::OSType OSType) { + switch (OSType) { + case Triple::FreeBSD: + return ELF::ELFOSABI_FREEBSD; + case Triple::Linux: + return ELF::ELFOSABI_LINUX; + default: + return ELF::ELFOSABI_NONE; + } + } + + virtual ~MCELFObjectTargetWriter() {} + + virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, + bool IsPCRel, bool IsRelocWithSymbol, + int64_t Addend) const = 0; + virtual unsigned getEFlags() const; + virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm, + const MCValue &Target, + const MCFragment &F, + const MCFixup &Fixup, + bool IsPCRel) const; + virtual void adjustFixupOffset(const MCFixup &Fixup, + uint64_t &RelocOffset); + + virtual void sortRelocs(const MCAssembler &Asm, + std::vector<ELFRelocationEntry> &Relocs); /// @name Accessors /// @{ - Triple::OSType getOSType() { return OSType; } + uint8_t getOSABI() { return OSABI; } uint16_t getEMachine() { return EMachine; } bool hasRelocationAddend() { return HasRelocationAddend; } - bool is64Bit() { return Is64Bit; } + bool is64Bit() const { return Is64Bit; } /// @} }; diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index 0f28599..ff33641 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -15,7 +15,6 @@ #include "llvm/Support/DataTypes.h" namespace llvm { -class MCAsmInfo; class MCAsmLayout; class MCAssembler; class MCContext; @@ -162,6 +161,7 @@ public: VK_TPOFF, VK_DTPOFF, 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_PLT, // ARM-style PLT references. i.e., (PLT) instead of @PLT VK_ARM_TLSGD, // ditto for TLSGD, GOT, GOTOFF, TPOFF and GOTTPOFF @@ -169,12 +169,32 @@ public: VK_ARM_GOTOFF, VK_ARM_TPOFF, VK_ARM_GOTTPOFF, + VK_ARM_TARGET1, VK_PPC_TOC, 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_Mips_GPREL, + VK_Mips_GOT_CALL, + VK_Mips_GOT16, + VK_Mips_GOT, + VK_Mips_ABS_HI, + VK_Mips_ABS_LO, + VK_Mips_TLSGD, + VK_Mips_TLSLDM, + VK_Mips_DTPREL_HI, + VK_Mips_DTPREL_LO, + VK_Mips_GOTTPREL, + VK_Mips_TPREL_HI, + VK_Mips_TPREL_LO, + VK_Mips_GPOFF_HI, + VK_Mips_GPOFF_LO, + VK_Mips_GOT_DISP, + VK_Mips_GOT_PAGE, + VK_Mips_GOT_OFST }; private: @@ -185,7 +205,9 @@ private: const VariantKind Kind; explicit MCSymbolRefExpr(const MCSymbol *_Symbol, VariantKind _Kind) - : MCExpr(MCExpr::SymbolRef), Symbol(_Symbol), Kind(_Kind) {} + : MCExpr(MCExpr::SymbolRef), Symbol(_Symbol), Kind(_Kind) { + assert(Symbol); + } public: /// @name Construction diff --git a/include/llvm/MC/MCFixup.h b/include/llvm/MC/MCFixup.h index 6fde797..16e9eb7 100644 --- a/include/llvm/MC/MCFixup.h +++ b/include/llvm/MC/MCFixup.h @@ -11,6 +11,8 @@ #define LLVM_MC_MCFIXUP_H #include "llvm/Support/DataTypes.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/SMLoc.h" #include <cassert> namespace llvm { @@ -26,6 +28,14 @@ enum MCFixupKind { FK_PCRel_2, ///< A two-byte pc relative fixup. FK_PCRel_4, ///< A four-byte pc relative fixup. FK_PCRel_8, ///< A eight-byte pc relative fixup. + FK_GPRel_1, ///< A one-byte gp relative fixup. + FK_GPRel_2, ///< A two-byte gp relative fixup. + FK_GPRel_4, ///< A four-byte gp relative fixup. + FK_GPRel_8, ///< A eight-byte gp relative fixup. + FK_SecRel_1, ///< A one-byte section relative fixup. + FK_SecRel_2, ///< A two-byte section relative fixup. + FK_SecRel_4, ///< A four-byte section relative fixup. + FK_SecRel_8, ///< A eight-byte section relative fixup. FirstTargetFixupKind = 128, @@ -61,14 +71,17 @@ class MCFixup { /// determine how the operand value should be encoded into the instruction. unsigned Kind; + /// The source location which gave rise to the fixup, if any. + SMLoc Loc; public: static MCFixup Create(uint32_t Offset, const MCExpr *Value, - MCFixupKind Kind) { + MCFixupKind Kind, SMLoc Loc = SMLoc()) { assert(unsigned(Kind) < MaxTargetFixupKind && "Kind out of range!"); MCFixup FI; FI.Value = Value; FI.Offset = Offset; FI.Kind = unsigned(Kind); + FI.Loc = Loc; return FI; } @@ -83,13 +96,15 @@ public: /// size. It is an error to pass an unsupported size. static MCFixupKind getKindForSize(unsigned Size, bool isPCRel) { switch (Size) { - default: assert(0 && "Invalid generic fixup size!"); + default: llvm_unreachable("Invalid generic fixup size!"); case 1: return isPCRel ? FK_PCRel_1 : FK_Data_1; case 2: return isPCRel ? FK_PCRel_2 : FK_Data_2; case 4: return isPCRel ? FK_PCRel_4 : FK_Data_4; case 8: return isPCRel ? FK_PCRel_8 : FK_Data_8; } } + + SMLoc getLoc() const { return Loc; } }; } // End llvm namespace diff --git a/include/llvm/MC/MCInst.h b/include/llvm/MC/MCInst.h index d384764..397a37d 100644 --- a/include/llvm/MC/MCInst.h +++ b/include/llvm/MC/MCInst.h @@ -19,12 +19,14 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/SMLoc.h" namespace llvm { class raw_ostream; class MCAsmInfo; class MCInstPrinter; class MCExpr; +class MCInst; /// MCOperand - Instances of this class represent operands of the MCInst class. /// This is a simple discriminated union. @@ -34,7 +36,8 @@ class MCOperand { kRegister, ///< Register operand. kImmediate, ///< Immediate operand. kFPImmediate, ///< Floating-point immediate operand. - kExpr ///< Relocatable immediate operand. + kExpr, ///< Relocatable immediate operand. + kInst ///< Sub-instruction operand. }; unsigned char Kind; @@ -43,6 +46,7 @@ class MCOperand { int64_t ImmVal; double FPImmVal; const MCExpr *ExprVal; + const MCInst *InstVal; }; public: @@ -53,6 +57,7 @@ public: bool isImm() const { return Kind == kImmediate; } bool isFPImm() const { return Kind == kFPImmediate; } bool isExpr() const { return Kind == kExpr; } + bool isInst() const { return Kind == kInst; } /// getReg - Returns the register number. unsigned getReg() const { @@ -94,6 +99,15 @@ public: ExprVal = Val; } + const MCInst *getInst() const { + assert(isInst() && "This is not a sub-instruction"); + return InstVal; + } + void setInst(const MCInst *Val) { + assert(isInst() && "This is not a sub-instruction"); + InstVal = Val; + } + static MCOperand CreateReg(unsigned Reg) { MCOperand Op; Op.Kind = kRegister; @@ -118,24 +132,34 @@ public: Op.ExprVal = Val; return Op; } + static MCOperand CreateInst(const MCInst *Val) { + MCOperand Op; + Op.Kind = kInst; + Op.InstVal = Val; + return Op; + } void print(raw_ostream &OS, const MCAsmInfo *MAI) const; void dump() const; }; +template <> struct isPodLike<MCOperand> { static const bool value = true; }; /// MCInst - Instances of this class represent a single low-level machine /// instruction. class MCInst { unsigned Opcode; + SMLoc Loc; SmallVector<MCOperand, 8> Operands; public: MCInst() : Opcode(0) {} void setOpcode(unsigned Op) { Opcode = Op; } - unsigned getOpcode() const { return Opcode; } + void setLoc(SMLoc loc) { Loc = loc; } + SMLoc getLoc() const { return Loc; } + const MCOperand &getOperand(unsigned i) const { return Operands[i]; } MCOperand &getOperand(unsigned i) { return Operands[i]; } unsigned getNumOperands() const { return Operands.size(); } diff --git a/include/llvm/MC/MCInstPrinter.h b/include/llvm/MC/MCInstPrinter.h index 01ad2d3f..3c4f28b 100644 --- a/include/llvm/MC/MCInstPrinter.h +++ b/include/llvm/MC/MCInstPrinter.h @@ -14,6 +14,8 @@ namespace llvm { class MCInst; class raw_ostream; class MCAsmInfo; +class MCInstrInfo; +class MCRegisterInfo; class StringRef; /// MCInstPrinter - This is an instance of a target assembly language printer @@ -25,6 +27,8 @@ protected: /// assembly emission is disable. raw_ostream *CommentStream; const MCAsmInfo &MAI; + const MCInstrInfo &MII; + const MCRegisterInfo &MRI; /// The current set of available features. unsigned AvailableFeatures; @@ -32,8 +36,9 @@ protected: /// Utility function for printing annotations. void printAnnotation(raw_ostream &OS, StringRef Annot); public: - MCInstPrinter(const MCAsmInfo &mai) - : CommentStream(0), MAI(mai), AvailableFeatures(0) {} + MCInstPrinter(const MCAsmInfo &mai, const MCInstrInfo &mii, + const MCRegisterInfo &mri) + : CommentStream(0), MAI(mai), MII(mii), MRI(mri), AvailableFeatures(0) {} virtual ~MCInstPrinter(); @@ -47,7 +52,7 @@ public: /// getOpcodeName - Return the name of the specified opcode enum (e.g. /// "MOV32ri") or empty if we can't resolve it. - virtual StringRef getOpcodeName(unsigned Opcode) const; + StringRef getOpcodeName(unsigned Opcode) const; /// printRegName - Print the assembler register name. virtual void printRegName(raw_ostream &OS, unsigned RegNo) const; diff --git a/include/llvm/MC/MCInstrAnalysis.h b/include/llvm/MC/MCInstrAnalysis.h index 8f3c499..acad633 100644 --- a/include/llvm/MC/MCInstrAnalysis.h +++ b/include/llvm/MC/MCInstrAnalysis.h @@ -33,7 +33,7 @@ public: } virtual bool isConditionalBranch(const MCInst &Inst) const { - return Info->get(Inst.getOpcode()).isBranch(); + return Info->get(Inst.getOpcode()).isConditionalBranch(); } virtual bool isUnconditionalBranch(const MCInst &Inst) const { diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h index aafa800..186612d 100644 --- a/include/llvm/MC/MCInstrDesc.h +++ b/include/llvm/MC/MCInstrDesc.h @@ -58,17 +58,17 @@ public: /// if the operand is a register. If isLookupPtrRegClass is set, then this is /// an index that is passed to TargetRegisterInfo::getPointerRegClass(x) to /// get a dynamic register class. - short RegClass; + int16_t RegClass; /// Flags - These are flags from the MCOI::OperandFlags enum. - unsigned short Flags; + uint8_t Flags; + + /// OperandType - Information about the type of the operand. + uint8_t OperandType; /// Lower 16 bits are used to specify which constraints are set. The higher 16 /// bits are used to specify the value of constraints (4 bits each). - unsigned Constraints; - - /// OperandType - Information about the type of the operand. - MCOI::OperandType OperandType; + uint32_t Constraints; /// Currently no other information. /// isLookupPtrRegClass - Set if this operand is a pointer value and it @@ -137,11 +137,10 @@ public: unsigned short NumDefs; // Num of args that are definitions unsigned short SchedClass; // enum identifying instr sched class unsigned short Size; // Number of bytes in encoding. - const char * Name; // Name of the instruction record in td file unsigned Flags; // Flags identifying machine instr class uint64_t TSFlags; // Target Specific Flag values - const unsigned *ImplicitUses; // Registers implicitly read by this instr - const unsigned *ImplicitDefs; // Registers implicitly defined by this instr + const uint16_t *ImplicitUses; // Registers implicitly read by this instr + 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 @@ -161,12 +160,6 @@ public: return Opcode; } - /// getName - Return the name of the record in the .td file for this - /// instruction, for example "ADD8ri". - const char *getName() const { - return Name; - } - /// getNumOperands - 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 @@ -184,6 +177,10 @@ public: return NumDefs; } + /// getFlags - Return flags of this instruction. + /// + unsigned getFlags() const { return Flags; } + /// isVariadic - 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 @@ -198,84 +195,6 @@ public: return Flags & (1 << MCID::HasOptionalDef); } - /// getImplicitUses - Return a list of registers that are potentially - /// read by any instance of this machine instruction. For example, on X86, - /// the "adc" instruction adds two register operands and adds the carry bit in - /// from the flags register. In this case, the instruction is marked as - /// implicitly reading the flags. Likewise, the variable shift instruction on - /// X86 is marked as implicitly reading the 'CL' register, which it always - /// does. - /// - /// This method returns null if the instruction has no implicit uses. - const unsigned *getImplicitUses() const { - return ImplicitUses; - } - - /// getNumImplicitUses - Return the number of implicit uses this instruction - /// has. - unsigned getNumImplicitUses() const { - if (ImplicitUses == 0) return 0; - unsigned i = 0; - for (; ImplicitUses[i]; ++i) /*empty*/; - return i; - } - - /// getImplicitDefs - Return a list of registers that are potentially - /// written by any instance of this machine instruction. For example, on X86, - /// many instructions implicitly set the flags register. In this case, they - /// are marked as setting the FLAGS. Likewise, many instructions always - /// deposit their result in a physical register. For example, the X86 divide - /// instruction always deposits the quotient and remainder in the EAX/EDX - /// registers. For that instruction, this will return a list containing the - /// EAX/EDX/EFLAGS registers. - /// - /// This method returns null if the instruction has no implicit defs. - const unsigned *getImplicitDefs() const { - return ImplicitDefs; - } - - /// getNumImplicitDefs - Return the number of implicit defs this instruction - /// has. - unsigned getNumImplicitDefs() const { - if (ImplicitDefs == 0) return 0; - unsigned i = 0; - for (; ImplicitDefs[i]; ++i) /*empty*/; - return i; - } - - /// hasImplicitUseOfPhysReg - Return true if this instruction implicitly - /// uses the specified physical register. - bool hasImplicitUseOfPhysReg(unsigned Reg) const { - if (const unsigned *ImpUses = ImplicitUses) - for (; *ImpUses; ++ImpUses) - if (*ImpUses == Reg) return true; - return false; - } - - /// hasImplicitDefOfPhysReg - Return true if this instruction implicitly - /// defines the specified physical register. - bool hasImplicitDefOfPhysReg(unsigned Reg) const { - if (const unsigned *ImpDefs = ImplicitDefs) - for (; *ImpDefs; ++ImpDefs) - if (*ImpDefs == Reg) return true; - return false; - } - - /// getSchedClass - 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, - /// or zero if the encoding size cannot be known from the opcode. - unsigned getSize() const { - return Size; - } - /// isPseudo - Return true if this is a pseudo instruction that doesn't /// correspond to a real machine instruction. /// @@ -298,18 +217,6 @@ public: return Flags & (1 << MCID::Barrier); } - /// findFirstPredOperandIdx() - 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 { - if (isPredicable()) { - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) - if (OpInfo[i].isPredicate()) - return i; - } - return -1; - } - /// isTerminator - Returns true if this instruction part of the terminator for /// a basic block. Typically this is things like return and branch /// instructions. @@ -530,6 +437,97 @@ public: bool hasExtraDefRegAllocReq() const { return Flags & (1 << MCID::ExtraDefRegAllocReq); } + + + /// getImplicitUses - Return a list of registers that are potentially + /// read by any instance of this machine instruction. For example, on X86, + /// the "adc" instruction adds two register operands and adds the carry bit in + /// from the flags register. In this case, the instruction is marked as + /// implicitly reading the flags. Likewise, the variable shift instruction on + /// X86 is marked as implicitly reading the 'CL' register, which it always + /// does. + /// + /// This method returns null if the instruction has no implicit uses. + const uint16_t *getImplicitUses() const { + return ImplicitUses; + } + + /// getNumImplicitUses - Return the number of implicit uses this instruction + /// has. + unsigned getNumImplicitUses() const { + if (ImplicitUses == 0) return 0; + unsigned i = 0; + for (; ImplicitUses[i]; ++i) /*empty*/; + return i; + } + + /// getImplicitDefs - Return a list of registers that are potentially + /// written by any instance of this machine instruction. For example, on X86, + /// many instructions implicitly set the flags register. In this case, they + /// are marked as setting the FLAGS. Likewise, many instructions always + /// deposit their result in a physical register. For example, the X86 divide + /// instruction always deposits the quotient and remainder in the EAX/EDX + /// registers. For that instruction, this will return a list containing the + /// EAX/EDX/EFLAGS registers. + /// + /// This method returns null if the instruction has no implicit defs. + const uint16_t *getImplicitDefs() const { + return ImplicitDefs; + } + + /// getNumImplicitDefs - Return the number of implicit defs this instruction + /// has. + unsigned getNumImplicitDefs() const { + if (ImplicitDefs == 0) return 0; + unsigned i = 0; + for (; ImplicitDefs[i]; ++i) /*empty*/; + return i; + } + + /// hasImplicitUseOfPhysReg - Return true if this instruction implicitly + /// uses the specified physical register. + bool hasImplicitUseOfPhysReg(unsigned Reg) const { + if (const uint16_t *ImpUses = ImplicitUses) + for (; *ImpUses; ++ImpUses) + if (*ImpUses == Reg) return true; + return false; + } + + /// hasImplicitDefOfPhysReg - Return true if this instruction implicitly + /// defines the specified physical register. + bool hasImplicitDefOfPhysReg(unsigned Reg) const { + if (const uint16_t *ImpDefs = ImplicitDefs) + for (; *ImpDefs; ++ImpDefs) + if (*ImpDefs == Reg) return true; + return false; + } + + /// getSchedClass - 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, + /// 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 + /// operand list that is used to represent the predicate. It returns -1 if + /// none is found. + int findFirstPredOperandIdx() const { + if (isPredicable()) { + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) + if (OpInfo[i].isPredicate()) + return i; + } + return -1; + } }; } // end namespace llvm diff --git a/include/llvm/MC/MCInstrInfo.h b/include/llvm/MC/MCInstrInfo.h index a63e5fa..1d3a36c 100644 --- a/include/llvm/MC/MCInstrInfo.h +++ b/include/llvm/MC/MCInstrInfo.h @@ -24,14 +24,19 @@ namespace llvm { /// MCInstrInfo - Interface to description of machine instruction set /// class MCInstrInfo { - const MCInstrDesc *Desc; // Raw array to allow static init'n - unsigned NumOpcodes; // Number of entries in the desc array + const MCInstrDesc *Desc; // Raw array to allow static init'n + const unsigned *InstrNameIndices; // Array for name indices in InstrNameData + const char *InstrNameData; // Instruction name string pool + unsigned NumOpcodes; // Number of entries in the desc array public: /// InitMCInstrInfo - Initialize MCInstrInfo, called by TableGen /// auto-generated routines. *DO NOT USE*. - void InitMCInstrInfo(const MCInstrDesc *D, unsigned NO) { + void InitMCInstrInfo(const MCInstrDesc *D, const unsigned *NI, const char *ND, + unsigned NO) { Desc = D; + InstrNameIndices = NI; + InstrNameData = ND; NumOpcodes = NO; } @@ -44,6 +49,12 @@ public: assert(Opcode < NumOpcodes && "Invalid opcode!"); return Desc[Opcode]; } + + /// getName - Returns the name for the instructions with the given opcode. + const char *getName(unsigned Opcode) const { + assert(Opcode < NumOpcodes && "Invalid opcode!"); + return &InstrNameData[InstrNameIndices[Opcode]]; + } }; } // End llvm namespace diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h index 060d508..aea4b41 100644 --- a/include/llvm/MC/MCObjectFileInfo.h +++ b/include/llvm/MC/MCObjectFileInfo.h @@ -14,15 +14,14 @@ #ifndef LLVM_MC_MCBJECTFILEINFO_H #define LLVM_MC_MCBJECTFILEINFO_H -#include "llvm/MC/MCCodeGenInfo.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/MC/SectionKind.h" +#include "llvm/Support/CodeGen.h" namespace llvm { -class MCContext; -class MCSection; -class Triple; - + class MCContext; + class MCSection; + class StringRef; + class Triple; + class MCObjectFileInfo { protected: /// CommDirectiveSupportsAlignment - True if .comm supports alignment. This @@ -47,6 +46,9 @@ protected: unsigned FDEEncoding; unsigned FDECFIEncoding; unsigned TTypeEncoding; + // Section flags for eh_frame + unsigned EHSectionType; + unsigned EHSectionFlags; /// TextSection - Section directive for standard text. /// @@ -82,13 +84,20 @@ 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; const MCSection *DwarfInfoSection; const MCSection *DwarfLineSection; const MCSection *DwarfFrameSection; - const MCSection *DwarfPubNamesSection; const MCSection *DwarfPubTypesSection; const MCSection *DwarfDebugInlineSection; const MCSection *DwarfStrSection; @@ -102,7 +111,7 @@ protected: const MCSection *TLSExtraDataSection; /// TLSDataSection - Section directive for Thread Local data. - /// ELF and MachO only. + /// ELF, MachO and COFF. const MCSection *TLSDataSection; // Defaults to ".tdata". /// TLSBSSSection - Section directive for Thread Local uninitialized data. @@ -156,7 +165,7 @@ protected: const MCSection *DrectveSection; const MCSection *PDataSection; const MCSection *XDataSection; - + public: void InitMCObjectFileInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM, MCContext &ctx); @@ -181,17 +190,26 @@ public: const MCSection *getTextSection() const { return TextSection; } const MCSection *getDataSection() const { return DataSection; } const MCSection *getBSSSection() const { return BSSSection; } - const MCSection *getStaticCtorSection() const { return StaticCtorSection; } - const MCSection *getStaticDtorSection() const { return StaticDtorSection; } const MCSection *getLSDASection() const { return LSDASection; } 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; } const MCSection *getDwarfFrameSection() const { return DwarfFrameSection; } - const MCSection *getDwarfPubNamesSection() const{return DwarfPubNamesSection;} const MCSection *getDwarfPubTypesSection() const{return DwarfPubTypesSection;} const MCSection *getDwarfDebugInlineSection() const { return DwarfDebugInlineSection; diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h index f897e64..a69075d 100644 --- a/include/llvm/MC/MCObjectStreamer.h +++ b/include/llvm/MC/MCObjectStreamer.h @@ -34,6 +34,8 @@ class MCObjectStreamer : public MCStreamer { MCSectionData *CurSectionData; virtual void EmitInstToData(const MCInst &Inst) = 0; + virtual void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame); + virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame); protected: MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, @@ -70,14 +72,15 @@ public: virtual void ChangeSection(const MCSection *Section); virtual void EmitInstruction(const MCInst &Inst); virtual void EmitInstToFragment(const MCInst &Inst); - virtual void EmitValueToOffset(const MCExpr *Offset, unsigned char Value); + virtual bool EmitValueToOffset(const MCExpr *Offset, unsigned char Value); virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, const MCSymbol *Label, unsigned PointerSize); virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, const MCSymbol *Label); - virtual void Finish(); + virtual void EmitGPRel32Value(const MCExpr *Value); + virtual void FinishImpl(); /// @} }; diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h index 782d844..6e44e6ce 100644 --- a/include/llvm/MC/MCObjectWriter.h +++ b/include/llvm/MC/MCObjectWriter.h @@ -10,7 +10,6 @@ #ifndef LLVM_MC_MCOBJECTWRITER_H #define LLVM_MC_MCOBJECTWRITER_H -#include "llvm/ADT/Triple.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/DataTypes.h" #include <cassert> @@ -20,11 +19,9 @@ class MCAsmLayout; class MCAssembler; class MCFixup; class MCFragment; -class MCSymbol; class MCSymbolData; class MCSymbolRefExpr; class MCValue; -class raw_ostream; /// MCObjectWriter - Defines the object file and target independent interfaces /// used by the assembler backend to write native file format object files. @@ -188,11 +185,10 @@ public: /// Utility function to encode a SLEB128 value. static void EncodeSLEB128(int64_t Value, raw_ostream &OS); /// Utility function to encode a ULEB128 value. - static void EncodeULEB128(uint64_t Value, raw_ostream &OS); + static void EncodeULEB128(uint64_t Value, raw_ostream &OS, + unsigned Padding = 0); }; -MCObjectWriter *createWinCOFFObjectWriter(raw_ostream &OS, bool is64Bit); - } // End llvm namespace #endif diff --git a/include/llvm/MC/MCParser/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h index 9bbb755..ac04483 100644 --- a/include/llvm/MC/MCParser/MCAsmLexer.h +++ b/include/llvm/MC/MCParser/MCAsmLexer.h @@ -71,6 +71,7 @@ public: bool isNot(TokenKind K) const { return Kind != K; } SMLoc getLoc() const; + SMLoc getEndLoc() const; /// getStringContents - Get the contents of a string token (without quotes). StringRef getStringContents() const { diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h index 6ff1753..793c709 100644 --- a/include/llvm/MC/MCParser/MCAsmParser.h +++ b/include/llvm/MC/MCParser/MCAsmParser.h @@ -11,6 +11,7 @@ #define LLVM_MC_MCASMPARSER_H #include "llvm/Support/DataTypes.h" +#include "llvm/ADT/ArrayRef.h" namespace llvm { class AsmToken; @@ -22,6 +23,7 @@ class MCExpr; class MCStreamer; class MCTargetAsmParser; class SMLoc; +class SMRange; class SourceMgr; class StringRef; class Twine; @@ -62,6 +64,9 @@ public: MCTargetAsmParser &getTargetParser() const { return *TargetParser; } void setTargetParser(MCTargetAsmParser &P); + virtual unsigned getAssemblerDialect() { return 0;} + virtual void setAssemblerDialect(unsigned i) { } + bool getShowParsedOperands() const { return ShowParsedOperands; } void setShowParsedOperands(bool Value) { ShowParsedOperands = Value; } @@ -72,14 +77,16 @@ public: /// Msg. /// /// \return The return value is true, if warnings are fatal. - virtual bool Warning(SMLoc L, const Twine &Msg) = 0; + 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. /// /// \return The return value is always true, as an idiomatic convenience to /// clients. - virtual bool Error(SMLoc L, const Twine &Msg) = 0; + virtual bool Error(SMLoc L, const Twine &Msg, + ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) = 0; /// Lex - Get the next AsmToken in the stream, possibly handling file /// inclusion first. @@ -89,7 +96,8 @@ public: const AsmToken &getTok(); /// \brief Report an error at the current lexer location. - bool TokError(const Twine &Msg); + bool TokError(const Twine &Msg, + ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()); /// ParseIdentifier - Parse an identifier or string (as a quoted identifier) /// and set \arg Res to the identifier contents. diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h index ada5ae8..27acf2f 100644 --- a/include/llvm/MC/MCRegisterInfo.h +++ b/include/llvm/MC/MCRegisterInfo.h @@ -17,6 +17,7 @@ #define LLVM_MC_MCREGISTERINFO_H #include "llvm/ADT/DenseMap.h" +#include "llvm/Support/ErrorHandling.h" #include <cassert> namespace llvm { @@ -24,28 +25,18 @@ namespace llvm { /// MCRegisterClass - Base class of TargetRegisterClass. class MCRegisterClass { public: - typedef const unsigned* iterator; - typedef const unsigned* const_iterator; -private: - unsigned ID; + typedef const uint16_t* iterator; + typedef const uint16_t* const_iterator; + const char *Name; - const unsigned RegSize, Alignment; // Size & Alignment of register in bytes - const int CopyCost; + const iterator RegsBegin; + const uint8_t *const RegSet; + const uint16_t RegsSize; + const uint16_t RegSetSize; + const uint16_t ID; + const uint16_t RegSize, Alignment; // Size & Alignment of register in bytes + const int8_t CopyCost; const bool Allocatable; - const iterator RegsBegin, RegsEnd; - const unsigned char *const RegSet; - const unsigned RegSetSize; -public: - MCRegisterClass(unsigned id, const char *name, - unsigned RS, unsigned Al, int CC, bool Allocable, - iterator RB, iterator RE, const unsigned char *Bits, - unsigned NumBytes) - : ID(id), Name(name), RegSize(RS), Alignment(Al), CopyCost(CC), - Allocatable(Allocable), RegsBegin(RB), RegsEnd(RE), RegSet(Bits), - RegSetSize(NumBytes) { - for (iterator i = RegsBegin; i != RegsEnd; ++i) - assert(contains(*i) && "Bit field corrupted."); - } /// getID() - Return the register class ID number. /// @@ -58,11 +49,11 @@ public: /// begin/end - Return all of the registers in this class. /// iterator begin() const { return RegsBegin; } - iterator end() const { return RegsEnd; } + iterator end() const { return RegsBegin + RegsSize; } /// getNumRegs - Return the number of registers in this class. /// - unsigned getNumRegs() const { return (unsigned)(RegsEnd-RegsBegin); } + unsigned getNumRegs() const { return RegsSize; } /// getRegister - Return the specified register in the class. /// @@ -115,10 +106,10 @@ public: /// of AX. /// struct MCRegisterDesc { - const char *Name; // Printable name for the reg (for debugging) - const unsigned *Overlaps; // Overlapping registers, described above - const unsigned *SubRegs; // Sub-register set, described above - const unsigned *SuperRegs; // Super-register set, described above + const char *Name; // Printable name for the reg (for debugging) + uint32_t Overlaps; // Overlapping registers, described above + uint32_t SubRegs; // Sub-register set, described above + uint32_t SuperRegs; // Super-register set, described above }; /// MCRegisterInfo base class - We assume that the target defines a static @@ -136,50 +127,82 @@ struct MCRegisterDesc { class MCRegisterInfo { public: typedef const MCRegisterClass *regclass_iterator; + + /// DwarfLLVMRegPair - Emitted by tablegen so Dwarf<->LLVM reg mappings can be + /// performed with a binary search. + struct DwarfLLVMRegPair { + unsigned FromReg; + unsigned ToReg; + + bool operator<(DwarfLLVMRegPair RHS) const { return FromReg < RHS.FromReg; } + }; private: const MCRegisterDesc *Desc; // Pointer to the descriptor array unsigned NumRegs; // Number of entries in the array unsigned RAReg; // Return address register const MCRegisterClass *Classes; // Pointer to the regclass array unsigned NumClasses; // Number of entries in the array - DenseMap<unsigned, int> L2DwarfRegs; // LLVM to Dwarf regs mapping - DenseMap<unsigned, int> EHL2DwarfRegs; // LLVM to Dwarf regs mapping EH - DenseMap<unsigned, unsigned> Dwarf2LRegs; // Dwarf to LLVM regs mapping - DenseMap<unsigned, unsigned> EHDwarf2LRegs; // Dwarf to LLVM regs mapping EH + const uint16_t *RegLists; // Pointer to the reglists array + const uint16_t *SubRegIndices; // Pointer to the subreg lookup + // array. + unsigned NumSubRegIndices; // Number of subreg indices. + + unsigned L2DwarfRegsSize; + unsigned EHL2DwarfRegsSize; + unsigned Dwarf2LRegsSize; + unsigned EHDwarf2LRegsSize; + const DwarfLLVMRegPair *L2DwarfRegs; // LLVM to Dwarf regs mapping + const DwarfLLVMRegPair *EHL2DwarfRegs; // LLVM to Dwarf regs mapping EH + const DwarfLLVMRegPair *Dwarf2LRegs; // Dwarf to LLVM regs mapping + const DwarfLLVMRegPair *EHDwarf2LRegs; // Dwarf to LLVM regs mapping EH DenseMap<unsigned, int> L2SEHRegs; // LLVM to SEH regs mapping public: /// InitMCRegisterInfo - Initialize MCRegisterInfo, called by TableGen /// auto-generated routines. *DO NOT USE*. void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR, unsigned RA, - const MCRegisterClass *C, unsigned NC) { + const MCRegisterClass *C, unsigned NC, + const uint16_t *RL, + const uint16_t *SubIndices, + unsigned NumIndices) { Desc = D; NumRegs = NR; RAReg = RA; Classes = C; + RegLists = RL; NumClasses = NC; + SubRegIndices = SubIndices; + NumSubRegIndices = NumIndices; } - /// mapLLVMRegToDwarfReg - Used to initialize LLVM register to Dwarf + /// mapLLVMRegsToDwarfRegs - Used to initialize LLVM register to Dwarf /// register number mapping. Called by TableGen auto-generated routines. /// *DO NOT USE*. - void mapLLVMRegToDwarfReg(unsigned LLVMReg, int DwarfReg, bool isEH) { - if (isEH) - EHL2DwarfRegs[LLVMReg] = DwarfReg; - else - L2DwarfRegs[LLVMReg] = DwarfReg; + void mapLLVMRegsToDwarfRegs(const DwarfLLVMRegPair *Map, unsigned Size, + bool isEH) { + if (isEH) { + EHL2DwarfRegs = Map; + EHL2DwarfRegsSize = Size; + } else { + L2DwarfRegs = Map; + L2DwarfRegsSize = Size; + } } - - /// mapDwarfRegToLLVMReg - Used to initialize Dwarf register to LLVM + + /// mapDwarfRegsToLLVMRegs - Used to initialize Dwarf register to LLVM /// register number mapping. Called by TableGen auto-generated routines. /// *DO NOT USE*. - void mapDwarfRegToLLVMReg(unsigned DwarfReg, unsigned LLVMReg, bool isEH) { - if (isEH) - EHDwarf2LRegs[DwarfReg] = LLVMReg; - else - Dwarf2LRegs[DwarfReg] = LLVMReg; + void mapDwarfRegsToLLVMRegs(const DwarfLLVMRegPair *Map, unsigned Size, + bool isEH) { + if (isEH) { + EHDwarf2LRegs = Map; + EHDwarf2LRegsSize = Size; + } else { + Dwarf2LRegs = Map; + Dwarf2LRegsSize = Size; + } } - + /// mapLLVMRegToSEHReg - Used to initialize LLVM register to SEH register /// number mapping. By default the SEH register number is just the same /// as the LLVM register number. @@ -212,9 +235,9 @@ public: /// register, or a null list of there are none. The list returned is zero /// terminated. /// - const unsigned *getAliasSet(unsigned RegNo) const { + const uint16_t *getAliasSet(unsigned RegNo) const { // The Overlaps set always begins with Reg itself. - return get(RegNo).Overlaps + 1; + return RegLists + get(RegNo).Overlaps + 1; } /// getOverlaps - Return a list of registers that overlap Reg, including @@ -222,8 +245,8 @@ public: /// list. /// These are exactly the registers in { x | regsOverlap(x, Reg) }. /// - const unsigned *getOverlaps(unsigned RegNo) const { - return get(RegNo).Overlaps; + const uint16_t *getOverlaps(unsigned RegNo) const { + return RegLists + get(RegNo).Overlaps; } /// getSubRegisters - Return the list of registers that are sub-registers of @@ -231,8 +254,35 @@ public: /// returned is zero terminated and sorted according to super-sub register /// relations. e.g. X86::RAX's sub-register list is EAX, AX, AL, AH. /// - const unsigned *getSubRegisters(unsigned RegNo) const { - return get(RegNo).SubRegs; + const uint16_t *getSubRegisters(unsigned RegNo) const { + return RegLists + get(RegNo).SubRegs; + } + + /// getSubReg - 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 { + return *(SubRegIndices + (Reg - 1) * NumSubRegIndices + Idx - 1); + } + + /// getMatchingSuperReg - 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 { + for (const uint16_t *SRs = getSuperRegisters(Reg); unsigned SR = *SRs;++SRs) + if (Reg == getSubReg(SR, SubIdx) && RC->contains(SR)) + return SR; + return 0; + } + + /// getSubRegIndex - 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 { + for (unsigned I = 1; I <= NumSubRegIndices; ++I) + if (getSubReg(RegNo, I) == SubRegNo) + return I; + return 0; } /// getSuperRegisters - Return the list of registers that are super-registers @@ -240,8 +290,8 @@ public: /// returned is zero terminated and sorted according to super-sub register /// relations. e.g. X86::AL's super-register list is AX, EAX, RAX. /// - const unsigned *getSuperRegisters(unsigned RegNo) const { - return get(RegNo).SuperRegs; + const uint16_t *getSuperRegisters(unsigned RegNo) const { + return RegLists + get(RegNo).SuperRegs; } /// getName - Return the human-readable symbolic target-specific name for the @@ -261,22 +311,26 @@ public: /// parameter allows targets to use different numberings for EH info and /// debugging info. int getDwarfRegNum(unsigned RegNum, bool isEH) const { - const DenseMap<unsigned, int> &M = isEH ? EHL2DwarfRegs : L2DwarfRegs; - const DenseMap<unsigned, int>::const_iterator I = M.find(RegNum); - if (I == M.end()) return -1; - return I->second; + const DwarfLLVMRegPair *M = isEH ? EHL2DwarfRegs : L2DwarfRegs; + unsigned Size = isEH ? EHL2DwarfRegsSize : L2DwarfRegsSize; + + DwarfLLVMRegPair Key = { RegNum, 0 }; + const DwarfLLVMRegPair *I = std::lower_bound(M, M+Size, Key); + if (I == M+Size || I->FromReg != RegNum) + return -1; + return I->ToReg; } /// getLLVMRegNum - Map a dwarf register back to a target register. /// int getLLVMRegNum(unsigned RegNum, bool isEH) const { - const DenseMap<unsigned, unsigned> &M = isEH ? EHDwarf2LRegs : Dwarf2LRegs; - const DenseMap<unsigned, unsigned>::const_iterator I = M.find(RegNum); - if (I == M.end()) { - assert(0 && "Invalid RegNum"); - return -1; - } - return I->second; + const DwarfLLVMRegPair *M = isEH ? EHDwarf2LRegs : Dwarf2LRegs; + unsigned Size = isEH ? EHDwarf2LRegsSize : Dwarf2LRegsSize; + + DwarfLLVMRegPair Key = { RegNum, 0 }; + const DwarfLLVMRegPair *I = std::lower_bound(M, M+Size, Key); + assert(I != M+Size && I->FromReg == RegNum && "Invalid RegNum"); + return I->ToReg; } /// getSEHRegNum - Map a target register to an equivalent SEH register @@ -301,7 +355,7 @@ public: return Classes[i]; } }; - + } // End llvm namespace #endif diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h index 5700817..7da6534 100644 --- a/include/llvm/MC/MCSection.h +++ b/include/llvm/MC/MCSection.h @@ -14,12 +14,10 @@ #ifndef LLVM_MC_MCSECTION_H #define LLVM_MC_MCSECTION_H -#include "llvm/ADT/StringRef.h" #include "llvm/MC/SectionKind.h" #include "llvm/Support/Casting.h" namespace llvm { - class MCContext; class MCAsmInfo; class raw_ostream; diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h index b154cf5..7eacde5 100644 --- a/include/llvm/MC/MCSectionCOFF.h +++ b/include/llvm/MC/MCSectionCOFF.h @@ -15,8 +15,8 @@ #define LLVM_MC_MCSECTIONCOFF_H #include "llvm/MC/MCSection.h" - #include "llvm/Support/COFF.h" +#include "llvm/ADT/StringRef.h" namespace llvm { diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h index c82de71..7321ca8 100644 --- a/include/llvm/MC/MCSectionELF.h +++ b/include/llvm/MC/MCSectionELF.h @@ -16,6 +16,7 @@ #include "llvm/MC/MCSection.h" #include "llvm/Support/ELF.h" +#include "llvm/ADT/StringRef.h" namespace llvm { diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h index bdb17e9..15eb4f4 100644 --- a/include/llvm/MC/MCSectionMachO.h +++ b/include/llvm/MC/MCSectionMachO.h @@ -15,6 +15,7 @@ #define LLVM_MC_MCSECTIONMACHO_H #include "llvm/MC/MCSection.h" +#include "llvm/ADT/StringRef.h" namespace llvm { diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 451efbf..2595600 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -23,7 +23,6 @@ namespace llvm { class MCAsmBackend; - class MCAsmInfo; class MCCodeEmitter; class MCContext; class MCExpr; @@ -32,7 +31,6 @@ namespace llvm { class MCSection; class MCSymbol; class StringRef; - class TargetLoweringObjectFile; class Twine; class raw_ostream; class formatted_raw_ostream; @@ -94,6 +92,10 @@ namespace llvm { const MCExpr *ForceExpAbs(const MCExpr* Expr); + void RecordProcStart(MCDwarfFrameInfo &Frame); + virtual void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame); + void RecordProcEnd(MCDwarfFrameInfo &Frame); + virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &CurFrame); void EmitFrames(bool usingCFI); MCWin64EHUnwindInfo *getCurrentW64UnwindInfo(){return CurrentW64UnwindInfo;} @@ -334,6 +336,11 @@ namespace llvm { /// EndCOFFSymbolDef - Marks the end of the symbol definition. virtual void EndCOFFSymbolDef() = 0; + /// EmitCOFFSecRel32 - Emits a COFF section relative relocation. + /// + /// @param Symbol - Symbol the section relative realocation should point to. + virtual void EmitCOFFSecRel32(MCSymbol const *Symbol); + /// EmitELFSize - Emit an ELF .size directive. /// /// This corresponds to an assembler statement such as: @@ -420,7 +427,8 @@ namespace llvm { /// EmitULEB128Value - Special case of EmitULEB128Value that avoids the /// client having to pass in a MCExpr for constant integers. - void EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace = 0); + void EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace = 0, + unsigned Padding = 0); /// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the /// client having to pass in a MCExpr for constant integers. @@ -431,6 +439,13 @@ namespace llvm { void EmitSymbolValue(const MCSymbol *Sym, unsigned Size, unsigned AddrSpace = 0); + /// EmitGPRel64Value - Emit the expression @p Value into the output as a + /// gprel64 (64-bit GP relative) value. + /// + /// This is used to implement assembler directives such as .gpdword on + /// targets that support them. + virtual void EmitGPRel64Value(const MCExpr *Value); + /// EmitGPRel32Value - Emit the expression @p Value into the output as a /// gprel32 (32-bit GP relative) value. /// @@ -493,7 +508,8 @@ namespace llvm { /// @param Offset - The offset to reach. This may be an expression, but the /// expression must be associated with the current section. /// @param Value - The value to use when filling bytes. - virtual void EmitValueToOffset(const MCExpr *Offset, + /// @return false on success, true if the offset was invalid. + virtual bool EmitValueToOffset(const MCExpr *Offset, unsigned char Value = 0) = 0; /// @} @@ -505,7 +521,8 @@ namespace llvm { /// EmitDwarfFileDirective - Associate a filename with a specified logical /// file number. This implements the DWARF2 '.file 4 "foo.c"' assembler /// directive. - virtual bool EmitDwarfFileDirective(unsigned FileNo,StringRef Filename); + virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, + StringRef Filename); /// EmitDwarfLocDirective - This implements the DWARF2 // '.loc fileno lineno ...' assembler directive. @@ -529,8 +546,8 @@ namespace llvm { virtual void EmitCompactUnwindEncoding(uint32_t CompactUnwindEncoding); virtual void EmitCFISections(bool EH, bool Debug); - virtual void EmitCFIStartProc(); - virtual void EmitCFIEndProc(); + void EmitCFIStartProc(); + void EmitCFIEndProc(); virtual void EmitCFIDefCfa(int64_t Register, int64_t Offset); virtual void EmitCFIDefCfaOffset(int64_t Offset); virtual void EmitCFIDefCfaRegister(int64_t Register); @@ -540,8 +557,11 @@ namespace llvm { virtual void EmitCFIRememberState(); virtual void EmitCFIRestoreState(); virtual void EmitCFISameValue(int64_t Register); + virtual void EmitCFIRestore(int64_t Register); virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset); virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment); + virtual void EmitCFIEscape(StringRef Values); + virtual void EmitCFISignalFrame(); virtual void EmitWin64EHStartProc(const MCSymbol *Symbol); virtual void EmitWin64EHEndProc(); @@ -581,8 +601,10 @@ namespace llvm { virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool isVector); + /// FinishImpl - Streamer specific finalization. + virtual void FinishImpl() = 0; /// Finish - Finish emission of machine code. - virtual void Finish() = 0; + void Finish(); }; /// createNullStreamer - Create a dummy machine code streamer, which does @@ -613,6 +635,7 @@ namespace llvm { bool isVerboseAsm, bool useLoc, bool useCFI, + bool useDwarfDirectory, MCInstPrinter *InstPrint = 0, MCCodeEmitter *CE = 0, MCAsmBackend *TAB = 0, @@ -638,14 +661,8 @@ namespace llvm { /// createELFStreamer - Create a machine code streamer which will generate /// ELF format object files. MCStreamer *createELFStreamer(MCContext &Ctx, MCAsmBackend &TAB, - raw_ostream &OS, MCCodeEmitter *CE, - bool RelaxAll, bool NoExecStack); - - /// createLoggingStreamer - Create a machine code streamer which just logs the - /// API calls and then dispatches to another streamer. - /// - /// The new streamer takes ownership of the \arg Child. - MCStreamer *createLoggingStreamer(MCStreamer *Child, raw_ostream &OS); + raw_ostream &OS, MCCodeEmitter *CE, + bool RelaxAll, bool NoExecStack); /// createPureStreamer - Create a machine code streamer which will generate /// "pure" MC object files, for use with MC-JIT and testing tools. diff --git a/include/llvm/MC/MCWinCOFFObjectWriter.h b/include/llvm/MC/MCWinCOFFObjectWriter.h new file mode 100644 index 0000000..7a0b1ff --- /dev/null +++ b/include/llvm/MC/MCWinCOFFObjectWriter.h @@ -0,0 +1,36 @@ +//===-- llvm/MC/MCWinCOFFObjectWriter.h - Win COFF Object Writer *- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCWINCOFFOBJECTWRITER_H +#define LLVM_MC_MCWINCOFFOBJECTWRITER_H + +namespace llvm { + class MCWinCOFFObjectTargetWriter { + const unsigned Machine; + + protected: + MCWinCOFFObjectTargetWriter(unsigned Machine_); + + public: + virtual ~MCWinCOFFObjectTargetWriter() {} + + unsigned getMachine() const { return Machine; } + virtual unsigned getRelocType(unsigned FixupKind) const = 0; + }; + + /// \brief Construct a new Win COFF writer instance. + /// + /// \param MOTW - The target specific WinCOFF writer subclass. + /// \param OS - The stream to write to. + /// \returns The constructed object writer. + MCObjectWriter *createWinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW, + raw_ostream &OS); +} // End llvm namespace + +#endif |