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