Coverage Report

Created: 2019-07-24 05:18

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