diff options
Diffstat (limited to 'include/llvm/MC')
26 files changed, 890 insertions, 669 deletions
diff --git a/include/llvm/MC/ConstantPools.h b/include/llvm/MC/ConstantPools.h new file mode 100644 index 0000000..2819b75 --- /dev/null +++ b/include/llvm/MC/ConstantPools.h @@ -0,0 +1,80 @@ +//===- ConstantPool.h - Keep track of assembler-generated ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the ConstantPool and AssemblerConstantPools classes. +// +//===----------------------------------------------------------------------===// + + +#ifndef LLVM_MC_CONSTANTPOOL_H +#define LLVM_MC_CONSTANTPOOL_H + +#include "llvm/ADT/SmallVector.h" +namespace llvm { +class MCContext; +class MCExpr; +class MCSection; +class MCStreamer; +class MCSymbol; +// A class to keep track of assembler-generated constant pools that are use to +// implement the ldr-pseudo. +class ConstantPool { + typedef SmallVector<std::pair<MCSymbol *, const MCExpr *>, 4> EntryVecTy; + EntryVecTy Entries; + +public: + // Initialize a new empty constant pool + ConstantPool() {} + + // Add a new entry to the constant pool in the next slot. + // \param Value is the new entry to put in the constant pool. + // + // \returns a MCExpr that references the newly inserted value + const MCExpr *addEntry(const MCExpr *Value, MCContext &Context); + + // Emit the contents of the constant pool using the provided streamer. + void emitEntries(MCStreamer &Streamer); + + // Return true if the constant pool is empty + bool empty(); +}; + +class AssemblerConstantPools { + // Map type used to keep track of per-Section constant pools used by the + // ldr-pseudo opcode. The map associates a section to its constant pool. The + // constant pool is a vector of (label, value) pairs. When the ldr + // pseudo is parsed we insert a new (label, value) pair into the constant pool + // for the current section and add MCSymbolRefExpr to the new label as + // an opcode to the ldr. After we have parsed all the user input we + // output the (label, value) pairs in each constant pool at the end of the + // section. + // + // We use the MapVector for the map type to ensure stable iteration of + // the sections at the end of the parse. We need to iterate over the + // sections in a stable order to ensure that we have print the + // constant pools in a deterministic order when printing an assembly + // file. + typedef MapVector<const MCSection *, ConstantPool> ConstantPoolMapTy; + ConstantPoolMapTy ConstantPools; + +public: + AssemblerConstantPools() {} + ~AssemblerConstantPools() {} + + void emitAll(MCStreamer &Streamer); + void emitForCurrentSection(MCStreamer &Streamer); + const MCExpr *addEntry(MCStreamer &Streamer, const MCExpr *Expr); + +private: + ConstantPool *getConstantPool(const MCSection *Section); + ConstantPool &getOrCreateConstantPool(const MCSection *Section); +}; +} // end namespace llvm + +#endif diff --git a/include/llvm/MC/MCAtom.h b/include/llvm/MC/MCAnalysis/MCAtom.h index e9d0fba..33f3431 100644 --- a/include/llvm/MC/MCAtom.h +++ b/include/llvm/MC/MCAnalysis/MCAtom.h @@ -1,4 +1,4 @@ -//===-- llvm/MC/MCAtom.h ----------------------------------------*- C++ -*-===// +//===-- MCAtom.h ------------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -13,8 +13,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_MC_MCATOM_H -#define LLVM_MC_MCATOM_H +#ifndef LLVM_MC_MCANALYSIS_MCATOM_H +#define LLVM_MC_MCANALYSIS_MCATOM_H #include "llvm/ADT/ArrayRef.h" #include "llvm/MC/MCInst.h" diff --git a/include/llvm/MC/MCFunction.h b/include/llvm/MC/MCAnalysis/MCFunction.h index bfa470b..44fa450 100644 --- a/include/llvm/MC/MCFunction.h +++ b/include/llvm/MC/MCAnalysis/MCFunction.h @@ -1,4 +1,4 @@ -//===-- llvm/MC/MCFunction.h ------------------------------------*- C++ -*-===// +//===-- MCFunction.h --------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_MC_MCFUNCTION_H -#define LLVM_MC_MCFUNCTION_H +#ifndef LLVM_MC_MCANALYSIS_MCFUNCTION_H +#define LLVM_MC_MCANALYSIS_MCFUNCTION_H #include "llvm/ADT/StringRef.h" #include "llvm/MC/MCInst.h" diff --git a/include/llvm/MC/MCModule.h b/include/llvm/MC/MCAnalysis/MCModule.h index aa389cb..cf7e2c0 100644 --- a/include/llvm/MC/MCModule.h +++ b/include/llvm/MC/MCAnalysis/MCModule.h @@ -1,4 +1,4 @@ -//===-- llvm/MC/MCModule.h - MCModule class ---------------------*- C++ -*-===// +//===-- MCModule.h - MCModule class -----------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_MC_MCMODULE_H -#define LLVM_MC_MCMODULE_H +#ifndef LLVM_MC_MCANALYSIS_MCMODULE_H +#define LLVM_MC_MCANALYSIS_MCMODULE_H #include "llvm/ADT/StringRef.h" #include "llvm/Support/Compiler.h" diff --git a/include/llvm/MC/MCModuleYAML.h b/include/llvm/MC/MCAnalysis/MCModuleYAML.h index c4ae829..4856277 100644 --- a/include/llvm/MC/MCModuleYAML.h +++ b/include/llvm/MC/MCAnalysis/MCModuleYAML.h @@ -13,11 +13,11 @@ /// //===----------------------------------------------------------------------===// -#ifndef LLVM_MC_MCMODULEYAML_H -#define LLVM_MC_MCMODULEYAML_H +#ifndef LLVM_MC_MCANALYSIS_MCMODULEYAML_H +#define LLVM_MC_MCANALYSIS_MCMODULEYAML_H #include "llvm/ADT/StringRef.h" -#include "llvm/MC/MCModule.h" +#include "llvm/MC/MCAnalysis/MCModule.h" #include "llvm/Support/raw_ostream.h" namespace llvm { diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index f7d3be2..06e473d 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -23,546 +23,496 @@ #include <vector> namespace llvm { - class MCExpr; - class MCSection; - class MCStreamer; - class MCSymbol; - class MCContext; - - namespace ExceptionHandling { - enum ExceptionsType { None, DwarfCFI, SjLj, ARM, Win64 }; +class MCExpr; +class MCSection; +class MCStreamer; +class MCSymbol; +class MCContext; + +namespace WinEH { +enum class EncodingType { + ET_Invalid, /// Invalid + ET_Alpha, /// Windows Alpha + ET_Alpha64, /// Windows AXP64 + ET_ARM, /// Windows NT (Windows on ARM) + ET_CE, /// Windows CE ARM, PowerPC, SH3, SH4 + ET_Itanium, /// Windows x64, Windows Itanium (IA-64) + ET_MIPS = ET_Alpha, +}; +} + +enum class ExceptionHandling { + None, /// No exception support + DwarfCFI, /// DWARF-like instruction based exceptions + SjLj, /// setjmp/longjmp based exceptions + ARM, /// ARM EHABI + WinEH, /// Windows Exception Handling +}; + +namespace LCOMM { +enum LCOMMType { NoAlignment, ByteAlignment, Log2Alignment }; +} + +/// This class is intended to be used as a base class for asm +/// properties and features specific to the target. +class MCAsmInfo { +protected: + //===------------------------------------------------------------------===// + // Properties to be set by the target writer, used to configure asm printer. + // + + /// Pointer size in bytes. Default is 4. + unsigned PointerSize; + + /// Size of the stack slot reserved for callee-saved registers, in bytes. + /// Default is same as pointer size. + unsigned CalleeSaveStackSlotSize; + + /// True if target is little endian. Default is true. + bool IsLittleEndian; + + /// True if target stack grow up. Default is false. + bool StackGrowsUp; + + /// True if this target has the MachO .subsections_via_symbols directive. + /// Default is false. + bool HasSubsectionsViaSymbols; + + /// True if this is a MachO target that supports the macho-specific .zerofill + /// directive for emitting BSS Symbols. Default is false. + bool HasMachoZeroFillDirective; + + /// True if this is a MachO target that supports the macho-specific .tbss + /// directive for emitting thread local BSS Symbols. Default is false. + bool HasMachoTBSSDirective; + + /// 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 emitted in Static relocation model. Default + /// is false. + bool HasStaticCtorDtorReferenceInStaticMode; + + /// True if the linker has a bug and requires that the debug_line section be + /// of a minimum size. In practice such a linker requires a non-empty line + /// sequence if a file is present. Default to false. + bool LinkerRequiresNonEmptyDwarfLines; + + /// This is the maximum possible length of an instruction, which is needed to + /// compute the size of an inline asm. Defaults to 4. + unsigned MaxInstLength; + + /// Every possible instruction length is a multiple of this value. Factored + /// out in .debug_frame and .debug_line. Defaults to 1. + unsigned MinInstAlignment; + + /// The '$' token, when not referencing an identifier or constant, refers to + /// the current PC. Defaults to false. + bool DollarIsPC; + + /// This string, if specified, is used to separate instructions from each + /// other when on the same line. Defaults to ';' + const char *SeparatorString; + + /// This indicates the comment character used by the assembler. Defaults to + /// "#" + const char *CommentString; + + /// This is appended to emitted labels. Defaults to ":" + const char *LabelSuffix; + + // Print the EH begin symbol with an assignment. Defaults to false. + bool UseAssignmentForEHBegin; + + /// This prefix is used for globals like constant pool entries that are + /// completely private to the .s file and should not have names in the .o + /// file. Defaults to "L" + const char *PrivateGlobalPrefix; + + /// This prefix is used for symbols that should be passed through the + /// assembler but be removed by the linker. This is 'l' on Darwin, currently + /// used for some ObjC metadata. The default of "" meast that for this system + /// a plain private symbol should be used. Defaults to "". + const char *LinkerPrivateGlobalPrefix; + + /// If these are nonempty, they contain a directive to emit before and after + /// an inline assembly statement. Defaults to "#APP\n", "#NO_APP\n" + const char *InlineAsmStart; + const char *InlineAsmEnd; + + /// These are assembly directives that tells the assembler to interpret the + /// following instructions differently. Defaults to ".code16", ".code32", + /// ".code64". + const char *Code16Directive; + const char *Code32Directive; + const char *Code64Directive; + + /// Which dialect of an assembler variant to use. Defaults to 0 + unsigned AssemblerDialect; + + /// This is true if the assembler allows @ characters in symbol names. + /// Defaults to false. + bool AllowAtInName; + + /// This is true if data region markers should be printed as + /// ".data_region/.end_data_region" directives. If false, use "$d/$a" labels + /// instead. + bool UseDataRegionDirectives; + + //===--- Data Emission Directives -------------------------------------===// + + /// This should be set to the directive used to get some number of zero bytes + /// emitted to the current section. Common cases are "\t.zero\t" and + /// "\t.space\t". If this is set to null, the Data*bitsDirective's will be + /// used to emit zero bytes. Defaults to "\t.zero\t" + const char *ZeroDirective; + + /// This directive allows emission of an ascii string with the standard C + /// escape characters embedded into it. Defaults to "\t.ascii\t" + const char *AsciiDirective; + + /// If not null, this allows for special handling of zero terminated strings + /// on this target. This is commonly supported as ".asciz". If a target + /// doesn't support this, it can be set to null. Defaults to "\t.asciz\t" + const char *AscizDirective; + + /// These directives are used to output some unit of integer data to the + /// current section. If a data directive is set to null, smaller data + /// directives will be used to emit the large sizes. Defaults to "\t.byte\t", + /// "\t.short\t", "\t.long\t", "\t.quad\t" + const char *Data8bitsDirective; + const char *Data16bitsDirective; + const char *Data32bitsDirective; + const char *Data64bitsDirective; + + /// 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. Defaults + /// to NULL. + const char *GPRel64Directive; + + /// 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. Defaults to NULL. + const char *GPRel32Directive; + + /// This is true if this target uses "Sun Style" syntax for section switching + /// ("#alloc,#write" etc) instead of the normal ELF syntax (,"a,w") in + /// .section directives. Defaults to false. + bool SunStyleELFSectionSwitchSyntax; + + /// This is true if this target uses ELF '.section' directive before the + /// '.bss' one. It's used for PPC/Linux which doesn't support the '.bss' + /// directive only. Defaults to false. + bool UsesELFSectionDirectiveForBSS; + + bool NeedsDwarfSectionOffsetDirective; + + //===--- Alignment Information ----------------------------------------===// + + /// If this is true (the default) then the asmprinter emits ".align N" + /// directives, where N is the number of bytes to align to. Otherwise, it + /// emits ".align log2(N)", e.g. 3 to align to an 8 byte boundary. Defaults + /// to true. + bool AlignmentIsInBytes; + + /// If non-zero, this is used to fill the executable space created as the + /// result of a alignment directive. Defaults to 0 + unsigned TextAlignFillValue; + + //===--- Global Variable Emission Directives --------------------------===// + + /// This is the directive used to declare a global entity. Defaults to NULL. + const char *GlobalDirective; + + /// True if the assembler supports the .set directive. Defaults to true. + bool HasSetDirective; + + /// False if the assembler requires that we use + /// \code + /// Lc = a - b + /// .long Lc + /// \endcode + // + /// instead of + // + /// \code + /// .long a - b + /// \endcode + /// + /// Defaults to true. + bool HasAggressiveSymbolFolding; + + /// True is .comm's and .lcomms optional alignment is to be specified in bytes + /// instead of log2(n). Defaults to true. + bool COMMDirectiveAlignmentIsInBytes; + + /// Describes if the .lcomm directive for the target supports an alignment + /// argument and how it is interpreted. Defaults to NoAlignment. + LCOMM::LCOMMType LCOMMDirectiveAlignmentType; + + /// True if the target has .type and .size directives, this is true for most + /// ELF targets. Defaults to true. + bool HasDotTypeDotSizeDirective; + + /// True if the target has a single parameter .file directive, this is true + /// for ELF targets. Defaults to true. + bool HasSingleParameterDotFile; + + /// True if the target has a .ident directive, this is true for ELF targets. + /// Defaults to false. + bool HasIdentDirective; + + /// True if this target supports the MachO .no_dead_strip directive. Defaults + /// to false. + bool HasNoDeadStrip; + + /// This directive, if non-null, is used to declare a global as being a weak + /// undefined symbol. Defaults to NULL. + const char *WeakRefDirective; + + /// True if we have a directive to declare a global as being a weak defined + /// symbol. Defaults to false. + bool HasWeakDefDirective; + + /// True if we have a directive to declare a global as being a weak defined + /// symbol that can be hidden (unexported). Defaults to false. + bool HasWeakDefCanBeHiddenDirective; + + /// True if we have a .linkonce directive. This is used on cygwin/mingw. + /// Defaults to false. + bool HasLinkOnceDirective; + + /// This attribute, if not MCSA_Invalid, is used to declare a symbol as having + /// hidden visibility. Defaults to MCSA_Hidden. + MCSymbolAttr HiddenVisibilityAttr; + + /// This attribute, if not MCSA_Invalid, is used to declare an undefined + /// symbol as having hidden visibility. Defaults to MCSA_Hidden. + MCSymbolAttr HiddenDeclarationVisibilityAttr; + + /// This attribute, if not MCSA_Invalid, is used to declare a symbol as having + /// protected visibility. Defaults to MCSA_Protected + MCSymbolAttr ProtectedVisibilityAttr; + + //===--- Dwarf Emission Directives -----------------------------------===// + + /// True if target asm supports leb128 directives. Defaults to false. + bool HasLEB128; + + /// True if target supports emission of debugging information. Defaults to + /// false. + bool SupportsDebugInformation; + + /// Exception handling format for the target. Defaults to None. + ExceptionHandling ExceptionsType; + + /// Windows exception handling data (.pdata) encoding. Defaults to Invalid. + WinEH::EncodingType WinEHEncodingType; + + /// True if Dwarf2 output generally uses relocations for references to other + /// .debug_* sections. + bool DwarfUsesRelocationsAcrossSections; + + /// True if DWARF FDE symbol reference relocations should be replaced by an + /// absolute difference. + bool DwarfFDESymbolsUseAbsDiff; + + /// True if dwarf register numbers are printed instead of symbolic register + /// names in .cfi_* directives. Defaults to false. + bool DwarfRegNumForCFI; + + /// True if target uses parens to indicate the symbol variant instead of @. + /// For example, foo(plt) instead of foo@plt. Defaults to false. + bool UseParensForSymbolVariant; + + //===--- Prologue State ----------------------------------------------===// + + std::vector<MCCFIInstruction> InitialFrameState; + + //===--- Integrated Assembler State ----------------------------------===// + + /// Should we use the integrated assembler? + /// The integrated assembler should be enabled by default (by the + /// constructors) when failing to parse a valid piece of assembly (inline + /// or otherwise) is considered a bug. It may then be overridden after + /// construction (see LLVMTargetMachine::initAsmInfo()). + bool UseIntegratedAssembler; + + /// Compress DWARF debug sections. Defaults to false. + bool CompressDebugSections; + +public: + explicit MCAsmInfo(); + virtual ~MCAsmInfo(); + + /// Get the pointer size in bytes. + unsigned getPointerSize() const { return PointerSize; } + + /// Get the callee-saved register stack slot + /// size in bytes. + unsigned getCalleeSaveStackSlotSize() const { + return CalleeSaveStackSlotSize; } - namespace LCOMM { - enum LCOMMType { NoAlignment, ByteAlignment, Log2Alignment }; + /// True if the target is little endian. + bool isLittleEndian() const { return IsLittleEndian; } + + /// True if target stack grow up. + bool isStackGrowthDirectionUp() const { return StackGrowsUp; } + + bool hasSubsectionsViaSymbols() const { return HasSubsectionsViaSymbols; } + + // Data directive accessors. + + const char *getData8bitsDirective() const { return Data8bitsDirective; } + const char *getData16bitsDirective() const { return Data16bitsDirective; } + const char *getData32bitsDirective() const { return Data32bitsDirective; } + const char *getData64bitsDirective() const { return Data64bitsDirective; } + const char *getGPRel64Directive() const { return GPRel64Directive; } + const char *getGPRel32Directive() const { return GPRel32Directive; } + + /// 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. + virtual const MCSection *getNonexecutableStackSection(MCContext &Ctx) const { + return nullptr; } - /// MCAsmInfo - This class is intended to be used as a base class for asm - /// properties and features specific to the target. - class MCAsmInfo { - protected: - //===------------------------------------------------------------------===// - // Properties to be set by the target writer, used to configure asm printer. - // - - /// PointerSize - Pointer size in bytes. - /// Default is 4. - unsigned PointerSize; - - /// CalleeSaveStackSlotSize - Size of the stack slot reserved for - /// callee-saved registers, in bytes. - /// Default is same as pointer size. - unsigned CalleeSaveStackSlotSize; - - /// IsLittleEndian - True if target is little endian. - /// Default is true. - bool IsLittleEndian; - - /// StackGrowsUp - True if target stack grow up. - /// Default is false. - bool StackGrowsUp; - - /// HasSubsectionsViaSymbols - True if this target has the MachO - /// .subsections_via_symbols directive. - bool HasSubsectionsViaSymbols; // Default is false. - - /// HasMachoZeroFillDirective - True if this is a MachO target that supports - /// the macho-specific .zerofill directive for emitting BSS Symbols. - bool HasMachoZeroFillDirective; // Default is false. - - /// HasMachoTBSSDirective - True if this is a MachO target that supports - /// the macho-specific .tbss directive for emitting thread local BSS Symbols - bool HasMachoTBSSDirective; // Default is false. - - /// 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 - /// emitted in Static relocation model. - bool HasStaticCtorDtorReferenceInStaticMode; // Default is false. - - /// LinkerRequiresNonEmptyDwarfLines - True if the linker has a bug and - /// requires that the debug_line section be of a minimum size. In practice - /// such a linker requires a non-empty line sequence if a file is present. - bool LinkerRequiresNonEmptyDwarfLines; // Default to false. - - /// MaxInstLength - This is the maximum possible length of an instruction, - /// which is needed to compute the size of an inline asm. - unsigned MaxInstLength; // Defaults to 4. - - /// MinInstAlignment - Every possible instruction length is a multiple of - /// this value. Factored out in .debug_frame and .debug_line. - unsigned MinInstAlignment; // Defaults to 1. - - /// DollarIsPC - The '$' token, when not referencing an identifier or - /// constant, refers to the current PC. - bool DollarIsPC; // Defaults to false. - - /// SeparatorString - This string, if specified, is used to separate - /// instructions from each other when on the same line. - const char *SeparatorString; // Defaults to ';' - - /// CommentString - This indicates the comment character used by the - /// assembler. - const char *CommentString; // Defaults to "#" - - /// LabelSuffix - This is appended to emitted labels. - const char *LabelSuffix; // Defaults to ":" - - /// LabelSuffix - This is appended to emitted labels. - const char *DebugLabelSuffix; // Defaults to ":" - - /// This prefix is used for globals like constant pool entries that are - /// completely private to the .s file and should not have names in the .o - /// file. - const char *PrivateGlobalPrefix; // Defaults to "L" - - /// This prefix is used for symbols that should be passed through the - /// assembler but be removed by the linker. This is 'l' on Darwin, - /// currently used for some ObjC metadata. - /// The default of "" meast that for this system a plain private symbol - /// should be used. - const char *LinkerPrivateGlobalPrefix; // Defaults to "". - - /// InlineAsmStart/End - If these are nonempty, they contain a directive to - /// emit before and after an inline assembly statement. - 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 - - /// \brief This is true if the assembler allows @ characters in symbol - /// names. Defaults to false. - bool AllowAtInName; - - /// UseDataRegionDirectives - This is true if data region markers should - /// be printed as ".data_region/.end_data_region" directives. If false, - /// use "$d/$a" labels instead. - bool UseDataRegionDirectives; - - //===--- Data Emission Directives -------------------------------------===// - - /// ZeroDirective - this should be set to the directive used to get some - /// number of zero bytes emitted to the current section. Common cases are - /// "\t.zero\t" and "\t.space\t". If this is set to null, the - /// Data*bitsDirective's will be used to emit zero bytes. - const char *ZeroDirective; // Defaults to "\t.zero\t" - - /// AsciiDirective - This directive allows emission of an ascii string with - /// the standard C escape characters embedded into it. - const char *AsciiDirective; // Defaults to "\t.ascii\t" - - /// AscizDirective - If not null, this allows for special handling of - /// zero terminated strings on this target. This is commonly supported as - /// ".asciz". If a target doesn't support this, it can be set to null. - const char *AscizDirective; // Defaults to "\t.asciz\t" - - /// DataDirectives - These directives are used to output some unit of - /// integer data to the current section. If a data directive is set to - /// null, smaller data directives will be used to emit the large sizes. - const char *Data8bitsDirective; // Defaults to "\t.byte\t" - const char *Data16bitsDirective; // Defaults to "\t.short\t" - const char *Data32bitsDirective; // Defaults to "\t.long\t" - const char *Data64bitsDirective; // Defaults to "\t.quad\t" - - /// 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. - const char *GPRel32Directive; // Defaults to NULL. - - /// SunStyleELFSectionSwitchSyntax - This is true if this target uses "Sun - /// Style" syntax for section switching ("#alloc,#write" etc) instead of the - /// normal ELF syntax (,"a,w") in .section directives. - bool SunStyleELFSectionSwitchSyntax; // Defaults to false. - - /// UsesELFSectionDirectiveForBSS - This is true if this target uses ELF - /// '.section' directive before the '.bss' one. It's used for PPC/Linux - /// which doesn't support the '.bss' directive only. - bool UsesELFSectionDirectiveForBSS; // Defaults to false. - - bool NeedsDwarfSectionOffsetDirective; - - //===--- Alignment Information ----------------------------------------===// - - /// AlignmentIsInBytes - If this is true (the default) then the asmprinter - /// emits ".align N" directives, where N is the number of bytes to align to. - /// Otherwise, it emits ".align log2(N)", e.g. 3 to align to an 8 byte - /// boundary. - bool AlignmentIsInBytes; // Defaults to true - - /// TextAlignFillValue - If non-zero, this is used to fill the executable - /// space created as the result of a alignment directive. - unsigned TextAlignFillValue; // Defaults to 0 + virtual const MCExpr *getExprForPersonalitySymbol(const MCSymbol *Sym, + unsigned Encoding, + MCStreamer &Streamer) const; + + virtual const MCExpr *getExprForFDESymbol(const MCSymbol *Sym, + unsigned Encoding, + MCStreamer &Streamer) const; + + bool usesSunStyleELFSectionSwitchSyntax() const { + return SunStyleELFSectionSwitchSyntax; + } - //===--- Global Variable Emission Directives --------------------------===// + bool usesELFSectionDirectiveForBSS() const { + return UsesELFSectionDirectiveForBSS; + } + + bool needsDwarfSectionOffsetDirective() const { + return NeedsDwarfSectionOffsetDirective; + } + + // Accessors. + + bool hasMachoZeroFillDirective() const { return HasMachoZeroFillDirective; } + bool hasMachoTBSSDirective() const { return HasMachoTBSSDirective; } + bool hasStaticCtorDtorReferenceInStaticMode() const { + return HasStaticCtorDtorReferenceInStaticMode; + } + bool getLinkerRequiresNonEmptyDwarfLines() const { + return LinkerRequiresNonEmptyDwarfLines; + } + unsigned getMaxInstLength() const { return MaxInstLength; } + unsigned getMinInstAlignment() const { return MinInstAlignment; } + bool getDollarIsPC() const { return DollarIsPC; } + const char *getSeparatorString() const { return SeparatorString; } + + /// This indicates the column (zero-based) at which asm comments should be + /// printed. + unsigned getCommentColumn() const { return 40; } + + const char *getCommentString() const { return CommentString; } + const char *getLabelSuffix() const { return LabelSuffix; } + + bool useAssignmentForEHBegin() const { return UseAssignmentForEHBegin; } + const char *getPrivateGlobalPrefix() const { return PrivateGlobalPrefix; } + bool hasLinkerPrivateGlobalPrefix() const { + return LinkerPrivateGlobalPrefix[0] != '\0'; + } + const char *getLinkerPrivateGlobalPrefix() const { + if (hasLinkerPrivateGlobalPrefix()) + return LinkerPrivateGlobalPrefix; + return getPrivateGlobalPrefix(); + } + const char *getInlineAsmStart() const { return InlineAsmStart; } + 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; } + bool doesAllowAtInName() const { return AllowAtInName; } + bool doesSupportDataRegionDirectives() const { + return UseDataRegionDirectives; + } + const char *getZeroDirective() const { return ZeroDirective; } + const char *getAsciiDirective() const { return AsciiDirective; } + const char *getAscizDirective() const { return AscizDirective; } + bool getAlignmentIsInBytes() const { return AlignmentIsInBytes; } + unsigned getTextAlignFillValue() const { return TextAlignFillValue; } + const char *getGlobalDirective() const { return GlobalDirective; } + bool hasSetDirective() const { return HasSetDirective; } + bool hasAggressiveSymbolFolding() const { return HasAggressiveSymbolFolding; } + bool getCOMMDirectiveAlignmentIsInBytes() const { + return COMMDirectiveAlignmentIsInBytes; + } + LCOMM::LCOMMType getLCOMMDirectiveAlignmentType() const { + return LCOMMDirectiveAlignmentType; + } + bool hasDotTypeDotSizeDirective() const { return HasDotTypeDotSizeDirective; } + bool hasSingleParameterDotFile() const { return HasSingleParameterDotFile; } + bool hasIdentDirective() const { return HasIdentDirective; } + bool hasNoDeadStrip() const { return HasNoDeadStrip; } + const char *getWeakRefDirective() const { return WeakRefDirective; } + bool hasWeakDefDirective() const { return HasWeakDefDirective; } + bool hasWeakDefCanBeHiddenDirective() const { + return HasWeakDefCanBeHiddenDirective; + } + bool hasLinkOnceDirective() const { return HasLinkOnceDirective; } - /// GlobalDirective - This is the directive used to declare a global entity. - /// - const char *GlobalDirective; // Defaults to NULL. - - /// HasSetDirective - True if the assembler supports the .set directive. - bool HasSetDirective; // Defaults to true. - - /// HasAggressiveSymbolFolding - False if the assembler requires that we use - /// Lc = a - b - /// .long Lc - /// instead of - /// .long a - b - bool HasAggressiveSymbolFolding; // Defaults to true. + MCSymbolAttr getHiddenVisibilityAttr() const { return HiddenVisibilityAttr; } + MCSymbolAttr getHiddenDeclarationVisibilityAttr() const { + return HiddenDeclarationVisibilityAttr; + } + MCSymbolAttr getProtectedVisibilityAttr() const { + return ProtectedVisibilityAttr; + } + bool hasLEB128() const { return HasLEB128; } + bool doesSupportDebugInformation() const { return SupportsDebugInformation; } + bool doesSupportExceptionHandling() const { + return ExceptionsType != ExceptionHandling::None; + } + ExceptionHandling getExceptionHandlingType() const { return ExceptionsType; } + WinEH::EncodingType getWinEHEncodingType() const { return WinEHEncodingType; } + bool isExceptionHandlingDwarf() const { + return (ExceptionsType == ExceptionHandling::DwarfCFI || + ExceptionsType == ExceptionHandling::ARM || + // Windows handler data still uses DWARF LSDA encoding. + ExceptionsType == ExceptionHandling::WinEH); + } + bool doesDwarfUseRelocationsAcrossSections() const { + return DwarfUsesRelocationsAcrossSections; + } + bool doDwarfFDESymbolsUseAbsDiff() const { return DwarfFDESymbolsUseAbsDiff; } + bool useDwarfRegNumForCFI() const { return DwarfRegNumForCFI; } + bool useParensForSymbolVariant() const { return UseParensForSymbolVariant; } - /// COMMDirectiveAlignmentIsInBytes - True is .comm's and .lcomms optional - /// alignment is to be specified in bytes instead of log2(n). - bool COMMDirectiveAlignmentIsInBytes; // Defaults to true; + void addInitialFrameState(const MCCFIInstruction &Inst) { + InitialFrameState.push_back(Inst); + } - /// LCOMMDirectiveAlignment - Describes if the .lcomm directive for the - /// target supports an alignment argument and how it is interpreted. - LCOMM::LCOMMType LCOMMDirectiveAlignmentType; // Defaults to NoAlignment. - - /// HasDotTypeDotSizeDirective - True if the target has .type and .size - /// directives, this is true for most ELF targets. - bool HasDotTypeDotSizeDirective; // Defaults to true. + const std::vector<MCCFIInstruction> &getInitialFrameState() const { + return InitialFrameState; + } - /// HasSingleParameterDotFile - True if the target has a single parameter - /// .file directive, this is true for ELF targets. - bool HasSingleParameterDotFile; // Defaults to true. + /// Return true if assembly (inline or otherwise) should be parsed. + bool useIntegratedAssembler() const { return UseIntegratedAssembler; } - /// hasIdentDirective - True if the target has a .ident directive, this is - /// true for ELF targets. - bool HasIdentDirective; // Defaults to false. + /// Set whether assembly (inline or otherwise) should be parsed. + virtual void setUseIntegratedAssembler(bool Value) { + UseIntegratedAssembler = Value; + } - /// HasNoDeadStrip - True if this target supports the MachO .no_dead_strip - /// directive. - bool HasNoDeadStrip; // Defaults to false. + bool compressDebugSections() const { return CompressDebugSections; } - /// WeakRefDirective - This directive, if non-null, is used to declare a - /// global as being a weak undefined symbol. - const char *WeakRefDirective; // Defaults to NULL. - - /// True if we have a directive to declare a global as being a weak - /// defined symbol. - bool HasWeakDefDirective; // Defaults to false. - - /// True if we have a directive to declare a global as being a weak - /// defined symbol that can be hidden (unexported). - bool HasWeakDefCanBeHiddenDirective; // Defaults to false. - - /// True if we have a .linkonce directive. This is used on cygwin/mingw. - bool HasLinkOnceDirective; // Defaults to false. - - /// HiddenVisibilityAttr - This attribute, if not MCSA_Invalid, is used to - /// declare a symbol as having hidden visibility. - MCSymbolAttr HiddenVisibilityAttr; // Defaults to MCSA_Hidden. - - /// HiddenDeclarationVisibilityAttr - This attribute, if not MCSA_Invalid, - /// is used to declare an undefined symbol as having hidden visibility. - MCSymbolAttr HiddenDeclarationVisibilityAttr; // Defaults to MCSA_Hidden. - - - /// ProtectedVisibilityAttr - This attribute, if not MCSA_Invalid, is used - /// to declare a symbol as having protected visibility. - MCSymbolAttr ProtectedVisibilityAttr; // Defaults to MCSA_Protected - - //===--- Dwarf Emission Directives -----------------------------------===// - - /// HasLEB128 - True if target asm supports leb128 directives. - bool HasLEB128; // Defaults to false. - - /// SupportsDebugInformation - True if target supports emission of debugging - /// information. - bool SupportsDebugInformation; // Defaults to false. - - /// SupportsExceptionHandling - True if target supports exception handling. - ExceptionHandling::ExceptionsType ExceptionsType; // Defaults to None - - /// DwarfUsesRelocationsAcrossSections - True if Dwarf2 output generally - /// uses relocations for references to other .debug_* sections. - bool DwarfUsesRelocationsAcrossSections; - - /// DwarfFDESymbolsUseAbsDiff - true if DWARF FDE symbol reference - /// relocations should be replaced by an absolute difference. - bool DwarfFDESymbolsUseAbsDiff; - - /// DwarfRegNumForCFI - True if dwarf register numbers are printed - /// instead of symbolic register names in .cfi_* directives. - bool DwarfRegNumForCFI; // Defaults to false; - - /// UseParensForSymbolVariant - True if target uses parens to indicate the - /// symbol variant instead of @. For example, foo(plt) instead of foo@plt. - bool UseParensForSymbolVariant; // Defaults to false; - - //===--- Prologue State ----------------------------------------------===// - - std::vector<MCCFIInstruction> InitialFrameState; - - //===--- Integrated Assembler State ----------------------------------===// - /// Should we use the integrated assembler? - /// The integrated assembler should be enabled by default (by the - /// constructors) when failing to parse a valid piece of assembly (inline - /// or otherwise) is considered a bug. It may then be overridden after - /// construction (see LLVMTargetMachine::initAsmInfo()). - bool UseIntegratedAssembler; - - /// Compress DWARF debug sections. Defaults to false. - bool CompressDebugSections; - - public: - explicit MCAsmInfo(); - virtual ~MCAsmInfo(); - - /// getPointerSize - Get the pointer size in bytes. - unsigned getPointerSize() const { - return PointerSize; - } - - /// getCalleeSaveStackSlotSize - Get the callee-saved register stack slot - /// size in bytes. - unsigned getCalleeSaveStackSlotSize() const { - return CalleeSaveStackSlotSize; - } - - /// isLittleEndian - True if the target is little endian. - bool isLittleEndian() const { - return IsLittleEndian; - } - - /// isStackGrowthDirectionUp - True if target stack grow up. - bool isStackGrowthDirectionUp() const { - return StackGrowsUp; - } - - bool hasSubsectionsViaSymbols() const { return HasSubsectionsViaSymbols; } - - // Data directive accessors. - // - const char *getData8bitsDirective() const { - return Data8bitsDirective; - } - const char *getData16bitsDirective() const { - return Data16bitsDirective; - } - const char *getData32bitsDirective() const { - return Data32bitsDirective; - } - const char *getData64bitsDirective() const { - return Data64bitsDirective; - } - const char *getGPRel64Directive() const { return GPRel64Directive; } - const char *getGPRel32Directive() const { return GPRel32Directive; } - - /// 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. - virtual const MCSection *getNonexecutableStackSection(MCContext &Ctx) const{ - return nullptr; - } - - virtual const MCExpr * - getExprForPersonalitySymbol(const MCSymbol *Sym, - unsigned Encoding, - MCStreamer &Streamer) const; - - virtual const MCExpr * - getExprForFDESymbol(const MCSymbol *Sym, - unsigned Encoding, - MCStreamer &Streamer) const; - - bool usesSunStyleELFSectionSwitchSyntax() const { - return SunStyleELFSectionSwitchSyntax; - } - - bool usesELFSectionDirectiveForBSS() const { - return UsesELFSectionDirectiveForBSS; - } - - bool needsDwarfSectionOffsetDirective() const { - return NeedsDwarfSectionOffsetDirective; - } - - // Accessors. - // - bool hasMachoZeroFillDirective() const { return HasMachoZeroFillDirective; } - bool hasMachoTBSSDirective() const { return HasMachoTBSSDirective; } - bool hasStaticCtorDtorReferenceInStaticMode() const { - return HasStaticCtorDtorReferenceInStaticMode; - } - bool getLinkerRequiresNonEmptyDwarfLines() const { - return LinkerRequiresNonEmptyDwarfLines; - } - unsigned getMaxInstLength() const { - return MaxInstLength; - } - unsigned getMinInstAlignment() const { - return MinInstAlignment; - } - bool getDollarIsPC() const { - return DollarIsPC; - } - const char *getSeparatorString() const { - return SeparatorString; - } - - /// This indicates the column (zero-based) at which asm comments should be - /// printed. - unsigned getCommentColumn() const { - return 40; - } - - const char *getCommentString() const { - return CommentString; - } - const char *getLabelSuffix() const { - return LabelSuffix; - } - - const char *getDebugLabelSuffix() const { - return DebugLabelSuffix; - } - const char *getPrivateGlobalPrefix() const { - return PrivateGlobalPrefix; - } - bool hasLinkerPrivateGlobalPrefix() const { - return LinkerPrivateGlobalPrefix[0] != '\0'; - } - const char *getLinkerPrivateGlobalPrefix() const { - if (hasLinkerPrivateGlobalPrefix()) - return LinkerPrivateGlobalPrefix; - return getPrivateGlobalPrefix(); - } - const char *getInlineAsmStart() const { - return InlineAsmStart; - } - 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; - } - bool doesAllowAtInName() const { - return AllowAtInName; - } - bool doesSupportDataRegionDirectives() const { - return UseDataRegionDirectives; - } - const char *getZeroDirective() const { - return ZeroDirective; - } - const char *getAsciiDirective() const { - return AsciiDirective; - } - const char *getAscizDirective() const { - return AscizDirective; - } - bool getAlignmentIsInBytes() const { - return AlignmentIsInBytes; - } - unsigned getTextAlignFillValue() const { - return TextAlignFillValue; - } - const char *getGlobalDirective() const { - return GlobalDirective; - } - bool hasSetDirective() const { return HasSetDirective; } - bool hasAggressiveSymbolFolding() const { - return HasAggressiveSymbolFolding; - } - bool getCOMMDirectiveAlignmentIsInBytes() const { - return COMMDirectiveAlignmentIsInBytes; - } - LCOMM::LCOMMType getLCOMMDirectiveAlignmentType() const { - return LCOMMDirectiveAlignmentType; - } - bool hasDotTypeDotSizeDirective() const {return HasDotTypeDotSizeDirective;} - bool hasSingleParameterDotFile() const { return HasSingleParameterDotFile; } - bool hasIdentDirective() const { return HasIdentDirective; } - bool hasNoDeadStrip() const { return HasNoDeadStrip; } - const char *getWeakRefDirective() const { return WeakRefDirective; } - bool hasWeakDefDirective() const { return HasWeakDefDirective; } - bool hasWeakDefCanBeHiddenDirective() const { - return HasWeakDefCanBeHiddenDirective; - } - bool hasLinkOnceDirective() const { return HasLinkOnceDirective; } - - MCSymbolAttr getHiddenVisibilityAttr() const { return HiddenVisibilityAttr;} - MCSymbolAttr getHiddenDeclarationVisibilityAttr() const { - return HiddenDeclarationVisibilityAttr; - } - MCSymbolAttr getProtectedVisibilityAttr() const { - return ProtectedVisibilityAttr; - } - bool hasLEB128() const { - return HasLEB128; - } - bool doesSupportDebugInformation() const { - return SupportsDebugInformation; - } - bool doesSupportExceptionHandling() const { - return ExceptionsType != ExceptionHandling::None; - } - ExceptionHandling::ExceptionsType getExceptionHandlingType() const { - return ExceptionsType; - } - bool isExceptionHandlingDwarf() const { - return - (ExceptionsType == ExceptionHandling::DwarfCFI || - ExceptionsType == ExceptionHandling::ARM || - ExceptionsType == ExceptionHandling::Win64); - } - bool doesDwarfUseRelocationsAcrossSections() const { - return DwarfUsesRelocationsAcrossSections; - } - bool doDwarfFDESymbolsUseAbsDiff() const { - return DwarfFDESymbolsUseAbsDiff; - } - bool useDwarfRegNumForCFI() const { - return DwarfRegNumForCFI; - } - bool useParensForSymbolVariant() const { - return UseParensForSymbolVariant; - } - - void addInitialFrameState(const MCCFIInstruction &Inst) { - InitialFrameState.push_back(Inst); - } - - const std::vector<MCCFIInstruction> &getInitialFrameState() const { - return InitialFrameState; - } - - /// Return true if assembly (inline or otherwise) should be parsed. - bool useIntegratedAssembler() const { return UseIntegratedAssembler; } - - /// Set whether assembly (inline or otherwise) should be parsed. - virtual void setUseIntegratedAssembler(bool Value) { - UseIntegratedAssembler = Value; - } - - bool compressDebugSections() const { return CompressDebugSections; } - - void setCompressDebugSections(bool CompressDebugSections) { - this->CompressDebugSections = CompressDebugSections; - } - }; + void setCompressDebugSections(bool CompressDebugSections) { + this->CompressDebugSections = CompressDebugSections; + } +}; } #endif diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index be13b36..1cb34c2 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -802,7 +802,7 @@ public: /// @} - void dump(); + void dump() const; }; // FIXME: This really doesn't belong here. See comments below. diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index 7557e76..eb0340f 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -11,15 +11,18 @@ #define LLVM_MC_MCCONTEXT_H #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/MC/MCDwarf.h" +#include "llvm/MC/MCStreamer.h" #include "llvm/MC/SectionKind.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/raw_ostream.h" #include <map> +#include <tuple> #include <vector> // FIXME: Shouldn't be needed. namespace llvm { @@ -129,11 +132,10 @@ namespace llvm { /// 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; + /// Symbols created for the start and end of each section, used for + /// generating the .debug_ranges and .debug_aranges sections. + MapVector<const MCSection *, std::pair<MCSymbol *, MCSymbol *> > + SectionStartEndSyms; /// The information gathered from labels that will have dwarf label /// entries when generating dwarf assembly source files. @@ -159,10 +161,11 @@ namespace llvm { unsigned DwarfCompileUnitID; typedef std::pair<std::string, std::string> SectionGroupPair; + typedef std::tuple<std::string, std::string, int> SectionGroupTriple; StringMap<const MCSectionMachO*> MachOUniquingMap; std::map<SectionGroupPair, const MCSectionELF *> ELFUniquingMap; - std::map<SectionGroupPair, const MCSectionCOFF *> COFFUniquingMap; + std::map<SectionGroupTriple, const MCSectionCOFF *> COFFUniquingMap; /// Do automatic reset in destructor bool AutoReset; @@ -273,9 +276,7 @@ namespace llvm { const MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics, SectionKind Kind, - StringRef COMDATSymName, - int Selection, - const MCSectionCOFF *Assoc = nullptr); + StringRef COMDATSymName, int Selection); const MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics, @@ -376,16 +377,18 @@ namespace llvm { void setGenDwarfFileNumber(unsigned FileNumber) { GenDwarfFileNumber = FileNumber; } - const MCSection *getGenDwarfSection() { return GenDwarfSection; } - void setGenDwarfSection(const MCSection *Sec) { GenDwarfSection = Sec; } - MCSymbol *getGenDwarfSectionStartSym() { return GenDwarfSectionStartSym; } - void setGenDwarfSectionStartSym(MCSymbol *Sym) { - GenDwarfSectionStartSym = Sym; + MapVector<const MCSection *, std::pair<MCSymbol *, MCSymbol *> > & + getGenDwarfSectionSyms() { + return SectionStartEndSyms; } - MCSymbol *getGenDwarfSectionEndSym() { return GenDwarfSectionEndSym; } - void setGenDwarfSectionEndSym(MCSymbol *Sym) { - GenDwarfSectionEndSym = Sym; + std::pair<MapVector<const MCSection *, + std::pair<MCSymbol *, MCSymbol *> >::iterator, + bool> + addGenDwarfSection(const MCSection *Sec) { + return SectionStartEndSyms.insert( + std::make_pair(Sec, std::make_pair(nullptr, nullptr))); } + void finalizeDwarfSections(MCStreamer &MCOS); const std::vector<MCGenDwarfLabelEntry> &getMCGenDwarfLabelEntries() const { return MCGenDwarfLabelEntries; } diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h index 6df8a19..6cd9a9a 100644 --- a/include/llvm/MC/MCDwarf.h +++ b/include/llvm/MC/MCDwarf.h @@ -465,14 +465,13 @@ public: struct MCDwarfFrameInfo { MCDwarfFrameInfo() - : Begin(nullptr), End(nullptr), Personality(nullptr), Lsda(nullptr), - Function(nullptr), Instructions(), PersonalityEncoding(), LsdaEncoding(0), - CompactUnwindEncoding(0), IsSignalFrame(false), IsSimple(false) {} + : Begin(nullptr), End(nullptr), Personality(nullptr), Lsda(nullptr), + Instructions(), PersonalityEncoding(), LsdaEncoding(0), + CompactUnwindEncoding(0), IsSignalFrame(false), IsSimple(false) {} MCSymbol *Begin; MCSymbol *End; const MCSymbol *Personality; const MCSymbol *Lsda; - const MCSymbol *Function; std::vector<MCCFIInstruction> Instructions; unsigned PersonalityEncoding; unsigned LsdaEncoding; diff --git a/include/llvm/MC/MCELFStreamer.h b/include/llvm/MC/MCELFStreamer.h index be39128..66729fe 100644 --- a/include/llvm/MC/MCELFStreamer.h +++ b/include/llvm/MC/MCELFStreamer.h @@ -48,7 +48,6 @@ public: void ChangeSection(const MCSection *Section, const MCExpr *Subsection) override; void EmitLabel(MCSymbol *Symbol) override; - void EmitDebugLabel(MCSymbol *Symbol) override; void EmitAssemblerFlag(MCAssemblerFlag Flag) override; void EmitThumbFunc(MCSymbol *Func) override; void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override; diff --git a/include/llvm/MC/MCELFSymbolFlags.h b/include/llvm/MC/MCELFSymbolFlags.h index 2f1f561..297c442 100644 --- a/include/llvm/MC/MCELFSymbolFlags.h +++ b/include/llvm/MC/MCELFSymbolFlags.h @@ -41,6 +41,7 @@ namespace llvm { ELF_STT_File = (ELF::STT_FILE << ELF_STT_Shift), ELF_STT_Common = (ELF::STT_COMMON << ELF_STT_Shift), ELF_STT_Tls = (ELF::STT_TLS << ELF_STT_Shift), + ELF_STT_GnuIFunc = (ELF::STT_GNU_IFUNC << ELF_STT_Shift), ELF_STT_Loproc = (ELF::STT_LOPROC << ELF_STT_Shift), ELF_STT_Hiproc = (ELF::STT_HIPROC << ELF_STT_Shift), diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index ca5cecb..e96ecb4 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -21,6 +21,7 @@ class MCAssembler; class MCContext; class MCSection; class MCSectionData; +class MCStreamer; class MCSymbol; class MCValue; class raw_ostream; @@ -524,7 +525,7 @@ public: virtual void PrintImpl(raw_ostream &OS) const = 0; virtual bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout) const = 0; - virtual void AddValueSymbols(MCAssembler *) const = 0; + virtual void visitUsedExpr(MCStreamer& Streamer) const = 0; virtual const MCSection *FindAssociatedSection() const = 0; virtual void fixELFSymbolsInTLSFixups(MCAssembler &) const = 0; diff --git a/include/llvm/MC/MCLinkerOptimizationHint.h b/include/llvm/MC/MCLinkerOptimizationHint.h index 3b0d933..50fd527 100644 --- a/include/llvm/MC/MCLinkerOptimizationHint.h +++ b/include/llvm/MC/MCLinkerOptimizationHint.h @@ -132,8 +132,19 @@ public: /// the given @p Layout. uint64_t getEmitSize(const MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const { - std::string Buffer; - raw_string_ostream OutStream(Buffer); + class raw_counting_ostream : public raw_ostream { + uint64_t Count; + + void write_impl(const char *, size_t size) override { Count += size; } + + uint64_t current_pos() const override { return Count; } + + public: + raw_counting_ostream() : Count(0) {} + ~raw_counting_ostream() { flush(); } + }; + + raw_counting_ostream OutStream; Emit_impl(OutStream, ObjWriter, Layout); return OutStream.tell(); } diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h index e7d5bbd..12a7f0e 100644 --- a/include/llvm/MC/MCMachObjectWriter.h +++ b/include/llvm/MC/MCMachObjectWriter.h @@ -111,6 +111,8 @@ class MachObjectWriter : public MCObjectWriter { /// @} + MachSymbolData *findSymbolData(const MCSymbol &Sym); + public: MachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_ostream &_OS, bool _IsLittleEndian) diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h index 1a56040..4d1715e 100644 --- a/include/llvm/MC/MCObjectFileInfo.h +++ b/include/llvm/MC/MCObjectFileInfo.h @@ -14,13 +14,13 @@ #ifndef LLVM_MC_MCBJECTFILEINFO_H #define LLVM_MC_MCBJECTFILEINFO_H +#include "llvm/ADT/Triple.h" #include "llvm/Support/CodeGen.h" namespace llvm { class MCContext; class MCSection; class StringRef; - class Triple; class MCObjectFileInfo { protected: @@ -33,12 +33,6 @@ protected: /// 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; - /// SupportsCompactUnwindWithoutEHFrame - True if the target object file /// supports emitting a compact unwind section without an associated EH frame /// section. @@ -201,9 +195,6 @@ public: void InitMCObjectFileInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM, MCContext &ctx); - bool isFunctionEHFrameSymbolPrivate() const { - return IsFunctionEHFrameSymbolPrivate; - } bool getSupportsWeakOmittedEHFrame() const { return SupportsWeakOmittedEHFrame; } @@ -380,6 +371,7 @@ private: Reloc::Model RelocM; CodeModel::Model CMModel; MCContext *Ctx; + Triple TT; void InitMachOMCObjectFileInfo(Triple T); void InitELFMCObjectFileInfo(Triple T); @@ -388,6 +380,9 @@ private: /// InitEHFrameSection - Initialize EHFrameSection on demand. /// void InitEHFrameSection(); + +public: + const Triple &getTargetTriple() const { return TT; } }; } // end namespace llvm diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h index e41a8ba..8d37c85 100644 --- a/include/llvm/MC/MCObjectStreamer.h +++ b/include/llvm/MC/MCObjectStreamer.h @@ -78,16 +78,15 @@ protected: /// fragment is not a data fragment. MCDataFragment *getOrCreateDataFragment() const; - const MCExpr *AddValueSymbols(const MCExpr *Value); - public: + void visitUsedSymbol(const MCSymbol &Sym) override; + MCAssembler &getAssembler() { return *Assembler; } /// @name MCStreamer Interface /// @{ void EmitLabel(MCSymbol *Symbol) override; - void EmitDebugLabel(MCSymbol *Symbol) override; void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override; void EmitValueImpl(const MCExpr *Value, unsigned Size, const SMLoc &Loc = SMLoc()) override; @@ -126,6 +125,10 @@ public: void EmitFill(uint64_t NumBytes, uint8_t FillValue) override; void EmitZeros(uint64_t NumBytes) override; void FinishImpl() override; + + virtual bool mayHaveInstructions() const { + return getCurrentSectionData()->hasInstructions(); + } }; } // end namespace llvm diff --git a/include/llvm/MC/MCParser/AsmLexer.h b/include/llvm/MC/MCParser/AsmLexer.h index 59b5c09..0b550ba 100644 --- a/include/llvm/MC/MCParser/AsmLexer.h +++ b/include/llvm/MC/MCParser/AsmLexer.h @@ -28,7 +28,7 @@ class AsmLexer : public MCAsmLexer { const MCAsmInfo &MAI; const char *CurPtr; - const MemoryBuffer *CurBuf; + StringRef CurBuf; bool isAtStartOfLine; void operator=(const AsmLexer&) LLVM_DELETED_FUNCTION; @@ -42,7 +42,7 @@ public: AsmLexer(const MCAsmInfo &MAI); ~AsmLexer(); - void setBuffer(const MemoryBuffer *buf, const char *ptr = nullptr); + void setBuffer(StringRef Buf, const char *ptr = nullptr); StringRef LexUntilEndOfStatement() override; StringRef LexUntilEndOfLine(); diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h index f751786..9836795 100644 --- a/include/llvm/MC/MCParser/MCAsmParser.h +++ b/include/llvm/MC/MCParser/MCAsmParser.h @@ -30,23 +30,24 @@ class SMRange; class SourceMgr; class Twine; +class InlineAsmIdentifierInfo { +public: + void *OpDecl; + bool IsVarDecl; + unsigned Length, Size, Type; + + void clear() { + OpDecl = nullptr; + IsVarDecl = false; + Length = 1; + Size = 0; + Type = 0; + } +}; + /// MCAsmParserSemaCallback - Generic Sema callback for assembly parser. class MCAsmParserSemaCallback { public: - typedef struct { - void *OpDecl; - bool IsVarDecl; - unsigned Length, Size, Type; - - void clear() { - OpDecl = nullptr; - IsVarDecl = false; - Length = 1; - Size = 0; - Type = 0; - } - } InlineAsmIdentifierInfo; - virtual ~MCAsmParserSemaCallback(); virtual void *LookupInlineAsmIdentifier(StringRef &LineBuf, InlineAsmIdentifierInfo &Info, @@ -56,9 +57,6 @@ public: unsigned &Offset) = 0; }; -typedef MCAsmParserSemaCallback::InlineAsmIdentifierInfo - InlineAsmIdentifierInfo; - /// MCAsmParser - Generic assembler parser interface, for use by target specific /// assembly parsers. class MCAsmParser { diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h index a428f9e..d205e2a 100644 --- a/include/llvm/MC/MCSectionCOFF.h +++ b/include/llvm/MC/MCSectionCOFF.h @@ -42,24 +42,15 @@ class MCSymbol; /// it is a COMDAT section (Characteristics & IMAGE_SCN_LNK_COMDAT) != 0 mutable int Selection; - /// Assoc - This is name of the associated section, if it is a COMDAT - /// section (Characteristics & IMAGE_SCN_LNK_COMDAT) != 0 with an - /// associative Selection (IMAGE_COMDAT_SELECT_ASSOCIATIVE). - mutable const MCSectionCOFF *Assoc; - private: friend class MCContext; MCSectionCOFF(StringRef Section, unsigned Characteristics, - const MCSymbol *COMDATSymbol, int Selection, - const MCSectionCOFF *Assoc, SectionKind K) + const MCSymbol *COMDATSymbol, int Selection, SectionKind K) : MCSection(SV_COFF, K), SectionName(Section), Characteristics(Characteristics), COMDATSymbol(COMDATSymbol), - Selection(Selection), Assoc(Assoc) { + Selection(Selection) { assert ((Characteristics & 0x00F00000) == 0 && "alignment must not be set upon section creation"); - assert ((Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) == - (Assoc != nullptr) && - "associative COMDAT section must have an associated section"); } ~MCSectionCOFF(); @@ -76,11 +67,10 @@ class MCSymbol; return SectionName.str() + "_end"; } unsigned getCharacteristics() const { return Characteristics; } + const MCSymbol *getCOMDATSymbol() const { return COMDATSymbol; } int getSelection() const { return Selection; } - const MCSectionCOFF *getAssocSection() const { return Assoc; } - void setSelection(int Selection, - const MCSectionCOFF *Assoc = nullptr) const; + void setSelection(int Selection) const; void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS, const MCExpr *Subsection) const override; diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 2a8367a..216de75 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -86,6 +86,27 @@ public: virtual void finish(); }; +class AArch64TargetStreamer : public MCTargetStreamer { +public: + AArch64TargetStreamer(MCStreamer &S); + ~AArch64TargetStreamer(); + + + void finish() override; + + /// Callback used to implement the ldr= pseudo. + /// Add a new entry to the constant pool for the current section and return an + /// MCExpr that can be used to refer to the constant pool location. + const MCExpr *addConstantPoolEntry(const MCExpr *); + + /// Callback used to implemnt the .ltorg directive. + /// Emit contents of constant pool for the current section. + void emitCurrentConstantPool(); + +private: + std::unique_ptr<AssemblerConstantPools> ConstantPools; +}; + // FIXME: declared here because it is used from // lib/CodeGen/AsmPrinter/ARMException.cpp. class ARMTargetStreamer : public MCTargetStreamer { @@ -164,8 +185,6 @@ class MCStreamer { void setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame); void EnsureValidW64UnwindInfo(); - MCSymbol *LastSymbol; - // SymbolOrdering - Tracks an index to represent the order // a symbol was emitted in. Zero means we did not emit that symbol. DenseMap<const MCSymbol *, unsigned> SymbolOrdering; @@ -182,9 +201,7 @@ protected: const MCExpr *ForceExpAbs(const MCExpr *Expr); - void RecordProcStart(MCDwarfFrameInfo &Frame); virtual void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame); - void RecordProcEnd(MCDwarfFrameInfo &Frame); virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &CurFrame); MCWin64EHUnwindInfo *getCurrentW64UnwindInfo() { @@ -197,6 +214,9 @@ protected: public: virtual ~MCStreamer(); + void visitUsedExpr(const MCExpr &Expr); + virtual void visitUsedSymbol(const MCSymbol &Sym); + void setTargetStreamer(MCTargetStreamer *TS) { TargetStreamer.reset(TS); } @@ -223,6 +243,10 @@ public: return *W64UnwindInfos[i]; } + ArrayRef<MCWin64EHUnwindInfo *> getW64UnwindInfos() const { + return W64UnwindInfos; + } + void generateCompactUnwindEncodings(MCAsmBackend *MAB); /// @name Assembly File Formatting. @@ -294,7 +318,7 @@ public: /// /// This is called by PopSection and SwitchSection, if the current /// section changes. - virtual void ChangeSection(const MCSection *, const MCExpr *) = 0; + virtual void ChangeSection(const MCSection *, const MCExpr *); /// pushSection - Save the current and previous section on the /// section stack. @@ -374,12 +398,10 @@ public: // add the section we're emitting it to later. virtual void EmitLabel(MCSymbol *Symbol); - virtual void EmitDebugLabel(MCSymbol *Symbol); - virtual void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol); /// EmitAssemblerFlag - Note in the output the specified @p Flag. - virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) = 0; + virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); /// EmitLinkerOptions - Emit the given list @p Options of strings as linker /// options into the output. @@ -394,7 +416,7 @@ public: /// EmitThumbFunc - Note in the output that the specified @p Func is /// a Thumb mode function (ARM target only). - virtual void EmitThumbFunc(MCSymbol *Func) = 0; + virtual void EmitThumbFunc(MCSymbol *Func); /// EmitAssignment - Emit an assignment of @p Value to @p Symbol. /// @@ -416,7 +438,7 @@ public: /// /// @param Alias - The alias that is being created. /// @param Symbol - The symbol being aliased. - virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) = 0; + virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol); /// EmitSymbolAttribute - Add the given @p Attribute to @p Symbol. virtual bool EmitSymbolAttribute(MCSymbol *Symbol, @@ -426,25 +448,25 @@ public: /// /// @param Symbol - The symbol to have its n_desc field set. /// @param DescValue - The value to set into the n_desc field. - virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) = 0; + virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue); /// BeginCOFFSymbolDef - Start emitting COFF symbol definition /// /// @param Symbol - The symbol to have its External & Type fields set. - virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) = 0; + virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol); /// EmitCOFFSymbolStorageClass - Emit the storage class of the symbol. /// /// @param StorageClass - The storage class the symbol should have. - virtual void EmitCOFFSymbolStorageClass(int StorageClass) = 0; + virtual void EmitCOFFSymbolStorageClass(int StorageClass); /// EmitCOFFSymbolType - Emit the type of the symbol. /// /// @param Type - A COFF type identifier (see COFF::SymbolType in X86COFF.h) - virtual void EmitCOFFSymbolType(int Type) = 0; + virtual void EmitCOFFSymbolType(int Type); /// EndCOFFSymbolDef - Marks the end of the symbol definition. - virtual void EndCOFFSymbolDef() = 0; + virtual void EndCOFFSymbolDef(); /// EmitCOFFSectionIndex - Emits a COFF section index. /// @@ -461,7 +483,7 @@ public: /// This corresponds to an assembler statement such as: /// .size symbol, expression /// - virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) = 0; + virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value); /// \brief Emit a Linker Optimization Hint (LOH) directive. /// \param Args - Arguments of the LOH. @@ -482,7 +504,7 @@ public: /// @param Size - The size of the common symbol. /// @param ByteAlignment - The alignment of the common symbol in bytes. virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, - unsigned ByteAlignment) = 0; + unsigned ByteAlignment); /// EmitZerofill - Emit the zerofill section and an optional symbol. /// @@ -503,7 +525,7 @@ public: /// @param ByteAlignment - The alignment of the thread local common symbol /// if non-zero. This must be a power of 2 on some targets. virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, - uint64_t Size, unsigned ByteAlignment = 0) = 0; + uint64_t Size, unsigned ByteAlignment = 0); /// @} /// @name Generating Data @@ -513,7 +535,7 @@ public: /// /// This is used to implement assembler directives such as .byte, .ascii, /// etc. - virtual void EmitBytes(StringRef Data) = 0; + virtual void EmitBytes(StringRef Data); /// EmitValue - Emit the expression @p Value into the output as a native /// integer of the given @p Size bytes. @@ -526,7 +548,7 @@ public: /// match a native machine width. /// @param Loc - The location of the expression for error reporting. virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, - const SMLoc &Loc = SMLoc()) = 0; + const SMLoc &Loc = SMLoc()); void EmitValue(const MCExpr *Value, unsigned Size, const SMLoc &Loc = SMLoc()); @@ -541,9 +563,9 @@ public: /// .long foo void EmitAbsValue(const MCExpr *Value, unsigned Size); - virtual void EmitULEB128Value(const MCExpr *Value) = 0; + virtual void EmitULEB128Value(const MCExpr *Value); - virtual void EmitSLEB128Value(const MCExpr *Value) = 0; + virtual void EmitSLEB128Value(const MCExpr *Value); /// EmitULEB128Value - Special case of EmitULEB128Value that avoids the /// client having to pass in a MCExpr for constant integers. @@ -598,7 +620,7 @@ public: /// emitted. virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0, unsigned ValueSize = 1, - unsigned MaxBytesToEmit = 0) = 0; + unsigned MaxBytesToEmit = 0); /// EmitCodeAlignment - Emit nops until the byte alignment @p ByteAlignment /// is reached. @@ -612,7 +634,7 @@ public: /// the alignment cannot be reached in this many bytes, no bytes are /// emitted. virtual void EmitCodeAlignment(unsigned ByteAlignment, - unsigned MaxBytesToEmit = 0) = 0; + unsigned MaxBytesToEmit = 0); /// EmitValueToOffset - Emit some number of copies of @p Value until the /// byte offset @p Offset is reached. @@ -624,13 +646,13 @@ public: /// @param Value - The value to use when filling bytes. /// @return false on success, true if the offset was invalid. virtual bool EmitValueToOffset(const MCExpr *Offset, - unsigned char Value = 0) = 0; + unsigned char Value = 0); /// @} /// EmitFileDirective - Switch to a new logical file. This is used to /// implement the '.file "foo.c"' assembler directive. - virtual void EmitFileDirective(StringRef Filename) = 0; + virtual void EmitFileDirective(StringRef Filename); /// Emit the "identifiers" directive. This implements the /// '.ident "version foo"' assembler directive. @@ -677,38 +699,38 @@ public: virtual void EmitCFIRegister(int64_t Register1, int64_t Register2); virtual void EmitCFIWindowSave(); - virtual void EmitWin64EHStartProc(const MCSymbol *Symbol); - virtual void EmitWin64EHEndProc(); - virtual void EmitWin64EHStartChained(); - virtual void EmitWin64EHEndChained(); - virtual void EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind, - bool Except); - virtual void EmitWin64EHHandlerData(); - virtual void EmitWin64EHPushReg(unsigned Register); - virtual void EmitWin64EHSetFrame(unsigned Register, unsigned Offset); - virtual void EmitWin64EHAllocStack(unsigned Size); - virtual void EmitWin64EHSaveReg(unsigned Register, unsigned Offset); - virtual void EmitWin64EHSaveXMM(unsigned Register, unsigned Offset); - virtual void EmitWin64EHPushFrame(bool Code); - virtual void EmitWin64EHEndProlog(); + virtual void EmitWinCFIStartProc(const MCSymbol *Symbol); + virtual void EmitWinCFIEndProc(); + virtual void EmitWinCFIStartChained(); + virtual void EmitWinCFIEndChained(); + virtual void EmitWinCFIPushReg(unsigned Register); + virtual void EmitWinCFISetFrame(unsigned Register, unsigned Offset); + virtual void EmitWinCFIAllocStack(unsigned Size); + virtual void EmitWinCFISaveReg(unsigned Register, unsigned Offset); + virtual void EmitWinCFISaveXMM(unsigned Register, unsigned Offset); + virtual void EmitWinCFIPushFrame(bool Code); + virtual void EmitWinCFIEndProlog(); + + virtual void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except); + virtual void EmitWinEHHandlerData(); /// EmitInstruction - Emit the given @p Instruction into the current /// section. - virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) = 0; + virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI); /// \brief Set the bundle alignment mode from now on in the section. /// The argument is the power of 2 to which the alignment is set. The /// value 0 means turn the bundle alignment off. - virtual void EmitBundleAlignMode(unsigned AlignPow2) = 0; + virtual void EmitBundleAlignMode(unsigned AlignPow2); /// \brief The following instructions are a bundle-locked group. /// /// \param AlignToEnd - If true, the bundle-locked group will be aligned to /// the end of a bundle. - virtual void EmitBundleLock(bool AlignToEnd) = 0; + virtual void EmitBundleLock(bool AlignToEnd); /// \brief Ends a bundle-locked group. - virtual void EmitBundleUnlock() = 0; + virtual void EmitBundleUnlock(); /// EmitRawText - If this file is backed by a assembly streamer, this dumps /// the specified string in the output .s file. This capability is @@ -719,9 +741,11 @@ public: virtual void Flush() {} /// FinishImpl - Streamer specific finalization. - virtual void FinishImpl() = 0; + virtual void FinishImpl(); /// Finish - Finish emission of machine code. void Finish(); + + virtual bool mayHaveInstructions() const { return true; } }; /// createNullStreamer - Create a dummy machine code streamer, which does diff --git a/include/llvm/MC/MCTargetAsmParser.h b/include/llvm/MC/MCTargetAsmParser.h index 18ef6c2..384cc1b 100644 --- a/include/llvm/MC/MCTargetAsmParser.h +++ b/include/llvm/MC/MCTargetAsmParser.h @@ -14,6 +14,8 @@ #include "llvm/MC/MCParser/MCAsmParserExtension.h" #include "llvm/MC/MCTargetOptions.h" +#include <memory> + namespace llvm { class AsmToken; class MCInst; @@ -23,6 +25,8 @@ class SMLoc; class StringRef; template <typename T> class SmallVectorImpl; +typedef SmallVectorImpl<std::unique_ptr<MCParsedAsmOperand>> OperandVector; + enum AsmRewriteKind { AOK_Delete = 0, // Rewrite should be ignored. AOK_Align, // Rewrite align as .align. @@ -131,8 +135,7 @@ public: /// ownership of them to the caller. /// \return True on failure. virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, - SMLoc NameLoc, - SmallVectorImpl<MCParsedAsmOperand*> &Operands) = 0; + SMLoc NameLoc, OperandVector &Operands) = 0; /// ParseDirective - Parse a target specific assembler directive /// @@ -156,17 +159,16 @@ public: /// /// On failure, the target parser is responsible for emitting a diagnostic /// explaining the match failure. - virtual bool - MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, - SmallVectorImpl<MCParsedAsmOperand*> &Operands, - MCStreamer &Out, unsigned &ErrorInfo, - bool MatchingInlineAsm) = 0; + virtual bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, + OperandVector &Operands, MCStreamer &Out, + unsigned &ErrorInfo, + bool MatchingInlineAsm) = 0; /// Allow a target to add special case operand matching for things that /// tblgen doesn't/can't handle effectively. For example, literal /// immediates on ARM. TableGen expects a token operand, but the parser /// will recognize them as immediates. - virtual unsigned validateTargetOperandClass(MCParsedAsmOperand *Op, + virtual unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, unsigned Kind) { return Match_InvalidOperand; } @@ -178,7 +180,7 @@ public: } virtual void convertToMapAndConstraints(unsigned Kind, - const SmallVectorImpl<MCParsedAsmOperand*> &Operands) = 0; + const OperandVector &Operands) = 0; virtual const MCExpr *applyModifierToExpr(const MCExpr *E, MCSymbolRefExpr::VariantKind, diff --git a/include/llvm/MC/MCTargetOptions.h b/include/llvm/MC/MCTargetOptions.h index 80cc8be..eb4348e 100644 --- a/include/llvm/MC/MCTargetOptions.h +++ b/include/llvm/MC/MCTargetOptions.h @@ -29,6 +29,7 @@ public: bool ShowMCEncoding : 1; bool ShowMCInst : 1; bool AsmVerbose : 1; + int DwarfVersion; MCTargetOptions(); }; @@ -41,7 +42,8 @@ inline bool operator==(const MCTargetOptions &LHS, const MCTargetOptions &RHS) { ARE_EQUAL(MCUseDwarfDirectory) && ARE_EQUAL(ShowMCEncoding) && ARE_EQUAL(ShowMCInst) && - ARE_EQUAL(AsmVerbose)); + ARE_EQUAL(AsmVerbose) && + ARE_EQUAL(DwarfVersion)); #undef ARE_EQUAL } diff --git a/include/llvm/MC/MCTargetOptionsCommandFlags.h b/include/llvm/MC/MCTargetOptionsCommandFlags.h index 17a117a..6d4eb0e 100644 --- a/include/llvm/MC/MCTargetOptionsCommandFlags.h +++ b/include/llvm/MC/MCTargetOptionsCommandFlags.h @@ -33,11 +33,20 @@ cl::opt<bool> RelaxAll("mc-relax-all", cl::desc("When used with filetype=obj, " "relax all fixups in the emitted object file")); +cl::opt<int> DwarfVersion("dwarf-version", cl::desc("Dwarf version"), + cl::init(0)); + +cl::opt<bool> ShowMCInst("asm-show-inst", + cl::desc("Emit internal instruction representation to " + "assembly file")); + static inline MCTargetOptions InitMCTargetOptionsFromFlags() { MCTargetOptions Options; Options.SanitizeAddress = (AsmInstrumentation == MCTargetOptions::AsmInstrumentationAddress); Options.MCRelaxAll = RelaxAll; + Options.DwarfVersion = DwarfVersion; + Options.ShowMCInst = ShowMCInst; return Options; } diff --git a/include/llvm/MC/MCWinCOFFStreamer.h b/include/llvm/MC/MCWinCOFFStreamer.h index 34e39bb..7d2d0e4 100644 --- a/include/llvm/MC/MCWinCOFFStreamer.h +++ b/include/llvm/MC/MCWinCOFFStreamer.h @@ -35,7 +35,6 @@ public: void InitSections() override; void EmitLabel(MCSymbol *Symbol) override; - void EmitDebugLabel(MCSymbol *Symbol) override; void EmitAssemblerFlag(MCAssemblerFlag Flag) override; void EmitThumbFunc(MCSymbol *Func) override; bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override; @@ -57,7 +56,7 @@ public: unsigned ByteAlignment) override; void EmitFileDirective(StringRef Filename) override; void EmitIdent(StringRef IdentString) override; - void EmitWin64EHHandlerData() override; + void EmitWinEHHandlerData() override; void FinishImpl() override; /// \} diff --git a/include/llvm/MC/StringTableBuilder.h b/include/llvm/MC/StringTableBuilder.h new file mode 100644 index 0000000..065e9e0 --- /dev/null +++ b/include/llvm/MC/StringTableBuilder.h @@ -0,0 +1,59 @@ +//===-- StringTableBuilder.h - String table building utility ------*- 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_STRINGTABLE_BUILDER_H +#define LLVM_MC_STRINGTABLE_BUILDER_H + +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringMap.h" +#include <cassert> + +namespace llvm { + +/// \brief Utility for building string tables with deduplicated suffixes. +class StringTableBuilder { + SmallString<256> StringTable; + StringMap<size_t> StringIndexMap; + +public: + /// \brief Add a string to the builder. Returns a StringRef to the internal + /// copy of s. Can only be used before the table is finalized. + StringRef add(StringRef s) { + assert(!isFinalized()); + return StringIndexMap.GetOrCreateValue(s, 0).getKey(); + } + + /// \brief Analyze the strings and build the final table. No more strings can + /// be added after this point. + void finalize(); + + /// \brief Retrieve the string table data. Can only be used after the table + /// is finalized. + StringRef data() { + assert(isFinalized()); + return StringTable; + } + + /// \brief Get the offest of a string in the string table. Can only be used + /// after the table is finalized. + size_t getOffset(StringRef s) { + assert(isFinalized()); + assert(StringIndexMap.count(s) && "String is not in table!"); + return StringIndexMap[s]; + } + +private: + bool isFinalized() { + return !StringTable.empty(); + } +}; + +} // end llvm namespace + +#endif diff --git a/include/llvm/MC/YAML.h b/include/llvm/MC/YAML.h new file mode 100644 index 0000000..383cdc6 --- /dev/null +++ b/include/llvm/MC/YAML.h @@ -0,0 +1,94 @@ +#ifndef LLVM_MC_YAML_H +#define LLVM_MC_YAML_H + +#include "llvm/Support/YAMLTraits.h" + +namespace llvm { +namespace yaml { +/// \brief Specialized YAMLIO scalar type for representing a binary blob. +/// +/// A typical use case would be to represent the content of a section in a +/// binary file. +/// This class has custom YAMLIO traits for convenient reading and writing. +/// It renders as a string of hex digits in a YAML file. +/// For example, it might render as `DEADBEEFCAFEBABE` (YAML does not +/// require the quotation marks, so for simplicity when outputting they are +/// omitted). +/// When reading, any string whose content is an even number of hex digits +/// will be accepted. +/// For example, all of the following are acceptable: +/// `DEADBEEF`, `"DeADbEeF"`, `"\x44EADBEEF"` (Note: '\x44' == 'D') +/// +/// A significant advantage of using this class is that it never allocates +/// temporary strings or buffers for any of its functionality. +/// +/// Example: +/// +/// The YAML mapping: +/// \code +/// Foo: DEADBEEFCAFEBABE +/// \endcode +/// +/// Could be modeled in YAMLIO by the struct: +/// \code +/// struct FooHolder { +/// BinaryRef Foo; +/// }; +/// namespace llvm { +/// namespace yaml { +/// template <> +/// struct MappingTraits<FooHolder> { +/// static void mapping(IO &IO, FooHolder &FH) { +/// IO.mapRequired("Foo", FH.Foo); +/// } +/// }; +/// } // end namespace yaml +/// } // end namespace llvm +/// \endcode +class BinaryRef { + friend bool operator==(const BinaryRef &LHS, const BinaryRef &RHS); + /// \brief Either raw binary data, or a string of hex bytes (must always + /// be an even number of characters). + ArrayRef<uint8_t> Data; + /// \brief Discriminator between the two states of the `Data` member. + bool DataIsHexString; + +public: + BinaryRef(ArrayRef<uint8_t> Data) : Data(Data), DataIsHexString(false) {} + BinaryRef(StringRef Data) + : Data(reinterpret_cast<const uint8_t *>(Data.data()), Data.size()), + DataIsHexString(true) {} + BinaryRef() : DataIsHexString(true) {} + /// \brief The number of bytes that are represented by this BinaryRef. + /// This is the number of bytes that writeAsBinary() will write. + ArrayRef<uint8_t>::size_type binary_size() const { + if (DataIsHexString) + return Data.size() / 2; + return Data.size(); + } + /// \brief Write the contents (regardless of whether it is binary or a + /// hex string) as binary to the given raw_ostream. + void writeAsBinary(raw_ostream &OS) const; + /// \brief Write the contents (regardless of whether it is binary or a + /// hex string) as hex to the given raw_ostream. + /// + /// For example, a possible output could be `DEADBEEFCAFEBABE`. + void writeAsHex(raw_ostream &OS) const; +}; + +inline bool operator==(const BinaryRef &LHS, const BinaryRef &RHS) { + // Special case for default constructed BinaryRef. + if (LHS.Data.empty() && RHS.Data.empty()) + return true; + + return LHS.DataIsHexString == RHS.DataIsHexString && LHS.Data == RHS.Data; +} + +template <> struct ScalarTraits<BinaryRef> { + static void output(const BinaryRef &, void *, llvm::raw_ostream &); + static StringRef input(StringRef, void *, BinaryRef &); + static bool mustQuote(StringRef S) { return needsQuotes(S); } +}; +} +} +#endif |