Line data Source code
1 : //===- llvm/CodeGen/AsmPrinter.h - AsmPrinter Framework ---------*- 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 base class for target specific
11 : // asm writers. This class primarily handles common functionality used by
12 : // all asm writers.
13 : //
14 : //===----------------------------------------------------------------------===//
15 :
16 : #ifndef LLVM_CODEGEN_ASMPRINTER_H
17 : #define LLVM_CODEGEN_ASMPRINTER_H
18 :
19 : #include "llvm/ADT/MapVector.h"
20 : #include "llvm/ADT/SmallVector.h"
21 : #include "llvm/ADT/StringRef.h"
22 : #include "llvm/ADT/Twine.h"
23 : #include "llvm/CodeGen/DwarfStringPoolEntry.h"
24 : #include "llvm/CodeGen/MachineFunctionPass.h"
25 : #include "llvm/IR/InlineAsm.h"
26 : #include "llvm/IR/LLVMContext.h"
27 : #include "llvm/Support/ErrorHandling.h"
28 : #include "llvm/Support/SourceMgr.h"
29 : #include <cstdint>
30 : #include <memory>
31 : #include <utility>
32 : #include <vector>
33 :
34 : namespace llvm {
35 :
36 : class AsmPrinterHandler;
37 : class BasicBlock;
38 : class BlockAddress;
39 : class Constant;
40 : class ConstantArray;
41 : class DataLayout;
42 : class DIE;
43 : class DIEAbbrev;
44 : class DwarfDebug;
45 : class GCMetadataPrinter;
46 : class GCStrategy;
47 : class GlobalIndirectSymbol;
48 : class GlobalObject;
49 : class GlobalValue;
50 : class GlobalVariable;
51 : class MachineBasicBlock;
52 : class MachineConstantPoolValue;
53 : class MachineDominatorTree;
54 : class MachineFunction;
55 : class MachineInstr;
56 : class MachineJumpTableInfo;
57 : class MachineLoopInfo;
58 : class MachineModuleInfo;
59 : class MachineOptimizationRemarkEmitter;
60 : class MCAsmInfo;
61 : class MCCFIInstruction;
62 : struct MCCodePaddingContext;
63 : class MCContext;
64 : class MCExpr;
65 : class MCInst;
66 : class MCSection;
67 : class MCStreamer;
68 : class MCSubtargetInfo;
69 : class MCSymbol;
70 : class MCTargetOptions;
71 : class MDNode;
72 : class Module;
73 : class raw_ostream;
74 : class TargetLoweringObjectFile;
75 : class TargetMachine;
76 :
77 : /// This class is intended to be used as a driving class for all asm writers.
78 : class AsmPrinter : public MachineFunctionPass {
79 : public:
80 : /// Target machine description.
81 : TargetMachine &TM;
82 :
83 : /// Target Asm Printer information.
84 : const MCAsmInfo *MAI;
85 :
86 : /// This is the context for the output file that we are streaming. This owns
87 : /// all of the global MC-related objects for the generated translation unit.
88 : MCContext &OutContext;
89 :
90 : /// This is the MCStreamer object for the file we are generating. This
91 : /// contains the transient state for the current translation unit that we are
92 : /// generating (such as the current section etc).
93 : std::unique_ptr<MCStreamer> OutStreamer;
94 :
95 : /// The current machine function.
96 : MachineFunction *MF = nullptr;
97 :
98 : /// This is a pointer to the current MachineModuleInfo.
99 : MachineModuleInfo *MMI = nullptr;
100 :
101 : /// This is a pointer to the current MachineLoopInfo.
102 : MachineDominatorTree *MDT = nullptr;
103 :
104 : /// This is a pointer to the current MachineLoopInfo.
105 : MachineLoopInfo *MLI = nullptr;
106 :
107 : /// Optimization remark emitter.
108 : MachineOptimizationRemarkEmitter *ORE;
109 :
110 : /// The symbol for the current function. This is recalculated at the beginning
111 : /// of each call to runOnMachineFunction().
112 : MCSymbol *CurrentFnSym = nullptr;
113 :
114 : /// The symbol used to represent the start of the current function for the
115 : /// purpose of calculating its size (e.g. using the .size directive). By
116 : /// default, this is equal to CurrentFnSym.
117 : MCSymbol *CurrentFnSymForSize = nullptr;
118 :
119 : /// Map global GOT equivalent MCSymbols to GlobalVariables and keep track of
120 : /// its number of uses by other globals.
121 : using GOTEquivUsePair = std::pair<const GlobalVariable *, unsigned>;
122 : MapVector<const MCSymbol *, GOTEquivUsePair> GlobalGOTEquivs;
123 :
124 : /// Enable print [latency:throughput] in output.
125 : bool EnablePrintSchedInfo = false;
126 :
127 : private:
128 : MCSymbol *CurrentFnBegin = nullptr;
129 : MCSymbol *CurrentFnEnd = nullptr;
130 : MCSymbol *CurExceptionSym = nullptr;
131 :
132 : // The garbage collection metadata printer table.
133 : void *GCMetadataPrinters = nullptr; // Really a DenseMap.
134 :
135 : /// Emit comments in assembly output if this is true.
136 : bool VerboseAsm;
137 :
138 : static char ID;
139 :
140 : struct HandlerInfo {
141 : AsmPrinterHandler *Handler;
142 : const char *TimerName;
143 : const char *TimerDescription;
144 : const char *TimerGroupName;
145 : const char *TimerGroupDescription;
146 :
147 : HandlerInfo(AsmPrinterHandler *Handler, const char *TimerName,
148 : const char *TimerDescription, const char *TimerGroupName,
149 : const char *TimerGroupDescription)
150 51403 : : Handler(Handler), TimerName(TimerName),
151 : TimerDescription(TimerDescription), TimerGroupName(TimerGroupName),
152 51403 : TimerGroupDescription(TimerGroupDescription) {}
153 : };
154 :
155 : /// A vector of all debug/EH info emitters we should use. This vector
156 : /// maintains ownership of the emitters.
157 : SmallVector<HandlerInfo, 1> Handlers;
158 :
159 : public:
160 : struct SrcMgrDiagInfo {
161 : SourceMgr SrcMgr;
162 : std::vector<const MDNode *> LocInfos;
163 : LLVMContext::InlineAsmDiagHandlerTy DiagHandler;
164 : void *DiagContext;
165 : };
166 :
167 : private:
168 : /// If generated on the fly this own the instance.
169 : std::unique_ptr<MachineDominatorTree> OwnedMDT;
170 :
171 : /// If generated on the fly this own the instance.
172 : std::unique_ptr<MachineLoopInfo> OwnedMLI;
173 :
174 : /// Structure for generating diagnostics for inline assembly. Only initialised
175 : /// when necessary.
176 : mutable std::unique_ptr<SrcMgrDiagInfo> DiagInfo;
177 :
178 : /// If the target supports dwarf debug info, this pointer is non-null.
179 : DwarfDebug *DD = nullptr;
180 :
181 : /// If the current module uses dwarf CFI annotations strictly for debugging.
182 : bool isCFIMoveForDebugging = false;
183 :
184 : protected:
185 : explicit AsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer);
186 :
187 : public:
188 : ~AsmPrinter() override;
189 :
190 0 : DwarfDebug *getDwarfDebug() { return DD; }
191 0 : DwarfDebug *getDwarfDebug() const { return DD; }
192 :
193 : uint16_t getDwarfVersion() const;
194 : void setDwarfVersion(uint16_t Version);
195 :
196 : bool isPositionIndependent() const;
197 :
198 : /// Return true if assembly output should contain comments.
199 0 : bool isVerbose() const { return VerboseAsm; }
200 :
201 : /// Return a unique ID for the current function.
202 : unsigned getFunctionNumber() const;
203 :
204 : /// Return symbol for the function pseudo stack if the stack frame is not a
205 : /// register based.
206 641 : virtual const MCSymbol *getFunctionFrameSymbol() const { return nullptr; }
207 :
208 0 : MCSymbol *getFunctionBegin() const { return CurrentFnBegin; }
209 0 : MCSymbol *getFunctionEnd() const { return CurrentFnEnd; }
210 : MCSymbol *getCurExceptionSym();
211 :
212 : /// Return information about object file lowering.
213 : const TargetLoweringObjectFile &getObjFileLowering() const;
214 :
215 : /// Return information about data layout.
216 : const DataLayout &getDataLayout() const;
217 :
218 : /// Return the pointer size from the TargetMachine
219 : unsigned getPointerSize() const;
220 :
221 : /// Return information about subtarget.
222 : const MCSubtargetInfo &getSubtargetInfo() const;
223 :
224 : void EmitToStreamer(MCStreamer &S, const MCInst &Inst);
225 :
226 : /// Return the current section we are emitting to.
227 : const MCSection *getCurrentSection() const;
228 :
229 : void getNameWithPrefix(SmallVectorImpl<char> &Name,
230 : const GlobalValue *GV) const;
231 :
232 : MCSymbol *getSymbol(const GlobalValue *GV) const;
233 :
234 : //===------------------------------------------------------------------===//
235 : // XRay instrumentation implementation.
236 : //===------------------------------------------------------------------===//
237 : public:
238 : // This describes the kind of sled we're storing in the XRay table.
239 : enum class SledKind : uint8_t {
240 : FUNCTION_ENTER = 0,
241 : FUNCTION_EXIT = 1,
242 : TAIL_CALL = 2,
243 : LOG_ARGS_ENTER = 3,
244 : CUSTOM_EVENT = 4,
245 : TYPED_EVENT = 5,
246 : };
247 :
248 : // The table will contain these structs that point to the sled, the function
249 : // containing the sled, and what kind of sled (and whether they should always
250 : // be instrumented). We also use a version identifier that the runtime can use
251 : // to decide what to do with the sled, depending on the version of the sled.
252 : struct XRayFunctionEntry {
253 : const MCSymbol *Sled;
254 : const MCSymbol *Function;
255 : SledKind Kind;
256 : bool AlwaysInstrument;
257 : const class Function *Fn;
258 : uint8_t Version;
259 :
260 : void emit(int, MCStreamer *, const MCSymbol *) const;
261 : };
262 :
263 : // All the sleds to be emitted.
264 : SmallVector<XRayFunctionEntry, 4> Sleds;
265 :
266 : // A unique ID used for ELF sections associated with a particular function.
267 : unsigned XRayFnUniqueID = 0;
268 :
269 : // Helper function to record a given XRay sled.
270 : void recordSled(MCSymbol *Sled, const MachineInstr &MI, SledKind Kind,
271 : uint8_t Version = 0);
272 :
273 : /// Emit a table with all XRay instrumentation points.
274 : void emitXRayTable();
275 :
276 : //===------------------------------------------------------------------===//
277 : // MachineFunctionPass Implementation.
278 : //===------------------------------------------------------------------===//
279 :
280 : /// Record analysis usage.
281 : void getAnalysisUsage(AnalysisUsage &AU) const override;
282 :
283 : /// Set up the AsmPrinter when we are working on a new module. If your pass
284 : /// overrides this, it must make sure to explicitly call this implementation.
285 : bool doInitialization(Module &M) override;
286 :
287 : /// Shut down the asmprinter. If you override this in your pass, you must make
288 : /// sure to call it explicitly.
289 : bool doFinalization(Module &M) override;
290 :
291 : /// Emit the specified function out to the OutStreamer.
292 8957 : bool runOnMachineFunction(MachineFunction &MF) override {
293 55553 : SetupMachineFunction(MF);
294 55553 : EmitFunctionBody();
295 8956 : return false;
296 : }
297 :
298 : //===------------------------------------------------------------------===//
299 : // Coarse grained IR lowering routines.
300 : //===------------------------------------------------------------------===//
301 :
302 : /// This should be called when a new MachineFunction is being processed from
303 : /// runOnMachineFunction.
304 : void SetupMachineFunction(MachineFunction &MF);
305 :
306 : /// This method emits the body and trailer for a function.
307 : void EmitFunctionBody();
308 :
309 : void emitCFIInstruction(const MachineInstr &MI);
310 :
311 : void emitFrameAlloc(const MachineInstr &MI);
312 :
313 : void emitStackSizeSection(const MachineFunction &MF);
314 :
315 : enum CFIMoveType { CFI_M_None, CFI_M_EH, CFI_M_Debug };
316 : CFIMoveType needsCFIMoves() const;
317 :
318 : /// Returns false if needsCFIMoves() == CFI_M_EH for any function
319 : /// in the module.
320 0 : bool needsOnlyDebugCFIMoves() const { return isCFIMoveForDebugging; }
321 :
322 : bool needsSEHMoves();
323 :
324 : /// Print to the current output stream assembly representations of the
325 : /// constants in the constant pool MCP. This is used to print out constants
326 : /// which have been "spilled to memory" by the code generator.
327 : virtual void EmitConstantPool();
328 :
329 : /// Print assembly representations of the jump tables used by the current
330 : /// function to the current output stream.
331 : virtual void EmitJumpTableInfo();
332 :
333 : /// Emit the specified global variable to the .s file.
334 : virtual void EmitGlobalVariable(const GlobalVariable *GV);
335 :
336 : /// Check to see if the specified global is a special global used by LLVM. If
337 : /// so, emit it and return true, otherwise do nothing and return false.
338 : bool EmitSpecialLLVMGlobal(const GlobalVariable *GV);
339 :
340 : /// Emit an alignment directive to the specified power of two boundary. For
341 : /// example, if you pass in 3 here, you will get an 8 byte alignment. If a
342 : /// global value is specified, and if that global has an explicit alignment
343 : /// requested, it will override the alignment request if required for
344 : /// correctness.
345 : void EmitAlignment(unsigned NumBits, const GlobalObject *GV = nullptr) const;
346 :
347 : /// Lower the specified LLVM Constant to an MCExpr.
348 : virtual const MCExpr *lowerConstant(const Constant *CV);
349 :
350 : /// Print a general LLVM constant to the .s file.
351 : void EmitGlobalConstant(const DataLayout &DL, const Constant *CV);
352 :
353 : /// Unnamed constant global variables solely contaning a pointer to
354 : /// another globals variable act like a global variable "proxy", or GOT
355 : /// equivalents, i.e., it's only used to hold the address of the latter. One
356 : /// optimization is to replace accesses to these proxies by using the GOT
357 : /// entry for the final global instead. Hence, we select GOT equivalent
358 : /// candidates among all the module global variables, avoid emitting them
359 : /// unnecessarily and finally replace references to them by pc relative
360 : /// accesses to GOT entries.
361 : void computeGlobalGOTEquivs(Module &M);
362 :
363 : /// Constant expressions using GOT equivalent globals may not be
364 : /// eligible for PC relative GOT entry conversion, in such cases we need to
365 : /// emit the proxies we previously omitted in EmitGlobalVariable.
366 : void emitGlobalGOTEquivs();
367 :
368 : //===------------------------------------------------------------------===//
369 : // Overridable Hooks
370 : //===------------------------------------------------------------------===//
371 :
372 : // Targets can, or in the case of EmitInstruction, must implement these to
373 : // customize output.
374 :
375 : /// This virtual method can be overridden by targets that want to emit
376 : /// something at the start of their file.
377 4305 : virtual void EmitStartOfAsmFile(Module &) {}
378 :
379 : /// This virtual method can be overridden by targets that want to emit
380 : /// something at the end of their file.
381 1904 : virtual void EmitEndOfAsmFile(Module &) {}
382 :
383 : /// Targets can override this to emit stuff before the first basic block in
384 : /// the function.
385 44577 : virtual void EmitFunctionBodyStart() {}
386 :
387 : /// Targets can override this to emit stuff after the last basic block in the
388 : /// function.
389 18868 : virtual void EmitFunctionBodyEnd() {}
390 :
391 : /// Targets can override this to emit stuff at the start of a basic block.
392 : /// By default, this method prints the label for the specified
393 : /// MachineBasicBlock, an alignment (if present) and a comment describing it
394 : /// if appropriate.
395 : virtual void EmitBasicBlockStart(const MachineBasicBlock &MBB) const;
396 :
397 : /// Targets can override this to emit stuff at the end of a basic block.
398 : virtual void EmitBasicBlockEnd(const MachineBasicBlock &MBB);
399 :
400 : /// Targets should implement this to emit instructions.
401 0 : virtual void EmitInstruction(const MachineInstr *) {
402 0 : llvm_unreachable("EmitInstruction not implemented");
403 : }
404 :
405 : /// Return the symbol for the specified constant pool entry.
406 : virtual MCSymbol *GetCPISymbol(unsigned CPID) const;
407 :
408 : virtual void EmitFunctionEntryLabel();
409 :
410 : virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV);
411 :
412 : /// Targets can override this to change how global constants that are part of
413 : /// a C++ static/global constructor list are emitted.
414 523 : virtual void EmitXXStructor(const DataLayout &DL, const Constant *CV) {
415 523 : EmitGlobalConstant(DL, CV);
416 523 : }
417 :
418 : /// Return true if the basic block has exactly one predecessor and the control
419 : /// transfer mechanism between the predecessor and this block is a
420 : /// fall-through.
421 : virtual bool
422 : isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const;
423 :
424 : /// Targets can override this to customize the output of IMPLICIT_DEF
425 : /// instructions in verbose mode.
426 : virtual void emitImplicitDef(const MachineInstr *MI) const;
427 :
428 : //===------------------------------------------------------------------===//
429 : // Symbol Lowering Routines.
430 : //===------------------------------------------------------------------===//
431 :
432 : MCSymbol *createTempSymbol(const Twine &Name) const;
433 :
434 : /// Return the MCSymbol for a private symbol with global value name as its
435 : /// base, with the specified suffix.
436 : MCSymbol *getSymbolWithGlobalValueBase(const GlobalValue *GV,
437 : StringRef Suffix) const;
438 :
439 : /// Return the MCSymbol for the specified ExternalSymbol.
440 : MCSymbol *GetExternalSymbolSymbol(StringRef Sym) const;
441 :
442 : /// Return the symbol for the specified jump table entry.
443 : MCSymbol *GetJTISymbol(unsigned JTID, bool isLinkerPrivate = false) const;
444 :
445 : /// Return the symbol for the specified jump table .set
446 : /// FIXME: privatize to AsmPrinter.
447 : MCSymbol *GetJTSetSymbol(unsigned UID, unsigned MBBID) const;
448 :
449 : /// Return the MCSymbol used to satisfy BlockAddress uses of the specified
450 : /// basic block.
451 : MCSymbol *GetBlockAddressSymbol(const BlockAddress *BA) const;
452 : MCSymbol *GetBlockAddressSymbol(const BasicBlock *BB) const;
453 :
454 : //===------------------------------------------------------------------===//
455 : // Emission Helper Routines.
456 : //===------------------------------------------------------------------===//
457 :
458 : /// This is just convenient handler for printing offsets.
459 : void printOffset(int64_t Offset, raw_ostream &OS) const;
460 :
461 : /// Emit a byte directive and value.
462 : void emitInt8(int Value) const;
463 :
464 : /// Emit a short directive and value.
465 : void emitInt16(int Value) const;
466 :
467 : /// Emit a long directive and value.
468 : void emitInt32(int Value) const;
469 :
470 : /// Emit a long long directive and value.
471 : void emitInt64(uint64_t Value) const;
472 :
473 : /// Emit something like ".long Hi-Lo" where the size in bytes of the directive
474 : /// is specified by Size and Hi/Lo specify the labels. This implicitly uses
475 : /// .set if it is available.
476 : void EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,
477 : unsigned Size) const;
478 :
479 : /// Emit something like ".uleb128 Hi-Lo".
480 : void EmitLabelDifferenceAsULEB128(const MCSymbol *Hi,
481 : const MCSymbol *Lo) const;
482 :
483 : /// Emit something like ".long Label+Offset" where the size in bytes of the
484 : /// directive is specified by Size and Label specifies the label. This
485 : /// implicitly uses .set if it is available.
486 : void EmitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset,
487 : unsigned Size, bool IsSectionRelative = false) const;
488 :
489 : /// Emit something like ".long Label" where the size in bytes of the directive
490 : /// is specified by Size and Label specifies the label.
491 : void EmitLabelReference(const MCSymbol *Label, unsigned Size,
492 : bool IsSectionRelative = false) const {
493 319573 : EmitLabelPlusOffset(Label, 0, Size, IsSectionRelative);
494 : }
495 :
496 : /// Emit something like ".long Label + Offset".
497 : void EmitDwarfOffset(const MCSymbol *Label, uint64_t Offset) const;
498 :
499 : //===------------------------------------------------------------------===//
500 : // Dwarf Emission Helper Routines
501 : //===------------------------------------------------------------------===//
502 :
503 : /// Emit the specified signed leb128 value.
504 : void EmitSLEB128(int64_t Value, const char *Desc = nullptr) const;
505 :
506 : /// Emit the specified unsigned leb128 value.
507 : void EmitULEB128(uint64_t Value, const char *Desc = nullptr) const;
508 :
509 : /// Emit a .byte 42 directive that corresponds to an encoding. If verbose
510 : /// assembly output is enabled, we output comments describing the encoding.
511 : /// Desc is a string saying what the encoding is specifying (e.g. "LSDA").
512 : void EmitEncodingByte(unsigned Val, const char *Desc = nullptr) const;
513 :
514 : /// Return the size of the encoding in bytes.
515 : unsigned GetSizeOfEncodedValue(unsigned Encoding) const;
516 :
517 : /// Emit reference to a ttype global with a specified encoding.
518 : void EmitTTypeReference(const GlobalValue *GV, unsigned Encoding) const;
519 :
520 : /// Emit a reference to a symbol for use in dwarf. Different object formats
521 : /// represent this in different ways. Some use a relocation others encode
522 : /// the label offset in its section.
523 : void emitDwarfSymbolReference(const MCSymbol *Label,
524 : bool ForceOffset = false) const;
525 :
526 : /// Emit the 4-byte offset of a string from the start of its section.
527 : ///
528 : /// When possible, emit a DwarfStringPool section offset without any
529 : /// relocations, and without using the symbol. Otherwise, defers to \a
530 : /// emitDwarfSymbolReference().
531 : void emitDwarfStringOffset(DwarfStringPoolEntry S) const;
532 :
533 : /// Emit the 4-byte offset of a string from the start of its section.
534 : void emitDwarfStringOffset(DwarfStringPoolEntryRef S) const {
535 0 : emitDwarfStringOffset(S.getEntry());
536 : }
537 :
538 : /// Get the value for DW_AT_APPLE_isa. Zero if no isa encoding specified.
539 274 : virtual unsigned getISAEncoding() { return 0; }
540 :
541 : /// Emit the directive and value for debug thread local expression
542 : ///
543 : /// \p Value - The value to emit.
544 : /// \p Size - The size of the integer (in bytes) to emit.
545 : virtual void EmitDebugThreadLocal(const MCExpr *Value, unsigned Size) const;
546 :
547 : //===------------------------------------------------------------------===//
548 : // Dwarf Lowering Routines
549 : //===------------------------------------------------------------------===//
550 :
551 : /// Emit frame instruction to describe the layout of the frame.
552 : void emitCFIInstruction(const MCCFIInstruction &Inst) const;
553 :
554 : /// Emit Dwarf abbreviation table.
555 1185 : template <typename T> void emitDwarfAbbrevs(const T &Abbrevs) const {
556 : // For each abbreviation.
557 15432 : for (const auto &Abbrev : Abbrevs)
558 14247 : emitDwarfAbbrev(*Abbrev);
559 :
560 : // Mark end of abbreviations.
561 1185 : EmitULEB128(0, "EOM(3)");
562 1185 : }
563 :
564 : void emitDwarfAbbrev(const DIEAbbrev &Abbrev) const;
565 :
566 : /// Recursively emit Dwarf DIE tree.
567 : void emitDwarfDIE(const DIE &Die) const;
568 :
569 : //===------------------------------------------------------------------===//
570 : // Inline Asm Support
571 : //===------------------------------------------------------------------===//
572 :
573 : // These are hooks that targets can override to implement inline asm
574 : // support. These should probably be moved out of AsmPrinter someday.
575 :
576 : /// Print information related to the specified machine instr that is
577 : /// independent of the operand, and may be independent of the instr itself.
578 : /// This can be useful for portably encoding the comment character or other
579 : /// bits of target-specific knowledge into the asmstrings. The syntax used is
580 : /// ${:comment}. Targets can override this to add support for their own
581 : /// strange codes.
582 : virtual void PrintSpecial(const MachineInstr *MI, raw_ostream &OS,
583 : const char *Code) const;
584 :
585 : /// Print the specified operand of MI, an INLINEASM instruction, using the
586 : /// specified assembler variant. Targets should override this to format as
587 : /// appropriate. This method can return true if the operand is erroneous.
588 : virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
589 : unsigned AsmVariant, const char *ExtraCode,
590 : raw_ostream &OS);
591 :
592 : /// Print the specified operand of MI, an INLINEASM instruction, using the
593 : /// specified assembler variant as an address. Targets should override this to
594 : /// format as appropriate. This method can return true if the operand is
595 : /// erroneous.
596 : virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
597 : unsigned AsmVariant, const char *ExtraCode,
598 : raw_ostream &OS);
599 :
600 : /// Let the target do anything it needs to do before emitting inlineasm.
601 : /// \p StartInfo - the subtarget info before parsing inline asm
602 : virtual void emitInlineAsmStart() const;
603 :
604 : /// Let the target do anything it needs to do after emitting inlineasm.
605 : /// This callback can be used restore the original mode in case the
606 : /// inlineasm contains directives to switch modes.
607 : /// \p StartInfo - the original subtarget info before inline asm
608 : /// \p EndInfo - the final subtarget info after parsing the inline asm,
609 : /// or NULL if the value is unknown.
610 : virtual void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
611 : const MCSubtargetInfo *EndInfo) const;
612 :
613 : private:
614 : /// Private state for PrintSpecial()
615 : // Assign a unique ID to this machine instruction.
616 : mutable const MachineInstr *LastMI = nullptr;
617 : mutable unsigned LastFn = 0;
618 : mutable unsigned Counter = ~0U;
619 :
620 : /// This method emits the header for the current function.
621 : virtual void EmitFunctionHeader();
622 :
623 : /// Emit a blob of inline asm to the output streamer.
624 : void
625 : EmitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
626 : const MCTargetOptions &MCOptions,
627 : const MDNode *LocMDNode = nullptr,
628 : InlineAsm::AsmDialect AsmDialect = InlineAsm::AD_ATT) const;
629 :
630 : /// This method formats and emits the specified machine instruction that is an
631 : /// inline asm.
632 : void EmitInlineAsm(const MachineInstr *MI) const;
633 :
634 : /// Add inline assembly info to the diagnostics machinery, so we can
635 : /// emit file and position info. Returns SrcMgr memory buffer position.
636 : unsigned addInlineAsmDiagBuffer(StringRef AsmStr,
637 : const MDNode *LocMDNode) const;
638 :
639 : //===------------------------------------------------------------------===//
640 : // Internal Implementation Details
641 : //===------------------------------------------------------------------===//
642 :
643 : /// This emits visibility information about symbol, if this is supported by
644 : /// the target.
645 : void EmitVisibility(MCSymbol *Sym, unsigned Visibility,
646 : bool IsDefinition = true) const;
647 :
648 : void EmitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const;
649 :
650 : void EmitJumpTableEntry(const MachineJumpTableInfo *MJTI,
651 : const MachineBasicBlock *MBB, unsigned uid) const;
652 : void EmitLLVMUsedList(const ConstantArray *InitList);
653 : /// Emit llvm.ident metadata in an '.ident' directive.
654 : void EmitModuleIdents(Module &M);
655 : void EmitXXStructorList(const DataLayout &DL, const Constant *List,
656 : bool isCtor);
657 :
658 : GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy &S);
659 : /// Emit GlobalAlias or GlobalIFunc.
660 : void emitGlobalIndirectSymbol(Module &M, const GlobalIndirectSymbol &GIS);
661 : void setupCodePaddingContext(const MachineBasicBlock &MBB,
662 : MCCodePaddingContext &Context) const;
663 : };
664 :
665 : } // end namespace llvm
666 :
667 : #endif // LLVM_CODEGEN_ASMPRINTER_H
|