//===-- SystemZAsmPrinter.h - SystemZ LLVM assembly printer ----*- 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_SYSTEMZ_SYSTEMZASMPRINTER_H
#define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZASMPRINTER_H

#include "MCTargetDesc/SystemZTargetStreamer.h"
#include "SystemZMCInstLower.h"
#include "SystemZTargetMachine.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/StackMaps.h"
#include "llvm/MC/MCInstBuilder.h"
#include "llvm/Support/Compiler.h"

namespace llvm {
class MCStreamer;
class MachineInstr;
class Module;
class raw_ostream;

class LLVM_LIBRARY_VISIBILITY SystemZAsmPrinter : public AsmPrinter {
public:
  static char ID;

private:
  MCSymbol *PPA2Sym;

  SystemZTargetStreamer *getTargetStreamer() {
    MCTargetStreamer *TS = OutStreamer->getTargetStreamer();
    assert(TS && "do not have a target streamer");
    return static_cast<SystemZTargetStreamer *>(TS);
  }

  /// Call type information for XPLINK.
  enum class CallType {
    BASR76 = 0,   // b'x000' == BASR  r7,r6
    BRAS7 = 1,    // b'x001' == BRAS  r7,ep
    RESVD_2 = 2,  // b'x010'
    BRASL7 = 3,   // b'x011' == BRASL r7,ep
    RESVD_4 = 4,  // b'x100'
    RESVD_5 = 5,  // b'x101'
    BALR1415 = 6, // b'x110' == BALR  r14,r15
    BASR33 = 7,   // b'x111' == BASR  r3,r3
  };

  // The Associated Data Area (ADA) contains descriptors which help locating
  // external symbols. For each symbol and type, the displacement into the ADA
  // is stored.
  class AssociatedDataAreaTable {
  public:
    using DisplacementTable =
        MapVector<std::pair<const MCSymbol *, unsigned>, uint32_t>;

  private:
    const uint64_t PointerSize;

    /// The mapping of name/slot type pairs to displacements.
    DisplacementTable Displacements;

    /// The next available displacement value. Incremented when new entries into
    /// the ADA are created.
    uint32_t NextDisplacement = 0;

  public:
    AssociatedDataAreaTable(uint64_t PointerSize) : PointerSize(PointerSize) {}

    /// @brief Add a function descriptor to the ADA.
    /// @param MI Pointer to an ADA_ENTRY instruction.
    /// @return The displacement of the descriptor into the ADA.
    uint32_t insert(const MachineOperand MO);

    /// @brief Get the displacement into associated data area (ADA) for a name.
    /// If no  displacement is already associated with the name, assign one and
    /// return it.
    /// @param Sym The symbol for which the displacement should be returned.
    /// @param SlotKind The ADA type.
    /// @return The displacement of the descriptor into the ADA.
    uint32_t insert(const MCSymbol *Sym, unsigned SlotKind);

    /// Get the table of GOFF displacements.  This is 'const' since it should
    /// never be modified by anything except the APIs on this class.
    const DisplacementTable &getTable() const { return Displacements; }

    uint32_t getNextDisplacement() const { return NextDisplacement; }
  };

  AssociatedDataAreaTable ADATable;

  // Record a list of GlobalAlias associated with a GlobalObject.
  // This is used for z/OS's extra-label-at-definition aliasing strategy.
  // This is similar to what is done for AIX.
  DenseMap<const GlobalObject *, SmallVector<const GlobalAlias *, 1>>
      GOAliasMap;

  struct PPA1Info {
    StringRef Name;
    MCSymbol *FnEnd = nullptr;    // Symbol marking function end.
    MCSymbol *PPA1 = nullptr;     // Symbol marking PPA1 begin.
    MCSymbol *EPMarker = nullptr; // Symbol marking entry point.
    MCSymbol *PersonalityRoutine = nullptr;
    MCSymbol *GCCEH = nullptr;
    int64_t OffsetFPR = 0;
    int64_t OffsetVR = 0;
    uint64_t CallFrameSize = 0;
    unsigned SizeOfFnParams = 0;
    uint32_t FrameAndFPROffset;
    uint32_t FrameAndVROffset;
    uint16_t SavedGPRMask = 0;
    uint16_t SavedFPRMask = 0;
    uint8_t SavedVRMask = 0;
    uint8_t FrameReg = 0;
    uint8_t AllocaReg = 0;
    bool IsVarArg = false;
    bool HasStackProtector = false;
  };
  SmallVector<PPA1Info, 0> DeferredPPA1;

  void calculatePPA1();
  void emitPPA1(PPA1Info &Info);
  void emitPPA2(Module &M);
  void emitADASection();
  void emitIDRLSection(Module &M);

public:
  SystemZAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
      : AsmPrinter(TM, std::move(Streamer), ID), PPA2Sym(nullptr),
        ADATable(TM.getPointerSize(0)) {}

  // Override AsmPrinter.
  StringRef getPassName() const override { return "SystemZ Assembly Printer"; }
  void emitInstruction(const MachineInstr *MI) override;
  void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) override;
  void emitXXStructorList(const DataLayout &DL, const Constant *List,
                          bool IsCtor) override;
  void emitEndOfAsmFile(Module &M) override;
  bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
                       const char *ExtraCode, raw_ostream &OS) override;
  bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
                             const char *ExtraCode, raw_ostream &OS) override;

  bool runOnMachineFunction(MachineFunction &MF) override {
    AsmPrinter::runOnMachineFunction(MF);

    // Emit the XRay table for this function.
    emitXRayTable();

    return false;
  }

  bool doInitialization(Module &M) override;
  void emitFunctionEntryLabel() override;
  void emitFunctionBodyEnd() override;
  void emitStartOfAsmFile(Module &M) override;
  void emitGlobalAlias(const Module &M, const GlobalAlias &GA) override;
  const MCExpr *lowerConstant(const Constant *CV,
                              const Constant *BaseCV = nullptr,
                              uint64_t Offset = 0) override;

private:
  void emitCallInformation(CallType CT);
  void LowerFENTRY_CALL(const MachineInstr &MI, SystemZMCInstLower &MCIL);
  void LowerSTACKMAP(const MachineInstr &MI);
  void LowerPATCHPOINT(const MachineInstr &MI, SystemZMCInstLower &Lower);
  void LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI,
                                     SystemZMCInstLower &Lower);
  void LowerPATCHABLE_RET(const MachineInstr &MI, SystemZMCInstLower &Lower);
  void emitAttributes(Module &M);
};
} // end namespace llvm

#endif
