diff options
Diffstat (limited to 'include/llvm/MC')
27 files changed, 1443 insertions, 110 deletions
diff --git a/include/llvm/MC/EDInstInfo.h b/include/llvm/MC/EDInstInfo.h index 83d9e78..0b9d3f6 100644 --- a/include/llvm/MC/EDInstInfo.h +++ b/include/llvm/MC/EDInstInfo.h @@ -21,7 +21,7 @@ struct EDInstInfo { uint8_t numOperands; uint8_t operandTypes[EDIS_MAX_OPERANDS]; uint8_t operandFlags[EDIS_MAX_OPERANDS]; - const char operandOrders[EDIS_MAX_SYNTAXES][EDIS_MAX_OPERANDS]; + const signed char operandOrders[EDIS_MAX_SYNTAXES][EDIS_MAX_OPERANDS]; }; } // namespace llvm diff --git a/include/llvm/MC/MCAsmBackend.h b/include/llvm/MC/MCAsmBackend.h new file mode 100644 index 0000000..4a0cf37 --- /dev/null +++ b/include/llvm/MC/MCAsmBackend.h @@ -0,0 +1,131 @@ +//===-- llvm/MC/MCAsmBack.h - MC Asm Backend --------------------*- 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_MCASMBACKEND_H +#define LLVM_MC_MCASMBACKEND_H + +#include "llvm/MC/MCDirectives.h" +#include "llvm/MC/MCFixup.h" +#include "llvm/MC/MCFixupKindInfo.h" +#include "llvm/Support/DataTypes.h" + +namespace llvm { +class MCELFObjectTargetWriter; +class MCFixup; +class MCInst; +class MCObjectWriter; +class MCSection; +template<typename T> +class SmallVectorImpl; +class raw_ostream; + +/// MCAsmBackend - Generic interface to target specific assembler backends. +class MCAsmBackend { + MCAsmBackend(const MCAsmBackend &); // DO NOT IMPLEMENT + void operator=(const MCAsmBackend &); // DO NOT IMPLEMENT +protected: // Can only create subclasses. + MCAsmBackend(); + + unsigned HasReliableSymbolDifference : 1; + +public: + virtual ~MCAsmBackend(); + + /// 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; + + /// 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; + } + + /// hasReliableSymbolDifference - Check whether this target implements + /// accurate relocations for differences between symbols. If not, differences + /// between symbols will always be relocatable expressions and any references + /// to temporary symbols will be assumed to be in the same atom, unless they + /// reside in a different section. + /// + /// This should always be true (since it results in fewer relocations with no + /// loss of functionality), but is currently supported as a way to maintain + /// exact object compatibility with Darwin 'as' (on non-x86_64). It should + /// eventually should be eliminated. + bool hasReliableSymbolDifference() const { + return HasReliableSymbolDifference; + } + + /// doesSectionRequireSymbols - Check whether the given section requires that + /// all symbols (even temporaries) have symbol table entries. + virtual bool doesSectionRequireSymbols(const MCSection &Section) const { + return false; + } + + /// isSectionAtomizable - Check whether the given section can be split into + /// atoms. + /// + /// \see MCAssembler::isSymbolLinkerVisible(). + virtual bool isSectionAtomizable(const MCSection &Section) const { + return true; + } + + /// @name Target Fixup Interfaces + /// @{ + + /// getNumFixupKinds - Get the number of target specific fixup kinds. + virtual unsigned getNumFixupKinds() const = 0; + + /// getFixupKindInfo - Get information on a fixup kind. + virtual const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const; + + /// @} + + /// 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, + uint64_t Value) const = 0; + + /// @} + + /// @name Target Relaxation Interfaces + /// @{ + + /// MayNeedRelaxation - Check whether the given instruction may need + /// relaxation. + /// + /// \param Inst - The instruction to test. + virtual bool MayNeedRelaxation(const MCInst &Inst) 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 + /// output. + /// \parm Res [output] - On return, the relaxed instruction. + virtual void RelaxInstruction(const MCInst &Inst, MCInst &Res) const = 0; + + /// @} + + /// 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; + + /// HandleAssemblerFlag - Handle any target-specific assembler flags. + /// By default, do nothing. + virtual void HandleAssemblerFlag(MCAssemblerFlag Flag) {} +}; + +} // End llvm namespace + +#endif diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index 41c1717..c3c296e 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -16,8 +16,10 @@ #ifndef LLVM_TARGET_ASM_INFO_H #define LLVM_TARGET_ASM_INFO_H +#include "llvm/MC/MachineLocation.h" #include "llvm/MC/MCDirectives.h" #include <cassert> +#include <vector> namespace llvm { class MCExpr; @@ -30,6 +32,14 @@ namespace llvm { enum ExceptionsType { None, DwarfCFI, SjLj, ARM, Win64 }; } + namespace LCOMM { + 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 { @@ -62,6 +72,11 @@ 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 @@ -115,6 +130,13 @@ namespace llvm { const char *InlineAsmStart; // Defaults to "#APP\n" const char *InlineAsmEnd; // Defaults to "#NO_APP\n" + /// Code16Directive, Code32Directive, Code64Directive - These are assembly + /// directives that tells the assembler to interpret the following + /// instructions differently. + const char *Code16Directive; // Defaults to ".code16" + const char *Code32Directive; // Defaults to ".code32" + const char *Code64Directive; // Defaults to ".code64" + /// AssemblerDialect - Which dialect of an assembler variant to use. unsigned AssemblerDialect; // Defaults to 0 @@ -155,6 +177,18 @@ namespace llvm { const char *Data32bitsDirective; // Defaults to "\t.long\t" const char *Data64bitsDirective; // Defaults to "\t.quad\t" + /// [Data|Code]Begin - These magic labels are used to marked a region as + /// data or code, and are used to provide additional information for + /// correct disassembly on targets that like to mix data and code within + /// a segment. These labels will be implicitly suffixed by the streamer + /// to give them unique names. + const char *DataBegin; // Defaults to "$d." + const char *CodeBegin; // Defaults to "$a." + const char *JT8Begin; // Defaults to "$a." + const char *JT16Begin; // Defaults to "$a." + const char *JT32Begin; // Defaults to "$a." + bool SupportsDataRegions; + /// 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. @@ -220,9 +254,9 @@ namespace llvm { /// .long a - b bool HasAggressiveSymbolFolding; // Defaults to true. - /// HasLCOMMDirective - This is true if the target supports the .lcomm - /// directive. - bool HasLCOMMDirective; // Defaults to false. + /// LCOMMDirectiveType - Describes if the target supports the .lcomm + /// directive and whether it has an alignment parameter. + LCOMM::LCOMMType LCOMMDirectiveType; // Defaults to LCOMM::None. /// COMMDirectiveAlignmentIsInBytes - True is COMMDirective's optional /// alignment is to be specified in bytes instead of log2(n). @@ -304,6 +338,10 @@ namespace llvm { const char *const *AsmTransCBE; // Defaults to empty + //===--- Prologue State ----------------------------------------------===// + + std::vector<MachineMove> InitialFrameState; + public: explicit MCAsmInfo(); virtual ~MCAsmInfo(); @@ -345,6 +383,14 @@ namespace llvm { } const char *getGPRel32Directive() const { return GPRel32Directive; } + /// [Code|Data]Begin label name accessors. + const char *getCodeBeginLabelName() const { return CodeBegin; } + const char *getDataBeginLabelName() const { return DataBegin; } + const char *getJumpTable8BeginLabelName() const { return JT8Begin; } + const char *getJumpTable16BeginLabelName() const { return JT16Begin; } + const char *getJumpTable32BeginLabelName() const { return JT32Begin; } + bool getSupportsDataRegions() const { return SupportsDataRegions; } + /// getNonexecutableStackSection - Targets can implement this method to /// specify a section to switch to if the translation unit doesn't have any /// trampolines that require an executable stack. @@ -378,6 +424,9 @@ namespace llvm { // bool hasMachoZeroFillDirective() const { return HasMachoZeroFillDirective; } bool hasMachoTBSSDirective() const { return HasMachoTBSSDirective; } + Structors::OutputOrder getStructorOutputOrder() const { + return StructorOutputOrder; + } bool hasStaticCtorDtorReferenceInStaticMode() const { return HasStaticCtorDtorReferenceInStaticMode; } @@ -417,6 +466,15 @@ namespace llvm { const char *getInlineAsmEnd() const { return InlineAsmEnd; } + const char *getCode16Directive() const { + return Code16Directive; + } + const char *getCode32Directive() const { + return Code32Directive; + } + const char *getCode64Directive() const { + return Code64Directive; + } unsigned getAssemblerDialect() const { return AssemblerDialect; } @@ -457,7 +515,9 @@ namespace llvm { bool hasAggressiveSymbolFolding() const { return HasAggressiveSymbolFolding; } - bool hasLCOMMDirective() const { return HasLCOMMDirective; } + LCOMM::LCOMMType getLCOMMDirectiveType() const { + return LCOMMDirectiveType; + } bool hasDotTypeDotSizeDirective() const {return HasDotTypeDotSizeDirective;} bool getCOMMDirectiveAlignmentIsInBytes() const { return COMMDirectiveAlignmentIsInBytes; @@ -512,6 +572,14 @@ namespace llvm { const char *const *getAsmCBE() const { return AsmTransCBE; } + + void addInitialFrameState(MCSymbol *label, const MachineLocation &D, + const MachineLocation &S) { + InitialFrameState.push_back(MachineMove(label, D, S)); + } + const std::vector<MachineMove> &getInitialFrameState() const { + return InitialFrameState; + } }; } diff --git a/include/llvm/MC/MCAsmInfoDarwin.h b/include/llvm/MC/MCAsmInfoDarwin.h index c85aa3d..1f6c499 100644 --- a/include/llvm/MC/MCAsmInfoDarwin.h +++ b/include/llvm/MC/MCAsmInfoDarwin.h @@ -18,11 +18,6 @@ #include "llvm/MC/MCAsmInfo.h" namespace llvm { - class GlobalValue; - class GlobalVariable; - class Type; - class Mangler; - struct MCAsmInfoDarwin : public MCAsmInfo { explicit MCAsmInfoDarwin(); }; diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index fc91966..b8f8cc4 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -10,14 +10,14 @@ #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/Support/Casting.h" -#include "llvm/MC/MCFixup.h" -#include "llvm/MC/MCInst.h" #include "llvm/Support/DataTypes.h" #include <vector> // FIXME: Shouldn't be needed. @@ -36,7 +36,7 @@ class MCSectionData; class MCSymbol; class MCSymbolData; class MCValue; -class TargetAsmBackend; +class MCAsmBackend; class MCFragment : public ilist_node<MCFragment> { friend class MCAsmLayout; @@ -660,7 +660,7 @@ private: MCContext &Context; - TargetAsmBackend &Backend; + MCAsmBackend &Backend; MCCodeEmitter &Emitter; @@ -780,14 +780,14 @@ public: // concrete and require clients to pass in a target like object. The other // option is to make this abstract, and have targets provide concrete // implementations as we do with AsmParser. - MCAssembler(MCContext &Context_, TargetAsmBackend &Backend_, + MCAssembler(MCContext &Context_, MCAsmBackend &Backend_, MCCodeEmitter &Emitter_, MCObjectWriter &Writer_, raw_ostream &OS); ~MCAssembler(); MCContext &getContext() const { return Context; } - TargetAsmBackend &getBackend() const { return Backend; } + MCAsmBackend &getBackend() const { return Backend; } MCCodeEmitter &getEmitter() const { return Emitter; } diff --git a/include/llvm/MC/MCAtom.h b/include/llvm/MC/MCAtom.h new file mode 100644 index 0000000..682cf7c --- /dev/null +++ b/include/llvm/MC/MCAtom.h @@ -0,0 +1,68 @@ +//===-- llvm/MC/MCAtom.h - MCAtom class ---------------------*- 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 declaration of the MCAtom class, which is used to +// represent a contiguous region in a decoded object that is uniformly data or +// instructions; +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCATOM_H +#define LLVM_MC_MCATOM_H + +#include "llvm/MC/MCInst.h" +#include "llvm/Support/DataTypes.h" +#include <vector> + +namespace llvm { + +class MCModule; + +/// MCData - An entry in a data MCAtom. +// NOTE: This may change to a more complex type in the future. +typedef uint8_t MCData; + +/// MCAtom - Represents a contiguous range of either instructions (a TextAtom) +/// or data (a DataAtom). Address ranges are expressed as _closed_ intervals. +class MCAtom { + friend class MCModule; + typedef enum { TextAtom, DataAtom } AtomType; + + AtomType Type; + MCModule *Parent; + uint64_t Begin, End; + + std::vector<std::pair<uint64_t, MCInst> > Text; + std::vector<MCData> Data; + + // Private constructor - only callable by MCModule + MCAtom(AtomType T, MCModule *P, uint64_t B, uint64_t E) + : Type(T), Parent(P), Begin(B), End(E) { } + +public: + bool isTextAtom() { return Type == TextAtom; } + bool isDataAtom() { return Type == DataAtom; } + + void addInst(const MCInst &I, uint64_t Address, unsigned Size); + void addData(const MCData &D); + + /// split - Splits the atom in two at a given address, which must align with + /// and instruction boundary if this is a TextAtom. Returns the newly created + /// atom representing the high part of the split. + MCAtom *split(uint64_t SplitPt); + + /// truncate - Truncates an atom so that TruncPt is the last byte address + /// contained in the atom. + void truncate(uint64_t TruncPt); +}; + +} + +#endif + diff --git a/include/llvm/MC/MCCodeGenInfo.h b/include/llvm/MC/MCCodeGenInfo.h new file mode 100644 index 0000000..1c54c47 --- /dev/null +++ b/include/llvm/MC/MCCodeGenInfo.h @@ -0,0 +1,41 @@ +//===-- llvm/MC/MCCodeGenInfo.h - Target CodeGen Info -----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file tracks information about the target which can affect codegen, +// asm parsing, and asm printing. For example, relocation model. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCCODEGENINFO_H +#define LLVM_MC_MCCODEGENINFO_H + +#include "llvm/Support/CodeGen.h" + +namespace llvm { + + class MCCodeGenInfo { + /// RelocationModel - Relocation model: statcic, pic, etc. + /// + Reloc::Model RelocationModel; + + /// CMModel - Code model. + /// + CodeModel::Model CMModel; + + public: + void InitMCCodeGenInfo(Reloc::Model RM = Reloc::Default, + CodeModel::Model CM = CodeModel::Default); + + Reloc::Model getRelocationModel() const { return RelocationModel; } + + CodeModel::Model getCodeModel() const { return CMModel; } + }; +} // namespace llvm + +#endif diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index 43a9ce6..a49a35c 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -26,10 +26,11 @@ namespace llvm { class MCLabel; class MCDwarfFile; class MCDwarfLoc; + class MCObjectFileInfo; + class MCRegisterInfo; class MCLineSection; class StringRef; class Twine; - class TargetAsmInfo; class MCSectionMachO; class MCSectionELF; @@ -46,7 +47,11 @@ namespace llvm { /// The MCAsmInfo for this target. const MCAsmInfo &MAI; - const TargetAsmInfo *TAI; + /// The MCRegisterInfo for this target. + const MCRegisterInfo &MRI; + + /// The MCObjectFileInfo for this target. + const MCObjectFileInfo *MOFI; /// Allocator - Allocator object used for creating machine code objects. /// @@ -110,12 +115,15 @@ namespace llvm { MCSymbol *CreateSymbol(StringRef Name); public: - explicit MCContext(const MCAsmInfo &MAI, const TargetAsmInfo *TAI); + explicit MCContext(const MCAsmInfo &MAI, const MCRegisterInfo &MRI, + const MCObjectFileInfo *MOFI); ~MCContext(); const MCAsmInfo &getAsmInfo() const { return MAI; } - const TargetAsmInfo &getTargetAsmInfo() const { return *TAI; } + const MCRegisterInfo &getRegisterInfo() const { return MRI; } + + const MCObjectFileInfo *getObjectFileInfo() const { return MOFI; } void setAllowTemporaryLabels(bool Value) { AllowTemporaryLabels = Value; } diff --git a/include/llvm/MC/MCDirectives.h b/include/llvm/MC/MCDirectives.h index 1df55dc..9180d1b 100644 --- a/include/llvm/MC/MCDirectives.h +++ b/include/llvm/MC/MCDirectives.h @@ -47,8 +47,9 @@ enum MCSymbolAttr { enum MCAssemblerFlag { MCAF_SyntaxUnified, ///< .syntax (ARM/ELF) MCAF_SubsectionsViaSymbols, ///< .subsections_via_symbols (MachO) - MCAF_Code16, ///< .code 16 - MCAF_Code32 ///< .code 32 + MCAF_Code16, ///< .code16 (X86) / .code 16 (ARM) + MCAF_Code32, ///< .code32 (X86) / .code 32 (ARM) + MCAF_Code64 ///< .code64 (X86) }; } // end namespace llvm diff --git a/include/llvm/MC/MCDisassembler.h b/include/llvm/MC/MCDisassembler.h index ce8759a..454277d 100644 --- a/include/llvm/MC/MCDisassembler.h +++ b/include/llvm/MC/MCDisassembler.h @@ -15,6 +15,7 @@ namespace llvm { class MCInst; +class MCSubtargetInfo; class MemoryObject; class raw_ostream; class MCContext; @@ -25,8 +26,38 @@ struct EDInstInfo; /// and provides an array of assembly instructions. class MCDisassembler { public: + /// Ternary decode status. Most backends will just use Fail and + /// Success, however some have a concept of an instruction with + /// understandable semantics but which is architecturally + /// incorrect. An example of this is ARM UNPREDICTABLE instructions + /// which are disassemblable but cause undefined behaviour. + /// + /// Because it makes sense to disassemble these instructions, there + /// is a "soft fail" failure mode that indicates the MCInst& is + /// valid but architecturally incorrect. + /// + /// The enum numbers are deliberately chosen such that reduction + /// from Success->SoftFail ->Fail can be done with a simple + /// bitwise-AND: + /// + /// LEFT & TOP = | Success Unpredictable Fail + /// --------------+----------------------------------- + /// Success | Success Unpredictable Fail + /// Unpredictable | Unpredictable Unpredictable Fail + /// Fail | Fail Fail Fail + /// + /// An easy way of encoding this is as 0b11, 0b01, 0b00 for + /// Success, SoftFail, Fail respectively. + enum DecodeStatus { + Fail = 0, + SoftFail = 1, + Success = 3 + }; + /// Constructor - Performs initial setup for the disassembler. - MCDisassembler() : GetOpInfo(0), DisInfo(0), Ctx(0) {} + MCDisassembler(const MCSubtargetInfo &STI) : GetOpInfo(0), SymbolLookUp(0), + DisInfo(0), Ctx(0), + STI(STI), CommentStream(0) {} virtual ~MCDisassembler(); @@ -41,12 +72,17 @@ public: /// @param address - The address, in the memory space of region, of the first /// byte of the instruction. /// @param vStream - The stream to print warnings and diagnostic messages on. - /// @return - True if the instruction is valid; false otherwise. - virtual bool getInstruction(MCInst& instr, + /// @param cStream - The stream to print comments and annotations on. + /// @return - MCDisassembler::Success if the instruction is valid, + /// MCDisassembler::SoftFail if the instruction was + /// disassemblable but invalid, + /// MCDisassembler::Fail if the instruction was invalid. + virtual DecodeStatus getInstruction(MCInst& instr, uint64_t& size, const MemoryObject ®ion, uint64_t address, - raw_ostream &vStream) const = 0; + raw_ostream &vStream, + raw_ostream &cStream) const = 0; /// getEDInfo - Returns the enhanced instruction information corresponding to /// the disassembler. @@ -62,23 +98,37 @@ private: // // The function to get the symbolic information for operands. LLVMOpInfoCallback GetOpInfo; + // The function to lookup a symbol name. + LLVMSymbolLookupCallback SymbolLookUp; // The pointer to the block of symbolic information for above call back. void *DisInfo; // The assembly context for creating symbols and MCExprs in place of // immediate operands when there is symbolic information. MCContext *Ctx; +protected: + // Subtarget information, for instruction decoding predicates if required. + const MCSubtargetInfo &STI; public: void setupForSymbolicDisassembly(LLVMOpInfoCallback getOpInfo, + LLVMSymbolLookupCallback symbolLookUp, void *disInfo, MCContext *ctx) { GetOpInfo = getOpInfo; + SymbolLookUp = symbolLookUp; DisInfo = disInfo; Ctx = ctx; } LLVMOpInfoCallback getLLVMOpInfoCallback() const { return GetOpInfo; } + LLVMSymbolLookupCallback getLLVMSymbolLookupCallback() const { + return SymbolLookUp; + } void *getDisInfoBlock() const { return DisInfo; } MCContext *getMCContext() const { return Ctx; } + + // Marked mutable because we cache it inside the disassembler, rather than + // having to pass it around as an argument through all the autogenerated code. + mutable raw_ostream *CommentStream; }; } // namespace llvm diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h index 90c3728..431e3c4 100644 --- a/include/llvm/MC/MCDwarf.h +++ b/include/llvm/MC/MCDwarf.h @@ -16,15 +16,13 @@ #define LLVM_MC_MCDWARF_H #include "llvm/ADT/StringRef.h" -#include "llvm/CodeGen/MachineLocation.h" // FIXME +#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 TargetAsmInfo; - class MachineMove; class MCContext; class MCExpr; class MCSection; @@ -265,7 +263,7 @@ namespace llvm { struct MCDwarfFrameInfo { MCDwarfFrameInfo() : Begin(0), End(0), Personality(0), Lsda(0), Function(0), Instructions(), PersonalityEncoding(), - LsdaEncoding(0) {} + LsdaEncoding(0), CompactUnwindEncoding(0) {} MCSymbol *Begin; MCSymbol *End; const MCSymbol *Personality; @@ -274,6 +272,7 @@ namespace llvm { std::vector<MCCFIInstruction> Instructions; unsigned PersonalityEncoding; unsigned LsdaEncoding; + uint32_t CompactUnwindEncoding; }; class MCDwarfFrameEmitter { diff --git a/include/llvm/MC/MCInst.h b/include/llvm/MC/MCInst.h index d6ef7b4..d384764 100644 --- a/include/llvm/MC/MCInst.h +++ b/include/llvm/MC/MCInst.h @@ -144,6 +144,16 @@ public: Operands.push_back(Op); } + void clear() { Operands.clear(); } + size_t size() { return Operands.size(); } + + typedef SmallVector<MCOperand, 8>::iterator iterator; + iterator begin() { return Operands.begin(); } + iterator end() { return Operands.end(); } + iterator insert(iterator I, const MCOperand &Op) { + return Operands.insert(I, Op); + } + void print(raw_ostream &OS, const MCAsmInfo *MAI) const; void dump() const; diff --git a/include/llvm/MC/MCInstPrinter.h b/include/llvm/MC/MCInstPrinter.h index 39002da..01ad2d3f 100644 --- a/include/llvm/MC/MCInstPrinter.h +++ b/include/llvm/MC/MCInstPrinter.h @@ -28,6 +28,9 @@ protected: /// The current set of available features. unsigned AvailableFeatures; + + /// Utility function for printing annotations. + void printAnnotation(raw_ostream &OS, StringRef Annot); public: MCInstPrinter(const MCAsmInfo &mai) : CommentStream(0), MAI(mai), AvailableFeatures(0) {} @@ -39,7 +42,8 @@ public: /// printInst - Print the specified MCInst to the specified raw_ostream. /// - virtual void printInst(const MCInst *MI, raw_ostream &OS) = 0; + virtual void printInst(const MCInst *MI, raw_ostream &OS, + StringRef Annot) = 0; /// getOpcodeName - Return the name of the specified opcode enum (e.g. /// "MOV32ri") or empty if we can't resolve it. diff --git a/include/llvm/MC/MCInstrAnalysis.h b/include/llvm/MC/MCInstrAnalysis.h new file mode 100644 index 0000000..8f3c499 --- /dev/null +++ b/include/llvm/MC/MCInstrAnalysis.h @@ -0,0 +1,61 @@ +//===-- llvm/MC/MCInstrAnalysis.h - InstrDesc target hooks ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the MCInstrAnalysis class which the MCTargetDescs can +// derive from to give additional information to MC. +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstrDesc.h" +#include "llvm/MC/MCInstrInfo.h" + +namespace llvm { + +class MCInstrAnalysis { +protected: + friend class Target; + const MCInstrInfo *Info; + +public: + MCInstrAnalysis(const MCInstrInfo *Info) : Info(Info) {} + + virtual ~MCInstrAnalysis() {} + + virtual bool isBranch(const MCInst &Inst) const { + return Info->get(Inst.getOpcode()).isBranch(); + } + + virtual bool isConditionalBranch(const MCInst &Inst) const { + return Info->get(Inst.getOpcode()).isBranch(); + } + + virtual bool isUnconditionalBranch(const MCInst &Inst) const { + return Info->get(Inst.getOpcode()).isUnconditionalBranch(); + } + + virtual bool isIndirectBranch(const MCInst &Inst) const { + return Info->get(Inst.getOpcode()).isIndirectBranch(); + } + + virtual bool isCall(const MCInst &Inst) const { + return Info->get(Inst.getOpcode()).isCall(); + } + + virtual bool isReturn(const MCInst &Inst) const { + return Info->get(Inst.getOpcode()).isReturn(); + } + + /// evaluateBranch - Given a branch instruction try to get the address the + /// branch targets. Otherwise return -1. + virtual uint64_t + evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size) const; +}; + +} diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h index 4996914..aafa800 100644 --- a/include/llvm/MC/MCInstrDesc.h +++ b/include/llvm/MC/MCInstrDesc.h @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // // This file defines the MCOperandInfo and MCInstrDesc classes, which -// are used to describe target instructions and their operands. +// are used to describe target instructions and their operands. // //===----------------------------------------------------------------------===// @@ -22,14 +22,14 @@ namespace llvm { //===----------------------------------------------------------------------===// // Machine Operand Flags and Description //===----------------------------------------------------------------------===// - + namespace MCOI { // Operand constraints enum OperandConstraint { TIED_TO = 0, // Must be allocated the same register as. EARLY_CLOBBER // Operand is an early clobber register operand }; - + /// OperandFlags - These are flags set on operands, but should be considered /// private, all access should go through the MCOperandInfo accessors. /// See the accessors for a description of what these are. @@ -54,15 +54,15 @@ namespace MCOI { /// class MCOperandInfo { public: - /// RegClass - This specifies the register class enumeration of the operand + /// RegClass - This specifies the register class enumeration of the operand /// 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; - + /// Flags - These are flags from the MCOI::OperandFlags enum. unsigned short Flags; - + /// 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; @@ -70,21 +70,21 @@ public: /// OperandType - Information about the type of the operand. MCOI::OperandType OperandType; /// Currently no other information. - + /// isLookupPtrRegClass - Set if this operand is a pointer value and it /// requires a callback to look up its register class. - bool isLookupPtrRegClass() const { return Flags&(1 <<MCOI::LookupPtrRegClass);} - + bool isLookupPtrRegClass() const {return Flags&(1 <<MCOI::LookupPtrRegClass);} + /// isPredicate - Set if this is one of the operands that made up of /// the predicate operand that controls an isPredicable() instruction. bool isPredicate() const { return Flags & (1 << MCOI::Predicate); } - + /// isOptionalDef - Set if this operand is a optional def. /// bool isOptionalDef() const { return Flags & (1 << MCOI::OptionalDef); } }; - + //===----------------------------------------------------------------------===// // Machine Instruction Flags and Description //===----------------------------------------------------------------------===// @@ -97,6 +97,7 @@ namespace MCID { enum { Variadic = 0, HasOptionalDef, + Pseudo, Return, Call, Barrier, @@ -116,6 +117,7 @@ namespace MCID { Commutable, ConvertibleTo3Addr, UsesCustomInserter, + HasPostISelHook, Rematerializable, CheapAsAMove, ExtraSrcRegAllocReq, @@ -158,13 +160,13 @@ public: unsigned getOpcode() const { 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 @@ -173,15 +175,15 @@ public: unsigned getNumOperands() const { return NumOperands; } - + /// getNumDefs - Return the number of MachineOperands that are register - /// definitions. Register definitions always occur at the start of the + /// 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. unsigned getNumDefs() const { return NumDefs; } - + /// 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 @@ -189,13 +191,13 @@ public: bool isVariadic() const { return Flags & (1 << MCID::Variadic); } - + /// hasOptionalDef - 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); } - + /// 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 @@ -208,7 +210,7 @@ public: const unsigned *getImplicitUses() const { return ImplicitUses; } - + /// getNumImplicitUses - Return the number of implicit uses this instruction /// has. unsigned getNumImplicitUses() const { @@ -231,7 +233,7 @@ public: const unsigned *getImplicitDefs() const { return ImplicitDefs; } - + /// getNumImplicitDefs - Return the number of implicit defs this instruction /// has. unsigned getNumImplicitDefs() const { @@ -240,7 +242,7 @@ public: for (; ImplicitDefs[i]; ++i) /*empty*/; return i; } - + /// hasImplicitUseOfPhysReg - Return true if this instruction implicitly /// uses the specified physical register. bool hasImplicitUseOfPhysReg(unsigned Reg) const { @@ -249,7 +251,7 @@ public: if (*ImpUses == Reg) return true; return false; } - + /// hasImplicitDefOfPhysReg - Return true if this instruction implicitly /// defines the specified physical register. bool hasImplicitDefOfPhysReg(unsigned Reg) const { @@ -267,28 +269,47 @@ public: 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. + /// + bool isPseudo() const { + return Flags & (1 << MCID::Pseudo); + } + bool isReturn() const { return Flags & (1 << MCID::Return); } - + bool isCall() const { return Flags & (1 << MCID::Call); } - + /// isBarrier - 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); } - + + /// 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. @@ -298,7 +319,7 @@ public: bool isTerminator() const { return Flags & (1 << MCID::Terminator); } - + /// isBranch - 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 @@ -320,7 +341,7 @@ public: bool isConditionalBranch() const { return isBranch() & !isBarrier() & !isIndirectBranch(); } - + /// isUnconditionalBranch - 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 @@ -328,7 +349,7 @@ public: bool isUnconditionalBranch() const { 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 @@ -336,14 +357,14 @@ public: bool isPredicable() const { return Flags & (1 << MCID::Predicable); } - + /// isCompare - 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 - /// (including conditional moves) instruction. + /// (including conditional moves) instruction. bool isMoveImmediate() const { return Flags & (1 << MCID::MoveImm); } @@ -353,20 +374,20 @@ public: bool isBitcast() const { return Flags & (1 << MCID::Bitcast); } - + /// isNotDuplicable - 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 { return Flags & (1 << MCID::NotDuplicable); } - + /// hasDelaySlot - Returns true if the specified instruction has a delay slot /// which must be filled by the code generator. bool hasDelaySlot() const { return Flags & (1 << MCID::DelaySlot); } - + /// canFoldAsLoad - Return true for instructions that can be folded as /// memory operands in other instructions. The most common use for this /// is instructions that are simple loads from memory that don't modify @@ -378,7 +399,7 @@ public: bool canFoldAsLoad() const { return Flags & (1 << MCID::FoldableAsLoad); } - + //===--------------------------------------------------------------------===// // Side Effect Analysis //===--------------------------------------------------------------------===// @@ -389,8 +410,8 @@ public: bool mayLoad() const { return Flags & (1 << MCID::MayLoad); } - - + + /// mayStore - 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 @@ -398,7 +419,7 @@ public: bool mayStore() const { return Flags & (1 << MCID::MayStore); } - + /// hasUnmodeledSideEffects - Return true if this instruction has side /// effects that are not modeled by other flags. This does not return true /// for instructions whose effects are captured by: @@ -415,14 +436,14 @@ public: bool hasUnmodeledSideEffects() const { return Flags & (1 << MCID::UnmodeledSideEffects); } - + //===--------------------------------------------------------------------===// // Flags that indicate whether an instruction can be modified by a method. //===--------------------------------------------------------------------===// - + /// isCommutable - Return true if this may be a 2- or 3-address /// instruction (of the form "X = op Y, Z, ..."), which produces the same - /// result if Y and Z are exchanged. If this flag is set, then the + /// result if Y and Z are exchanged. If this flag is set, then the /// TargetInstrInfo::commuteInstruction method may be used to hack on the /// instruction. /// @@ -433,7 +454,7 @@ public: bool isCommutable() const { return Flags & (1 << MCID::Commutable); } - + /// isConvertibleTo3Addr - Return true if this is a 2-address instruction /// which can be changed into a 3-address instruction if needed. Doing this /// transformation can be profitable in the register allocator, because it @@ -451,11 +472,11 @@ public: bool isConvertibleTo3Addr() const { return Flags & (1 << MCID::ConvertibleTo3Addr); } - + /// usesCustomInsertionHook - Return true if this instruction requires /// custom insertion support when the DAG scheduler is inserting it into a /// machine basic block. If this is true for the instruction, it basically - /// means that it is a pseudo instruction used at SelectionDAG time that is + /// means that it is a pseudo instruction used at SelectionDAG time that is /// expanded out into magic code by the target when MachineInstrs are formed. /// /// If this is true, the TargetLoweringInfo::InsertAtEndOfBasicBlock method @@ -463,7 +484,15 @@ public: bool usesCustomInsertionHook() const { return Flags & (1 << MCID::UsesCustomInserter); } - + + /// hasPostISelHook - Return true if this instruction requires *adjustment* + /// after instruction selection by calling a target hook. For example, this + /// can be used to fill in ARM 's' optional operand depending on whether + /// the conditional flag register is used. + bool hasPostISelHook() const { + return Flags & (1 << MCID::HasPostISelHook); + } + /// isRematerializable - Returns true if this instruction is a candidate for /// remat. This flag is deprecated, please don't use it anymore. If this /// flag is set, the isReallyTriviallyReMaterializable() method is called to diff --git a/include/llvm/MC/MCModule.h b/include/llvm/MC/MCModule.h new file mode 100644 index 0000000..755fa02 --- /dev/null +++ b/include/llvm/MC/MCModule.h @@ -0,0 +1,58 @@ +//===-- llvm/MC/MCModule.h - MCModule class ---------------------*- 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 declaration of the MCModule class, which is used to +// represent a complete, disassembled object file or executable. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCMODULE_H +#define LLVM_MC_MCMODULE_H + +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/IntervalMap.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/Support/DataTypes.h" + +namespace llvm { + +class MCAtom; + +/// MCModule - This class represent a completely disassembled object file or +/// executable. It comprises a list of MCAtom's, and a branch target table. +/// Each atom represents a contiguous range of either instructions or data. +class MCModule { + /// AtomAllocationTracker - An MCModule owns its component MCAtom's, so it + /// must track them in order to ensure they are properly freed as atoms are + /// merged or otherwise manipulated. + SmallPtrSet<MCAtom*, 8> AtomAllocationTracker; + + /// OffsetMap - Efficiently maps offset ranges to MCAtom's. + IntervalMap<uint64_t, MCAtom*> OffsetMap; + + /// BranchTargetMap - Maps offsets that are determined to be branches and + /// can be statically resolved to their target offsets. + DenseMap<uint64_t, MCAtom*> BranchTargetMap; + + friend class MCAtom; + + /// remap - Update the interval mapping for an MCAtom. + void remap(MCAtom *Atom, uint64_t NewBegin, uint64_t NewEnd); + +public: + MCModule(IntervalMap<uint64_t, MCAtom*>::Allocator &A) : OffsetMap(A) { } + + /// createAtom - Creates a new MCAtom covering the specified offset range. + MCAtom *createAtom(MCAtom::AtomType Type, uint64_t Begin, uint64_t End); +}; + +} + +#endif + diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h new file mode 100644 index 0000000..060d508 --- /dev/null +++ b/include/llvm/MC/MCObjectFileInfo.h @@ -0,0 +1,294 @@ +//===-- llvm/MC/MCObjectFileInfo.h - Object File Info -----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file describes common object file formats. +// +//===----------------------------------------------------------------------===// + +#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" + +namespace llvm { +class MCContext; +class MCSection; +class Triple; + +class MCObjectFileInfo { +protected: + /// CommDirectiveSupportsAlignment - True if .comm supports alignment. This + /// is a hack for as long as we support 10.4 Tiger, whose assembler doesn't + /// support alignment on comm. + bool CommDirectiveSupportsAlignment; + + /// SupportsWeakEmptyEHFrame - True if target object file supports a + /// weak_definition of constant 0 for an omitted EH frame. + bool SupportsWeakOmittedEHFrame; + + /// IsFunctionEHFrameSymbolPrivate - This flag is set to true if the + /// "EH_frame" symbol for EH information should be an assembler temporary (aka + /// private linkage, aka an L or .L label) or false if it should be a normal + /// non-.globl label. This defaults to true. + bool IsFunctionEHFrameSymbolPrivate; + + /// PersonalityEncoding, LSDAEncoding, FDEEncoding, TTypeEncoding - Some + /// encoding values for EH. + unsigned PersonalityEncoding; + unsigned LSDAEncoding; + unsigned FDEEncoding; + unsigned FDECFIEncoding; + unsigned TTypeEncoding; + + /// TextSection - Section directive for standard text. + /// + const MCSection *TextSection; + + /// DataSection - Section directive for standard data. + /// + const MCSection *DataSection; + + /// BSSSection - Section that is default initialized to zero. + const MCSection *BSSSection; + + /// ReadOnlySection - Section that is readonly and can contain arbitrary + /// initialized data. Targets are not required to have a readonly section. + /// If they don't, various bits of code will fall back to using the data + /// section for constants. + const MCSection *ReadOnlySection; + + /// StaticCtorSection - This section contains the static constructor pointer + /// list. + const MCSection *StaticCtorSection; + + /// StaticDtorSection - This section contains the static destructor pointer + /// list. + const MCSection *StaticDtorSection; + + /// LSDASection - If exception handling is supported by the target, this is + /// the section the Language Specific Data Area information is emitted to. + const MCSection *LSDASection; + + /// CompactUnwindSection - If exception handling is supported by the target + /// and the target can support a compact representation of the CIE and FDE, + /// this is the section to emit them into. + const MCSection *CompactUnwindSection; + + // 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; + const MCSection *DwarfLocSection; + const MCSection *DwarfARangesSection; + const MCSection *DwarfRangesSection; + const MCSection *DwarfMacroInfoSection; + + // Extra TLS Variable Data section. If the target needs to put additional + // information for a TLS variable, it'll go here. + const MCSection *TLSExtraDataSection; + + /// TLSDataSection - Section directive for Thread Local data. + /// ELF and MachO only. + const MCSection *TLSDataSection; // Defaults to ".tdata". + + /// TLSBSSSection - Section directive for Thread Local uninitialized data. + /// Null if this target doesn't support a BSS section. + /// ELF and MachO only. + const MCSection *TLSBSSSection; // Defaults to ".tbss". + + + /// EHFrameSection - EH frame section. It is initialized on demand so it + /// can be overwritten (with uniquing). + const MCSection *EHFrameSection; + + /// ELF specific sections. + /// + const MCSection *DataRelSection; + const MCSection *DataRelLocalSection; + const MCSection *DataRelROSection; + const MCSection *DataRelROLocalSection; + const MCSection *MergeableConst4Section; + const MCSection *MergeableConst8Section; + const MCSection *MergeableConst16Section; + + /// MachO specific sections. + /// + + /// TLSTLVSection - Section for thread local structure information. + /// Contains the source code name of the variable, visibility and a pointer + /// to the initial value (.tdata or .tbss). + const MCSection *TLSTLVSection; // Defaults to ".tlv". + + /// TLSThreadInitSection - Section for thread local data initialization + /// functions. + const MCSection *TLSThreadInitSection; // Defaults to ".thread_init_func". + + const MCSection *CStringSection; + const MCSection *UStringSection; + const MCSection *TextCoalSection; + const MCSection *ConstTextCoalSection; + const MCSection *ConstDataSection; + const MCSection *DataCoalSection; + const MCSection *DataCommonSection; + const MCSection *DataBSSSection; + const MCSection *FourByteConstantSection; + const MCSection *EightByteConstantSection; + const MCSection *SixteenByteConstantSection; + const MCSection *LazySymbolPointerSection; + const MCSection *NonLazySymbolPointerSection; + + /// COFF specific sections. + /// + const MCSection *DrectveSection; + const MCSection *PDataSection; + const MCSection *XDataSection; + +public: + void InitMCObjectFileInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM, + MCContext &ctx); + + bool isFunctionEHFrameSymbolPrivate() const { + return IsFunctionEHFrameSymbolPrivate; + } + bool getSupportsWeakOmittedEHFrame() const { + return SupportsWeakOmittedEHFrame; + } + bool getCommDirectiveSupportsAlignment() const { + return CommDirectiveSupportsAlignment; + } + + unsigned getPersonalityEncoding() const { return PersonalityEncoding; } + unsigned getLSDAEncoding() const { return LSDAEncoding; } + unsigned getFDEEncoding(bool CFI) const { + return CFI ? FDECFIEncoding : FDEEncoding; + } + unsigned getTTypeEncoding() const { return TTypeEncoding; } + + 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 *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; + } + const MCSection *getDwarfStrSection() const { return DwarfStrSection; } + const MCSection *getDwarfLocSection() const { return DwarfLocSection; } + const MCSection *getDwarfARangesSection() const { return DwarfARangesSection;} + const MCSection *getDwarfRangesSection() const { return DwarfRangesSection; } + const MCSection *getDwarfMacroInfoSection() const { + return DwarfMacroInfoSection; + } + const MCSection *getTLSExtraDataSection() const { + return TLSExtraDataSection; + } + const MCSection *getTLSDataSection() const { return TLSDataSection; } + const MCSection *getTLSBSSSection() const { return TLSBSSSection; } + + /// ELF specific sections. + /// + const MCSection *getDataRelSection() const { return DataRelSection; } + const MCSection *getDataRelLocalSection() const { + return DataRelLocalSection; + } + const MCSection *getDataRelROSection() const { return DataRelROSection; } + const MCSection *getDataRelROLocalSection() const { + return DataRelROLocalSection; + } + const MCSection *getMergeableConst4Section() const { + return MergeableConst4Section; + } + const MCSection *getMergeableConst8Section() const { + return MergeableConst8Section; + } + const MCSection *getMergeableConst16Section() const { + return MergeableConst16Section; + } + + /// MachO specific sections. + /// + const MCSection *getTLSTLVSection() const { return TLSTLVSection; } + const MCSection *getTLSThreadInitSection() const { + return TLSThreadInitSection; + } + const MCSection *getCStringSection() const { return CStringSection; } + const MCSection *getUStringSection() const { return UStringSection; } + const MCSection *getTextCoalSection() const { return TextCoalSection; } + const MCSection *getConstTextCoalSection() const { + return ConstTextCoalSection; + } + const MCSection *getConstDataSection() const { return ConstDataSection; } + const MCSection *getDataCoalSection() const { return DataCoalSection; } + const MCSection *getDataCommonSection() const { return DataCommonSection; } + const MCSection *getDataBSSSection() const { return DataBSSSection; } + const MCSection *getFourByteConstantSection() const { + return FourByteConstantSection; + } + const MCSection *getEightByteConstantSection() const { + return EightByteConstantSection; + } + const MCSection *getSixteenByteConstantSection() const { + return SixteenByteConstantSection; + } + const MCSection *getLazySymbolPointerSection() const { + return LazySymbolPointerSection; + } + const MCSection *getNonLazySymbolPointerSection() const { + return NonLazySymbolPointerSection; + } + + /// COFF specific sections. + /// + const MCSection *getDrectveSection() const { return DrectveSection; } + const MCSection *getPDataSection() const { return PDataSection; } + const MCSection *getXDataSection() const { return XDataSection; } + + const MCSection *getEHFrameSection() { + if (!EHFrameSection) + InitEHFrameSection(); + return EHFrameSection; + } + +private: + enum Environment { IsMachO, IsELF, IsCOFF }; + Environment Env; + Reloc::Model RelocM; + CodeModel::Model CMModel; + MCContext *Ctx; + + void InitMachOMCObjectFileInfo(Triple T); + void InitELFMCObjectFileInfo(Triple T); + void InitCOFFMCObjectFileInfo(Triple T); + + /// InitEHFrameSection - Initialize EHFrameSection on demand. + /// + void InitEHFrameSection(); +}; + +} // end namespace llvm + +#endif diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h index a89933b..f897e64 100644 --- a/include/llvm/MC/MCObjectStreamer.h +++ b/include/llvm/MC/MCObjectStreamer.h @@ -19,7 +19,7 @@ class MCSectionData; class MCExpr; class MCFragment; class MCDataFragment; -class TargetAsmBackend; +class MCAsmBackend; class raw_ostream; /// \brief Streaming object file generation interface. @@ -36,9 +36,9 @@ class MCObjectStreamer : public MCStreamer { virtual void EmitInstToData(const MCInst &Inst) = 0; protected: - MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB, + MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &_OS, MCCodeEmitter *_Emitter); - MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB, + MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &_OS, MCCodeEmitter *_Emitter, MCAssembler *_Assembler); ~MCObjectStreamer(); diff --git a/include/llvm/MC/MCParser/AsmLexer.h b/include/llvm/MC/MCParser/AsmLexer.h index ab78799..dcecfb6 100644 --- a/include/llvm/MC/MCParser/AsmLexer.h +++ b/include/llvm/MC/MCParser/AsmLexer.h @@ -32,6 +32,7 @@ class AsmLexer : public MCAsmLexer { const char *CurPtr; const MemoryBuffer *CurBuf; + bool isAtStartOfLine; void operator=(const AsmLexer&); // DO NOT IMPLEMENT AsmLexer(const AsmLexer&); // DO NOT IMPLEMENT @@ -47,6 +48,7 @@ public: void setBuffer(const MemoryBuffer *buf, const char *ptr = NULL); virtual StringRef LexUntilEndOfStatement(); + StringRef LexUntilEndOfLine(); bool isAtStartOfComment(char Char); bool isAtStatementSeparator(const char *Ptr); diff --git a/include/llvm/MC/MCParser/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h index 47c580f..9bbb755 100644 --- a/include/llvm/MC/MCParser/MCAsmLexer.h +++ b/include/llvm/MC/MCParser/MCAsmLexer.h @@ -17,7 +17,6 @@ namespace llvm { class MCAsmLexer; class MCInst; -class Target; /// AsmToken - Target independent representation for an assembler token. class AsmToken { @@ -36,7 +35,7 @@ public: // Real values. Real, - // Register values (stored in IntVal). Only used by TargetAsmLexer. + // Register values (stored in IntVal). Only used by MCTargetAsmLexer. Register, // No-value. diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h index 7376693..6ff1753 100644 --- a/include/llvm/MC/MCParser/MCAsmParser.h +++ b/include/llvm/MC/MCParser/MCAsmParser.h @@ -20,11 +20,10 @@ class MCAsmParserExtension; class MCContext; class MCExpr; class MCStreamer; +class MCTargetAsmParser; class SMLoc; class SourceMgr; class StringRef; -class Target; -class TargetAsmParser; class Twine; /// MCAsmParser - Generic assembler parser interface, for use by target specific @@ -37,7 +36,7 @@ private: MCAsmParser(const MCAsmParser &); // DO NOT IMPLEMENT void operator=(const MCAsmParser &); // DO NOT IMPLEMENT - TargetAsmParser *TargetParser; + MCTargetAsmParser *TargetParser; unsigned ShowParsedOperands : 1; @@ -60,8 +59,8 @@ public: /// getStreamer - Return the output streamer for the assembler. virtual MCStreamer &getStreamer() = 0; - TargetAsmParser &getTargetParser() const { return *TargetParser; } - void setTargetParser(TargetAsmParser &P); + MCTargetAsmParser &getTargetParser() const { return *TargetParser; } + void setTargetParser(MCTargetAsmParser &P); bool getShowParsedOperands() const { return ShowParsedOperands; } void setShowParsedOperands(bool Value) { ShowParsedOperands = Value; } @@ -131,7 +130,7 @@ public: }; /// \brief Create an MCAsmParser instance. -MCAsmParser *createMCAsmParser(const Target &, SourceMgr &, MCContext &, +MCAsmParser *createMCAsmParser(SourceMgr &, MCContext &, MCStreamer &, const MCAsmInfo &); } // End llvm namespace diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h index caf98bb..ada5ae8 100644 --- a/include/llvm/MC/MCRegisterInfo.h +++ b/include/llvm/MC/MCRegisterInfo.h @@ -16,10 +16,94 @@ #ifndef LLVM_MC_MCREGISTERINFO_H #define LLVM_MC_MCREGISTERINFO_H +#include "llvm/ADT/DenseMap.h" #include <cassert> namespace llvm { +/// MCRegisterClass - Base class of TargetRegisterClass. +class MCRegisterClass { +public: + typedef const unsigned* iterator; + typedef const unsigned* const_iterator; +private: + unsigned ID; + const char *Name; + const unsigned RegSize, Alignment; // Size & Alignment of register in bytes + const int 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. + /// + unsigned getID() const { return ID; } + + /// getName() - Return the register class name for debugging. + /// + const char *getName() const { return Name; } + + /// begin/end - Return all of the registers in this class. + /// + iterator begin() const { return RegsBegin; } + iterator end() const { return RegsEnd; } + + /// getNumRegs - Return the number of registers in this class. + /// + unsigned getNumRegs() const { return (unsigned)(RegsEnd-RegsBegin); } + + /// getRegister - Return the specified register in the class. + /// + unsigned getRegister(unsigned i) const { + assert(i < getNumRegs() && "Register number out of range!"); + return RegsBegin[i]; + } + + /// contains - Return true if the specified register is included in this + /// register class. This does not include virtual registers. + bool contains(unsigned Reg) const { + unsigned InByte = Reg % 8; + unsigned Byte = Reg / 8; + if (Byte >= RegSetSize) + return false; + return (RegSet[Byte] & (1 << InByte)) != 0; + } + + /// contains - Return true if both registers are in this class. + bool contains(unsigned Reg1, unsigned Reg2) const { + return contains(Reg1) && contains(Reg2); + } + + /// getSize - Return the size of the register in bytes, which is also the size + /// of a stack slot allocated to hold a spilled copy of this register. + unsigned getSize() const { return RegSize; } + + /// getAlignment - Return the minimum required alignment for a register of + /// this class. + unsigned getAlignment() const { return Alignment; } + + /// getCopyCost - Return the cost of copying a value between two registers in + /// this class. A negative number means the register class is very expensive + /// to copy e.g. status flag register classes. + int getCopyCost() const { return CopyCost; } + + /// isAllocatable - Return true if this register class may be used to create + /// virtual registers. + bool isAllocatable() const { return Allocatable; } +}; + /// MCRegisterDesc - This record contains all of the information known about /// a particular register. The Overlaps field contains a pointer to a zero /// terminated array of registers that this register aliases, starting with @@ -50,18 +134,67 @@ struct MCRegisterDesc { /// virtual methods. /// class MCRegisterInfo { +public: + typedef const MCRegisterClass *regclass_iterator; private: - const MCRegisterDesc *Desc; // Pointer to the descriptor array - unsigned NumRegs; // Number of entries in the array + 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 + 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) { + void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR, unsigned RA, + const MCRegisterClass *C, unsigned NC) { Desc = D; NumRegs = NR; + RAReg = RA; + Classes = C; + NumClasses = NC; + } + + /// mapLLVMRegToDwarfReg - 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; } + /// mapDwarfRegToLLVMReg - 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; + } + + /// 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. + /// FIXME: TableGen these numbers. Currently this requires target specific + /// initialization code. + void mapLLVMRegToSEHReg(unsigned LLVMReg, int SEHReg) { + L2SEHRegs[LLVMReg] = SEHReg; + } + + /// getRARegister - This method should return the register where the return + /// address can be found. + unsigned getRARegister() const { + return RAReg; + } + const MCRegisterDesc &operator[](unsigned RegNo) const { assert(RegNo < NumRegs && "Attempting to access record for invalid register number!"); @@ -122,6 +255,51 @@ public: unsigned getNumRegs() const { return NumRegs; } + + /// getDwarfRegNum - 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 { + 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; + } + + /// 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; + } + + /// getSEHRegNum - 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 { + const DenseMap<unsigned, int>::const_iterator I = L2SEHRegs.find(RegNum); + if (I == L2SEHRegs.end()) return (int)RegNum; + return I->second; + } + + regclass_iterator regclass_begin() const { return Classes; } + regclass_iterator regclass_end() const { return Classes+NumClasses; } + + unsigned getNumRegClasses() const { + return (unsigned)(regclass_end()-regclass_begin()); + } + + /// getRegClass - Returns the register class associated with the enumeration + /// value. See class MCOperandInfo. + const MCRegisterClass getRegClass(unsigned i) const { + assert(i < getNumRegClasses() && "Register Class ID out of range"); + return Classes[i]; + } }; } // End llvm namespace diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 7bdba5f..451efbf 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -14,13 +14,15 @@ #ifndef LLVM_MC_MCSTREAMER_H #define LLVM_MC_MCSTREAMER_H -#include "llvm/ADT/SmallVector.h" #include "llvm/Support/DataTypes.h" #include "llvm/MC/MCDirectives.h" #include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCWin64EH.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallVector.h" namespace llvm { + class MCAsmBackend; class MCAsmInfo; class MCCodeEmitter; class MCContext; @@ -30,7 +32,6 @@ namespace llvm { class MCSection; class MCSymbol; class StringRef; - class TargetAsmBackend; class TargetLoweringObjectFile; class Twine; class raw_ostream; @@ -63,14 +64,29 @@ namespace llvm { void setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame); void EnsureValidW64UnwindInfo(); - const MCSymbol* LastNonPrivate; + MCSymbol* LastSymbol; /// SectionStack - This is stack of current and previous section /// values saved by PushSection. SmallVector<std::pair<const MCSection *, const MCSection *>, 4> SectionStack; + unsigned UniqueCodeBeginSuffix; + unsigned UniqueDataBeginSuffix; + protected: + /// Indicator of whether the previous data-or-code indicator was for + /// code or not. Used to determine when we need to emit a new indicator. + enum DataType { + Data, + Code, + JumpTable8, + JumpTable16, + JumpTable32 + }; + DataType RegionIndicator; + + MCStreamer(MCContext &Ctx); const MCExpr *BuildSymbolDiff(MCContext &Context, const MCSymbol *A, @@ -96,6 +112,10 @@ namespace llvm { return FrameInfos[i]; } + ArrayRef<MCDwarfFrameInfo> getFrameInfos() { + return FrameInfos; + } + unsigned getNumW64UnwindInfos() { return W64UnwindInfos.size(); } @@ -219,6 +239,41 @@ namespace llvm { /// used in an assignment. virtual void EmitLabel(MCSymbol *Symbol); + /// EmitDataRegion - Emit a label that marks the beginning of a data + /// region. + /// On ELF targets, this corresponds to an assembler statement such as: + /// $d.1: + virtual void EmitDataRegion(); + + /// EmitJumpTable8Region - Emit a label that marks the beginning of a + /// jump table composed of 8-bit offsets. + /// On ELF targets, this corresponds to an assembler statement such as: + /// $d.1: + virtual void EmitJumpTable8Region(); + + /// EmitJumpTable16Region - Emit a label that marks the beginning of a + /// jump table composed of 16-bit offsets. + /// On ELF targets, this corresponds to an assembler statement such as: + /// $d.1: + virtual void EmitJumpTable16Region(); + + /// EmitJumpTable32Region - Emit a label that marks the beginning of a + /// jump table composed of 32-bit offsets. + /// On ELF targets, this corresponds to an assembler statement such as: + /// $d.1: + virtual void EmitJumpTable32Region(); + + /// EmitCodeRegion - Emit a label that marks the beginning of a code + /// region. + /// On ELF targets, this corresponds to an assembler statement such as: + /// $a.1: + virtual void EmitCodeRegion(); + + /// ForceCodeRegion - Forcibly sets the current region mode to code. Used + /// at function entry points. + void ForceCodeRegion() { RegionIndicator = Code; } + + virtual void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol); @@ -299,7 +354,9 @@ namespace llvm { /// /// @param Symbol - The common symbol to emit. /// @param Size - The size of the common symbol. - virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) = 0; + /// @param ByteAlignment - The alignment of the common symbol in bytes. + virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment) = 0; /// EmitZerofill - Emit the zerofill section and an optional symbol. /// @@ -470,6 +527,7 @@ namespace llvm { void EmitDwarfSetLineAddr(int64_t LineDelta, const MCSymbol *Label, int PointerSize); + virtual void EmitCompactUnwindEncoding(uint32_t CompactUnwindEncoding); virtual void EmitCFISections(bool EH, bool Debug); virtual void EmitCFIStartProc(); virtual void EmitCFIEndProc(); @@ -557,14 +615,14 @@ namespace llvm { bool useCFI, MCInstPrinter *InstPrint = 0, MCCodeEmitter *CE = 0, - TargetAsmBackend *TAB = 0, + MCAsmBackend *TAB = 0, bool ShowInst = false); /// createMachOStreamer - Create a machine code streamer which will generate /// Mach-O format object files. /// /// Takes ownership of \arg TAB and \arg CE. - MCStreamer *createMachOStreamer(MCContext &Ctx, TargetAsmBackend &TAB, + MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *CE, bool RelaxAll = false); @@ -573,13 +631,13 @@ namespace llvm { /// /// Takes ownership of \arg TAB and \arg CE. MCStreamer *createWinCOFFStreamer(MCContext &Ctx, - TargetAsmBackend &TAB, + MCAsmBackend &TAB, MCCodeEmitter &CE, raw_ostream &OS, bool RelaxAll = false); /// createELFStreamer - Create a machine code streamer which will generate /// ELF format object files. - MCStreamer *createELFStreamer(MCContext &Ctx, TargetAsmBackend &TAB, + MCStreamer *createELFStreamer(MCContext &Ctx, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *CE, bool RelaxAll, bool NoExecStack); @@ -593,7 +651,7 @@ namespace llvm { /// "pure" MC object files, for use with MC-JIT and testing tools. /// /// Takes ownership of \arg TAB and \arg CE. - MCStreamer *createPureStreamer(MCContext &Ctx, TargetAsmBackend &TAB, + MCStreamer *createPureStreamer(MCContext &Ctx, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *CE); } // end namespace llvm diff --git a/include/llvm/MC/MCTargetAsmLexer.h b/include/llvm/MC/MCTargetAsmLexer.h new file mode 100644 index 0000000..acb3d4d --- /dev/null +++ b/include/llvm/MC/MCTargetAsmLexer.h @@ -0,0 +1,89 @@ +//===-- 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 &); // DO NOT IMPLEMENT + void operator=(const MCTargetAsmLexer &); // DO NOT IMPLEMENT +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 new file mode 100644 index 0000000..4e3fd0d --- /dev/null +++ b/include/llvm/MC/MCTargetAsmParser.h @@ -0,0 +1,103 @@ +//===-- llvm/MC/MCTargetAsmParser.h - Target Assembly Parser ----*- 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_TARGETPARSER_H +#define LLVM_MC_TARGETPARSER_H + +#include "llvm/MC/MCParser/MCAsmParserExtension.h" + +namespace llvm { +class MCStreamer; +class StringRef; +class SMLoc; +class AsmToken; +class MCParsedAsmOperand; +class MCInst; +template <typename T> class SmallVectorImpl; + +/// MCTargetAsmParser - Generic interface to target specific assembly parsers. +class MCTargetAsmParser : public MCAsmParserExtension { +public: + enum MatchResultTy { + Match_ConversionFail, + Match_InvalidOperand, + Match_MissingFeature, + Match_MnemonicFail, + Match_Success, + FIRST_TARGET_MATCH_RESULT_TY + }; + +private: + MCTargetAsmParser(const MCTargetAsmParser &); // DO NOT IMPLEMENT + void operator=(const MCTargetAsmParser &); // DO NOT IMPLEMENT +protected: // Can only create subclasses. + MCTargetAsmParser(); + + /// AvailableFeatures - The current set of available features. + unsigned AvailableFeatures; + +public: + virtual ~MCTargetAsmParser(); + + unsigned getAvailableFeatures() const { return AvailableFeatures; } + void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; } + + virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, + SMLoc &EndLoc) = 0; + + /// ParseInstruction - Parse one assembly instruction. + /// + /// The parser is positioned following the instruction name. The target + /// specific instruction parser should parse the entire instruction and + /// construct the appropriate MCInst, or emit an error. On success, the entire + /// line should be parsed up to and including the end-of-statement token. On + /// failure, the parser is not required to read to the end of the line. + // + /// \param Name - The instruction name. + /// \param NameLoc - The source location of the name. + /// \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, + SmallVectorImpl<MCParsedAsmOperand*> &Operands) = 0; + + /// ParseDirective - Parse a target specific assembler directive + /// + /// The parser is positioned following the directive name. The target + /// specific directive parser should parse the entire directive doing or + /// recording any target specific work, or return true and do nothing if the + /// directive is not target specific. If the directive is specific for + /// the target, the entire line is parsed up to and including the + /// end-of-statement token and false is returned. + /// + /// \param DirectiveID - the identifier token of the directive. + virtual bool ParseDirective(AsmToken DirectiveID) = 0; + + /// MatchAndEmitInstruction - Recognize a series of operands of a parsed + /// instruction as an actual MCInst and emit it to the specified MCStreamer. + /// 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 + MatchAndEmitInstruction(SMLoc IDLoc, + SmallVectorImpl<MCParsedAsmOperand*> &Operands, + MCStreamer &Out) = 0; + + /// checkTargetMatchPredicate - Validate the instruction match against + /// any complex target predicates not expressible via match classes. + virtual unsigned checkTargetMatchPredicate(MCInst &Inst) { + return Match_Success; + } + +}; + +} // End llvm namespace + +#endif diff --git a/include/llvm/MC/MCValue.h b/include/llvm/MC/MCValue.h index df8dbd9..8352ed1 100644 --- a/include/llvm/MC/MCValue.h +++ b/include/llvm/MC/MCValue.h @@ -46,16 +46,6 @@ public: /// isAbsolute - Is this an absolute (as opposed to relocatable) value. bool isAbsolute() const { return !SymA && !SymB; } - /// getAssociatedSection - For relocatable values, return the section the - /// value is associated with. - /// - /// @result - The value's associated section, or null for external or constant - /// values. - // - // FIXME: Switch to a tagged section, so this can return the tagged section - // value. - const MCSection *getAssociatedSection() const; - /// print - Print the value to the stream \arg OS. void print(raw_ostream &OS, const MCAsmInfo *MAI) const; diff --git a/include/llvm/MC/MachineLocation.h b/include/llvm/MC/MachineLocation.h new file mode 100644 index 0000000..8ddfdbc --- /dev/null +++ b/include/llvm/MC/MachineLocation.h @@ -0,0 +1,98 @@ +//===-- llvm/MC/MachineLocation.h -------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// The MachineLocation class is used to represent a simple location in a machine +// frame. Locations will be one of two forms; a register or an address formed +// from a base address plus an offset. Register indirection can be specified by +// using an offset of zero. +// +// The MachineMove class is used to represent abstract move operations in the +// prolog/epilog of a compiled function. A collection of these objects can be +// used by a debug consumer to track the location of values when unwinding stack +// frames. +//===----------------------------------------------------------------------===// + + +#ifndef LLVM_MC_MACHINELOCATION_H +#define LLVM_MC_MACHINELOCATION_H + +namespace llvm { + class MCSymbol; + +class MachineLocation { +private: + bool IsRegister; // True if location is a register. + unsigned Register; // gcc/gdb register number. + int Offset; // Displacement if not register. +public: + enum { + // The target register number for an abstract frame pointer. The value is + // an arbitrary value that doesn't collide with any real target register. + VirtualFP = ~0U + }; + MachineLocation() + : IsRegister(false), Register(0), Offset(0) {} + explicit MachineLocation(unsigned R) + : IsRegister(true), Register(R), Offset(0) {} + MachineLocation(unsigned R, int O) + : IsRegister(false), Register(R), Offset(O) {} + + bool operator==(const MachineLocation &Other) const { + return IsRegister == Other.IsRegister && Register == Other.Register && + Offset == Other.Offset; + } + + // Accessors + bool isReg() const { return IsRegister; } + unsigned getReg() const { return Register; } + int getOffset() const { return Offset; } + void setIsRegister(bool Is) { IsRegister = Is; } + void setRegister(unsigned R) { Register = R; } + void setOffset(int O) { Offset = O; } + void set(unsigned R) { + IsRegister = true; + Register = R; + Offset = 0; + } + void set(unsigned R, int O) { + IsRegister = false; + Register = R; + Offset = O; + } + +#ifndef NDEBUG + void dump(); +#endif +}; + +/// MachineMove - This class represents the save or restore of a callee saved +/// register that exception or debug info needs to know about. +class MachineMove { +private: + /// Label - Symbol for post-instruction address when result of move takes + /// effect. + MCSymbol *Label; + + // Move to & from location. + MachineLocation Destination, Source; +public: + MachineMove() : Label(0) {} + + MachineMove(MCSymbol *label, const MachineLocation &D, + const MachineLocation &S) + : Label(label), Destination(D), Source(S) {} + + // Accessors + MCSymbol *getLabel() const { return Label; } + const MachineLocation &getDestination() const { return Destination; } + const MachineLocation &getSource() const { return Source; } +}; + +} // End llvm namespace + +#endif |