1//===-- llvm/MC/MCAsmInfo.h - Asm info --------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains a class to be used as the basis for target specific
11// asm writers.  This class primarily takes care of global printing constants,
12// which are used in very similar ways across all targets.
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_MC_MCASMINFO_H
17#define LLVM_MC_MCASMINFO_H
18
19#include "llvm/MC/MCDirectives.h"
20#include "llvm/MC/MCDwarf.h"
21#include <cassert>
22#include <vector>
23
24namespace llvm {
25class MCExpr;
26class MCSection;
27class MCStreamer;
28class MCSymbol;
29class MCContext;
30
31namespace WinEH {
32enum class EncodingType {
33  Invalid, /// Invalid
34  Alpha,   /// Windows Alpha
35  Alpha64, /// Windows AXP64
36  ARM,     /// Windows NT (Windows on ARM)
37  CE,      /// Windows CE ARM, PowerPC, SH3, SH4
38  Itanium, /// Windows x64, Windows Itanium (IA-64)
39  X86,     /// Windows x86, uses no CFI, just EH tables
40  MIPS = Alpha,
41};
42}
43
44enum class ExceptionHandling {
45  None,     /// No exception support
46  DwarfCFI, /// DWARF-like instruction based exceptions
47  SjLj,     /// setjmp/longjmp based exceptions
48  ARM,      /// ARM EHABI
49  WinEH,    /// Windows Exception Handling
50};
51
52namespace LCOMM {
53enum LCOMMType { NoAlignment, ByteAlignment, Log2Alignment };
54}
55
56/// This class is intended to be used as a base class for asm
57/// properties and features specific to the target.
58class MCAsmInfo {
59protected:
60  //===------------------------------------------------------------------===//
61  // Properties to be set by the target writer, used to configure asm printer.
62  //
63
64  /// Pointer size in bytes.  Default is 4.
65  unsigned PointerSize;
66
67  /// Size of the stack slot reserved for callee-saved registers, in bytes.
68  /// Default is same as pointer size.
69  unsigned CalleeSaveStackSlotSize;
70
71  /// True if target is little endian.  Default is true.
72  bool IsLittleEndian;
73
74  /// True if target stack grow up.  Default is false.
75  bool StackGrowsUp;
76
77  /// True if this target has the MachO .subsections_via_symbols directive.
78  /// Default is false.
79  bool HasSubsectionsViaSymbols;
80
81  /// True if this is a MachO target that supports the macho-specific .zerofill
82  /// directive for emitting BSS Symbols.  Default is false.
83  bool HasMachoZeroFillDirective;
84
85  /// True if this is a MachO target that supports the macho-specific .tbss
86  /// directive for emitting thread local BSS Symbols.  Default is false.
87  bool HasMachoTBSSDirective;
88
89  /// True if the compiler should emit a ".reference .constructors_used" or
90  /// ".reference .destructors_used" directive after the static ctor/dtor
91  /// list.  This directive is only emitted in Static relocation model.  Default
92  /// is false.
93  bool HasStaticCtorDtorReferenceInStaticMode;
94
95  /// This is the maximum possible length of an instruction, which is needed to
96  /// compute the size of an inline asm.  Defaults to 4.
97  unsigned MaxInstLength;
98
99  /// Every possible instruction length is a multiple of this value.  Factored
100  /// out in .debug_frame and .debug_line.  Defaults to 1.
101  unsigned MinInstAlignment;
102
103  /// The '$' token, when not referencing an identifier or constant, refers to
104  /// the current PC.  Defaults to false.
105  bool DollarIsPC;
106
107  /// This string, if specified, is used to separate instructions from each
108  /// other when on the same line.  Defaults to ';'
109  const char *SeparatorString;
110
111  /// This indicates the comment character used by the assembler.  Defaults to
112  /// "#"
113  const char *CommentString;
114
115  /// This is appended to emitted labels.  Defaults to ":"
116  const char *LabelSuffix;
117
118  // Print the EH begin symbol with an assignment. Defaults to false.
119  bool UseAssignmentForEHBegin;
120
121  // Do we need to create a local symbol for .size?
122  bool NeedsLocalForSize;
123
124  /// This prefix is used for globals like constant pool entries that are
125  /// completely private to the .s file and should not have names in the .o
126  /// file.  Defaults to "L"
127  const char *PrivateGlobalPrefix;
128
129  /// This prefix is used for labels for basic blocks. Defaults to the same as
130  /// PrivateGlobalPrefix.
131  const char *PrivateLabelPrefix;
132
133  /// This prefix is used for symbols that should be passed through the
134  /// assembler but be removed by the linker.  This is 'l' on Darwin, currently
135  /// used for some ObjC metadata.  The default of "" meast that for this system
136  /// a plain private symbol should be used.  Defaults to "".
137  const char *LinkerPrivateGlobalPrefix;
138
139  /// If these are nonempty, they contain a directive to emit before and after
140  /// an inline assembly statement.  Defaults to "#APP\n", "#NO_APP\n"
141  const char *InlineAsmStart;
142  const char *InlineAsmEnd;
143
144  /// These are assembly directives that tells the assembler to interpret the
145  /// following instructions differently.  Defaults to ".code16", ".code32",
146  /// ".code64".
147  const char *Code16Directive;
148  const char *Code32Directive;
149  const char *Code64Directive;
150
151  /// Which dialect of an assembler variant to use.  Defaults to 0
152  unsigned AssemblerDialect;
153
154  /// This is true if the assembler allows @ characters in symbol names.
155  /// Defaults to false.
156  bool AllowAtInName;
157
158  /// If this is true, symbol names with invalid characters will be printed in
159  /// quotes.
160  bool SupportsQuotedNames;
161
162  /// This is true if data region markers should be printed as
163  /// ".data_region/.end_data_region" directives. If false, use "$d/$a" labels
164  /// instead.
165  bool UseDataRegionDirectives;
166
167  //===--- Data Emission Directives -------------------------------------===//
168
169  /// This should be set to the directive used to get some number of zero bytes
170  /// emitted to the current section.  Common cases are "\t.zero\t" and
171  /// "\t.space\t".  If this is set to null, the Data*bitsDirective's will be
172  /// used to emit zero bytes.  Defaults to "\t.zero\t"
173  const char *ZeroDirective;
174
175  /// This directive allows emission of an ascii string with the standard C
176  /// escape characters embedded into it.  Defaults to "\t.ascii\t"
177  const char *AsciiDirective;
178
179  /// If not null, this allows for special handling of zero terminated strings
180  /// on this target.  This is commonly supported as ".asciz".  If a target
181  /// doesn't support this, it can be set to null.  Defaults to "\t.asciz\t"
182  const char *AscizDirective;
183
184  /// These directives are used to output some unit of integer data to the
185  /// current section.  If a data directive is set to null, smaller data
186  /// directives will be used to emit the large sizes.  Defaults to "\t.byte\t",
187  /// "\t.short\t", "\t.long\t", "\t.quad\t"
188  const char *Data8bitsDirective;
189  const char *Data16bitsDirective;
190  const char *Data32bitsDirective;
191  const char *Data64bitsDirective;
192
193  /// If non-null, a directive that is used to emit a word which should be
194  /// relocated as a 64-bit GP-relative offset, e.g. .gpdword on Mips.  Defaults
195  /// to NULL.
196  const char *GPRel64Directive;
197
198  /// If non-null, a directive that is used to emit a word which should be
199  /// relocated as a 32-bit GP-relative offset, e.g. .gpword on Mips or .gprel32
200  /// on Alpha.  Defaults to NULL.
201  const char *GPRel32Directive;
202
203  /// This is true if this target uses "Sun Style" syntax for section switching
204  /// ("#alloc,#write" etc) instead of the normal ELF syntax (,"a,w") in
205  /// .section directives.  Defaults to false.
206  bool SunStyleELFSectionSwitchSyntax;
207
208  /// This is true if this target uses ELF '.section' directive before the
209  /// '.bss' one. It's used for PPC/Linux which doesn't support the '.bss'
210  /// directive only.  Defaults to false.
211  bool UsesELFSectionDirectiveForBSS;
212
213  bool NeedsDwarfSectionOffsetDirective;
214
215  //===--- Alignment Information ----------------------------------------===//
216
217  /// If this is true (the default) then the asmprinter emits ".align N"
218  /// directives, where N is the number of bytes to align to.  Otherwise, it
219  /// emits ".align log2(N)", e.g. 3 to align to an 8 byte boundary.  Defaults
220  /// to true.
221  bool AlignmentIsInBytes;
222
223  /// If non-zero, this is used to fill the executable space created as the
224  /// result of a alignment directive.  Defaults to 0
225  unsigned TextAlignFillValue;
226
227  //===--- Global Variable Emission Directives --------------------------===//
228
229  /// This is the directive used to declare a global entity. Defaults to
230  /// ".globl".
231  const char *GlobalDirective;
232
233  /// True if the expression
234  ///   .long f - g
235  /// uses a relocation but it can be suppressed by writing
236  ///   a = f - g
237  ///   .long a
238  bool SetDirectiveSuppressesReloc;
239
240  /// False if the assembler requires that we use
241  /// \code
242  ///   Lc = a - b
243  ///   .long Lc
244  /// \endcode
245  //
246  /// instead of
247  //
248  /// \code
249  ///   .long a - b
250  /// \endcode
251  ///
252  ///  Defaults to true.
253  bool HasAggressiveSymbolFolding;
254
255  /// True is .comm's and .lcomms optional alignment is to be specified in bytes
256  /// instead of log2(n).  Defaults to true.
257  bool COMMDirectiveAlignmentIsInBytes;
258
259  /// Describes if the .lcomm directive for the target supports an alignment
260  /// argument and how it is interpreted.  Defaults to NoAlignment.
261  LCOMM::LCOMMType LCOMMDirectiveAlignmentType;
262
263  // True if the target allows .align directives on functions. This is true for
264  // most targets, so defaults to true.
265  bool HasFunctionAlignment;
266
267  /// True if the target has .type and .size directives, this is true for most
268  /// ELF targets.  Defaults to true.
269  bool HasDotTypeDotSizeDirective;
270
271  /// True if the target has a single parameter .file directive, this is true
272  /// for ELF targets.  Defaults to true.
273  bool HasSingleParameterDotFile;
274
275  /// True if the target has a .ident directive, this is true for ELF targets.
276  /// Defaults to false.
277  bool HasIdentDirective;
278
279  /// True if this target supports the MachO .no_dead_strip directive.  Defaults
280  /// to false.
281  bool HasNoDeadStrip;
282
283  /// Used to declare a global as being a weak symbol. Defaults to ".weak".
284  const char *WeakDirective;
285
286  /// This directive, if non-null, is used to declare a global as being a weak
287  /// undefined symbol.  Defaults to NULL.
288  const char *WeakRefDirective;
289
290  /// True if we have a directive to declare a global as being a weak defined
291  /// symbol.  Defaults to false.
292  bool HasWeakDefDirective;
293
294  /// True if we have a directive to declare a global as being a weak defined
295  /// symbol that can be hidden (unexported).  Defaults to false.
296  bool HasWeakDefCanBeHiddenDirective;
297
298  /// True if we have a .linkonce directive.  This is used on cygwin/mingw.
299  /// Defaults to false.
300  bool HasLinkOnceDirective;
301
302  /// This attribute, if not MCSA_Invalid, is used to declare a symbol as having
303  /// hidden visibility.  Defaults to MCSA_Hidden.
304  MCSymbolAttr HiddenVisibilityAttr;
305
306  /// This attribute, if not MCSA_Invalid, is used to declare an undefined
307  /// symbol as having hidden visibility. Defaults to MCSA_Hidden.
308  MCSymbolAttr HiddenDeclarationVisibilityAttr;
309
310  /// This attribute, if not MCSA_Invalid, is used to declare a symbol as having
311  /// protected visibility.  Defaults to MCSA_Protected
312  MCSymbolAttr ProtectedVisibilityAttr;
313
314  //===--- Dwarf Emission Directives -----------------------------------===//
315
316  /// True if target supports emission of debugging information.  Defaults to
317  /// false.
318  bool SupportsDebugInformation;
319
320  /// Exception handling format for the target.  Defaults to None.
321  ExceptionHandling ExceptionsType;
322
323  /// Windows exception handling data (.pdata) encoding.  Defaults to Invalid.
324  WinEH::EncodingType WinEHEncodingType;
325
326  /// True if Dwarf2 output generally uses relocations for references to other
327  /// .debug_* sections.
328  bool DwarfUsesRelocationsAcrossSections;
329
330  /// True if DWARF FDE symbol reference relocations should be replaced by an
331  /// absolute difference.
332  bool DwarfFDESymbolsUseAbsDiff;
333
334  /// True if dwarf register numbers are printed instead of symbolic register
335  /// names in .cfi_* directives.  Defaults to false.
336  bool DwarfRegNumForCFI;
337
338  /// True if target uses parens to indicate the symbol variant instead of @.
339  /// For example, foo(plt) instead of foo@plt.  Defaults to false.
340  bool UseParensForSymbolVariant;
341
342  //===--- Prologue State ----------------------------------------------===//
343
344  std::vector<MCCFIInstruction> InitialFrameState;
345
346  //===--- Integrated Assembler Information ----------------------------===//
347
348  /// Should we use the integrated assembler?
349  /// The integrated assembler should be enabled by default (by the
350  /// constructors) when failing to parse a valid piece of assembly (inline
351  /// or otherwise) is considered a bug. It may then be overridden after
352  /// construction (see LLVMTargetMachine::initAsmInfo()).
353  bool UseIntegratedAssembler;
354
355  /// Compress DWARF debug sections. Defaults to false.
356  bool CompressDebugSections;
357
358  /// True if the integrated assembler should interpret 'a >> b' constant
359  /// expressions as logical rather than arithmetic.
360  bool UseLogicalShr;
361
362public:
363  explicit MCAsmInfo();
364  virtual ~MCAsmInfo();
365
366  /// Get the pointer size in bytes.
367  unsigned getPointerSize() const { return PointerSize; }
368
369  /// Get the callee-saved register stack slot
370  /// size in bytes.
371  unsigned getCalleeSaveStackSlotSize() const {
372    return CalleeSaveStackSlotSize;
373  }
374
375  /// True if the target is little endian.
376  bool isLittleEndian() const { return IsLittleEndian; }
377
378  /// True if target stack grow up.
379  bool isStackGrowthDirectionUp() const { return StackGrowsUp; }
380
381  bool hasSubsectionsViaSymbols() const { return HasSubsectionsViaSymbols; }
382
383  // Data directive accessors.
384
385  const char *getData8bitsDirective() const { return Data8bitsDirective; }
386  const char *getData16bitsDirective() const { return Data16bitsDirective; }
387  const char *getData32bitsDirective() const { return Data32bitsDirective; }
388  const char *getData64bitsDirective() const { return Data64bitsDirective; }
389  const char *getGPRel64Directive() const { return GPRel64Directive; }
390  const char *getGPRel32Directive() const { return GPRel32Directive; }
391
392  /// Targets can implement this method to specify a section to switch to if the
393  /// translation unit doesn't have any trampolines that require an executable
394  /// stack.
395  virtual MCSection *getNonexecutableStackSection(MCContext &Ctx) const {
396    return nullptr;
397  }
398
399  /// \brief True if the section is atomized using the symbols in it.
400  /// This is false if the section is not atomized at all (most ELF sections) or
401  /// if it is atomized based on its contents (MachO' __TEXT,__cstring for
402  /// example).
403  virtual bool isSectionAtomizableBySymbols(const MCSection &Section) const;
404
405  virtual const MCExpr *getExprForPersonalitySymbol(const MCSymbol *Sym,
406                                                    unsigned Encoding,
407                                                    MCStreamer &Streamer) const;
408
409  virtual const MCExpr *getExprForFDESymbol(const MCSymbol *Sym,
410                                            unsigned Encoding,
411                                            MCStreamer &Streamer) const;
412
413  /// Return true if the identifier \p Name does not need quotes to be
414  /// syntactically correct.
415  virtual bool isValidUnquotedName(StringRef Name) const;
416
417  /// Return true if the .section directive should be omitted when
418  /// emitting \p SectionName.  For example:
419  ///
420  /// shouldOmitSectionDirective(".text")
421  ///
422  /// returns false => .section .text,#alloc,#execinstr
423  /// returns true  => .text
424  virtual bool shouldOmitSectionDirective(StringRef SectionName) const;
425
426  bool usesSunStyleELFSectionSwitchSyntax() const {
427    return SunStyleELFSectionSwitchSyntax;
428  }
429
430  bool usesELFSectionDirectiveForBSS() const {
431    return UsesELFSectionDirectiveForBSS;
432  }
433
434  bool needsDwarfSectionOffsetDirective() const {
435    return NeedsDwarfSectionOffsetDirective;
436  }
437
438  // Accessors.
439
440  bool hasMachoZeroFillDirective() const { return HasMachoZeroFillDirective; }
441  bool hasMachoTBSSDirective() const { return HasMachoTBSSDirective; }
442  bool hasStaticCtorDtorReferenceInStaticMode() const {
443    return HasStaticCtorDtorReferenceInStaticMode;
444  }
445  unsigned getMaxInstLength() const { return MaxInstLength; }
446  unsigned getMinInstAlignment() const { return MinInstAlignment; }
447  bool getDollarIsPC() const { return DollarIsPC; }
448  const char *getSeparatorString() const { return SeparatorString; }
449
450  /// This indicates the column (zero-based) at which asm comments should be
451  /// printed.
452  unsigned getCommentColumn() const { return 40; }
453
454  const char *getCommentString() const { return CommentString; }
455  const char *getLabelSuffix() const { return LabelSuffix; }
456
457  bool useAssignmentForEHBegin() const { return UseAssignmentForEHBegin; }
458  bool needsLocalForSize() const { return NeedsLocalForSize; }
459  const char *getPrivateGlobalPrefix() const { return PrivateGlobalPrefix; }
460  const char *getPrivateLabelPrefix() const { return PrivateLabelPrefix; }
461  bool hasLinkerPrivateGlobalPrefix() const {
462    return LinkerPrivateGlobalPrefix[0] != '\0';
463  }
464  const char *getLinkerPrivateGlobalPrefix() const {
465    if (hasLinkerPrivateGlobalPrefix())
466      return LinkerPrivateGlobalPrefix;
467    return getPrivateGlobalPrefix();
468  }
469  const char *getInlineAsmStart() const { return InlineAsmStart; }
470  const char *getInlineAsmEnd() const { return InlineAsmEnd; }
471  const char *getCode16Directive() const { return Code16Directive; }
472  const char *getCode32Directive() const { return Code32Directive; }
473  const char *getCode64Directive() const { return Code64Directive; }
474  unsigned getAssemblerDialect() const { return AssemblerDialect; }
475  bool doesAllowAtInName() const { return AllowAtInName; }
476  bool supportsNameQuoting() const { return SupportsQuotedNames; }
477  bool doesSupportDataRegionDirectives() const {
478    return UseDataRegionDirectives;
479  }
480  const char *getZeroDirective() const { return ZeroDirective; }
481  const char *getAsciiDirective() const { return AsciiDirective; }
482  const char *getAscizDirective() const { return AscizDirective; }
483  bool getAlignmentIsInBytes() const { return AlignmentIsInBytes; }
484  unsigned getTextAlignFillValue() const { return TextAlignFillValue; }
485  const char *getGlobalDirective() const { return GlobalDirective; }
486  bool doesSetDirectiveSuppressesReloc() const {
487    return SetDirectiveSuppressesReloc;
488  }
489  bool hasAggressiveSymbolFolding() const { return HasAggressiveSymbolFolding; }
490  bool getCOMMDirectiveAlignmentIsInBytes() const {
491    return COMMDirectiveAlignmentIsInBytes;
492  }
493  LCOMM::LCOMMType getLCOMMDirectiveAlignmentType() const {
494    return LCOMMDirectiveAlignmentType;
495  }
496  bool hasFunctionAlignment() const { return HasFunctionAlignment; }
497  bool hasDotTypeDotSizeDirective() const { return HasDotTypeDotSizeDirective; }
498  bool hasSingleParameterDotFile() const { return HasSingleParameterDotFile; }
499  bool hasIdentDirective() const { return HasIdentDirective; }
500  bool hasNoDeadStrip() const { return HasNoDeadStrip; }
501  const char *getWeakDirective() const { return WeakDirective; }
502  const char *getWeakRefDirective() const { return WeakRefDirective; }
503  bool hasWeakDefDirective() const { return HasWeakDefDirective; }
504  bool hasWeakDefCanBeHiddenDirective() const {
505    return HasWeakDefCanBeHiddenDirective;
506  }
507  bool hasLinkOnceDirective() const { return HasLinkOnceDirective; }
508
509  MCSymbolAttr getHiddenVisibilityAttr() const { return HiddenVisibilityAttr; }
510  MCSymbolAttr getHiddenDeclarationVisibilityAttr() const {
511    return HiddenDeclarationVisibilityAttr;
512  }
513  MCSymbolAttr getProtectedVisibilityAttr() const {
514    return ProtectedVisibilityAttr;
515  }
516  bool doesSupportDebugInformation() const { return SupportsDebugInformation; }
517  bool doesSupportExceptionHandling() const {
518    return ExceptionsType != ExceptionHandling::None;
519  }
520  ExceptionHandling getExceptionHandlingType() const { return ExceptionsType; }
521  WinEH::EncodingType getWinEHEncodingType() const { return WinEHEncodingType; }
522
523  /// Returns true if the exception handling method for the platform uses call
524  /// frame information to unwind.
525  bool usesCFIForEH() const {
526    return (ExceptionsType == ExceptionHandling::DwarfCFI ||
527            ExceptionsType == ExceptionHandling::ARM || usesWindowsCFI());
528  }
529
530  bool usesWindowsCFI() const {
531    return ExceptionsType == ExceptionHandling::WinEH &&
532           (WinEHEncodingType != WinEH::EncodingType::Invalid &&
533            WinEHEncodingType != WinEH::EncodingType::X86);
534  }
535
536  bool doesDwarfUseRelocationsAcrossSections() const {
537    return DwarfUsesRelocationsAcrossSections;
538  }
539  bool doDwarfFDESymbolsUseAbsDiff() const { return DwarfFDESymbolsUseAbsDiff; }
540  bool useDwarfRegNumForCFI() const { return DwarfRegNumForCFI; }
541  bool useParensForSymbolVariant() const { return UseParensForSymbolVariant; }
542
543  void addInitialFrameState(const MCCFIInstruction &Inst) {
544    InitialFrameState.push_back(Inst);
545  }
546
547  const std::vector<MCCFIInstruction> &getInitialFrameState() const {
548    return InitialFrameState;
549  }
550
551  /// Return true if assembly (inline or otherwise) should be parsed.
552  bool useIntegratedAssembler() const { return UseIntegratedAssembler; }
553
554  /// Set whether assembly (inline or otherwise) should be parsed.
555  virtual void setUseIntegratedAssembler(bool Value) {
556    UseIntegratedAssembler = Value;
557  }
558
559  bool compressDebugSections() const { return CompressDebugSections; }
560
561  void setCompressDebugSections(bool CompressDebugSections) {
562    this->CompressDebugSections = CompressDebugSections;
563  }
564
565  bool shouldUseLogicalShr() const { return UseLogicalShr; }
566};
567}
568
569#endif
570