Don't use a potentially expensive shift if all we want is one set bit.
[oota-llvm.git] / lib / Target / R600 / R600InstrInfo.cpp
1 //===-- R600InstrInfo.cpp - R600 Instruction Information ------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 /// \file
11 /// \brief R600 Implementation of TargetInstrInfo.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "R600InstrInfo.h"
16 #include "AMDGPU.h"
17 #include "AMDGPUSubtarget.h"
18 #include "AMDGPUTargetMachine.h"
19 #include "R600Defines.h"
20 #include "R600MachineFunctionInfo.h"
21 #include "R600RegisterInfo.h"
22 #include "llvm/CodeGen/MachineFrameInfo.h"
23 #include "llvm/CodeGen/MachineInstrBuilder.h"
24 #include "llvm/CodeGen/MachineRegisterInfo.h"
25
26 #define GET_INSTRINFO_CTOR
27 #include "AMDGPUGenDFAPacketizer.inc"
28
29 using namespace llvm;
30
31 R600InstrInfo::R600InstrInfo(AMDGPUTargetMachine &tm)
32   : AMDGPUInstrInfo(tm),
33     RI(tm),
34     ST(tm.getSubtarget<AMDGPUSubtarget>())
35   { }
36
37 const R600RegisterInfo &R600InstrInfo::getRegisterInfo() const {
38   return RI;
39 }
40
41 bool R600InstrInfo::isTrig(const MachineInstr &MI) const {
42   return get(MI.getOpcode()).TSFlags & R600_InstFlag::TRIG;
43 }
44
45 bool R600InstrInfo::isVector(const MachineInstr &MI) const {
46   return get(MI.getOpcode()).TSFlags & R600_InstFlag::VECTOR;
47 }
48
49 void
50 R600InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
51                            MachineBasicBlock::iterator MI, DebugLoc DL,
52                            unsigned DestReg, unsigned SrcReg,
53                            bool KillSrc) const {
54   if (AMDGPU::R600_Reg128RegClass.contains(DestReg)
55       && AMDGPU::R600_Reg128RegClass.contains(SrcReg)) {
56     for (unsigned I = 0; I < 4; I++) {
57       unsigned SubRegIndex = RI.getSubRegFromChannel(I);
58       buildDefaultInstruction(MBB, MI, AMDGPU::MOV,
59                               RI.getSubReg(DestReg, SubRegIndex),
60                               RI.getSubReg(SrcReg, SubRegIndex))
61                               .addReg(DestReg,
62                                       RegState::Define | RegState::Implicit);
63     }
64   } else {
65
66     // We can't copy vec4 registers
67     assert(!AMDGPU::R600_Reg128RegClass.contains(DestReg)
68            && !AMDGPU::R600_Reg128RegClass.contains(SrcReg));
69
70     MachineInstr *NewMI = buildDefaultInstruction(MBB, MI, AMDGPU::MOV,
71                                                   DestReg, SrcReg);
72     NewMI->getOperand(getOperandIdx(*NewMI, AMDGPU::OpName::src0))
73                                     .setIsKill(KillSrc);
74   }
75 }
76
77 MachineInstr * R600InstrInfo::getMovImmInstr(MachineFunction *MF,
78                                              unsigned DstReg, int64_t Imm) const {
79   MachineInstr * MI = MF->CreateMachineInstr(get(AMDGPU::MOV), DebugLoc());
80   MachineInstrBuilder MIB(*MF, MI);
81   MIB.addReg(DstReg, RegState::Define);
82   MIB.addReg(AMDGPU::ALU_LITERAL_X);
83   MIB.addImm(Imm);
84   MIB.addReg(0); // PREDICATE_BIT
85
86   return MI;
87 }
88
89 unsigned R600InstrInfo::getIEQOpcode() const {
90   return AMDGPU::SETE_INT;
91 }
92
93 bool R600InstrInfo::isMov(unsigned Opcode) const {
94
95
96   switch(Opcode) {
97   default: return false;
98   case AMDGPU::MOV:
99   case AMDGPU::MOV_IMM_F32:
100   case AMDGPU::MOV_IMM_I32:
101     return true;
102   }
103 }
104
105 // Some instructions act as place holders to emulate operations that the GPU
106 // hardware does automatically. This function can be used to check if
107 // an opcode falls into this category.
108 bool R600InstrInfo::isPlaceHolderOpcode(unsigned Opcode) const {
109   switch (Opcode) {
110   default: return false;
111   case AMDGPU::RETURN:
112     return true;
113   }
114 }
115
116 bool R600InstrInfo::isReductionOp(unsigned Opcode) const {
117   return false;
118 }
119
120 bool R600InstrInfo::isCubeOp(unsigned Opcode) const {
121   switch(Opcode) {
122     default: return false;
123     case AMDGPU::CUBE_r600_pseudo:
124     case AMDGPU::CUBE_r600_real:
125     case AMDGPU::CUBE_eg_pseudo:
126     case AMDGPU::CUBE_eg_real:
127       return true;
128   }
129 }
130
131 bool R600InstrInfo::isALUInstr(unsigned Opcode) const {
132   unsigned TargetFlags = get(Opcode).TSFlags;
133
134   return (TargetFlags & R600_InstFlag::ALU_INST);
135 }
136
137 bool R600InstrInfo::hasInstrModifiers(unsigned Opcode) const {
138   unsigned TargetFlags = get(Opcode).TSFlags;
139
140   return ((TargetFlags & R600_InstFlag::OP1) |
141           (TargetFlags & R600_InstFlag::OP2) |
142           (TargetFlags & R600_InstFlag::OP3));
143 }
144
145 bool R600InstrInfo::isLDSInstr(unsigned Opcode) const {
146   unsigned TargetFlags = get(Opcode).TSFlags;
147
148   return ((TargetFlags & R600_InstFlag::LDS_1A) |
149           (TargetFlags & R600_InstFlag::LDS_1A1D));
150 }
151
152 bool R600InstrInfo::isTransOnly(unsigned Opcode) const {
153   return (get(Opcode).TSFlags & R600_InstFlag::TRANS_ONLY);
154 }
155
156 bool R600InstrInfo::isTransOnly(const MachineInstr *MI) const {
157   return isTransOnly(MI->getOpcode());
158 }
159
160 bool R600InstrInfo::usesVertexCache(unsigned Opcode) const {
161   return ST.hasVertexCache() && IS_VTX(get(Opcode));
162 }
163
164 bool R600InstrInfo::usesVertexCache(const MachineInstr *MI) const {
165   const R600MachineFunctionInfo *MFI = MI->getParent()->getParent()->getInfo<R600MachineFunctionInfo>();
166   return MFI->ShaderType != ShaderType::COMPUTE && usesVertexCache(MI->getOpcode());
167 }
168
169 bool R600InstrInfo::usesTextureCache(unsigned Opcode) const {
170   return (!ST.hasVertexCache() && IS_VTX(get(Opcode))) || IS_TEX(get(Opcode));
171 }
172
173 bool R600InstrInfo::usesTextureCache(const MachineInstr *MI) const {
174   const R600MachineFunctionInfo *MFI = MI->getParent()->getParent()->getInfo<R600MachineFunctionInfo>();
175   return (MFI->ShaderType == ShaderType::COMPUTE && usesVertexCache(MI->getOpcode())) ||
176          usesTextureCache(MI->getOpcode());
177 }
178
179 bool R600InstrInfo::mustBeLastInClause(unsigned Opcode) const {
180   switch (Opcode) {
181   case AMDGPU::KILLGT:
182   case AMDGPU::GROUP_BARRIER:
183     return true;
184   default:
185     return false;
186   }
187 }
188
189 SmallVector<std::pair<MachineOperand *, int64_t>, 3>
190 R600InstrInfo::getSrcs(MachineInstr *MI) const {
191   SmallVector<std::pair<MachineOperand *, int64_t>, 3> Result;
192
193   if (MI->getOpcode() == AMDGPU::DOT_4) {
194     static const unsigned OpTable[8][2] = {
195       {AMDGPU::OpName::src0_X, AMDGPU::OpName::src0_sel_X},
196       {AMDGPU::OpName::src0_Y, AMDGPU::OpName::src0_sel_Y},
197       {AMDGPU::OpName::src0_Z, AMDGPU::OpName::src0_sel_Z},
198       {AMDGPU::OpName::src0_W, AMDGPU::OpName::src0_sel_W},
199       {AMDGPU::OpName::src1_X, AMDGPU::OpName::src1_sel_X},
200       {AMDGPU::OpName::src1_Y, AMDGPU::OpName::src1_sel_Y},
201       {AMDGPU::OpName::src1_Z, AMDGPU::OpName::src1_sel_Z},
202       {AMDGPU::OpName::src1_W, AMDGPU::OpName::src1_sel_W},
203     };
204
205     for (unsigned j = 0; j < 8; j++) {
206       MachineOperand &MO = MI->getOperand(getOperandIdx(MI->getOpcode(),
207                                                         OpTable[j][0]));
208       unsigned Reg = MO.getReg();
209       if (Reg == AMDGPU::ALU_CONST) {
210         unsigned Sel = MI->getOperand(getOperandIdx(MI->getOpcode(),
211                                                     OpTable[j][1])).getImm();
212         Result.push_back(std::pair<MachineOperand *, int64_t>(&MO, Sel));
213         continue;
214       }
215       
216     }
217     return Result;
218   }
219
220   static const unsigned OpTable[3][2] = {
221     {AMDGPU::OpName::src0, AMDGPU::OpName::src0_sel},
222     {AMDGPU::OpName::src1, AMDGPU::OpName::src1_sel},
223     {AMDGPU::OpName::src2, AMDGPU::OpName::src2_sel},
224   };
225
226   for (unsigned j = 0; j < 3; j++) {
227     int SrcIdx = getOperandIdx(MI->getOpcode(), OpTable[j][0]);
228     if (SrcIdx < 0)
229       break;
230     MachineOperand &MO = MI->getOperand(SrcIdx);
231     unsigned Reg = MI->getOperand(SrcIdx).getReg();
232     if (Reg == AMDGPU::ALU_CONST) {
233       unsigned Sel = MI->getOperand(
234           getOperandIdx(MI->getOpcode(), OpTable[j][1])).getImm();
235       Result.push_back(std::pair<MachineOperand *, int64_t>(&MO, Sel));
236       continue;
237     }
238     if (Reg == AMDGPU::ALU_LITERAL_X) {
239       unsigned Imm = MI->getOperand(
240           getOperandIdx(MI->getOpcode(), AMDGPU::OpName::literal)).getImm();
241       Result.push_back(std::pair<MachineOperand *, int64_t>(&MO, Imm));
242       continue;
243     }
244     Result.push_back(std::pair<MachineOperand *, int64_t>(&MO, 0));
245   }
246   return Result;
247 }
248
249 std::vector<std::pair<int, unsigned> >
250 R600InstrInfo::ExtractSrcs(MachineInstr *MI,
251                            const DenseMap<unsigned, unsigned> &PV,
252                            unsigned &ConstCount) const {
253   ConstCount = 0;
254   const SmallVector<std::pair<MachineOperand *, int64_t>, 3> Srcs = getSrcs(MI);
255   const std::pair<int, unsigned> DummyPair(-1, 0);
256   std::vector<std::pair<int, unsigned> > Result;
257   unsigned i = 0;
258   for (unsigned n = Srcs.size(); i < n; ++i) {
259     unsigned Reg = Srcs[i].first->getReg();
260     unsigned Index = RI.getEncodingValue(Reg) & 0xff;
261     if (Reg == AMDGPU::OQAP) {
262       Result.push_back(std::pair<int, unsigned>(Index, 0));
263     }
264     if (PV.find(Reg) != PV.end()) {
265       // 255 is used to tells its a PS/PV reg
266       Result.push_back(std::pair<int, unsigned>(255, 0));
267       continue;
268     }
269     if (Index > 127) {
270       ConstCount++;
271       Result.push_back(DummyPair);
272       continue;
273     }
274     unsigned Chan = RI.getHWRegChan(Reg);
275     Result.push_back(std::pair<int, unsigned>(Index, Chan));
276   }
277   for (; i < 3; ++i)
278     Result.push_back(DummyPair);
279   return Result;
280 }
281
282 static std::vector<std::pair<int, unsigned> >
283 Swizzle(std::vector<std::pair<int, unsigned> > Src,
284         R600InstrInfo::BankSwizzle Swz) {
285   switch (Swz) {
286   case R600InstrInfo::ALU_VEC_012_SCL_210:
287     break;
288   case R600InstrInfo::ALU_VEC_021_SCL_122:
289     std::swap(Src[1], Src[2]);
290     break;
291   case R600InstrInfo::ALU_VEC_102_SCL_221:
292     std::swap(Src[0], Src[1]);
293     break;
294   case R600InstrInfo::ALU_VEC_120_SCL_212:
295     std::swap(Src[0], Src[1]);
296     std::swap(Src[0], Src[2]);
297     break;
298   case R600InstrInfo::ALU_VEC_201:
299     std::swap(Src[0], Src[2]);
300     std::swap(Src[0], Src[1]);
301     break;
302   case R600InstrInfo::ALU_VEC_210:
303     std::swap(Src[0], Src[2]);
304     break;
305   }
306   return Src;
307 }
308
309 static unsigned
310 getTransSwizzle(R600InstrInfo::BankSwizzle Swz, unsigned Op) {
311   switch (Swz) {
312   case R600InstrInfo::ALU_VEC_012_SCL_210: {
313     unsigned Cycles[3] = { 2, 1, 0};
314     return Cycles[Op];
315   }
316   case R600InstrInfo::ALU_VEC_021_SCL_122: {
317     unsigned Cycles[3] = { 1, 2, 2};
318     return Cycles[Op];
319   }
320   case R600InstrInfo::ALU_VEC_120_SCL_212: {
321     unsigned Cycles[3] = { 2, 1, 2};
322     return Cycles[Op];
323   }
324   case R600InstrInfo::ALU_VEC_102_SCL_221: {
325     unsigned Cycles[3] = { 2, 2, 1};
326     return Cycles[Op];
327   }
328   default:
329     llvm_unreachable("Wrong Swizzle for Trans Slot");
330     return 0;
331   }
332 }
333
334 /// returns how many MIs (whose inputs are represented by IGSrcs) can be packed
335 /// in the same Instruction Group while meeting read port limitations given a
336 /// Swz swizzle sequence.
337 unsigned  R600InstrInfo::isLegalUpTo(
338     const std::vector<std::vector<std::pair<int, unsigned> > > &IGSrcs,
339     const std::vector<R600InstrInfo::BankSwizzle> &Swz,
340     const std::vector<std::pair<int, unsigned> > &TransSrcs,
341     R600InstrInfo::BankSwizzle TransSwz) const {
342   int Vector[4][3];
343   memset(Vector, -1, sizeof(Vector));
344   for (unsigned i = 0, e = IGSrcs.size(); i < e; i++) {
345     const std::vector<std::pair<int, unsigned> > &Srcs =
346         Swizzle(IGSrcs[i], Swz[i]);
347     for (unsigned j = 0; j < 3; j++) {
348       const std::pair<int, unsigned> &Src = Srcs[j];
349       if (Src.first < 0 || Src.first == 255)
350         continue;
351       if (Src.first == GET_REG_INDEX(RI.getEncodingValue(AMDGPU::OQAP))) {
352         if (Swz[i] != R600InstrInfo::ALU_VEC_012_SCL_210 &&
353             Swz[i] != R600InstrInfo::ALU_VEC_021_SCL_122) {
354             // The value from output queue A (denoted by register OQAP) can
355             // only be fetched during the first cycle.
356             return false;
357         }
358         // OQAP does not count towards the normal read port restrictions
359         continue;
360       }
361       if (Vector[Src.second][j] < 0)
362         Vector[Src.second][j] = Src.first;
363       if (Vector[Src.second][j] != Src.first)
364         return i;
365     }
366   }
367   // Now check Trans Alu
368   for (unsigned i = 0, e = TransSrcs.size(); i < e; ++i) {
369     const std::pair<int, unsigned> &Src = TransSrcs[i];
370     unsigned Cycle = getTransSwizzle(TransSwz, i);
371     if (Src.first < 0)
372       continue;
373     if (Src.first == 255)
374       continue;
375     if (Vector[Src.second][Cycle] < 0)
376       Vector[Src.second][Cycle] = Src.first;
377     if (Vector[Src.second][Cycle] != Src.first)
378       return IGSrcs.size() - 1;
379   }
380   return IGSrcs.size();
381 }
382
383 /// Given a swizzle sequence SwzCandidate and an index Idx, returns the next
384 /// (in lexicographic term) swizzle sequence assuming that all swizzles after
385 /// Idx can be skipped
386 static bool
387 NextPossibleSolution(
388     std::vector<R600InstrInfo::BankSwizzle> &SwzCandidate,
389     unsigned Idx) {
390   assert(Idx < SwzCandidate.size());
391   int ResetIdx = Idx;
392   while (ResetIdx > -1 && SwzCandidate[ResetIdx] == R600InstrInfo::ALU_VEC_210)
393     ResetIdx --;
394   for (unsigned i = ResetIdx + 1, e = SwzCandidate.size(); i < e; i++) {
395     SwzCandidate[i] = R600InstrInfo::ALU_VEC_012_SCL_210;
396   }
397   if (ResetIdx == -1)
398     return false;
399   int NextSwizzle = SwzCandidate[ResetIdx] + 1;
400   SwzCandidate[ResetIdx] = (R600InstrInfo::BankSwizzle)NextSwizzle;
401   return true;
402 }
403
404 /// Enumerate all possible Swizzle sequence to find one that can meet all
405 /// read port requirements.
406 bool R600InstrInfo::FindSwizzleForVectorSlot(
407     const std::vector<std::vector<std::pair<int, unsigned> > > &IGSrcs,
408     std::vector<R600InstrInfo::BankSwizzle> &SwzCandidate,
409     const std::vector<std::pair<int, unsigned> > &TransSrcs,
410     R600InstrInfo::BankSwizzle TransSwz) const {
411   unsigned ValidUpTo = 0;
412   do {
413     ValidUpTo = isLegalUpTo(IGSrcs, SwzCandidate, TransSrcs, TransSwz);
414     if (ValidUpTo == IGSrcs.size())
415       return true;
416   } while (NextPossibleSolution(SwzCandidate, ValidUpTo));
417   return false;
418 }
419
420 /// Instructions in Trans slot can't read gpr at cycle 0 if they also read
421 /// a const, and can't read a gpr at cycle 1 if they read 2 const.
422 static bool
423 isConstCompatible(R600InstrInfo::BankSwizzle TransSwz,
424                   const std::vector<std::pair<int, unsigned> > &TransOps,
425                   unsigned ConstCount) {
426   for (unsigned i = 0, e = TransOps.size(); i < e; ++i) {
427     const std::pair<int, unsigned> &Src = TransOps[i];
428     unsigned Cycle = getTransSwizzle(TransSwz, i);
429     if (Src.first < 0)
430       continue;
431     if (ConstCount > 0 && Cycle == 0)
432       return false;
433     if (ConstCount > 1 && Cycle == 1)
434       return false;
435   }
436   return true;
437 }
438
439 bool
440 R600InstrInfo::fitsReadPortLimitations(const std::vector<MachineInstr *> &IG,
441                                        const DenseMap<unsigned, unsigned> &PV,
442                                        std::vector<BankSwizzle> &ValidSwizzle,
443                                        bool isLastAluTrans)
444     const {
445   //Todo : support shared src0 - src1 operand
446
447   std::vector<std::vector<std::pair<int, unsigned> > > IGSrcs;
448   ValidSwizzle.clear();
449   unsigned ConstCount;
450   BankSwizzle TransBS = ALU_VEC_012_SCL_210;
451   for (unsigned i = 0, e = IG.size(); i < e; ++i) {
452     IGSrcs.push_back(ExtractSrcs(IG[i], PV, ConstCount));
453     unsigned Op = getOperandIdx(IG[i]->getOpcode(),
454         AMDGPU::OpName::bank_swizzle);
455     ValidSwizzle.push_back( (R600InstrInfo::BankSwizzle)
456         IG[i]->getOperand(Op).getImm());
457   }
458   std::vector<std::pair<int, unsigned> > TransOps;
459   if (!isLastAluTrans)
460     return FindSwizzleForVectorSlot(IGSrcs, ValidSwizzle, TransOps, TransBS);
461
462   TransOps = IGSrcs.back();
463   IGSrcs.pop_back();
464   ValidSwizzle.pop_back();
465
466   static const R600InstrInfo::BankSwizzle TransSwz[] = {
467     ALU_VEC_012_SCL_210,
468     ALU_VEC_021_SCL_122,
469     ALU_VEC_120_SCL_212,
470     ALU_VEC_102_SCL_221
471   };
472   for (unsigned i = 0; i < 4; i++) {
473     TransBS = TransSwz[i];
474     if (!isConstCompatible(TransBS, TransOps, ConstCount))
475       continue;
476     bool Result = FindSwizzleForVectorSlot(IGSrcs, ValidSwizzle, TransOps,
477         TransBS);
478     if (Result) {
479       ValidSwizzle.push_back(TransBS);
480       return true;
481     }
482   }
483
484   return false;
485 }
486
487
488 bool
489 R600InstrInfo::fitsConstReadLimitations(const std::vector<unsigned> &Consts)
490     const {
491   assert (Consts.size() <= 12 && "Too many operands in instructions group");
492   unsigned Pair1 = 0, Pair2 = 0;
493   for (unsigned i = 0, n = Consts.size(); i < n; ++i) {
494     unsigned ReadConstHalf = Consts[i] & 2;
495     unsigned ReadConstIndex = Consts[i] & (~3);
496     unsigned ReadHalfConst = ReadConstIndex | ReadConstHalf;
497     if (!Pair1) {
498       Pair1 = ReadHalfConst;
499       continue;
500     }
501     if (Pair1 == ReadHalfConst)
502       continue;
503     if (!Pair2) {
504       Pair2 = ReadHalfConst;
505       continue;
506     }
507     if (Pair2 != ReadHalfConst)
508       return false;
509   }
510   return true;
511 }
512
513 bool
514 R600InstrInfo::fitsConstReadLimitations(const std::vector<MachineInstr *> &MIs)
515     const {
516   std::vector<unsigned> Consts;
517   for (unsigned i = 0, n = MIs.size(); i < n; i++) {
518     MachineInstr *MI = MIs[i];
519     if (!isALUInstr(MI->getOpcode()))
520       continue;
521
522     const SmallVector<std::pair<MachineOperand *, int64_t>, 3> &Srcs =
523         getSrcs(MI);
524
525     for (unsigned j = 0, e = Srcs.size(); j < e; j++) {
526       std::pair<MachineOperand *, unsigned> Src = Srcs[j];
527       if (Src.first->getReg() == AMDGPU::ALU_CONST)
528         Consts.push_back(Src.second);
529       if (AMDGPU::R600_KC0RegClass.contains(Src.first->getReg()) ||
530           AMDGPU::R600_KC1RegClass.contains(Src.first->getReg())) {
531         unsigned Index = RI.getEncodingValue(Src.first->getReg()) & 0xff;
532         unsigned Chan = RI.getHWRegChan(Src.first->getReg());
533         Consts.push_back((Index << 2) | Chan);
534       }
535     }
536   }
537   return fitsConstReadLimitations(Consts);
538 }
539
540 DFAPacketizer *R600InstrInfo::CreateTargetScheduleState(const TargetMachine *TM,
541     const ScheduleDAG *DAG) const {
542   const InstrItineraryData *II = TM->getInstrItineraryData();
543   return TM->getSubtarget<AMDGPUSubtarget>().createDFAPacketizer(II);
544 }
545
546 static bool
547 isPredicateSetter(unsigned Opcode) {
548   switch (Opcode) {
549   case AMDGPU::PRED_X:
550     return true;
551   default:
552     return false;
553   }
554 }
555
556 static MachineInstr *
557 findFirstPredicateSetterFrom(MachineBasicBlock &MBB,
558                              MachineBasicBlock::iterator I) {
559   while (I != MBB.begin()) {
560     --I;
561     MachineInstr *MI = I;
562     if (isPredicateSetter(MI->getOpcode()))
563       return MI;
564   }
565
566   return NULL;
567 }
568
569 static
570 bool isJump(unsigned Opcode) {
571   return Opcode == AMDGPU::JUMP || Opcode == AMDGPU::JUMP_COND;
572 }
573
574 bool
575 R600InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
576                              MachineBasicBlock *&TBB,
577                              MachineBasicBlock *&FBB,
578                              SmallVectorImpl<MachineOperand> &Cond,
579                              bool AllowModify) const {
580   // Most of the following comes from the ARM implementation of AnalyzeBranch
581
582   // If the block has no terminators, it just falls into the block after it.
583   MachineBasicBlock::iterator I = MBB.end();
584   if (I == MBB.begin())
585     return false;
586   --I;
587   while (I->isDebugValue()) {
588     if (I == MBB.begin())
589       return false;
590     --I;
591   }
592   if (!isJump(static_cast<MachineInstr *>(I)->getOpcode())) {
593     return false;
594   }
595
596   // Get the last instruction in the block.
597   MachineInstr *LastInst = I;
598
599   // If there is only one terminator instruction, process it.
600   unsigned LastOpc = LastInst->getOpcode();
601   if (I == MBB.begin() ||
602           !isJump(static_cast<MachineInstr *>(--I)->getOpcode())) {
603     if (LastOpc == AMDGPU::JUMP) {
604       TBB = LastInst->getOperand(0).getMBB();
605       return false;
606     } else if (LastOpc == AMDGPU::JUMP_COND) {
607       MachineInstr *predSet = I;
608       while (!isPredicateSetter(predSet->getOpcode())) {
609         predSet = --I;
610       }
611       TBB = LastInst->getOperand(0).getMBB();
612       Cond.push_back(predSet->getOperand(1));
613       Cond.push_back(predSet->getOperand(2));
614       Cond.push_back(MachineOperand::CreateReg(AMDGPU::PRED_SEL_ONE, false));
615       return false;
616     }
617     return true;  // Can't handle indirect branch.
618   }
619
620   // Get the instruction before it if it is a terminator.
621   MachineInstr *SecondLastInst = I;
622   unsigned SecondLastOpc = SecondLastInst->getOpcode();
623
624   // If the block ends with a B and a Bcc, handle it.
625   if (SecondLastOpc == AMDGPU::JUMP_COND && LastOpc == AMDGPU::JUMP) {
626     MachineInstr *predSet = --I;
627     while (!isPredicateSetter(predSet->getOpcode())) {
628       predSet = --I;
629     }
630     TBB = SecondLastInst->getOperand(0).getMBB();
631     FBB = LastInst->getOperand(0).getMBB();
632     Cond.push_back(predSet->getOperand(1));
633     Cond.push_back(predSet->getOperand(2));
634     Cond.push_back(MachineOperand::CreateReg(AMDGPU::PRED_SEL_ONE, false));
635     return false;
636   }
637
638   // Otherwise, can't handle this.
639   return true;
640 }
641
642 int R600InstrInfo::getBranchInstr(const MachineOperand &op) const {
643   const MachineInstr *MI = op.getParent();
644
645   switch (MI->getDesc().OpInfo->RegClass) {
646   default: // FIXME: fallthrough??
647   case AMDGPU::GPRI32RegClassID: return AMDGPU::BRANCH_COND_i32;
648   case AMDGPU::GPRF32RegClassID: return AMDGPU::BRANCH_COND_f32;
649   };
650 }
651
652 static
653 MachineBasicBlock::iterator FindLastAluClause(MachineBasicBlock &MBB) {
654   for (MachineBasicBlock::reverse_iterator It = MBB.rbegin(), E = MBB.rend();
655       It != E; ++It) {
656     if (It->getOpcode() == AMDGPU::CF_ALU ||
657         It->getOpcode() == AMDGPU::CF_ALU_PUSH_BEFORE)
658       return llvm::prior(It.base());
659   }
660   return MBB.end();
661 }
662
663 unsigned
664 R600InstrInfo::InsertBranch(MachineBasicBlock &MBB,
665                             MachineBasicBlock *TBB,
666                             MachineBasicBlock *FBB,
667                             const SmallVectorImpl<MachineOperand> &Cond,
668                             DebugLoc DL) const {
669   assert(TBB && "InsertBranch must not be told to insert a fallthrough");
670
671   if (FBB == 0) {
672     if (Cond.empty()) {
673       BuildMI(&MBB, DL, get(AMDGPU::JUMP)).addMBB(TBB);
674       return 1;
675     } else {
676       MachineInstr *PredSet = findFirstPredicateSetterFrom(MBB, MBB.end());
677       assert(PredSet && "No previous predicate !");
678       addFlag(PredSet, 0, MO_FLAG_PUSH);
679       PredSet->getOperand(2).setImm(Cond[1].getImm());
680
681       BuildMI(&MBB, DL, get(AMDGPU::JUMP_COND))
682              .addMBB(TBB)
683              .addReg(AMDGPU::PREDICATE_BIT, RegState::Kill);
684       MachineBasicBlock::iterator CfAlu = FindLastAluClause(MBB);
685       if (CfAlu == MBB.end())
686         return 1;
687       assert (CfAlu->getOpcode() == AMDGPU::CF_ALU);
688       CfAlu->setDesc(get(AMDGPU::CF_ALU_PUSH_BEFORE));
689       return 1;
690     }
691   } else {
692     MachineInstr *PredSet = findFirstPredicateSetterFrom(MBB, MBB.end());
693     assert(PredSet && "No previous predicate !");
694     addFlag(PredSet, 0, MO_FLAG_PUSH);
695     PredSet->getOperand(2).setImm(Cond[1].getImm());
696     BuildMI(&MBB, DL, get(AMDGPU::JUMP_COND))
697             .addMBB(TBB)
698             .addReg(AMDGPU::PREDICATE_BIT, RegState::Kill);
699     BuildMI(&MBB, DL, get(AMDGPU::JUMP)).addMBB(FBB);
700     MachineBasicBlock::iterator CfAlu = FindLastAluClause(MBB);
701     if (CfAlu == MBB.end())
702       return 2;
703     assert (CfAlu->getOpcode() == AMDGPU::CF_ALU);
704     CfAlu->setDesc(get(AMDGPU::CF_ALU_PUSH_BEFORE));
705     return 2;
706   }
707 }
708
709 unsigned
710 R600InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
711
712   // Note : we leave PRED* instructions there.
713   // They may be needed when predicating instructions.
714
715   MachineBasicBlock::iterator I = MBB.end();
716
717   if (I == MBB.begin()) {
718     return 0;
719   }
720   --I;
721   switch (I->getOpcode()) {
722   default:
723     return 0;
724   case AMDGPU::JUMP_COND: {
725     MachineInstr *predSet = findFirstPredicateSetterFrom(MBB, I);
726     clearFlag(predSet, 0, MO_FLAG_PUSH);
727     I->eraseFromParent();
728     MachineBasicBlock::iterator CfAlu = FindLastAluClause(MBB);
729     if (CfAlu == MBB.end())
730       break;
731     assert (CfAlu->getOpcode() == AMDGPU::CF_ALU_PUSH_BEFORE);
732     CfAlu->setDesc(get(AMDGPU::CF_ALU));
733     break;
734   }
735   case AMDGPU::JUMP:
736     I->eraseFromParent();
737     break;
738   }
739   I = MBB.end();
740
741   if (I == MBB.begin()) {
742     return 1;
743   }
744   --I;
745   switch (I->getOpcode()) {
746     // FIXME: only one case??
747   default:
748     return 1;
749   case AMDGPU::JUMP_COND: {
750     MachineInstr *predSet = findFirstPredicateSetterFrom(MBB, I);
751     clearFlag(predSet, 0, MO_FLAG_PUSH);
752     I->eraseFromParent();
753     MachineBasicBlock::iterator CfAlu = FindLastAluClause(MBB);
754     if (CfAlu == MBB.end())
755       break;
756     assert (CfAlu->getOpcode() == AMDGPU::CF_ALU_PUSH_BEFORE);
757     CfAlu->setDesc(get(AMDGPU::CF_ALU));
758     break;
759   }
760   case AMDGPU::JUMP:
761     I->eraseFromParent();
762     break;
763   }
764   return 2;
765 }
766
767 bool
768 R600InstrInfo::isPredicated(const MachineInstr *MI) const {
769   int idx = MI->findFirstPredOperandIdx();
770   if (idx < 0)
771     return false;
772
773   unsigned Reg = MI->getOperand(idx).getReg();
774   switch (Reg) {
775   default: return false;
776   case AMDGPU::PRED_SEL_ONE:
777   case AMDGPU::PRED_SEL_ZERO:
778   case AMDGPU::PREDICATE_BIT:
779     return true;
780   }
781 }
782
783 bool
784 R600InstrInfo::isPredicable(MachineInstr *MI) const {
785   // XXX: KILL* instructions can be predicated, but they must be the last
786   // instruction in a clause, so this means any instructions after them cannot
787   // be predicated.  Until we have proper support for instruction clauses in the
788   // backend, we will mark KILL* instructions as unpredicable.
789
790   if (MI->getOpcode() == AMDGPU::KILLGT) {
791     return false;
792   } else if (MI->getOpcode() == AMDGPU::CF_ALU) {
793     // If the clause start in the middle of MBB then the MBB has more
794     // than a single clause, unable to predicate several clauses.
795     if (MI->getParent()->begin() != MachineBasicBlock::iterator(MI))
796       return false;
797     // TODO: We don't support KC merging atm
798     if (MI->getOperand(3).getImm() != 0 || MI->getOperand(4).getImm() != 0)
799       return false;
800     return true;
801   } else if (isVector(*MI)) {
802     return false;
803   } else {
804     return AMDGPUInstrInfo::isPredicable(MI);
805   }
806 }
807
808
809 bool
810 R600InstrInfo::isProfitableToIfCvt(MachineBasicBlock &MBB,
811                                    unsigned NumCyles,
812                                    unsigned ExtraPredCycles,
813                                    const BranchProbability &Probability) const{
814   return true;
815 }
816
817 bool
818 R600InstrInfo::isProfitableToIfCvt(MachineBasicBlock &TMBB,
819                                    unsigned NumTCycles,
820                                    unsigned ExtraTCycles,
821                                    MachineBasicBlock &FMBB,
822                                    unsigned NumFCycles,
823                                    unsigned ExtraFCycles,
824                                    const BranchProbability &Probability) const {
825   return true;
826 }
827
828 bool
829 R600InstrInfo::isProfitableToDupForIfCvt(MachineBasicBlock &MBB,
830                                          unsigned NumCyles,
831                                          const BranchProbability &Probability)
832                                          const {
833   return true;
834 }
835
836 bool
837 R600InstrInfo::isProfitableToUnpredicate(MachineBasicBlock &TMBB,
838                                          MachineBasicBlock &FMBB) const {
839   return false;
840 }
841
842
843 bool
844 R600InstrInfo::ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
845   MachineOperand &MO = Cond[1];
846   switch (MO.getImm()) {
847   case OPCODE_IS_ZERO_INT:
848     MO.setImm(OPCODE_IS_NOT_ZERO_INT);
849     break;
850   case OPCODE_IS_NOT_ZERO_INT:
851     MO.setImm(OPCODE_IS_ZERO_INT);
852     break;
853   case OPCODE_IS_ZERO:
854     MO.setImm(OPCODE_IS_NOT_ZERO);
855     break;
856   case OPCODE_IS_NOT_ZERO:
857     MO.setImm(OPCODE_IS_ZERO);
858     break;
859   default:
860     return true;
861   }
862
863   MachineOperand &MO2 = Cond[2];
864   switch (MO2.getReg()) {
865   case AMDGPU::PRED_SEL_ZERO:
866     MO2.setReg(AMDGPU::PRED_SEL_ONE);
867     break;
868   case AMDGPU::PRED_SEL_ONE:
869     MO2.setReg(AMDGPU::PRED_SEL_ZERO);
870     break;
871   default:
872     return true;
873   }
874   return false;
875 }
876
877 bool
878 R600InstrInfo::DefinesPredicate(MachineInstr *MI,
879                                 std::vector<MachineOperand> &Pred) const {
880   return isPredicateSetter(MI->getOpcode());
881 }
882
883
884 bool
885 R600InstrInfo::SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
886                        const SmallVectorImpl<MachineOperand> &Pred2) const {
887   return false;
888 }
889
890
891 bool
892 R600InstrInfo::PredicateInstruction(MachineInstr *MI,
893                       const SmallVectorImpl<MachineOperand> &Pred) const {
894   int PIdx = MI->findFirstPredOperandIdx();
895
896   if (MI->getOpcode() == AMDGPU::CF_ALU) {
897     MI->getOperand(8).setImm(0);
898     return true;
899   }
900
901   if (PIdx != -1) {
902     MachineOperand &PMO = MI->getOperand(PIdx);
903     PMO.setReg(Pred[2].getReg());
904     MachineInstrBuilder MIB(*MI->getParent()->getParent(), MI);
905     MIB.addReg(AMDGPU::PREDICATE_BIT, RegState::Implicit);
906     return true;
907   }
908
909   return false;
910 }
911
912 unsigned int R600InstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
913                                             const MachineInstr *MI,
914                                             unsigned *PredCost) const {
915   if (PredCost)
916     *PredCost = 2;
917   return 2;
918 }
919
920 int R600InstrInfo::getIndirectIndexBegin(const MachineFunction &MF) const {
921   const MachineRegisterInfo &MRI = MF.getRegInfo();
922   const MachineFrameInfo *MFI = MF.getFrameInfo();
923   int Offset = 0;
924
925   if (MFI->getNumObjects() == 0) {
926     return -1;
927   }
928
929   if (MRI.livein_empty()) {
930     return 0;
931   }
932
933   for (MachineRegisterInfo::livein_iterator LI = MRI.livein_begin(),
934                                             LE = MRI.livein_end();
935                                             LI != LE; ++LI) {
936     Offset = std::max(Offset,
937                       GET_REG_INDEX(RI.getEncodingValue(LI->first)));
938   }
939
940   return Offset + 1;
941 }
942
943 int R600InstrInfo::getIndirectIndexEnd(const MachineFunction &MF) const {
944   int Offset = 0;
945   const MachineFrameInfo *MFI = MF.getFrameInfo();
946
947   // Variable sized objects are not supported
948   assert(!MFI->hasVarSizedObjects());
949
950   if (MFI->getNumObjects() == 0) {
951     return -1;
952   }
953
954   Offset = TM.getFrameLowering()->getFrameIndexOffset(MF, -1);
955
956   return getIndirectIndexBegin(MF) + Offset;
957 }
958
959 std::vector<unsigned> R600InstrInfo::getIndirectReservedRegs(
960                                              const MachineFunction &MF) const {
961   const AMDGPUFrameLowering *TFL =
962                  static_cast<const AMDGPUFrameLowering*>(TM.getFrameLowering());
963   std::vector<unsigned> Regs;
964
965   unsigned StackWidth = TFL->getStackWidth(MF);
966   int End = getIndirectIndexEnd(MF);
967
968   if (End == -1) {
969     return Regs;
970   }
971
972   for (int Index = getIndirectIndexBegin(MF); Index <= End; ++Index) {
973     unsigned SuperReg = AMDGPU::R600_Reg128RegClass.getRegister(Index);
974     Regs.push_back(SuperReg);
975     for (unsigned Chan = 0; Chan < StackWidth; ++Chan) {
976       unsigned Reg = AMDGPU::R600_TReg32RegClass.getRegister((4 * Index) + Chan);
977       Regs.push_back(Reg);
978     }
979   }
980   return Regs;
981 }
982
983 unsigned R600InstrInfo::calculateIndirectAddress(unsigned RegIndex,
984                                                  unsigned Channel) const {
985   // XXX: Remove when we support a stack width > 2
986   assert(Channel == 0);
987   return RegIndex;
988 }
989
990 const TargetRegisterClass * R600InstrInfo::getIndirectAddrStoreRegClass(
991                                                      unsigned SourceReg) const {
992   return &AMDGPU::R600_TReg32RegClass;
993 }
994
995 const TargetRegisterClass *R600InstrInfo::getIndirectAddrLoadRegClass() const {
996   return &AMDGPU::TRegMemRegClass;
997 }
998
999 MachineInstrBuilder R600InstrInfo::buildIndirectWrite(MachineBasicBlock *MBB,
1000                                        MachineBasicBlock::iterator I,
1001                                        unsigned ValueReg, unsigned Address,
1002                                        unsigned OffsetReg) const {
1003   unsigned AddrReg = AMDGPU::R600_AddrRegClass.getRegister(Address);
1004   MachineInstr *MOVA = buildDefaultInstruction(*MBB, I, AMDGPU::MOVA_INT_eg,
1005                                                AMDGPU::AR_X, OffsetReg);
1006   setImmOperand(MOVA, AMDGPU::OpName::write, 0);
1007
1008   MachineInstrBuilder Mov = buildDefaultInstruction(*MBB, I, AMDGPU::MOV,
1009                                       AddrReg, ValueReg)
1010                                       .addReg(AMDGPU::AR_X,
1011                                            RegState::Implicit | RegState::Kill);
1012   setImmOperand(Mov, AMDGPU::OpName::dst_rel, 1);
1013   return Mov;
1014 }
1015
1016 MachineInstrBuilder R600InstrInfo::buildIndirectRead(MachineBasicBlock *MBB,
1017                                        MachineBasicBlock::iterator I,
1018                                        unsigned ValueReg, unsigned Address,
1019                                        unsigned OffsetReg) const {
1020   unsigned AddrReg = AMDGPU::R600_AddrRegClass.getRegister(Address);
1021   MachineInstr *MOVA = buildDefaultInstruction(*MBB, I, AMDGPU::MOVA_INT_eg,
1022                                                        AMDGPU::AR_X,
1023                                                        OffsetReg);
1024   setImmOperand(MOVA, AMDGPU::OpName::write, 0);
1025   MachineInstrBuilder Mov = buildDefaultInstruction(*MBB, I, AMDGPU::MOV,
1026                                       ValueReg,
1027                                       AddrReg)
1028                                       .addReg(AMDGPU::AR_X,
1029                                            RegState::Implicit | RegState::Kill);
1030   setImmOperand(Mov, AMDGPU::OpName::src0_rel, 1);
1031
1032   return Mov;
1033 }
1034
1035 const TargetRegisterClass *R600InstrInfo::getSuperIndirectRegClass() const {
1036   return &AMDGPU::IndirectRegRegClass;
1037 }
1038
1039 unsigned R600InstrInfo::getMaxAlusPerClause() const {
1040   return 115;
1041 }
1042
1043 MachineInstrBuilder R600InstrInfo::buildDefaultInstruction(MachineBasicBlock &MBB,
1044                                                   MachineBasicBlock::iterator I,
1045                                                   unsigned Opcode,
1046                                                   unsigned DstReg,
1047                                                   unsigned Src0Reg,
1048                                                   unsigned Src1Reg) const {
1049   MachineInstrBuilder MIB = BuildMI(MBB, I, MBB.findDebugLoc(I), get(Opcode),
1050     DstReg);           // $dst
1051
1052   if (Src1Reg) {
1053     MIB.addImm(0)     // $update_exec_mask
1054        .addImm(0);    // $update_predicate
1055   }
1056   MIB.addImm(1)        // $write
1057      .addImm(0)        // $omod
1058      .addImm(0)        // $dst_rel
1059      .addImm(0)        // $dst_clamp
1060      .addReg(Src0Reg)  // $src0
1061      .addImm(0)        // $src0_neg
1062      .addImm(0)        // $src0_rel
1063      .addImm(0)        // $src0_abs
1064      .addImm(-1);       // $src0_sel
1065
1066   if (Src1Reg) {
1067     MIB.addReg(Src1Reg) // $src1
1068        .addImm(0)       // $src1_neg
1069        .addImm(0)       // $src1_rel
1070        .addImm(0)       // $src1_abs
1071        .addImm(-1);      // $src1_sel
1072   }
1073
1074   //XXX: The r600g finalizer expects this to be 1, once we've moved the
1075   //scheduling to the backend, we can change the default to 0.
1076   MIB.addImm(1)        // $last
1077       .addReg(AMDGPU::PRED_SEL_OFF) // $pred_sel
1078       .addImm(0)         // $literal
1079       .addImm(0);        // $bank_swizzle
1080
1081   return MIB;
1082 }
1083
1084 #define OPERAND_CASE(Label) \
1085   case Label: { \
1086     static const unsigned Ops[] = \
1087     { \
1088       Label##_X, \
1089       Label##_Y, \
1090       Label##_Z, \
1091       Label##_W \
1092     }; \
1093     return Ops[Slot]; \
1094   }
1095
1096 static unsigned getSlotedOps(unsigned  Op, unsigned Slot) {
1097   switch (Op) {
1098   OPERAND_CASE(AMDGPU::OpName::update_exec_mask)
1099   OPERAND_CASE(AMDGPU::OpName::update_pred)
1100   OPERAND_CASE(AMDGPU::OpName::write)
1101   OPERAND_CASE(AMDGPU::OpName::omod)
1102   OPERAND_CASE(AMDGPU::OpName::dst_rel)
1103   OPERAND_CASE(AMDGPU::OpName::clamp)
1104   OPERAND_CASE(AMDGPU::OpName::src0)
1105   OPERAND_CASE(AMDGPU::OpName::src0_neg)
1106   OPERAND_CASE(AMDGPU::OpName::src0_rel)
1107   OPERAND_CASE(AMDGPU::OpName::src0_abs)
1108   OPERAND_CASE(AMDGPU::OpName::src0_sel)
1109   OPERAND_CASE(AMDGPU::OpName::src1)
1110   OPERAND_CASE(AMDGPU::OpName::src1_neg)
1111   OPERAND_CASE(AMDGPU::OpName::src1_rel)
1112   OPERAND_CASE(AMDGPU::OpName::src1_abs)
1113   OPERAND_CASE(AMDGPU::OpName::src1_sel)
1114   OPERAND_CASE(AMDGPU::OpName::pred_sel)
1115   default:
1116     llvm_unreachable("Wrong Operand");
1117   }
1118 }
1119
1120 #undef OPERAND_CASE
1121
1122 MachineInstr *R600InstrInfo::buildSlotOfVectorInstruction(
1123     MachineBasicBlock &MBB, MachineInstr *MI, unsigned Slot, unsigned DstReg)
1124     const {
1125   assert (MI->getOpcode() == AMDGPU::DOT_4 && "Not Implemented");
1126   unsigned Opcode;
1127   const AMDGPUSubtarget &ST = TM.getSubtarget<AMDGPUSubtarget>();
1128   if (ST.getGeneration() <= AMDGPUSubtarget::R700)
1129     Opcode = AMDGPU::DOT4_r600;
1130   else
1131     Opcode = AMDGPU::DOT4_eg;
1132   MachineBasicBlock::iterator I = MI;
1133   MachineOperand &Src0 = MI->getOperand(
1134       getOperandIdx(MI->getOpcode(), getSlotedOps(AMDGPU::OpName::src0, Slot)));
1135   MachineOperand &Src1 = MI->getOperand(
1136       getOperandIdx(MI->getOpcode(), getSlotedOps(AMDGPU::OpName::src1, Slot)));
1137   MachineInstr *MIB = buildDefaultInstruction(
1138       MBB, I, Opcode, DstReg, Src0.getReg(), Src1.getReg());
1139   static const unsigned  Operands[14] = {
1140     AMDGPU::OpName::update_exec_mask,
1141     AMDGPU::OpName::update_pred,
1142     AMDGPU::OpName::write,
1143     AMDGPU::OpName::omod,
1144     AMDGPU::OpName::dst_rel,
1145     AMDGPU::OpName::clamp,
1146     AMDGPU::OpName::src0_neg,
1147     AMDGPU::OpName::src0_rel,
1148     AMDGPU::OpName::src0_abs,
1149     AMDGPU::OpName::src0_sel,
1150     AMDGPU::OpName::src1_neg,
1151     AMDGPU::OpName::src1_rel,
1152     AMDGPU::OpName::src1_abs,
1153     AMDGPU::OpName::src1_sel,
1154   };
1155
1156   for (unsigned i = 0; i < 14; i++) {
1157     MachineOperand &MO = MI->getOperand(
1158         getOperandIdx(MI->getOpcode(), getSlotedOps(Operands[i], Slot)));
1159     assert (MO.isImm());
1160     setImmOperand(MIB, Operands[i], MO.getImm());
1161   }
1162   MIB->getOperand(20).setImm(0);
1163   return MIB;
1164 }
1165
1166 MachineInstr *R600InstrInfo::buildMovImm(MachineBasicBlock &BB,
1167                                          MachineBasicBlock::iterator I,
1168                                          unsigned DstReg,
1169                                          uint64_t Imm) const {
1170   MachineInstr *MovImm = buildDefaultInstruction(BB, I, AMDGPU::MOV, DstReg,
1171                                                   AMDGPU::ALU_LITERAL_X);
1172   setImmOperand(MovImm, AMDGPU::OpName::literal, Imm);
1173   return MovImm;
1174 }
1175
1176 int R600InstrInfo::getOperandIdx(const MachineInstr &MI, unsigned Op) const {
1177   return getOperandIdx(MI.getOpcode(), Op);
1178 }
1179
1180 int R600InstrInfo::getOperandIdx(unsigned Opcode, unsigned Op) const {
1181   return AMDGPU::getNamedOperandIdx(Opcode, Op);
1182 }
1183
1184 void R600InstrInfo::setImmOperand(MachineInstr *MI, unsigned Op,
1185                                   int64_t Imm) const {
1186   int Idx = getOperandIdx(*MI, Op);
1187   assert(Idx != -1 && "Operand not supported for this instruction.");
1188   assert(MI->getOperand(Idx).isImm());
1189   MI->getOperand(Idx).setImm(Imm);
1190 }
1191
1192 //===----------------------------------------------------------------------===//
1193 // Instruction flag getters/setters
1194 //===----------------------------------------------------------------------===//
1195
1196 bool R600InstrInfo::hasFlagOperand(const MachineInstr &MI) const {
1197   return GET_FLAG_OPERAND_IDX(get(MI.getOpcode()).TSFlags) != 0;
1198 }
1199
1200 MachineOperand &R600InstrInfo::getFlagOp(MachineInstr *MI, unsigned SrcIdx,
1201                                          unsigned Flag) const {
1202   unsigned TargetFlags = get(MI->getOpcode()).TSFlags;
1203   int FlagIndex = 0;
1204   if (Flag != 0) {
1205     // If we pass something other than the default value of Flag to this
1206     // function, it means we are want to set a flag on an instruction
1207     // that uses native encoding.
1208     assert(HAS_NATIVE_OPERANDS(TargetFlags));
1209     bool IsOP3 = (TargetFlags & R600_InstFlag::OP3) == R600_InstFlag::OP3;
1210     switch (Flag) {
1211     case MO_FLAG_CLAMP:
1212       FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::clamp);
1213       break;
1214     case MO_FLAG_MASK:
1215       FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::write);
1216       break;
1217     case MO_FLAG_NOT_LAST:
1218     case MO_FLAG_LAST:
1219       FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::last);
1220       break;
1221     case MO_FLAG_NEG:
1222       switch (SrcIdx) {
1223       case 0: FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::src0_neg); break;
1224       case 1: FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::src1_neg); break;
1225       case 2: FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::src2_neg); break;
1226       }
1227       break;
1228
1229     case MO_FLAG_ABS:
1230       assert(!IsOP3 && "Cannot set absolute value modifier for OP3 "
1231                        "instructions.");
1232       (void)IsOP3;
1233       switch (SrcIdx) {
1234       case 0: FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::src0_abs); break;
1235       case 1: FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::src1_abs); break;
1236       }
1237       break;
1238
1239     default:
1240       FlagIndex = -1;
1241       break;
1242     }
1243     assert(FlagIndex != -1 && "Flag not supported for this instruction");
1244   } else {
1245       FlagIndex = GET_FLAG_OPERAND_IDX(TargetFlags);
1246       assert(FlagIndex != 0 &&
1247          "Instruction flags not supported for this instruction");
1248   }
1249
1250   MachineOperand &FlagOp = MI->getOperand(FlagIndex);
1251   assert(FlagOp.isImm());
1252   return FlagOp;
1253 }
1254
1255 void R600InstrInfo::addFlag(MachineInstr *MI, unsigned Operand,
1256                             unsigned Flag) const {
1257   unsigned TargetFlags = get(MI->getOpcode()).TSFlags;
1258   if (Flag == 0) {
1259     return;
1260   }
1261   if (HAS_NATIVE_OPERANDS(TargetFlags)) {
1262     MachineOperand &FlagOp = getFlagOp(MI, Operand, Flag);
1263     if (Flag == MO_FLAG_NOT_LAST) {
1264       clearFlag(MI, Operand, MO_FLAG_LAST);
1265     } else if (Flag == MO_FLAG_MASK) {
1266       clearFlag(MI, Operand, Flag);
1267     } else {
1268       FlagOp.setImm(1);
1269     }
1270   } else {
1271       MachineOperand &FlagOp = getFlagOp(MI, Operand);
1272       FlagOp.setImm(FlagOp.getImm() | (Flag << (NUM_MO_FLAGS * Operand)));
1273   }
1274 }
1275
1276 void R600InstrInfo::clearFlag(MachineInstr *MI, unsigned Operand,
1277                               unsigned Flag) const {
1278   unsigned TargetFlags = get(MI->getOpcode()).TSFlags;
1279   if (HAS_NATIVE_OPERANDS(TargetFlags)) {
1280     MachineOperand &FlagOp = getFlagOp(MI, Operand, Flag);
1281     FlagOp.setImm(0);
1282   } else {
1283     MachineOperand &FlagOp = getFlagOp(MI);
1284     unsigned InstFlags = FlagOp.getImm();
1285     InstFlags &= ~(Flag << (NUM_MO_FLAGS * Operand));
1286     FlagOp.setImm(InstFlags);
1287   }
1288 }