xref: /freebsd/contrib/llvm-project/llvm/lib/Target/X86/X86AsmPrinter.h (revision b64c5a0ace59af62eff52bfe110a521dc73c937b)
1 //===-- X86AsmPrinter.h - X86 implementation of AsmPrinter ------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_LIB_TARGET_X86_X86ASMPRINTER_H
10 #define LLVM_LIB_TARGET_X86_X86ASMPRINTER_H
11 
12 #include "llvm/CodeGen/AsmPrinter.h"
13 #include "llvm/CodeGen/FaultMaps.h"
14 #include "llvm/CodeGen/StackMaps.h"
15 
16 // Implemented in X86MCInstLower.cpp
17 namespace {
18   class X86MCInstLower;
19 }
20 
21 namespace llvm {
22 class MCCodeEmitter;
23 class MCStreamer;
24 class X86Subtarget;
25 class TargetMachine;
26 
27 class LLVM_LIBRARY_VISIBILITY X86AsmPrinter : public AsmPrinter {
28   const X86Subtarget *Subtarget = nullptr;
29   FaultMaps FM;
30   std::unique_ptr<MCCodeEmitter> CodeEmitter;
31   bool EmitFPOData = false;
32   bool ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags = false;
33   bool IndCSPrefix = false;
34 
35   // This utility class tracks the length of a stackmap instruction's 'shadow'.
36   // It is used by the X86AsmPrinter to ensure that the stackmap shadow
37   // invariants (i.e. no other stackmaps, patchpoints, or control flow within
38   // the shadow) are met, while outputting a minimal number of NOPs for padding.
39   //
40   // To minimise the number of NOPs used, the shadow tracker counts the number
41   // of instruction bytes output since the last stackmap. Only if there are too
42   // few instruction bytes to cover the shadow are NOPs used for padding.
43   class StackMapShadowTracker {
44   public:
45     void startFunction(MachineFunction &MF) {
46       this->MF = &MF;
47     }
48     void count(MCInst &Inst, const MCSubtargetInfo &STI,
49                MCCodeEmitter *CodeEmitter);
50 
51     // Called to signal the start of a shadow of RequiredSize bytes.
52     void reset(unsigned RequiredSize) {
53       RequiredShadowSize = RequiredSize;
54       CurrentShadowSize = 0;
55       InShadow = true;
56     }
57 
58     // Called before every stackmap/patchpoint, and at the end of basic blocks,
59     // to emit any necessary padding-NOPs.
60     void emitShadowPadding(MCStreamer &OutStreamer, const MCSubtargetInfo &STI);
61   private:
62     const MachineFunction *MF = nullptr;
63     bool InShadow = false;
64 
65     // RequiredShadowSize holds the length of the shadow specified in the most
66     // recently encountered STACKMAP instruction.
67     // CurrentShadowSize counts the number of bytes encoded since the most
68     // recently encountered STACKMAP, stopping when that number is greater than
69     // or equal to RequiredShadowSize.
70     unsigned RequiredShadowSize = 0, CurrentShadowSize = 0;
71   };
72 
73   StackMapShadowTracker SMShadowTracker;
74 
75   // All instructions emitted by the X86AsmPrinter should use this helper
76   // method.
77   //
78   // This helper function invokes the SMShadowTracker on each instruction before
79   // outputting it to the OutStream. This allows the shadow tracker to minimise
80   // the number of NOPs used for stackmap padding.
81   void EmitAndCountInstruction(MCInst &Inst);
82   void LowerSTACKMAP(const MachineInstr &MI);
83   void LowerPATCHPOINT(const MachineInstr &MI, X86MCInstLower &MCIL);
84   void LowerSTATEPOINT(const MachineInstr &MI, X86MCInstLower &MCIL);
85   void LowerFAULTING_OP(const MachineInstr &MI, X86MCInstLower &MCIL);
86   void LowerPATCHABLE_OP(const MachineInstr &MI, X86MCInstLower &MCIL);
87 
88   void LowerTlsAddr(X86MCInstLower &MCInstLowering, const MachineInstr &MI);
89 
90   // XRay-specific lowering for X86.
91   void LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI,
92                                      X86MCInstLower &MCIL);
93   void LowerPATCHABLE_RET(const MachineInstr &MI, X86MCInstLower &MCIL);
94   void LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI, X86MCInstLower &MCIL);
95   void LowerPATCHABLE_EVENT_CALL(const MachineInstr &MI, X86MCInstLower &MCIL);
96   void LowerPATCHABLE_TYPED_EVENT_CALL(const MachineInstr &MI,
97                                        X86MCInstLower &MCIL);
98 
99   void LowerFENTRY_CALL(const MachineInstr &MI, X86MCInstLower &MCIL);
100 
101   // KCFI specific lowering for X86.
102   uint32_t MaskKCFIType(uint32_t Value);
103   void EmitKCFITypePadding(const MachineFunction &MF, bool HasType = true);
104   void LowerKCFI_CHECK(const MachineInstr &MI);
105 
106   // Address sanitizer specific lowering for X86.
107   void LowerASAN_CHECK_MEMACCESS(const MachineInstr &MI);
108 
109   // Choose between emitting .seh_ directives and .cv_fpo_ directives.
110   void EmitSEHInstruction(const MachineInstr *MI);
111 
112   void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O) override;
113   void PrintOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
114   void PrintModifiedOperand(const MachineInstr *MI, unsigned OpNo,
115                             raw_ostream &O, const char *Modifier);
116   void PrintPCRelImm(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
117   void PrintLeaMemReference(const MachineInstr *MI, unsigned OpNo,
118                             raw_ostream &O, const char *Modifier);
119   void PrintMemReference(const MachineInstr *MI, unsigned OpNo, raw_ostream &O,
120                          const char *Modifier);
121   void PrintIntelMemReference(const MachineInstr *MI, unsigned OpNo,
122                               raw_ostream &O, const char *Modifier);
123   const MCSubtargetInfo *getIFuncMCSubtargetInfo() const override;
124   void emitMachOIFuncStubBody(Module &M, const GlobalIFunc &GI,
125                               MCSymbol *LazyPointer) override;
126   void emitMachOIFuncStubHelperBody(Module &M, const GlobalIFunc &GI,
127                                     MCSymbol *LazyPointer) override;
128 
129 public:
130   X86AsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer);
131 
132   StringRef getPassName() const override {
133     return "X86 Assembly Printer";
134   }
135 
136   const X86Subtarget &getSubtarget() const { return *Subtarget; }
137 
138   void emitStartOfAsmFile(Module &M) override;
139 
140   void emitEndOfAsmFile(Module &M) override;
141 
142   void emitInstruction(const MachineInstr *MI) override;
143 
144   void emitBasicBlockEnd(const MachineBasicBlock &MBB) override;
145 
146   bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
147                        const char *ExtraCode, raw_ostream &O) override;
148   bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
149                              const char *ExtraCode, raw_ostream &O) override;
150 
151   bool doInitialization(Module &M) override {
152     SMShadowTracker.reset(0);
153     SM.reset();
154     FM.reset();
155     return AsmPrinter::doInitialization(M);
156   }
157 
158   bool runOnMachineFunction(MachineFunction &MF) override;
159   void emitFunctionBodyStart() override;
160   void emitFunctionBodyEnd() override;
161   void emitKCFITypeId(const MachineFunction &MF) override;
162 
163   bool shouldEmitWeakSwiftAsyncExtendedFramePointerFlags() const override {
164     return ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags;
165   }
166 };
167 
168 } // end namespace llvm
169 
170 #endif
171