xref: /aosp_15_r20/external/llvm/lib/Target/AMDGPU/R600InstrInfo.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- R600InstrInfo.cpp - R600 Instruction Information ------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker /// \file
11*9880d681SAndroid Build Coastguard Worker /// \brief R600 Implementation of TargetInstrInfo.
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker 
15*9880d681SAndroid Build Coastguard Worker #include "R600InstrInfo.h"
16*9880d681SAndroid Build Coastguard Worker #include "AMDGPU.h"
17*9880d681SAndroid Build Coastguard Worker #include "AMDGPUSubtarget.h"
18*9880d681SAndroid Build Coastguard Worker #include "AMDGPUTargetMachine.h"
19*9880d681SAndroid Build Coastguard Worker #include "R600Defines.h"
20*9880d681SAndroid Build Coastguard Worker #include "R600MachineFunctionInfo.h"
21*9880d681SAndroid Build Coastguard Worker #include "R600RegisterInfo.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFrameInfo.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
25*9880d681SAndroid Build Coastguard Worker 
26*9880d681SAndroid Build Coastguard Worker using namespace llvm;
27*9880d681SAndroid Build Coastguard Worker 
28*9880d681SAndroid Build Coastguard Worker #define GET_INSTRINFO_CTOR_DTOR
29*9880d681SAndroid Build Coastguard Worker #include "AMDGPUGenDFAPacketizer.inc"
30*9880d681SAndroid Build Coastguard Worker 
R600InstrInfo(const R600Subtarget & ST)31*9880d681SAndroid Build Coastguard Worker R600InstrInfo::R600InstrInfo(const R600Subtarget &ST)
32*9880d681SAndroid Build Coastguard Worker   : AMDGPUInstrInfo(ST), RI(), ST(ST) {}
33*9880d681SAndroid Build Coastguard Worker 
isTrig(const MachineInstr & MI) const34*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::isTrig(const MachineInstr &MI) const {
35*9880d681SAndroid Build Coastguard Worker   return get(MI.getOpcode()).TSFlags & R600_InstFlag::TRIG;
36*9880d681SAndroid Build Coastguard Worker }
37*9880d681SAndroid Build Coastguard Worker 
isVector(const MachineInstr & MI) const38*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::isVector(const MachineInstr &MI) const {
39*9880d681SAndroid Build Coastguard Worker   return get(MI.getOpcode()).TSFlags & R600_InstFlag::VECTOR;
40*9880d681SAndroid Build Coastguard Worker }
41*9880d681SAndroid Build Coastguard Worker 
copyPhysReg(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,const DebugLoc & DL,unsigned DestReg,unsigned SrcReg,bool KillSrc) const42*9880d681SAndroid Build Coastguard Worker void R600InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
43*9880d681SAndroid Build Coastguard Worker                                 MachineBasicBlock::iterator MI,
44*9880d681SAndroid Build Coastguard Worker                                 const DebugLoc &DL, unsigned DestReg,
45*9880d681SAndroid Build Coastguard Worker                                 unsigned SrcReg, bool KillSrc) const {
46*9880d681SAndroid Build Coastguard Worker   unsigned VectorComponents = 0;
47*9880d681SAndroid Build Coastguard Worker   if ((AMDGPU::R600_Reg128RegClass.contains(DestReg) ||
48*9880d681SAndroid Build Coastguard Worker       AMDGPU::R600_Reg128VerticalRegClass.contains(DestReg)) &&
49*9880d681SAndroid Build Coastguard Worker       (AMDGPU::R600_Reg128RegClass.contains(SrcReg) ||
50*9880d681SAndroid Build Coastguard Worker        AMDGPU::R600_Reg128VerticalRegClass.contains(SrcReg))) {
51*9880d681SAndroid Build Coastguard Worker     VectorComponents = 4;
52*9880d681SAndroid Build Coastguard Worker   } else if((AMDGPU::R600_Reg64RegClass.contains(DestReg) ||
53*9880d681SAndroid Build Coastguard Worker             AMDGPU::R600_Reg64VerticalRegClass.contains(DestReg)) &&
54*9880d681SAndroid Build Coastguard Worker             (AMDGPU::R600_Reg64RegClass.contains(SrcReg) ||
55*9880d681SAndroid Build Coastguard Worker              AMDGPU::R600_Reg64VerticalRegClass.contains(SrcReg))) {
56*9880d681SAndroid Build Coastguard Worker     VectorComponents = 2;
57*9880d681SAndroid Build Coastguard Worker   }
58*9880d681SAndroid Build Coastguard Worker 
59*9880d681SAndroid Build Coastguard Worker   if (VectorComponents > 0) {
60*9880d681SAndroid Build Coastguard Worker     for (unsigned I = 0; I < VectorComponents; I++) {
61*9880d681SAndroid Build Coastguard Worker       unsigned SubRegIndex = RI.getSubRegFromChannel(I);
62*9880d681SAndroid Build Coastguard Worker       buildDefaultInstruction(MBB, MI, AMDGPU::MOV,
63*9880d681SAndroid Build Coastguard Worker                               RI.getSubReg(DestReg, SubRegIndex),
64*9880d681SAndroid Build Coastguard Worker                               RI.getSubReg(SrcReg, SubRegIndex))
65*9880d681SAndroid Build Coastguard Worker                               .addReg(DestReg,
66*9880d681SAndroid Build Coastguard Worker                                       RegState::Define | RegState::Implicit);
67*9880d681SAndroid Build Coastguard Worker     }
68*9880d681SAndroid Build Coastguard Worker   } else {
69*9880d681SAndroid Build Coastguard Worker     MachineInstr *NewMI = buildDefaultInstruction(MBB, MI, AMDGPU::MOV,
70*9880d681SAndroid Build Coastguard Worker                                                   DestReg, SrcReg);
71*9880d681SAndroid Build Coastguard Worker     NewMI->getOperand(getOperandIdx(*NewMI, AMDGPU::OpName::src0))
72*9880d681SAndroid Build Coastguard Worker                                     .setIsKill(KillSrc);
73*9880d681SAndroid Build Coastguard Worker   }
74*9880d681SAndroid Build Coastguard Worker }
75*9880d681SAndroid Build Coastguard Worker 
76*9880d681SAndroid Build Coastguard Worker /// \returns true if \p MBBI can be moved into a new basic.
isLegalToSplitMBBAt(MachineBasicBlock & MBB,MachineBasicBlock::iterator MBBI) const77*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::isLegalToSplitMBBAt(MachineBasicBlock &MBB,
78*9880d681SAndroid Build Coastguard Worker                                        MachineBasicBlock::iterator MBBI) const {
79*9880d681SAndroid Build Coastguard Worker   for (MachineInstr::const_mop_iterator I = MBBI->operands_begin(),
80*9880d681SAndroid Build Coastguard Worker                                         E = MBBI->operands_end(); I != E; ++I) {
81*9880d681SAndroid Build Coastguard Worker     if (I->isReg() && !TargetRegisterInfo::isVirtualRegister(I->getReg()) &&
82*9880d681SAndroid Build Coastguard Worker         I->isUse() && RI.isPhysRegLiveAcrossClauses(I->getReg()))
83*9880d681SAndroid Build Coastguard Worker       return false;
84*9880d681SAndroid Build Coastguard Worker   }
85*9880d681SAndroid Build Coastguard Worker   return true;
86*9880d681SAndroid Build Coastguard Worker }
87*9880d681SAndroid Build Coastguard Worker 
isMov(unsigned Opcode) const88*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::isMov(unsigned Opcode) const {
89*9880d681SAndroid Build Coastguard Worker   switch(Opcode) {
90*9880d681SAndroid Build Coastguard Worker   default:
91*9880d681SAndroid Build Coastguard Worker     return false;
92*9880d681SAndroid Build Coastguard Worker   case AMDGPU::MOV:
93*9880d681SAndroid Build Coastguard Worker   case AMDGPU::MOV_IMM_F32:
94*9880d681SAndroid Build Coastguard Worker   case AMDGPU::MOV_IMM_I32:
95*9880d681SAndroid Build Coastguard Worker     return true;
96*9880d681SAndroid Build Coastguard Worker   }
97*9880d681SAndroid Build Coastguard Worker }
98*9880d681SAndroid Build Coastguard Worker 
99*9880d681SAndroid Build Coastguard Worker // Some instructions act as place holders to emulate operations that the GPU
100*9880d681SAndroid Build Coastguard Worker // hardware does automatically. This function can be used to check if
101*9880d681SAndroid Build Coastguard Worker // an opcode falls into this category.
isPlaceHolderOpcode(unsigned Opcode) const102*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::isPlaceHolderOpcode(unsigned Opcode) const {
103*9880d681SAndroid Build Coastguard Worker   switch (Opcode) {
104*9880d681SAndroid Build Coastguard Worker   default: return false;
105*9880d681SAndroid Build Coastguard Worker   case AMDGPU::RETURN:
106*9880d681SAndroid Build Coastguard Worker     return true;
107*9880d681SAndroid Build Coastguard Worker   }
108*9880d681SAndroid Build Coastguard Worker }
109*9880d681SAndroid Build Coastguard Worker 
isReductionOp(unsigned Opcode) const110*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::isReductionOp(unsigned Opcode) const {
111*9880d681SAndroid Build Coastguard Worker   return false;
112*9880d681SAndroid Build Coastguard Worker }
113*9880d681SAndroid Build Coastguard Worker 
isCubeOp(unsigned Opcode) const114*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::isCubeOp(unsigned Opcode) const {
115*9880d681SAndroid Build Coastguard Worker   switch(Opcode) {
116*9880d681SAndroid Build Coastguard Worker     default: return false;
117*9880d681SAndroid Build Coastguard Worker     case AMDGPU::CUBE_r600_pseudo:
118*9880d681SAndroid Build Coastguard Worker     case AMDGPU::CUBE_r600_real:
119*9880d681SAndroid Build Coastguard Worker     case AMDGPU::CUBE_eg_pseudo:
120*9880d681SAndroid Build Coastguard Worker     case AMDGPU::CUBE_eg_real:
121*9880d681SAndroid Build Coastguard Worker       return true;
122*9880d681SAndroid Build Coastguard Worker   }
123*9880d681SAndroid Build Coastguard Worker }
124*9880d681SAndroid Build Coastguard Worker 
isALUInstr(unsigned Opcode) const125*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::isALUInstr(unsigned Opcode) const {
126*9880d681SAndroid Build Coastguard Worker   unsigned TargetFlags = get(Opcode).TSFlags;
127*9880d681SAndroid Build Coastguard Worker 
128*9880d681SAndroid Build Coastguard Worker   return (TargetFlags & R600_InstFlag::ALU_INST);
129*9880d681SAndroid Build Coastguard Worker }
130*9880d681SAndroid Build Coastguard Worker 
hasInstrModifiers(unsigned Opcode) const131*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::hasInstrModifiers(unsigned Opcode) const {
132*9880d681SAndroid Build Coastguard Worker   unsigned TargetFlags = get(Opcode).TSFlags;
133*9880d681SAndroid Build Coastguard Worker 
134*9880d681SAndroid Build Coastguard Worker   return ((TargetFlags & R600_InstFlag::OP1) |
135*9880d681SAndroid Build Coastguard Worker           (TargetFlags & R600_InstFlag::OP2) |
136*9880d681SAndroid Build Coastguard Worker           (TargetFlags & R600_InstFlag::OP3));
137*9880d681SAndroid Build Coastguard Worker }
138*9880d681SAndroid Build Coastguard Worker 
isLDSInstr(unsigned Opcode) const139*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::isLDSInstr(unsigned Opcode) const {
140*9880d681SAndroid Build Coastguard Worker   unsigned TargetFlags = get(Opcode).TSFlags;
141*9880d681SAndroid Build Coastguard Worker 
142*9880d681SAndroid Build Coastguard Worker   return ((TargetFlags & R600_InstFlag::LDS_1A) |
143*9880d681SAndroid Build Coastguard Worker           (TargetFlags & R600_InstFlag::LDS_1A1D) |
144*9880d681SAndroid Build Coastguard Worker           (TargetFlags & R600_InstFlag::LDS_1A2D));
145*9880d681SAndroid Build Coastguard Worker }
146*9880d681SAndroid Build Coastguard Worker 
isLDSNoRetInstr(unsigned Opcode) const147*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::isLDSNoRetInstr(unsigned Opcode) const {
148*9880d681SAndroid Build Coastguard Worker   return isLDSInstr(Opcode) && getOperandIdx(Opcode, AMDGPU::OpName::dst) == -1;
149*9880d681SAndroid Build Coastguard Worker }
150*9880d681SAndroid Build Coastguard Worker 
isLDSRetInstr(unsigned Opcode) const151*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::isLDSRetInstr(unsigned Opcode) const {
152*9880d681SAndroid Build Coastguard Worker   return isLDSInstr(Opcode) && getOperandIdx(Opcode, AMDGPU::OpName::dst) != -1;
153*9880d681SAndroid Build Coastguard Worker }
154*9880d681SAndroid Build Coastguard Worker 
canBeConsideredALU(const MachineInstr & MI) const155*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::canBeConsideredALU(const MachineInstr &MI) const {
156*9880d681SAndroid Build Coastguard Worker   if (isALUInstr(MI.getOpcode()))
157*9880d681SAndroid Build Coastguard Worker     return true;
158*9880d681SAndroid Build Coastguard Worker   if (isVector(MI) || isCubeOp(MI.getOpcode()))
159*9880d681SAndroid Build Coastguard Worker     return true;
160*9880d681SAndroid Build Coastguard Worker   switch (MI.getOpcode()) {
161*9880d681SAndroid Build Coastguard Worker   case AMDGPU::PRED_X:
162*9880d681SAndroid Build Coastguard Worker   case AMDGPU::INTERP_PAIR_XY:
163*9880d681SAndroid Build Coastguard Worker   case AMDGPU::INTERP_PAIR_ZW:
164*9880d681SAndroid Build Coastguard Worker   case AMDGPU::INTERP_VEC_LOAD:
165*9880d681SAndroid Build Coastguard Worker   case AMDGPU::COPY:
166*9880d681SAndroid Build Coastguard Worker   case AMDGPU::DOT_4:
167*9880d681SAndroid Build Coastguard Worker     return true;
168*9880d681SAndroid Build Coastguard Worker   default:
169*9880d681SAndroid Build Coastguard Worker     return false;
170*9880d681SAndroid Build Coastguard Worker   }
171*9880d681SAndroid Build Coastguard Worker }
172*9880d681SAndroid Build Coastguard Worker 
isTransOnly(unsigned Opcode) const173*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::isTransOnly(unsigned Opcode) const {
174*9880d681SAndroid Build Coastguard Worker   if (ST.hasCaymanISA())
175*9880d681SAndroid Build Coastguard Worker     return false;
176*9880d681SAndroid Build Coastguard Worker   return (get(Opcode).getSchedClass() == AMDGPU::Sched::TransALU);
177*9880d681SAndroid Build Coastguard Worker }
178*9880d681SAndroid Build Coastguard Worker 
isTransOnly(const MachineInstr & MI) const179*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::isTransOnly(const MachineInstr &MI) const {
180*9880d681SAndroid Build Coastguard Worker   return isTransOnly(MI.getOpcode());
181*9880d681SAndroid Build Coastguard Worker }
182*9880d681SAndroid Build Coastguard Worker 
isVectorOnly(unsigned Opcode) const183*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::isVectorOnly(unsigned Opcode) const {
184*9880d681SAndroid Build Coastguard Worker   return (get(Opcode).getSchedClass() == AMDGPU::Sched::VecALU);
185*9880d681SAndroid Build Coastguard Worker }
186*9880d681SAndroid Build Coastguard Worker 
isVectorOnly(const MachineInstr & MI) const187*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::isVectorOnly(const MachineInstr &MI) const {
188*9880d681SAndroid Build Coastguard Worker   return isVectorOnly(MI.getOpcode());
189*9880d681SAndroid Build Coastguard Worker }
190*9880d681SAndroid Build Coastguard Worker 
isExport(unsigned Opcode) const191*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::isExport(unsigned Opcode) const {
192*9880d681SAndroid Build Coastguard Worker   return (get(Opcode).TSFlags & R600_InstFlag::IS_EXPORT);
193*9880d681SAndroid Build Coastguard Worker }
194*9880d681SAndroid Build Coastguard Worker 
usesVertexCache(unsigned Opcode) const195*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::usesVertexCache(unsigned Opcode) const {
196*9880d681SAndroid Build Coastguard Worker   return ST.hasVertexCache() && IS_VTX(get(Opcode));
197*9880d681SAndroid Build Coastguard Worker }
198*9880d681SAndroid Build Coastguard Worker 
usesVertexCache(const MachineInstr & MI) const199*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::usesVertexCache(const MachineInstr &MI) const {
200*9880d681SAndroid Build Coastguard Worker   const MachineFunction *MF = MI.getParent()->getParent();
201*9880d681SAndroid Build Coastguard Worker   return !AMDGPU::isCompute(MF->getFunction()->getCallingConv()) &&
202*9880d681SAndroid Build Coastguard Worker          usesVertexCache(MI.getOpcode());
203*9880d681SAndroid Build Coastguard Worker }
204*9880d681SAndroid Build Coastguard Worker 
usesTextureCache(unsigned Opcode) const205*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::usesTextureCache(unsigned Opcode) const {
206*9880d681SAndroid Build Coastguard Worker   return (!ST.hasVertexCache() && IS_VTX(get(Opcode))) || IS_TEX(get(Opcode));
207*9880d681SAndroid Build Coastguard Worker }
208*9880d681SAndroid Build Coastguard Worker 
usesTextureCache(const MachineInstr & MI) const209*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::usesTextureCache(const MachineInstr &MI) const {
210*9880d681SAndroid Build Coastguard Worker   const MachineFunction *MF = MI.getParent()->getParent();
211*9880d681SAndroid Build Coastguard Worker   return (AMDGPU::isCompute(MF->getFunction()->getCallingConv()) &&
212*9880d681SAndroid Build Coastguard Worker           usesVertexCache(MI.getOpcode())) ||
213*9880d681SAndroid Build Coastguard Worker          usesTextureCache(MI.getOpcode());
214*9880d681SAndroid Build Coastguard Worker }
215*9880d681SAndroid Build Coastguard Worker 
mustBeLastInClause(unsigned Opcode) const216*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::mustBeLastInClause(unsigned Opcode) const {
217*9880d681SAndroid Build Coastguard Worker   switch (Opcode) {
218*9880d681SAndroid Build Coastguard Worker   case AMDGPU::KILLGT:
219*9880d681SAndroid Build Coastguard Worker   case AMDGPU::GROUP_BARRIER:
220*9880d681SAndroid Build Coastguard Worker     return true;
221*9880d681SAndroid Build Coastguard Worker   default:
222*9880d681SAndroid Build Coastguard Worker     return false;
223*9880d681SAndroid Build Coastguard Worker   }
224*9880d681SAndroid Build Coastguard Worker }
225*9880d681SAndroid Build Coastguard Worker 
usesAddressRegister(MachineInstr & MI) const226*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::usesAddressRegister(MachineInstr &MI) const {
227*9880d681SAndroid Build Coastguard Worker   return MI.findRegisterUseOperandIdx(AMDGPU::AR_X) != -1;
228*9880d681SAndroid Build Coastguard Worker }
229*9880d681SAndroid Build Coastguard Worker 
definesAddressRegister(MachineInstr & MI) const230*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::definesAddressRegister(MachineInstr &MI) const {
231*9880d681SAndroid Build Coastguard Worker   return MI.findRegisterDefOperandIdx(AMDGPU::AR_X) != -1;
232*9880d681SAndroid Build Coastguard Worker }
233*9880d681SAndroid Build Coastguard Worker 
readsLDSSrcReg(const MachineInstr & MI) const234*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::readsLDSSrcReg(const MachineInstr &MI) const {
235*9880d681SAndroid Build Coastguard Worker   if (!isALUInstr(MI.getOpcode())) {
236*9880d681SAndroid Build Coastguard Worker     return false;
237*9880d681SAndroid Build Coastguard Worker   }
238*9880d681SAndroid Build Coastguard Worker   for (MachineInstr::const_mop_iterator I = MI.operands_begin(),
239*9880d681SAndroid Build Coastguard Worker                                         E = MI.operands_end();
240*9880d681SAndroid Build Coastguard Worker        I != E; ++I) {
241*9880d681SAndroid Build Coastguard Worker     if (!I->isReg() || !I->isUse() ||
242*9880d681SAndroid Build Coastguard Worker         TargetRegisterInfo::isVirtualRegister(I->getReg()))
243*9880d681SAndroid Build Coastguard Worker       continue;
244*9880d681SAndroid Build Coastguard Worker 
245*9880d681SAndroid Build Coastguard Worker     if (AMDGPU::R600_LDS_SRC_REGRegClass.contains(I->getReg()))
246*9880d681SAndroid Build Coastguard Worker       return true;
247*9880d681SAndroid Build Coastguard Worker   }
248*9880d681SAndroid Build Coastguard Worker   return false;
249*9880d681SAndroid Build Coastguard Worker }
250*9880d681SAndroid Build Coastguard Worker 
getSrcIdx(unsigned Opcode,unsigned SrcNum) const251*9880d681SAndroid Build Coastguard Worker int R600InstrInfo::getSrcIdx(unsigned Opcode, unsigned SrcNum) const {
252*9880d681SAndroid Build Coastguard Worker   static const unsigned OpTable[] = {
253*9880d681SAndroid Build Coastguard Worker     AMDGPU::OpName::src0,
254*9880d681SAndroid Build Coastguard Worker     AMDGPU::OpName::src1,
255*9880d681SAndroid Build Coastguard Worker     AMDGPU::OpName::src2
256*9880d681SAndroid Build Coastguard Worker   };
257*9880d681SAndroid Build Coastguard Worker 
258*9880d681SAndroid Build Coastguard Worker   assert (SrcNum < 3);
259*9880d681SAndroid Build Coastguard Worker   return getOperandIdx(Opcode, OpTable[SrcNum]);
260*9880d681SAndroid Build Coastguard Worker }
261*9880d681SAndroid Build Coastguard Worker 
getSelIdx(unsigned Opcode,unsigned SrcIdx) const262*9880d681SAndroid Build Coastguard Worker int R600InstrInfo::getSelIdx(unsigned Opcode, unsigned SrcIdx) const {
263*9880d681SAndroid Build Coastguard Worker   static const unsigned SrcSelTable[][2] = {
264*9880d681SAndroid Build Coastguard Worker     {AMDGPU::OpName::src0, AMDGPU::OpName::src0_sel},
265*9880d681SAndroid Build Coastguard Worker     {AMDGPU::OpName::src1, AMDGPU::OpName::src1_sel},
266*9880d681SAndroid Build Coastguard Worker     {AMDGPU::OpName::src2, AMDGPU::OpName::src2_sel},
267*9880d681SAndroid Build Coastguard Worker     {AMDGPU::OpName::src0_X, AMDGPU::OpName::src0_sel_X},
268*9880d681SAndroid Build Coastguard Worker     {AMDGPU::OpName::src0_Y, AMDGPU::OpName::src0_sel_Y},
269*9880d681SAndroid Build Coastguard Worker     {AMDGPU::OpName::src0_Z, AMDGPU::OpName::src0_sel_Z},
270*9880d681SAndroid Build Coastguard Worker     {AMDGPU::OpName::src0_W, AMDGPU::OpName::src0_sel_W},
271*9880d681SAndroid Build Coastguard Worker     {AMDGPU::OpName::src1_X, AMDGPU::OpName::src1_sel_X},
272*9880d681SAndroid Build Coastguard Worker     {AMDGPU::OpName::src1_Y, AMDGPU::OpName::src1_sel_Y},
273*9880d681SAndroid Build Coastguard Worker     {AMDGPU::OpName::src1_Z, AMDGPU::OpName::src1_sel_Z},
274*9880d681SAndroid Build Coastguard Worker     {AMDGPU::OpName::src1_W, AMDGPU::OpName::src1_sel_W}
275*9880d681SAndroid Build Coastguard Worker   };
276*9880d681SAndroid Build Coastguard Worker 
277*9880d681SAndroid Build Coastguard Worker   for (const auto &Row : SrcSelTable) {
278*9880d681SAndroid Build Coastguard Worker     if (getOperandIdx(Opcode, Row[0]) == (int)SrcIdx) {
279*9880d681SAndroid Build Coastguard Worker       return getOperandIdx(Opcode, Row[1]);
280*9880d681SAndroid Build Coastguard Worker     }
281*9880d681SAndroid Build Coastguard Worker   }
282*9880d681SAndroid Build Coastguard Worker   return -1;
283*9880d681SAndroid Build Coastguard Worker }
284*9880d681SAndroid Build Coastguard Worker 
285*9880d681SAndroid Build Coastguard Worker SmallVector<std::pair<MachineOperand *, int64_t>, 3>
getSrcs(MachineInstr & MI) const286*9880d681SAndroid Build Coastguard Worker R600InstrInfo::getSrcs(MachineInstr &MI) const {
287*9880d681SAndroid Build Coastguard Worker   SmallVector<std::pair<MachineOperand *, int64_t>, 3> Result;
288*9880d681SAndroid Build Coastguard Worker 
289*9880d681SAndroid Build Coastguard Worker   if (MI.getOpcode() == AMDGPU::DOT_4) {
290*9880d681SAndroid Build Coastguard Worker     static const unsigned OpTable[8][2] = {
291*9880d681SAndroid Build Coastguard Worker       {AMDGPU::OpName::src0_X, AMDGPU::OpName::src0_sel_X},
292*9880d681SAndroid Build Coastguard Worker       {AMDGPU::OpName::src0_Y, AMDGPU::OpName::src0_sel_Y},
293*9880d681SAndroid Build Coastguard Worker       {AMDGPU::OpName::src0_Z, AMDGPU::OpName::src0_sel_Z},
294*9880d681SAndroid Build Coastguard Worker       {AMDGPU::OpName::src0_W, AMDGPU::OpName::src0_sel_W},
295*9880d681SAndroid Build Coastguard Worker       {AMDGPU::OpName::src1_X, AMDGPU::OpName::src1_sel_X},
296*9880d681SAndroid Build Coastguard Worker       {AMDGPU::OpName::src1_Y, AMDGPU::OpName::src1_sel_Y},
297*9880d681SAndroid Build Coastguard Worker       {AMDGPU::OpName::src1_Z, AMDGPU::OpName::src1_sel_Z},
298*9880d681SAndroid Build Coastguard Worker       {AMDGPU::OpName::src1_W, AMDGPU::OpName::src1_sel_W},
299*9880d681SAndroid Build Coastguard Worker     };
300*9880d681SAndroid Build Coastguard Worker 
301*9880d681SAndroid Build Coastguard Worker     for (unsigned j = 0; j < 8; j++) {
302*9880d681SAndroid Build Coastguard Worker       MachineOperand &MO =
303*9880d681SAndroid Build Coastguard Worker           MI.getOperand(getOperandIdx(MI.getOpcode(), OpTable[j][0]));
304*9880d681SAndroid Build Coastguard Worker       unsigned Reg = MO.getReg();
305*9880d681SAndroid Build Coastguard Worker       if (Reg == AMDGPU::ALU_CONST) {
306*9880d681SAndroid Build Coastguard Worker         MachineOperand &Sel =
307*9880d681SAndroid Build Coastguard Worker             MI.getOperand(getOperandIdx(MI.getOpcode(), OpTable[j][1]));
308*9880d681SAndroid Build Coastguard Worker         Result.push_back(std::make_pair(&MO, Sel.getImm()));
309*9880d681SAndroid Build Coastguard Worker         continue;
310*9880d681SAndroid Build Coastguard Worker       }
311*9880d681SAndroid Build Coastguard Worker 
312*9880d681SAndroid Build Coastguard Worker     }
313*9880d681SAndroid Build Coastguard Worker     return Result;
314*9880d681SAndroid Build Coastguard Worker   }
315*9880d681SAndroid Build Coastguard Worker 
316*9880d681SAndroid Build Coastguard Worker   static const unsigned OpTable[3][2] = {
317*9880d681SAndroid Build Coastguard Worker     {AMDGPU::OpName::src0, AMDGPU::OpName::src0_sel},
318*9880d681SAndroid Build Coastguard Worker     {AMDGPU::OpName::src1, AMDGPU::OpName::src1_sel},
319*9880d681SAndroid Build Coastguard Worker     {AMDGPU::OpName::src2, AMDGPU::OpName::src2_sel},
320*9880d681SAndroid Build Coastguard Worker   };
321*9880d681SAndroid Build Coastguard Worker 
322*9880d681SAndroid Build Coastguard Worker   for (unsigned j = 0; j < 3; j++) {
323*9880d681SAndroid Build Coastguard Worker     int SrcIdx = getOperandIdx(MI.getOpcode(), OpTable[j][0]);
324*9880d681SAndroid Build Coastguard Worker     if (SrcIdx < 0)
325*9880d681SAndroid Build Coastguard Worker       break;
326*9880d681SAndroid Build Coastguard Worker     MachineOperand &MO = MI.getOperand(SrcIdx);
327*9880d681SAndroid Build Coastguard Worker     unsigned Reg = MO.getReg();
328*9880d681SAndroid Build Coastguard Worker     if (Reg == AMDGPU::ALU_CONST) {
329*9880d681SAndroid Build Coastguard Worker       MachineOperand &Sel =
330*9880d681SAndroid Build Coastguard Worker           MI.getOperand(getOperandIdx(MI.getOpcode(), OpTable[j][1]));
331*9880d681SAndroid Build Coastguard Worker       Result.push_back(std::make_pair(&MO, Sel.getImm()));
332*9880d681SAndroid Build Coastguard Worker       continue;
333*9880d681SAndroid Build Coastguard Worker     }
334*9880d681SAndroid Build Coastguard Worker     if (Reg == AMDGPU::ALU_LITERAL_X) {
335*9880d681SAndroid Build Coastguard Worker       MachineOperand &Operand =
336*9880d681SAndroid Build Coastguard Worker           MI.getOperand(getOperandIdx(MI.getOpcode(), AMDGPU::OpName::literal));
337*9880d681SAndroid Build Coastguard Worker       if (Operand.isImm()) {
338*9880d681SAndroid Build Coastguard Worker         Result.push_back(std::make_pair(&MO, Operand.getImm()));
339*9880d681SAndroid Build Coastguard Worker         continue;
340*9880d681SAndroid Build Coastguard Worker       }
341*9880d681SAndroid Build Coastguard Worker       assert(Operand.isGlobal());
342*9880d681SAndroid Build Coastguard Worker     }
343*9880d681SAndroid Build Coastguard Worker     Result.push_back(std::make_pair(&MO, 0));
344*9880d681SAndroid Build Coastguard Worker   }
345*9880d681SAndroid Build Coastguard Worker   return Result;
346*9880d681SAndroid Build Coastguard Worker }
347*9880d681SAndroid Build Coastguard Worker 
348*9880d681SAndroid Build Coastguard Worker std::vector<std::pair<int, unsigned>>
ExtractSrcs(MachineInstr & MI,const DenseMap<unsigned,unsigned> & PV,unsigned & ConstCount) const349*9880d681SAndroid Build Coastguard Worker R600InstrInfo::ExtractSrcs(MachineInstr &MI,
350*9880d681SAndroid Build Coastguard Worker                            const DenseMap<unsigned, unsigned> &PV,
351*9880d681SAndroid Build Coastguard Worker                            unsigned &ConstCount) const {
352*9880d681SAndroid Build Coastguard Worker   ConstCount = 0;
353*9880d681SAndroid Build Coastguard Worker   ArrayRef<std::pair<MachineOperand *, int64_t>> Srcs = getSrcs(MI);
354*9880d681SAndroid Build Coastguard Worker   const std::pair<int, unsigned> DummyPair(-1, 0);
355*9880d681SAndroid Build Coastguard Worker   std::vector<std::pair<int, unsigned> > Result;
356*9880d681SAndroid Build Coastguard Worker   unsigned i = 0;
357*9880d681SAndroid Build Coastguard Worker   for (unsigned n = Srcs.size(); i < n; ++i) {
358*9880d681SAndroid Build Coastguard Worker     unsigned Reg = Srcs[i].first->getReg();
359*9880d681SAndroid Build Coastguard Worker     int Index = RI.getEncodingValue(Reg) & 0xff;
360*9880d681SAndroid Build Coastguard Worker     if (Reg == AMDGPU::OQAP) {
361*9880d681SAndroid Build Coastguard Worker       Result.push_back(std::make_pair(Index, 0U));
362*9880d681SAndroid Build Coastguard Worker     }
363*9880d681SAndroid Build Coastguard Worker     if (PV.find(Reg) != PV.end()) {
364*9880d681SAndroid Build Coastguard Worker       // 255 is used to tells its a PS/PV reg
365*9880d681SAndroid Build Coastguard Worker       Result.push_back(std::make_pair(255, 0U));
366*9880d681SAndroid Build Coastguard Worker       continue;
367*9880d681SAndroid Build Coastguard Worker     }
368*9880d681SAndroid Build Coastguard Worker     if (Index > 127) {
369*9880d681SAndroid Build Coastguard Worker       ConstCount++;
370*9880d681SAndroid Build Coastguard Worker       Result.push_back(DummyPair);
371*9880d681SAndroid Build Coastguard Worker       continue;
372*9880d681SAndroid Build Coastguard Worker     }
373*9880d681SAndroid Build Coastguard Worker     unsigned Chan = RI.getHWRegChan(Reg);
374*9880d681SAndroid Build Coastguard Worker     Result.push_back(std::make_pair(Index, Chan));
375*9880d681SAndroid Build Coastguard Worker   }
376*9880d681SAndroid Build Coastguard Worker   for (; i < 3; ++i)
377*9880d681SAndroid Build Coastguard Worker     Result.push_back(DummyPair);
378*9880d681SAndroid Build Coastguard Worker   return Result;
379*9880d681SAndroid Build Coastguard Worker }
380*9880d681SAndroid Build Coastguard Worker 
381*9880d681SAndroid Build Coastguard Worker static std::vector<std::pair<int, unsigned> >
Swizzle(std::vector<std::pair<int,unsigned>> Src,R600InstrInfo::BankSwizzle Swz)382*9880d681SAndroid Build Coastguard Worker Swizzle(std::vector<std::pair<int, unsigned> > Src,
383*9880d681SAndroid Build Coastguard Worker         R600InstrInfo::BankSwizzle Swz) {
384*9880d681SAndroid Build Coastguard Worker   if (Src[0] == Src[1])
385*9880d681SAndroid Build Coastguard Worker     Src[1].first = -1;
386*9880d681SAndroid Build Coastguard Worker   switch (Swz) {
387*9880d681SAndroid Build Coastguard Worker   case R600InstrInfo::ALU_VEC_012_SCL_210:
388*9880d681SAndroid Build Coastguard Worker     break;
389*9880d681SAndroid Build Coastguard Worker   case R600InstrInfo::ALU_VEC_021_SCL_122:
390*9880d681SAndroid Build Coastguard Worker     std::swap(Src[1], Src[2]);
391*9880d681SAndroid Build Coastguard Worker     break;
392*9880d681SAndroid Build Coastguard Worker   case R600InstrInfo::ALU_VEC_102_SCL_221:
393*9880d681SAndroid Build Coastguard Worker     std::swap(Src[0], Src[1]);
394*9880d681SAndroid Build Coastguard Worker     break;
395*9880d681SAndroid Build Coastguard Worker   case R600InstrInfo::ALU_VEC_120_SCL_212:
396*9880d681SAndroid Build Coastguard Worker     std::swap(Src[0], Src[1]);
397*9880d681SAndroid Build Coastguard Worker     std::swap(Src[0], Src[2]);
398*9880d681SAndroid Build Coastguard Worker     break;
399*9880d681SAndroid Build Coastguard Worker   case R600InstrInfo::ALU_VEC_201:
400*9880d681SAndroid Build Coastguard Worker     std::swap(Src[0], Src[2]);
401*9880d681SAndroid Build Coastguard Worker     std::swap(Src[0], Src[1]);
402*9880d681SAndroid Build Coastguard Worker     break;
403*9880d681SAndroid Build Coastguard Worker   case R600InstrInfo::ALU_VEC_210:
404*9880d681SAndroid Build Coastguard Worker     std::swap(Src[0], Src[2]);
405*9880d681SAndroid Build Coastguard Worker     break;
406*9880d681SAndroid Build Coastguard Worker   }
407*9880d681SAndroid Build Coastguard Worker   return Src;
408*9880d681SAndroid Build Coastguard Worker }
409*9880d681SAndroid Build Coastguard Worker 
410*9880d681SAndroid Build Coastguard Worker static unsigned
getTransSwizzle(R600InstrInfo::BankSwizzle Swz,unsigned Op)411*9880d681SAndroid Build Coastguard Worker getTransSwizzle(R600InstrInfo::BankSwizzle Swz, unsigned Op) {
412*9880d681SAndroid Build Coastguard Worker   switch (Swz) {
413*9880d681SAndroid Build Coastguard Worker   case R600InstrInfo::ALU_VEC_012_SCL_210: {
414*9880d681SAndroid Build Coastguard Worker     unsigned Cycles[3] = { 2, 1, 0};
415*9880d681SAndroid Build Coastguard Worker     return Cycles[Op];
416*9880d681SAndroid Build Coastguard Worker   }
417*9880d681SAndroid Build Coastguard Worker   case R600InstrInfo::ALU_VEC_021_SCL_122: {
418*9880d681SAndroid Build Coastguard Worker     unsigned Cycles[3] = { 1, 2, 2};
419*9880d681SAndroid Build Coastguard Worker     return Cycles[Op];
420*9880d681SAndroid Build Coastguard Worker   }
421*9880d681SAndroid Build Coastguard Worker   case R600InstrInfo::ALU_VEC_120_SCL_212: {
422*9880d681SAndroid Build Coastguard Worker     unsigned Cycles[3] = { 2, 1, 2};
423*9880d681SAndroid Build Coastguard Worker     return Cycles[Op];
424*9880d681SAndroid Build Coastguard Worker   }
425*9880d681SAndroid Build Coastguard Worker   case R600InstrInfo::ALU_VEC_102_SCL_221: {
426*9880d681SAndroid Build Coastguard Worker     unsigned Cycles[3] = { 2, 2, 1};
427*9880d681SAndroid Build Coastguard Worker     return Cycles[Op];
428*9880d681SAndroid Build Coastguard Worker   }
429*9880d681SAndroid Build Coastguard Worker   default:
430*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Wrong Swizzle for Trans Slot");
431*9880d681SAndroid Build Coastguard Worker     return 0;
432*9880d681SAndroid Build Coastguard Worker   }
433*9880d681SAndroid Build Coastguard Worker }
434*9880d681SAndroid Build Coastguard Worker 
435*9880d681SAndroid Build Coastguard Worker /// returns how many MIs (whose inputs are represented by IGSrcs) can be packed
436*9880d681SAndroid Build Coastguard Worker /// in the same Instruction Group while meeting read port limitations given a
437*9880d681SAndroid Build Coastguard Worker /// Swz swizzle sequence.
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) const438*9880d681SAndroid Build Coastguard Worker unsigned  R600InstrInfo::isLegalUpTo(
439*9880d681SAndroid Build Coastguard Worker     const std::vector<std::vector<std::pair<int, unsigned> > > &IGSrcs,
440*9880d681SAndroid Build Coastguard Worker     const std::vector<R600InstrInfo::BankSwizzle> &Swz,
441*9880d681SAndroid Build Coastguard Worker     const std::vector<std::pair<int, unsigned> > &TransSrcs,
442*9880d681SAndroid Build Coastguard Worker     R600InstrInfo::BankSwizzle TransSwz) const {
443*9880d681SAndroid Build Coastguard Worker   int Vector[4][3];
444*9880d681SAndroid Build Coastguard Worker   memset(Vector, -1, sizeof(Vector));
445*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = IGSrcs.size(); i < e; i++) {
446*9880d681SAndroid Build Coastguard Worker     const std::vector<std::pair<int, unsigned> > &Srcs =
447*9880d681SAndroid Build Coastguard Worker         Swizzle(IGSrcs[i], Swz[i]);
448*9880d681SAndroid Build Coastguard Worker     for (unsigned j = 0; j < 3; j++) {
449*9880d681SAndroid Build Coastguard Worker       const std::pair<int, unsigned> &Src = Srcs[j];
450*9880d681SAndroid Build Coastguard Worker       if (Src.first < 0 || Src.first == 255)
451*9880d681SAndroid Build Coastguard Worker         continue;
452*9880d681SAndroid Build Coastguard Worker       if (Src.first == GET_REG_INDEX(RI.getEncodingValue(AMDGPU::OQAP))) {
453*9880d681SAndroid Build Coastguard Worker         if (Swz[i] != R600InstrInfo::ALU_VEC_012_SCL_210 &&
454*9880d681SAndroid Build Coastguard Worker             Swz[i] != R600InstrInfo::ALU_VEC_021_SCL_122) {
455*9880d681SAndroid Build Coastguard Worker             // The value from output queue A (denoted by register OQAP) can
456*9880d681SAndroid Build Coastguard Worker             // only be fetched during the first cycle.
457*9880d681SAndroid Build Coastguard Worker             return false;
458*9880d681SAndroid Build Coastguard Worker         }
459*9880d681SAndroid Build Coastguard Worker         // OQAP does not count towards the normal read port restrictions
460*9880d681SAndroid Build Coastguard Worker         continue;
461*9880d681SAndroid Build Coastguard Worker       }
462*9880d681SAndroid Build Coastguard Worker       if (Vector[Src.second][j] < 0)
463*9880d681SAndroid Build Coastguard Worker         Vector[Src.second][j] = Src.first;
464*9880d681SAndroid Build Coastguard Worker       if (Vector[Src.second][j] != Src.first)
465*9880d681SAndroid Build Coastguard Worker         return i;
466*9880d681SAndroid Build Coastguard Worker     }
467*9880d681SAndroid Build Coastguard Worker   }
468*9880d681SAndroid Build Coastguard Worker   // Now check Trans Alu
469*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = TransSrcs.size(); i < e; ++i) {
470*9880d681SAndroid Build Coastguard Worker     const std::pair<int, unsigned> &Src = TransSrcs[i];
471*9880d681SAndroid Build Coastguard Worker     unsigned Cycle = getTransSwizzle(TransSwz, i);
472*9880d681SAndroid Build Coastguard Worker     if (Src.first < 0)
473*9880d681SAndroid Build Coastguard Worker       continue;
474*9880d681SAndroid Build Coastguard Worker     if (Src.first == 255)
475*9880d681SAndroid Build Coastguard Worker       continue;
476*9880d681SAndroid Build Coastguard Worker     if (Vector[Src.second][Cycle] < 0)
477*9880d681SAndroid Build Coastguard Worker       Vector[Src.second][Cycle] = Src.first;
478*9880d681SAndroid Build Coastguard Worker     if (Vector[Src.second][Cycle] != Src.first)
479*9880d681SAndroid Build Coastguard Worker       return IGSrcs.size() - 1;
480*9880d681SAndroid Build Coastguard Worker   }
481*9880d681SAndroid Build Coastguard Worker   return IGSrcs.size();
482*9880d681SAndroid Build Coastguard Worker }
483*9880d681SAndroid Build Coastguard Worker 
484*9880d681SAndroid Build Coastguard Worker /// Given a swizzle sequence SwzCandidate and an index Idx, returns the next
485*9880d681SAndroid Build Coastguard Worker /// (in lexicographic term) swizzle sequence assuming that all swizzles after
486*9880d681SAndroid Build Coastguard Worker /// Idx can be skipped
487*9880d681SAndroid Build Coastguard Worker static bool
NextPossibleSolution(std::vector<R600InstrInfo::BankSwizzle> & SwzCandidate,unsigned Idx)488*9880d681SAndroid Build Coastguard Worker NextPossibleSolution(
489*9880d681SAndroid Build Coastguard Worker     std::vector<R600InstrInfo::BankSwizzle> &SwzCandidate,
490*9880d681SAndroid Build Coastguard Worker     unsigned Idx) {
491*9880d681SAndroid Build Coastguard Worker   assert(Idx < SwzCandidate.size());
492*9880d681SAndroid Build Coastguard Worker   int ResetIdx = Idx;
493*9880d681SAndroid Build Coastguard Worker   while (ResetIdx > -1 && SwzCandidate[ResetIdx] == R600InstrInfo::ALU_VEC_210)
494*9880d681SAndroid Build Coastguard Worker     ResetIdx --;
495*9880d681SAndroid Build Coastguard Worker   for (unsigned i = ResetIdx + 1, e = SwzCandidate.size(); i < e; i++) {
496*9880d681SAndroid Build Coastguard Worker     SwzCandidate[i] = R600InstrInfo::ALU_VEC_012_SCL_210;
497*9880d681SAndroid Build Coastguard Worker   }
498*9880d681SAndroid Build Coastguard Worker   if (ResetIdx == -1)
499*9880d681SAndroid Build Coastguard Worker     return false;
500*9880d681SAndroid Build Coastguard Worker   int NextSwizzle = SwzCandidate[ResetIdx] + 1;
501*9880d681SAndroid Build Coastguard Worker   SwzCandidate[ResetIdx] = (R600InstrInfo::BankSwizzle)NextSwizzle;
502*9880d681SAndroid Build Coastguard Worker   return true;
503*9880d681SAndroid Build Coastguard Worker }
504*9880d681SAndroid Build Coastguard Worker 
505*9880d681SAndroid Build Coastguard Worker /// Enumerate all possible Swizzle sequence to find one that can meet all
506*9880d681SAndroid Build Coastguard Worker /// read port requirements.
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) const507*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::FindSwizzleForVectorSlot(
508*9880d681SAndroid Build Coastguard Worker     const std::vector<std::vector<std::pair<int, unsigned> > > &IGSrcs,
509*9880d681SAndroid Build Coastguard Worker     std::vector<R600InstrInfo::BankSwizzle> &SwzCandidate,
510*9880d681SAndroid Build Coastguard Worker     const std::vector<std::pair<int, unsigned> > &TransSrcs,
511*9880d681SAndroid Build Coastguard Worker     R600InstrInfo::BankSwizzle TransSwz) const {
512*9880d681SAndroid Build Coastguard Worker   unsigned ValidUpTo = 0;
513*9880d681SAndroid Build Coastguard Worker   do {
514*9880d681SAndroid Build Coastguard Worker     ValidUpTo = isLegalUpTo(IGSrcs, SwzCandidate, TransSrcs, TransSwz);
515*9880d681SAndroid Build Coastguard Worker     if (ValidUpTo == IGSrcs.size())
516*9880d681SAndroid Build Coastguard Worker       return true;
517*9880d681SAndroid Build Coastguard Worker   } while (NextPossibleSolution(SwzCandidate, ValidUpTo));
518*9880d681SAndroid Build Coastguard Worker   return false;
519*9880d681SAndroid Build Coastguard Worker }
520*9880d681SAndroid Build Coastguard Worker 
521*9880d681SAndroid Build Coastguard Worker /// Instructions in Trans slot can't read gpr at cycle 0 if they also read
522*9880d681SAndroid Build Coastguard Worker /// a const, and can't read a gpr at cycle 1 if they read 2 const.
523*9880d681SAndroid Build Coastguard Worker static bool
isConstCompatible(R600InstrInfo::BankSwizzle TransSwz,const std::vector<std::pair<int,unsigned>> & TransOps,unsigned ConstCount)524*9880d681SAndroid Build Coastguard Worker isConstCompatible(R600InstrInfo::BankSwizzle TransSwz,
525*9880d681SAndroid Build Coastguard Worker                   const std::vector<std::pair<int, unsigned> > &TransOps,
526*9880d681SAndroid Build Coastguard Worker                   unsigned ConstCount) {
527*9880d681SAndroid Build Coastguard Worker   // TransALU can't read 3 constants
528*9880d681SAndroid Build Coastguard Worker   if (ConstCount > 2)
529*9880d681SAndroid Build Coastguard Worker     return false;
530*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = TransOps.size(); i < e; ++i) {
531*9880d681SAndroid Build Coastguard Worker     const std::pair<int, unsigned> &Src = TransOps[i];
532*9880d681SAndroid Build Coastguard Worker     unsigned Cycle = getTransSwizzle(TransSwz, i);
533*9880d681SAndroid Build Coastguard Worker     if (Src.first < 0)
534*9880d681SAndroid Build Coastguard Worker       continue;
535*9880d681SAndroid Build Coastguard Worker     if (ConstCount > 0 && Cycle == 0)
536*9880d681SAndroid Build Coastguard Worker       return false;
537*9880d681SAndroid Build Coastguard Worker     if (ConstCount > 1 && Cycle == 1)
538*9880d681SAndroid Build Coastguard Worker       return false;
539*9880d681SAndroid Build Coastguard Worker   }
540*9880d681SAndroid Build Coastguard Worker   return true;
541*9880d681SAndroid Build Coastguard Worker }
542*9880d681SAndroid Build Coastguard Worker 
543*9880d681SAndroid Build Coastguard Worker bool
fitsReadPortLimitations(const std::vector<MachineInstr * > & IG,const DenseMap<unsigned,unsigned> & PV,std::vector<BankSwizzle> & ValidSwizzle,bool isLastAluTrans) const544*9880d681SAndroid Build Coastguard Worker R600InstrInfo::fitsReadPortLimitations(const std::vector<MachineInstr *> &IG,
545*9880d681SAndroid Build Coastguard Worker                                        const DenseMap<unsigned, unsigned> &PV,
546*9880d681SAndroid Build Coastguard Worker                                        std::vector<BankSwizzle> &ValidSwizzle,
547*9880d681SAndroid Build Coastguard Worker                                        bool isLastAluTrans)
548*9880d681SAndroid Build Coastguard Worker     const {
549*9880d681SAndroid Build Coastguard Worker   //Todo : support shared src0 - src1 operand
550*9880d681SAndroid Build Coastguard Worker 
551*9880d681SAndroid Build Coastguard Worker   std::vector<std::vector<std::pair<int, unsigned> > > IGSrcs;
552*9880d681SAndroid Build Coastguard Worker   ValidSwizzle.clear();
553*9880d681SAndroid Build Coastguard Worker   unsigned ConstCount;
554*9880d681SAndroid Build Coastguard Worker   BankSwizzle TransBS = ALU_VEC_012_SCL_210;
555*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = IG.size(); i < e; ++i) {
556*9880d681SAndroid Build Coastguard Worker     IGSrcs.push_back(ExtractSrcs(*IG[i], PV, ConstCount));
557*9880d681SAndroid Build Coastguard Worker     unsigned Op = getOperandIdx(IG[i]->getOpcode(),
558*9880d681SAndroid Build Coastguard Worker         AMDGPU::OpName::bank_swizzle);
559*9880d681SAndroid Build Coastguard Worker     ValidSwizzle.push_back( (R600InstrInfo::BankSwizzle)
560*9880d681SAndroid Build Coastguard Worker         IG[i]->getOperand(Op).getImm());
561*9880d681SAndroid Build Coastguard Worker   }
562*9880d681SAndroid Build Coastguard Worker   std::vector<std::pair<int, unsigned> > TransOps;
563*9880d681SAndroid Build Coastguard Worker   if (!isLastAluTrans)
564*9880d681SAndroid Build Coastguard Worker     return FindSwizzleForVectorSlot(IGSrcs, ValidSwizzle, TransOps, TransBS);
565*9880d681SAndroid Build Coastguard Worker 
566*9880d681SAndroid Build Coastguard Worker   TransOps = std::move(IGSrcs.back());
567*9880d681SAndroid Build Coastguard Worker   IGSrcs.pop_back();
568*9880d681SAndroid Build Coastguard Worker   ValidSwizzle.pop_back();
569*9880d681SAndroid Build Coastguard Worker 
570*9880d681SAndroid Build Coastguard Worker   static const R600InstrInfo::BankSwizzle TransSwz[] = {
571*9880d681SAndroid Build Coastguard Worker     ALU_VEC_012_SCL_210,
572*9880d681SAndroid Build Coastguard Worker     ALU_VEC_021_SCL_122,
573*9880d681SAndroid Build Coastguard Worker     ALU_VEC_120_SCL_212,
574*9880d681SAndroid Build Coastguard Worker     ALU_VEC_102_SCL_221
575*9880d681SAndroid Build Coastguard Worker   };
576*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0; i < 4; i++) {
577*9880d681SAndroid Build Coastguard Worker     TransBS = TransSwz[i];
578*9880d681SAndroid Build Coastguard Worker     if (!isConstCompatible(TransBS, TransOps, ConstCount))
579*9880d681SAndroid Build Coastguard Worker       continue;
580*9880d681SAndroid Build Coastguard Worker     bool Result = FindSwizzleForVectorSlot(IGSrcs, ValidSwizzle, TransOps,
581*9880d681SAndroid Build Coastguard Worker         TransBS);
582*9880d681SAndroid Build Coastguard Worker     if (Result) {
583*9880d681SAndroid Build Coastguard Worker       ValidSwizzle.push_back(TransBS);
584*9880d681SAndroid Build Coastguard Worker       return true;
585*9880d681SAndroid Build Coastguard Worker     }
586*9880d681SAndroid Build Coastguard Worker   }
587*9880d681SAndroid Build Coastguard Worker 
588*9880d681SAndroid Build Coastguard Worker   return false;
589*9880d681SAndroid Build Coastguard Worker }
590*9880d681SAndroid Build Coastguard Worker 
591*9880d681SAndroid Build Coastguard Worker 
592*9880d681SAndroid Build Coastguard Worker bool
fitsConstReadLimitations(const std::vector<unsigned> & Consts) const593*9880d681SAndroid Build Coastguard Worker R600InstrInfo::fitsConstReadLimitations(const std::vector<unsigned> &Consts)
594*9880d681SAndroid Build Coastguard Worker     const {
595*9880d681SAndroid Build Coastguard Worker   assert (Consts.size() <= 12 && "Too many operands in instructions group");
596*9880d681SAndroid Build Coastguard Worker   unsigned Pair1 = 0, Pair2 = 0;
597*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, n = Consts.size(); i < n; ++i) {
598*9880d681SAndroid Build Coastguard Worker     unsigned ReadConstHalf = Consts[i] & 2;
599*9880d681SAndroid Build Coastguard Worker     unsigned ReadConstIndex = Consts[i] & (~3);
600*9880d681SAndroid Build Coastguard Worker     unsigned ReadHalfConst = ReadConstIndex | ReadConstHalf;
601*9880d681SAndroid Build Coastguard Worker     if (!Pair1) {
602*9880d681SAndroid Build Coastguard Worker       Pair1 = ReadHalfConst;
603*9880d681SAndroid Build Coastguard Worker       continue;
604*9880d681SAndroid Build Coastguard Worker     }
605*9880d681SAndroid Build Coastguard Worker     if (Pair1 == ReadHalfConst)
606*9880d681SAndroid Build Coastguard Worker       continue;
607*9880d681SAndroid Build Coastguard Worker     if (!Pair2) {
608*9880d681SAndroid Build Coastguard Worker       Pair2 = ReadHalfConst;
609*9880d681SAndroid Build Coastguard Worker       continue;
610*9880d681SAndroid Build Coastguard Worker     }
611*9880d681SAndroid Build Coastguard Worker     if (Pair2 != ReadHalfConst)
612*9880d681SAndroid Build Coastguard Worker       return false;
613*9880d681SAndroid Build Coastguard Worker   }
614*9880d681SAndroid Build Coastguard Worker   return true;
615*9880d681SAndroid Build Coastguard Worker }
616*9880d681SAndroid Build Coastguard Worker 
617*9880d681SAndroid Build Coastguard Worker bool
fitsConstReadLimitations(const std::vector<MachineInstr * > & MIs) const618*9880d681SAndroid Build Coastguard Worker R600InstrInfo::fitsConstReadLimitations(const std::vector<MachineInstr *> &MIs)
619*9880d681SAndroid Build Coastguard Worker     const {
620*9880d681SAndroid Build Coastguard Worker   std::vector<unsigned> Consts;
621*9880d681SAndroid Build Coastguard Worker   SmallSet<int64_t, 4> Literals;
622*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, n = MIs.size(); i < n; i++) {
623*9880d681SAndroid Build Coastguard Worker     MachineInstr &MI = *MIs[i];
624*9880d681SAndroid Build Coastguard Worker     if (!isALUInstr(MI.getOpcode()))
625*9880d681SAndroid Build Coastguard Worker       continue;
626*9880d681SAndroid Build Coastguard Worker 
627*9880d681SAndroid Build Coastguard Worker     ArrayRef<std::pair<MachineOperand *, int64_t>> Srcs = getSrcs(MI);
628*9880d681SAndroid Build Coastguard Worker 
629*9880d681SAndroid Build Coastguard Worker     for (const auto &Src:Srcs) {
630*9880d681SAndroid Build Coastguard Worker       if (Src.first->getReg() == AMDGPU::ALU_LITERAL_X)
631*9880d681SAndroid Build Coastguard Worker         Literals.insert(Src.second);
632*9880d681SAndroid Build Coastguard Worker       if (Literals.size() > 4)
633*9880d681SAndroid Build Coastguard Worker         return false;
634*9880d681SAndroid Build Coastguard Worker       if (Src.first->getReg() == AMDGPU::ALU_CONST)
635*9880d681SAndroid Build Coastguard Worker         Consts.push_back(Src.second);
636*9880d681SAndroid Build Coastguard Worker       if (AMDGPU::R600_KC0RegClass.contains(Src.first->getReg()) ||
637*9880d681SAndroid Build Coastguard Worker           AMDGPU::R600_KC1RegClass.contains(Src.first->getReg())) {
638*9880d681SAndroid Build Coastguard Worker         unsigned Index = RI.getEncodingValue(Src.first->getReg()) & 0xff;
639*9880d681SAndroid Build Coastguard Worker         unsigned Chan = RI.getHWRegChan(Src.first->getReg());
640*9880d681SAndroid Build Coastguard Worker         Consts.push_back((Index << 2) | Chan);
641*9880d681SAndroid Build Coastguard Worker       }
642*9880d681SAndroid Build Coastguard Worker     }
643*9880d681SAndroid Build Coastguard Worker   }
644*9880d681SAndroid Build Coastguard Worker   return fitsConstReadLimitations(Consts);
645*9880d681SAndroid Build Coastguard Worker }
646*9880d681SAndroid Build Coastguard Worker 
647*9880d681SAndroid Build Coastguard Worker DFAPacketizer *
CreateTargetScheduleState(const TargetSubtargetInfo & STI) const648*9880d681SAndroid Build Coastguard Worker R600InstrInfo::CreateTargetScheduleState(const TargetSubtargetInfo &STI) const {
649*9880d681SAndroid Build Coastguard Worker   const InstrItineraryData *II = STI.getInstrItineraryData();
650*9880d681SAndroid Build Coastguard Worker   return static_cast<const R600Subtarget &>(STI).createDFAPacketizer(II);
651*9880d681SAndroid Build Coastguard Worker }
652*9880d681SAndroid Build Coastguard Worker 
653*9880d681SAndroid Build Coastguard Worker static bool
isPredicateSetter(unsigned Opcode)654*9880d681SAndroid Build Coastguard Worker isPredicateSetter(unsigned Opcode) {
655*9880d681SAndroid Build Coastguard Worker   switch (Opcode) {
656*9880d681SAndroid Build Coastguard Worker   case AMDGPU::PRED_X:
657*9880d681SAndroid Build Coastguard Worker     return true;
658*9880d681SAndroid Build Coastguard Worker   default:
659*9880d681SAndroid Build Coastguard Worker     return false;
660*9880d681SAndroid Build Coastguard Worker   }
661*9880d681SAndroid Build Coastguard Worker }
662*9880d681SAndroid Build Coastguard Worker 
663*9880d681SAndroid Build Coastguard Worker static MachineInstr *
findFirstPredicateSetterFrom(MachineBasicBlock & MBB,MachineBasicBlock::iterator I)664*9880d681SAndroid Build Coastguard Worker findFirstPredicateSetterFrom(MachineBasicBlock &MBB,
665*9880d681SAndroid Build Coastguard Worker                              MachineBasicBlock::iterator I) {
666*9880d681SAndroid Build Coastguard Worker   while (I != MBB.begin()) {
667*9880d681SAndroid Build Coastguard Worker     --I;
668*9880d681SAndroid Build Coastguard Worker     MachineInstr &MI = *I;
669*9880d681SAndroid Build Coastguard Worker     if (isPredicateSetter(MI.getOpcode()))
670*9880d681SAndroid Build Coastguard Worker       return &MI;
671*9880d681SAndroid Build Coastguard Worker   }
672*9880d681SAndroid Build Coastguard Worker 
673*9880d681SAndroid Build Coastguard Worker   return nullptr;
674*9880d681SAndroid Build Coastguard Worker }
675*9880d681SAndroid Build Coastguard Worker 
676*9880d681SAndroid Build Coastguard Worker static
isJump(unsigned Opcode)677*9880d681SAndroid Build Coastguard Worker bool isJump(unsigned Opcode) {
678*9880d681SAndroid Build Coastguard Worker   return Opcode == AMDGPU::JUMP || Opcode == AMDGPU::JUMP_COND;
679*9880d681SAndroid Build Coastguard Worker }
680*9880d681SAndroid Build Coastguard Worker 
isBranch(unsigned Opcode)681*9880d681SAndroid Build Coastguard Worker static bool isBranch(unsigned Opcode) {
682*9880d681SAndroid Build Coastguard Worker   return Opcode == AMDGPU::BRANCH || Opcode == AMDGPU::BRANCH_COND_i32 ||
683*9880d681SAndroid Build Coastguard Worker       Opcode == AMDGPU::BRANCH_COND_f32;
684*9880d681SAndroid Build Coastguard Worker }
685*9880d681SAndroid Build Coastguard Worker 
analyzeBranch(MachineBasicBlock & MBB,MachineBasicBlock * & TBB,MachineBasicBlock * & FBB,SmallVectorImpl<MachineOperand> & Cond,bool AllowModify) const686*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::analyzeBranch(MachineBasicBlock &MBB,
687*9880d681SAndroid Build Coastguard Worker                                   MachineBasicBlock *&TBB,
688*9880d681SAndroid Build Coastguard Worker                                   MachineBasicBlock *&FBB,
689*9880d681SAndroid Build Coastguard Worker                                   SmallVectorImpl<MachineOperand> &Cond,
690*9880d681SAndroid Build Coastguard Worker                                   bool AllowModify) const {
691*9880d681SAndroid Build Coastguard Worker   // Most of the following comes from the ARM implementation of AnalyzeBranch
692*9880d681SAndroid Build Coastguard Worker 
693*9880d681SAndroid Build Coastguard Worker   // If the block has no terminators, it just falls into the block after it.
694*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
695*9880d681SAndroid Build Coastguard Worker   if (I == MBB.end())
696*9880d681SAndroid Build Coastguard Worker     return false;
697*9880d681SAndroid Build Coastguard Worker 
698*9880d681SAndroid Build Coastguard Worker   // AMDGPU::BRANCH* instructions are only available after isel and are not
699*9880d681SAndroid Build Coastguard Worker   // handled
700*9880d681SAndroid Build Coastguard Worker   if (isBranch(I->getOpcode()))
701*9880d681SAndroid Build Coastguard Worker     return true;
702*9880d681SAndroid Build Coastguard Worker   if (!isJump(static_cast<MachineInstr *>(I)->getOpcode())) {
703*9880d681SAndroid Build Coastguard Worker     return false;
704*9880d681SAndroid Build Coastguard Worker   }
705*9880d681SAndroid Build Coastguard Worker 
706*9880d681SAndroid Build Coastguard Worker   // Remove successive JUMP
707*9880d681SAndroid Build Coastguard Worker   while (I != MBB.begin() && std::prev(I)->getOpcode() == AMDGPU::JUMP) {
708*9880d681SAndroid Build Coastguard Worker       MachineBasicBlock::iterator PriorI = std::prev(I);
709*9880d681SAndroid Build Coastguard Worker       if (AllowModify)
710*9880d681SAndroid Build Coastguard Worker         I->removeFromParent();
711*9880d681SAndroid Build Coastguard Worker       I = PriorI;
712*9880d681SAndroid Build Coastguard Worker   }
713*9880d681SAndroid Build Coastguard Worker   MachineInstr &LastInst = *I;
714*9880d681SAndroid Build Coastguard Worker 
715*9880d681SAndroid Build Coastguard Worker   // If there is only one terminator instruction, process it.
716*9880d681SAndroid Build Coastguard Worker   unsigned LastOpc = LastInst.getOpcode();
717*9880d681SAndroid Build Coastguard Worker   if (I == MBB.begin() ||
718*9880d681SAndroid Build Coastguard Worker           !isJump(static_cast<MachineInstr *>(--I)->getOpcode())) {
719*9880d681SAndroid Build Coastguard Worker     if (LastOpc == AMDGPU::JUMP) {
720*9880d681SAndroid Build Coastguard Worker       TBB = LastInst.getOperand(0).getMBB();
721*9880d681SAndroid Build Coastguard Worker       return false;
722*9880d681SAndroid Build Coastguard Worker     } else if (LastOpc == AMDGPU::JUMP_COND) {
723*9880d681SAndroid Build Coastguard Worker       auto predSet = I;
724*9880d681SAndroid Build Coastguard Worker       while (!isPredicateSetter(predSet->getOpcode())) {
725*9880d681SAndroid Build Coastguard Worker         predSet = --I;
726*9880d681SAndroid Build Coastguard Worker       }
727*9880d681SAndroid Build Coastguard Worker       TBB = LastInst.getOperand(0).getMBB();
728*9880d681SAndroid Build Coastguard Worker       Cond.push_back(predSet->getOperand(1));
729*9880d681SAndroid Build Coastguard Worker       Cond.push_back(predSet->getOperand(2));
730*9880d681SAndroid Build Coastguard Worker       Cond.push_back(MachineOperand::CreateReg(AMDGPU::PRED_SEL_ONE, false));
731*9880d681SAndroid Build Coastguard Worker       return false;
732*9880d681SAndroid Build Coastguard Worker     }
733*9880d681SAndroid Build Coastguard Worker     return true;  // Can't handle indirect branch.
734*9880d681SAndroid Build Coastguard Worker   }
735*9880d681SAndroid Build Coastguard Worker 
736*9880d681SAndroid Build Coastguard Worker   // Get the instruction before it if it is a terminator.
737*9880d681SAndroid Build Coastguard Worker   MachineInstr &SecondLastInst = *I;
738*9880d681SAndroid Build Coastguard Worker   unsigned SecondLastOpc = SecondLastInst.getOpcode();
739*9880d681SAndroid Build Coastguard Worker 
740*9880d681SAndroid Build Coastguard Worker   // If the block ends with a B and a Bcc, handle it.
741*9880d681SAndroid Build Coastguard Worker   if (SecondLastOpc == AMDGPU::JUMP_COND && LastOpc == AMDGPU::JUMP) {
742*9880d681SAndroid Build Coastguard Worker     auto predSet = --I;
743*9880d681SAndroid Build Coastguard Worker     while (!isPredicateSetter(predSet->getOpcode())) {
744*9880d681SAndroid Build Coastguard Worker       predSet = --I;
745*9880d681SAndroid Build Coastguard Worker     }
746*9880d681SAndroid Build Coastguard Worker     TBB = SecondLastInst.getOperand(0).getMBB();
747*9880d681SAndroid Build Coastguard Worker     FBB = LastInst.getOperand(0).getMBB();
748*9880d681SAndroid Build Coastguard Worker     Cond.push_back(predSet->getOperand(1));
749*9880d681SAndroid Build Coastguard Worker     Cond.push_back(predSet->getOperand(2));
750*9880d681SAndroid Build Coastguard Worker     Cond.push_back(MachineOperand::CreateReg(AMDGPU::PRED_SEL_ONE, false));
751*9880d681SAndroid Build Coastguard Worker     return false;
752*9880d681SAndroid Build Coastguard Worker   }
753*9880d681SAndroid Build Coastguard Worker 
754*9880d681SAndroid Build Coastguard Worker   // Otherwise, can't handle this.
755*9880d681SAndroid Build Coastguard Worker   return true;
756*9880d681SAndroid Build Coastguard Worker }
757*9880d681SAndroid Build Coastguard Worker 
758*9880d681SAndroid Build Coastguard Worker static
FindLastAluClause(MachineBasicBlock & MBB)759*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator FindLastAluClause(MachineBasicBlock &MBB) {
760*9880d681SAndroid Build Coastguard Worker   for (MachineBasicBlock::reverse_iterator It = MBB.rbegin(), E = MBB.rend();
761*9880d681SAndroid Build Coastguard Worker       It != E; ++It) {
762*9880d681SAndroid Build Coastguard Worker     if (It->getOpcode() == AMDGPU::CF_ALU ||
763*9880d681SAndroid Build Coastguard Worker         It->getOpcode() == AMDGPU::CF_ALU_PUSH_BEFORE)
764*9880d681SAndroid Build Coastguard Worker       return std::prev(It.base());
765*9880d681SAndroid Build Coastguard Worker   }
766*9880d681SAndroid Build Coastguard Worker   return MBB.end();
767*9880d681SAndroid Build Coastguard Worker }
768*9880d681SAndroid Build Coastguard Worker 
InsertBranch(MachineBasicBlock & MBB,MachineBasicBlock * TBB,MachineBasicBlock * FBB,ArrayRef<MachineOperand> Cond,const DebugLoc & DL) const769*9880d681SAndroid Build Coastguard Worker unsigned R600InstrInfo::InsertBranch(MachineBasicBlock &MBB,
770*9880d681SAndroid Build Coastguard Worker                                      MachineBasicBlock *TBB,
771*9880d681SAndroid Build Coastguard Worker                                      MachineBasicBlock *FBB,
772*9880d681SAndroid Build Coastguard Worker                                      ArrayRef<MachineOperand> Cond,
773*9880d681SAndroid Build Coastguard Worker                                      const DebugLoc &DL) const {
774*9880d681SAndroid Build Coastguard Worker   assert(TBB && "InsertBranch must not be told to insert a fallthrough");
775*9880d681SAndroid Build Coastguard Worker 
776*9880d681SAndroid Build Coastguard Worker   if (!FBB) {
777*9880d681SAndroid Build Coastguard Worker     if (Cond.empty()) {
778*9880d681SAndroid Build Coastguard Worker       BuildMI(&MBB, DL, get(AMDGPU::JUMP)).addMBB(TBB);
779*9880d681SAndroid Build Coastguard Worker       return 1;
780*9880d681SAndroid Build Coastguard Worker     } else {
781*9880d681SAndroid Build Coastguard Worker       MachineInstr *PredSet = findFirstPredicateSetterFrom(MBB, MBB.end());
782*9880d681SAndroid Build Coastguard Worker       assert(PredSet && "No previous predicate !");
783*9880d681SAndroid Build Coastguard Worker       addFlag(*PredSet, 0, MO_FLAG_PUSH);
784*9880d681SAndroid Build Coastguard Worker       PredSet->getOperand(2).setImm(Cond[1].getImm());
785*9880d681SAndroid Build Coastguard Worker 
786*9880d681SAndroid Build Coastguard Worker       BuildMI(&MBB, DL, get(AMDGPU::JUMP_COND))
787*9880d681SAndroid Build Coastguard Worker              .addMBB(TBB)
788*9880d681SAndroid Build Coastguard Worker              .addReg(AMDGPU::PREDICATE_BIT, RegState::Kill);
789*9880d681SAndroid Build Coastguard Worker       MachineBasicBlock::iterator CfAlu = FindLastAluClause(MBB);
790*9880d681SAndroid Build Coastguard Worker       if (CfAlu == MBB.end())
791*9880d681SAndroid Build Coastguard Worker         return 1;
792*9880d681SAndroid Build Coastguard Worker       assert (CfAlu->getOpcode() == AMDGPU::CF_ALU);
793*9880d681SAndroid Build Coastguard Worker       CfAlu->setDesc(get(AMDGPU::CF_ALU_PUSH_BEFORE));
794*9880d681SAndroid Build Coastguard Worker       return 1;
795*9880d681SAndroid Build Coastguard Worker     }
796*9880d681SAndroid Build Coastguard Worker   } else {
797*9880d681SAndroid Build Coastguard Worker     MachineInstr *PredSet = findFirstPredicateSetterFrom(MBB, MBB.end());
798*9880d681SAndroid Build Coastguard Worker     assert(PredSet && "No previous predicate !");
799*9880d681SAndroid Build Coastguard Worker     addFlag(*PredSet, 0, MO_FLAG_PUSH);
800*9880d681SAndroid Build Coastguard Worker     PredSet->getOperand(2).setImm(Cond[1].getImm());
801*9880d681SAndroid Build Coastguard Worker     BuildMI(&MBB, DL, get(AMDGPU::JUMP_COND))
802*9880d681SAndroid Build Coastguard Worker             .addMBB(TBB)
803*9880d681SAndroid Build Coastguard Worker             .addReg(AMDGPU::PREDICATE_BIT, RegState::Kill);
804*9880d681SAndroid Build Coastguard Worker     BuildMI(&MBB, DL, get(AMDGPU::JUMP)).addMBB(FBB);
805*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock::iterator CfAlu = FindLastAluClause(MBB);
806*9880d681SAndroid Build Coastguard Worker     if (CfAlu == MBB.end())
807*9880d681SAndroid Build Coastguard Worker       return 2;
808*9880d681SAndroid Build Coastguard Worker     assert (CfAlu->getOpcode() == AMDGPU::CF_ALU);
809*9880d681SAndroid Build Coastguard Worker     CfAlu->setDesc(get(AMDGPU::CF_ALU_PUSH_BEFORE));
810*9880d681SAndroid Build Coastguard Worker     return 2;
811*9880d681SAndroid Build Coastguard Worker   }
812*9880d681SAndroid Build Coastguard Worker }
813*9880d681SAndroid Build Coastguard Worker 
814*9880d681SAndroid Build Coastguard Worker unsigned
RemoveBranch(MachineBasicBlock & MBB) const815*9880d681SAndroid Build Coastguard Worker R600InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
816*9880d681SAndroid Build Coastguard Worker 
817*9880d681SAndroid Build Coastguard Worker   // Note : we leave PRED* instructions there.
818*9880d681SAndroid Build Coastguard Worker   // They may be needed when predicating instructions.
819*9880d681SAndroid Build Coastguard Worker 
820*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::iterator I = MBB.end();
821*9880d681SAndroid Build Coastguard Worker 
822*9880d681SAndroid Build Coastguard Worker   if (I == MBB.begin()) {
823*9880d681SAndroid Build Coastguard Worker     return 0;
824*9880d681SAndroid Build Coastguard Worker   }
825*9880d681SAndroid Build Coastguard Worker   --I;
826*9880d681SAndroid Build Coastguard Worker   switch (I->getOpcode()) {
827*9880d681SAndroid Build Coastguard Worker   default:
828*9880d681SAndroid Build Coastguard Worker     return 0;
829*9880d681SAndroid Build Coastguard Worker   case AMDGPU::JUMP_COND: {
830*9880d681SAndroid Build Coastguard Worker     MachineInstr *predSet = findFirstPredicateSetterFrom(MBB, I);
831*9880d681SAndroid Build Coastguard Worker     clearFlag(*predSet, 0, MO_FLAG_PUSH);
832*9880d681SAndroid Build Coastguard Worker     I->eraseFromParent();
833*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock::iterator CfAlu = FindLastAluClause(MBB);
834*9880d681SAndroid Build Coastguard Worker     if (CfAlu == MBB.end())
835*9880d681SAndroid Build Coastguard Worker       break;
836*9880d681SAndroid Build Coastguard Worker     assert (CfAlu->getOpcode() == AMDGPU::CF_ALU_PUSH_BEFORE);
837*9880d681SAndroid Build Coastguard Worker     CfAlu->setDesc(get(AMDGPU::CF_ALU));
838*9880d681SAndroid Build Coastguard Worker     break;
839*9880d681SAndroid Build Coastguard Worker   }
840*9880d681SAndroid Build Coastguard Worker   case AMDGPU::JUMP:
841*9880d681SAndroid Build Coastguard Worker     I->eraseFromParent();
842*9880d681SAndroid Build Coastguard Worker     break;
843*9880d681SAndroid Build Coastguard Worker   }
844*9880d681SAndroid Build Coastguard Worker   I = MBB.end();
845*9880d681SAndroid Build Coastguard Worker 
846*9880d681SAndroid Build Coastguard Worker   if (I == MBB.begin()) {
847*9880d681SAndroid Build Coastguard Worker     return 1;
848*9880d681SAndroid Build Coastguard Worker   }
849*9880d681SAndroid Build Coastguard Worker   --I;
850*9880d681SAndroid Build Coastguard Worker   switch (I->getOpcode()) {
851*9880d681SAndroid Build Coastguard Worker     // FIXME: only one case??
852*9880d681SAndroid Build Coastguard Worker   default:
853*9880d681SAndroid Build Coastguard Worker     return 1;
854*9880d681SAndroid Build Coastguard Worker   case AMDGPU::JUMP_COND: {
855*9880d681SAndroid Build Coastguard Worker     MachineInstr *predSet = findFirstPredicateSetterFrom(MBB, I);
856*9880d681SAndroid Build Coastguard Worker     clearFlag(*predSet, 0, MO_FLAG_PUSH);
857*9880d681SAndroid Build Coastguard Worker     I->eraseFromParent();
858*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock::iterator CfAlu = FindLastAluClause(MBB);
859*9880d681SAndroid Build Coastguard Worker     if (CfAlu == MBB.end())
860*9880d681SAndroid Build Coastguard Worker       break;
861*9880d681SAndroid Build Coastguard Worker     assert (CfAlu->getOpcode() == AMDGPU::CF_ALU_PUSH_BEFORE);
862*9880d681SAndroid Build Coastguard Worker     CfAlu->setDesc(get(AMDGPU::CF_ALU));
863*9880d681SAndroid Build Coastguard Worker     break;
864*9880d681SAndroid Build Coastguard Worker   }
865*9880d681SAndroid Build Coastguard Worker   case AMDGPU::JUMP:
866*9880d681SAndroid Build Coastguard Worker     I->eraseFromParent();
867*9880d681SAndroid Build Coastguard Worker     break;
868*9880d681SAndroid Build Coastguard Worker   }
869*9880d681SAndroid Build Coastguard Worker   return 2;
870*9880d681SAndroid Build Coastguard Worker }
871*9880d681SAndroid Build Coastguard Worker 
isPredicated(const MachineInstr & MI) const872*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::isPredicated(const MachineInstr &MI) const {
873*9880d681SAndroid Build Coastguard Worker   int idx = MI.findFirstPredOperandIdx();
874*9880d681SAndroid Build Coastguard Worker   if (idx < 0)
875*9880d681SAndroid Build Coastguard Worker     return false;
876*9880d681SAndroid Build Coastguard Worker 
877*9880d681SAndroid Build Coastguard Worker   unsigned Reg = MI.getOperand(idx).getReg();
878*9880d681SAndroid Build Coastguard Worker   switch (Reg) {
879*9880d681SAndroid Build Coastguard Worker   default: return false;
880*9880d681SAndroid Build Coastguard Worker   case AMDGPU::PRED_SEL_ONE:
881*9880d681SAndroid Build Coastguard Worker   case AMDGPU::PRED_SEL_ZERO:
882*9880d681SAndroid Build Coastguard Worker   case AMDGPU::PREDICATE_BIT:
883*9880d681SAndroid Build Coastguard Worker     return true;
884*9880d681SAndroid Build Coastguard Worker   }
885*9880d681SAndroid Build Coastguard Worker }
886*9880d681SAndroid Build Coastguard Worker 
isPredicable(MachineInstr & MI) const887*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::isPredicable(MachineInstr &MI) const {
888*9880d681SAndroid Build Coastguard Worker   // XXX: KILL* instructions can be predicated, but they must be the last
889*9880d681SAndroid Build Coastguard Worker   // instruction in a clause, so this means any instructions after them cannot
890*9880d681SAndroid Build Coastguard Worker   // be predicated.  Until we have proper support for instruction clauses in the
891*9880d681SAndroid Build Coastguard Worker   // backend, we will mark KILL* instructions as unpredicable.
892*9880d681SAndroid Build Coastguard Worker 
893*9880d681SAndroid Build Coastguard Worker   if (MI.getOpcode() == AMDGPU::KILLGT) {
894*9880d681SAndroid Build Coastguard Worker     return false;
895*9880d681SAndroid Build Coastguard Worker   } else if (MI.getOpcode() == AMDGPU::CF_ALU) {
896*9880d681SAndroid Build Coastguard Worker     // If the clause start in the middle of MBB then the MBB has more
897*9880d681SAndroid Build Coastguard Worker     // than a single clause, unable to predicate several clauses.
898*9880d681SAndroid Build Coastguard Worker     if (MI.getParent()->begin() != MachineBasicBlock::iterator(MI))
899*9880d681SAndroid Build Coastguard Worker       return false;
900*9880d681SAndroid Build Coastguard Worker     // TODO: We don't support KC merging atm
901*9880d681SAndroid Build Coastguard Worker     return MI.getOperand(3).getImm() == 0 && MI.getOperand(4).getImm() == 0;
902*9880d681SAndroid Build Coastguard Worker   } else if (isVector(MI)) {
903*9880d681SAndroid Build Coastguard Worker     return false;
904*9880d681SAndroid Build Coastguard Worker   } else {
905*9880d681SAndroid Build Coastguard Worker     return AMDGPUInstrInfo::isPredicable(MI);
906*9880d681SAndroid Build Coastguard Worker   }
907*9880d681SAndroid Build Coastguard Worker }
908*9880d681SAndroid Build Coastguard Worker 
909*9880d681SAndroid Build Coastguard Worker 
910*9880d681SAndroid Build Coastguard Worker bool
isProfitableToIfCvt(MachineBasicBlock & MBB,unsigned NumCyles,unsigned ExtraPredCycles,BranchProbability Probability) const911*9880d681SAndroid Build Coastguard Worker R600InstrInfo::isProfitableToIfCvt(MachineBasicBlock &MBB,
912*9880d681SAndroid Build Coastguard Worker                                    unsigned NumCyles,
913*9880d681SAndroid Build Coastguard Worker                                    unsigned ExtraPredCycles,
914*9880d681SAndroid Build Coastguard Worker                                    BranchProbability Probability) const{
915*9880d681SAndroid Build Coastguard Worker   return true;
916*9880d681SAndroid Build Coastguard Worker }
917*9880d681SAndroid Build Coastguard Worker 
918*9880d681SAndroid Build Coastguard Worker bool
isProfitableToIfCvt(MachineBasicBlock & TMBB,unsigned NumTCycles,unsigned ExtraTCycles,MachineBasicBlock & FMBB,unsigned NumFCycles,unsigned ExtraFCycles,BranchProbability Probability) const919*9880d681SAndroid Build Coastguard Worker R600InstrInfo::isProfitableToIfCvt(MachineBasicBlock &TMBB,
920*9880d681SAndroid Build Coastguard Worker                                    unsigned NumTCycles,
921*9880d681SAndroid Build Coastguard Worker                                    unsigned ExtraTCycles,
922*9880d681SAndroid Build Coastguard Worker                                    MachineBasicBlock &FMBB,
923*9880d681SAndroid Build Coastguard Worker                                    unsigned NumFCycles,
924*9880d681SAndroid Build Coastguard Worker                                    unsigned ExtraFCycles,
925*9880d681SAndroid Build Coastguard Worker                                    BranchProbability Probability) const {
926*9880d681SAndroid Build Coastguard Worker   return true;
927*9880d681SAndroid Build Coastguard Worker }
928*9880d681SAndroid Build Coastguard Worker 
929*9880d681SAndroid Build Coastguard Worker bool
isProfitableToDupForIfCvt(MachineBasicBlock & MBB,unsigned NumCyles,BranchProbability Probability) const930*9880d681SAndroid Build Coastguard Worker R600InstrInfo::isProfitableToDupForIfCvt(MachineBasicBlock &MBB,
931*9880d681SAndroid Build Coastguard Worker                                          unsigned NumCyles,
932*9880d681SAndroid Build Coastguard Worker                                          BranchProbability Probability)
933*9880d681SAndroid Build Coastguard Worker                                          const {
934*9880d681SAndroid Build Coastguard Worker   return true;
935*9880d681SAndroid Build Coastguard Worker }
936*9880d681SAndroid Build Coastguard Worker 
937*9880d681SAndroid Build Coastguard Worker bool
isProfitableToUnpredicate(MachineBasicBlock & TMBB,MachineBasicBlock & FMBB) const938*9880d681SAndroid Build Coastguard Worker R600InstrInfo::isProfitableToUnpredicate(MachineBasicBlock &TMBB,
939*9880d681SAndroid Build Coastguard Worker                                          MachineBasicBlock &FMBB) const {
940*9880d681SAndroid Build Coastguard Worker   return false;
941*9880d681SAndroid Build Coastguard Worker }
942*9880d681SAndroid Build Coastguard Worker 
943*9880d681SAndroid Build Coastguard Worker 
944*9880d681SAndroid Build Coastguard Worker bool
ReverseBranchCondition(SmallVectorImpl<MachineOperand> & Cond) const945*9880d681SAndroid Build Coastguard Worker R600InstrInfo::ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
946*9880d681SAndroid Build Coastguard Worker   MachineOperand &MO = Cond[1];
947*9880d681SAndroid Build Coastguard Worker   switch (MO.getImm()) {
948*9880d681SAndroid Build Coastguard Worker   case OPCODE_IS_ZERO_INT:
949*9880d681SAndroid Build Coastguard Worker     MO.setImm(OPCODE_IS_NOT_ZERO_INT);
950*9880d681SAndroid Build Coastguard Worker     break;
951*9880d681SAndroid Build Coastguard Worker   case OPCODE_IS_NOT_ZERO_INT:
952*9880d681SAndroid Build Coastguard Worker     MO.setImm(OPCODE_IS_ZERO_INT);
953*9880d681SAndroid Build Coastguard Worker     break;
954*9880d681SAndroid Build Coastguard Worker   case OPCODE_IS_ZERO:
955*9880d681SAndroid Build Coastguard Worker     MO.setImm(OPCODE_IS_NOT_ZERO);
956*9880d681SAndroid Build Coastguard Worker     break;
957*9880d681SAndroid Build Coastguard Worker   case OPCODE_IS_NOT_ZERO:
958*9880d681SAndroid Build Coastguard Worker     MO.setImm(OPCODE_IS_ZERO);
959*9880d681SAndroid Build Coastguard Worker     break;
960*9880d681SAndroid Build Coastguard Worker   default:
961*9880d681SAndroid Build Coastguard Worker     return true;
962*9880d681SAndroid Build Coastguard Worker   }
963*9880d681SAndroid Build Coastguard Worker 
964*9880d681SAndroid Build Coastguard Worker   MachineOperand &MO2 = Cond[2];
965*9880d681SAndroid Build Coastguard Worker   switch (MO2.getReg()) {
966*9880d681SAndroid Build Coastguard Worker   case AMDGPU::PRED_SEL_ZERO:
967*9880d681SAndroid Build Coastguard Worker     MO2.setReg(AMDGPU::PRED_SEL_ONE);
968*9880d681SAndroid Build Coastguard Worker     break;
969*9880d681SAndroid Build Coastguard Worker   case AMDGPU::PRED_SEL_ONE:
970*9880d681SAndroid Build Coastguard Worker     MO2.setReg(AMDGPU::PRED_SEL_ZERO);
971*9880d681SAndroid Build Coastguard Worker     break;
972*9880d681SAndroid Build Coastguard Worker   default:
973*9880d681SAndroid Build Coastguard Worker     return true;
974*9880d681SAndroid Build Coastguard Worker   }
975*9880d681SAndroid Build Coastguard Worker   return false;
976*9880d681SAndroid Build Coastguard Worker }
977*9880d681SAndroid Build Coastguard Worker 
DefinesPredicate(MachineInstr & MI,std::vector<MachineOperand> & Pred) const978*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::DefinesPredicate(MachineInstr &MI,
979*9880d681SAndroid Build Coastguard Worker                                      std::vector<MachineOperand> &Pred) const {
980*9880d681SAndroid Build Coastguard Worker   return isPredicateSetter(MI.getOpcode());
981*9880d681SAndroid Build Coastguard Worker }
982*9880d681SAndroid Build Coastguard Worker 
983*9880d681SAndroid Build Coastguard Worker 
984*9880d681SAndroid Build Coastguard Worker bool
SubsumesPredicate(ArrayRef<MachineOperand> Pred1,ArrayRef<MachineOperand> Pred2) const985*9880d681SAndroid Build Coastguard Worker R600InstrInfo::SubsumesPredicate(ArrayRef<MachineOperand> Pred1,
986*9880d681SAndroid Build Coastguard Worker                                  ArrayRef<MachineOperand> Pred2) const {
987*9880d681SAndroid Build Coastguard Worker   return false;
988*9880d681SAndroid Build Coastguard Worker }
989*9880d681SAndroid Build Coastguard Worker 
PredicateInstruction(MachineInstr & MI,ArrayRef<MachineOperand> Pred) const990*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::PredicateInstruction(MachineInstr &MI,
991*9880d681SAndroid Build Coastguard Worker                                          ArrayRef<MachineOperand> Pred) const {
992*9880d681SAndroid Build Coastguard Worker   int PIdx = MI.findFirstPredOperandIdx();
993*9880d681SAndroid Build Coastguard Worker 
994*9880d681SAndroid Build Coastguard Worker   if (MI.getOpcode() == AMDGPU::CF_ALU) {
995*9880d681SAndroid Build Coastguard Worker     MI.getOperand(8).setImm(0);
996*9880d681SAndroid Build Coastguard Worker     return true;
997*9880d681SAndroid Build Coastguard Worker   }
998*9880d681SAndroid Build Coastguard Worker 
999*9880d681SAndroid Build Coastguard Worker   if (MI.getOpcode() == AMDGPU::DOT_4) {
1000*9880d681SAndroid Build Coastguard Worker     MI.getOperand(getOperandIdx(MI, AMDGPU::OpName::pred_sel_X))
1001*9880d681SAndroid Build Coastguard Worker         .setReg(Pred[2].getReg());
1002*9880d681SAndroid Build Coastguard Worker     MI.getOperand(getOperandIdx(MI, AMDGPU::OpName::pred_sel_Y))
1003*9880d681SAndroid Build Coastguard Worker         .setReg(Pred[2].getReg());
1004*9880d681SAndroid Build Coastguard Worker     MI.getOperand(getOperandIdx(MI, AMDGPU::OpName::pred_sel_Z))
1005*9880d681SAndroid Build Coastguard Worker         .setReg(Pred[2].getReg());
1006*9880d681SAndroid Build Coastguard Worker     MI.getOperand(getOperandIdx(MI, AMDGPU::OpName::pred_sel_W))
1007*9880d681SAndroid Build Coastguard Worker         .setReg(Pred[2].getReg());
1008*9880d681SAndroid Build Coastguard Worker     MachineInstrBuilder MIB(*MI.getParent()->getParent(), MI);
1009*9880d681SAndroid Build Coastguard Worker     MIB.addReg(AMDGPU::PREDICATE_BIT, RegState::Implicit);
1010*9880d681SAndroid Build Coastguard Worker     return true;
1011*9880d681SAndroid Build Coastguard Worker   }
1012*9880d681SAndroid Build Coastguard Worker 
1013*9880d681SAndroid Build Coastguard Worker   if (PIdx != -1) {
1014*9880d681SAndroid Build Coastguard Worker     MachineOperand &PMO = MI.getOperand(PIdx);
1015*9880d681SAndroid Build Coastguard Worker     PMO.setReg(Pred[2].getReg());
1016*9880d681SAndroid Build Coastguard Worker     MachineInstrBuilder MIB(*MI.getParent()->getParent(), MI);
1017*9880d681SAndroid Build Coastguard Worker     MIB.addReg(AMDGPU::PREDICATE_BIT, RegState::Implicit);
1018*9880d681SAndroid Build Coastguard Worker     return true;
1019*9880d681SAndroid Build Coastguard Worker   }
1020*9880d681SAndroid Build Coastguard Worker 
1021*9880d681SAndroid Build Coastguard Worker   return false;
1022*9880d681SAndroid Build Coastguard Worker }
1023*9880d681SAndroid Build Coastguard Worker 
getPredicationCost(const MachineInstr &) const1024*9880d681SAndroid Build Coastguard Worker unsigned int R600InstrInfo::getPredicationCost(const MachineInstr &) const {
1025*9880d681SAndroid Build Coastguard Worker   return 2;
1026*9880d681SAndroid Build Coastguard Worker }
1027*9880d681SAndroid Build Coastguard Worker 
getInstrLatency(const InstrItineraryData * ItinData,const MachineInstr &,unsigned * PredCost) const1028*9880d681SAndroid Build Coastguard Worker unsigned int R600InstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
1029*9880d681SAndroid Build Coastguard Worker                                             const MachineInstr &,
1030*9880d681SAndroid Build Coastguard Worker                                             unsigned *PredCost) const {
1031*9880d681SAndroid Build Coastguard Worker   if (PredCost)
1032*9880d681SAndroid Build Coastguard Worker     *PredCost = 2;
1033*9880d681SAndroid Build Coastguard Worker   return 2;
1034*9880d681SAndroid Build Coastguard Worker }
1035*9880d681SAndroid Build Coastguard Worker 
calculateIndirectAddress(unsigned RegIndex,unsigned Channel) const1036*9880d681SAndroid Build Coastguard Worker unsigned R600InstrInfo::calculateIndirectAddress(unsigned RegIndex,
1037*9880d681SAndroid Build Coastguard Worker                                                    unsigned Channel) const {
1038*9880d681SAndroid Build Coastguard Worker   assert(Channel == 0);
1039*9880d681SAndroid Build Coastguard Worker   return RegIndex;
1040*9880d681SAndroid Build Coastguard Worker }
1041*9880d681SAndroid Build Coastguard Worker 
expandPostRAPseudo(MachineInstr & MI) const1042*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
1043*9880d681SAndroid Build Coastguard Worker   switch (MI.getOpcode()) {
1044*9880d681SAndroid Build Coastguard Worker   default: {
1045*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock *MBB = MI.getParent();
1046*9880d681SAndroid Build Coastguard Worker     int OffsetOpIdx =
1047*9880d681SAndroid Build Coastguard Worker         AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::addr);
1048*9880d681SAndroid Build Coastguard Worker     // addr is a custom operand with multiple MI operands, and only the
1049*9880d681SAndroid Build Coastguard Worker     // first MI operand is given a name.
1050*9880d681SAndroid Build Coastguard Worker     int RegOpIdx = OffsetOpIdx + 1;
1051*9880d681SAndroid Build Coastguard Worker     int ChanOpIdx =
1052*9880d681SAndroid Build Coastguard Worker         AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::chan);
1053*9880d681SAndroid Build Coastguard Worker     if (isRegisterLoad(MI)) {
1054*9880d681SAndroid Build Coastguard Worker       int DstOpIdx =
1055*9880d681SAndroid Build Coastguard Worker           AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::dst);
1056*9880d681SAndroid Build Coastguard Worker       unsigned RegIndex = MI.getOperand(RegOpIdx).getImm();
1057*9880d681SAndroid Build Coastguard Worker       unsigned Channel = MI.getOperand(ChanOpIdx).getImm();
1058*9880d681SAndroid Build Coastguard Worker       unsigned Address = calculateIndirectAddress(RegIndex, Channel);
1059*9880d681SAndroid Build Coastguard Worker       unsigned OffsetReg = MI.getOperand(OffsetOpIdx).getReg();
1060*9880d681SAndroid Build Coastguard Worker       if (OffsetReg == AMDGPU::INDIRECT_BASE_ADDR) {
1061*9880d681SAndroid Build Coastguard Worker         buildMovInstr(MBB, MI, MI.getOperand(DstOpIdx).getReg(),
1062*9880d681SAndroid Build Coastguard Worker                       getIndirectAddrRegClass()->getRegister(Address));
1063*9880d681SAndroid Build Coastguard Worker       } else {
1064*9880d681SAndroid Build Coastguard Worker         buildIndirectRead(MBB, MI, MI.getOperand(DstOpIdx).getReg(), Address,
1065*9880d681SAndroid Build Coastguard Worker                           OffsetReg);
1066*9880d681SAndroid Build Coastguard Worker       }
1067*9880d681SAndroid Build Coastguard Worker     } else if (isRegisterStore(MI)) {
1068*9880d681SAndroid Build Coastguard Worker       int ValOpIdx =
1069*9880d681SAndroid Build Coastguard Worker           AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::val);
1070*9880d681SAndroid Build Coastguard Worker       unsigned RegIndex = MI.getOperand(RegOpIdx).getImm();
1071*9880d681SAndroid Build Coastguard Worker       unsigned Channel = MI.getOperand(ChanOpIdx).getImm();
1072*9880d681SAndroid Build Coastguard Worker       unsigned Address = calculateIndirectAddress(RegIndex, Channel);
1073*9880d681SAndroid Build Coastguard Worker       unsigned OffsetReg = MI.getOperand(OffsetOpIdx).getReg();
1074*9880d681SAndroid Build Coastguard Worker       if (OffsetReg == AMDGPU::INDIRECT_BASE_ADDR) {
1075*9880d681SAndroid Build Coastguard Worker         buildMovInstr(MBB, MI, getIndirectAddrRegClass()->getRegister(Address),
1076*9880d681SAndroid Build Coastguard Worker                       MI.getOperand(ValOpIdx).getReg());
1077*9880d681SAndroid Build Coastguard Worker       } else {
1078*9880d681SAndroid Build Coastguard Worker         buildIndirectWrite(MBB, MI, MI.getOperand(ValOpIdx).getReg(),
1079*9880d681SAndroid Build Coastguard Worker                            calculateIndirectAddress(RegIndex, Channel),
1080*9880d681SAndroid Build Coastguard Worker                            OffsetReg);
1081*9880d681SAndroid Build Coastguard Worker       }
1082*9880d681SAndroid Build Coastguard Worker     } else {
1083*9880d681SAndroid Build Coastguard Worker       return false;
1084*9880d681SAndroid Build Coastguard Worker     }
1085*9880d681SAndroid Build Coastguard Worker 
1086*9880d681SAndroid Build Coastguard Worker     MBB->erase(MI);
1087*9880d681SAndroid Build Coastguard Worker     return true;
1088*9880d681SAndroid Build Coastguard Worker   }
1089*9880d681SAndroid Build Coastguard Worker   case AMDGPU::R600_EXTRACT_ELT_V2:
1090*9880d681SAndroid Build Coastguard Worker   case AMDGPU::R600_EXTRACT_ELT_V4:
1091*9880d681SAndroid Build Coastguard Worker     buildIndirectRead(MI.getParent(), MI, MI.getOperand(0).getReg(),
1092*9880d681SAndroid Build Coastguard Worker                       RI.getHWRegIndex(MI.getOperand(1).getReg()), //  Address
1093*9880d681SAndroid Build Coastguard Worker                       MI.getOperand(2).getReg(),
1094*9880d681SAndroid Build Coastguard Worker                       RI.getHWRegChan(MI.getOperand(1).getReg()));
1095*9880d681SAndroid Build Coastguard Worker     break;
1096*9880d681SAndroid Build Coastguard Worker   case AMDGPU::R600_INSERT_ELT_V2:
1097*9880d681SAndroid Build Coastguard Worker   case AMDGPU::R600_INSERT_ELT_V4:
1098*9880d681SAndroid Build Coastguard Worker     buildIndirectWrite(MI.getParent(), MI, MI.getOperand(2).getReg(), // Value
1099*9880d681SAndroid Build Coastguard Worker                        RI.getHWRegIndex(MI.getOperand(1).getReg()),   // Address
1100*9880d681SAndroid Build Coastguard Worker                        MI.getOperand(3).getReg(),                     // Offset
1101*9880d681SAndroid Build Coastguard Worker                        RI.getHWRegChan(MI.getOperand(1).getReg()));   // Channel
1102*9880d681SAndroid Build Coastguard Worker     break;
1103*9880d681SAndroid Build Coastguard Worker   }
1104*9880d681SAndroid Build Coastguard Worker   MI.eraseFromParent();
1105*9880d681SAndroid Build Coastguard Worker   return true;
1106*9880d681SAndroid Build Coastguard Worker }
1107*9880d681SAndroid Build Coastguard Worker 
reserveIndirectRegisters(BitVector & Reserved,const MachineFunction & MF) const1108*9880d681SAndroid Build Coastguard Worker void  R600InstrInfo::reserveIndirectRegisters(BitVector &Reserved,
1109*9880d681SAndroid Build Coastguard Worker                                              const MachineFunction &MF) const {
1110*9880d681SAndroid Build Coastguard Worker   const R600Subtarget &ST = MF.getSubtarget<R600Subtarget>();
1111*9880d681SAndroid Build Coastguard Worker   const R600FrameLowering *TFL = ST.getFrameLowering();
1112*9880d681SAndroid Build Coastguard Worker 
1113*9880d681SAndroid Build Coastguard Worker   unsigned StackWidth = TFL->getStackWidth(MF);
1114*9880d681SAndroid Build Coastguard Worker   int End = getIndirectIndexEnd(MF);
1115*9880d681SAndroid Build Coastguard Worker 
1116*9880d681SAndroid Build Coastguard Worker   if (End == -1)
1117*9880d681SAndroid Build Coastguard Worker     return;
1118*9880d681SAndroid Build Coastguard Worker 
1119*9880d681SAndroid Build Coastguard Worker   for (int Index = getIndirectIndexBegin(MF); Index <= End; ++Index) {
1120*9880d681SAndroid Build Coastguard Worker     unsigned SuperReg = AMDGPU::R600_Reg128RegClass.getRegister(Index);
1121*9880d681SAndroid Build Coastguard Worker     Reserved.set(SuperReg);
1122*9880d681SAndroid Build Coastguard Worker     for (unsigned Chan = 0; Chan < StackWidth; ++Chan) {
1123*9880d681SAndroid Build Coastguard Worker       unsigned Reg = AMDGPU::R600_TReg32RegClass.getRegister((4 * Index) + Chan);
1124*9880d681SAndroid Build Coastguard Worker       Reserved.set(Reg);
1125*9880d681SAndroid Build Coastguard Worker     }
1126*9880d681SAndroid Build Coastguard Worker   }
1127*9880d681SAndroid Build Coastguard Worker }
1128*9880d681SAndroid Build Coastguard Worker 
getIndirectAddrRegClass() const1129*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *R600InstrInfo::getIndirectAddrRegClass() const {
1130*9880d681SAndroid Build Coastguard Worker   return &AMDGPU::R600_TReg32_XRegClass;
1131*9880d681SAndroid Build Coastguard Worker }
1132*9880d681SAndroid Build Coastguard Worker 
buildIndirectWrite(MachineBasicBlock * MBB,MachineBasicBlock::iterator I,unsigned ValueReg,unsigned Address,unsigned OffsetReg) const1133*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder R600InstrInfo::buildIndirectWrite(MachineBasicBlock *MBB,
1134*9880d681SAndroid Build Coastguard Worker                                        MachineBasicBlock::iterator I,
1135*9880d681SAndroid Build Coastguard Worker                                        unsigned ValueReg, unsigned Address,
1136*9880d681SAndroid Build Coastguard Worker                                        unsigned OffsetReg) const {
1137*9880d681SAndroid Build Coastguard Worker   return buildIndirectWrite(MBB, I, ValueReg, Address, OffsetReg, 0);
1138*9880d681SAndroid Build Coastguard Worker }
1139*9880d681SAndroid Build Coastguard Worker 
buildIndirectWrite(MachineBasicBlock * MBB,MachineBasicBlock::iterator I,unsigned ValueReg,unsigned Address,unsigned OffsetReg,unsigned AddrChan) const1140*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder R600InstrInfo::buildIndirectWrite(MachineBasicBlock *MBB,
1141*9880d681SAndroid Build Coastguard Worker                                        MachineBasicBlock::iterator I,
1142*9880d681SAndroid Build Coastguard Worker                                        unsigned ValueReg, unsigned Address,
1143*9880d681SAndroid Build Coastguard Worker                                        unsigned OffsetReg,
1144*9880d681SAndroid Build Coastguard Worker                                        unsigned AddrChan) const {
1145*9880d681SAndroid Build Coastguard Worker   unsigned AddrReg;
1146*9880d681SAndroid Build Coastguard Worker   switch (AddrChan) {
1147*9880d681SAndroid Build Coastguard Worker     default: llvm_unreachable("Invalid Channel");
1148*9880d681SAndroid Build Coastguard Worker     case 0: AddrReg = AMDGPU::R600_AddrRegClass.getRegister(Address); break;
1149*9880d681SAndroid Build Coastguard Worker     case 1: AddrReg = AMDGPU::R600_Addr_YRegClass.getRegister(Address); break;
1150*9880d681SAndroid Build Coastguard Worker     case 2: AddrReg = AMDGPU::R600_Addr_ZRegClass.getRegister(Address); break;
1151*9880d681SAndroid Build Coastguard Worker     case 3: AddrReg = AMDGPU::R600_Addr_WRegClass.getRegister(Address); break;
1152*9880d681SAndroid Build Coastguard Worker   }
1153*9880d681SAndroid Build Coastguard Worker   MachineInstr *MOVA = buildDefaultInstruction(*MBB, I, AMDGPU::MOVA_INT_eg,
1154*9880d681SAndroid Build Coastguard Worker                                                AMDGPU::AR_X, OffsetReg);
1155*9880d681SAndroid Build Coastguard Worker   setImmOperand(*MOVA, AMDGPU::OpName::write, 0);
1156*9880d681SAndroid Build Coastguard Worker 
1157*9880d681SAndroid Build Coastguard Worker   MachineInstrBuilder Mov = buildDefaultInstruction(*MBB, I, AMDGPU::MOV,
1158*9880d681SAndroid Build Coastguard Worker                                       AddrReg, ValueReg)
1159*9880d681SAndroid Build Coastguard Worker                                       .addReg(AMDGPU::AR_X,
1160*9880d681SAndroid Build Coastguard Worker                                            RegState::Implicit | RegState::Kill);
1161*9880d681SAndroid Build Coastguard Worker   setImmOperand(*Mov, AMDGPU::OpName::dst_rel, 1);
1162*9880d681SAndroid Build Coastguard Worker   return Mov;
1163*9880d681SAndroid Build Coastguard Worker }
1164*9880d681SAndroid Build Coastguard Worker 
buildIndirectRead(MachineBasicBlock * MBB,MachineBasicBlock::iterator I,unsigned ValueReg,unsigned Address,unsigned OffsetReg) const1165*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder R600InstrInfo::buildIndirectRead(MachineBasicBlock *MBB,
1166*9880d681SAndroid Build Coastguard Worker                                        MachineBasicBlock::iterator I,
1167*9880d681SAndroid Build Coastguard Worker                                        unsigned ValueReg, unsigned Address,
1168*9880d681SAndroid Build Coastguard Worker                                        unsigned OffsetReg) const {
1169*9880d681SAndroid Build Coastguard Worker   return buildIndirectRead(MBB, I, ValueReg, Address, OffsetReg, 0);
1170*9880d681SAndroid Build Coastguard Worker }
1171*9880d681SAndroid Build Coastguard Worker 
buildIndirectRead(MachineBasicBlock * MBB,MachineBasicBlock::iterator I,unsigned ValueReg,unsigned Address,unsigned OffsetReg,unsigned AddrChan) const1172*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder R600InstrInfo::buildIndirectRead(MachineBasicBlock *MBB,
1173*9880d681SAndroid Build Coastguard Worker                                        MachineBasicBlock::iterator I,
1174*9880d681SAndroid Build Coastguard Worker                                        unsigned ValueReg, unsigned Address,
1175*9880d681SAndroid Build Coastguard Worker                                        unsigned OffsetReg,
1176*9880d681SAndroid Build Coastguard Worker                                        unsigned AddrChan) const {
1177*9880d681SAndroid Build Coastguard Worker   unsigned AddrReg;
1178*9880d681SAndroid Build Coastguard Worker   switch (AddrChan) {
1179*9880d681SAndroid Build Coastguard Worker     default: llvm_unreachable("Invalid Channel");
1180*9880d681SAndroid Build Coastguard Worker     case 0: AddrReg = AMDGPU::R600_AddrRegClass.getRegister(Address); break;
1181*9880d681SAndroid Build Coastguard Worker     case 1: AddrReg = AMDGPU::R600_Addr_YRegClass.getRegister(Address); break;
1182*9880d681SAndroid Build Coastguard Worker     case 2: AddrReg = AMDGPU::R600_Addr_ZRegClass.getRegister(Address); break;
1183*9880d681SAndroid Build Coastguard Worker     case 3: AddrReg = AMDGPU::R600_Addr_WRegClass.getRegister(Address); break;
1184*9880d681SAndroid Build Coastguard Worker   }
1185*9880d681SAndroid Build Coastguard Worker   MachineInstr *MOVA = buildDefaultInstruction(*MBB, I, AMDGPU::MOVA_INT_eg,
1186*9880d681SAndroid Build Coastguard Worker                                                        AMDGPU::AR_X,
1187*9880d681SAndroid Build Coastguard Worker                                                        OffsetReg);
1188*9880d681SAndroid Build Coastguard Worker   setImmOperand(*MOVA, AMDGPU::OpName::write, 0);
1189*9880d681SAndroid Build Coastguard Worker   MachineInstrBuilder Mov = buildDefaultInstruction(*MBB, I, AMDGPU::MOV,
1190*9880d681SAndroid Build Coastguard Worker                                       ValueReg,
1191*9880d681SAndroid Build Coastguard Worker                                       AddrReg)
1192*9880d681SAndroid Build Coastguard Worker                                       .addReg(AMDGPU::AR_X,
1193*9880d681SAndroid Build Coastguard Worker                                            RegState::Implicit | RegState::Kill);
1194*9880d681SAndroid Build Coastguard Worker   setImmOperand(*Mov, AMDGPU::OpName::src0_rel, 1);
1195*9880d681SAndroid Build Coastguard Worker 
1196*9880d681SAndroid Build Coastguard Worker   return Mov;
1197*9880d681SAndroid Build Coastguard Worker }
1198*9880d681SAndroid Build Coastguard Worker 
getIndirectIndexBegin(const MachineFunction & MF) const1199*9880d681SAndroid Build Coastguard Worker int R600InstrInfo::getIndirectIndexBegin(const MachineFunction &MF) const {
1200*9880d681SAndroid Build Coastguard Worker   const MachineRegisterInfo &MRI = MF.getRegInfo();
1201*9880d681SAndroid Build Coastguard Worker   const MachineFrameInfo *MFI = MF.getFrameInfo();
1202*9880d681SAndroid Build Coastguard Worker   int Offset = -1;
1203*9880d681SAndroid Build Coastguard Worker 
1204*9880d681SAndroid Build Coastguard Worker   if (MFI->getNumObjects() == 0) {
1205*9880d681SAndroid Build Coastguard Worker     return -1;
1206*9880d681SAndroid Build Coastguard Worker   }
1207*9880d681SAndroid Build Coastguard Worker 
1208*9880d681SAndroid Build Coastguard Worker   if (MRI.livein_empty()) {
1209*9880d681SAndroid Build Coastguard Worker     return 0;
1210*9880d681SAndroid Build Coastguard Worker   }
1211*9880d681SAndroid Build Coastguard Worker 
1212*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *IndirectRC = getIndirectAddrRegClass();
1213*9880d681SAndroid Build Coastguard Worker   for (MachineRegisterInfo::livein_iterator LI = MRI.livein_begin(),
1214*9880d681SAndroid Build Coastguard Worker                                             LE = MRI.livein_end();
1215*9880d681SAndroid Build Coastguard Worker                                             LI != LE; ++LI) {
1216*9880d681SAndroid Build Coastguard Worker     unsigned Reg = LI->first;
1217*9880d681SAndroid Build Coastguard Worker     if (TargetRegisterInfo::isVirtualRegister(Reg) ||
1218*9880d681SAndroid Build Coastguard Worker         !IndirectRC->contains(Reg))
1219*9880d681SAndroid Build Coastguard Worker       continue;
1220*9880d681SAndroid Build Coastguard Worker 
1221*9880d681SAndroid Build Coastguard Worker     unsigned RegIndex;
1222*9880d681SAndroid Build Coastguard Worker     unsigned RegEnd;
1223*9880d681SAndroid Build Coastguard Worker     for (RegIndex = 0, RegEnd = IndirectRC->getNumRegs(); RegIndex != RegEnd;
1224*9880d681SAndroid Build Coastguard Worker                                                           ++RegIndex) {
1225*9880d681SAndroid Build Coastguard Worker       if (IndirectRC->getRegister(RegIndex) == Reg)
1226*9880d681SAndroid Build Coastguard Worker         break;
1227*9880d681SAndroid Build Coastguard Worker     }
1228*9880d681SAndroid Build Coastguard Worker     Offset = std::max(Offset, (int)RegIndex);
1229*9880d681SAndroid Build Coastguard Worker   }
1230*9880d681SAndroid Build Coastguard Worker 
1231*9880d681SAndroid Build Coastguard Worker   return Offset + 1;
1232*9880d681SAndroid Build Coastguard Worker }
1233*9880d681SAndroid Build Coastguard Worker 
getIndirectIndexEnd(const MachineFunction & MF) const1234*9880d681SAndroid Build Coastguard Worker int R600InstrInfo::getIndirectIndexEnd(const MachineFunction &MF) const {
1235*9880d681SAndroid Build Coastguard Worker   int Offset = 0;
1236*9880d681SAndroid Build Coastguard Worker   const MachineFrameInfo *MFI = MF.getFrameInfo();
1237*9880d681SAndroid Build Coastguard Worker 
1238*9880d681SAndroid Build Coastguard Worker   // Variable sized objects are not supported
1239*9880d681SAndroid Build Coastguard Worker   if (MFI->hasVarSizedObjects()) {
1240*9880d681SAndroid Build Coastguard Worker     return -1;
1241*9880d681SAndroid Build Coastguard Worker   }
1242*9880d681SAndroid Build Coastguard Worker 
1243*9880d681SAndroid Build Coastguard Worker   if (MFI->getNumObjects() == 0) {
1244*9880d681SAndroid Build Coastguard Worker     return -1;
1245*9880d681SAndroid Build Coastguard Worker   }
1246*9880d681SAndroid Build Coastguard Worker 
1247*9880d681SAndroid Build Coastguard Worker   const R600Subtarget &ST = MF.getSubtarget<R600Subtarget>();
1248*9880d681SAndroid Build Coastguard Worker   const R600FrameLowering *TFL = ST.getFrameLowering();
1249*9880d681SAndroid Build Coastguard Worker 
1250*9880d681SAndroid Build Coastguard Worker   unsigned IgnoredFrameReg;
1251*9880d681SAndroid Build Coastguard Worker   Offset = TFL->getFrameIndexReference(MF, -1, IgnoredFrameReg);
1252*9880d681SAndroid Build Coastguard Worker 
1253*9880d681SAndroid Build Coastguard Worker   return getIndirectIndexBegin(MF) + Offset;
1254*9880d681SAndroid Build Coastguard Worker }
1255*9880d681SAndroid Build Coastguard Worker 
getMaxAlusPerClause() const1256*9880d681SAndroid Build Coastguard Worker unsigned R600InstrInfo::getMaxAlusPerClause() const {
1257*9880d681SAndroid Build Coastguard Worker   return 115;
1258*9880d681SAndroid Build Coastguard Worker }
1259*9880d681SAndroid Build Coastguard Worker 
buildDefaultInstruction(MachineBasicBlock & MBB,MachineBasicBlock::iterator I,unsigned Opcode,unsigned DstReg,unsigned Src0Reg,unsigned Src1Reg) const1260*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder R600InstrInfo::buildDefaultInstruction(MachineBasicBlock &MBB,
1261*9880d681SAndroid Build Coastguard Worker                                                   MachineBasicBlock::iterator I,
1262*9880d681SAndroid Build Coastguard Worker                                                   unsigned Opcode,
1263*9880d681SAndroid Build Coastguard Worker                                                   unsigned DstReg,
1264*9880d681SAndroid Build Coastguard Worker                                                   unsigned Src0Reg,
1265*9880d681SAndroid Build Coastguard Worker                                                   unsigned Src1Reg) const {
1266*9880d681SAndroid Build Coastguard Worker   MachineInstrBuilder MIB = BuildMI(MBB, I, MBB.findDebugLoc(I), get(Opcode),
1267*9880d681SAndroid Build Coastguard Worker     DstReg);           // $dst
1268*9880d681SAndroid Build Coastguard Worker 
1269*9880d681SAndroid Build Coastguard Worker   if (Src1Reg) {
1270*9880d681SAndroid Build Coastguard Worker     MIB.addImm(0)     // $update_exec_mask
1271*9880d681SAndroid Build Coastguard Worker        .addImm(0);    // $update_predicate
1272*9880d681SAndroid Build Coastguard Worker   }
1273*9880d681SAndroid Build Coastguard Worker   MIB.addImm(1)        // $write
1274*9880d681SAndroid Build Coastguard Worker      .addImm(0)        // $omod
1275*9880d681SAndroid Build Coastguard Worker      .addImm(0)        // $dst_rel
1276*9880d681SAndroid Build Coastguard Worker      .addImm(0)        // $dst_clamp
1277*9880d681SAndroid Build Coastguard Worker      .addReg(Src0Reg)  // $src0
1278*9880d681SAndroid Build Coastguard Worker      .addImm(0)        // $src0_neg
1279*9880d681SAndroid Build Coastguard Worker      .addImm(0)        // $src0_rel
1280*9880d681SAndroid Build Coastguard Worker      .addImm(0)        // $src0_abs
1281*9880d681SAndroid Build Coastguard Worker      .addImm(-1);       // $src0_sel
1282*9880d681SAndroid Build Coastguard Worker 
1283*9880d681SAndroid Build Coastguard Worker   if (Src1Reg) {
1284*9880d681SAndroid Build Coastguard Worker     MIB.addReg(Src1Reg) // $src1
1285*9880d681SAndroid Build Coastguard Worker        .addImm(0)       // $src1_neg
1286*9880d681SAndroid Build Coastguard Worker        .addImm(0)       // $src1_rel
1287*9880d681SAndroid Build Coastguard Worker        .addImm(0)       // $src1_abs
1288*9880d681SAndroid Build Coastguard Worker        .addImm(-1);      // $src1_sel
1289*9880d681SAndroid Build Coastguard Worker   }
1290*9880d681SAndroid Build Coastguard Worker 
1291*9880d681SAndroid Build Coastguard Worker   //XXX: The r600g finalizer expects this to be 1, once we've moved the
1292*9880d681SAndroid Build Coastguard Worker   //scheduling to the backend, we can change the default to 0.
1293*9880d681SAndroid Build Coastguard Worker   MIB.addImm(1)        // $last
1294*9880d681SAndroid Build Coastguard Worker       .addReg(AMDGPU::PRED_SEL_OFF) // $pred_sel
1295*9880d681SAndroid Build Coastguard Worker       .addImm(0)         // $literal
1296*9880d681SAndroid Build Coastguard Worker       .addImm(0);        // $bank_swizzle
1297*9880d681SAndroid Build Coastguard Worker 
1298*9880d681SAndroid Build Coastguard Worker   return MIB;
1299*9880d681SAndroid Build Coastguard Worker }
1300*9880d681SAndroid Build Coastguard Worker 
1301*9880d681SAndroid Build Coastguard Worker #define OPERAND_CASE(Label) \
1302*9880d681SAndroid Build Coastguard Worker   case Label: { \
1303*9880d681SAndroid Build Coastguard Worker     static const unsigned Ops[] = \
1304*9880d681SAndroid Build Coastguard Worker     { \
1305*9880d681SAndroid Build Coastguard Worker       Label##_X, \
1306*9880d681SAndroid Build Coastguard Worker       Label##_Y, \
1307*9880d681SAndroid Build Coastguard Worker       Label##_Z, \
1308*9880d681SAndroid Build Coastguard Worker       Label##_W \
1309*9880d681SAndroid Build Coastguard Worker     }; \
1310*9880d681SAndroid Build Coastguard Worker     return Ops[Slot]; \
1311*9880d681SAndroid Build Coastguard Worker   }
1312*9880d681SAndroid Build Coastguard Worker 
getSlotedOps(unsigned Op,unsigned Slot)1313*9880d681SAndroid Build Coastguard Worker static unsigned getSlotedOps(unsigned  Op, unsigned Slot) {
1314*9880d681SAndroid Build Coastguard Worker   switch (Op) {
1315*9880d681SAndroid Build Coastguard Worker   OPERAND_CASE(AMDGPU::OpName::update_exec_mask)
1316*9880d681SAndroid Build Coastguard Worker   OPERAND_CASE(AMDGPU::OpName::update_pred)
1317*9880d681SAndroid Build Coastguard Worker   OPERAND_CASE(AMDGPU::OpName::write)
1318*9880d681SAndroid Build Coastguard Worker   OPERAND_CASE(AMDGPU::OpName::omod)
1319*9880d681SAndroid Build Coastguard Worker   OPERAND_CASE(AMDGPU::OpName::dst_rel)
1320*9880d681SAndroid Build Coastguard Worker   OPERAND_CASE(AMDGPU::OpName::clamp)
1321*9880d681SAndroid Build Coastguard Worker   OPERAND_CASE(AMDGPU::OpName::src0)
1322*9880d681SAndroid Build Coastguard Worker   OPERAND_CASE(AMDGPU::OpName::src0_neg)
1323*9880d681SAndroid Build Coastguard Worker   OPERAND_CASE(AMDGPU::OpName::src0_rel)
1324*9880d681SAndroid Build Coastguard Worker   OPERAND_CASE(AMDGPU::OpName::src0_abs)
1325*9880d681SAndroid Build Coastguard Worker   OPERAND_CASE(AMDGPU::OpName::src0_sel)
1326*9880d681SAndroid Build Coastguard Worker   OPERAND_CASE(AMDGPU::OpName::src1)
1327*9880d681SAndroid Build Coastguard Worker   OPERAND_CASE(AMDGPU::OpName::src1_neg)
1328*9880d681SAndroid Build Coastguard Worker   OPERAND_CASE(AMDGPU::OpName::src1_rel)
1329*9880d681SAndroid Build Coastguard Worker   OPERAND_CASE(AMDGPU::OpName::src1_abs)
1330*9880d681SAndroid Build Coastguard Worker   OPERAND_CASE(AMDGPU::OpName::src1_sel)
1331*9880d681SAndroid Build Coastguard Worker   OPERAND_CASE(AMDGPU::OpName::pred_sel)
1332*9880d681SAndroid Build Coastguard Worker   default:
1333*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Wrong Operand");
1334*9880d681SAndroid Build Coastguard Worker   }
1335*9880d681SAndroid Build Coastguard Worker }
1336*9880d681SAndroid Build Coastguard Worker 
1337*9880d681SAndroid Build Coastguard Worker #undef OPERAND_CASE
1338*9880d681SAndroid Build Coastguard Worker 
buildSlotOfVectorInstruction(MachineBasicBlock & MBB,MachineInstr * MI,unsigned Slot,unsigned DstReg) const1339*9880d681SAndroid Build Coastguard Worker MachineInstr *R600InstrInfo::buildSlotOfVectorInstruction(
1340*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock &MBB, MachineInstr *MI, unsigned Slot, unsigned DstReg)
1341*9880d681SAndroid Build Coastguard Worker     const {
1342*9880d681SAndroid Build Coastguard Worker   assert (MI->getOpcode() == AMDGPU::DOT_4 && "Not Implemented");
1343*9880d681SAndroid Build Coastguard Worker   unsigned Opcode;
1344*9880d681SAndroid Build Coastguard Worker   if (ST.getGeneration() <= R600Subtarget::R700)
1345*9880d681SAndroid Build Coastguard Worker     Opcode = AMDGPU::DOT4_r600;
1346*9880d681SAndroid Build Coastguard Worker   else
1347*9880d681SAndroid Build Coastguard Worker     Opcode = AMDGPU::DOT4_eg;
1348*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::iterator I = MI;
1349*9880d681SAndroid Build Coastguard Worker   MachineOperand &Src0 = MI->getOperand(
1350*9880d681SAndroid Build Coastguard Worker       getOperandIdx(MI->getOpcode(), getSlotedOps(AMDGPU::OpName::src0, Slot)));
1351*9880d681SAndroid Build Coastguard Worker   MachineOperand &Src1 = MI->getOperand(
1352*9880d681SAndroid Build Coastguard Worker       getOperandIdx(MI->getOpcode(), getSlotedOps(AMDGPU::OpName::src1, Slot)));
1353*9880d681SAndroid Build Coastguard Worker   MachineInstr *MIB = buildDefaultInstruction(
1354*9880d681SAndroid Build Coastguard Worker       MBB, I, Opcode, DstReg, Src0.getReg(), Src1.getReg());
1355*9880d681SAndroid Build Coastguard Worker   static const unsigned  Operands[14] = {
1356*9880d681SAndroid Build Coastguard Worker     AMDGPU::OpName::update_exec_mask,
1357*9880d681SAndroid Build Coastguard Worker     AMDGPU::OpName::update_pred,
1358*9880d681SAndroid Build Coastguard Worker     AMDGPU::OpName::write,
1359*9880d681SAndroid Build Coastguard Worker     AMDGPU::OpName::omod,
1360*9880d681SAndroid Build Coastguard Worker     AMDGPU::OpName::dst_rel,
1361*9880d681SAndroid Build Coastguard Worker     AMDGPU::OpName::clamp,
1362*9880d681SAndroid Build Coastguard Worker     AMDGPU::OpName::src0_neg,
1363*9880d681SAndroid Build Coastguard Worker     AMDGPU::OpName::src0_rel,
1364*9880d681SAndroid Build Coastguard Worker     AMDGPU::OpName::src0_abs,
1365*9880d681SAndroid Build Coastguard Worker     AMDGPU::OpName::src0_sel,
1366*9880d681SAndroid Build Coastguard Worker     AMDGPU::OpName::src1_neg,
1367*9880d681SAndroid Build Coastguard Worker     AMDGPU::OpName::src1_rel,
1368*9880d681SAndroid Build Coastguard Worker     AMDGPU::OpName::src1_abs,
1369*9880d681SAndroid Build Coastguard Worker     AMDGPU::OpName::src1_sel,
1370*9880d681SAndroid Build Coastguard Worker   };
1371*9880d681SAndroid Build Coastguard Worker 
1372*9880d681SAndroid Build Coastguard Worker   MachineOperand &MO = MI->getOperand(getOperandIdx(MI->getOpcode(),
1373*9880d681SAndroid Build Coastguard Worker       getSlotedOps(AMDGPU::OpName::pred_sel, Slot)));
1374*9880d681SAndroid Build Coastguard Worker   MIB->getOperand(getOperandIdx(Opcode, AMDGPU::OpName::pred_sel))
1375*9880d681SAndroid Build Coastguard Worker       .setReg(MO.getReg());
1376*9880d681SAndroid Build Coastguard Worker 
1377*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0; i < 14; i++) {
1378*9880d681SAndroid Build Coastguard Worker     MachineOperand &MO = MI->getOperand(
1379*9880d681SAndroid Build Coastguard Worker         getOperandIdx(MI->getOpcode(), getSlotedOps(Operands[i], Slot)));
1380*9880d681SAndroid Build Coastguard Worker     assert (MO.isImm());
1381*9880d681SAndroid Build Coastguard Worker     setImmOperand(*MIB, Operands[i], MO.getImm());
1382*9880d681SAndroid Build Coastguard Worker   }
1383*9880d681SAndroid Build Coastguard Worker   MIB->getOperand(20).setImm(0);
1384*9880d681SAndroid Build Coastguard Worker   return MIB;
1385*9880d681SAndroid Build Coastguard Worker }
1386*9880d681SAndroid Build Coastguard Worker 
buildMovImm(MachineBasicBlock & BB,MachineBasicBlock::iterator I,unsigned DstReg,uint64_t Imm) const1387*9880d681SAndroid Build Coastguard Worker MachineInstr *R600InstrInfo::buildMovImm(MachineBasicBlock &BB,
1388*9880d681SAndroid Build Coastguard Worker                                          MachineBasicBlock::iterator I,
1389*9880d681SAndroid Build Coastguard Worker                                          unsigned DstReg,
1390*9880d681SAndroid Build Coastguard Worker                                          uint64_t Imm) const {
1391*9880d681SAndroid Build Coastguard Worker   MachineInstr *MovImm = buildDefaultInstruction(BB, I, AMDGPU::MOV, DstReg,
1392*9880d681SAndroid Build Coastguard Worker                                                   AMDGPU::ALU_LITERAL_X);
1393*9880d681SAndroid Build Coastguard Worker   setImmOperand(*MovImm, AMDGPU::OpName::literal, Imm);
1394*9880d681SAndroid Build Coastguard Worker   return MovImm;
1395*9880d681SAndroid Build Coastguard Worker }
1396*9880d681SAndroid Build Coastguard Worker 
buildMovInstr(MachineBasicBlock * MBB,MachineBasicBlock::iterator I,unsigned DstReg,unsigned SrcReg) const1397*9880d681SAndroid Build Coastguard Worker MachineInstr *R600InstrInfo::buildMovInstr(MachineBasicBlock *MBB,
1398*9880d681SAndroid Build Coastguard Worker                                        MachineBasicBlock::iterator I,
1399*9880d681SAndroid Build Coastguard Worker                                        unsigned DstReg, unsigned SrcReg) const {
1400*9880d681SAndroid Build Coastguard Worker   return buildDefaultInstruction(*MBB, I, AMDGPU::MOV, DstReg, SrcReg);
1401*9880d681SAndroid Build Coastguard Worker }
1402*9880d681SAndroid Build Coastguard Worker 
getOperandIdx(const MachineInstr & MI,unsigned Op) const1403*9880d681SAndroid Build Coastguard Worker int R600InstrInfo::getOperandIdx(const MachineInstr &MI, unsigned Op) const {
1404*9880d681SAndroid Build Coastguard Worker   return getOperandIdx(MI.getOpcode(), Op);
1405*9880d681SAndroid Build Coastguard Worker }
1406*9880d681SAndroid Build Coastguard Worker 
getOperandIdx(unsigned Opcode,unsigned Op) const1407*9880d681SAndroid Build Coastguard Worker int R600InstrInfo::getOperandIdx(unsigned Opcode, unsigned Op) const {
1408*9880d681SAndroid Build Coastguard Worker   return AMDGPU::getNamedOperandIdx(Opcode, Op);
1409*9880d681SAndroid Build Coastguard Worker }
1410*9880d681SAndroid Build Coastguard Worker 
setImmOperand(MachineInstr & MI,unsigned Op,int64_t Imm) const1411*9880d681SAndroid Build Coastguard Worker void R600InstrInfo::setImmOperand(MachineInstr &MI, unsigned Op,
1412*9880d681SAndroid Build Coastguard Worker                                   int64_t Imm) const {
1413*9880d681SAndroid Build Coastguard Worker   int Idx = getOperandIdx(MI, Op);
1414*9880d681SAndroid Build Coastguard Worker   assert(Idx != -1 && "Operand not supported for this instruction.");
1415*9880d681SAndroid Build Coastguard Worker   assert(MI.getOperand(Idx).isImm());
1416*9880d681SAndroid Build Coastguard Worker   MI.getOperand(Idx).setImm(Imm);
1417*9880d681SAndroid Build Coastguard Worker }
1418*9880d681SAndroid Build Coastguard Worker 
1419*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
1420*9880d681SAndroid Build Coastguard Worker // Instruction flag getters/setters
1421*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
1422*9880d681SAndroid Build Coastguard Worker 
hasFlagOperand(const MachineInstr & MI) const1423*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::hasFlagOperand(const MachineInstr &MI) const {
1424*9880d681SAndroid Build Coastguard Worker   return GET_FLAG_OPERAND_IDX(get(MI.getOpcode()).TSFlags) != 0;
1425*9880d681SAndroid Build Coastguard Worker }
1426*9880d681SAndroid Build Coastguard Worker 
getFlagOp(MachineInstr & MI,unsigned SrcIdx,unsigned Flag) const1427*9880d681SAndroid Build Coastguard Worker MachineOperand &R600InstrInfo::getFlagOp(MachineInstr &MI, unsigned SrcIdx,
1428*9880d681SAndroid Build Coastguard Worker                                          unsigned Flag) const {
1429*9880d681SAndroid Build Coastguard Worker   unsigned TargetFlags = get(MI.getOpcode()).TSFlags;
1430*9880d681SAndroid Build Coastguard Worker   int FlagIndex = 0;
1431*9880d681SAndroid Build Coastguard Worker   if (Flag != 0) {
1432*9880d681SAndroid Build Coastguard Worker     // If we pass something other than the default value of Flag to this
1433*9880d681SAndroid Build Coastguard Worker     // function, it means we are want to set a flag on an instruction
1434*9880d681SAndroid Build Coastguard Worker     // that uses native encoding.
1435*9880d681SAndroid Build Coastguard Worker     assert(HAS_NATIVE_OPERANDS(TargetFlags));
1436*9880d681SAndroid Build Coastguard Worker     bool IsOP3 = (TargetFlags & R600_InstFlag::OP3) == R600_InstFlag::OP3;
1437*9880d681SAndroid Build Coastguard Worker     switch (Flag) {
1438*9880d681SAndroid Build Coastguard Worker     case MO_FLAG_CLAMP:
1439*9880d681SAndroid Build Coastguard Worker       FlagIndex = getOperandIdx(MI, AMDGPU::OpName::clamp);
1440*9880d681SAndroid Build Coastguard Worker       break;
1441*9880d681SAndroid Build Coastguard Worker     case MO_FLAG_MASK:
1442*9880d681SAndroid Build Coastguard Worker       FlagIndex = getOperandIdx(MI, AMDGPU::OpName::write);
1443*9880d681SAndroid Build Coastguard Worker       break;
1444*9880d681SAndroid Build Coastguard Worker     case MO_FLAG_NOT_LAST:
1445*9880d681SAndroid Build Coastguard Worker     case MO_FLAG_LAST:
1446*9880d681SAndroid Build Coastguard Worker       FlagIndex = getOperandIdx(MI, AMDGPU::OpName::last);
1447*9880d681SAndroid Build Coastguard Worker       break;
1448*9880d681SAndroid Build Coastguard Worker     case MO_FLAG_NEG:
1449*9880d681SAndroid Build Coastguard Worker       switch (SrcIdx) {
1450*9880d681SAndroid Build Coastguard Worker       case 0:
1451*9880d681SAndroid Build Coastguard Worker         FlagIndex = getOperandIdx(MI, AMDGPU::OpName::src0_neg);
1452*9880d681SAndroid Build Coastguard Worker         break;
1453*9880d681SAndroid Build Coastguard Worker       case 1:
1454*9880d681SAndroid Build Coastguard Worker         FlagIndex = getOperandIdx(MI, AMDGPU::OpName::src1_neg);
1455*9880d681SAndroid Build Coastguard Worker         break;
1456*9880d681SAndroid Build Coastguard Worker       case 2:
1457*9880d681SAndroid Build Coastguard Worker         FlagIndex = getOperandIdx(MI, AMDGPU::OpName::src2_neg);
1458*9880d681SAndroid Build Coastguard Worker         break;
1459*9880d681SAndroid Build Coastguard Worker       }
1460*9880d681SAndroid Build Coastguard Worker       break;
1461*9880d681SAndroid Build Coastguard Worker 
1462*9880d681SAndroid Build Coastguard Worker     case MO_FLAG_ABS:
1463*9880d681SAndroid Build Coastguard Worker       assert(!IsOP3 && "Cannot set absolute value modifier for OP3 "
1464*9880d681SAndroid Build Coastguard Worker                        "instructions.");
1465*9880d681SAndroid Build Coastguard Worker       (void)IsOP3;
1466*9880d681SAndroid Build Coastguard Worker       switch (SrcIdx) {
1467*9880d681SAndroid Build Coastguard Worker       case 0:
1468*9880d681SAndroid Build Coastguard Worker         FlagIndex = getOperandIdx(MI, AMDGPU::OpName::src0_abs);
1469*9880d681SAndroid Build Coastguard Worker         break;
1470*9880d681SAndroid Build Coastguard Worker       case 1:
1471*9880d681SAndroid Build Coastguard Worker         FlagIndex = getOperandIdx(MI, AMDGPU::OpName::src1_abs);
1472*9880d681SAndroid Build Coastguard Worker         break;
1473*9880d681SAndroid Build Coastguard Worker       }
1474*9880d681SAndroid Build Coastguard Worker       break;
1475*9880d681SAndroid Build Coastguard Worker 
1476*9880d681SAndroid Build Coastguard Worker     default:
1477*9880d681SAndroid Build Coastguard Worker       FlagIndex = -1;
1478*9880d681SAndroid Build Coastguard Worker       break;
1479*9880d681SAndroid Build Coastguard Worker     }
1480*9880d681SAndroid Build Coastguard Worker     assert(FlagIndex != -1 && "Flag not supported for this instruction");
1481*9880d681SAndroid Build Coastguard Worker   } else {
1482*9880d681SAndroid Build Coastguard Worker       FlagIndex = GET_FLAG_OPERAND_IDX(TargetFlags);
1483*9880d681SAndroid Build Coastguard Worker       assert(FlagIndex != 0 &&
1484*9880d681SAndroid Build Coastguard Worker          "Instruction flags not supported for this instruction");
1485*9880d681SAndroid Build Coastguard Worker   }
1486*9880d681SAndroid Build Coastguard Worker 
1487*9880d681SAndroid Build Coastguard Worker   MachineOperand &FlagOp = MI.getOperand(FlagIndex);
1488*9880d681SAndroid Build Coastguard Worker   assert(FlagOp.isImm());
1489*9880d681SAndroid Build Coastguard Worker   return FlagOp;
1490*9880d681SAndroid Build Coastguard Worker }
1491*9880d681SAndroid Build Coastguard Worker 
addFlag(MachineInstr & MI,unsigned Operand,unsigned Flag) const1492*9880d681SAndroid Build Coastguard Worker void R600InstrInfo::addFlag(MachineInstr &MI, unsigned Operand,
1493*9880d681SAndroid Build Coastguard Worker                             unsigned Flag) const {
1494*9880d681SAndroid Build Coastguard Worker   unsigned TargetFlags = get(MI.getOpcode()).TSFlags;
1495*9880d681SAndroid Build Coastguard Worker   if (Flag == 0) {
1496*9880d681SAndroid Build Coastguard Worker     return;
1497*9880d681SAndroid Build Coastguard Worker   }
1498*9880d681SAndroid Build Coastguard Worker   if (HAS_NATIVE_OPERANDS(TargetFlags)) {
1499*9880d681SAndroid Build Coastguard Worker     MachineOperand &FlagOp = getFlagOp(MI, Operand, Flag);
1500*9880d681SAndroid Build Coastguard Worker     if (Flag == MO_FLAG_NOT_LAST) {
1501*9880d681SAndroid Build Coastguard Worker       clearFlag(MI, Operand, MO_FLAG_LAST);
1502*9880d681SAndroid Build Coastguard Worker     } else if (Flag == MO_FLAG_MASK) {
1503*9880d681SAndroid Build Coastguard Worker       clearFlag(MI, Operand, Flag);
1504*9880d681SAndroid Build Coastguard Worker     } else {
1505*9880d681SAndroid Build Coastguard Worker       FlagOp.setImm(1);
1506*9880d681SAndroid Build Coastguard Worker     }
1507*9880d681SAndroid Build Coastguard Worker   } else {
1508*9880d681SAndroid Build Coastguard Worker       MachineOperand &FlagOp = getFlagOp(MI, Operand);
1509*9880d681SAndroid Build Coastguard Worker       FlagOp.setImm(FlagOp.getImm() | (Flag << (NUM_MO_FLAGS * Operand)));
1510*9880d681SAndroid Build Coastguard Worker   }
1511*9880d681SAndroid Build Coastguard Worker }
1512*9880d681SAndroid Build Coastguard Worker 
clearFlag(MachineInstr & MI,unsigned Operand,unsigned Flag) const1513*9880d681SAndroid Build Coastguard Worker void R600InstrInfo::clearFlag(MachineInstr &MI, unsigned Operand,
1514*9880d681SAndroid Build Coastguard Worker                               unsigned Flag) const {
1515*9880d681SAndroid Build Coastguard Worker   unsigned TargetFlags = get(MI.getOpcode()).TSFlags;
1516*9880d681SAndroid Build Coastguard Worker   if (HAS_NATIVE_OPERANDS(TargetFlags)) {
1517*9880d681SAndroid Build Coastguard Worker     MachineOperand &FlagOp = getFlagOp(MI, Operand, Flag);
1518*9880d681SAndroid Build Coastguard Worker     FlagOp.setImm(0);
1519*9880d681SAndroid Build Coastguard Worker   } else {
1520*9880d681SAndroid Build Coastguard Worker     MachineOperand &FlagOp = getFlagOp(MI);
1521*9880d681SAndroid Build Coastguard Worker     unsigned InstFlags = FlagOp.getImm();
1522*9880d681SAndroid Build Coastguard Worker     InstFlags &= ~(Flag << (NUM_MO_FLAGS * Operand));
1523*9880d681SAndroid Build Coastguard Worker     FlagOp.setImm(InstFlags);
1524*9880d681SAndroid Build Coastguard Worker   }
1525*9880d681SAndroid Build Coastguard Worker }
1526*9880d681SAndroid Build Coastguard Worker 
isRegisterStore(const MachineInstr & MI) const1527*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::isRegisterStore(const MachineInstr &MI) const {
1528*9880d681SAndroid Build Coastguard Worker   return get(MI.getOpcode()).TSFlags & AMDGPU_FLAG_REGISTER_STORE;
1529*9880d681SAndroid Build Coastguard Worker }
1530*9880d681SAndroid Build Coastguard Worker 
isRegisterLoad(const MachineInstr & MI) const1531*9880d681SAndroid Build Coastguard Worker bool R600InstrInfo::isRegisterLoad(const MachineInstr &MI) const {
1532*9880d681SAndroid Build Coastguard Worker   return get(MI.getOpcode()).TSFlags & AMDGPU_FLAG_REGISTER_LOAD;
1533*9880d681SAndroid Build Coastguard Worker }
1534