X86AsmPrinter.h revision 296417
1151497Sru//===-- X86AsmPrinter.h - X86 implementation of AsmPrinter ------*- C++ -*-===// 2151497Sru// 318099Spst// The LLVM Compiler Infrastructure 4151497Sru// 5151497Sru// This file is distributed under the University of Illinois Open Source 6151497Sru// License. See LICENSE.TXT for details. 7151497Sru// 8151497Sru//===----------------------------------------------------------------------===// 9151497Sru 10151497Sru#ifndef LLVM_LIB_TARGET_X86_X86ASMPRINTER_H 11151497Sru#define LLVM_LIB_TARGET_X86_X86ASMPRINTER_H 1218099Spst 13151497Sru#include "X86Subtarget.h" 14151497Sru#include "llvm/CodeGen/AsmPrinter.h" 1518099Spst#include "llvm/CodeGen/FaultMaps.h" 16151497Sru#include "llvm/CodeGen/StackMaps.h" 1718099Spst#include "llvm/Target/TargetMachine.h" 18151497Sru 19151497Sru// Implemented in X86MCInstLower.cpp 2018099Spstnamespace { 21151497Sru class X86MCInstLower; 22151497Sru} 2318099Spst 24151497Srunamespace llvm { 25151497Sruclass MCStreamer; 2618099Spstclass MCSymbol; 27151497Sru 28151497Sruclass LLVM_LIBRARY_VISIBILITY X86AsmPrinter : public AsmPrinter { 29151497Sru const X86Subtarget *Subtarget; 30151497Sru StackMaps SM; 3118099Spst FaultMaps FM; 32151497Sru 33151497Sru // This utility class tracks the length of a stackmap instruction's 'shadow'. 34151497Sru // It is used by the X86AsmPrinter to ensure that the stackmap shadow 3555839Sasmodai // invariants (i.e. no other stackmaps, patchpoints, or control flow within 36151497Sru // the shadow) are met, while outputting a minimal number of NOPs for padding. 3755839Sasmodai // 38151497Sru // To minimise the number of NOPs used, the shadow tracker counts the number 39151497Sru // of instruction bytes output since the last stackmap. Only if there are too 40151497Sru // few instruction bytes to cover the shadow are NOPs used for padding. 4155839Sasmodai class StackMapShadowTracker { 42151497Sru public: 43151497Sru StackMapShadowTracker(TargetMachine &TM); 4455839Sasmodai ~StackMapShadowTracker(); 45151497Sru void startFunction(MachineFunction &MF); 4655839Sasmodai void count(MCInst &Inst, const MCSubtargetInfo &STI); 47151497Sru 48151497Sru // Called to signal the start of a shadow of RequiredSize bytes. 4955839Sasmodai void reset(unsigned RequiredSize) { 50151497Sru RequiredShadowSize = RequiredSize; 5155839Sasmodai CurrentShadowSize = 0; 52151497Sru InShadow = true; 53151497Sru } 5455839Sasmodai 55151497Sru // Called before every stackmap/patchpoint, and at the end of basic blocks, 5655839Sasmodai // to emit any necessary padding-NOPs. 57151497Sru void emitShadowPadding(MCStreamer &OutStreamer, const MCSubtargetInfo &STI); 58151497Sru private: 59151497Sru TargetMachine &TM; 60151497Sru const MachineFunction *MF; 61151497Sru std::unique_ptr<MCCodeEmitter> CodeEmitter; 62151497Sru bool InShadow; 63151497Sru 6469626Sru // RequiredShadowSize holds the length of the shadow specified in the most 6569626Sru // recently encountered STACKMAP instruction. 6669626Sru // CurrentShadowSize counts the number of bytes encoded since the most 6769626Sru // recently encountered STACKMAP, stopping when that number is greater than 6869626Sru // or equal to RequiredShadowSize. 6969626Sru unsigned RequiredShadowSize, CurrentShadowSize; 70151497Sru }; 71151497Sru 72151497Sru StackMapShadowTracker SMShadowTracker; 73151497Sru 74151497Sru // All instructions emitted by the X86AsmPrinter should use this helper 75151497Sru // method. 76151497Sru // 77151497Sru // This helper function invokes the SMShadowTracker on each instruction before 78151497Sru // outputting it to the OutStream. This allows the shadow tracker to minimise 79151497Sru // the number of NOPs used for stackmap padding. 80151497Sru void EmitAndCountInstruction(MCInst &Inst); 81151497Sru void LowerSTACKMAP(const MachineInstr &MI); 82151497Sru void LowerPATCHPOINT(const MachineInstr &MI, X86MCInstLower &MCIL); 83151497Sru void LowerSTATEPOINT(const MachineInstr &MI, X86MCInstLower &MCIL); 84151497Sru void LowerFAULTING_LOAD_OP(const MachineInstr &MI, X86MCInstLower &MCIL); 85151497Sru 86151497Sru void LowerTlsAddr(X86MCInstLower &MCInstLowering, const MachineInstr &MI); 87151497Sru 88151497Sru public: 89151497Sru explicit X86AsmPrinter(TargetMachine &TM, 90151497Sru std::unique_ptr<MCStreamer> Streamer) 91151497Sru : AsmPrinter(TM, std::move(Streamer)), SM(*this), FM(*this), 92151497Sru SMShadowTracker(TM) {} 93151497Sru 94151497Sru const char *getPassName() const override { 95151497Sru return "X86 Assembly / Object Emitter"; 96151497Sru } 97151497Sru 98151497Sru const X86Subtarget &getSubtarget() const { return *Subtarget; } 99151497Sru 100151497Sru void EmitStartOfAsmFile(Module &M) override; 101151497Sru 102151497Sru void EmitEndOfAsmFile(Module &M) override; 103151497Sru 10455839Sasmodai void EmitInstruction(const MachineInstr *MI) override; 105151497Sru 10655839Sasmodai void EmitBasicBlockEnd(const MachineBasicBlock &MBB) override { 107151497Sru SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo()); 10869626Sru } 10918099Spst 11055839Sasmodai bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 11155839Sasmodai unsigned AsmVariant, const char *ExtraCode, 11255839Sasmodai raw_ostream &OS) override; 11355839Sasmodai bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 114151497Sru unsigned AsmVariant, const char *ExtraCode, 115151497Sru raw_ostream &OS) override; 11655839Sasmodai 117151497Sru /// \brief Return the symbol for the specified constant pool entry. 118151497Sru MCSymbol *GetCPISymbol(unsigned CPID) const override; 11955839Sasmodai 12055839Sasmodai bool doInitialization(Module &M) override { 121151497Sru SMShadowTracker.reset(0); 122151497Sru SM.reset(); 123151497Sru return AsmPrinter::doInitialization(M); 12455839Sasmodai } 125151497Sru 126151497Sru bool runOnMachineFunction(MachineFunction &F) override; 127151497Sru}; 128151497Sru 129151497Sru} // end namespace llvm 130151497Sru 131151497Sru#endif 132151497Sru