59 if (Op0Idx == -1 && Op1Idx == -1)
63 if ((Op0Idx == -1 && Op1Idx != -1) ||
64 (Op1Idx == -1 && Op0Idx != -1))
83 case AMDGPU::V_MOV_B32_e32:
84 case AMDGPU::V_MOV_B32_e64:
93 int64_t &Offset1)
const {
101 if (!
get(Opc0).mayLoad() || !
get(Opc1).mayLoad())
125 Offset0 = cast<ConstantSDNode>(Load0->
getOperand(2))->getZExtValue();
126 Offset1 = cast<ConstantSDNode>(Load1->
getOperand(2))->getZExtValue();
142 if (!Load0Offset || !Load1Offset)
150 Offset1 = Load1Offset->getZExtValue();
167 if (OffIdx0 == -1 || OffIdx1 == -1)
180 if (!isa<ConstantSDNode>(Off0) || !isa<ConstantSDNode>(Off1))
183 Offset0 = cast<ConstantSDNode>(Off0)->getZExtValue();
184 Offset1 = cast<ConstantSDNode>(Off1)->getZExtValue();
193 case AMDGPU::DS_READ2ST64_B32:
194 case AMDGPU::DS_READ2ST64_B64:
195 case AMDGPU::DS_WRITE2ST64_B32:
196 case AMDGPU::DS_WRITE2ST64_B64:
209 AMDGPU::OpName::offset);
215 BaseReg = AddrReg->
getReg();
216 Offset = OffsetImm->
getImm();
224 AMDGPU::OpName::offset0);
226 AMDGPU::OpName::offset1);
228 uint8_t Offset0 = Offset0Imm->
getImm();
229 uint8_t Offset1 = Offset1Imm->
getImm();
231 if (Offset1 > Offset0 && Offset1 - Offset0 == 1) {
249 BaseReg = AddrReg->
getReg();
250 Offset = EltSize * Offset0;
262 AMDGPU::OpName::vaddr);
267 AMDGPU::OpName::offset);
268 BaseReg = AddrReg->
getReg();
269 Offset = OffsetImm->
getImm();
275 AMDGPU::OpName::offset);
280 AMDGPU::OpName::sbase);
281 BaseReg = SBaseReg->
getReg();
282 Offset = OffsetImm->
getImm();
291 unsigned NumLoads)
const {
314 unsigned DestReg,
unsigned SrcReg,
315 bool KillSrc)
const {
320 assert(DestReg != AMDGPU::SCC && SrcReg != AMDGPU::SCC);
322 static const int16_t Sub0_15[] = {
323 AMDGPU::sub0, AMDGPU::sub1, AMDGPU::sub2, AMDGPU::sub3,
324 AMDGPU::sub4, AMDGPU::sub5, AMDGPU::sub6, AMDGPU::sub7,
325 AMDGPU::sub8, AMDGPU::sub9, AMDGPU::sub10, AMDGPU::sub11,
326 AMDGPU::sub12, AMDGPU::sub13, AMDGPU::sub14, AMDGPU::sub15, 0
329 static const int16_t Sub0_7[] = {
330 AMDGPU::sub0, AMDGPU::sub1, AMDGPU::sub2, AMDGPU::sub3,
331 AMDGPU::sub4, AMDGPU::sub5, AMDGPU::sub6, AMDGPU::sub7, 0
334 static const int16_t Sub0_3[] = {
335 AMDGPU::sub0, AMDGPU::sub1, AMDGPU::sub2, AMDGPU::sub3, 0
338 static const int16_t Sub0_2[] = {
339 AMDGPU::sub0, AMDGPU::sub1, AMDGPU::sub2, 0
342 static const int16_t Sub0_1[] = {
343 AMDGPU::sub0, AMDGPU::sub1, 0
347 const int16_t *SubIndices;
349 if (AMDGPU::SReg_32RegClass.
contains(DestReg)) {
350 assert(AMDGPU::SReg_32RegClass.
contains(SrcReg));
351 BuildMI(MBB, MI, DL,
get(AMDGPU::S_MOV_B32), DestReg)
355 }
else if (AMDGPU::SReg_64RegClass.
contains(DestReg)) {
356 if (DestReg == AMDGPU::VCC) {
357 if (AMDGPU::SReg_64RegClass.
contains(SrcReg)) {
358 BuildMI(MBB, MI, DL,
get(AMDGPU::S_MOV_B64), AMDGPU::VCC)
362 assert(AMDGPU::VGPR_32RegClass.
contains(SrcReg));
363 BuildMI(MBB, MI, DL,
get(AMDGPU::V_CMP_NE_I32_e32), AMDGPU::VCC)
371 assert(AMDGPU::SReg_64RegClass.
contains(SrcReg));
372 BuildMI(MBB, MI, DL,
get(AMDGPU::S_MOV_B64), DestReg)
376 }
else if (AMDGPU::SReg_128RegClass.
contains(DestReg)) {
377 assert(AMDGPU::SReg_128RegClass.
contains(SrcReg));
378 Opcode = AMDGPU::S_MOV_B32;
381 }
else if (AMDGPU::SReg_256RegClass.
contains(DestReg)) {
382 assert(AMDGPU::SReg_256RegClass.
contains(SrcReg));
383 Opcode = AMDGPU::S_MOV_B32;
386 }
else if (AMDGPU::SReg_512RegClass.
contains(DestReg)) {
387 assert(AMDGPU::SReg_512RegClass.
contains(SrcReg));
388 Opcode = AMDGPU::S_MOV_B32;
389 SubIndices = Sub0_15;
391 }
else if (AMDGPU::VGPR_32RegClass.
contains(DestReg)) {
392 assert(AMDGPU::VGPR_32RegClass.
contains(SrcReg) ||
393 AMDGPU::SReg_32RegClass.
contains(SrcReg));
394 BuildMI(MBB, MI, DL,
get(AMDGPU::V_MOV_B32_e32), DestReg)
398 }
else if (AMDGPU::VReg_64RegClass.
contains(DestReg)) {
399 assert(AMDGPU::VReg_64RegClass.
contains(SrcReg) ||
400 AMDGPU::SReg_64RegClass.
contains(SrcReg));
401 Opcode = AMDGPU::V_MOV_B32_e32;
404 }
else if (AMDGPU::VReg_96RegClass.
contains(DestReg)) {
405 assert(AMDGPU::VReg_96RegClass.
contains(SrcReg));
406 Opcode = AMDGPU::V_MOV_B32_e32;
409 }
else if (AMDGPU::VReg_128RegClass.
contains(DestReg)) {
410 assert(AMDGPU::VReg_128RegClass.
contains(SrcReg) ||
411 AMDGPU::SReg_128RegClass.
contains(SrcReg));
412 Opcode = AMDGPU::V_MOV_B32_e32;
415 }
else if (AMDGPU::VReg_256RegClass.
contains(DestReg)) {
416 assert(AMDGPU::VReg_256RegClass.
contains(SrcReg) ||
417 AMDGPU::SReg_256RegClass.
contains(SrcReg));
418 Opcode = AMDGPU::V_MOV_B32_e32;
421 }
else if (AMDGPU::VReg_512RegClass.
contains(DestReg)) {
422 assert(AMDGPU::VReg_512RegClass.
contains(SrcReg) ||
423 AMDGPU::SReg_512RegClass.
contains(SrcReg));
424 Opcode = AMDGPU::V_MOV_B32_e32;
425 SubIndices = Sub0_15;
431 while (
unsigned SubIdx = *SubIndices++) {
433 get(Opcode), RI.getSubReg(DestReg, SubIdx));
465 return RI.
isSGPRClass(DstRC) ? AMDGPU::S_MOV_B32 : AMDGPU::V_MOV_B32_e32;
467 return AMDGPU::S_MOV_B64;
469 return AMDGPU::V_MOV_B64_PSEUDO;
476 unsigned SrcReg,
bool isKill,
491 case 32: Opcode = AMDGPU::SI_SPILL_S32_SAVE;
break;
492 case 64: Opcode = AMDGPU::SI_SPILL_S64_SAVE;
break;
493 case 128: Opcode = AMDGPU::SI_SPILL_S128_SAVE;
break;
494 case 256: Opcode = AMDGPU::SI_SPILL_S256_SAVE;
break;
495 case 512: Opcode = AMDGPU::SI_SPILL_S512_SAVE;
break;
501 case 32: Opcode = AMDGPU::SI_SPILL_V32_SAVE;
break;
502 case 64: Opcode = AMDGPU::SI_SPILL_V64_SAVE;
break;
503 case 96: Opcode = AMDGPU::SI_SPILL_V96_SAVE;
break;
504 case 128: Opcode = AMDGPU::SI_SPILL_V128_SAVE;
break;
505 case 256: Opcode = AMDGPU::SI_SPILL_V256_SAVE;
break;
506 case 512: Opcode = AMDGPU::SI_SPILL_V512_SAVE;
break;
511 FrameInfo->setObjectAlignment(FrameIndex, 4);
512 BuildMI(MBB, MI, DL,
get(Opcode))
521 Ctx.
emitError(
"SIInstrInfo::storeRegToStackSlot - Do not know how to"
541 case 32: Opcode = AMDGPU::SI_SPILL_S32_RESTORE;
break;
542 case 64: Opcode = AMDGPU::SI_SPILL_S64_RESTORE;
break;
543 case 128: Opcode = AMDGPU::SI_SPILL_S128_RESTORE;
break;
544 case 256: Opcode = AMDGPU::SI_SPILL_S256_RESTORE;
break;
545 case 512: Opcode = AMDGPU::SI_SPILL_S512_RESTORE;
break;
549 case 32: Opcode = AMDGPU::SI_SPILL_V32_RESTORE;
break;
550 case 64: Opcode = AMDGPU::SI_SPILL_V64_RESTORE;
break;
551 case 96: Opcode = AMDGPU::SI_SPILL_V96_RESTORE;
break;
552 case 128: Opcode = AMDGPU::SI_SPILL_V128_RESTORE;
break;
553 case 256: Opcode = AMDGPU::SI_SPILL_V256_RESTORE;
break;
554 case 512: Opcode = AMDGPU::SI_SPILL_V512_RESTORE;
break;
559 FrameInfo->setObjectAlignment(FrameIndex, 4);
560 BuildMI(MBB, MI, DL,
get(Opcode), DestReg)
569 Ctx.
emitError(
"SIInstrInfo::loadRegFromStackSlot - Do not know how to"
570 " restore register");
579 unsigned FrameOffset,
580 unsigned Size)
const {
588 unsigned WavefrontSize = ST.getWavefrontSize();
594 DebugLoc DL = Insert->getDebugLoc();
597 if (TIDReg == AMDGPU::NoRegister)
602 WorkGroupSize > WavefrontSize) {
607 unsigned InputPtrReg =
609 for (
unsigned Reg : {TIDIGXReg, TIDIGYReg, TIDIGZReg}) {
617 BuildMI(Entry, Insert, DL,
get(AMDGPU::S_LOAD_DWORD_IMM), STmp0)
620 BuildMI(Entry, Insert, DL,
get(AMDGPU::S_LOAD_DWORD_IMM), STmp1)
625 BuildMI(Entry, Insert, DL,
get(AMDGPU::S_MUL_I32), STmp1)
629 BuildMI(Entry, Insert, DL,
get(AMDGPU::V_MUL_U32_U24_e32), TIDReg)
633 BuildMI(Entry, Insert, DL,
get(AMDGPU::V_MAD_U32_U24), TIDReg)
638 BuildMI(Entry, Insert, DL,
get(AMDGPU::V_ADD_I32_e32), TIDReg)
643 BuildMI(Entry, Insert, DL,
get(AMDGPU::V_MBCNT_LO_U32_B32_e64),
648 BuildMI(Entry, Insert, DL,
get(AMDGPU::V_MBCNT_HI_U32_B32_e64),
654 BuildMI(Entry, Insert, DL,
get(AMDGPU::V_LSHLREV_B32_e32),
662 unsigned LDSOffset = MFI->
LDSSize + (FrameOffset * WorkGroupSize);
663 BuildMI(MBB, MI, DL,
get(AMDGPU::V_ADD_I32_e32), TmpReg)
679 BuildMI(*MI->getParent(),
MI, MI->getDebugLoc(),
get(AMDGPU::S_NOP))
687 switch (MI->getOpcode()) {
690 case AMDGPU::SI_CONSTDATA_PTR: {
691 unsigned Reg = MI->getOperand(0).getReg();
692 unsigned RegLo = RI.getSubReg(Reg, AMDGPU::sub0);
693 unsigned RegHi = RI.getSubReg(Reg, AMDGPU::sub1);
695 BuildMI(MBB, MI, DL,
get(AMDGPU::S_GETPC_B64), Reg);
698 BuildMI(MBB, MI, DL,
get(AMDGPU::S_ADD_U32), RegLo)
702 BuildMI(MBB, MI, DL,
get(AMDGPU::S_ADDC_U32), RegHi)
710 case AMDGPU::SGPR_USE:
712 MI->eraseFromParent();
715 case AMDGPU::V_MOV_B64_PSEUDO: {
716 unsigned Dst = MI->getOperand(0).getReg();
717 unsigned DstLo = RI.getSubReg(Dst, AMDGPU::sub0);
718 unsigned DstHi = RI.getSubReg(Dst, AMDGPU::sub1);
725 BuildMI(MBB, MI, DL,
get(AMDGPU::V_MOV_B32_e32), DstLo)
726 .
addImm(Imm.getLoBits(32).getZExtValue())
728 BuildMI(MBB, MI, DL,
get(AMDGPU::V_MOV_B32_e32), DstHi)
729 .
addImm(Imm.getHiBits(32).getZExtValue())
732 assert(SrcOp.
isReg());
733 BuildMI(MBB, MI, DL,
get(AMDGPU::V_MOV_B32_e32), DstLo)
736 BuildMI(MBB, MI, DL,
get(AMDGPU::V_MOV_B32_e32), DstHi)
744 case AMDGPU::V_CNDMASK_B64_PSEUDO: {
745 unsigned Dst = MI->getOperand(0).getReg();
746 unsigned DstLo = RI.getSubReg(Dst, AMDGPU::sub0);
747 unsigned DstHi = RI.getSubReg(Dst, AMDGPU::sub1);
748 unsigned Src0 = MI->getOperand(1).getReg();
749 unsigned Src1 = MI->getOperand(2).getReg();
752 BuildMI(MBB, MI, DL,
get(AMDGPU::V_CNDMASK_B32_e64), DstLo)
753 .
addReg(RI.getSubReg(Src0, AMDGPU::sub0))
754 .addReg(RI.getSubReg(Src1, AMDGPU::sub0))
755 .addOperand(SrcCond);
756 BuildMI(MBB, MI, DL,
get(AMDGPU::V_CNDMASK_B32_e64), DstHi)
757 .
addReg(RI.getSubReg(Src0, AMDGPU::sub1))
758 .addReg(RI.getSubReg(Src1, AMDGPU::sub1))
759 .addOperand(SrcCond);
774 if (CommutedOpcode == -1)
778 AMDGPU::OpName::src0);
779 assert(Src0Idx != -1 &&
"Should always have src0 operand");
786 AMDGPU::OpName::src1);
801 if (NewMI || !Src1.
isImm() ||
812 int Src0ModsVal = Src0Mods->getImm();
813 if (!Src1Mods && Src0ModsVal != 0)
818 int Src1ModsVal = Src1Mods->
getImm();
819 assert((Src1ModsVal == 0) &&
"Not expecting modifiers with immediates");
821 Src1Mods->
setImm(Src0ModsVal);
822 Src0Mods->setImm(Src1ModsVal);
839 MI->
setDesc(
get(CommutedOpcode));
849 unsigned &SrcOpIdx2)
const {
885 unsigned SrcReg)
const {
892 default:
return false;
893 case AMDGPU::S_MOV_B32:
894 case AMDGPU::S_MOV_B64:
895 case AMDGPU::V_MOV_B32_e32:
896 case AMDGPU::V_MOV_B32_e64:
903 return RC != &AMDGPU::EXECRegRegClass;
909 AMDGPU::OpName::src0_modifiers);
911 AMDGPU::OpName::src1_modifiers);
913 AMDGPU::OpName::src2_modifiers);
926 if (Opc == AMDGPU::V_MAD_F32 || Opc == AMDGPU::V_MAC_F32_e64) {
942 if (!Src1->
isReg() ||
946 if (!Src2->
isReg() ||
966 AMDGPU::OpName::omod));
968 AMDGPU::OpName::clamp));
970 unsigned Src1Reg = Src1->
getReg();
972 unsigned Src2Reg = Src2->
getReg();
982 if (Opc == AMDGPU::V_MAC_F32_e64) {
988 AMDGPU::OpName::src2));
993 UseMI->
setDesc(
get(AMDGPU::V_MADMK_F32));
1006 if (!Src0->
isImm() &&
1010 if (!Src1->
isReg() ||
1021 AMDGPU::OpName::omod));
1023 AMDGPU::OpName::clamp));
1025 if (Opc == AMDGPU::V_MAC_F32_e64) {
1035 UseMI->
setDesc(
get(AMDGPU::V_MADAK_F32));
1052 default:
return AMDGPUInstrInfo::isTriviallyReMaterializable(MI, AA);
1053 case AMDGPU::S_MOV_B32:
1054 case AMDGPU::S_MOV_B64:
1055 case AMDGPU::V_MOV_B32_e32:
1061 int WidthB,
int OffsetB) {
1062 int LowOffset = OffsetA < OffsetB ? OffsetA : OffsetB;
1063 int HighOffset = OffsetA < OffsetB ? OffsetB : OffsetA;
1064 int LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
1065 return LowOffset + LowWidth <= HighOffset;
1068 bool SIInstrInfo::checkInstOffsetsDoNotOverlap(
MachineInstr *MIa,
1070 unsigned BaseReg0, Offset0;
1071 unsigned BaseReg1, Offset1;
1076 "read2 / write2 not expected here yet");
1079 if (BaseReg0 == BaseReg1 &&
1095 "MIa must load from or modify a memory location");
1097 "MIb must load from or modify a memory location");
1113 return checkInstOffsetsDoNotOverlap(MIa, MIb);
1120 return checkInstOffsetsDoNotOverlap(MIa, MIb);
1127 return checkInstOffsetsDoNotOverlap(MIa, MIb);
1134 return checkInstOffsetsDoNotOverlap(MIa, MIb);
1146 switch (MI->getOpcode()) {
1147 default:
return nullptr;
1148 case AMDGPU::V_MAC_F32_e64:
break;
1149 case AMDGPU::V_MAC_F32_e32: {
1162 return BuildMI(*MBB, MI, MI->getDebugLoc(),
get(AMDGPU::V_MAD_F32))
1176 if (SVal >= -16 && SVal <= 64)
1214 unsigned OpSize)
const {
1222 unsigned BitSize = 8 * OpSize;
1230 unsigned OpSize)
const {
1261 unsigned OpSize = RI.getRegClass(OpInfo.
RegClass)->getSize();
1281 AMDGPU::OpName::src0_modifiers) != -1;
1285 unsigned OpName)
const {
1287 return Mods && Mods->
getImm();
1292 unsigned OpSize)
const {
1312 if (MO.
getReg() == AMDGPU::M0 || MO.
getReg() == AMDGPU::VCC ||
1314 (AMDGPU::SGPR_32RegClass.contains(MO.
getReg()) ||
1334 ErrInfo =
"Instruction has wrong number of operands.";
1341 ErrInfo =
"FPImm Machine Operands are not supported. ISel should bitcast "
1342 "all fp values to integers.";
1351 ErrInfo =
"Illegal immediate value for operand.";
1359 RI.getRegClass(RegClass)->getSize())) {
1360 ErrInfo =
"Illegal immediate value for operand.";
1369 ErrInfo =
"Expected immediate, but got non-immediate";
1380 if (RegClass != -1) {
1387 ErrInfo =
"Operand has incorrect register class.";
1399 const int OpIndices[] = { Src0Idx, Src1Idx, Src2Idx };
1401 unsigned ConstantBusCount = 0;
1402 unsigned SGPRUsed = AMDGPU::NoRegister;
1403 for (
int OpIdx : OpIndices) {
1409 if (MO.
getReg() != SGPRUsed)
1417 if (ConstantBusCount > 1) {
1418 ErrInfo =
"VOP* instruction uses the constant bus more than once";
1424 if (Desc.
getOpcode() == AMDGPU::V_DIV_SCALE_F32 ||
1425 Desc.
getOpcode() == AMDGPU::V_DIV_SCALE_F64) {
1432 ErrInfo =
"v_div_scale_{f32|f64} require src0 = src1 or src2";
1443 default:
return AMDGPU::INSTRUCTION_LIST_END;
1448 case AMDGPU::S_MOV_B32:
1451 case AMDGPU::S_ADD_I32:
1452 case AMDGPU::S_ADD_U32:
return AMDGPU::V_ADD_I32_e32;
1453 case AMDGPU::S_ADDC_U32:
return AMDGPU::V_ADDC_U32_e32;
1454 case AMDGPU::S_SUB_I32:
1455 case AMDGPU::S_SUB_U32:
return AMDGPU::V_SUB_I32_e32;
1456 case AMDGPU::S_SUBB_U32:
return AMDGPU::V_SUBB_U32_e32;
1457 case AMDGPU::S_MUL_I32:
return AMDGPU::V_MUL_LO_I32;
1458 case AMDGPU::S_AND_B32:
return AMDGPU::V_AND_B32_e32;
1459 case AMDGPU::S_OR_B32:
return AMDGPU::V_OR_B32_e32;
1460 case AMDGPU::S_XOR_B32:
return AMDGPU::V_XOR_B32_e32;
1461 case AMDGPU::S_MIN_I32:
return AMDGPU::V_MIN_I32_e32;
1462 case AMDGPU::S_MIN_U32:
return AMDGPU::V_MIN_U32_e32;
1463 case AMDGPU::S_MAX_I32:
return AMDGPU::V_MAX_I32_e32;
1464 case AMDGPU::S_MAX_U32:
return AMDGPU::V_MAX_U32_e32;
1465 case AMDGPU::S_ASHR_I32:
return AMDGPU::V_ASHR_I32_e32;
1466 case AMDGPU::S_ASHR_I64:
return AMDGPU::V_ASHR_I64;
1467 case AMDGPU::S_LSHL_B32:
return AMDGPU::V_LSHL_B32_e32;
1468 case AMDGPU::S_LSHL_B64:
return AMDGPU::V_LSHL_B64;
1469 case AMDGPU::S_LSHR_B32:
return AMDGPU::V_LSHR_B32_e32;
1470 case AMDGPU::S_LSHR_B64:
return AMDGPU::V_LSHR_B64;
1471 case AMDGPU::S_SEXT_I32_I8:
return AMDGPU::V_BFE_I32;
1472 case AMDGPU::S_SEXT_I32_I16:
return AMDGPU::V_BFE_I32;
1473 case AMDGPU::S_BFE_U32:
return AMDGPU::V_BFE_U32;
1474 case AMDGPU::S_BFE_I32:
return AMDGPU::V_BFE_I32;
1475 case AMDGPU::S_BFM_B32:
return AMDGPU::V_BFM_B32_e64;
1476 case AMDGPU::S_BREV_B32:
return AMDGPU::V_BFREV_B32_e32;
1477 case AMDGPU::S_NOT_B32:
return AMDGPU::V_NOT_B32_e32;
1478 case AMDGPU::S_NOT_B64:
return AMDGPU::V_NOT_B32_e32;
1479 case AMDGPU::S_CMP_EQ_I32:
return AMDGPU::V_CMP_EQ_I32_e32;
1480 case AMDGPU::S_CMP_LG_I32:
return AMDGPU::V_CMP_NE_I32_e32;
1481 case AMDGPU::S_CMP_GT_I32:
return AMDGPU::V_CMP_GT_I32_e32;
1482 case AMDGPU::S_CMP_GE_I32:
return AMDGPU::V_CMP_GE_I32_e32;
1483 case AMDGPU::S_CMP_LT_I32:
return AMDGPU::V_CMP_LT_I32_e32;
1484 case AMDGPU::S_CMP_LE_I32:
return AMDGPU::V_CMP_LE_I32_e32;
1485 case AMDGPU::S_LOAD_DWORD_IMM:
1486 case AMDGPU::S_LOAD_DWORD_SGPR:
return AMDGPU::BUFFER_LOAD_DWORD_ADDR64;
1487 case AMDGPU::S_LOAD_DWORDX2_IMM:
1488 case AMDGPU::S_LOAD_DWORDX2_SGPR:
return AMDGPU::BUFFER_LOAD_DWORDX2_ADDR64;
1489 case AMDGPU::S_LOAD_DWORDX4_IMM:
1490 case AMDGPU::S_LOAD_DWORDX4_SGPR:
return AMDGPU::BUFFER_LOAD_DWORDX4_ADDR64;
1491 case AMDGPU::S_BCNT1_I32_B32:
return AMDGPU::V_BCNT_U32_B32_e64;
1492 case AMDGPU::S_FF1_I32_B32:
return AMDGPU::V_FFBL_B32_e32;
1493 case AMDGPU::S_FLBIT_I32_B32:
return AMDGPU::V_FFBH_U32_e32;
1494 case AMDGPU::S_FLBIT_I32:
return AMDGPU::V_FFBH_I32_e64;
1499 return getVALUOp(MI) != AMDGPU::INSTRUCTION_LIST_END;
1503 unsigned OpNo)
const {
1516 return RI.getRegClass(RCID);
1536 unsigned RCID =
get(MI->
getOpcode()).OpInfo[OpIdx].RegClass;
1538 unsigned Opcode = AMDGPU::V_MOV_B32_e32;
1542 Opcode = AMDGPU::S_MOV_B32;
1546 if (RI.getCommonSubClass(&AMDGPU::VReg_64RegClass, VRC))
1547 VRC = &AMDGPU::VReg_64RegClass;
1549 VRC = &AMDGPU::VGPR_32RegClass;
1565 assert(SuperReg.
isReg());
1581 .
addReg(NewSuperReg, 0, SubIdx);
1595 if (SubIdx == AMDGPU::sub0)
1597 if (SubIdx == AMDGPU::sub1)
1603 unsigned SubReg = buildExtractSubReg(MII, MRI, Op, SuperRC,
1640 assert(Inst->getNumExplicitOperands() == 3);
1642 Inst->RemoveOperand(1);
1643 Inst->addOperand(Op1);
1687 return RI.getCommonSubClass(RC, RI.getRegClass(OpInfo.
RegClass)) == RC;
1706 AMDGPU::OpName::src0);
1708 AMDGPU::OpName::src1);
1710 AMDGPU::OpName::src2);
1739 int VOP3Idx[3] = { Src0Idx, Src1Idx, Src2Idx };
1742 unsigned SGPRReg = findUsedSGPR(MI, VOP3Idx);
1744 for (
unsigned i = 0; i < 3; ++i) {
1745 int Idx = VOP3Idx[i];
1754 assert(MO.
getReg() != AMDGPU::SCC &&
"SCC operand to VOP3 instruction");
1756 if (SGPRReg == AMDGPU::NoRegister || SGPRReg == MO.
getReg()) {
1834 if (DstRC != Src0RC) {
1849 if (SRsrcIdx != -1) {
1852 unsigned SRsrcRC =
get(MI->
getOpcode()).OpInfo[SRsrcIdx].RegClass;
1854 RI.getRegClass(SRsrcRC))) {
1864 unsigned SRsrcPtrLo = buildExtractSubReg(MI, MRI, *SRsrc,
1865 &AMDGPU::VReg_128RegClass, AMDGPU::sub0, &AMDGPU::VGPR_32RegClass);
1868 unsigned SRsrcPtrHi = buildExtractSubReg(MI, MRI, *SRsrc,
1869 &AMDGPU::VReg_128RegClass, AMDGPU::sub1, &AMDGPU::VGPR_32RegClass);
1886 .
addImm(RsrcDataFormat & 0xFFFFFFFF);
1891 .
addImm(RsrcDataFormat >> 32);
1897 .
addImm(AMDGPU::sub0_sub1)
1905 unsigned NewVAddrLo;
1906 unsigned NewVAddrHi;
1940 .
addReg(AMDGPU::NoRegister)
1953 NewVAddrLo = SRsrcPtrLo;
1954 NewVAddrHi = SRsrcPtrHi;
1977 unsigned HalfImmOp,
unsigned HalfSGPROp,
1985 unsigned HalfSize = HalfRC->
getSize();
1993 bool IsKill = SBase->
isKill();
1998 unsigned OffScale = isVI ? 1 : 4;
2000 unsigned LoOffset = OffOp->
getImm() * OffScale;
2001 unsigned HiOffset = LoOffset + HalfSize;
2002 Lo =
BuildMI(*MBB, MI, DL,
get(HalfImmOp), RegLo)
2006 .addImm(LoOffset / OffScale);
2008 if (!isUInt<20>(HiOffset) || (!isVI && !
isUInt<8>(HiOffset / OffScale))) {
2009 unsigned OffsetSGPR =
2011 BuildMI(*MBB, MI, DL,
get(AMDGPU::S_MOV_B32), OffsetSGPR)
2013 Hi =
BuildMI(*MBB, MI, DL,
get(HalfSGPROp), RegHi)
2016 .addReg(OffsetSGPR);
2018 Hi =
BuildMI(*MBB, MI, DL,
get(HalfImmOp), RegHi)
2021 .addImm(HiOffset / OffScale);
2026 Lo =
BuildMI(*MBB, MI, DL,
get(HalfSGPROp), RegLo)
2030 BuildMI(*MBB, MI, DL,
get(AMDGPU::S_ADD_I32), OffsetSGPR)
2033 Hi =
BuildMI(*MBB, MI, DL,
get(HalfSGPROp))
2036 .addReg(OffsetSGPR);
2039 unsigned SubLo, SubHi;
2042 SubLo = AMDGPU::sub0;
2043 SubHi = AMDGPU::sub1;
2046 SubLo = AMDGPU::sub0_sub1;
2047 SubHi = AMDGPU::sub2_sub3;
2050 SubLo = AMDGPU::sub0_sub1_sub2_sub3;
2051 SubHi = AMDGPU::sub4_sub5_sub6_sub7;
2054 SubLo = AMDGPU::sub0_sub1_sub2_sub3_sub4_sub5_sub6_sub7;
2055 SubHi = AMDGPU::sub8_sub9_sub10_sub11_sub12_sub13_sub14_sub15;
2072 case AMDGPU::S_LOAD_DWORD_IMM:
2073 case AMDGPU::S_LOAD_DWORD_SGPR:
2074 case AMDGPU::S_LOAD_DWORDX2_IMM:
2075 case AMDGPU::S_LOAD_DWORDX2_SGPR:
2076 case AMDGPU::S_LOAD_DWORDX4_IMM:
2077 case AMDGPU::S_LOAD_DWORDX4_SGPR: {
2095 if (isUInt<12>(ImmOffset)) {
2108 unsigned DWord0 = RegOffset;
2117 .
addImm(RsrcDataFormat & 0xFFFFFFFF);
2119 .
addImm(RsrcDataFormat >> 32);
2142 RI.getRegClass(
get(NewOpcode).OpInfo[0].RegClass);
2149 case AMDGPU::S_LOAD_DWORDX8_IMM:
2150 case AMDGPU::S_LOAD_DWORDX8_SGPR: {
2152 splitSMRD(MI, &AMDGPU::SReg_128RegClass, AMDGPU::S_LOAD_DWORDX4_IMM,
2153 AMDGPU::S_LOAD_DWORDX4_SGPR, Lo, Hi);
2160 case AMDGPU::S_LOAD_DWORDX16_IMM:
2161 case AMDGPU::S_LOAD_DWORDX16_SGPR: {
2163 splitSMRD(MI, &AMDGPU::SReg_256RegClass, AMDGPU::S_LOAD_DWORDX8_IMM,
2164 AMDGPU::S_LOAD_DWORDX8_SGPR, Lo, Hi);
2177 while (!Worklist.
empty()) {
2192 case AMDGPU::S_MOV_B64: {
2206 unsigned Dst = split64BitImm(Worklist,
2216 case AMDGPU::S_AND_B64:
2217 splitScalar64BitBinaryOp(Worklist, Inst, AMDGPU::S_AND_B32);
2221 case AMDGPU::S_OR_B64:
2222 splitScalar64BitBinaryOp(Worklist, Inst, AMDGPU::S_OR_B32);
2226 case AMDGPU::S_XOR_B64:
2227 splitScalar64BitBinaryOp(Worklist, Inst, AMDGPU::S_XOR_B32);
2231 case AMDGPU::S_NOT_B64:
2232 splitScalar64BitUnaryOp(Worklist, Inst, AMDGPU::S_NOT_B32);
2236 case AMDGPU::S_BCNT1_I32_B64:
2237 splitScalar64BitBCNT(Worklist, Inst);
2241 case AMDGPU::S_BFE_I64: {
2242 splitScalar64BitBFE(Worklist, Inst);
2247 case AMDGPU::S_LSHL_B32:
2249 NewOpcode = AMDGPU::V_LSHLREV_B32_e64;
2253 case AMDGPU::S_ASHR_I32:
2255 NewOpcode = AMDGPU::V_ASHRREV_I32_e64;
2259 case AMDGPU::S_LSHR_B32:
2261 NewOpcode = AMDGPU::V_LSHRREV_B32_e64;
2265 case AMDGPU::S_LSHL_B64:
2267 NewOpcode = AMDGPU::V_LSHLREV_B64;
2271 case AMDGPU::S_ASHR_I64:
2273 NewOpcode = AMDGPU::V_ASHRREV_I64;
2277 case AMDGPU::S_LSHR_B64:
2279 NewOpcode = AMDGPU::V_LSHRREV_B64;
2284 case AMDGPU::S_BFE_U64:
2285 case AMDGPU::S_BFM_B64:
2289 if (NewOpcode == AMDGPU::INSTRUCTION_LIST_END) {
2309 if (Opcode == AMDGPU::S_SEXT_I32_I8 || Opcode == AMDGPU::S_SEXT_I32_I16) {
2312 unsigned Size = (Opcode == AMDGPU::S_SEXT_I32_I8) ? 8 : 16;
2316 }
else if (Opcode == AMDGPU::S_BCNT1_I32_B32) {
2322 addDescImplicitUseDef(NewDesc, Inst);
2324 if (Opcode == AMDGPU::S_BFE_I32 || Opcode == AMDGPU::S_BFE_U32) {
2328 assert(OffsetWidthOp.
isImm() &&
2329 "Scalar BFE is only implemented for constant width and offset");
2330 uint32_t Imm = OffsetWidthOp.
getImm();
2332 uint32_t Offset = Imm & 0x3f;
2333 uint32_t BitWidth = (Imm & 0x7f0000) >> 16;
2384 unsigned Channel)
const {
2385 assert(Channel == 0);
2390 return &AMDGPU::VGPR_32RegClass;
2393 void SIInstrInfo::splitScalar64BitUnaryOp(
2396 unsigned Opcode)
const {
2409 &AMDGPU::SGPR_32RegClass;
2413 MachineOperand SrcReg0Sub0 = buildExtractSubRegOrImm(MII, MRI, Src0, Src0RC,
2414 AMDGPU::sub0, Src0SubRC);
2423 MachineOperand SrcReg0Sub1 = buildExtractSubRegOrImm(MII, MRI, Src0, Src0RC,
2424 AMDGPU::sub1, Src0SubRC);
2445 void SIInstrInfo::splitScalar64BitBinaryOp(
2448 unsigned Opcode)
const {
2462 &AMDGPU::SGPR_32RegClass;
2467 &AMDGPU::SGPR_32RegClass;
2471 MachineOperand SrcReg0Sub0 = buildExtractSubRegOrImm(MII, MRI, Src0, Src0RC,
2472 AMDGPU::sub0, Src0SubRC);
2473 MachineOperand SrcReg1Sub0 = buildExtractSubRegOrImm(MII, MRI, Src1, Src1RC,
2474 AMDGPU::sub0, Src1SubRC);
2484 MachineOperand SrcReg0Sub1 = buildExtractSubRegOrImm(MII, MRI, Src0, Src0RC,
2485 AMDGPU::sub1, Src0SubRC);
2486 MachineOperand SrcReg1Sub1 = buildExtractSubRegOrImm(MII, MRI, Src1, Src1RC,
2487 AMDGPU::sub1, Src1SubRC);
2520 const MCInstrDesc &InstDesc =
get(AMDGPU::V_BCNT_U32_B32_e64);
2523 &AMDGPU::SGPR_32RegClass;
2530 MachineOperand SrcRegSub0 = buildExtractSubRegOrImm(MII, MRI, Src, SrcRC,
2531 AMDGPU::sub0, SrcSubRC);
2532 MachineOperand SrcRegSub1 = buildExtractSubRegOrImm(MII, MRI, Src, SrcRC,
2533 AMDGPU::sub1, SrcSubRC);
2558 uint32_t Offset = Imm & 0x3f;
2559 uint32_t BitWidth = (Imm & 0x7f0000) >> 16;
2564 assert(Inst->
getOpcode() == AMDGPU::S_BFE_I64 &&
2569 if (BitWidth < 32) {
2574 BuildMI(MBB, MII, DL,
get(AMDGPU::V_BFE_I32), MidRegLo)
2579 BuildMI(MBB, MII, DL,
get(AMDGPU::V_ASHRREV_I32_e32), MidRegHi)
2597 BuildMI(MBB, MII, DL,
get(AMDGPU::V_ASHRREV_I32_e64), TmpReg)
2603 .addImm(AMDGPU::sub0)
2610 void SIInstrInfo::addDescImplicitUseDef(
const MCInstrDesc &NewDesc,
2628 unsigned SIInstrInfo::findUsedSGPR(
const MachineInstr *MI,
2629 int OpIndices[3])
const {
2633 unsigned SGPRReg = AMDGPU::NoRegister;
2647 if (MO.getReg() == AMDGPU::VCC)
2650 if (MO.getReg() == AMDGPU::FLAT_SCR)
2651 return AMDGPU::FLAT_SCR;
2654 unsigned UsedSGPRs[3] = { AMDGPU::NoRegister };
2657 for (
unsigned i = 0; i < 3; ++i) {
2658 int Idx = OpIndices[i];
2667 UsedSGPRs[i] = MO.
getReg();
2670 if (SGPRReg != AMDGPU::NoRegister)
2683 if (UsedSGPRs[0] != AMDGPU::NoRegister) {
2684 if (UsedSGPRs[0] == UsedSGPRs[1] || UsedSGPRs[0] == UsedSGPRs[2])
2685 SGPRReg = UsedSGPRs[0];
2688 if (SGPRReg == AMDGPU::NoRegister && UsedSGPRs[1] != AMDGPU::NoRegister) {
2689 if (UsedSGPRs[1] == UsedSGPRs[2])
2690 SGPRReg = UsedSGPRs[1];
2700 unsigned Address,
unsigned OffsetReg)
const {
2702 unsigned IndirectBaseReg = AMDGPU::VGPR_32RegClass.getRegister(
2705 return BuildMI(*MBB, I, DL,
get(AMDGPU::SI_INDIRECT_DST_V1))
2708 .addReg(IndirectBaseReg)
2718 unsigned Address,
unsigned OffsetReg)
const {
2720 unsigned IndirectBaseReg = AMDGPU::VGPR_32RegClass.getRegister(
2723 return BuildMI(*MBB, I, DL,
get(AMDGPU::SI_INDIRECT_SRC))
2725 .addOperand(I->getOperand(1))
2726 .addReg(IndirectBaseReg)
2741 for (
int Index = Begin; Index <= End; ++Index)
2742 Reserved.
set(AMDGPU::VGPR_32RegClass.getRegister(Index));
2744 for (
int Index = std::max(0, Begin - 1); Index <= End; ++Index)
2745 Reserved.
set(AMDGPU::VReg_64RegClass.getRegister(Index));
2747 for (
int Index = std::max(0, Begin - 2); Index <= End; ++Index)
2748 Reserved.
set(AMDGPU::VReg_96RegClass.getRegister(Index));
2750 for (
int Index = std::max(0, Begin - 3); Index <= End; ++Index)
2751 Reserved.
set(AMDGPU::VReg_128RegClass.getRegister(Index));
2753 for (
int Index = std::max(0, Begin - 7); Index <= End; ++Index)
2754 Reserved.
set(AMDGPU::VReg_256RegClass.getRegister(Index));
2756 for (
int Index = std::max(0, Begin - 15); Index <= End; ++Index)
2757 Reserved.
set(AMDGPU::VReg_512RegClass.getRegister(Index));
2761 unsigned OperandName)
const {
2772 RsrcDataFormat |= (1ULL << 56);
2776 RsrcDataFormat |= (2ULL << 59);
2779 return RsrcDataFormat;
bool isUInt< 8 >(uint64_t x)
void push_back(const T &Elt)
const MachineFunction * getParent() const
getParent - Return the MachineFunction containing this basic block.
bool opCanUseInlineConstant(unsigned OpType) const
bool shouldClusterLoads(MachineInstr *FirstLdSt, MachineInstr *SecondLdSt, unsigned NumLoads) const final
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, DebugLoc DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const override
uint64_t getZExtValue() const
Get zero extended value.
MachineInstrBuilder buildIndirectWrite(MachineBasicBlock *MBB, MachineBasicBlock::iterator I, unsigned ValueReg, unsigned Address, unsigned OffsetReg) const override
Build instruction(s) for an indirect register write.
bool isCommutable() const
Return true if this may be a 2- or 3-address instruction (of the form "X = op Y, Z, ..."), which produces the same result if Y and Z are exchanged.
void ChangeToRegister(unsigned Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isDebug=false)
ChangeToRegister - Replace this operand with a new register operand of the specified value...
MachineBasicBlock * getMBB() const
bool isTargetIndex() const
isTargetIndex - Tests if this is a MO_TargetIndex operand.
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
static bool isStride64(unsigned Opc)
void splitSMRD(MachineInstr *MI, const TargetRegisterClass *HalfRC, unsigned HalfImmOp, unsigned HalfSGPROp, MachineInstr *&Lo, MachineInstr *&Hi) const
Split an SMRD instruction into two smaller loads of half the.
iterator getFirstTerminator()
getFirstTerminator - returns an iterator to the first terminator instruction of this basic block...
Describe properties that are true of each instruction in the target description file.
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
static bool isVirtualRegister(unsigned Reg)
isVirtualRegister - Return true if the specified register number is in the virtual register namespace...
void moveToVALU(MachineInstr &MI) const
Replace this instruction's opcode with the equivalent VALU opcode.
bool hasOrderedMemoryRef() const
Return true if this instruction may have an ordered or volatile memory reference, or if the informati...
void addLiveIn(unsigned Reg)
Adds the specified register as a live in.
bool hasVGPRs(const TargetRegisterClass *RC) const
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
unsigned getMovOpcode(const TargetRegisterClass *DstRC) const
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
MachineInstr * commuteInstruction(MachineInstr *MI, bool NewMI=false) const override
static SDValue findChainOperand(SDNode *Load)
bool hasModifiers(unsigned Opcode) const
Return true if this instruction has any modifiers.
bool isVariadic() const
Return true if this instruction can have a variable number of operands.
bool isFLAT(uint16_t Opcode) const
int pseudoToMCOpcode(int Opcode) const
Return a target-specific opcode if Opcode is a pseudo instruction.
COPY - Target-independent register copy.
unsigned getSize() const
getSize - Return the size of the register in bytes, which is also the size of a stack slot allocated ...
static use_iterator use_end()
bool verifyInstruction(const MachineInstr *MI, StringRef &ErrInfo) const override
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const AMDGPUSubtarget & ST
static MachineOperand CreateReg(unsigned Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false)
bool isVALU(uint16_t Opcode) const
T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val()
unsigned getShaderType() const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
bool isReg() const
isReg - Tests if this is a MO_Register operand.
unsigned calculateLDSSpillAddress(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, RegScavenger *RS, unsigned TmpReg, unsigned Offset, unsigned Size) const
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
bool getMemOpBaseRegImmOfs(MachineInstr *LdSt, unsigned &BaseReg, unsigned &Offset, const TargetRegisterInfo *TRI) const final
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
MachineOperand * getNamedOperand(MachineInstr &MI, unsigned OperandName) const
Returns the operand named Op.
const TargetRegisterClass * getRegClass(unsigned Reg) const
getRegClass - Return the register class of the specified virtual register.
void setHasSpilledVGPRs(bool Spill=true)
void setTIDReg(unsigned Reg)
bool isSGPRClass(const TargetRegisterClass *RC) const
Reg
All possible values of the reg field in the ModR/M byte.
int getCommuteOrig(uint16_t Opcode)
bool isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const override
const uint16_t * ImplicitUses
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
const MachineInstrBuilder & addImm(int64_t Val) const
addImm - Add a new immediate operand.
unsigned getNumOperands() const
Access to explicit operands of the instruction.
void emitError(unsigned LocCookie, const Twine &ErrorStr)
emitError - Emit an error message to the currently installed error handler with optional location inf...
unsigned calculateIndirectAddress(unsigned RegIndex, unsigned Channel) const override
Calculate the "Indirect Address" for the given RegIndex and Channel.
uint8_t OperandType
Information about the type of the operand.
void RemoveOperand(unsigned i)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
const MachineBasicBlock & front() const
int commuteOpcode(const MachineInstr &MI) const
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
bool canReadVGPR(const MachineInstr &MI, unsigned OpNo) const
virtual MachineInstr * commuteInstruction(MachineInstr *MI, bool NewMI=false) const
If a target has any instructions that are commutable but require converting to different instructions...
bool isImmOperandLegal(const MachineInstr *MI, unsigned OpNo, const MachineOperand &MO) const
SIInstrInfo(const AMDGPUSubtarget &st)
const uint64_t RSRC_DATA_FORMAT
void untieRegOperand(unsigned OpIdx)
Break any tie involving OpIdx.
void enterBasicBlock(MachineBasicBlock *mbb)
Start tracking liveness from the begin of the specific basic block.
bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const override
bool isVOP3(uint16_t Opcode) const
Operand with register or inline constant.
bool isSMRD(uint16_t Opcode) const
Generation getGeneration() const
bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const override
unsigned getMaximumWorkGroupSize(const MachineFunction &MF) const
unsigned getKillRegState(bool B)
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
uint32_t FloatToBits(float Float)
FloatToBits - This function takes a float and returns the bit equivalent 32-bit integer.
void ChangeToImmediate(int64_t ImmVal)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value...
const MachineBasicBlock * getParent() const
IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef.
bundle_iterator< MachineInstr, instr_iterator > iterator
static bool nodesHaveSameOperandValue(SDNode *N0, SDNode *N1, unsigned OpName)
Returns true if both nodes have the same value for the given operand Op, or if both nodes do not have...
unsigned getOpSize(uint16_t Opcode, unsigned OpNo) const
Return the size in bytes of the operand OpNo on the given.
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
bool usesConstantBus(const MachineRegisterInfo &MRI, const MachineOperand &MO, unsigned OpSize) const
Returns true if this operand uses the constant bus.
This is an important class for using LLVM in a threaded context.
DebugLoc findDebugLoc(instr_iterator MBBI)
findDebugLoc - find the next valid DebugLoc starting at MBBI, skipping any DBG_VALUE instructions...
int64_t getSExtValue() const
Get sign extended value.
const MachineOperand & getOperand(unsigned i) const
INSERT_SUBREG - This instruction takes three operands: a register that has subregisters, a register providing an insert value, and a subregister index.
bool isMov(unsigned Opcode) const override
static unsigned getNumOperandsNoGlue(SDNode *Node)
static void removeModOperands(MachineInstr &MI)
unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const override
const MachineInstrBuilder & addTargetIndex(unsigned Idx, int64_t Offset=0, unsigned char TargetFlags=0) const
bool isVariadic(QueryType Type=IgnoreBundle) const
Return true if this instruction can have a variable number of operands.
unsigned getBitWidth() const
Return the number of bits in the APInt.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
void setImm(int64_t immVal)
bool hasOneMemOperand() const
Return true if this instruction has exactly one MachineMemOperand.
bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore...
uint64_t getDefaultRsrcDataFormat() const
unsigned findUnusedRegister(const MachineRegisterInfo &MRI, const TargetRegisterClass *RC) const
Returns a register that is not used at any point in the function.
The AMDGPU TargetMachine interface definition for hw codgen targets.
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
BuildMI - Builder interface.
unsigned getSubReg() const
const TargetRegisterClass * getEquivalentVGPRClass(const TargetRegisterClass *SRC) const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
bool isLiteralConstant(const MachineOperand &MO, unsigned OpSize) const
void setIsKill(bool Val=true)
int getVOPe32(uint16_t Opcode)
REG_SEQUENCE - This variadic instruction is used to form a register that represents a consecutive seq...
unsigned getOpcode() const
Return the opcode number for this descriptor.
bool isVOP1(uint16_t Opcode) const
bool isInlineConstant(const APInt &Imm) const
void legalizeOpWithMove(MachineInstr *MI, unsigned OpIdx) const
Legalize the OpIndex operand of this instruction by inserting a MOV.
bool isOperandLegal(const MachineInstr *MI, unsigned OpIdx, const MachineOperand *MO=nullptr) const
Check if MO is a legal operand if it was the OpIdx Operand for MI.
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
unsigned LDSSize
Number of bytes in the LDS that are being used.
bool opCanUseLiteralConstant(unsigned OpType) const
bool hasVALU32BitEncoding(unsigned Opcode) const
Return true if this 64-bit VALU instruction has a 32-bit encoding.
static bool offsetsDoNotOverlap(int WidthA, int OffsetA, int WidthB, int OffsetB)
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
const TargetRegisterClass * getIndirectAddrRegClass() const override
MachineInstr * convertToThreeAddress(MachineFunction::iterator &MBB, MachineBasicBlock::iterator &MI, LiveVariables *LV) const override
MachineFrameInfo * getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Represents one node in the SelectionDAG.
bool isDS(uint16_t Opcode) const
uint64_t DoubleToBits(double Double)
DoubleToBits - This function takes a double and returns the bit equivalent 64-bit integer...
const MachineInstrBuilder & addFrameIndex(int Idx) const
bool isVOP2(uint16_t Opcode) const
bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2, int64_t &Offset1, int64_t &Offset2) const override
bool isFPImm() const
isFPImm - Tests if this is a MO_FPImmediate operand.
Class for arbitrary precision integers.
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
iterator_range< mop_iterator > implicit_operands()
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI, unsigned Reg, MachineRegisterInfo *MRI) const final
void replaceRegWith(unsigned FromReg, unsigned ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
KILL - This instruction is a noop that is used only to adjust the liveness of registers.
bool isSGPRClassID(unsigned RCID) const
const TargetRegisterClass * getSubRegClass(const TargetRegisterClass *RC, unsigned SubIdx) const
void reserveIndirectRegisters(BitVector &Reserved, const MachineFunction &MF) const
int getIndirectIndexEnd(const MachineFunction &MF) const
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
void moveSMRDToVALU(MachineInstr *MI, MachineRegisterInfo &MRI) const
const TargetRegisterClass * getPhysRegClass(unsigned Reg) const
Return the 'base' register class for this register.
static bool compareMachineOp(const MachineOperand &Op0, const MachineOperand &Op1)
Representation of each machine instruction.
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
Interface definition for SIInstrInfo.
bool isLiveIn(unsigned Reg) const
isLiveIn - Return true if the specified register is in the live in set.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
bool isMTBUF(uint16_t Opcode) const
int16_t RegClass
This specifies the register class enumeration of the operand if the operand is a register.
void legalizeOperands(MachineInstr *MI) const
Legalize all operands in this instruction.
use_iterator use_begin(unsigned RegNo) const
bool hasOneNonDBGUse(unsigned RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug instruction using the specified regis...
void setReg(unsigned Reg)
Change the register this operand corresponds to.
static MachineOperand CreateImm(int64_t Val)
void setSubReg(unsigned subReg)
int getCommuteRev(uint16_t Opcode)
int getAddr64Inst(uint16_t Opcode)
Operand with register or 32-bit immediate.
MachineInstr * removeFromParent()
Unlink 'this' from the containing basic block, and return it without deleting it. ...
EVT getValueType() const
Return the ValueType of the referenced return value.
static unsigned getVALUOp(const MachineInstr &MI)
bool isSALUOpSupportedOnVALU(const MachineInstr &MI) const
unsigned getReg() const
getReg - Returns the register number.
MachineInstrBuilder buildIndirectRead(MachineBasicBlock *MBB, MachineBasicBlock::iterator I, unsigned ValueReg, unsigned Address, unsigned OffsetReg) const override
Build instruction(s) for an indirect register read.
bool isCommutable(QueryType Type=IgnoreBundle) const
Return true if this may be a 2- or 3-address instruction (of the form "X = op Y, Z, ..."), which produces the same result if Y and Z are exchanged.
const uint16_t * ImplicitDefs
bool isTriviallyReMaterializable(const MachineInstr *MI, AliasAnalysis *AA=nullptr) const
bool hasModifiersSet(const MachineInstr &MI, unsigned OpName) const
bool areMemAccessesTriviallyDisjoint(MachineInstr *MIa, MachineInstr *MIb, AliasAnalysis *AA=nullptr) const override
int getIndirectIndexBegin(const MachineFunction &MF) const
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
const MCOperandInfo * OpInfo
const MachineInstrBuilder & addOperand(const MachineOperand &MO) const
bool isVOPC(uint16_t Opcode) const
BasicBlockListType::iterator iterator
int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIndex)
const TargetRegisterClass * getOpRegClass(const MachineInstr &MI, unsigned OpNo) const
Return the correct register class for OpNo.
StringRef - Represent a constant reference to a string, i.e.
bool isVGPRSpillingEnabled(const SIMachineFunctionInfo *MFI) const
MachineInstr * buildMovInstr(MachineBasicBlock *MBB, MachineBasicBlock::iterator I, unsigned DstReg, unsigned SrcReg) const override
Build a MOV instruction.
bool hasCalculatedTID() const
This holds information about one operand of a machine instruction, indicating the register class for ...
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
addReg - Add a new virtual register operand...
unsigned getTIDReg() const
reg_begin/reg_end - Provide iteration support to walk over all definitions and uses of a register wit...
void insertNOPs(MachineBasicBlock::iterator MI, int Count) const
bool isMUBUF(uint16_t Opcode) const
bool isReallyTriviallyReMaterializable(const MachineInstr *MI, AliasAnalysis *AA) const override
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode...
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
uint64_t getZExtValue() const
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
unsigned scavengeRegister(const TargetRegisterClass *RegClass, MachineBasicBlock::iterator I, int SPAdj)
Make a register of the specific register class available and do the appropriate bookkeeping.
bool contains(unsigned Reg) const
contains - Return true if the specified register is included in this register class.