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