//===-- R600InstrInfo.h - R600 Instruction Info Interface -------*- 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
//
//===----------------------------------------------------------------------===//
//
/// \file
/// Interface definition for R600InstrInfo
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_AMDGPU_R600INSTRINFO_H
#define LLVM_LIB_TARGET_AMDGPU_R600INSTRINFO_H

#include "R600RegisterInfo.h"
#include "llvm/CodeGen/TargetInstrInfo.h"

#define GET_INSTRINFO_HEADER
#include "R600GenInstrInfo.inc"

namespace llvm {

namespace R600InstrFlags {
enum : uint64_t {
 REGISTER_STORE = UINT64_C(1) << 62,
 REGISTER_LOAD = UINT64_C(1) << 63
};
}

class AMDGPUTargetMachine;
class DFAPacketizer;
class MachineFunction;
class MachineInstr;
class MachineInstrBuilder;
class R600Subtarget;

class R600InstrInfo final : public R600GenInstrInfo {
private:
  const R600RegisterInfo RI;
  const R600Subtarget &ST;

  std::vector<std::pair<int, unsigned>>
  ExtractSrcs(MachineInstr &MI, const DenseMap<unsigned, unsigned> &PV,
              unsigned &ConstCount) const;

  MachineInstrBuilder buildIndirectRead(MachineBasicBlock *MBB,
                                        MachineBasicBlock::iterator I,
                                        unsigned ValueReg, unsigned Address,
                                        unsigned OffsetReg,
                                        unsigned AddrChan) const;

  MachineInstrBuilder buildIndirectWrite(MachineBasicBlock *MBB,
                                         MachineBasicBlock::iterator I,
                                         unsigned ValueReg, unsigned Address,
                                         unsigned OffsetReg,
                                         unsigned AddrChan) const;
public:
  enum BankSwizzle {
    ALU_VEC_012_SCL_210 = 0,
    ALU_VEC_021_SCL_122,
    ALU_VEC_120_SCL_212,
    ALU_VEC_102_SCL_221,
    ALU_VEC_201,
    ALU_VEC_210
  };

  explicit R600InstrInfo(const R600Subtarget &);

  const R600RegisterInfo &getRegisterInfo() const {
    return RI;
  }

  void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
                   const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
                   bool KillSrc) const override;
  bool isLegalToSplitMBBAt(MachineBasicBlock &MBB,
                           MachineBasicBlock::iterator MBBI) const override;

  bool isReductionOp(unsigned opcode) const;
  bool isCubeOp(unsigned opcode) const;

  /// \returns true if this \p Opcode represents an ALU instruction.
  bool isALUInstr(unsigned Opcode) const;
  bool hasInstrModifiers(unsigned Opcode) const;
  bool isLDSInstr(unsigned Opcode) const;
  bool isLDSRetInstr(unsigned Opcode) const;

  /// \returns true if this \p Opcode represents an ALU instruction or an
  /// instruction that will be lowered in ExpandSpecialInstrs Pass.
  bool canBeConsideredALU(const MachineInstr &MI) const;

  bool isTransOnly(unsigned Opcode) const;
  bool isTransOnly(const MachineInstr &MI) const;
  bool isVectorOnly(unsigned Opcode) const;
  bool isVectorOnly(const MachineInstr &MI) const;
  bool isExport(unsigned Opcode) const;

  bool usesVertexCache(unsigned Opcode) const;
  bool usesVertexCache(const MachineInstr &MI) const;
  bool usesTextureCache(unsigned Opcode) const;
  bool usesTextureCache(const MachineInstr &MI) const;

  bool mustBeLastInClause(unsigned Opcode) const;
  bool usesAddressRegister(MachineInstr &MI) const;
  bool definesAddressRegister(MachineInstr &MI) const;
  bool readsLDSSrcReg(const MachineInstr &MI) const;

  /// \returns The operand Index for the Sel operand given an index to one
  /// of the instruction's src operands.
  int getSelIdx(unsigned Opcode, unsigned SrcIdx) const;

  /// \returns a pair for each src of an ALU instructions.
  /// The first member of a pair is the register id.
  /// If register is ALU_CONST, second member is SEL.
  /// If register is ALU_LITERAL, second member is IMM.
  /// Otherwise, second member value is undefined.
  SmallVector<std::pair<MachineOperand *, int64_t>, 3>
  getSrcs(MachineInstr &MI) const;

