25 #define GET_INSTRINFO_CTOR_DTOR
26 #include "R600GenDFAPacketizer.inc"
28 #define GET_INSTRINFO_CTOR_DTOR
29 #define GET_INSTRMAP_INFO
30 #define GET_INSTRINFO_NAMED_OPS
31 #include "R600GenInstrInfo.inc"
44 unsigned VectorComponents = 0;
45 if ((R600::R600_Reg128RegClass.
contains(DestReg) ||
46 R600::R600_Reg128VerticalRegClass.
contains(DestReg)) &&
47 (R600::R600_Reg128RegClass.
contains(SrcReg) ||
48 R600::R600_Reg128VerticalRegClass.
contains(SrcReg))) {
50 }
else if((R600::R600_Reg64RegClass.
contains(DestReg) ||
51 R600::R600_Reg64VerticalRegClass.
contains(DestReg)) &&
52 (R600::R600_Reg64RegClass.
contains(SrcReg) ||
53 R600::R600_Reg64VerticalRegClass.
contains(SrcReg))) {
57 if (VectorComponents > 0) {
58 for (
unsigned I = 0;
I < VectorComponents;
I++) {
61 RI.getSubReg(DestReg, SubRegIndex),
62 RI.getSubReg(SrcReg, SubRegIndex))
78 E =
MBBI->operands_end();
I !=
E; ++
I) {
79 if (
I->isReg() && !
I->getReg().isVirtual() &&
I->isUse() &&
91 case R600::MOV_IMM_F32:
92 case R600::MOV_IMM_I32:
103 default:
return false;
104 case R600::CUBE_r600_pseudo:
105 case R600::CUBE_r600_real:
106 case R600::CUBE_eg_pseudo:
107 case R600::CUBE_eg_real:
113 unsigned TargetFlags =
get(Opcode).TSFlags;
119 unsigned TargetFlags =
get(Opcode).TSFlags;
127 unsigned TargetFlags =
get(Opcode).TSFlags;
143 switch (
MI.getOpcode()) {
145 case R600::INTERP_PAIR_XY:
146 case R600::INTERP_PAIR_ZW:
147 case R600::INTERP_VEC_LOAD:
159 return (
get(Opcode).getSchedClass() == R600::Sched::TransALU);
167 return (
get(Opcode).getSchedClass() == R600::Sched::VecALU);
202 case R600::GROUP_BARRIER:
210 return MI.findRegisterUseOperandIdx(R600::AR_X,
false, &RI) != -1;
214 return MI.findRegisterDefOperandIdx(R600::AR_X,
false,
false, &RI) != -1;
222 E =
MI.operands_end();
224 if (!
I->isReg() || !
I->isUse() ||
I->getReg().isVirtual())
227 if (R600::R600_LDS_SRC_REGRegClass.
contains(
I->getReg()))
234 static const unsigned SrcSelTable[][2] = {
235 {R600::OpName::src0, R600::OpName::src0_sel},
236 {R600::OpName::src1, R600::OpName::src1_sel},
237 {R600::OpName::src2, R600::OpName::src2_sel},
238 {R600::OpName::src0_X, R600::OpName::src0_sel_X},
239 {R600::OpName::src0_Y, R600::OpName::src0_sel_Y},
240 {R600::OpName::src0_Z, R600::OpName::src0_sel_Z},
241 {R600::OpName::src0_W, R600::OpName::src0_sel_W},
242 {R600::OpName::src1_X, R600::OpName::src1_sel_X},
243 {R600::OpName::src1_Y, R600::OpName::src1_sel_Y},
244 {R600::OpName::src1_Z, R600::OpName::src1_sel_Z},
245 {R600::OpName::src1_W, R600::OpName::src1_sel_W}
248 for (
const auto &Row : SrcSelTable) {
260 if (
MI.getOpcode() == R600::DOT_4) {
261 static const unsigned OpTable[8][2] = {
262 {R600::OpName::src0_X, R600::OpName::src0_sel_X},
263 {R600::OpName::src0_Y, R600::OpName::src0_sel_Y},
264 {R600::OpName::src0_Z, R600::OpName::src0_sel_Z},
265 {R600::OpName::src0_W, R600::OpName::src0_sel_W},
266 {R600::OpName::src1_X, R600::OpName::src1_sel_X},
267 {R600::OpName::src1_Y, R600::OpName::src1_sel_Y},
268 {R600::OpName::src1_Z, R600::OpName::src1_sel_Z},
269 {R600::OpName::src1_W, R600::OpName::src1_sel_W},
272 for (
const auto &
Op : OpTable) {
275 if (
Reg == R600::ALU_CONST) {
278 Result.push_back(std::make_pair(&MO, Sel.
getImm()));
285 static const unsigned OpTable[3][2] = {
286 {R600::OpName::src0, R600::OpName::src0_sel},
287 {R600::OpName::src1, R600::OpName::src1_sel},
288 {R600::OpName::src2, R600::OpName::src2_sel},
291 for (
const auto &
Op : OpTable) {
297 if (
Reg == R600::ALU_CONST) {
299 Result.push_back(std::make_pair(&MO, Sel.
getImm()));
302 if (
Reg == R600::ALU_LITERAL_X) {
305 if (Operand.
isImm()) {
306 Result.push_back(std::make_pair(&MO, Operand.
getImm()));
311 Result.push_back(std::make_pair(&MO, 0));
316 std::vector<std::pair<int, unsigned>>
319 unsigned &ConstCount)
const {
321 const std::pair<int, unsigned> DummyPair(-1, 0);
322 std::vector<std::pair<int, unsigned>> Result;
327 int Index = RI.getEncodingValue(
Reg) & 0xff;
328 if (
Reg == R600::OQAP) {
329 Result.push_back(std::make_pair(Index, 0U));
333 Result.push_back(std::make_pair(255, 0U));
338 Result.push_back(DummyPair);
342 Result.push_back(std::make_pair(Index, Chan));
345 Result.push_back(DummyPair);
349 static std::vector<std::pair<int, unsigned>>
350 Swizzle(std::vector<std::pair<int, unsigned>> Src,
352 if (Src[0] == Src[1])
379 assert(
Op < 3 &&
"Out of range swizzle index");
382 unsigned Cycles[3] = { 2, 1, 0};
386 unsigned Cycles[3] = { 1, 2, 2};
390 unsigned Cycles[3] = { 2, 1, 2};
394 unsigned Cycles[3] = { 2, 2, 1};
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,
412 for (
unsigned i = 0,
e = IGSrcs.size();
i <
e;
i++) {
413 const std::vector<std::pair<int, unsigned>> &Srcs =
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)
419 if (Src.first ==
GET_REG_INDEX(RI.getEncodingValue(R600::OQAP))) {
430 Vector[Src.second][
j] = Src.first;
431 if (
Vector[Src.second][
j] != Src.first)
436 for (
unsigned i = 0,
e = TransSrcs.size();
i <
e; ++
i) {
437 const std::pair<int, unsigned> &Src = TransSrcs[
i];
441 if (Src.first == 255)
446 return IGSrcs.size() - 1;
448 return IGSrcs.size();
456 std::vector<R600InstrInfo::BankSwizzle> &SwzCandidate,
458 assert(Idx < SwzCandidate.size());
462 for (
unsigned i = ResetIdx + 1,
e = SwzCandidate.size();
i <
e;
i++) {
467 int NextSwizzle = SwzCandidate[ResetIdx] + 1;
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,
479 unsigned ValidUpTo = 0;
481 ValidUpTo =
isLegalUpTo(IGSrcs, SwzCandidate, TransSrcs, TransSwz);
482 if (ValidUpTo == IGSrcs.size())
492 const std::vector<std::pair<int, unsigned>> &TransOps,
493 unsigned ConstCount) {
497 for (
unsigned i = 0,
e = TransOps.size();
i <
e; ++
i) {
498 const std::pair<int, unsigned> &Src = TransOps[
i];
502 if (ConstCount > 0 &&
Cycle == 0)
504 if (ConstCount > 1 &&
Cycle == 1)
513 std::vector<BankSwizzle> &ValidSwizzle,
518 std::vector<std::vector<std::pair<int, unsigned>>> IGSrcs;
519 ValidSwizzle.clear();
523 IGSrcs.push_back(ExtractSrcs(*
MI, PV, ConstCount));
525 ValidSwizzle.push_back(
528 std::vector<std::pair<int, unsigned>> TransOps;
534 ValidSwizzle.pop_back();
548 ValidSwizzle.push_back(TransBS);
559 assert (Consts.size() <= 12 &&
"Too many operands in instructions group");
560 unsigned Pair1 = 0, Pair2 = 0;
561 for (
unsigned Const : Consts) {
562 unsigned ReadConstHalf = Const & 2;
563 unsigned ReadConstIndex = Const & (~3);
564 unsigned ReadHalfConst = ReadConstIndex | ReadConstHalf;
566 Pair1 = ReadHalfConst;
569 if (Pair1 == ReadHalfConst)
572 Pair2 = ReadHalfConst;
575 if (Pair2 != ReadHalfConst)
584 std::vector<unsigned> Consts;
591 if (Src.first->getReg() == R600::ALU_LITERAL_X)
592 Literals.
insert(Src.second);
593 if (Literals.
size() > 4)
595 if (Src.first->getReg() == R600::ALU_CONST)
596 Consts.push_back(Src.second);
597 if (R600::R600_KC0RegClass.
contains(Src.first->getReg()) ||
598 R600::R600_KC1RegClass.contains(Src.first->getReg())) {
599 unsigned Index = RI.getEncodingValue(Src.first->getReg()) & 0xff;
601 Consts.push_back((Index << 2) | Chan);
611 return static_cast<const R600Subtarget &
>(STI).createDFAPacketizer(II);
639 return Opcode == R600::JUMP || Opcode == R600::JUMP_COND;
643 return Opcode == R600::BRANCH || Opcode == R600::BRANCH_COND_i32 ||
644 Opcode == R600::BRANCH_COND_f32;
651 bool AllowModify)
const {
668 while (
I !=
MBB.
begin() && std::prev(
I)->getOpcode() == R600::JUMP) {
671 I->removeFromParent();
679 if (LastOpc == R600::JUMP) {
682 }
else if (LastOpc == R600::JUMP_COND) {
688 Cond.push_back(predSet->getOperand(1));
689 Cond.push_back(predSet->getOperand(2));
698 unsigned SecondLastOpc = SecondLastInst.
getOpcode();
701 if (SecondLastOpc == R600::JUMP_COND && LastOpc == R600::JUMP) {
708 Cond.push_back(predSet->getOperand(1));
709 Cond.push_back(predSet->getOperand(2));
722 if (It->getOpcode() == R600::CF_ALU ||
723 It->getOpcode() == R600::CF_ALU_PUSH_BEFORE)
734 int *BytesAdded)
const {
735 assert(TBB &&
"insertBranch must not be told to insert a fallthrough");
736 assert(!BytesAdded &&
"code size not handled");
744 assert(PredSet &&
"No previous predicate !");
754 assert (CfAlu->getOpcode() == R600::CF_ALU);
755 CfAlu->setDesc(
get(R600::CF_ALU_PUSH_BEFORE));
760 assert(PredSet &&
"No previous predicate !");
770 assert (CfAlu->getOpcode() == R600::CF_ALU);
771 CfAlu->setDesc(
get(R600::CF_ALU_PUSH_BEFORE));
777 int *BytesRemoved)
const {
778 assert(!BytesRemoved &&
"code size not handled");
789 switch (
I->getOpcode()) {
792 case R600::JUMP_COND: {
795 I->eraseFromParent();
799 assert (CfAlu->getOpcode() == R600::CF_ALU_PUSH_BEFORE);
800 CfAlu->setDesc(
get(R600::CF_ALU));
804 I->eraseFromParent();
813 switch (
I->getOpcode()) {
817 case R600::JUMP_COND: {
820 I->eraseFromParent();
824 assert (CfAlu->getOpcode() == R600::CF_ALU_PUSH_BEFORE);
825 CfAlu->setDesc(
get(R600::CF_ALU));
829 I->eraseFromParent();
836 int idx =
MI.findFirstPredOperandIdx();
842 default:
return false;
843 case R600::PRED_SEL_ONE:
844 case R600::PRED_SEL_ZERO:
845 case R600::PREDICATE_BIT:
856 if (
MI.getOpcode() == R600::KILLGT) {
858 }
else if (
MI.getOpcode() == R600::CF_ALU) {
864 return MI.getOperand(3).getImm() == 0 &&
MI.getOperand(4).getImm() == 0;
875 unsigned ExtraPredCycles,
883 unsigned ExtraTCycles,
886 unsigned ExtraFCycles,
909 case R600::PRED_SETE_INT:
910 MO.
setImm(R600::PRED_SETNE_INT);
912 case R600::PRED_SETNE_INT:
913 MO.
setImm(R600::PRED_SETE_INT);
915 case R600::PRED_SETE:
916 MO.
setImm(R600::PRED_SETNE);
918 case R600::PRED_SETNE:
919 MO.
setImm(R600::PRED_SETE);
927 case R600::PRED_SEL_ZERO:
928 MO2.
setReg(R600::PRED_SEL_ONE);
930 case R600::PRED_SEL_ONE:
931 MO2.
setReg(R600::PRED_SEL_ZERO);
940 std::vector<MachineOperand> &Pred,
941 bool SkipDead)
const {
947 int PIdx =
MI.findFirstPredOperandIdx();
949 if (
MI.getOpcode() == R600::CF_ALU) {
950 MI.getOperand(8).setImm(0);
954 if (
MI.getOpcode() == R600::DOT_4) {
956 .setReg(Pred[2].
getReg());
958 .setReg(Pred[2].
getReg());
960 .setReg(Pred[2].
getReg());
962 .setReg(Pred[2].
getReg());
985 unsigned *PredCost)
const {
992 unsigned Channel)
const {
998 switch (
MI.getOpcode()) {
1005 int RegOpIdx = OffsetOpIdx + 1;
1011 unsigned RegIndex =
MI.getOperand(RegOpIdx).getImm();
1012 unsigned Channel =
MI.getOperand(ChanOpIdx).getImm();
1014 Register OffsetReg =
MI.getOperand(OffsetOpIdx).getReg();
1015 if (OffsetReg == R600::INDIRECT_BASE_ADDR) {
1019 buildIndirectRead(
MBB,
MI,
MI.getOperand(DstOpIdx).getReg(), Address,
1025 unsigned RegIndex =
MI.getOperand(RegOpIdx).getImm();
1026 unsigned Channel =
MI.getOperand(ChanOpIdx).getImm();
1028 Register OffsetReg =
MI.getOperand(OffsetOpIdx).getReg();
1029 if (OffsetReg == R600::INDIRECT_BASE_ADDR) {
1031 MI.getOperand(ValOpIdx).getReg());
1033 buildIndirectWrite(
MBB,
MI,
MI.getOperand(ValOpIdx).getReg(),
1044 case R600::R600_EXTRACT_ELT_V2:
1045 case R600::R600_EXTRACT_ELT_V4:
1046 buildIndirectRead(
MI.getParent(),
MI,
MI.getOperand(0).getReg(),
1048 MI.getOperand(2).getReg(),
1051 case R600::R600_INSERT_ELT_V2:
1052 case R600::R600_INSERT_ELT_V4:
1053 buildIndirectWrite(
MI.getParent(),
MI,
MI.getOperand(2).getReg(),
1055 MI.getOperand(3).getReg(),
1059 MI.eraseFromParent();
1069 unsigned StackWidth = TFL->getStackWidth(MF);
1076 for (
unsigned Chan = 0; Chan < StackWidth; ++Chan) {
1077 unsigned Reg = R600::R600_TReg32RegClass.getRegister((4 * Index) + Chan);
1078 TRI.reserveRegisterTuples(Reserved,
Reg);
1084 return &R600::R600_TReg32_XRegClass;
1089 unsigned ValueReg,
unsigned Address,
1090 unsigned OffsetReg)
const {
1091 return buildIndirectWrite(
MBB,
I, ValueReg, Address, OffsetReg, 0);
1096 unsigned ValueReg,
unsigned Address,
1098 unsigned AddrChan)
const {
1102 case 0: AddrReg = R600::R600_AddrRegClass.getRegister(Address);
break;
1103 case 1: AddrReg = R600::R600_Addr_YRegClass.getRegister(Address);
break;
1104 case 2: AddrReg = R600::R600_Addr_ZRegClass.getRegister(Address);
break;
1105 case 3: AddrReg = R600::R600_Addr_WRegClass.getRegister(Address);
break;
1108 R600::AR_X, OffsetReg);
1121 unsigned ValueReg,
unsigned Address,
1122 unsigned OffsetReg)
const {
1123 return buildIndirectRead(
MBB,
I, ValueReg, Address, OffsetReg, 0);
1128 unsigned ValueReg,
unsigned Address,
1130 unsigned AddrChan)
const {
1134 case 0: AddrReg = R600::R600_AddrRegClass.getRegister(Address);
break;
1135 case 1: AddrReg = R600::R600_Addr_YRegClass.getRegister(Address);
break;
1136 case 2: AddrReg = R600::R600_Addr_ZRegClass.getRegister(Address);
break;
1137 case 3: AddrReg = R600::R600_Addr_WRegClass.getRegister(Address);
break;
1167 for (std::pair<unsigned, unsigned> LI :
MRI.
liveins()) {
1174 for (RegIndex = 0, RegEnd = IndirectRC->
getNumRegs(); RegIndex != RegEnd;
1179 Offset =
std::max(Offset, (
int)RegIndex);
1202 Offset = TFL->getFrameIndexReference(MF, -1, IgnoredFrameReg).getFixed();
1216 unsigned Src1Reg)
const {
1245 .
addReg(R600::PRED_SEL_OFF)
1252 #define OPERAND_CASE(Label) \
1254 static const unsigned Ops[] = \
1293 assert (
MI->getOpcode() == R600::DOT_4 &&
"Not Implemented");
1296 Opcode = R600::DOT4_r600;
1298 Opcode = R600::DOT4_eg;
1306 static const unsigned Operands[14] = {
1307 R600::OpName::update_exec_mask,
1308 R600::OpName::update_pred,
1311 R600::OpName::dst_rel,
1313 R600::OpName::src0_neg,
1314 R600::OpName::src0_rel,
1315 R600::OpName::src0_abs,
1316 R600::OpName::src0_sel,
1317 R600::OpName::src1_neg,
1318 R600::OpName::src1_rel,
1319 R600::OpName::src1_abs,
1320 R600::OpName::src1_sel,
1328 for (
unsigned Operand :
Operands) {
1343 R600::ALU_LITERAL_X);
1350 unsigned DstReg,
unsigned SrcReg)
const {
1363 int64_t Imm)
const {
1365 assert(Idx != -1 &&
"Operand not supported for this instruction.");
1366 assert(
MI.getOperand(Idx).isImm());
1367 MI.getOperand(Idx).setImm(Imm);
1375 unsigned Flag)
const {
1376 unsigned TargetFlags =
get(
MI.getOpcode()).TSFlags;
1410 assert(!IsOP3 &&
"Cannot set absolute value modifier for OP3 "
1427 assert(FlagIndex != -1 &&
"Flag not supported for this instruction");
1431 "Instruction flags not supported for this instruction");
1440 unsigned Flag)
const {
1441 unsigned TargetFlags =
get(
MI.getOpcode()).TSFlags;
1461 unsigned Flag)
const {
1462 unsigned TargetFlags =
get(
MI.getOpcode()).TSFlags;
1468 unsigned InstFlags = FlagOp.
getImm();
1470 FlagOp.
setImm(InstFlags);
1475 unsigned Kind)
const {