1249259Sdim//===-- R600InstrInfo.h - R600 Instruction Info Interface -------*- C++ -*-===// 2249259Sdim// 3249259Sdim// The LLVM Compiler Infrastructure 4249259Sdim// 5249259Sdim// This file is distributed under the University of Illinois Open Source 6249259Sdim// License. See LICENSE.TXT for details. 7249259Sdim// 8249259Sdim//===----------------------------------------------------------------------===// 9249259Sdim// 10249259Sdim/// \file 11249259Sdim/// \brief Interface definition for R600InstrInfo 12249259Sdim// 13249259Sdim//===----------------------------------------------------------------------===// 14249259Sdim 15249259Sdim#ifndef R600INSTRUCTIONINFO_H_ 16249259Sdim#define R600INSTRUCTIONINFO_H_ 17249259Sdim 18249259Sdim#include "AMDGPUInstrInfo.h" 19249259Sdim#include "R600Defines.h" 20249259Sdim#include "R600RegisterInfo.h" 21249259Sdim#include <map> 22249259Sdim 23249259Sdimnamespace llvm { 24249259Sdim 25249259Sdim class AMDGPUTargetMachine; 26249259Sdim class DFAPacketizer; 27249259Sdim class ScheduleDAG; 28249259Sdim class MachineFunction; 29249259Sdim class MachineInstr; 30249259Sdim class MachineInstrBuilder; 31249259Sdim 32249259Sdim class R600InstrInfo : public AMDGPUInstrInfo { 33249259Sdim private: 34249259Sdim const R600RegisterInfo RI; 35251662Sdim const AMDGPUSubtarget &ST; 36249259Sdim 37249259Sdim int getBranchInstr(const MachineOperand &op) const; 38263508Sdim std::vector<std::pair<int, unsigned> > 39263508Sdim ExtractSrcs(MachineInstr *MI, const DenseMap<unsigned, unsigned> &PV, unsigned &ConstCount) const; 40249259Sdim 41249259Sdim public: 42263508Sdim enum BankSwizzle { 43263508Sdim ALU_VEC_012_SCL_210 = 0, 44263508Sdim ALU_VEC_021_SCL_122, 45263508Sdim ALU_VEC_120_SCL_212, 46263508Sdim ALU_VEC_102_SCL_221, 47263508Sdim ALU_VEC_201, 48263508Sdim ALU_VEC_210 49263508Sdim }; 50263508Sdim 51249259Sdim explicit R600InstrInfo(AMDGPUTargetMachine &tm); 52249259Sdim 53249259Sdim const R600RegisterInfo &getRegisterInfo() const; 54249259Sdim virtual void copyPhysReg(MachineBasicBlock &MBB, 55249259Sdim MachineBasicBlock::iterator MI, DebugLoc DL, 56249259Sdim unsigned DestReg, unsigned SrcReg, 57249259Sdim bool KillSrc) const; 58263508Sdim bool isLegalToSplitMBBAt(MachineBasicBlock &MBB, 59263508Sdim MachineBasicBlock::iterator MBBI) const; 60249259Sdim 61249259Sdim bool isTrig(const MachineInstr &MI) const; 62249259Sdim bool isPlaceHolderOpcode(unsigned opcode) const; 63249259Sdim bool isReductionOp(unsigned opcode) const; 64249259Sdim bool isCubeOp(unsigned opcode) const; 65249259Sdim 66249259Sdim /// \returns true if this \p Opcode represents an ALU instruction. 67249259Sdim bool isALUInstr(unsigned Opcode) const; 68263508Sdim bool hasInstrModifiers(unsigned Opcode) const; 69263508Sdim bool isLDSInstr(unsigned Opcode) const; 70263508Sdim bool isLDSNoRetInstr(unsigned Opcode) const; 71263508Sdim bool isLDSRetInstr(unsigned Opcode) const; 72249259Sdim 73263508Sdim /// \returns true if this \p Opcode represents an ALU instruction or an 74263508Sdim /// instruction that will be lowered in ExpandSpecialInstrs Pass. 75263508Sdim bool canBeConsideredALU(const MachineInstr *MI) const; 76263508Sdim 77251662Sdim bool isTransOnly(unsigned Opcode) const; 78251662Sdim bool isTransOnly(const MachineInstr *MI) const; 79263508Sdim bool isVectorOnly(unsigned Opcode) const; 80263508Sdim bool isVectorOnly(const MachineInstr *MI) const; 81263508Sdim bool isExport(unsigned Opcode) const; 82251662Sdim 83251662Sdim bool usesVertexCache(unsigned Opcode) const; 84251662Sdim bool usesVertexCache(const MachineInstr *MI) const; 85251662Sdim bool usesTextureCache(unsigned Opcode) const; 86251662Sdim bool usesTextureCache(const MachineInstr *MI) const; 87251662Sdim 88263508Sdim bool mustBeLastInClause(unsigned Opcode) const; 89263508Sdim bool usesAddressRegister(MachineInstr *MI) const; 90263508Sdim bool definesAddressRegister(MachineInstr *MI) const; 91263508Sdim bool readsLDSSrcReg(const MachineInstr *MI) const; 92263508Sdim 93263508Sdim /// \returns The operand index for the given source number. Legal values 94263508Sdim /// for SrcNum are 0, 1, and 2. 95263508Sdim int getSrcIdx(unsigned Opcode, unsigned SrcNum) const; 96263508Sdim /// \returns The operand Index for the Sel operand given an index to one 97263508Sdim /// of the instruction's src operands. 98263508Sdim int getSelIdx(unsigned Opcode, unsigned SrcIdx) const; 99263508Sdim 100263508Sdim /// \returns a pair for each src of an ALU instructions. 101263508Sdim /// The first member of a pair is the register id. 102263508Sdim /// If register is ALU_CONST, second member is SEL. 103263508Sdim /// If register is ALU_LITERAL, second member is IMM. 104263508Sdim /// Otherwise, second member value is undefined. 105263508Sdim SmallVector<std::pair<MachineOperand *, int64_t>, 3> 106263508Sdim getSrcs(MachineInstr *MI) const; 107263508Sdim 108263508Sdim unsigned isLegalUpTo( 109263508Sdim const std::vector<std::vector<std::pair<int, unsigned> > > &IGSrcs, 110263508Sdim const std::vector<R600InstrInfo::BankSwizzle> &Swz, 111263508Sdim const std::vector<std::pair<int, unsigned> > &TransSrcs, 112263508Sdim R600InstrInfo::BankSwizzle TransSwz) const; 113263508Sdim 114263508Sdim bool FindSwizzleForVectorSlot( 115263508Sdim const std::vector<std::vector<std::pair<int, unsigned> > > &IGSrcs, 116263508Sdim std::vector<R600InstrInfo::BankSwizzle> &SwzCandidate, 117263508Sdim const std::vector<std::pair<int, unsigned> > &TransSrcs, 118263508Sdim R600InstrInfo::BankSwizzle TransSwz) const; 119263508Sdim 120263508Sdim /// Given the order VEC_012 < VEC_021 < VEC_120 < VEC_102 < VEC_201 < VEC_210 121263508Sdim /// returns true and the first (in lexical order) BankSwizzle affectation 122263508Sdim /// starting from the one already provided in the Instruction Group MIs that 123263508Sdim /// fits Read Port limitations in BS if available. Otherwise returns false 124263508Sdim /// and undefined content in BS. 125263508Sdim /// isLastAluTrans should be set if the last Alu of MIs will be executed on 126263508Sdim /// Trans ALU. In this case, ValidTSwizzle returns the BankSwizzle value to 127263508Sdim /// apply to the last instruction. 128263508Sdim /// PV holds GPR to PV registers in the Instruction Group MIs. 129263508Sdim bool fitsReadPortLimitations(const std::vector<MachineInstr *> &MIs, 130263508Sdim const DenseMap<unsigned, unsigned> &PV, 131263508Sdim std::vector<BankSwizzle> &BS, 132263508Sdim bool isLastAluTrans) const; 133263508Sdim 134263508Sdim /// An instruction group can only access 2 channel pair (either [XY] or [ZW]) 135263508Sdim /// from KCache bank on R700+. This function check if MI set in input meet 136263508Sdim /// this limitations 137263508Sdim bool fitsConstReadLimitations(const std::vector<MachineInstr *> &) const; 138263508Sdim /// Same but using const index set instead of MI set. 139249259Sdim bool fitsConstReadLimitations(const std::vector<unsigned>&) const; 140249259Sdim 141249259Sdim /// \breif Vector instructions are instructions that must fill all 142249259Sdim /// instruction slots within an instruction group. 143249259Sdim bool isVector(const MachineInstr &MI) const; 144249259Sdim 145249259Sdim virtual unsigned getIEQOpcode() const; 146249259Sdim virtual bool isMov(unsigned Opcode) const; 147249259Sdim 148249259Sdim DFAPacketizer *CreateTargetScheduleState(const TargetMachine *TM, 149249259Sdim const ScheduleDAG *DAG) const; 150249259Sdim 151249259Sdim bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const; 152249259Sdim 153249259Sdim bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, 154249259Sdim SmallVectorImpl<MachineOperand> &Cond, bool AllowModify) const; 155249259Sdim 156249259Sdim unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, const SmallVectorImpl<MachineOperand> &Cond, DebugLoc DL) const; 157249259Sdim 158249259Sdim unsigned RemoveBranch(MachineBasicBlock &MBB) const; 159249259Sdim 160249259Sdim bool isPredicated(const MachineInstr *MI) const; 161249259Sdim 162249259Sdim bool isPredicable(MachineInstr *MI) const; 163249259Sdim 164249259Sdim bool 165249259Sdim isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCyles, 166249259Sdim const BranchProbability &Probability) const; 167249259Sdim 168249259Sdim bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCyles, 169249259Sdim unsigned ExtraPredCycles, 170249259Sdim const BranchProbability &Probability) const ; 171249259Sdim 172249259Sdim bool 173249259Sdim isProfitableToIfCvt(MachineBasicBlock &TMBB, 174249259Sdim unsigned NumTCycles, unsigned ExtraTCycles, 175249259Sdim MachineBasicBlock &FMBB, 176249259Sdim unsigned NumFCycles, unsigned ExtraFCycles, 177249259Sdim const BranchProbability &Probability) const; 178249259Sdim 179249259Sdim bool DefinesPredicate(MachineInstr *MI, 180249259Sdim std::vector<MachineOperand> &Pred) const; 181249259Sdim 182249259Sdim bool SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1, 183249259Sdim const SmallVectorImpl<MachineOperand> &Pred2) const; 184249259Sdim 185249259Sdim bool isProfitableToUnpredicate(MachineBasicBlock &TMBB, 186249259Sdim MachineBasicBlock &FMBB) const; 187249259Sdim 188249259Sdim bool PredicateInstruction(MachineInstr *MI, 189249259Sdim const SmallVectorImpl<MachineOperand> &Pred) const; 190249259Sdim 191263508Sdim unsigned int getPredicationCost(const MachineInstr *) const; 192263508Sdim 193249259Sdim unsigned int getInstrLatency(const InstrItineraryData *ItinData, 194249259Sdim const MachineInstr *MI, 195249259Sdim unsigned *PredCost = 0) const; 196249259Sdim 197249259Sdim virtual int getInstrLatency(const InstrItineraryData *ItinData, 198249259Sdim SDNode *Node) const { return 1;} 199249259Sdim 200263508Sdim /// \brief Reserve the registers that may be accesed using indirect addressing. 201263508Sdim void reserveIndirectRegisters(BitVector &Reserved, 202263508Sdim const MachineFunction &MF) const; 203249259Sdim 204249259Sdim virtual unsigned calculateIndirectAddress(unsigned RegIndex, 205249259Sdim unsigned Channel) const; 206249259Sdim 207263508Sdim virtual const TargetRegisterClass *getIndirectAddrRegClass() const; 208249259Sdim 209249259Sdim virtual MachineInstrBuilder buildIndirectWrite(MachineBasicBlock *MBB, 210249259Sdim MachineBasicBlock::iterator I, 211249259Sdim unsigned ValueReg, unsigned Address, 212249259Sdim unsigned OffsetReg) const; 213249259Sdim 214249259Sdim virtual MachineInstrBuilder buildIndirectRead(MachineBasicBlock *MBB, 215249259Sdim MachineBasicBlock::iterator I, 216249259Sdim unsigned ValueReg, unsigned Address, 217249259Sdim unsigned OffsetReg) const; 218249259Sdim 219249259Sdim unsigned getMaxAlusPerClause() const; 220249259Sdim 221249259Sdim ///buildDefaultInstruction - This function returns a MachineInstr with 222249259Sdim /// all the instruction modifiers initialized to their default values. 223249259Sdim /// You can use this function to avoid manually specifying each instruction 224249259Sdim /// modifier operand when building a new instruction. 225249259Sdim /// 226249259Sdim /// \returns a MachineInstr with all the instruction modifiers initialized 227249259Sdim /// to their default values. 228249259Sdim MachineInstrBuilder buildDefaultInstruction(MachineBasicBlock &MBB, 229249259Sdim MachineBasicBlock::iterator I, 230249259Sdim unsigned Opcode, 231249259Sdim unsigned DstReg, 232249259Sdim unsigned Src0Reg, 233249259Sdim unsigned Src1Reg = 0) const; 234249259Sdim 235263508Sdim MachineInstr *buildSlotOfVectorInstruction(MachineBasicBlock &MBB, 236263508Sdim MachineInstr *MI, 237263508Sdim unsigned Slot, 238263508Sdim unsigned DstReg) const; 239263508Sdim 240249259Sdim MachineInstr *buildMovImm(MachineBasicBlock &BB, 241249259Sdim MachineBasicBlock::iterator I, 242249259Sdim unsigned DstReg, 243249259Sdim uint64_t Imm) const; 244249259Sdim 245263508Sdim MachineInstr *buildMovInstr(MachineBasicBlock *MBB, 246263508Sdim MachineBasicBlock::iterator I, 247263508Sdim unsigned DstReg, unsigned SrcReg) const; 248263508Sdim 249249259Sdim /// \brief Get the index of Op in the MachineInstr. 250249259Sdim /// 251249259Sdim /// \returns -1 if the Instruction does not contain the specified \p Op. 252263508Sdim int getOperandIdx(const MachineInstr &MI, unsigned Op) const; 253249259Sdim 254249259Sdim /// \brief Get the index of \p Op for the given Opcode. 255249259Sdim /// 256249259Sdim /// \returns -1 if the Instruction does not contain the specified \p Op. 257263508Sdim int getOperandIdx(unsigned Opcode, unsigned Op) const; 258249259Sdim 259249259Sdim /// \brief Helper function for setting instruction flag values. 260263508Sdim void setImmOperand(MachineInstr *MI, unsigned Op, int64_t Imm) const; 261249259Sdim 262249259Sdim /// \returns true if this instruction has an operand for storing target flags. 263249259Sdim bool hasFlagOperand(const MachineInstr &MI) const; 264249259Sdim 265249259Sdim ///\brief Add one of the MO_FLAG* flags to the specified \p Operand. 266249259Sdim void addFlag(MachineInstr *MI, unsigned Operand, unsigned Flag) const; 267249259Sdim 268249259Sdim ///\brief Determine if the specified \p Flag is set on this \p Operand. 269249259Sdim bool isFlagSet(const MachineInstr &MI, unsigned Operand, unsigned Flag) const; 270249259Sdim 271249259Sdim /// \param SrcIdx The register source to set the flag on (e.g src0, src1, src2) 272249259Sdim /// \param Flag The flag being set. 273249259Sdim /// 274249259Sdim /// \returns the operand containing the flags for this instruction. 275249259Sdim MachineOperand &getFlagOp(MachineInstr *MI, unsigned SrcIdx = 0, 276249259Sdim unsigned Flag = 0) const; 277249259Sdim 278249259Sdim /// \brief Clear the specified flag on the instruction. 279249259Sdim void clearFlag(MachineInstr *MI, unsigned Operand, unsigned Flag) const; 280249259Sdim}; 281249259Sdim 282263508Sdimnamespace AMDGPU { 283263508Sdim 284263508Sdimint getLDSNoRetOp(uint16_t Opcode); 285263508Sdim 286263508Sdim} //End namespace AMDGPU 287263508Sdim 288249259Sdim} // End llvm namespace 289249259Sdim 290249259Sdim#endif // R600INSTRINFO_H_ 291