//===-- X86AsmPrinter.h - X86 implementation of AsmPrinter ------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_X86_X86ASMPRINTER_H
#define LLVM_LIB_TARGET_X86_X86ASMPRINTER_H

#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/FaultMaps.h"
#include "llvm/CodeGen/StackMaps.h"

// Implemented in X86MCInstLower.cpp
namespace {
  class X86MCInstLower;
}

namespace llvm {
class MCCodeEmitter;
class MCStreamer;
class X86Subtarget;
class TargetMachine;
struct ASanAccessInfo;

class LLVM_LIBRARY_VISIBILITY X86AsmPrinter : public AsmPrinter {
  const X86Subtarget *Subtarget = nullptr;
  StackMaps SM;
  FaultMaps FM;
  std::unique_ptr<MCCodeEmitter> CodeEmitter;
  bool EmitFPOData = false;

  // This utility class tracks the length of a stackmap instruction's 'shadow'.
  // It is used by the X86AsmPrinter to ensure that the stackmap shadow
  // invariants (i.e. no other stackmaps, patchpoints, or control flow within
  // the shadow) are met, while outputting a minimal number of NOPs for padding.
  //
  // To minimise the number of NOPs used, the shadow tracker counts the number
  // of instruction bytes output since the last stackmap. Only if there are too
  // few instruction bytes to cover the shadow are NOPs used for padding.
  class StackMapShadowTracker {
  public:
    void startFunction(MachineFunction &MF) {
      this->MF = &MF;
    }
    void count(MCInst &Inst, const MCSubtargetInfo &STI,
               MCCodeEmitter *CodeEmitter);

    // Called to signal the start of a shadow of RequiredSize bytes.
    void reset(unsigned RequiredSize) {
      RequiredShadowSize = RequiredSize;
      CurrentShadowSize = 0;
      InShadow = true;
    }

    // Called before every stackmap/patchpoint, and at the end of basic blocks,
    // to emit any necessary padding-NOPs.
    void emitShadowPadding(MCStreamer &OutStreamer, const MCSubtargetInfo &STI);
  private:
    const MachineFunction *MF = nullptr;
    bool InShadow = false;

    // RequiredShadowSize holds the length of the shadow specified in the most
    // recently encountered STACKMAP instruction.
    // CurrentShadowSize counts the number of bytes encoded since the most
    // recently encountered STACKMAP, stopping when that number is greater than
    // or equal to RequiredShadowSize.
    unsigned RequiredShadowSize = 0, CurrentShadowSize = 0;
  };

  StackMapShadowTracker SMShadowTracker;

  // All instructions emitted by the X86AsmPrinter should use this helper
  // method.
  //
  // This helper function invokes the SMShadowTracker on each instruction before
  // outputting it to the OutStream. This allows the shadow tracker to minimise
  // the number of NOPs used for stackmap padding.
  void EmitAndCountInstruction(MCInst &Inst);
  void LowerSTACKMAP(const MachineInstr &MI);
  void LowerPATCHPOINT(const MachineInstr &MI, X86MCInstLower &MCIL);
  void LowerSTATEPOINT(const MachineInstr &MI, X86MCInstLower &MCIL);
  void LowerFAULTING_OP(const MachineInstr &MI, X86MCInstLower &MCIL);
  void LowerPATCHABLE_OP(const MachineInstr &MI, X86MCInstLower &MCIL);

  void LowerTlsAddr(X86MCInstLower &MCInstLowering, const MachineInstr &MI);

  // XRay-specific lowering for X86.
  void LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI,
                                     X86MCInstLower &MCIL);
  void LowerPATCHABLE_RET(const MachineInstr &MI, X86MCInstLower &MCIL);
  void LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI, X86MCInstLower &MCIL);
  void LowerPATCHABLE_EVENT_CALL(const MachineInstr &MI, X86MCInstLower &MCIL);
  void LowerPATCHABLE_TYPED_EVENT_CALL(const MachineInstr &MI,
                                       X86MCInstLower &MCIL);

  void LowerFENTRY_CALL(const MachineInstr &MI, X86MCInstLower &MCIL);

  // Address sanitizer specific lowering for X86.
  void LowerASAN_CHECK_MEMACCESS(const MachineInstr &MI);
  void emitAsanMemaccessSymbols(Module &M);
  void emitAsanMemaccessPartial(Module &M, unsigned Reg,
                                const ASanAccessInfo &AccessInfo,
                                MCSubtargetInfo &STI);
  void emitAsanMemaccessFull(Module &M, unsigned Reg,
                             const ASanAccessInfo &AccessInfo,
                             MCSubtargetInfo &STI);
  void emitAsanReportError(Module &M, unsigned Reg,
                           const ASanAccessInfo &AccessInfo,
                           MCSubtargetInfo &STI);

  typedef std::tuple<unsigned /*Reg*/, uint32_t /*AccessInfo*/>
      AsanMemaccessTuple;
  std::map<AsanMemaccessTuple, MCSymbol *> AsanMemaccessSymbols;

  // Choose between emitting .seh_ directives and .cv_fpo_ directives.
  void EmitSEHInstruction(const MachineInstr *MI);

  void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O) override;
  void PrintOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
  void PrintModifiedOperand(const MachineInstr *MI, unsigned OpNo,
                            raw_ostream &O, const char *Modifier);
  void PrintPCRelImm(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
  void PrintLeaMemReference(const MachineInstr *MI, unsigned OpNo,
                            raw_ostream &O, const char *Modifier);
  void PrintMemReference(const MachineInstr *MI, unsigned OpNo, raw_ostream &O,
                         const char *Modifier);
  void PrintIntelMemReference(const MachineInstr *MI, unsigned OpNo,
                              raw_ostream &O, const char *Modifier);

public:
  X86AsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer);

  StringRef getPassName() const override {
    return "X86 Assembly Printer";
  }

  const X86Subtarget &getSubtarget() const { return *Subtarget; }

  void emitStartOfAsmFile(Module &M) override;

  void emitEndOfAsmFile(Module &M) override;

  void emitInstruction(const MachineInstr *MI) override;

  void emitBasicBlockEnd(const MachineBasicBlock &MBB) override {
    AsmPrinter::emitBasicBlockEnd(MBB);
    SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());
  }

  bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
                       const char *ExtraCode, raw_ostream &O) override;
  bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
                             const char *ExtraCode, raw_ostream &O) override;

  bool doInitialization(Module &M) override {
    SMShadowTracker.reset(0);
    SM.reset();
    FM.reset();
    return AsmPrinter::doInitialization(M);
  }

  bool runOnMachineFunction(MachineFunction &MF) override;
  void emitFunctionBodyStart() override;
  void emitFunctionBodyEnd() override;
};

} // end namespace llvm

#endif
