1 //===-- X86AsmPrinter.h - X86 implementation of AsmPrinter ------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_LIB_TARGET_X86_X86ASMPRINTER_H
10 #define LLVM_LIB_TARGET_X86_X86ASMPRINTER_H
12 #include "llvm/CodeGen/AsmPrinter.h"
13 #include "llvm/CodeGen/FaultMaps.h"
14 #include "llvm/CodeGen/StackMaps.h"
16 // Implemented in X86MCInstLower.cpp
27 class LLVM_LIBRARY_VISIBILITY X86AsmPrinter
: public AsmPrinter
{
28 const X86Subtarget
*Subtarget
= nullptr;
30 std::unique_ptr
<MCCodeEmitter
> CodeEmitter
;
31 bool EmitFPOData
= false;
32 bool ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags
= false;
33 bool IndCSPrefix
= false;
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.
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
{
45 void startFunction(MachineFunction
&MF
) {
48 void count(MCInst
&Inst
, const MCSubtargetInfo
&STI
,
49 MCCodeEmitter
*CodeEmitter
);
51 // Called to signal the start of a shadow of RequiredSize bytes.
52 void reset(unsigned RequiredSize
) {
53 RequiredShadowSize
= RequiredSize
;
54 CurrentShadowSize
= 0;
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
);
62 const MachineFunction
*MF
= nullptr;
63 bool InShadow
= false;
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;
73 StackMapShadowTracker SMShadowTracker
;
75 // All instructions emitted by the X86AsmPrinter should use this helper
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
);
88 void LowerTlsAddr(X86MCInstLower
&MCInstLowering
, const MachineInstr
&MI
);
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
);
99 void LowerFENTRY_CALL(const MachineInstr
&MI
, X86MCInstLower
&MCIL
);
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
);
106 // Address sanitizer specific lowering for X86.
107 void LowerASAN_CHECK_MEMACCESS(const MachineInstr
&MI
);
109 // Choose between emitting .seh_ directives and .cv_fpo_ directives.
110 void EmitSEHInstruction(const MachineInstr
*MI
);
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
);
125 X86AsmPrinter(TargetMachine
&TM
, std::unique_ptr
<MCStreamer
> Streamer
);
127 StringRef
getPassName() const override
{
128 return "X86 Assembly Printer";
131 const X86Subtarget
&getSubtarget() const { return *Subtarget
; }
133 void emitStartOfAsmFile(Module
&M
) override
;
135 void emitEndOfAsmFile(Module
&M
) override
;
137 void emitInstruction(const MachineInstr
*MI
) override
;
139 void emitBasicBlockEnd(const MachineBasicBlock
&MBB
) override
;
141 bool PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNo
,
142 const char *ExtraCode
, raw_ostream
&O
) override
;
143 bool PrintAsmMemoryOperand(const MachineInstr
*MI
, unsigned OpNo
,
144 const char *ExtraCode
, raw_ostream
&O
) override
;
146 bool doInitialization(Module
&M
) override
{
147 SMShadowTracker
.reset(0);
150 return AsmPrinter::doInitialization(M
);
153 bool runOnMachineFunction(MachineFunction
&MF
) override
;
154 void emitFunctionBodyStart() override
;
155 void emitFunctionBodyEnd() override
;
156 void emitKCFITypeId(const MachineFunction
&MF
) override
;
158 bool shouldEmitWeakSwiftAsyncExtendedFramePointerFlags() const override
{
159 return ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags
;
163 } // end namespace llvm