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