xref: /aosp_15_r20/external/llvm/lib/Target/X86/X86AsmPrinter.h (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- X86AsmPrinter.h - X86 implementation of AsmPrinter ------*- C++ -*-===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker 
10*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_LIB_TARGET_X86_X86ASMPRINTER_H
11*9880d681SAndroid Build Coastguard Worker #define LLVM_LIB_TARGET_X86_X86ASMPRINTER_H
12*9880d681SAndroid Build Coastguard Worker 
13*9880d681SAndroid Build Coastguard Worker #include "X86Subtarget.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/AsmPrinter.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/FaultMaps.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/StackMaps.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetMachine.h"
18*9880d681SAndroid Build Coastguard Worker 
19*9880d681SAndroid Build Coastguard Worker // Implemented in X86MCInstLower.cpp
20*9880d681SAndroid Build Coastguard Worker namespace {
21*9880d681SAndroid Build Coastguard Worker   class X86MCInstLower;
22*9880d681SAndroid Build Coastguard Worker }
23*9880d681SAndroid Build Coastguard Worker 
24*9880d681SAndroid Build Coastguard Worker namespace llvm {
25*9880d681SAndroid Build Coastguard Worker class MCStreamer;
26*9880d681SAndroid Build Coastguard Worker class MCSymbol;
27*9880d681SAndroid Build Coastguard Worker 
28*9880d681SAndroid Build Coastguard Worker class LLVM_LIBRARY_VISIBILITY X86AsmPrinter : public AsmPrinter {
29*9880d681SAndroid Build Coastguard Worker   const X86Subtarget *Subtarget;
30*9880d681SAndroid Build Coastguard Worker   StackMaps SM;
31*9880d681SAndroid Build Coastguard Worker   FaultMaps FM;
32*9880d681SAndroid Build Coastguard Worker   std::unique_ptr<MCCodeEmitter> CodeEmitter;
33*9880d681SAndroid Build Coastguard Worker 
34*9880d681SAndroid Build Coastguard Worker   // This utility class tracks the length of a stackmap instruction's 'shadow'.
35*9880d681SAndroid Build Coastguard Worker   // It is used by the X86AsmPrinter to ensure that the stackmap shadow
36*9880d681SAndroid Build Coastguard Worker   // invariants (i.e. no other stackmaps, patchpoints, or control flow within
37*9880d681SAndroid Build Coastguard Worker   // the shadow) are met, while outputting a minimal number of NOPs for padding.
38*9880d681SAndroid Build Coastguard Worker   //
39*9880d681SAndroid Build Coastguard Worker   // To minimise the number of NOPs used, the shadow tracker counts the number
40*9880d681SAndroid Build Coastguard Worker   // of instruction bytes output since the last stackmap. Only if there are too
41*9880d681SAndroid Build Coastguard Worker   // few instruction bytes to cover the shadow are NOPs used for padding.
42*9880d681SAndroid Build Coastguard Worker   class StackMapShadowTracker {
43*9880d681SAndroid Build Coastguard Worker   public:
startFunction(MachineFunction & MF)44*9880d681SAndroid Build Coastguard Worker     void startFunction(MachineFunction &MF) {
45*9880d681SAndroid Build Coastguard Worker       this->MF = &MF;
46*9880d681SAndroid Build Coastguard Worker     }
47*9880d681SAndroid Build Coastguard Worker     void count(MCInst &Inst, const MCSubtargetInfo &STI,
48*9880d681SAndroid Build Coastguard Worker                MCCodeEmitter *CodeEmitter);
49*9880d681SAndroid Build Coastguard Worker 
50*9880d681SAndroid Build Coastguard Worker     // Called to signal the start of a shadow of RequiredSize bytes.
reset(unsigned RequiredSize)51*9880d681SAndroid Build Coastguard Worker     void reset(unsigned RequiredSize) {
52*9880d681SAndroid Build Coastguard Worker       RequiredShadowSize = RequiredSize;
53*9880d681SAndroid Build Coastguard Worker       CurrentShadowSize = 0;
54*9880d681SAndroid Build Coastguard Worker       InShadow = true;
55*9880d681SAndroid Build Coastguard Worker     }
56*9880d681SAndroid Build Coastguard Worker 
57*9880d681SAndroid Build Coastguard Worker     // Called before every stackmap/patchpoint, and at the end of basic blocks,
58*9880d681SAndroid Build Coastguard Worker     // to emit any necessary padding-NOPs.
59*9880d681SAndroid Build Coastguard Worker     void emitShadowPadding(MCStreamer &OutStreamer, const MCSubtargetInfo &STI);
60*9880d681SAndroid Build Coastguard Worker   private:
61*9880d681SAndroid Build Coastguard Worker     const MachineFunction *MF;
62*9880d681SAndroid Build Coastguard Worker     bool InShadow = false;
63*9880d681SAndroid Build Coastguard Worker 
64*9880d681SAndroid Build Coastguard Worker     // RequiredShadowSize holds the length of the shadow specified in the most
65*9880d681SAndroid Build Coastguard Worker     // recently encountered STACKMAP instruction.
66*9880d681SAndroid Build Coastguard Worker     // CurrentShadowSize counts the number of bytes encoded since the most
67*9880d681SAndroid Build Coastguard Worker     // recently encountered STACKMAP, stopping when that number is greater than
68*9880d681SAndroid Build Coastguard Worker     // or equal to RequiredShadowSize.
69*9880d681SAndroid Build Coastguard Worker     unsigned RequiredShadowSize = 0, CurrentShadowSize = 0;
70*9880d681SAndroid Build Coastguard Worker   };
71*9880d681SAndroid Build Coastguard Worker 
72*9880d681SAndroid Build Coastguard Worker   StackMapShadowTracker SMShadowTracker;
73*9880d681SAndroid Build Coastguard Worker 
74*9880d681SAndroid Build Coastguard Worker   // This describes the kind of sled we're storing in the XRay table.
75*9880d681SAndroid Build Coastguard Worker   enum class SledKind : uint8_t {
76*9880d681SAndroid Build Coastguard Worker     FUNCTION_ENTER = 0,
77*9880d681SAndroid Build Coastguard Worker     FUNCTION_EXIT = 1,
78*9880d681SAndroid Build Coastguard Worker     TAIL_CALL = 2,
79*9880d681SAndroid Build Coastguard Worker   };
80*9880d681SAndroid Build Coastguard Worker 
81*9880d681SAndroid Build Coastguard Worker   // The table will contain these structs that point to the sled, the function
82*9880d681SAndroid Build Coastguard Worker   // containing the sled, and what kind of sled (and whether they should always
83*9880d681SAndroid Build Coastguard Worker   // be instrumented).
84*9880d681SAndroid Build Coastguard Worker   struct XRayFunctionEntry {
85*9880d681SAndroid Build Coastguard Worker     const MCSymbol *Sled;
86*9880d681SAndroid Build Coastguard Worker     const MCSymbol *Function;
87*9880d681SAndroid Build Coastguard Worker     SledKind Kind;
88*9880d681SAndroid Build Coastguard Worker     bool AlwaysInstrument;
89*9880d681SAndroid Build Coastguard Worker     const class Function *Fn;
90*9880d681SAndroid Build Coastguard Worker   };
91*9880d681SAndroid Build Coastguard Worker 
92*9880d681SAndroid Build Coastguard Worker   // All the sleds to be emitted.
93*9880d681SAndroid Build Coastguard Worker   std::vector<XRayFunctionEntry> Sleds;
94*9880d681SAndroid Build Coastguard Worker 
95*9880d681SAndroid Build Coastguard Worker   // All instructions emitted by the X86AsmPrinter should use this helper
96*9880d681SAndroid Build Coastguard Worker   // method.
97*9880d681SAndroid Build Coastguard Worker   //
98*9880d681SAndroid Build Coastguard Worker   // This helper function invokes the SMShadowTracker on each instruction before
99*9880d681SAndroid Build Coastguard Worker   // outputting it to the OutStream. This allows the shadow tracker to minimise
100*9880d681SAndroid Build Coastguard Worker   // the number of NOPs used for stackmap padding.
101*9880d681SAndroid Build Coastguard Worker   void EmitAndCountInstruction(MCInst &Inst);
102*9880d681SAndroid Build Coastguard Worker   void LowerSTACKMAP(const MachineInstr &MI);
103*9880d681SAndroid Build Coastguard Worker   void LowerPATCHPOINT(const MachineInstr &MI, X86MCInstLower &MCIL);
104*9880d681SAndroid Build Coastguard Worker   void LowerSTATEPOINT(const MachineInstr &MI, X86MCInstLower &MCIL);
105*9880d681SAndroid Build Coastguard Worker   void LowerFAULTING_LOAD_OP(const MachineInstr &MI, X86MCInstLower &MCIL);
106*9880d681SAndroid Build Coastguard Worker   void LowerPATCHABLE_OP(const MachineInstr &MI, X86MCInstLower &MCIL);
107*9880d681SAndroid Build Coastguard Worker 
108*9880d681SAndroid Build Coastguard Worker   void LowerTlsAddr(X86MCInstLower &MCInstLowering, const MachineInstr &MI);
109*9880d681SAndroid Build Coastguard Worker 
110*9880d681SAndroid Build Coastguard Worker   // XRay-specific lowering for X86.
111*9880d681SAndroid Build Coastguard Worker   void LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI,
112*9880d681SAndroid Build Coastguard Worker                                      X86MCInstLower &MCIL);
113*9880d681SAndroid Build Coastguard Worker   void LowerPATCHABLE_RET(const MachineInstr &MI, X86MCInstLower &MCIL);
114*9880d681SAndroid Build Coastguard Worker   void LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI, X86MCInstLower &MCIL);
115*9880d681SAndroid Build Coastguard Worker 
116*9880d681SAndroid Build Coastguard Worker   // Helper function that emits the XRay sleds we've collected for a particular
117*9880d681SAndroid Build Coastguard Worker   // function.
118*9880d681SAndroid Build Coastguard Worker   void EmitXRayTable();
119*9880d681SAndroid Build Coastguard Worker 
120*9880d681SAndroid Build Coastguard Worker   // Helper function to record a given XRay sled.
121*9880d681SAndroid Build Coastguard Worker   void recordSled(MCSymbol *Sled, const MachineInstr &MI, SledKind Kind);
122*9880d681SAndroid Build Coastguard Worker public:
X86AsmPrinter(TargetMachine & TM,std::unique_ptr<MCStreamer> Streamer)123*9880d681SAndroid Build Coastguard Worker   explicit X86AsmPrinter(TargetMachine &TM,
124*9880d681SAndroid Build Coastguard Worker                          std::unique_ptr<MCStreamer> Streamer)
125*9880d681SAndroid Build Coastguard Worker       : AsmPrinter(TM, std::move(Streamer)), SM(*this), FM(*this) {}
126*9880d681SAndroid Build Coastguard Worker 
getPassName()127*9880d681SAndroid Build Coastguard Worker   const char *getPassName() const override {
128*9880d681SAndroid Build Coastguard Worker     return "X86 Assembly / Object Emitter";
129*9880d681SAndroid Build Coastguard Worker   }
130*9880d681SAndroid Build Coastguard Worker 
getSubtarget()131*9880d681SAndroid Build Coastguard Worker   const X86Subtarget &getSubtarget() const { return *Subtarget; }
132*9880d681SAndroid Build Coastguard Worker 
133*9880d681SAndroid Build Coastguard Worker   void EmitStartOfAsmFile(Module &M) override;
134*9880d681SAndroid Build Coastguard Worker 
135*9880d681SAndroid Build Coastguard Worker   void EmitEndOfAsmFile(Module &M) override;
136*9880d681SAndroid Build Coastguard Worker 
137*9880d681SAndroid Build Coastguard Worker   void EmitInstruction(const MachineInstr *MI) override;
138*9880d681SAndroid Build Coastguard Worker 
EmitBasicBlockEnd(const MachineBasicBlock & MBB)139*9880d681SAndroid Build Coastguard Worker   void EmitBasicBlockEnd(const MachineBasicBlock &MBB) override {
140*9880d681SAndroid Build Coastguard Worker     SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());
141*9880d681SAndroid Build Coastguard Worker   }
142*9880d681SAndroid Build Coastguard Worker 
143*9880d681SAndroid Build Coastguard Worker   bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
144*9880d681SAndroid Build Coastguard Worker                        unsigned AsmVariant, const char *ExtraCode,
145*9880d681SAndroid Build Coastguard Worker                        raw_ostream &OS) override;
146*9880d681SAndroid Build Coastguard Worker   bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
147*9880d681SAndroid Build Coastguard Worker                              unsigned AsmVariant, const char *ExtraCode,
148*9880d681SAndroid Build Coastguard Worker                              raw_ostream &OS) override;
149*9880d681SAndroid Build Coastguard Worker 
150*9880d681SAndroid Build Coastguard Worker   /// \brief Return the symbol for the specified constant pool entry.
151*9880d681SAndroid Build Coastguard Worker   MCSymbol *GetCPISymbol(unsigned CPID) const override;
152*9880d681SAndroid Build Coastguard Worker 
doInitialization(Module & M)153*9880d681SAndroid Build Coastguard Worker   bool doInitialization(Module &M) override {
154*9880d681SAndroid Build Coastguard Worker     SMShadowTracker.reset(0);
155*9880d681SAndroid Build Coastguard Worker     SM.reset();
156*9880d681SAndroid Build Coastguard Worker     return AsmPrinter::doInitialization(M);
157*9880d681SAndroid Build Coastguard Worker   }
158*9880d681SAndroid Build Coastguard Worker 
159*9880d681SAndroid Build Coastguard Worker   bool runOnMachineFunction(MachineFunction &F) override;
160*9880d681SAndroid Build Coastguard Worker };
161*9880d681SAndroid Build Coastguard Worker 
162*9880d681SAndroid Build Coastguard Worker } // end namespace llvm
163*9880d681SAndroid Build Coastguard Worker 
164*9880d681SAndroid Build Coastguard Worker #endif
165