//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_TARGET_ASM_INFO_H
-#define LLVM_TARGET_ASM_INFO_H
+#ifndef LLVM_MC_MCASMINFO_H
+#define LLVM_MC_MCASMINFO_H
#include "llvm/MC/MCDirectives.h"
+#include "llvm/MC/MCDwarf.h"
+#include "llvm/MC/MachineLocation.h"
#include <cassert>
+#include <vector>
namespace llvm {
class MCExpr;
class MCSymbol;
class MCContext;
- /// MCAsmInfo - This class is intended to be used as a base class for asm
- /// properties and features specific to the target.
namespace ExceptionHandling {
- enum ExceptionsType { None, DwarfCFI, SjLj, ARM };
+ enum ExceptionsType { None, DwarfCFI, SjLj, ARM, Win64 };
+ }
+
+ namespace LCOMM {
+ enum LCOMMType { NoAlignment, ByteAlignment, Log2Alignment };
}
+ /// 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.
/// 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.
+ /// 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.
- /// PCSymbol - The symbol used to represent the current PC. Used in PC
- /// relative expressions.
- const char *PCSymbol; // Defaults to "$".
+ /// 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 ';'
- /// CommentColumn - This indicates the comment num (zero-based) at
- /// which asm comments should be printed.
- unsigned CommentColumn; // Defaults to 40
-
/// 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 ":"
- /// GlobalPrefix - If this is set to a non-empty string, it is prepended
- /// onto all global symbols. This is often used for "_" or ".".
- const char *GlobalPrefix; // Defaults to ""
-
- /// PrivateGlobalPrefix - 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. This is often "." or "L".
- const char *PrivateGlobalPrefix; // Defaults to "."
+ /// LabelSuffix - This is appended to emitted labels.
+ const char *DebugLabelSuffix; // Defaults to ":"
- /// LinkerPrivateGlobalPrefix - 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.
- const char *LinkerPrivateGlobalPrefix; // 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"
/// 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
- /// AllowQuotesInName - This is true if the assembler allows for complex
- /// symbol names to be surrounded in quotes. This defaults to false.
- bool AllowQuotesInName;
-
- /// AllowNameToStartWithDigit - This is true if the assembler allows symbol
- /// names to start with a digit (e.g., "0x0021"). This defaults to false.
- bool AllowNameToStartWithDigit;
+ /// \brief This is true if the assembler allows @ characters in symbol
+ /// names. Defaults to false.
+ bool AllowAtInName;
- /// AllowPeriodsInName - This is true if the assembler allows periods in
- /// symbol names. This defaults to true.
- bool AllowPeriodsInName;
+ /// 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 -------------------------------------===//
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.
- /// getDataASDirective - Return the directive that should be used to emit
- /// data of the specified size to the specified numeric address space.
- virtual const char *getDataASDirective(unsigned Size, unsigned AS) const {
- assert(AS != 0 && "Don't know the directives for default addr space");
- return 0;
- }
-
/// 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.
/// which doesn't support the '.bss' directive only.
bool UsesELFSectionDirectiveForBSS; // Defaults to false.
- /// HasMicrosoftFastStdCallMangling - True if this target uses microsoft
- /// style mangling for functions with X86_StdCall/X86_FastCall calling
- /// convention.
- bool HasMicrosoftFastStdCallMangling; // Defaults to false.
+ bool NeedsDwarfSectionOffsetDirective;
//===--- Alignment Information ----------------------------------------===//
- /// AlignDirective - The directive used to emit round up to an alignment
- /// boundary.
- ///
- const char *AlignDirective; // Defaults to "\t.align\t"
-
/// 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
///
const char *GlobalDirective; // Defaults to NULL.
- /// ExternDirective - This is the directive used to declare external
- /// globals.
- ///
- const char *ExternDirective; // Defaults to NULL.
-
/// HasSetDirective - True if the assembler supports the .set directive.
bool HasSetDirective; // Defaults to true.
/// .long a - b
bool HasAggressiveSymbolFolding; // Defaults to true.
- /// HasLCOMMDirective - This is true if the target supports the .lcomm
- /// directive.
- bool HasLCOMMDirective; // Defaults to false.
-
- /// COMMDirectiveAlignmentIsInBytes - True is COMMDirective's optional
+ /// COMMDirectiveAlignmentIsInBytes - True is .comm's and .lcomms optional
/// alignment is to be specified in bytes instead of log2(n).
bool COMMDirectiveAlignmentIsInBytes; // Defaults to true;
+ /// 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.
/// .file directive, this is true for ELF targets.
bool HasSingleParameterDotFile; // Defaults to true.
+ /// hasIdentDirective - True if the target has a .ident directive, this is
+ /// true for ELF targets.
+ bool HasIdentDirective; // Defaults to false.
+
/// HasNoDeadStrip - True if this target supports the MachO .no_dead_strip
/// directive.
bool HasNoDeadStrip; // Defaults to false.
- /// HasSymbolResolver - True if this target supports the MachO
- /// .symbol_resolver directive.
- bool HasSymbolResolver; // Defaults to false.
-
/// WeakRefDirective - This directive, if non-null, is used to declare a
/// global as being a weak undefined symbol.
const char *WeakRefDirective; // Defaults to NULL.
- /// WeakDefDirective - This directive, if non-null, is used to declare a
- /// global as being a weak defined symbol.
- const char *WeakDefDirective; // 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.
- /// LinkOnceDirective - This directive, if non-null is used to declare a
- /// global as being a weak defined symbol. This is used on cygwin/mingw.
- const char *LinkOnceDirective; // Defaults to NULL.
+ /// 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.
/// SupportsExceptionHandling - True if target supports exception handling.
ExceptionHandling::ExceptionsType ExceptionsType; // Defaults to None
- /// DwarfUsesInlineInfoSection - True if DwarfDebugInlineSection is used to
- /// encode inline subroutine information.
- bool DwarfUsesInlineInfoSection; // Defaults to false.
+ /// DwarfUsesRelocationsAcrossSections - True if Dwarf2 output generally
+ /// uses relocations for references to other .debug_* sections.
+ bool DwarfUsesRelocationsAcrossSections;
- /// DwarfSectionOffsetDirective - Special section offset directive.
- const char* DwarfSectionOffsetDirective; // Defaults to NULL
+ /// DwarfFDESymbolsUseAbsDiff - true if DWARF FDE symbol reference
+ /// relocations should be replaced by an absolute difference.
+ bool DwarfFDESymbolsUseAbsDiff;
- /// DwarfRequiresRelocationForStmtList - True if DW_AT_stmt_list needs
- /// a relocation to the correct offset.
- bool DwarfRequiresRelocationForStmtList; // Defaults to true;
+ /// DwarfRegNumForCFI - True if dwarf register numbers are printed
+ /// instead of symbolic register names in .cfi_* directives.
+ bool DwarfRegNumForCFI; // Defaults to false;
- // DwarfUsesLabelOffsetDifference - True if Dwarf2 output can
- // use EmitLabelOffsetDifference.
- bool DwarfUsesLabelOffsetForRanges;
+ /// 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;
- //===--- CBE Asm Translation Table -----------------------------------===//
+ //===--- Prologue State ----------------------------------------------===//
- const char *const *AsmTransCBE; // Defaults to empty
+ 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;
public:
explicit MCAsmInfo();
virtual ~MCAsmInfo();
- // FIXME: move these methods to DwarfPrinter when the JIT stops using them.
- static unsigned getSLEB128Size(int Value);
- static unsigned getULEB128Size(unsigned Value);
+ /// 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(unsigned AS = 0) const {
- return AS == 0 ? Data8bitsDirective : getDataASDirective(8, AS);
+ const char *getData8bitsDirective() const {
+ return Data8bitsDirective;
}
- const char *getData16bitsDirective(unsigned AS = 0) const {
- return AS == 0 ? Data16bitsDirective : getDataASDirective(16, AS);
+ const char *getData16bitsDirective() const {
+ return Data16bitsDirective;
}
- const char *getData32bitsDirective(unsigned AS = 0) const {
- return AS == 0 ? Data32bitsDirective : getDataASDirective(32, AS);
+ const char *getData32bitsDirective() const {
+ return Data32bitsDirective;
}
- const char *getData64bitsDirective(unsigned AS = 0) const {
- return AS == 0 ? Data64bitsDirective : getDataASDirective(64, AS);
+ 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
unsigned Encoding,
MCStreamer &Streamer) const;
- const MCExpr *
+ virtual const MCExpr *
getExprForFDESymbol(const MCSymbol *Sym,
unsigned Encoding,
MCStreamer &Streamer) const;
return UsesELFSectionDirectiveForBSS;
}
- bool hasMicrosoftFastStdCallMangling() const {
- return HasMicrosoftFastStdCallMangling;
+ bool needsDwarfSectionOffsetDirective() const {
+ return NeedsDwarfSectionOffsetDirective;
}
// Accessors.
unsigned getMaxInstLength() const {
return MaxInstLength;
}
- const char *getPCSymbol() const {
- return PCSymbol;
+ 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 CommentColumn;
+ return 40;
}
+
const char *getCommentString() const {
return CommentString;
}
const char *getLabelSuffix() const {
return LabelSuffix;
}
- const char *getGlobalPrefix() const {
- return GlobalPrefix;
+
+ const char *getDebugLabelSuffix() const {
+ return DebugLabelSuffix;
}
const char *getPrivateGlobalPrefix() const {
return PrivateGlobalPrefix;
}
- const char *getLinkerPrivateGlobalPrefix() const {
- return LinkerPrivateGlobalPrefix;
- }
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 doesAllowQuotesInName() const {
- return AllowQuotesInName;
+ bool doesAllowAtInName() const {
+ return AllowAtInName;
}
- bool doesAllowNameToStartWithDigit() const {
- return AllowNameToStartWithDigit;
- }
- bool doesAllowPeriodsInName() const {
- return AllowPeriodsInName;
+ bool doesSupportDataRegionDirectives() const {
+ return UseDataRegionDirectives;
}
const char *getZeroDirective() const {
return ZeroDirective;
const char *getAscizDirective() const {
return AscizDirective;
}
- const char *getAlignDirective() const {
- return AlignDirective;
- }
bool getAlignmentIsInBytes() const {
return AlignmentIsInBytes;
}
const char *getGlobalDirective() const {
return GlobalDirective;
}
- const char *getExternDirective() const {
- return ExternDirective;
- }
bool hasSetDirective() const { return HasSetDirective; }
bool hasAggressiveSymbolFolding() const {
return HasAggressiveSymbolFolding;
}
- bool hasLCOMMDirective() const { return HasLCOMMDirective; }
- bool hasDotTypeDotSizeDirective() const {return HasDotTypeDotSizeDirective;}
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; }
- bool hasSymbolResolver() const { return HasSymbolResolver; }
const char *getWeakRefDirective() const { return WeakRefDirective; }
- const char *getWeakDefDirective() const { return WeakDefDirective; }
- const char *getLinkOnceDirective() const { return LinkOnceDirective; }
+ bool hasWeakDefDirective() const { return HasWeakDefDirective; }
+ bool hasWeakDefCanBeHiddenDirective() const {
+ return HasWeakDefCanBeHiddenDirective;
+ }
+ bool hasLinkOnceDirective() const { return HasLinkOnceDirective; }
MCSymbolAttr getHiddenVisibilityAttr() const { return HiddenVisibilityAttr;}
MCSymbolAttr getHiddenDeclarationVisibilityAttr() const {
bool isExceptionHandlingDwarf() const {
return
(ExceptionsType == ExceptionHandling::DwarfCFI ||
- ExceptionsType == ExceptionHandling::ARM);
+ ExceptionsType == ExceptionHandling::ARM ||
+ ExceptionsType == ExceptionHandling::Win64);
+ }
+ bool doesDwarfUseRelocationsAcrossSections() const {
+ return DwarfUsesRelocationsAcrossSections;
}
- bool doesDwarfUsesInlineInfoSection() const {
- return DwarfUsesInlineInfoSection;
+ bool doDwarfFDESymbolsUseAbsDiff() const {
+ return DwarfFDESymbolsUseAbsDiff;
}
- const char *getDwarfSectionOffsetDirective() const {
- return DwarfSectionOffsetDirective;
+ bool useDwarfRegNumForCFI() const {
+ return DwarfRegNumForCFI;
}
- bool doesDwarfRequireRelocationForStmtList() const {
- return DwarfRequiresRelocationForStmtList;
+ bool useParensForSymbolVariant() const {
+ return UseParensForSymbolVariant;
}
- bool doesDwarfUsesLabelOffsetForRanges() const {
- return DwarfUsesLabelOffsetForRanges;
+
+ void addInitialFrameState(const MCCFIInstruction &Inst) {
+ InitialFrameState.push_back(Inst);
}
- const char *const *getAsmCBE() const {
- return AsmTransCBE;
+
+ 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;
}
};
}