  unsigned  isLegalUpTo(
    const std::vector<std::vector<std::pair<int, unsigned> > > &IGSrcs,
    const std::vector<R600InstrInfo::BankSwizzle> &Swz,
    const std::vector<std::pair<int, unsigned> > &TransSrcs,
    R600InstrInfo::BankSwizzle TransSwz) const;

  bool FindSwizzleForVectorSlot(
    const std::vector<std::vector<std::pair<int, unsigned> > > &IGSrcs,
    std::vector<R600InstrInfo::BankSwizzle> &SwzCandidate,
    const std::vector<std::pair<int, unsigned> > &TransSrcs,
    R600InstrInfo::BankSwizzle TransSwz) const;

  /// Given the order VEC_012 < VEC_021 < VEC_120 < VEC_102 < VEC_201 < VEC_210
  /// returns true and the first (in lexical order) BankSwizzle affectation
  /// starting from the one already provided in the Instruction Group MIs that
  /// fits Read Port limitations in BS if available. Otherwise returns false
  /// and undefined content in BS.
  /// isLastAluTrans should be set if the last Alu of MIs will be executed on
  /// Trans ALU. In this case, ValidTSwizzle returns the BankSwizzle value to
  /// apply to the last instruction.
  /// PV holds GPR to PV registers in the Instruction Group MIs.
  bool fitsReadPortLimitations(const std::vector<MachineInstr *> &MIs,
                               const DenseMap<unsigned, unsigned> &PV,
                               std::vector<BankSwizzle> &BS,
                               bool isLastAluTrans) const;

  /// An instruction group can only access 2 channel pair (either [XY] or [ZW])
  /// from KCache bank on R700+. This function check if MI set in input meet
  /// this limitations
  bool fitsConstReadLimitations(const std::vector<MachineInstr *> &) const;
  /// Same but using const index set instead of MI set.
  bool fitsConstReadLimitations(const std::vector<unsigned>&) const;

  /// Vector instructions are instructions that must fill all
  /// instruction slots within an instruction group.
  bool isVector(const MachineInstr &MI) const;

  bool isMov(unsigned Opcode) const;

  DFAPacketizer *
  CreateTargetScheduleState(const TargetSubtargetInfo &) const override;

  bool reverseBranchCondition(
    SmallVectorImpl<MachineOperand> &Cond) const override;

  bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
                     MachineBasicBlock *&FBB,
                     SmallVectorImpl<MachineOperand> &Cond,
                     bool AllowModify) const override;

  unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
                        MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
                        const DebugLoc &DL,
                        int *BytesAdded = nullptr) const override;

  unsigned removeBranch(MachineBasicBlock &MBB,
                        int *BytesRemvoed = nullptr) const override;

  bool isPredicated(const MachineInstr &MI) const override;

  bool isPredicable(const MachineInstr &MI) const override;

  bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,
                                 BranchProbability Probability) const override;

  bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,
                           unsigned ExtraPredCycles,
                           BranchProbability Probability) const override ;

  bool isProfitableToIfCvt(MachineBasicBlock &TMBB,
                           unsigned NumTCycles, unsigned ExtraTCycles,
                           MachineBasicBlock &FMBB,
                           unsigned NumFCycles, unsigned ExtraFCycles,
                           BranchProbability Probability) const override;

  bool DefinesPredicate(MachineInstr &MI,
                        std::vector<MachineOperand> &Pred) const override;

  bool isProfitableToUnpredicate(MachineBasicBlock &TMBB,
                                 MachineBasicBlock &FMBB) const override;

  bool PredicateInstruction(MachineInstr &MI,
                            ArrayRef<MachineOperand> Pred) const override;

  unsigned int getPredicationCost(const MachineInstr &) const override;

  unsigned int getInstrLatency(const InstrItineraryData *ItinData,
                               const MachineInstr &MI,
                               unsigned *PredCost = nullptr) const override;

  bool expandPostRAPseudo(MachineInstr &MI) const override;

  /// Reserve the registers that may be accesed using indirect addressing.
  void reserveIndirectRegisters(BitVector &Reserved,
                                const MachineFunction &MF,
                                const R600RegisterInfo &TRI) const;

  /// Calculate the "Indirect Address" for the given \p RegIndex and
  /// \p Channel
  ///
  /// We model indirect addressing using a virtual address space that can be
  /// accesed with loads and stores.  The "Indirect Address" is the memory
  /// address in this virtual address space that maps to the given \p RegIndex
  /// and \p Channel.
  unsigned calculateIndirectAddress(unsigned RegIndex, unsigned Channel) const;


  /// \returns The register class to be used for loading and storing values
  /// from an "Indirect Address" .
  const TargetRegisterClass *getIndirectAddrRegClass() const;

  /// \returns the smallest register index that will be accessed by an indirect
  /// read or write or -1 if indirect addressing is not used by this program.
  int getIndirectIndexBegin(const MachineFunction &MF) const;

  /// \returns the largest register index that will be accessed by an indirect
  /// read or write or -1 if indirect addressing is not used by this program.
  int getIndirectIndexEnd(const MachineFunction &MF) const;

  /// Build instruction(s) for an indirect register write.
  ///
  /// \returns The instruction that performs the indirect register write
  MachineInstrBuilder buildIndirectWrite(MachineBasicBlock *MBB,
                                         MachineBasicBlock::iterator I,
                                         unsigned ValueReg, unsigned Address,
                                         unsigned OffsetReg) const;

  /// Build instruction(s) for an indirect register read.
  ///
  /// \returns The instruction that performs the indirect register read
  MachineInstrBuilder buildIndirectRead(MachineBasicBlock *MBB,
                                        MachineBasicBlock::iterator I,
                                        unsigned ValueReg, unsigned Address,
                                        unsigned OffsetReg) const;

  unsigned getMaxAlusPerClause() const;

  /// buildDefaultInstruction - This function returns a MachineInstr with all
  /// the instruction modifiers initialized to their default values.  You can
  /// use this function to avoid manually specifying each instruction modifier
  /// operand when building a new instruction.
  ///
  /// \returns a MachineInstr with all the instruction modifiers initialized
  /// to their default values.
  MachineInstrBuilder buildDefaultInstruction(MachineBasicBlock &MBB,
                                              MachineBasicBlock::iterator I,
                                              unsigned Opcode,
                                              unsigned DstReg,
                                              unsigned Src0Reg,
                                              unsigned Src1Reg = 0) const;

  MachineInstr *buildSlotOfVectorInstruction(MachineBasicBlock &MBB,
                                             MachineInstr *MI,
                                             unsigned Slot,
                                             unsigned DstReg) const;

  MachineInstr *buildMovImm(MachineBasicBlock &BB,
                            MachineBasicBlock::iterator I,
                            unsigned DstReg,
                            uint64_t Imm) const;

  MachineInstr *buildMovInstr(MachineBasicBlock *MBB,
                              MachineBasicBlock::iterator I,
                              unsigned DstReg, unsigned SrcReg) const;

  /// Get the index of Op in the MachineInstr.
  ///
  /// \returns -1 if the Instruction does not contain the specified \p Op.
  int getOperandIdx(const MachineInstr &MI, unsigned Op) const;

  /// Get the index of \p Op for the given Opcode.
  ///
  /// \returns -1 if the Instruction does not contain the specified \p Op.
  int getOperandIdx(unsigned Opcode, unsigned Op) const;

  /// Helper function for setting instruction flag values.
  void setImmOperand(MachineInstr &MI, unsigned Op, int64_t Imm) const;

  ///Add one of the MO_FLAG* flags to the specified \p Operand.
  void addFlag(MachineInstr &MI, unsigned Operand, unsigned Flag) const;

  ///Determine if the specified \p Flag is set on this \p Operand.
  bool isFlagSet(const MachineInstr &MI, unsigned Operand, unsigned Flag) const;

  /// \param SrcIdx The register source to set the flag on (e.g src0, src1, src2)
  /// \param Flag The flag being set.
  ///
  /// \returns the operand containing the flags for this instruction.
  MachineOperand &getFlagOp(MachineInstr &MI, unsigned SrcIdx = 0,
                            unsigned Flag = 0) const;

  /// Clear the specified flag on the instruction.
  void clearFlag(MachineInstr &MI, unsigned Operand, unsigned Flag) const;

  // Helper functions that check the opcode for status information
  bool isRegisterStore(const MachineInstr &MI) const {
    return get(MI.getOpcode()).TSFlags & R600InstrFlags::REGISTER_STORE;
  }

  bool isRegisterLoad(const MachineInstr &MI) const {
    return get(MI.getOpcode()).TSFlags & R600InstrFlags::REGISTER_LOAD;
  }

  unsigned getAddressSpaceForPseudoSourceKind(
      unsigned Kind) const override;
};

namespace R600 {

int getLDSNoRetOp(uint16_t Opcode);

} //End namespace AMDGPU

} // End llvm namespace

#endif
