+// Emit a minimal sequence of nops spanning NumBytes bytes.
+static void EmitNops(MCStreamer &OS, unsigned NumBytes, bool Is64Bit,
+ const MCSubtargetInfo &STI);
+
+namespace llvm {
+ X86AsmPrinter::StackMapShadowTracker::StackMapShadowTracker(TargetMachine &TM)
+ : TM(TM), Count(false), RequiredShadowSize(0), CurrentShadowSize(0) {}
+
+ X86AsmPrinter::StackMapShadowTracker::~StackMapShadowTracker() {}
+
+ void
+ X86AsmPrinter::StackMapShadowTracker::startFunction(MachineFunction &MF) {
+ CodeEmitter.reset(TM.getTarget().createMCCodeEmitter(*TM.getInstrInfo(),
+ *TM.getRegisterInfo(),
+ *TM.getSubtargetImpl(),
+ MF.getContext()));
+ }
+
+ void X86AsmPrinter::StackMapShadowTracker::count(MCInst &Inst,
+ const MCSubtargetInfo &STI) {
+ if (Count) {
+ SmallString<256> Code;
+ SmallVector<MCFixup, 4> Fixups;
+ raw_svector_ostream VecOS(Code);
+ CodeEmitter->EncodeInstruction(Inst, VecOS, Fixups, STI);
+ VecOS.flush();
+ CurrentShadowSize += Code.size();
+ if (CurrentShadowSize >= RequiredShadowSize)
+ Count = false; // The shadow is big enough. Stop counting.
+ }
+ }
+
+ void X86AsmPrinter::StackMapShadowTracker::emitShadowPadding(
+ MCStreamer &OutStreamer, const MCSubtargetInfo &STI) {
+ if (Count && CurrentShadowSize < RequiredShadowSize)
+ EmitNops(OutStreamer, RequiredShadowSize - CurrentShadowSize,
+ TM.getSubtarget<X86Subtarget>().is64Bit(), STI);
+ Count = false;
+ }
+
+ void X86AsmPrinter::EmitAndCountInstruction(MCInst &Inst) {
+ OutStreamer.EmitInstruction(Inst, getSubtargetInfo());
+ SMShadowTracker.count(Inst, getSubtargetInfo());
+ }
+} // end llvm namespace
+