1 //===-- R600InstrInfo.cpp - R600 Instruction Information ------------------===//
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
7 //===----------------------------------------------------------------------===//
10 /// R600 Implementation of TargetInstrInfo.
12 //===----------------------------------------------------------------------===//
14 #include "R600InstrInfo.h"
16 #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
17 #include "R600Defines.h"
18 #include "R600Subtarget.h"
19 #include "llvm/ADT/SmallSet.h"
23 #define GET_INSTRINFO_CTOR_DTOR
24 #include "R600GenDFAPacketizer.inc"
26 #define GET_INSTRINFO_CTOR_DTOR
27 #define GET_INSTRMAP_INFO
28 #define GET_INSTRINFO_NAMED_OPS
29 #include "R600GenInstrInfo.inc"
31 R600InstrInfo::R600InstrInfo(const R600Subtarget
&ST
)
32 : R600GenInstrInfo(-1, -1), RI(), ST(ST
) {}
34 bool R600InstrInfo::isVector(const MachineInstr
&MI
) const {
35 return get(MI
.getOpcode()).TSFlags
& R600_InstFlag::VECTOR
;
38 void R600InstrInfo::copyPhysReg(MachineBasicBlock
&MBB
,
39 MachineBasicBlock::iterator MI
,
40 const DebugLoc
&DL
, MCRegister DestReg
,
41 MCRegister SrcReg
, bool KillSrc
) const {
42 unsigned VectorComponents
= 0;
43 if ((R600::R600_Reg128RegClass
.contains(DestReg
) ||
44 R600::R600_Reg128VerticalRegClass
.contains(DestReg
)) &&
45 (R600::R600_Reg128RegClass
.contains(SrcReg
) ||
46 R600::R600_Reg128VerticalRegClass
.contains(SrcReg
))) {
48 } else if((R600::R600_Reg64RegClass
.contains(DestReg
) ||
49 R600::R600_Reg64VerticalRegClass
.contains(DestReg
)) &&
50 (R600::R600_Reg64RegClass
.contains(SrcReg
) ||
51 R600::R600_Reg64VerticalRegClass
.contains(SrcReg
))) {
55 if (VectorComponents
> 0) {
56 for (unsigned I
= 0; I
< VectorComponents
; I
++) {
57 unsigned SubRegIndex
= R600RegisterInfo::getSubRegFromChannel(I
);
58 buildDefaultInstruction(MBB
, MI
, R600::MOV
,
59 RI
.getSubReg(DestReg
, SubRegIndex
),
60 RI
.getSubReg(SrcReg
, SubRegIndex
))
62 RegState::Define
| RegState::Implicit
);
65 MachineInstr
*NewMI
= buildDefaultInstruction(MBB
, MI
, R600::MOV
,
67 NewMI
->getOperand(getOperandIdx(*NewMI
, R600::OpName::src0
))
72 /// \returns true if \p MBBI can be moved into a new basic.
73 bool R600InstrInfo::isLegalToSplitMBBAt(MachineBasicBlock
&MBB
,
74 MachineBasicBlock::iterator MBBI
) const {
75 for (MachineInstr::const_mop_iterator I
= MBBI
->operands_begin(),
76 E
= MBBI
->operands_end(); I
!= E
; ++I
) {
77 if (I
->isReg() && !I
->getReg().isVirtual() && I
->isUse() &&
78 RI
.isPhysRegLiveAcrossClauses(I
->getReg()))
84 bool R600InstrInfo::isMov(unsigned Opcode
) const {
89 case R600::MOV_IMM_F32
:
90 case R600::MOV_IMM_I32
:
95 bool R600InstrInfo::isReductionOp(unsigned Opcode
) const {
99 bool R600InstrInfo::isCubeOp(unsigned Opcode
) const {
101 default: return false;
102 case R600::CUBE_r600_pseudo
:
103 case R600::CUBE_r600_real
:
104 case R600::CUBE_eg_pseudo
:
105 case R600::CUBE_eg_real
:
110 bool R600InstrInfo::isALUInstr(unsigned Opcode
) const {
111 unsigned TargetFlags
= get(Opcode
).TSFlags
;
113 return (TargetFlags
& R600_InstFlag::ALU_INST
);
116 bool R600InstrInfo::hasInstrModifiers(unsigned Opcode
) const {
117 unsigned TargetFlags
= get(Opcode
).TSFlags
;
119 return ((TargetFlags
& R600_InstFlag::OP1
) |
120 (TargetFlags
& R600_InstFlag::OP2
) |
121 (TargetFlags
& R600_InstFlag::OP3
));
124 bool R600InstrInfo::isLDSInstr(unsigned Opcode
) const {
125 unsigned TargetFlags
= get(Opcode
).TSFlags
;
127 return ((TargetFlags
& R600_InstFlag::LDS_1A
) |
128 (TargetFlags
& R600_InstFlag::LDS_1A1D
) |
129 (TargetFlags
& R600_InstFlag::LDS_1A2D
));
132 bool R600InstrInfo::isLDSRetInstr(unsigned Opcode
) const {
133 return isLDSInstr(Opcode
) && getOperandIdx(Opcode
, R600::OpName::dst
) != -1;
136 bool R600InstrInfo::canBeConsideredALU(const MachineInstr
&MI
) const {
137 if (isALUInstr(MI
.getOpcode()))
139 if (isVector(MI
) || isCubeOp(MI
.getOpcode()))
141 switch (MI
.getOpcode()) {
143 case R600::INTERP_PAIR_XY
:
144 case R600::INTERP_PAIR_ZW
:
145 case R600::INTERP_VEC_LOAD
:
154 bool R600InstrInfo::isTransOnly(unsigned Opcode
) const {
155 if (ST
.hasCaymanISA())
157 return (get(Opcode
).getSchedClass() == R600::Sched::TransALU
);
160 bool R600InstrInfo::isTransOnly(const MachineInstr
&MI
) const {
161 return isTransOnly(MI
.getOpcode());
164 bool R600InstrInfo::isVectorOnly(unsigned Opcode
) const {
165 return (get(Opcode
).getSchedClass() == R600::Sched::VecALU
);
168 bool R600InstrInfo::isVectorOnly(const MachineInstr
&MI
) const {
169 return isVectorOnly(MI
.getOpcode());
172 bool R600InstrInfo::isExport(unsigned Opcode
) const {
173 return (get(Opcode
).TSFlags
& R600_InstFlag::IS_EXPORT
);
176 bool R600InstrInfo::usesVertexCache(unsigned Opcode
) const {
177 return ST
.hasVertexCache() && IS_VTX(get(Opcode
));
180 bool R600InstrInfo::usesVertexCache(const MachineInstr
&MI
) const {
181 const MachineFunction
*MF
= MI
.getParent()->getParent();
182 return !AMDGPU::isCompute(MF
->getFunction().getCallingConv()) &&
183 usesVertexCache(MI
.getOpcode());
186 bool R600InstrInfo::usesTextureCache(unsigned Opcode
) const {
187 return (!ST
.hasVertexCache() && IS_VTX(get(Opcode
))) || IS_TEX(get(Opcode
));
190 bool R600InstrInfo::usesTextureCache(const MachineInstr
&MI
) const {
191 const MachineFunction
*MF
= MI
.getParent()->getParent();
192 return (AMDGPU::isCompute(MF
->getFunction().getCallingConv()) &&
193 usesVertexCache(MI
.getOpcode())) ||
194 usesTextureCache(MI
.getOpcode());
197 bool R600InstrInfo::mustBeLastInClause(unsigned Opcode
) const {
200 case R600::GROUP_BARRIER
:
207 bool R600InstrInfo::usesAddressRegister(MachineInstr
&MI
) const {
208 return MI
.findRegisterUseOperandIdx(R600::AR_X
, false, &RI
) != -1;
211 bool R600InstrInfo::definesAddressRegister(MachineInstr
&MI
) const {
212 return MI
.findRegisterDefOperandIdx(R600::AR_X
, false, false, &RI
) != -1;
215 bool R600InstrInfo::readsLDSSrcReg(const MachineInstr
&MI
) const {
216 if (!isALUInstr(MI
.getOpcode())) {
219 for (MachineInstr::const_mop_iterator I
= MI
.operands_begin(),
220 E
= MI
.operands_end();
222 if (!I
->isReg() || !I
->isUse() || I
->getReg().isVirtual())
225 if (R600::R600_LDS_SRC_REGRegClass
.contains(I
->getReg()))
231 int R600InstrInfo::getSelIdx(unsigned Opcode
, unsigned SrcIdx
) const {
232 static const unsigned SrcSelTable
[][2] = {
233 {R600::OpName::src0
, R600::OpName::src0_sel
},
234 {R600::OpName::src1
, R600::OpName::src1_sel
},
235 {R600::OpName::src2
, R600::OpName::src2_sel
},
236 {R600::OpName::src0_X
, R600::OpName::src0_sel_X
},
237 {R600::OpName::src0_Y
, R600::OpName::src0_sel_Y
},
238 {R600::OpName::src0_Z
, R600::OpName::src0_sel_Z
},
239 {R600::OpName::src0_W
, R600::OpName::src0_sel_W
},
240 {R600::OpName::src1_X
, R600::OpName::src1_sel_X
},
241 {R600::OpName::src1_Y
, R600::OpName::src1_sel_Y
},
242 {R600::OpName::src1_Z
, R600::OpName::src1_sel_Z
},
243 {R600::OpName::src1_W
, R600::OpName::src1_sel_W
}
246 for (const auto &Row
: SrcSelTable
) {
247 if (getOperandIdx(Opcode
, Row
[0]) == (int)SrcIdx
) {
248 return getOperandIdx(Opcode
, Row
[1]);
254 SmallVector
<std::pair
<MachineOperand
*, int64_t>, 3>
255 R600InstrInfo::getSrcs(MachineInstr
&MI
) const {
256 SmallVector
<std::pair
<MachineOperand
*, int64_t>, 3> Result
;
258 if (MI
.getOpcode() == R600::DOT_4
) {
259 static const unsigned OpTable
[8][2] = {
260 {R600::OpName::src0_X
, R600::OpName::src0_sel_X
},
261 {R600::OpName::src0_Y
, R600::OpName::src0_sel_Y
},
262 {R600::OpName::src0_Z
, R600::OpName::src0_sel_Z
},
263 {R600::OpName::src0_W
, R600::OpName::src0_sel_W
},
264 {R600::OpName::src1_X
, R600::OpName::src1_sel_X
},
265 {R600::OpName::src1_Y
, R600::OpName::src1_sel_Y
},
266 {R600::OpName::src1_Z
, R600::OpName::src1_sel_Z
},
267 {R600::OpName::src1_W
, R600::OpName::src1_sel_W
},
270 for (unsigned j
= 0; j
< 8; j
++) {
272 MI
.getOperand(getOperandIdx(MI
.getOpcode(), OpTable
[j
][0]));
273 Register Reg
= MO
.getReg();
274 if (Reg
== R600::ALU_CONST
) {
275 MachineOperand
&Sel
=
276 MI
.getOperand(getOperandIdx(MI
.getOpcode(), OpTable
[j
][1]));
277 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 (unsigned j
= 0; j
< 3; j
++) {
292 int SrcIdx
= getOperandIdx(MI
.getOpcode(), OpTable
[j
][0]);
295 MachineOperand
&MO
= MI
.getOperand(SrcIdx
);
296 Register Reg
= MO
.getReg();
297 if (Reg
== R600::ALU_CONST
) {
298 MachineOperand
&Sel
=
299 MI
.getOperand(getOperandIdx(MI
.getOpcode(), OpTable
[j
][1]));
300 Result
.push_back(std::make_pair(&MO
, Sel
.getImm()));
303 if (Reg
== R600::ALU_LITERAL_X
) {
304 MachineOperand
&Operand
=
305 MI
.getOperand(getOperandIdx(MI
.getOpcode(), R600::OpName::literal
));
306 if (Operand
.isImm()) {
307 Result
.push_back(std::make_pair(&MO
, Operand
.getImm()));
310 assert(Operand
.isGlobal());
312 Result
.push_back(std::make_pair(&MO
, 0));
317 std::vector
<std::pair
<int, unsigned>>
318 R600InstrInfo::ExtractSrcs(MachineInstr
&MI
,
319 const DenseMap
<unsigned, unsigned> &PV
,
320 unsigned &ConstCount
) const {
322 const std::pair
<int, unsigned> DummyPair(-1, 0);
323 std::vector
<std::pair
<int, unsigned>> Result
;
325 for (const auto &Src
: getSrcs(MI
)) {
327 Register Reg
= Src
.first
->getReg();
328 int Index
= RI
.getEncodingValue(Reg
) & 0xff;
329 if (Reg
== R600::OQAP
) {
330 Result
.push_back(std::make_pair(Index
, 0U));
332 if (PV
.find(Reg
) != PV
.end()) {
333 // 255 is used to tells its a PS/PV reg
334 Result
.push_back(std::make_pair(255, 0U));
339 Result
.push_back(DummyPair
);
342 unsigned Chan
= RI
.getHWRegChan(Reg
);
343 Result
.push_back(std::make_pair(Index
, Chan
));
346 Result
.push_back(DummyPair
);
350 static std::vector
<std::pair
<int, unsigned>>
351 Swizzle(std::vector
<std::pair
<int, unsigned>> Src
,
352 R600InstrInfo::BankSwizzle Swz
) {
353 if (Src
[0] == Src
[1])
356 case R600InstrInfo::ALU_VEC_012_SCL_210
:
358 case R600InstrInfo::ALU_VEC_021_SCL_122
:
359 std::swap(Src
[1], Src
[2]);
361 case R600InstrInfo::ALU_VEC_102_SCL_221
:
362 std::swap(Src
[0], Src
[1]);
364 case R600InstrInfo::ALU_VEC_120_SCL_212
:
365 std::swap(Src
[0], Src
[1]);
366 std::swap(Src
[0], Src
[2]);
368 case R600InstrInfo::ALU_VEC_201
:
369 std::swap(Src
[0], Src
[2]);
370 std::swap(Src
[0], Src
[1]);
372 case R600InstrInfo::ALU_VEC_210
:
373 std::swap(Src
[0], Src
[2]);
379 static unsigned getTransSwizzle(R600InstrInfo::BankSwizzle Swz
, unsigned Op
) {
380 assert(Op
< 3 && "Out of range swizzle index");
382 case R600InstrInfo::ALU_VEC_012_SCL_210
: {
383 unsigned Cycles
[3] = { 2, 1, 0};
386 case R600InstrInfo::ALU_VEC_021_SCL_122
: {
387 unsigned Cycles
[3] = { 1, 2, 2};
390 case R600InstrInfo::ALU_VEC_120_SCL_212
: {
391 unsigned Cycles
[3] = { 2, 1, 2};
394 case R600InstrInfo::ALU_VEC_102_SCL_221
: {
395 unsigned Cycles
[3] = { 2, 2, 1};
399 llvm_unreachable("Wrong Swizzle for Trans Slot");
403 /// returns how many MIs (whose inputs are represented by IGSrcs) can be packed
404 /// in the same Instruction Group while meeting read port limitations given a
405 /// Swz swizzle sequence.
406 unsigned R600InstrInfo::isLegalUpTo(
407 const std::vector
<std::vector
<std::pair
<int, unsigned>>> &IGSrcs
,
408 const std::vector
<R600InstrInfo::BankSwizzle
> &Swz
,
409 const std::vector
<std::pair
<int, unsigned>> &TransSrcs
,
410 R600InstrInfo::BankSwizzle TransSwz
) const {
412 memset(Vector
, -1, sizeof(Vector
));
413 for (unsigned i
= 0, e
= IGSrcs
.size(); i
< e
; i
++) {
414 const std::vector
<std::pair
<int, unsigned>> &Srcs
=
415 Swizzle(IGSrcs
[i
], Swz
[i
]);
416 for (unsigned j
= 0; j
< 3; j
++) {
417 const std::pair
<int, unsigned> &Src
= Srcs
[j
];
418 if (Src
.first
< 0 || Src
.first
== 255)
420 if (Src
.first
== GET_REG_INDEX(RI
.getEncodingValue(R600::OQAP
))) {
421 if (Swz
[i
] != R600InstrInfo::ALU_VEC_012_SCL_210
&&
422 Swz
[i
] != R600InstrInfo::ALU_VEC_021_SCL_122
) {
423 // The value from output queue A (denoted by register OQAP) can
424 // only be fetched during the first cycle.
427 // OQAP does not count towards the normal read port restrictions
430 if (Vector
[Src
.second
][j
] < 0)
431 Vector
[Src
.second
][j
] = Src
.first
;
432 if (Vector
[Src
.second
][j
] != Src
.first
)
436 // Now check Trans Alu
437 for (unsigned i
= 0, e
= TransSrcs
.size(); i
< e
; ++i
) {
438 const std::pair
<int, unsigned> &Src
= TransSrcs
[i
];
439 unsigned Cycle
= getTransSwizzle(TransSwz
, i
);
442 if (Src
.first
== 255)
444 if (Vector
[Src
.second
][Cycle
] < 0)
445 Vector
[Src
.second
][Cycle
] = Src
.first
;
446 if (Vector
[Src
.second
][Cycle
] != Src
.first
)
447 return IGSrcs
.size() - 1;
449 return IGSrcs
.size();
452 /// Given a swizzle sequence SwzCandidate and an index Idx, returns the next
453 /// (in lexicographic term) swizzle sequence assuming that all swizzles after
454 /// Idx can be skipped
456 NextPossibleSolution(
457 std::vector
<R600InstrInfo::BankSwizzle
> &SwzCandidate
,
459 assert(Idx
< SwzCandidate
.size());
461 while (ResetIdx
> -1 && SwzCandidate
[ResetIdx
] == R600InstrInfo::ALU_VEC_210
)
463 for (unsigned i
= ResetIdx
+ 1, e
= SwzCandidate
.size(); i
< e
; i
++) {
464 SwzCandidate
[i
] = R600InstrInfo::ALU_VEC_012_SCL_210
;
468 int NextSwizzle
= SwzCandidate
[ResetIdx
] + 1;
469 SwzCandidate
[ResetIdx
] = (R600InstrInfo::BankSwizzle
)NextSwizzle
;
473 /// Enumerate all possible Swizzle sequence to find one that can meet all
474 /// read port requirements.
475 bool R600InstrInfo::FindSwizzleForVectorSlot(
476 const std::vector
<std::vector
<std::pair
<int, unsigned>>> &IGSrcs
,
477 std::vector
<R600InstrInfo::BankSwizzle
> &SwzCandidate
,
478 const std::vector
<std::pair
<int, unsigned>> &TransSrcs
,
479 R600InstrInfo::BankSwizzle TransSwz
) const {
480 unsigned ValidUpTo
= 0;
482 ValidUpTo
= isLegalUpTo(IGSrcs
, SwzCandidate
, TransSrcs
, TransSwz
);
483 if (ValidUpTo
== IGSrcs
.size())
485 } while (NextPossibleSolution(SwzCandidate
, ValidUpTo
));
489 /// Instructions in Trans slot can't read gpr at cycle 0 if they also read
490 /// a const, and can't read a gpr at cycle 1 if they read 2 const.
492 isConstCompatible(R600InstrInfo::BankSwizzle TransSwz
,
493 const std::vector
<std::pair
<int, unsigned>> &TransOps
,
494 unsigned ConstCount
) {
495 // TransALU can't read 3 constants
498 for (unsigned i
= 0, e
= TransOps
.size(); i
< e
; ++i
) {
499 const std::pair
<int, unsigned> &Src
= TransOps
[i
];
500 unsigned Cycle
= getTransSwizzle(TransSwz
, i
);
503 if (ConstCount
> 0 && Cycle
== 0)
505 if (ConstCount
> 1 && Cycle
== 1)
512 R600InstrInfo::fitsReadPortLimitations(const std::vector
<MachineInstr
*> &IG
,
513 const DenseMap
<unsigned, unsigned> &PV
,
514 std::vector
<BankSwizzle
> &ValidSwizzle
,
517 //Todo : support shared src0 - src1 operand
519 std::vector
<std::vector
<std::pair
<int, unsigned>>> IGSrcs
;
520 ValidSwizzle
.clear();
522 BankSwizzle TransBS
= ALU_VEC_012_SCL_210
;
523 for (unsigned i
= 0, e
= IG
.size(); i
< e
; ++i
) {
524 IGSrcs
.push_back(ExtractSrcs(*IG
[i
], PV
, ConstCount
));
525 unsigned Op
= getOperandIdx(IG
[i
]->getOpcode(),
526 R600::OpName::bank_swizzle
);
527 ValidSwizzle
.push_back( (R600InstrInfo::BankSwizzle
)
528 IG
[i
]->getOperand(Op
).getImm());
530 std::vector
<std::pair
<int, unsigned>> TransOps
;
532 return FindSwizzleForVectorSlot(IGSrcs
, ValidSwizzle
, TransOps
, TransBS
);
534 TransOps
= std::move(IGSrcs
.back());
536 ValidSwizzle
.pop_back();
538 static const R600InstrInfo::BankSwizzle TransSwz
[] = {
544 for (unsigned i
= 0; i
< 4; i
++) {
545 TransBS
= TransSwz
[i
];
546 if (!isConstCompatible(TransBS
, TransOps
, ConstCount
))
548 bool Result
= FindSwizzleForVectorSlot(IGSrcs
, ValidSwizzle
, TransOps
,
551 ValidSwizzle
.push_back(TransBS
);
560 R600InstrInfo::fitsConstReadLimitations(const std::vector
<unsigned> &Consts
)
562 assert (Consts
.size() <= 12 && "Too many operands in instructions group");
563 unsigned Pair1
= 0, Pair2
= 0;
564 for (unsigned i
= 0, n
= Consts
.size(); i
< n
; ++i
) {
565 unsigned ReadConstHalf
= Consts
[i
] & 2;
566 unsigned ReadConstIndex
= Consts
[i
] & (~3);
567 unsigned ReadHalfConst
= ReadConstIndex
| ReadConstHalf
;
569 Pair1
= ReadHalfConst
;
572 if (Pair1
== ReadHalfConst
)
575 Pair2
= ReadHalfConst
;
578 if (Pair2
!= ReadHalfConst
)
585 R600InstrInfo::fitsConstReadLimitations(const std::vector
<MachineInstr
*> &MIs
)
587 std::vector
<unsigned> Consts
;
588 SmallSet
<int64_t, 4> Literals
;
589 for (unsigned i
= 0, n
= MIs
.size(); i
< n
; i
++) {
590 MachineInstr
&MI
= *MIs
[i
];
591 if (!isALUInstr(MI
.getOpcode()))
594 for (const auto &Src
: getSrcs(MI
)) {
595 if (Src
.first
->getReg() == R600::ALU_LITERAL_X
)
596 Literals
.insert(Src
.second
);
597 if (Literals
.size() > 4)
599 if (Src
.first
->getReg() == R600::ALU_CONST
)
600 Consts
.push_back(Src
.second
);
601 if (R600::R600_KC0RegClass
.contains(Src
.first
->getReg()) ||
602 R600::R600_KC1RegClass
.contains(Src
.first
->getReg())) {
603 unsigned Index
= RI
.getEncodingValue(Src
.first
->getReg()) & 0xff;
604 unsigned Chan
= RI
.getHWRegChan(Src
.first
->getReg());
605 Consts
.push_back((Index
<< 2) | Chan
);
609 return fitsConstReadLimitations(Consts
);
613 R600InstrInfo::CreateTargetScheduleState(const TargetSubtargetInfo
&STI
) const {
614 const InstrItineraryData
*II
= STI
.getInstrItineraryData();
615 return static_cast<const R600Subtarget
&>(STI
).createDFAPacketizer(II
);
619 isPredicateSetter(unsigned Opcode
) {
628 static MachineInstr
*
629 findFirstPredicateSetterFrom(MachineBasicBlock
&MBB
,
630 MachineBasicBlock::iterator I
) {
631 while (I
!= MBB
.begin()) {
633 MachineInstr
&MI
= *I
;
634 if (isPredicateSetter(MI
.getOpcode()))
642 bool isJump(unsigned Opcode
) {
643 return Opcode
== R600::JUMP
|| Opcode
== R600::JUMP_COND
;
646 static bool isBranch(unsigned Opcode
) {
647 return Opcode
== R600::BRANCH
|| Opcode
== R600::BRANCH_COND_i32
||
648 Opcode
== R600::BRANCH_COND_f32
;
651 bool R600InstrInfo::analyzeBranch(MachineBasicBlock
&MBB
,
652 MachineBasicBlock
*&TBB
,
653 MachineBasicBlock
*&FBB
,
654 SmallVectorImpl
<MachineOperand
> &Cond
,
655 bool AllowModify
) const {
656 // Most of the following comes from the ARM implementation of analyzeBranch
658 // If the block has no terminators, it just falls into the block after it.
659 MachineBasicBlock::iterator I
= MBB
.getLastNonDebugInstr();
663 // R600::BRANCH* instructions are only available after isel and are not
665 if (isBranch(I
->getOpcode()))
667 if (!isJump(I
->getOpcode())) {
671 // Remove successive JUMP
672 while (I
!= MBB
.begin() && std::prev(I
)->getOpcode() == R600::JUMP
) {
673 MachineBasicBlock::iterator PriorI
= std::prev(I
);
675 I
->removeFromParent();
678 MachineInstr
&LastInst
= *I
;
680 // If there is only one terminator instruction, process it.
681 unsigned LastOpc
= LastInst
.getOpcode();
682 if (I
== MBB
.begin() || !isJump((--I
)->getOpcode())) {
683 if (LastOpc
== R600::JUMP
) {
684 TBB
= LastInst
.getOperand(0).getMBB();
686 } else if (LastOpc
== R600::JUMP_COND
) {
688 while (!isPredicateSetter(predSet
->getOpcode())) {
691 TBB
= LastInst
.getOperand(0).getMBB();
692 Cond
.push_back(predSet
->getOperand(1));
693 Cond
.push_back(predSet
->getOperand(2));
694 Cond
.push_back(MachineOperand::CreateReg(R600::PRED_SEL_ONE
, false));
697 return true; // Can't handle indirect branch.
700 // Get the instruction before it if it is a terminator.
701 MachineInstr
&SecondLastInst
= *I
;
702 unsigned SecondLastOpc
= SecondLastInst
.getOpcode();
704 // If the block ends with a B and a Bcc, handle it.
705 if (SecondLastOpc
== R600::JUMP_COND
&& LastOpc
== R600::JUMP
) {
707 while (!isPredicateSetter(predSet
->getOpcode())) {
710 TBB
= SecondLastInst
.getOperand(0).getMBB();
711 FBB
= LastInst
.getOperand(0).getMBB();
712 Cond
.push_back(predSet
->getOperand(1));
713 Cond
.push_back(predSet
->getOperand(2));
714 Cond
.push_back(MachineOperand::CreateReg(R600::PRED_SEL_ONE
, false));
718 // Otherwise, can't handle this.
723 MachineBasicBlock::iterator
FindLastAluClause(MachineBasicBlock
&MBB
) {
724 for (MachineBasicBlock::reverse_iterator It
= MBB
.rbegin(), E
= MBB
.rend();
726 if (It
->getOpcode() == R600::CF_ALU
||
727 It
->getOpcode() == R600::CF_ALU_PUSH_BEFORE
)
728 return It
.getReverse();
733 unsigned R600InstrInfo::insertBranch(MachineBasicBlock
&MBB
,
734 MachineBasicBlock
*TBB
,
735 MachineBasicBlock
*FBB
,
736 ArrayRef
<MachineOperand
> Cond
,
738 int *BytesAdded
) const {
739 assert(TBB
&& "insertBranch must not be told to insert a fallthrough");
740 assert(!BytesAdded
&& "code size not handled");
744 BuildMI(&MBB
, DL
, get(R600::JUMP
)).addMBB(TBB
);
747 MachineInstr
*PredSet
= findFirstPredicateSetterFrom(MBB
, MBB
.end());
748 assert(PredSet
&& "No previous predicate !");
749 addFlag(*PredSet
, 0, MO_FLAG_PUSH
);
750 PredSet
->getOperand(2).setImm(Cond
[1].getImm());
752 BuildMI(&MBB
, DL
, get(R600::JUMP_COND
))
754 .addReg(R600::PREDICATE_BIT
, RegState::Kill
);
755 MachineBasicBlock::iterator CfAlu
= FindLastAluClause(MBB
);
756 if (CfAlu
== MBB
.end())
758 assert (CfAlu
->getOpcode() == R600::CF_ALU
);
759 CfAlu
->setDesc(get(R600::CF_ALU_PUSH_BEFORE
));
763 MachineInstr
*PredSet
= findFirstPredicateSetterFrom(MBB
, MBB
.end());
764 assert(PredSet
&& "No previous predicate !");
765 addFlag(*PredSet
, 0, MO_FLAG_PUSH
);
766 PredSet
->getOperand(2).setImm(Cond
[1].getImm());
767 BuildMI(&MBB
, DL
, get(R600::JUMP_COND
))
769 .addReg(R600::PREDICATE_BIT
, RegState::Kill
);
770 BuildMI(&MBB
, DL
, get(R600::JUMP
)).addMBB(FBB
);
771 MachineBasicBlock::iterator CfAlu
= FindLastAluClause(MBB
);
772 if (CfAlu
== MBB
.end())
774 assert (CfAlu
->getOpcode() == R600::CF_ALU
);
775 CfAlu
->setDesc(get(R600::CF_ALU_PUSH_BEFORE
));
780 unsigned R600InstrInfo::removeBranch(MachineBasicBlock
&MBB
,
781 int *BytesRemoved
) const {
782 assert(!BytesRemoved
&& "code size not handled");
784 // Note : we leave PRED* instructions there.
785 // They may be needed when predicating instructions.
787 MachineBasicBlock::iterator I
= MBB
.end();
789 if (I
== MBB
.begin()) {
793 switch (I
->getOpcode()) {
796 case R600::JUMP_COND
: {
797 MachineInstr
*predSet
= findFirstPredicateSetterFrom(MBB
, I
);
798 clearFlag(*predSet
, 0, MO_FLAG_PUSH
);
799 I
->eraseFromParent();
800 MachineBasicBlock::iterator CfAlu
= FindLastAluClause(MBB
);
801 if (CfAlu
== MBB
.end())
803 assert (CfAlu
->getOpcode() == R600::CF_ALU_PUSH_BEFORE
);
804 CfAlu
->setDesc(get(R600::CF_ALU
));
808 I
->eraseFromParent();
813 if (I
== MBB
.begin()) {
817 switch (I
->getOpcode()) {
818 // FIXME: only one case??
821 case R600::JUMP_COND
: {
822 MachineInstr
*predSet
= findFirstPredicateSetterFrom(MBB
, I
);
823 clearFlag(*predSet
, 0, MO_FLAG_PUSH
);
824 I
->eraseFromParent();
825 MachineBasicBlock::iterator CfAlu
= FindLastAluClause(MBB
);
826 if (CfAlu
== MBB
.end())
828 assert (CfAlu
->getOpcode() == R600::CF_ALU_PUSH_BEFORE
);
829 CfAlu
->setDesc(get(R600::CF_ALU
));
833 I
->eraseFromParent();
839 bool R600InstrInfo::isPredicated(const MachineInstr
&MI
) const {
840 int idx
= MI
.findFirstPredOperandIdx();
844 Register Reg
= MI
.getOperand(idx
).getReg();
846 default: return false;
847 case R600::PRED_SEL_ONE
:
848 case R600::PRED_SEL_ZERO
:
849 case R600::PREDICATE_BIT
:
854 bool R600InstrInfo::isPredicable(const MachineInstr
&MI
) const {
855 // XXX: KILL* instructions can be predicated, but they must be the last
856 // instruction in a clause, so this means any instructions after them cannot
857 // be predicated. Until we have proper support for instruction clauses in the
858 // backend, we will mark KILL* instructions as unpredicable.
860 if (MI
.getOpcode() == R600::KILLGT
) {
862 } else if (MI
.getOpcode() == R600::CF_ALU
) {
863 // If the clause start in the middle of MBB then the MBB has more
864 // than a single clause, unable to predicate several clauses.
865 if (MI
.getParent()->begin() != MachineBasicBlock::const_iterator(MI
))
867 // TODO: We don't support KC merging atm
868 return MI
.getOperand(3).getImm() == 0 && MI
.getOperand(4).getImm() == 0;
869 } else if (isVector(MI
)) {
872 return TargetInstrInfo::isPredicable(MI
);
877 R600InstrInfo::isProfitableToIfCvt(MachineBasicBlock
&MBB
,
879 unsigned ExtraPredCycles
,
880 BranchProbability Probability
) const{
885 R600InstrInfo::isProfitableToIfCvt(MachineBasicBlock
&TMBB
,
887 unsigned ExtraTCycles
,
888 MachineBasicBlock
&FMBB
,
890 unsigned ExtraFCycles
,
891 BranchProbability Probability
) const {
896 R600InstrInfo::isProfitableToDupForIfCvt(MachineBasicBlock
&MBB
,
898 BranchProbability Probability
)
904 R600InstrInfo::isProfitableToUnpredicate(MachineBasicBlock
&TMBB
,
905 MachineBasicBlock
&FMBB
) const {
910 R600InstrInfo::reverseBranchCondition(SmallVectorImpl
<MachineOperand
> &Cond
) const {
911 MachineOperand
&MO
= Cond
[1];
912 switch (MO
.getImm()) {
913 case R600::PRED_SETE_INT
:
914 MO
.setImm(R600::PRED_SETNE_INT
);
916 case R600::PRED_SETNE_INT
:
917 MO
.setImm(R600::PRED_SETE_INT
);
919 case R600::PRED_SETE
:
920 MO
.setImm(R600::PRED_SETNE
);
922 case R600::PRED_SETNE
:
923 MO
.setImm(R600::PRED_SETE
);
929 MachineOperand
&MO2
= Cond
[2];
930 switch (MO2
.getReg()) {
931 case R600::PRED_SEL_ZERO
:
932 MO2
.setReg(R600::PRED_SEL_ONE
);
934 case R600::PRED_SEL_ONE
:
935 MO2
.setReg(R600::PRED_SEL_ZERO
);
943 bool R600InstrInfo::ClobbersPredicate(MachineInstr
&MI
,
944 std::vector
<MachineOperand
> &Pred
,
945 bool SkipDead
) const {
946 return isPredicateSetter(MI
.getOpcode());
949 bool R600InstrInfo::PredicateInstruction(MachineInstr
&MI
,
950 ArrayRef
<MachineOperand
> Pred
) const {
951 int PIdx
= MI
.findFirstPredOperandIdx();
953 if (MI
.getOpcode() == R600::CF_ALU
) {
954 MI
.getOperand(8).setImm(0);
958 if (MI
.getOpcode() == R600::DOT_4
) {
959 MI
.getOperand(getOperandIdx(MI
, R600::OpName::pred_sel_X
))
960 .setReg(Pred
[2].getReg());
961 MI
.getOperand(getOperandIdx(MI
, R600::OpName::pred_sel_Y
))
962 .setReg(Pred
[2].getReg());
963 MI
.getOperand(getOperandIdx(MI
, R600::OpName::pred_sel_Z
))
964 .setReg(Pred
[2].getReg());
965 MI
.getOperand(getOperandIdx(MI
, R600::OpName::pred_sel_W
))
966 .setReg(Pred
[2].getReg());
967 MachineInstrBuilder
MIB(*MI
.getParent()->getParent(), MI
);
968 MIB
.addReg(R600::PREDICATE_BIT
, RegState::Implicit
);
973 MachineOperand
&PMO
= MI
.getOperand(PIdx
);
974 PMO
.setReg(Pred
[2].getReg());
975 MachineInstrBuilder
MIB(*MI
.getParent()->getParent(), MI
);
976 MIB
.addReg(R600::PREDICATE_BIT
, RegState::Implicit
);
983 unsigned int R600InstrInfo::getPredicationCost(const MachineInstr
&) const {
987 unsigned int R600InstrInfo::getInstrLatency(const InstrItineraryData
*ItinData
,
988 const MachineInstr
&,
989 unsigned *PredCost
) const {
995 unsigned R600InstrInfo::calculateIndirectAddress(unsigned RegIndex
,
996 unsigned Channel
) const {
997 assert(Channel
== 0);
1001 bool R600InstrInfo::expandPostRAPseudo(MachineInstr
&MI
) const {
1002 switch (MI
.getOpcode()) {
1004 MachineBasicBlock
*MBB
= MI
.getParent();
1006 R600::getNamedOperandIdx(MI
.getOpcode(), R600::OpName::addr
);
1007 // addr is a custom operand with multiple MI operands, and only the
1008 // first MI operand is given a name.
1009 int RegOpIdx
= OffsetOpIdx
+ 1;
1011 R600::getNamedOperandIdx(MI
.getOpcode(), R600::OpName::chan
);
1012 if (isRegisterLoad(MI
)) {
1014 R600::getNamedOperandIdx(MI
.getOpcode(), R600::OpName::dst
);
1015 unsigned RegIndex
= MI
.getOperand(RegOpIdx
).getImm();
1016 unsigned Channel
= MI
.getOperand(ChanOpIdx
).getImm();
1017 unsigned Address
= calculateIndirectAddress(RegIndex
, Channel
);
1018 Register OffsetReg
= MI
.getOperand(OffsetOpIdx
).getReg();
1019 if (OffsetReg
== R600::INDIRECT_BASE_ADDR
) {
1020 buildMovInstr(MBB
, MI
, MI
.getOperand(DstOpIdx
).getReg(),
1021 getIndirectAddrRegClass()->getRegister(Address
));
1023 buildIndirectRead(MBB
, MI
, MI
.getOperand(DstOpIdx
).getReg(), Address
,
1026 } else if (isRegisterStore(MI
)) {
1028 R600::getNamedOperandIdx(MI
.getOpcode(), R600::OpName::val
);
1029 unsigned RegIndex
= MI
.getOperand(RegOpIdx
).getImm();
1030 unsigned Channel
= MI
.getOperand(ChanOpIdx
).getImm();
1031 unsigned Address
= calculateIndirectAddress(RegIndex
, Channel
);
1032 Register OffsetReg
= MI
.getOperand(OffsetOpIdx
).getReg();
1033 if (OffsetReg
== R600::INDIRECT_BASE_ADDR
) {
1034 buildMovInstr(MBB
, MI
, getIndirectAddrRegClass()->getRegister(Address
),
1035 MI
.getOperand(ValOpIdx
).getReg());
1037 buildIndirectWrite(MBB
, MI
, MI
.getOperand(ValOpIdx
).getReg(),
1038 calculateIndirectAddress(RegIndex
, Channel
),
1048 case R600::R600_EXTRACT_ELT_V2
:
1049 case R600::R600_EXTRACT_ELT_V4
:
1050 buildIndirectRead(MI
.getParent(), MI
, MI
.getOperand(0).getReg(),
1051 RI
.getHWRegIndex(MI
.getOperand(1).getReg()), // Address
1052 MI
.getOperand(2).getReg(),
1053 RI
.getHWRegChan(MI
.getOperand(1).getReg()));
1055 case R600::R600_INSERT_ELT_V2
:
1056 case R600::R600_INSERT_ELT_V4
:
1057 buildIndirectWrite(MI
.getParent(), MI
, MI
.getOperand(2).getReg(), // Value
1058 RI
.getHWRegIndex(MI
.getOperand(1).getReg()), // Address
1059 MI
.getOperand(3).getReg(), // Offset
1060 RI
.getHWRegChan(MI
.getOperand(1).getReg())); // Channel
1063 MI
.eraseFromParent();
1067 void R600InstrInfo::reserveIndirectRegisters(BitVector
&Reserved
,
1068 const MachineFunction
&MF
,
1069 const R600RegisterInfo
&TRI
) const {
1070 const R600Subtarget
&ST
= MF
.getSubtarget
<R600Subtarget
>();
1071 const R600FrameLowering
*TFL
= ST
.getFrameLowering();
1073 unsigned StackWidth
= TFL
->getStackWidth(MF
);
1074 int End
= getIndirectIndexEnd(MF
);
1079 for (int Index
= getIndirectIndexBegin(MF
); Index
<= End
; ++Index
) {
1080 for (unsigned Chan
= 0; Chan
< StackWidth
; ++Chan
) {
1081 unsigned Reg
= R600::R600_TReg32RegClass
.getRegister((4 * Index
) + Chan
);
1082 TRI
.reserveRegisterTuples(Reserved
, Reg
);
1087 const TargetRegisterClass
*R600InstrInfo::getIndirectAddrRegClass() const {
1088 return &R600::R600_TReg32_XRegClass
;
1091 MachineInstrBuilder
R600InstrInfo::buildIndirectWrite(MachineBasicBlock
*MBB
,
1092 MachineBasicBlock::iterator I
,
1093 unsigned ValueReg
, unsigned Address
,
1094 unsigned OffsetReg
) const {
1095 return buildIndirectWrite(MBB
, I
, ValueReg
, Address
, OffsetReg
, 0);
1098 MachineInstrBuilder
R600InstrInfo::buildIndirectWrite(MachineBasicBlock
*MBB
,
1099 MachineBasicBlock::iterator I
,
1100 unsigned ValueReg
, unsigned Address
,
1102 unsigned AddrChan
) const {
1105 default: llvm_unreachable("Invalid Channel");
1106 case 0: AddrReg
= R600::R600_AddrRegClass
.getRegister(Address
); break;
1107 case 1: AddrReg
= R600::R600_Addr_YRegClass
.getRegister(Address
); break;
1108 case 2: AddrReg
= R600::R600_Addr_ZRegClass
.getRegister(Address
); break;
1109 case 3: AddrReg
= R600::R600_Addr_WRegClass
.getRegister(Address
); break;
1111 MachineInstr
*MOVA
= buildDefaultInstruction(*MBB
, I
, R600::MOVA_INT_eg
,
1112 R600::AR_X
, OffsetReg
);
1113 setImmOperand(*MOVA
, R600::OpName::write
, 0);
1115 MachineInstrBuilder Mov
= buildDefaultInstruction(*MBB
, I
, R600::MOV
,
1118 RegState::Implicit
| RegState::Kill
);
1119 setImmOperand(*Mov
, R600::OpName::dst_rel
, 1);
1123 MachineInstrBuilder
R600InstrInfo::buildIndirectRead(MachineBasicBlock
*MBB
,
1124 MachineBasicBlock::iterator I
,
1125 unsigned ValueReg
, unsigned Address
,
1126 unsigned OffsetReg
) const {
1127 return buildIndirectRead(MBB
, I
, ValueReg
, Address
, OffsetReg
, 0);
1130 MachineInstrBuilder
R600InstrInfo::buildIndirectRead(MachineBasicBlock
*MBB
,
1131 MachineBasicBlock::iterator I
,
1132 unsigned ValueReg
, unsigned Address
,
1134 unsigned AddrChan
) const {
1137 default: llvm_unreachable("Invalid Channel");
1138 case 0: AddrReg
= R600::R600_AddrRegClass
.getRegister(Address
); break;
1139 case 1: AddrReg
= R600::R600_Addr_YRegClass
.getRegister(Address
); break;
1140 case 2: AddrReg
= R600::R600_Addr_ZRegClass
.getRegister(Address
); break;
1141 case 3: AddrReg
= R600::R600_Addr_WRegClass
.getRegister(Address
); break;
1143 MachineInstr
*MOVA
= buildDefaultInstruction(*MBB
, I
, R600::MOVA_INT_eg
,
1146 setImmOperand(*MOVA
, R600::OpName::write
, 0);
1147 MachineInstrBuilder Mov
= buildDefaultInstruction(*MBB
, I
, R600::MOV
,
1151 RegState::Implicit
| RegState::Kill
);
1152 setImmOperand(*Mov
, R600::OpName::src0_rel
, 1);
1157 int R600InstrInfo::getIndirectIndexBegin(const MachineFunction
&MF
) const {
1158 const MachineRegisterInfo
&MRI
= MF
.getRegInfo();
1159 const MachineFrameInfo
&MFI
= MF
.getFrameInfo();
1162 if (MFI
.getNumObjects() == 0) {
1166 if (MRI
.livein_empty()) {
1170 const TargetRegisterClass
*IndirectRC
= getIndirectAddrRegClass();
1171 for (std::pair
<unsigned, unsigned> LI
: MRI
.liveins()) {
1172 Register Reg
= LI
.first
;
1173 if (Reg
.isVirtual() || !IndirectRC
->contains(Reg
))
1178 for (RegIndex
= 0, RegEnd
= IndirectRC
->getNumRegs(); RegIndex
!= RegEnd
;
1180 if (IndirectRC
->getRegister(RegIndex
) == (unsigned)Reg
)
1183 Offset
= std::max(Offset
, (int)RegIndex
);
1189 int R600InstrInfo::getIndirectIndexEnd(const MachineFunction
&MF
) const {
1191 const MachineFrameInfo
&MFI
= MF
.getFrameInfo();
1193 // Variable sized objects are not supported
1194 if (MFI
.hasVarSizedObjects()) {
1198 if (MFI
.getNumObjects() == 0) {
1202 const R600Subtarget
&ST
= MF
.getSubtarget
<R600Subtarget
>();
1203 const R600FrameLowering
*TFL
= ST
.getFrameLowering();
1205 Register IgnoredFrameReg
;
1206 Offset
= TFL
->getFrameIndexReference(MF
, -1, IgnoredFrameReg
).getFixed();
1208 return getIndirectIndexBegin(MF
) + Offset
;
1211 unsigned R600InstrInfo::getMaxAlusPerClause() const {
1215 MachineInstrBuilder
R600InstrInfo::buildDefaultInstruction(MachineBasicBlock
&MBB
,
1216 MachineBasicBlock::iterator I
,
1220 unsigned Src1Reg
) const {
1221 MachineInstrBuilder MIB
= BuildMI(MBB
, I
, MBB
.findDebugLoc(I
), get(Opcode
),
1225 MIB
.addImm(0) // $update_exec_mask
1226 .addImm(0); // $update_predicate
1228 MIB
.addImm(1) // $write
1230 .addImm(0) // $dst_rel
1231 .addImm(0) // $dst_clamp
1232 .addReg(Src0Reg
) // $src0
1233 .addImm(0) // $src0_neg
1234 .addImm(0) // $src0_rel
1235 .addImm(0) // $src0_abs
1236 .addImm(-1); // $src0_sel
1239 MIB
.addReg(Src1Reg
) // $src1
1240 .addImm(0) // $src1_neg
1241 .addImm(0) // $src1_rel
1242 .addImm(0) // $src1_abs
1243 .addImm(-1); // $src1_sel
1246 //XXX: The r600g finalizer expects this to be 1, once we've moved the
1247 //scheduling to the backend, we can change the default to 0.
1248 MIB
.addImm(1) // $last
1249 .addReg(R600::PRED_SEL_OFF
) // $pred_sel
1250 .addImm(0) // $literal
1251 .addImm(0); // $bank_swizzle
1256 #define OPERAND_CASE(Label) \
1258 static const unsigned Ops[] = \
1268 static unsigned getSlotedOps(unsigned Op
, unsigned Slot
) {
1270 OPERAND_CASE(R600::OpName::update_exec_mask
)
1271 OPERAND_CASE(R600::OpName::update_pred
)
1272 OPERAND_CASE(R600::OpName::write
)
1273 OPERAND_CASE(R600::OpName::omod
)
1274 OPERAND_CASE(R600::OpName::dst_rel
)
1275 OPERAND_CASE(R600::OpName::clamp
)
1276 OPERAND_CASE(R600::OpName::src0
)
1277 OPERAND_CASE(R600::OpName::src0_neg
)
1278 OPERAND_CASE(R600::OpName::src0_rel
)
1279 OPERAND_CASE(R600::OpName::src0_abs
)
1280 OPERAND_CASE(R600::OpName::src0_sel
)
1281 OPERAND_CASE(R600::OpName::src1
)
1282 OPERAND_CASE(R600::OpName::src1_neg
)
1283 OPERAND_CASE(R600::OpName::src1_rel
)
1284 OPERAND_CASE(R600::OpName::src1_abs
)
1285 OPERAND_CASE(R600::OpName::src1_sel
)
1286 OPERAND_CASE(R600::OpName::pred_sel
)
1288 llvm_unreachable("Wrong Operand");
1294 MachineInstr
*R600InstrInfo::buildSlotOfVectorInstruction(
1295 MachineBasicBlock
&MBB
, MachineInstr
*MI
, unsigned Slot
, unsigned DstReg
)
1297 assert (MI
->getOpcode() == R600::DOT_4
&& "Not Implemented");
1299 if (ST
.getGeneration() <= AMDGPUSubtarget::R700
)
1300 Opcode
= R600::DOT4_r600
;
1302 Opcode
= R600::DOT4_eg
;
1303 MachineBasicBlock::iterator I
= MI
;
1304 MachineOperand
&Src0
= MI
->getOperand(
1305 getOperandIdx(MI
->getOpcode(), getSlotedOps(R600::OpName::src0
, Slot
)));
1306 MachineOperand
&Src1
= MI
->getOperand(
1307 getOperandIdx(MI
->getOpcode(), getSlotedOps(R600::OpName::src1
, Slot
)));
1308 MachineInstr
*MIB
= buildDefaultInstruction(
1309 MBB
, I
, Opcode
, DstReg
, Src0
.getReg(), Src1
.getReg());
1310 static const unsigned Operands
[14] = {
1311 R600::OpName::update_exec_mask
,
1312 R600::OpName::update_pred
,
1313 R600::OpName::write
,
1315 R600::OpName::dst_rel
,
1316 R600::OpName::clamp
,
1317 R600::OpName::src0_neg
,
1318 R600::OpName::src0_rel
,
1319 R600::OpName::src0_abs
,
1320 R600::OpName::src0_sel
,
1321 R600::OpName::src1_neg
,
1322 R600::OpName::src1_rel
,
1323 R600::OpName::src1_abs
,
1324 R600::OpName::src1_sel
,
1327 MachineOperand
&MO
= MI
->getOperand(getOperandIdx(MI
->getOpcode(),
1328 getSlotedOps(R600::OpName::pred_sel
, Slot
)));
1329 MIB
->getOperand(getOperandIdx(Opcode
, R600::OpName::pred_sel
))
1330 .setReg(MO
.getReg());
1332 for (unsigned i
= 0; i
< 14; i
++) {
1333 MachineOperand
&MO
= MI
->getOperand(
1334 getOperandIdx(MI
->getOpcode(), getSlotedOps(Operands
[i
], Slot
)));
1335 assert (MO
.isImm());
1336 setImmOperand(*MIB
, Operands
[i
], MO
.getImm());
1338 MIB
->getOperand(20).setImm(0);
1342 MachineInstr
*R600InstrInfo::buildMovImm(MachineBasicBlock
&BB
,
1343 MachineBasicBlock::iterator I
,
1345 uint64_t Imm
) const {
1346 MachineInstr
*MovImm
= buildDefaultInstruction(BB
, I
, R600::MOV
, DstReg
,
1347 R600::ALU_LITERAL_X
);
1348 setImmOperand(*MovImm
, R600::OpName::literal
, Imm
);
1352 MachineInstr
*R600InstrInfo::buildMovInstr(MachineBasicBlock
*MBB
,
1353 MachineBasicBlock::iterator I
,
1354 unsigned DstReg
, unsigned SrcReg
) const {
1355 return buildDefaultInstruction(*MBB
, I
, R600::MOV
, DstReg
, SrcReg
);
1358 int R600InstrInfo::getOperandIdx(const MachineInstr
&MI
, unsigned Op
) const {
1359 return getOperandIdx(MI
.getOpcode(), Op
);
1362 int R600InstrInfo::getOperandIdx(unsigned Opcode
, unsigned Op
) const {
1363 return R600::getNamedOperandIdx(Opcode
, Op
);
1366 void R600InstrInfo::setImmOperand(MachineInstr
&MI
, unsigned Op
,
1367 int64_t Imm
) const {
1368 int Idx
= getOperandIdx(MI
, Op
);
1369 assert(Idx
!= -1 && "Operand not supported for this instruction.");
1370 assert(MI
.getOperand(Idx
).isImm());
1371 MI
.getOperand(Idx
).setImm(Imm
);
1374 //===----------------------------------------------------------------------===//
1375 // Instruction flag getters/setters
1376 //===----------------------------------------------------------------------===//
1378 MachineOperand
&R600InstrInfo::getFlagOp(MachineInstr
&MI
, unsigned SrcIdx
,
1379 unsigned Flag
) const {
1380 unsigned TargetFlags
= get(MI
.getOpcode()).TSFlags
;
1383 // If we pass something other than the default value of Flag to this
1384 // function, it means we are want to set a flag on an instruction
1385 // that uses native encoding.
1386 assert(HAS_NATIVE_OPERANDS(TargetFlags
));
1387 bool IsOP3
= (TargetFlags
& R600_InstFlag::OP3
) == R600_InstFlag::OP3
;
1390 FlagIndex
= getOperandIdx(MI
, R600::OpName::clamp
);
1393 FlagIndex
= getOperandIdx(MI
, R600::OpName::write
);
1395 case MO_FLAG_NOT_LAST
:
1397 FlagIndex
= getOperandIdx(MI
, R600::OpName::last
);
1402 FlagIndex
= getOperandIdx(MI
, R600::OpName::src0_neg
);
1405 FlagIndex
= getOperandIdx(MI
, R600::OpName::src1_neg
);
1408 FlagIndex
= getOperandIdx(MI
, R600::OpName::src2_neg
);
1414 assert(!IsOP3
&& "Cannot set absolute value modifier for OP3 "
1419 FlagIndex
= getOperandIdx(MI
, R600::OpName::src0_abs
);
1422 FlagIndex
= getOperandIdx(MI
, R600::OpName::src1_abs
);
1431 assert(FlagIndex
!= -1 && "Flag not supported for this instruction");
1433 FlagIndex
= GET_FLAG_OPERAND_IDX(TargetFlags
);
1434 assert(FlagIndex
!= 0 &&
1435 "Instruction flags not supported for this instruction");
1438 MachineOperand
&FlagOp
= MI
.getOperand(FlagIndex
);
1439 assert(FlagOp
.isImm());
1443 void R600InstrInfo::addFlag(MachineInstr
&MI
, unsigned Operand
,
1444 unsigned Flag
) const {
1445 unsigned TargetFlags
= get(MI
.getOpcode()).TSFlags
;
1449 if (HAS_NATIVE_OPERANDS(TargetFlags
)) {
1450 MachineOperand
&FlagOp
= getFlagOp(MI
, Operand
, Flag
);
1451 if (Flag
== MO_FLAG_NOT_LAST
) {
1452 clearFlag(MI
, Operand
, MO_FLAG_LAST
);
1453 } else if (Flag
== MO_FLAG_MASK
) {
1454 clearFlag(MI
, Operand
, Flag
);
1459 MachineOperand
&FlagOp
= getFlagOp(MI
, Operand
);
1460 FlagOp
.setImm(FlagOp
.getImm() | (Flag
<< (NUM_MO_FLAGS
* Operand
)));
1464 void R600InstrInfo::clearFlag(MachineInstr
&MI
, unsigned Operand
,
1465 unsigned Flag
) const {
1466 unsigned TargetFlags
= get(MI
.getOpcode()).TSFlags
;
1467 if (HAS_NATIVE_OPERANDS(TargetFlags
)) {
1468 MachineOperand
&FlagOp
= getFlagOp(MI
, Operand
, Flag
);
1471 MachineOperand
&FlagOp
= getFlagOp(MI
);
1472 unsigned InstFlags
= FlagOp
.getImm();
1473 InstFlags
&= ~(Flag
<< (NUM_MO_FLAGS
* Operand
));
1474 FlagOp
.setImm(InstFlags
);
1478 unsigned R600InstrInfo::getAddressSpaceForPseudoSourceKind(
1479 unsigned Kind
) const {
1481 case PseudoSourceValue::Stack
:
1482 case PseudoSourceValue::FixedStack
:
1483 return AMDGPUAS::PRIVATE_ADDRESS
;
1484 case PseudoSourceValue::ConstantPool
:
1485 case PseudoSourceValue::GOT
:
1486 case PseudoSourceValue::JumpTable
:
1487 case PseudoSourceValue::GlobalValueCallEntry
:
1488 case PseudoSourceValue::ExternalSymbolCallEntry
:
1489 case PseudoSourceValue::TargetCustom
:
1490 return AMDGPUAS::CONSTANT_ADDRESS
;
1493 llvm_unreachable("Invalid pseudo source kind");