R600: Add FetchInst bit to instruction defs to denote vertex/tex instructions
[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 "AMDGPUSubtarget.h"
17 #include "AMDGPUTargetMachine.h"
18 #include "R600Defines.h"
19 #include "R600MachineFunctionInfo.h"
20 #include "R600RegisterInfo.h"
21 #include "llvm/CodeGen/MachineInstrBuilder.h"
22 #include "llvm/CodeGen/MachineFrameInfo.h"
23 #include "llvm/CodeGen/MachineRegisterInfo.h"
24
25 #define GET_INSTRINFO_CTOR
26 #include "AMDGPUGenDFAPacketizer.inc"
27
28 using namespace llvm;
29
30 R600InstrInfo::R600InstrInfo(AMDGPUTargetMachine &tm)
31   : AMDGPUInstrInfo(tm),
32     RI(tm, *this),
33     ST(tm.getSubtarget<AMDGPUSubtarget>())
34   { }
35
36 const R600RegisterInfo &R600InstrInfo::getRegisterInfo() const {
37   return RI;
38 }
39
40 bool R600InstrInfo::isTrig(const MachineInstr &MI) const {
41   return get(MI.getOpcode()).TSFlags & R600_InstFlag::TRIG;
42 }
43
44 bool R600InstrInfo::isVector(const MachineInstr &MI) const {
45   return get(MI.getOpcode()).TSFlags & R600_InstFlag::VECTOR;
46 }
47
48 void
49 R600InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
50                            MachineBasicBlock::iterator MI, DebugLoc DL,
51                            unsigned DestReg, unsigned SrcReg,
52                            bool KillSrc) const {
53   if (AMDGPU::R600_Reg128RegClass.contains(DestReg)
54       && AMDGPU::R600_Reg128RegClass.contains(SrcReg)) {
55     for (unsigned I = 0; I < 4; I++) {
56       unsigned SubRegIndex = RI.getSubRegFromChannel(I);
57       buildDefaultInstruction(MBB, MI, AMDGPU::MOV,
58                               RI.getSubReg(DestReg, SubRegIndex),
59                               RI.getSubReg(SrcReg, SubRegIndex))
60                               .addReg(DestReg,
61                                       RegState::Define | RegState::Implicit);
62     }
63   } else {
64
65     // We can't copy vec4 registers
66     assert(!AMDGPU::R600_Reg128RegClass.contains(DestReg)
67            && !AMDGPU::R600_Reg128RegClass.contains(SrcReg));
68
69     MachineInstr *NewMI = buildDefaultInstruction(MBB, MI, AMDGPU::MOV,
70                                                   DestReg, SrcReg);
71     NewMI->getOperand(getOperandIdx(*NewMI, R600Operands::SRC0))
72                                     .setIsKill(KillSrc);
73   }
74 }
75
76 MachineInstr * R600InstrInfo::getMovImmInstr(MachineFunction *MF,
77                                              unsigned DstReg, int64_t Imm) const {
78   MachineInstr * MI = MF->CreateMachineInstr(get(AMDGPU::MOV), DebugLoc());
79   MachineInstrBuilder MIB(*MF, MI);
80   MIB.addReg(DstReg, RegState::Define);
81   MIB.addReg(AMDGPU::ALU_LITERAL_X);
82   MIB.addImm(Imm);
83   MIB.addReg(0); // PREDICATE_BIT
84
85   return MI;
86 }
87
88 unsigned R600InstrInfo::getIEQOpcode() const {
89   return AMDGPU::SETE_INT;
90 }
91
92 bool R600InstrInfo::isMov(unsigned Opcode) const {
93
94
95   switch(Opcode) {
96   default: return false;
97   case AMDGPU::MOV:
98   case AMDGPU::MOV_IMM_F32:
99   case AMDGPU::MOV_IMM_I32:
100     return true;
101   }
102 }
103
104 // Some instructions act as place holders to emulate operations that the GPU
105 // hardware does automatically. This function can be used to check if
106 // an opcode falls into this category.
107 bool R600InstrInfo::isPlaceHolderOpcode(unsigned Opcode) const {
108   switch (Opcode) {
109   default: return false;
110   case AMDGPU::RETURN:
111     return true;
112   }
113 }
114
115 bool R600InstrInfo::isReductionOp(unsigned Opcode) const {
116   switch(Opcode) {
117     default: return false;
118     case AMDGPU::DOT4_r600_pseudo:
119     case AMDGPU::DOT4_eg_pseudo:
120       return true;
121   }
122 }
123
124 bool R600InstrInfo::isCubeOp(unsigned Opcode) const {
125   switch(Opcode) {
126     default: return false;
127     case AMDGPU::CUBE_r600_pseudo:
128     case AMDGPU::CUBE_r600_real:
129     case AMDGPU::CUBE_eg_pseudo:
130     case AMDGPU::CUBE_eg_real:
131       return true;
132   }
133 }
134
135 bool R600InstrInfo::isALUInstr(unsigned Opcode) const {
136   unsigned TargetFlags = get(Opcode).TSFlags;
137
138   return ((TargetFlags & R600_InstFlag::OP1) |
139           (TargetFlags & R600_InstFlag::OP2) |
140           (TargetFlags & R600_InstFlag::OP3));
141 }
142
143 bool R600InstrInfo::usesVertexCache(unsigned Opcode) const {
144   return ST.hasVertexCache() && get(Opcode).TSFlags & R600_InstFlag::VTX_INST;
145 }
146
147 bool R600InstrInfo::usesVertexCache(const MachineInstr *MI) const {
148   return usesVertexCache(MI->getOpcode());
149 }
150
151 bool R600InstrInfo::usesTextureCache(unsigned Opcode) const {
152   return (!ST.hasVertexCache() && get(Opcode).TSFlags & R600_InstFlag::VTX_INST) ||
153       (get(Opcode).TSFlags & R600_InstFlag::TEX_INST);
154 }
155
156 bool R600InstrInfo::usesTextureCache(const MachineInstr *MI) const {
157   return usesTextureCache(MI->getOpcode());
158 }
159
160 bool
161 R600InstrInfo::fitsConstReadLimitations(const std::vector<unsigned> &Consts)
162     const {
163   assert (Consts.size() <= 12 && "Too many operands in instructions group");
164   unsigned Pair1 = 0, Pair2 = 0;
165   for (unsigned i = 0, n = Consts.size(); i < n; ++i) {
166     unsigned ReadConstHalf = Consts[i] & 2;
167     unsigned ReadConstIndex = Consts[i] & (~3);
168     unsigned ReadHalfConst = ReadConstIndex | ReadConstHalf;
169     if (!Pair1) {
170       Pair1 = ReadHalfConst;
171       continue;
172     }
173     if (Pair1 == ReadHalfConst)
174       continue;
175     if (!Pair2) {
176       Pair2 = ReadHalfConst;
177       continue;
178     }
179     if (Pair2 != ReadHalfConst)
180       return false;
181   }
182   return true;
183 }
184
185 bool
186 R600InstrInfo::canBundle(const std::vector<MachineInstr *> &MIs) const {
187   std::vector<unsigned> Consts;
188   for (unsigned i = 0, n = MIs.size(); i < n; i++) {
189     const MachineInstr *MI = MIs[i];
190
191     const R600Operands::Ops OpTable[3][2] = {
192       {R600Operands::SRC0, R600Operands::SRC0_SEL},
193       {R600Operands::SRC1, R600Operands::SRC1_SEL},
194       {R600Operands::SRC2, R600Operands::SRC2_SEL},
195     };
196
197     if (!isALUInstr(MI->getOpcode()))
198       continue;
199
200     for (unsigned j = 0; j < 3; j++) {
201       int SrcIdx = getOperandIdx(MI->getOpcode(), OpTable[j][0]);
202       if (SrcIdx < 0)
203         break;
204       if (MI->getOperand(SrcIdx).getReg() == AMDGPU::ALU_CONST) {
205         unsigned Const = MI->getOperand(
206             getOperandIdx(MI->getOpcode(), OpTable[j][1])).getImm();
207         Consts.push_back(Const);
208       }
209     }
210   }
211   return fitsConstReadLimitations(Consts);
212 }
213
214 DFAPacketizer *R600InstrInfo::CreateTargetScheduleState(const TargetMachine *TM,
215     const ScheduleDAG *DAG) const {
216   const InstrItineraryData *II = TM->getInstrItineraryData();
217   return TM->getSubtarget<AMDGPUSubtarget>().createDFAPacketizer(II);
218 }
219
220 static bool
221 isPredicateSetter(unsigned Opcode) {
222   switch (Opcode) {
223   case AMDGPU::PRED_X:
224     return true;
225   default:
226     return false;
227   }
228 }
229
230 static MachineInstr *
231 findFirstPredicateSetterFrom(MachineBasicBlock &MBB,
232                              MachineBasicBlock::iterator I) {
233   while (I != MBB.begin()) {
234     --I;
235     MachineInstr *MI = I;
236     if (isPredicateSetter(MI->getOpcode()))
237       return MI;
238   }
239
240   return NULL;
241 }
242
243 static
244 bool isJump(unsigned Opcode) {
245   return Opcode == AMDGPU::JUMP || Opcode == AMDGPU::JUMP_COND;
246 }
247
248 bool
249 R600InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
250                              MachineBasicBlock *&TBB,
251                              MachineBasicBlock *&FBB,
252                              SmallVectorImpl<MachineOperand> &Cond,
253                              bool AllowModify) const {
254   // Most of the following comes from the ARM implementation of AnalyzeBranch
255
256   // If the block has no terminators, it just falls into the block after it.
257   MachineBasicBlock::iterator I = MBB.end();
258   if (I == MBB.begin())
259     return false;
260   --I;
261   while (I->isDebugValue()) {
262     if (I == MBB.begin())
263       return false;
264     --I;
265   }
266   if (!isJump(static_cast<MachineInstr *>(I)->getOpcode())) {
267     return false;
268   }
269
270   // Get the last instruction in the block.
271   MachineInstr *LastInst = I;
272
273   // If there is only one terminator instruction, process it.
274   unsigned LastOpc = LastInst->getOpcode();
275   if (I == MBB.begin() ||
276           !isJump(static_cast<MachineInstr *>(--I)->getOpcode())) {
277     if (LastOpc == AMDGPU::JUMP) {
278       TBB = LastInst->getOperand(0).getMBB();
279       return false;
280     } else if (LastOpc == AMDGPU::JUMP_COND) {
281       MachineInstr *predSet = I;
282       while (!isPredicateSetter(predSet->getOpcode())) {
283         predSet = --I;
284       }
285       TBB = LastInst->getOperand(0).getMBB();
286       Cond.push_back(predSet->getOperand(1));
287       Cond.push_back(predSet->getOperand(2));
288       Cond.push_back(MachineOperand::CreateReg(AMDGPU::PRED_SEL_ONE, false));
289       return false;
290     }
291     return true;  // Can't handle indirect branch.
292   }
293
294   // Get the instruction before it if it is a terminator.
295   MachineInstr *SecondLastInst = I;
296   unsigned SecondLastOpc = SecondLastInst->getOpcode();
297
298   // If the block ends with a B and a Bcc, handle it.
299   if (SecondLastOpc == AMDGPU::JUMP_COND && LastOpc == AMDGPU::JUMP) {
300     MachineInstr *predSet = --I;
301     while (!isPredicateSetter(predSet->getOpcode())) {
302       predSet = --I;
303     }
304     TBB = SecondLastInst->getOperand(0).getMBB();
305     FBB = LastInst->getOperand(0).getMBB();
306     Cond.push_back(predSet->getOperand(1));
307     Cond.push_back(predSet->getOperand(2));
308     Cond.push_back(MachineOperand::CreateReg(AMDGPU::PRED_SEL_ONE, false));
309     return false;
310   }
311
312   // Otherwise, can't handle this.
313   return true;
314 }
315
316 int R600InstrInfo::getBranchInstr(const MachineOperand &op) const {
317   const MachineInstr *MI = op.getParent();
318
319   switch (MI->getDesc().OpInfo->RegClass) {
320   default: // FIXME: fallthrough??
321   case AMDGPU::GPRI32RegClassID: return AMDGPU::BRANCH_COND_i32;
322   case AMDGPU::GPRF32RegClassID: return AMDGPU::BRANCH_COND_f32;
323   };
324 }
325
326 unsigned
327 R600InstrInfo::InsertBranch(MachineBasicBlock &MBB,
328                             MachineBasicBlock *TBB,
329                             MachineBasicBlock *FBB,
330                             const SmallVectorImpl<MachineOperand> &Cond,
331                             DebugLoc DL) const {
332   assert(TBB && "InsertBranch must not be told to insert a fallthrough");
333
334   if (FBB == 0) {
335     if (Cond.empty()) {
336       BuildMI(&MBB, DL, get(AMDGPU::JUMP)).addMBB(TBB);
337       return 1;
338     } else {
339       MachineInstr *PredSet = findFirstPredicateSetterFrom(MBB, MBB.end());
340       assert(PredSet && "No previous predicate !");
341       addFlag(PredSet, 0, MO_FLAG_PUSH);
342       PredSet->getOperand(2).setImm(Cond[1].getImm());
343
344       BuildMI(&MBB, DL, get(AMDGPU::JUMP_COND))
345              .addMBB(TBB)
346              .addReg(AMDGPU::PREDICATE_BIT, RegState::Kill);
347       return 1;
348     }
349   } else {
350     MachineInstr *PredSet = findFirstPredicateSetterFrom(MBB, MBB.end());
351     assert(PredSet && "No previous predicate !");
352     addFlag(PredSet, 0, MO_FLAG_PUSH);
353     PredSet->getOperand(2).setImm(Cond[1].getImm());
354     BuildMI(&MBB, DL, get(AMDGPU::JUMP_COND))
355             .addMBB(TBB)
356             .addReg(AMDGPU::PREDICATE_BIT, RegState::Kill);
357     BuildMI(&MBB, DL, get(AMDGPU::JUMP)).addMBB(FBB);
358     return 2;
359   }
360 }
361
362 unsigned
363 R600InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
364
365   // Note : we leave PRED* instructions there.
366   // They may be needed when predicating instructions.
367
368   MachineBasicBlock::iterator I = MBB.end();
369
370   if (I == MBB.begin()) {
371     return 0;
372   }
373   --I;
374   switch (I->getOpcode()) {
375   default:
376     return 0;
377   case AMDGPU::JUMP_COND: {
378     MachineInstr *predSet = findFirstPredicateSetterFrom(MBB, I);
379     clearFlag(predSet, 0, MO_FLAG_PUSH);
380     I->eraseFromParent();
381     break;
382   }
383   case AMDGPU::JUMP:
384     I->eraseFromParent();
385     break;
386   }
387   I = MBB.end();
388
389   if (I == MBB.begin()) {
390     return 1;
391   }
392   --I;
393   switch (I->getOpcode()) {
394     // FIXME: only one case??
395   default:
396     return 1;
397   case AMDGPU::JUMP_COND: {
398     MachineInstr *predSet = findFirstPredicateSetterFrom(MBB, I);
399     clearFlag(predSet, 0, MO_FLAG_PUSH);
400     I->eraseFromParent();
401     break;
402   }
403   case AMDGPU::JUMP:
404     I->eraseFromParent();
405     break;
406   }
407   return 2;
408 }
409
410 bool
411 R600InstrInfo::isPredicated(const MachineInstr *MI) const {
412   int idx = MI->findFirstPredOperandIdx();
413   if (idx < 0)
414     return false;
415
416   unsigned Reg = MI->getOperand(idx).getReg();
417   switch (Reg) {
418   default: return false;
419   case AMDGPU::PRED_SEL_ONE:
420   case AMDGPU::PRED_SEL_ZERO:
421   case AMDGPU::PREDICATE_BIT:
422     return true;
423   }
424 }
425
426 bool
427 R600InstrInfo::isPredicable(MachineInstr *MI) const {
428   // XXX: KILL* instructions can be predicated, but they must be the last
429   // instruction in a clause, so this means any instructions after them cannot
430   // be predicated.  Until we have proper support for instruction clauses in the
431   // backend, we will mark KILL* instructions as unpredicable.
432
433   if (MI->getOpcode() == AMDGPU::KILLGT) {
434     return false;
435   } else if (isVector(*MI)) {
436     return false;
437   } else {
438     return AMDGPUInstrInfo::isPredicable(MI);
439   }
440 }
441
442
443 bool
444 R600InstrInfo::isProfitableToIfCvt(MachineBasicBlock &MBB,
445                                    unsigned NumCyles,
446                                    unsigned ExtraPredCycles,
447                                    const BranchProbability &Probability) const{
448   return true;
449 }
450
451 bool
452 R600InstrInfo::isProfitableToIfCvt(MachineBasicBlock &TMBB,
453                                    unsigned NumTCycles,
454                                    unsigned ExtraTCycles,
455                                    MachineBasicBlock &FMBB,
456                                    unsigned NumFCycles,
457                                    unsigned ExtraFCycles,
458                                    const BranchProbability &Probability) const {
459   return true;
460 }
461
462 bool
463 R600InstrInfo::isProfitableToDupForIfCvt(MachineBasicBlock &MBB,
464                                          unsigned NumCyles,
465                                          const BranchProbability &Probability)
466                                          const {
467   return true;
468 }
469
470 bool
471 R600InstrInfo::isProfitableToUnpredicate(MachineBasicBlock &TMBB,
472                                          MachineBasicBlock &FMBB) const {
473   return false;
474 }
475
476
477 bool
478 R600InstrInfo::ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
479   MachineOperand &MO = Cond[1];
480   switch (MO.getImm()) {
481   case OPCODE_IS_ZERO_INT:
482     MO.setImm(OPCODE_IS_NOT_ZERO_INT);
483     break;
484   case OPCODE_IS_NOT_ZERO_INT:
485     MO.setImm(OPCODE_IS_ZERO_INT);
486     break;
487   case OPCODE_IS_ZERO:
488     MO.setImm(OPCODE_IS_NOT_ZERO);
489     break;
490   case OPCODE_IS_NOT_ZERO:
491     MO.setImm(OPCODE_IS_ZERO);
492     break;
493   default:
494     return true;
495   }
496
497   MachineOperand &MO2 = Cond[2];
498   switch (MO2.getReg()) {
499   case AMDGPU::PRED_SEL_ZERO:
500     MO2.setReg(AMDGPU::PRED_SEL_ONE);
501     break;
502   case AMDGPU::PRED_SEL_ONE:
503     MO2.setReg(AMDGPU::PRED_SEL_ZERO);
504     break;
505   default:
506     return true;
507   }
508   return false;
509 }
510
511 bool
512 R600InstrInfo::DefinesPredicate(MachineInstr *MI,
513                                 std::vector<MachineOperand> &Pred) const {
514   return isPredicateSetter(MI->getOpcode());
515 }
516
517
518 bool
519 R600InstrInfo::SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
520                        const SmallVectorImpl<MachineOperand> &Pred2) const {
521   return false;
522 }
523
524
525 bool
526 R600InstrInfo::PredicateInstruction(MachineInstr *MI,
527                       const SmallVectorImpl<MachineOperand> &Pred) const {
528   int PIdx = MI->findFirstPredOperandIdx();
529
530   if (PIdx != -1) {
531     MachineOperand &PMO = MI->getOperand(PIdx);
532     PMO.setReg(Pred[2].getReg());
533     MachineInstrBuilder MIB(*MI->getParent()->getParent(), MI);
534     MIB.addReg(AMDGPU::PREDICATE_BIT, RegState::Implicit);
535     return true;
536   }
537
538   return false;
539 }
540
541 unsigned int R600InstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
542                                             const MachineInstr *MI,
543                                             unsigned *PredCost) const {
544   if (PredCost)
545     *PredCost = 2;
546   return 2;
547 }
548
549 int R600InstrInfo::getIndirectIndexBegin(const MachineFunction &MF) const {
550   const MachineRegisterInfo &MRI = MF.getRegInfo();
551   const MachineFrameInfo *MFI = MF.getFrameInfo();
552   int Offset = 0;
553
554   if (MFI->getNumObjects() == 0) {
555     return -1;
556   }
557
558   if (MRI.livein_empty()) {
559     return 0;
560   }
561
562   for (MachineRegisterInfo::livein_iterator LI = MRI.livein_begin(),
563                                             LE = MRI.livein_end();
564                                             LI != LE; ++LI) {
565     Offset = std::max(Offset,
566                       GET_REG_INDEX(RI.getEncodingValue(LI->first)));
567   }
568
569   return Offset + 1;
570 }
571
572 int R600InstrInfo::getIndirectIndexEnd(const MachineFunction &MF) const {
573   int Offset = 0;
574   const MachineFrameInfo *MFI = MF.getFrameInfo();
575
576   // Variable sized objects are not supported
577   assert(!MFI->hasVarSizedObjects());
578
579   if (MFI->getNumObjects() == 0) {
580     return -1;
581   }
582
583   Offset = TM.getFrameLowering()->getFrameIndexOffset(MF, -1);
584
585   return getIndirectIndexBegin(MF) + Offset;
586 }
587
588 std::vector<unsigned> R600InstrInfo::getIndirectReservedRegs(
589                                              const MachineFunction &MF) const {
590   const AMDGPUFrameLowering *TFL =
591                  static_cast<const AMDGPUFrameLowering*>(TM.getFrameLowering());
592   std::vector<unsigned> Regs;
593
594   unsigned StackWidth = TFL->getStackWidth(MF);
595   int End = getIndirectIndexEnd(MF);
596
597   if (End == -1) {
598     return Regs;
599   }
600
601   for (int Index = getIndirectIndexBegin(MF); Index <= End; ++Index) {
602     unsigned SuperReg = AMDGPU::R600_Reg128RegClass.getRegister(Index);
603     Regs.push_back(SuperReg);
604     for (unsigned Chan = 0; Chan < StackWidth; ++Chan) {
605       unsigned Reg = AMDGPU::R600_TReg32RegClass.getRegister((4 * Index) + Chan);
606       Regs.push_back(Reg);
607     }
608   }
609   return Regs;
610 }
611
612 unsigned R600InstrInfo::calculateIndirectAddress(unsigned RegIndex,
613                                                  unsigned Channel) const {
614   // XXX: Remove when we support a stack width > 2
615   assert(Channel == 0);
616   return RegIndex;
617 }
618
619 const TargetRegisterClass * R600InstrInfo::getIndirectAddrStoreRegClass(
620                                                      unsigned SourceReg) const {
621   return &AMDGPU::R600_TReg32RegClass;
622 }
623
624 const TargetRegisterClass *R600InstrInfo::getIndirectAddrLoadRegClass() const {
625   return &AMDGPU::TRegMemRegClass;
626 }
627
628 MachineInstrBuilder R600InstrInfo::buildIndirectWrite(MachineBasicBlock *MBB,
629                                        MachineBasicBlock::iterator I,
630                                        unsigned ValueReg, unsigned Address,
631                                        unsigned OffsetReg) const {
632   unsigned AddrReg = AMDGPU::R600_AddrRegClass.getRegister(Address);
633   MachineInstr *MOVA = buildDefaultInstruction(*MBB, I, AMDGPU::MOVA_INT_eg,
634                                                AMDGPU::AR_X, OffsetReg);
635   setImmOperand(MOVA, R600Operands::WRITE, 0);
636
637   MachineInstrBuilder Mov = buildDefaultInstruction(*MBB, I, AMDGPU::MOV,
638                                       AddrReg, ValueReg)
639                                       .addReg(AMDGPU::AR_X, RegState::Implicit);
640   setImmOperand(Mov, R600Operands::DST_REL, 1);
641   return Mov;
642 }
643
644 MachineInstrBuilder R600InstrInfo::buildIndirectRead(MachineBasicBlock *MBB,
645                                        MachineBasicBlock::iterator I,
646                                        unsigned ValueReg, unsigned Address,
647                                        unsigned OffsetReg) const {
648   unsigned AddrReg = AMDGPU::R600_AddrRegClass.getRegister(Address);
649   MachineInstr *MOVA = buildDefaultInstruction(*MBB, I, AMDGPU::MOVA_INT_eg,
650                                                        AMDGPU::AR_X,
651                                                        OffsetReg);
652   setImmOperand(MOVA, R600Operands::WRITE, 0);
653   MachineInstrBuilder Mov = buildDefaultInstruction(*MBB, I, AMDGPU::MOV,
654                                       ValueReg,
655                                       AddrReg)
656                                       .addReg(AMDGPU::AR_X, RegState::Implicit);
657   setImmOperand(Mov, R600Operands::SRC0_REL, 1);
658
659   return Mov;
660 }
661
662 const TargetRegisterClass *R600InstrInfo::getSuperIndirectRegClass() const {
663   return &AMDGPU::IndirectRegRegClass;
664 }
665
666 unsigned R600InstrInfo::getMaxAlusPerClause() const {
667   return 115;
668 }
669
670 MachineInstrBuilder R600InstrInfo::buildDefaultInstruction(MachineBasicBlock &MBB,
671                                                   MachineBasicBlock::iterator I,
672                                                   unsigned Opcode,
673                                                   unsigned DstReg,
674                                                   unsigned Src0Reg,
675                                                   unsigned Src1Reg) const {
676   MachineInstrBuilder MIB = BuildMI(MBB, I, MBB.findDebugLoc(I), get(Opcode),
677     DstReg);           // $dst
678
679   if (Src1Reg) {
680     MIB.addImm(0)     // $update_exec_mask
681        .addImm(0);    // $update_predicate
682   }
683   MIB.addImm(1)        // $write
684      .addImm(0)        // $omod
685      .addImm(0)        // $dst_rel
686      .addImm(0)        // $dst_clamp
687      .addReg(Src0Reg)  // $src0
688      .addImm(0)        // $src0_neg
689      .addImm(0)        // $src0_rel
690      .addImm(0)        // $src0_abs
691      .addImm(-1);       // $src0_sel
692
693   if (Src1Reg) {
694     MIB.addReg(Src1Reg) // $src1
695        .addImm(0)       // $src1_neg
696        .addImm(0)       // $src1_rel
697        .addImm(0)       // $src1_abs
698        .addImm(-1);      // $src1_sel
699   }
700
701   //XXX: The r600g finalizer expects this to be 1, once we've moved the
702   //scheduling to the backend, we can change the default to 0.
703   MIB.addImm(1)        // $last
704       .addReg(AMDGPU::PRED_SEL_OFF) // $pred_sel
705       .addImm(0);        // $literal
706
707   return MIB;
708 }
709
710 MachineInstr *R600InstrInfo::buildMovImm(MachineBasicBlock &BB,
711                                          MachineBasicBlock::iterator I,
712                                          unsigned DstReg,
713                                          uint64_t Imm) const {
714   MachineInstr *MovImm = buildDefaultInstruction(BB, I, AMDGPU::MOV, DstReg,
715                                                   AMDGPU::ALU_LITERAL_X);
716   setImmOperand(MovImm, R600Operands::IMM, Imm);
717   return MovImm;
718 }
719
720 int R600InstrInfo::getOperandIdx(const MachineInstr &MI,
721                                  R600Operands::Ops Op) const {
722   return getOperandIdx(MI.getOpcode(), Op);
723 }
724
725 int R600InstrInfo::getOperandIdx(unsigned Opcode,
726                                  R600Operands::Ops Op) const {
727   unsigned TargetFlags = get(Opcode).TSFlags;
728   unsigned OpTableIdx;
729
730   if (!HAS_NATIVE_OPERANDS(TargetFlags)) {
731     switch (Op) {
732     case R600Operands::DST: return 0;
733     case R600Operands::SRC0: return 1;
734     case R600Operands::SRC1: return 2;
735     case R600Operands::SRC2: return 3;
736     default:
737       assert(!"Unknown operand type for instruction");
738       return -1;
739     }
740   }
741
742   if (TargetFlags & R600_InstFlag::OP1) {
743     OpTableIdx = 0;
744   } else if (TargetFlags & R600_InstFlag::OP2) {
745     OpTableIdx = 1;
746   } else {
747     assert((TargetFlags & R600_InstFlag::OP3) && "OP1, OP2, or OP3 not defined "
748                                                  "for this instruction");
749     OpTableIdx = 2;
750   }
751
752   return R600Operands::ALUOpTable[OpTableIdx][Op];
753 }
754
755 void R600InstrInfo::setImmOperand(MachineInstr *MI, R600Operands::Ops Op,
756                                   int64_t Imm) const {
757   int Idx = getOperandIdx(*MI, Op);
758   assert(Idx != -1 && "Operand not supported for this instruction.");
759   assert(MI->getOperand(Idx).isImm());
760   MI->getOperand(Idx).setImm(Imm);
761 }
762
763 //===----------------------------------------------------------------------===//
764 // Instruction flag getters/setters
765 //===----------------------------------------------------------------------===//
766
767 bool R600InstrInfo::hasFlagOperand(const MachineInstr &MI) const {
768   return GET_FLAG_OPERAND_IDX(get(MI.getOpcode()).TSFlags) != 0;
769 }
770
771 MachineOperand &R600InstrInfo::getFlagOp(MachineInstr *MI, unsigned SrcIdx,
772                                          unsigned Flag) const {
773   unsigned TargetFlags = get(MI->getOpcode()).TSFlags;
774   int FlagIndex = 0;
775   if (Flag != 0) {
776     // If we pass something other than the default value of Flag to this
777     // function, it means we are want to set a flag on an instruction
778     // that uses native encoding.
779     assert(HAS_NATIVE_OPERANDS(TargetFlags));
780     bool IsOP3 = (TargetFlags & R600_InstFlag::OP3) == R600_InstFlag::OP3;
781     switch (Flag) {
782     case MO_FLAG_CLAMP:
783       FlagIndex = getOperandIdx(*MI, R600Operands::CLAMP);
784       break;
785     case MO_FLAG_MASK:
786       FlagIndex = getOperandIdx(*MI, R600Operands::WRITE);
787       break;
788     case MO_FLAG_NOT_LAST:
789     case MO_FLAG_LAST:
790       FlagIndex = getOperandIdx(*MI, R600Operands::LAST);
791       break;
792     case MO_FLAG_NEG:
793       switch (SrcIdx) {
794       case 0: FlagIndex = getOperandIdx(*MI, R600Operands::SRC0_NEG); break;
795       case 1: FlagIndex = getOperandIdx(*MI, R600Operands::SRC1_NEG); break;
796       case 2: FlagIndex = getOperandIdx(*MI, R600Operands::SRC2_NEG); break;
797       }
798       break;
799
800     case MO_FLAG_ABS:
801       assert(!IsOP3 && "Cannot set absolute value modifier for OP3 "
802                        "instructions.");
803       (void)IsOP3;
804       switch (SrcIdx) {
805       case 0: FlagIndex = getOperandIdx(*MI, R600Operands::SRC0_ABS); break;
806       case 1: FlagIndex = getOperandIdx(*MI, R600Operands::SRC1_ABS); break;
807       }
808       break;
809
810     default:
811       FlagIndex = -1;
812       break;
813     }
814     assert(FlagIndex != -1 && "Flag not supported for this instruction");
815   } else {
816       FlagIndex = GET_FLAG_OPERAND_IDX(TargetFlags);
817       assert(FlagIndex != 0 &&
818          "Instruction flags not supported for this instruction");
819   }
820
821   MachineOperand &FlagOp = MI->getOperand(FlagIndex);
822   assert(FlagOp.isImm());
823   return FlagOp;
824 }
825
826 void R600InstrInfo::addFlag(MachineInstr *MI, unsigned Operand,
827                             unsigned Flag) const {
828   unsigned TargetFlags = get(MI->getOpcode()).TSFlags;
829   if (Flag == 0) {
830     return;
831   }
832   if (HAS_NATIVE_OPERANDS(TargetFlags)) {
833     MachineOperand &FlagOp = getFlagOp(MI, Operand, Flag);
834     if (Flag == MO_FLAG_NOT_LAST) {
835       clearFlag(MI, Operand, MO_FLAG_LAST);
836     } else if (Flag == MO_FLAG_MASK) {
837       clearFlag(MI, Operand, Flag);
838     } else {
839       FlagOp.setImm(1);
840     }
841   } else {
842       MachineOperand &FlagOp = getFlagOp(MI, Operand);
843       FlagOp.setImm(FlagOp.getImm() | (Flag << (NUM_MO_FLAGS * Operand)));
844   }
845 }
846
847 void R600InstrInfo::clearFlag(MachineInstr *MI, unsigned Operand,
848                               unsigned Flag) const {
849   unsigned TargetFlags = get(MI->getOpcode()).TSFlags;
850   if (HAS_NATIVE_OPERANDS(TargetFlags)) {
851     MachineOperand &FlagOp = getFlagOp(MI, Operand, Flag);
852     FlagOp.setImm(0);
853   } else {
854     MachineOperand &FlagOp = getFlagOp(MI);
855     unsigned InstFlags = FlagOp.getImm();
856     InstFlags &= ~(Flag << (NUM_MO_FLAGS * Operand));
857     FlagOp.setImm(InstFlags);
858   }
859 }