LCOV - code coverage report
Current view: top level - lib/Target/AMDGPU - R600InstrInfo.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 605 658 91.9 %
Date: 2018-06-17 00:07:59 Functions: 76 77 98.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13