xref: /freebsd/contrib/llvm-project/llvm/lib/Target/X86/X86AsmPrinter.h (revision 5956d97f4b3204318ceb6aa9c77bd0bc6ea87a41)
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   StackMaps SM;
30   FaultMaps FM;
31   std::unique_ptr<MCCodeEmitter> CodeEmitter;
32   bool EmitFPOData = false;
33   bool ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags = 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   // Address sanitizer specific lowering for X86.
102   void LowerASAN_CHECK_MEMACCESS(const MachineInstr &MI);
103 
104   // Choose between emitting .seh_ directives and .cv_fpo_ directives.
105   void EmitSEHInstruction(const MachineInstr *MI);
106 
107   void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O) override;
108   void PrintOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
109   void PrintModifiedOperand(const MachineInstr *MI, unsigned OpNo,
110                             raw_ostream &O, const char *Modifier);
111   void PrintPCRelImm(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
112   void PrintLeaMemReference(const MachineInstr *MI, unsigned OpNo,
113                             raw_ostream &O, const char *Modifier);
114   void PrintMemReference(const MachineInstr *MI, unsigned OpNo, raw_ostream &O,
115                          const char *Modifier);
116   void PrintIntelMemReference(const MachineInstr *MI, unsigned OpNo,
117                               raw_ostream &O, const char *Modifier);
118 
119 public:
120   X86AsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer);
121 
122   StringRef getPassName() const override {
123     return "X86 Assembly Printer";
124   }
125 
126   const X86Subtarget &getSubtarget() const { return *Subtarget; }
127 
128   void emitStartOfAsmFile(Module &M) override;
129 
130   void emitEndOfAsmFile(Module &M) override;
131 
132   void emitInstruction(const MachineInstr *MI) override;
133 
134   void emitBasicBlockEnd(const MachineBasicBlock &MBB) override {
135     AsmPrinter::emitBasicBlockEnd(MBB);
136     SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());
137   }
138 
139   bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
140                        const char *ExtraCode, raw_ostream &O) override;
141   bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
142                              const char *ExtraCode, raw_ostream &O) override;
143 
144   bool doInitialization(Module &M) override {
145     SMShadowTracker.reset(0);
146     SM.reset();
147     FM.reset();
148     return AsmPrinter::doInitialization(M);
149   }
150 
151   bool runOnMachineFunction(MachineFunction &MF) override;
152   void emitFunctionBodyStart() override;
153   void emitFunctionBodyEnd() override;
154 
155   bool shouldEmitWeakSwiftAsyncExtendedFramePointerFlags() const override {
156     return ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags;
157   }
158 };
159 
160 } // end namespace llvm
161 
162 #endif
163