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 "AMDGPUInstrInfo.h"
17 #include "AMDGPUSubtarget.h"
18 #include "R600Defines.h"
19 #include "R600FrameLowering.h"
20 #include "R600RegisterInfo.h"
21 #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
22 #include "Utils/AMDGPUBaseInfo.h"
23 #include "llvm/ADT/BitVector.h"
24 #include "llvm/ADT/SmallSet.h"
25 #include "llvm/ADT/SmallVector.h"
26 #include "llvm/CodeGen/MachineBasicBlock.h"
27 #include "llvm/CodeGen/MachineFrameInfo.h"
28 #include "llvm/CodeGen/MachineFunction.h"
29 #include "llvm/CodeGen/MachineInstr.h"
30 #include "llvm/CodeGen/MachineInstrBuilder.h"
31 #include "llvm/CodeGen/MachineOperand.h"
32 #include "llvm/CodeGen/MachineRegisterInfo.h"
33 #include "llvm/CodeGen/TargetRegisterInfo.h"
34 #include "llvm/CodeGen/TargetSubtargetInfo.h"
35 #include "llvm/Support/ErrorHandling.h"
46 #define GET_INSTRINFO_CTOR_DTOR
47 #include "R600GenDFAPacketizer.inc"
49 #define GET_INSTRINFO_CTOR_DTOR
50 #define GET_INSTRMAP_INFO
51 #define GET_INSTRINFO_NAMED_OPS
52 #include "R600GenInstrInfo.inc"
54 R600InstrInfo::R600InstrInfo(const R600Subtarget
&ST
)
55 : R600GenInstrInfo(-1, -1), RI(), ST(ST
) {}
57 bool R600InstrInfo::isVector(const MachineInstr
&MI
) const {
58 return get(MI
.getOpcode()).TSFlags
& R600_InstFlag::VECTOR
;
61 void R600InstrInfo::copyPhysReg(MachineBasicBlock
&MBB
,
62 MachineBasicBlock::iterator MI
,
63 const DebugLoc
&DL
, unsigned DestReg
,
64 unsigned SrcReg
, bool KillSrc
) const {
65 unsigned VectorComponents
= 0;
66 if ((R600::R600_Reg128RegClass
.contains(DestReg
) ||
67 R600::R600_Reg128VerticalRegClass
.contains(DestReg
)) &&
68 (R600::R600_Reg128RegClass
.contains(SrcReg
) ||
69 R600::R600_Reg128VerticalRegClass
.contains(SrcReg
))) {
71 } else if((R600::R600_Reg64RegClass
.contains(DestReg
) ||
72 R600::R600_Reg64VerticalRegClass
.contains(DestReg
)) &&
73 (R600::R600_Reg64RegClass
.contains(SrcReg
) ||
74 R600::R600_Reg64VerticalRegClass
.contains(SrcReg
))) {
78 if (VectorComponents
> 0) {
79 for (unsigned I
= 0; I
< VectorComponents
; I
++) {
80 unsigned SubRegIndex
= AMDGPURegisterInfo::getSubRegFromChannel(I
);
81 buildDefaultInstruction(MBB
, MI
, R600::MOV
,
82 RI
.getSubReg(DestReg
, SubRegIndex
),
83 RI
.getSubReg(SrcReg
, SubRegIndex
))
85 RegState::Define
| RegState::Implicit
);
88 MachineInstr
*NewMI
= buildDefaultInstruction(MBB
, MI
, R600::MOV
,
90 NewMI
->getOperand(getOperandIdx(*NewMI
, R600::OpName::src0
))
95 /// \returns true if \p MBBI can be moved into a new basic.
96 bool R600InstrInfo::isLegalToSplitMBBAt(MachineBasicBlock
&MBB
,
97 MachineBasicBlock::iterator MBBI
) const {
98 for (MachineInstr::const_mop_iterator I
= MBBI
->operands_begin(),
99 E
= MBBI
->operands_end(); I
!= E
; ++I
) {
100 if (I
->isReg() && !TargetRegisterInfo::isVirtualRegister(I
->getReg()) &&
101 I
->isUse() && RI
.isPhysRegLiveAcrossClauses(I
->getReg()))
107 bool R600InstrInfo::isMov(unsigned Opcode
) const {
112 case R600::MOV_IMM_F32
:
113 case R600::MOV_IMM_I32
:
118 bool R600InstrInfo::isReductionOp(unsigned Opcode
) const {
122 bool R600InstrInfo::isCubeOp(unsigned Opcode
) const {
124 default: return false;
125 case R600::CUBE_r600_pseudo
:
126 case R600::CUBE_r600_real
:
127 case R600::CUBE_eg_pseudo
:
128 case R600::CUBE_eg_real
:
133 bool R600InstrInfo::isALUInstr(unsigned Opcode
) const {
134 unsigned TargetFlags
= get(Opcode
).TSFlags
;
136 return (TargetFlags
& R600_InstFlag::ALU_INST
);
139 bool R600InstrInfo::hasInstrModifiers(unsigned Opcode
) const {
140 unsigned TargetFlags
= get(Opcode
).TSFlags
;
142 return ((TargetFlags
& R600_InstFlag::OP1
) |
143 (TargetFlags
& R600_InstFlag::OP2
) |
144 (TargetFlags
& R600_InstFlag::OP3
));
147 bool R600InstrInfo::isLDSInstr(unsigned Opcode
) const {
148 unsigned TargetFlags
= get(Opcode
).TSFlags
;
150 return ((TargetFlags
& R600_InstFlag::LDS_1A
) |
151 (TargetFlags
& R600_InstFlag::LDS_1A1D
) |
152 (TargetFlags
& R600_InstFlag::LDS_1A2D
));
155 bool R600InstrInfo::isLDSRetInstr(unsigned Opcode
) const {
156 return isLDSInstr(Opcode
) && getOperandIdx(Opcode
, R600::OpName::dst
) != -1;
159 bool R600InstrInfo::canBeConsideredALU(const MachineInstr
&MI
) const {
160 if (isALUInstr(MI
.getOpcode()))
162 if (isVector(MI
) || isCubeOp(MI
.getOpcode()))
164 switch (MI
.getOpcode()) {
166 case R600::INTERP_PAIR_XY
:
167 case R600::INTERP_PAIR_ZW
:
168 case R600::INTERP_VEC_LOAD
:
177 bool R600InstrInfo::isTransOnly(unsigned Opcode
) const {
178 if (ST
.hasCaymanISA())
180 return (get(Opcode
).getSchedClass() == R600::Sched::TransALU
);
183 bool R600InstrInfo::isTransOnly(const MachineInstr
&MI
) const {
184 return isTransOnly(MI
.getOpcode());
187 bool R600InstrInfo::isVectorOnly(unsigned Opcode
) const {
188 return (get(Opcode
).getSchedClass() == R600::Sched::VecALU
);
191 bool R600InstrInfo::isVectorOnly(const MachineInstr
&MI
) const {
192 return isVectorOnly(MI
.getOpcode());
195 bool R600InstrInfo::isExport(unsigned Opcode
) const {
196 return (get(Opcode
).TSFlags
& R600_InstFlag::IS_EXPORT
);
199 bool R600InstrInfo::usesVertexCache(unsigned Opcode
) const {
200 return ST
.hasVertexCache() && IS_VTX(get(Opcode
));
203 bool R600InstrInfo::usesVertexCache(const MachineInstr
&MI
) const {
204 const MachineFunction
*MF
= MI
.getParent()->getParent();
205 return !AMDGPU::isCompute(MF
->getFunction().getCallingConv()) &&
206 usesVertexCache(MI
.getOpcode());
209 bool R600InstrInfo::usesTextureCache(unsigned Opcode
) const {
210 return (!ST
.hasVertexCache() && IS_VTX(get(Opcode
))) || IS_TEX(get(Opcode
));
213 bool R600InstrInfo::usesTextureCache(const MachineInstr
&MI
) const {
214 const MachineFunction
*MF
= MI
.getParent()->getParent();
215 return (AMDGPU::isCompute(MF
->getFunction().getCallingConv()) &&
216 usesVertexCache(MI
.getOpcode())) ||
217 usesTextureCache(MI
.getOpcode());
220 bool R600InstrInfo::mustBeLastInClause(unsigned Opcode
) const {
223 case R600::GROUP_BARRIER
:
230 bool R600InstrInfo::usesAddressRegister(MachineInstr
&MI
) const {
231 return MI
.findRegisterUseOperandIdx(R600::AR_X
, false, &RI
) != -1;
234 bool R600InstrInfo::definesAddressRegister(MachineInstr
&MI
) const {
235 return MI
.findRegisterDefOperandIdx(R600::AR_X
, false, false, &RI
) != -1;
238 bool R600InstrInfo::readsLDSSrcReg(const MachineInstr
&MI
) const {
239 if (!isALUInstr(MI
.getOpcode())) {
242 for (MachineInstr::const_mop_iterator I
= MI
.operands_begin(),
243 E
= MI
.operands_end();
245 if (!I
->isReg() || !I
->isUse() ||
246 TargetRegisterInfo::isVirtualRegister(I
->getReg()))
249 if (R600::R600_LDS_SRC_REGRegClass
.contains(I
->getReg()))
255 int R600InstrInfo::getSelIdx(unsigned Opcode
, unsigned SrcIdx
) const {
256 static const unsigned SrcSelTable
[][2] = {
257 {R600::OpName::src0
, R600::OpName::src0_sel
},
258 {R600::OpName::src1
, R600::OpName::src1_sel
},
259 {R600::OpName::src2
, R600::OpName::src2_sel
},
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 (const auto &Row
: SrcSelTable
) {
271 if (getOperandIdx(Opcode
, Row
[0]) == (int)SrcIdx
) {
272 return getOperandIdx(Opcode
, Row
[1]);
278 SmallVector
<std::pair
<MachineOperand
*, int64_t>, 3>
279 R600InstrInfo::getSrcs(MachineInstr
&MI
) const {
280 SmallVector
<std::pair
<MachineOperand
*, int64_t>, 3> Result
;
282 if (MI
.getOpcode() == R600::DOT_4
) {
283 static const unsigned OpTable
[8][2] = {
284 {R600::OpName::src0_X
, R600::OpName::src0_sel_X
},
285 {R600::OpName::src0_Y
, R600::OpName::src0_sel_Y
},
286 {R600::OpName::src0_Z
, R600::OpName::src0_sel_Z
},
287 {R600::OpName::src0_W
, R600::OpName::src0_sel_W
},
288 {R600::OpName::src1_X
, R600::OpName::src1_sel_X
},
289 {R600::OpName::src1_Y
, R600::OpName::src1_sel_Y
},
290 {R600::OpName::src1_Z
, R600::OpName::src1_sel_Z
},
291 {R600::OpName::src1_W
, R600::OpName::src1_sel_W
},
294 for (unsigned j
= 0; j
< 8; j
++) {
296 MI
.getOperand(getOperandIdx(MI
.getOpcode(), OpTable
[j
][0]));
297 unsigned Reg
= MO
.getReg();
298 if (Reg
== R600::ALU_CONST
) {
299 MachineOperand
&Sel
=
300 MI
.getOperand(getOperandIdx(MI
.getOpcode(), OpTable
[j
][1]));
301 Result
.push_back(std::make_pair(&MO
, Sel
.getImm()));
309 static const unsigned OpTable
[3][2] = {
310 {R600::OpName::src0
, R600::OpName::src0_sel
},
311 {R600::OpName::src1
, R600::OpName::src1_sel
},
312 {R600::OpName::src2
, R600::OpName::src2_sel
},
315 for (unsigned j
= 0; j
< 3; j
++) {
316 int SrcIdx
= getOperandIdx(MI
.getOpcode(), OpTable
[j
][0]);
319 MachineOperand
&MO
= MI
.getOperand(SrcIdx
);
320 unsigned Reg
= MO
.getReg();
321 if (Reg
== R600::ALU_CONST
) {
322 MachineOperand
&Sel
=
323 MI
.getOperand(getOperandIdx(MI
.getOpcode(), OpTable
[j
][1]));
324 Result
.push_back(std::make_pair(&MO
, Sel
.getImm()));
327 if (Reg
== R600::ALU_LITERAL_X
) {
328 MachineOperand
&Operand
=
329 MI
.getOperand(getOperandIdx(MI
.getOpcode(), R600::OpName::literal
));
330 if (Operand
.isImm()) {
331 Result
.push_back(std::make_pair(&MO
, Operand
.getImm()));
334 assert(Operand
.isGlobal());
336 Result
.push_back(std::make_pair(&MO
, 0));
341 std::vector
<std::pair
<int, unsigned>>
342 R600InstrInfo::ExtractSrcs(MachineInstr
&MI
,
343 const DenseMap
<unsigned, unsigned> &PV
,
344 unsigned &ConstCount
) const {
346 const std::pair
<int, unsigned> DummyPair(-1, 0);
347 std::vector
<std::pair
<int, unsigned>> Result
;
349 for (const auto &Src
: getSrcs(MI
)) {
351 unsigned Reg
= Src
.first
->getReg();
352 int Index
= RI
.getEncodingValue(Reg
) & 0xff;
353 if (Reg
== R600::OQAP
) {
354 Result
.push_back(std::make_pair(Index
, 0U));
356 if (PV
.find(Reg
) != PV
.end()) {
357 // 255 is used to tells its a PS/PV reg
358 Result
.push_back(std::make_pair(255, 0U));
363 Result
.push_back(DummyPair
);
366 unsigned Chan
= RI
.getHWRegChan(Reg
);
367 Result
.push_back(std::make_pair(Index
, Chan
));
370 Result
.push_back(DummyPair
);
374 static std::vector
<std::pair
<int, unsigned>>
375 Swizzle(std::vector
<std::pair
<int, unsigned>> Src
,
376 R600InstrInfo::BankSwizzle Swz
) {
377 if (Src
[0] == Src
[1])
380 case R600InstrInfo::ALU_VEC_012_SCL_210
:
382 case R600InstrInfo::ALU_VEC_021_SCL_122
:
383 std::swap(Src
[1], Src
[2]);
385 case R600InstrInfo::ALU_VEC_102_SCL_221
:
386 std::swap(Src
[0], Src
[1]);
388 case R600InstrInfo::ALU_VEC_120_SCL_212
:
389 std::swap(Src
[0], Src
[1]);
390 std::swap(Src
[0], Src
[2]);
392 case R600InstrInfo::ALU_VEC_201
:
393 std::swap(Src
[0], Src
[2]);
394 std::swap(Src
[0], Src
[1]);
396 case R600InstrInfo::ALU_VEC_210
:
397 std::swap(Src
[0], Src
[2]);
403 static unsigned getTransSwizzle(R600InstrInfo::BankSwizzle Swz
, unsigned Op
) {
404 assert(Op
< 3 && "Out of range swizzle index");
406 case R600InstrInfo::ALU_VEC_012_SCL_210
: {
407 unsigned Cycles
[3] = { 2, 1, 0};
410 case R600InstrInfo::ALU_VEC_021_SCL_122
: {
411 unsigned Cycles
[3] = { 1, 2, 2};
414 case R600InstrInfo::ALU_VEC_120_SCL_212
: {
415 unsigned Cycles
[3] = { 2, 1, 2};
418 case R600InstrInfo::ALU_VEC_102_SCL_221
: {
419 unsigned Cycles
[3] = { 2, 2, 1};
423 llvm_unreachable("Wrong Swizzle for Trans Slot");
427 /// returns how many MIs (whose inputs are represented by IGSrcs) can be packed
428 /// in the same Instruction Group while meeting read port limitations given a
429 /// Swz swizzle sequence.
430 unsigned R600InstrInfo::isLegalUpTo(
431 const std::vector
<std::vector
<std::pair
<int, unsigned>>> &IGSrcs
,
432 const std::vector
<R600InstrInfo::BankSwizzle
> &Swz
,
433 const std::vector
<std::pair
<int, unsigned>> &TransSrcs
,
434 R600InstrInfo::BankSwizzle TransSwz
) const {
436 memset(Vector
, -1, sizeof(Vector
));
437 for (unsigned i
= 0, e
= IGSrcs
.size(); i
< e
; i
++) {
438 const std::vector
<std::pair
<int, unsigned>> &Srcs
=
439 Swizzle(IGSrcs
[i
], Swz
[i
]);
440 for (unsigned j
= 0; j
< 3; j
++) {
441 const std::pair
<int, unsigned> &Src
= Srcs
[j
];
442 if (Src
.first
< 0 || Src
.first
== 255)
444 if (Src
.first
== GET_REG_INDEX(RI
.getEncodingValue(R600::OQAP
))) {
445 if (Swz
[i
] != R600InstrInfo::ALU_VEC_012_SCL_210
&&
446 Swz
[i
] != R600InstrInfo::ALU_VEC_021_SCL_122
) {
447 // The value from output queue A (denoted by register OQAP) can
448 // only be fetched during the first cycle.
451 // OQAP does not count towards the normal read port restrictions
454 if (Vector
[Src
.second
][j
] < 0)
455 Vector
[Src
.second
][j
] = Src
.first
;
456 if (Vector
[Src
.second
][j
] != Src
.first
)
460 // Now check Trans Alu
461 for (unsigned i
= 0, e
= TransSrcs
.size(); i
< e
; ++i
) {
462 const std::pair
<int, unsigned> &Src
= TransSrcs
[i
];
463 unsigned Cycle
= getTransSwizzle(TransSwz
, i
);
466 if (Src
.first
== 255)
468 if (Vector
[Src
.second
][Cycle
] < 0)
469 Vector
[Src
.second
][Cycle
] = Src
.first
;
470 if (Vector
[Src
.second
][Cycle
] != Src
.first
)
471 return IGSrcs
.size() - 1;
473 return IGSrcs
.size();
476 /// Given a swizzle sequence SwzCandidate and an index Idx, returns the next
477 /// (in lexicographic term) swizzle sequence assuming that all swizzles after
478 /// Idx can be skipped
480 NextPossibleSolution(
481 std::vector
<R600InstrInfo::BankSwizzle
> &SwzCandidate
,
483 assert(Idx
< SwzCandidate
.size());
485 while (ResetIdx
> -1 && SwzCandidate
[ResetIdx
] == R600InstrInfo::ALU_VEC_210
)
487 for (unsigned i
= ResetIdx
+ 1, e
= SwzCandidate
.size(); i
< e
; i
++) {
488 SwzCandidate
[i
] = R600InstrInfo::ALU_VEC_012_SCL_210
;
492 int NextSwizzle
= SwzCandidate
[ResetIdx
] + 1;
493 SwzCandidate
[ResetIdx
] = (R600InstrInfo::BankSwizzle
)NextSwizzle
;
497 /// Enumerate all possible Swizzle sequence to find one that can meet all
498 /// read port requirements.
499 bool R600InstrInfo::FindSwizzleForVectorSlot(
500 const std::vector
<std::vector
<std::pair
<int, unsigned>>> &IGSrcs
,
501 std::vector
<R600InstrInfo::BankSwizzle
> &SwzCandidate
,
502 const std::vector
<std::pair
<int, unsigned>> &TransSrcs
,
503 R600InstrInfo::BankSwizzle TransSwz
) const {
504 unsigned ValidUpTo
= 0;
506 ValidUpTo
= isLegalUpTo(IGSrcs
, SwzCandidate
, TransSrcs
, TransSwz
);
507 if (ValidUpTo
== IGSrcs
.size())
509 } while (NextPossibleSolution(SwzCandidate
, ValidUpTo
));
513 /// Instructions in Trans slot can't read gpr at cycle 0 if they also read
514 /// a const, and can't read a gpr at cycle 1 if they read 2 const.
516 isConstCompatible(R600InstrInfo::BankSwizzle TransSwz
,
517 const std::vector
<std::pair
<int, unsigned>> &TransOps
,
518 unsigned ConstCount
) {
519 // TransALU can't read 3 constants
522 for (unsigned i
= 0, e
= TransOps
.size(); i
< e
; ++i
) {
523 const std::pair
<int, unsigned> &Src
= TransOps
[i
];
524 unsigned Cycle
= getTransSwizzle(TransSwz
, i
);
527 if (ConstCount
> 0 && Cycle
== 0)
529 if (ConstCount
> 1 && Cycle
== 1)
536 R600InstrInfo::fitsReadPortLimitations(const std::vector
<MachineInstr
*> &IG
,
537 const DenseMap
<unsigned, unsigned> &PV
,
538 std::vector
<BankSwizzle
> &ValidSwizzle
,
541 //Todo : support shared src0 - src1 operand
543 std::vector
<std::vector
<std::pair
<int, unsigned>>> IGSrcs
;
544 ValidSwizzle
.clear();
546 BankSwizzle TransBS
= ALU_VEC_012_SCL_210
;
547 for (unsigned i
= 0, e
= IG
.size(); i
< e
; ++i
) {
548 IGSrcs
.push_back(ExtractSrcs(*IG
[i
], PV
, ConstCount
));
549 unsigned Op
= getOperandIdx(IG
[i
]->getOpcode(),
550 R600::OpName::bank_swizzle
);
551 ValidSwizzle
.push_back( (R600InstrInfo::BankSwizzle
)
552 IG
[i
]->getOperand(Op
).getImm());
554 std::vector
<std::pair
<int, unsigned>> TransOps
;
556 return FindSwizzleForVectorSlot(IGSrcs
, ValidSwizzle
, TransOps
, TransBS
);
558 TransOps
= std::move(IGSrcs
.back());
560 ValidSwizzle
.pop_back();
562 static const R600InstrInfo::BankSwizzle TransSwz
[] = {
568 for (unsigned i
= 0; i
< 4; i
++) {
569 TransBS
= TransSwz
[i
];
570 if (!isConstCompatible(TransBS
, TransOps
, ConstCount
))
572 bool Result
= FindSwizzleForVectorSlot(IGSrcs
, ValidSwizzle
, TransOps
,
575 ValidSwizzle
.push_back(TransBS
);
584 R600InstrInfo::fitsConstReadLimitations(const std::vector
<unsigned> &Consts
)
586 assert (Consts
.size() <= 12 && "Too many operands in instructions group");
587 unsigned Pair1
= 0, Pair2
= 0;
588 for (unsigned i
= 0, n
= Consts
.size(); i
< n
; ++i
) {
589 unsigned ReadConstHalf
= Consts
[i
] & 2;
590 unsigned ReadConstIndex
= Consts
[i
] & (~3);
591 unsigned ReadHalfConst
= ReadConstIndex
| ReadConstHalf
;
593 Pair1
= ReadHalfConst
;
596 if (Pair1
== ReadHalfConst
)
599 Pair2
= ReadHalfConst
;
602 if (Pair2
!= ReadHalfConst
)
609 R600InstrInfo::fitsConstReadLimitations(const std::vector
<MachineInstr
*> &MIs
)
611 std::vector
<unsigned> Consts
;
612 SmallSet
<int64_t, 4> Literals
;
613 for (unsigned i
= 0, n
= MIs
.size(); i
< n
; i
++) {
614 MachineInstr
&MI
= *MIs
[i
];
615 if (!isALUInstr(MI
.getOpcode()))
618 for (const auto &Src
: getSrcs(MI
)) {
619 if (Src
.first
->getReg() == R600::ALU_LITERAL_X
)
620 Literals
.insert(Src
.second
);
621 if (Literals
.size() > 4)
623 if (Src
.first
->getReg() == R600::ALU_CONST
)
624 Consts
.push_back(Src
.second
);
625 if (R600::R600_KC0RegClass
.contains(Src
.first
->getReg()) ||
626 R600::R600_KC1RegClass
.contains(Src
.first
->getReg())) {
627 unsigned Index
= RI
.getEncodingValue(Src
.first
->getReg()) & 0xff;
628 unsigned Chan
= RI
.getHWRegChan(Src
.first
->getReg());
629 Consts
.push_back((Index
<< 2) | Chan
);
633 return fitsConstReadLimitations(Consts
);
637 R600InstrInfo::CreateTargetScheduleState(const TargetSubtargetInfo
&STI
) const {
638 const InstrItineraryData
*II
= STI
.getInstrItineraryData();
639 return static_cast<const R600Subtarget
&>(STI
).createDFAPacketizer(II
);
643 isPredicateSetter(unsigned Opcode
) {
652 static MachineInstr
*
653 findFirstPredicateSetterFrom(MachineBasicBlock
&MBB
,
654 MachineBasicBlock::iterator I
) {
655 while (I
!= MBB
.begin()) {
657 MachineInstr
&MI
= *I
;
658 if (isPredicateSetter(MI
.getOpcode()))
666 bool isJump(unsigned Opcode
) {
667 return Opcode
== R600::JUMP
|| Opcode
== R600::JUMP_COND
;
670 static bool isBranch(unsigned Opcode
) {
671 return Opcode
== R600::BRANCH
|| Opcode
== R600::BRANCH_COND_i32
||
672 Opcode
== R600::BRANCH_COND_f32
;
675 bool R600InstrInfo::analyzeBranch(MachineBasicBlock
&MBB
,
676 MachineBasicBlock
*&TBB
,
677 MachineBasicBlock
*&FBB
,
678 SmallVectorImpl
<MachineOperand
> &Cond
,
679 bool AllowModify
) const {
680 // Most of the following comes from the ARM implementation of AnalyzeBranch
682 // If the block has no terminators, it just falls into the block after it.
683 MachineBasicBlock::iterator I
= MBB
.getLastNonDebugInstr();
687 // R600::BRANCH* instructions are only available after isel and are not
689 if (isBranch(I
->getOpcode()))
691 if (!isJump(I
->getOpcode())) {
695 // Remove successive JUMP
696 while (I
!= MBB
.begin() && std::prev(I
)->getOpcode() == R600::JUMP
) {
697 MachineBasicBlock::iterator PriorI
= std::prev(I
);
699 I
->removeFromParent();
702 MachineInstr
&LastInst
= *I
;
704 // If there is only one terminator instruction, process it.
705 unsigned LastOpc
= LastInst
.getOpcode();
706 if (I
== MBB
.begin() || !isJump((--I
)->getOpcode())) {
707 if (LastOpc
== R600::JUMP
) {
708 TBB
= LastInst
.getOperand(0).getMBB();
710 } else if (LastOpc
== R600::JUMP_COND
) {
712 while (!isPredicateSetter(predSet
->getOpcode())) {
715 TBB
= LastInst
.getOperand(0).getMBB();
716 Cond
.push_back(predSet
->getOperand(1));
717 Cond
.push_back(predSet
->getOperand(2));
718 Cond
.push_back(MachineOperand::CreateReg(R600::PRED_SEL_ONE
, false));
721 return true; // Can't handle indirect branch.
724 // Get the instruction before it if it is a terminator.
725 MachineInstr
&SecondLastInst
= *I
;
726 unsigned SecondLastOpc
= SecondLastInst
.getOpcode();
728 // If the block ends with a B and a Bcc, handle it.
729 if (SecondLastOpc
== R600::JUMP_COND
&& LastOpc
== R600::JUMP
) {
731 while (!isPredicateSetter(predSet
->getOpcode())) {
734 TBB
= SecondLastInst
.getOperand(0).getMBB();
735 FBB
= LastInst
.getOperand(0).getMBB();
736 Cond
.push_back(predSet
->getOperand(1));
737 Cond
.push_back(predSet
->getOperand(2));
738 Cond
.push_back(MachineOperand::CreateReg(R600::PRED_SEL_ONE
, false));
742 // Otherwise, can't handle this.
747 MachineBasicBlock::iterator
FindLastAluClause(MachineBasicBlock
&MBB
) {
748 for (MachineBasicBlock::reverse_iterator It
= MBB
.rbegin(), E
= MBB
.rend();
750 if (It
->getOpcode() == R600::CF_ALU
||
751 It
->getOpcode() == R600::CF_ALU_PUSH_BEFORE
)
752 return It
.getReverse();
757 unsigned R600InstrInfo::insertBranch(MachineBasicBlock
&MBB
,
758 MachineBasicBlock
*TBB
,
759 MachineBasicBlock
*FBB
,
760 ArrayRef
<MachineOperand
> Cond
,
762 int *BytesAdded
) const {
763 assert(TBB
&& "insertBranch must not be told to insert a fallthrough");
764 assert(!BytesAdded
&& "code size not handled");
768 BuildMI(&MBB
, DL
, get(R600::JUMP
)).addMBB(TBB
);
771 MachineInstr
*PredSet
= findFirstPredicateSetterFrom(MBB
, MBB
.end());
772 assert(PredSet
&& "No previous predicate !");
773 addFlag(*PredSet
, 0, MO_FLAG_PUSH
);
774 PredSet
->getOperand(2).setImm(Cond
[1].getImm());
776 BuildMI(&MBB
, DL
, get(R600::JUMP_COND
))
778 .addReg(R600::PREDICATE_BIT
, RegState::Kill
);
779 MachineBasicBlock::iterator CfAlu
= FindLastAluClause(MBB
);
780 if (CfAlu
== MBB
.end())
782 assert (CfAlu
->getOpcode() == R600::CF_ALU
);
783 CfAlu
->setDesc(get(R600::CF_ALU_PUSH_BEFORE
));
787 MachineInstr
*PredSet
= findFirstPredicateSetterFrom(MBB
, MBB
.end());
788 assert(PredSet
&& "No previous predicate !");
789 addFlag(*PredSet
, 0, MO_FLAG_PUSH
);
790 PredSet
->getOperand(2).setImm(Cond
[1].getImm());
791 BuildMI(&MBB
, DL
, get(R600::JUMP_COND
))
793 .addReg(R600::PREDICATE_BIT
, RegState::Kill
);
794 BuildMI(&MBB
, DL
, get(R600::JUMP
)).addMBB(FBB
);
795 MachineBasicBlock::iterator CfAlu
= FindLastAluClause(MBB
);
796 if (CfAlu
== MBB
.end())
798 assert (CfAlu
->getOpcode() == R600::CF_ALU
);
799 CfAlu
->setDesc(get(R600::CF_ALU_PUSH_BEFORE
));
804 unsigned R600InstrInfo::removeBranch(MachineBasicBlock
&MBB
,
805 int *BytesRemoved
) const {
806 assert(!BytesRemoved
&& "code size not handled");
808 // Note : we leave PRED* instructions there.
809 // They may be needed when predicating instructions.
811 MachineBasicBlock::iterator I
= MBB
.end();
813 if (I
== MBB
.begin()) {
817 switch (I
->getOpcode()) {
820 case R600::JUMP_COND
: {
821 MachineInstr
*predSet
= findFirstPredicateSetterFrom(MBB
, I
);
822 clearFlag(*predSet
, 0, MO_FLAG_PUSH
);
823 I
->eraseFromParent();
824 MachineBasicBlock::iterator CfAlu
= FindLastAluClause(MBB
);
825 if (CfAlu
== MBB
.end())
827 assert (CfAlu
->getOpcode() == R600::CF_ALU_PUSH_BEFORE
);
828 CfAlu
->setDesc(get(R600::CF_ALU
));
832 I
->eraseFromParent();
837 if (I
== MBB
.begin()) {
841 switch (I
->getOpcode()) {
842 // FIXME: only one case??
845 case R600::JUMP_COND
: {
846 MachineInstr
*predSet
= findFirstPredicateSetterFrom(MBB
, I
);
847 clearFlag(*predSet
, 0, MO_FLAG_PUSH
);
848 I
->eraseFromParent();
849 MachineBasicBlock::iterator CfAlu
= FindLastAluClause(MBB
);
850 if (CfAlu
== MBB
.end())
852 assert (CfAlu
->getOpcode() == R600::CF_ALU_PUSH_BEFORE
);
853 CfAlu
->setDesc(get(R600::CF_ALU
));
857 I
->eraseFromParent();
863 bool R600InstrInfo::isPredicated(const MachineInstr
&MI
) const {
864 int idx
= MI
.findFirstPredOperandIdx();
868 unsigned Reg
= MI
.getOperand(idx
).getReg();
870 default: return false;
871 case R600::PRED_SEL_ONE
:
872 case R600::PRED_SEL_ZERO
:
873 case R600::PREDICATE_BIT
:
878 bool R600InstrInfo::isPredicable(const MachineInstr
&MI
) const {
879 // XXX: KILL* instructions can be predicated, but they must be the last
880 // instruction in a clause, so this means any instructions after them cannot
881 // be predicated. Until we have proper support for instruction clauses in the
882 // backend, we will mark KILL* instructions as unpredicable.
884 if (MI
.getOpcode() == R600::KILLGT
) {
886 } else if (MI
.getOpcode() == R600::CF_ALU
) {
887 // If the clause start in the middle of MBB then the MBB has more
888 // than a single clause, unable to predicate several clauses.
889 if (MI
.getParent()->begin() != MachineBasicBlock::const_iterator(MI
))
891 // TODO: We don't support KC merging atm
892 return MI
.getOperand(3).getImm() == 0 && MI
.getOperand(4).getImm() == 0;
893 } else if (isVector(MI
)) {
896 return TargetInstrInfo::isPredicable(MI
);
901 R600InstrInfo::isProfitableToIfCvt(MachineBasicBlock
&MBB
,
903 unsigned ExtraPredCycles
,
904 BranchProbability Probability
) const{
909 R600InstrInfo::isProfitableToIfCvt(MachineBasicBlock
&TMBB
,
911 unsigned ExtraTCycles
,
912 MachineBasicBlock
&FMBB
,
914 unsigned ExtraFCycles
,
915 BranchProbability Probability
) const {
920 R600InstrInfo::isProfitableToDupForIfCvt(MachineBasicBlock
&MBB
,
922 BranchProbability Probability
)
928 R600InstrInfo::isProfitableToUnpredicate(MachineBasicBlock
&TMBB
,
929 MachineBasicBlock
&FMBB
) const {
934 R600InstrInfo::reverseBranchCondition(SmallVectorImpl
<MachineOperand
> &Cond
) const {
935 MachineOperand
&MO
= Cond
[1];
936 switch (MO
.getImm()) {
937 case R600::PRED_SETE_INT
:
938 MO
.setImm(R600::PRED_SETNE_INT
);
940 case R600::PRED_SETNE_INT
:
941 MO
.setImm(R600::PRED_SETE_INT
);
943 case R600::PRED_SETE
:
944 MO
.setImm(R600::PRED_SETNE
);
946 case R600::PRED_SETNE
:
947 MO
.setImm(R600::PRED_SETE
);
953 MachineOperand
&MO2
= Cond
[2];
954 switch (MO2
.getReg()) {
955 case R600::PRED_SEL_ZERO
:
956 MO2
.setReg(R600::PRED_SEL_ONE
);
958 case R600::PRED_SEL_ONE
:
959 MO2
.setReg(R600::PRED_SEL_ZERO
);
967 bool R600InstrInfo::DefinesPredicate(MachineInstr
&MI
,
968 std::vector
<MachineOperand
> &Pred
) const {
969 return isPredicateSetter(MI
.getOpcode());
972 bool R600InstrInfo::PredicateInstruction(MachineInstr
&MI
,
973 ArrayRef
<MachineOperand
> Pred
) const {
974 int PIdx
= MI
.findFirstPredOperandIdx();
976 if (MI
.getOpcode() == R600::CF_ALU
) {
977 MI
.getOperand(8).setImm(0);
981 if (MI
.getOpcode() == R600::DOT_4
) {
982 MI
.getOperand(getOperandIdx(MI
, R600::OpName::pred_sel_X
))
983 .setReg(Pred
[2].getReg());
984 MI
.getOperand(getOperandIdx(MI
, R600::OpName::pred_sel_Y
))
985 .setReg(Pred
[2].getReg());
986 MI
.getOperand(getOperandIdx(MI
, R600::OpName::pred_sel_Z
))
987 .setReg(Pred
[2].getReg());
988 MI
.getOperand(getOperandIdx(MI
, R600::OpName::pred_sel_W
))
989 .setReg(Pred
[2].getReg());
990 MachineInstrBuilder
MIB(*MI
.getParent()->getParent(), MI
);
991 MIB
.addReg(R600::PREDICATE_BIT
, RegState::Implicit
);
996 MachineOperand
&PMO
= MI
.getOperand(PIdx
);
997 PMO
.setReg(Pred
[2].getReg());
998 MachineInstrBuilder
MIB(*MI
.getParent()->getParent(), MI
);
999 MIB
.addReg(R600::PREDICATE_BIT
, RegState::Implicit
);
1006 unsigned int R600InstrInfo::getPredicationCost(const MachineInstr
&) const {
1010 unsigned int R600InstrInfo::getInstrLatency(const InstrItineraryData
*ItinData
,
1011 const MachineInstr
&,
1012 unsigned *PredCost
) const {
1018 unsigned R600InstrInfo::calculateIndirectAddress(unsigned RegIndex
,
1019 unsigned Channel
) const {
1020 assert(Channel
== 0);
1024 bool R600InstrInfo::expandPostRAPseudo(MachineInstr
&MI
) const {
1025 switch (MI
.getOpcode()) {
1027 MachineBasicBlock
*MBB
= MI
.getParent();
1029 R600::getNamedOperandIdx(MI
.getOpcode(), R600::OpName::addr
);
1030 // addr is a custom operand with multiple MI operands, and only the
1031 // first MI operand is given a name.
1032 int RegOpIdx
= OffsetOpIdx
+ 1;
1034 R600::getNamedOperandIdx(MI
.getOpcode(), R600::OpName::chan
);
1035 if (isRegisterLoad(MI
)) {
1037 R600::getNamedOperandIdx(MI
.getOpcode(), R600::OpName::dst
);
1038 unsigned RegIndex
= MI
.getOperand(RegOpIdx
).getImm();
1039 unsigned Channel
= MI
.getOperand(ChanOpIdx
).getImm();
1040 unsigned Address
= calculateIndirectAddress(RegIndex
, Channel
);
1041 unsigned OffsetReg
= MI
.getOperand(OffsetOpIdx
).getReg();
1042 if (OffsetReg
== R600::INDIRECT_BASE_ADDR
) {
1043 buildMovInstr(MBB
, MI
, MI
.getOperand(DstOpIdx
).getReg(),
1044 getIndirectAddrRegClass()->getRegister(Address
));
1046 buildIndirectRead(MBB
, MI
, MI
.getOperand(DstOpIdx
).getReg(), Address
,
1049 } else if (isRegisterStore(MI
)) {
1051 R600::getNamedOperandIdx(MI
.getOpcode(), R600::OpName::val
);
1052 unsigned RegIndex
= MI
.getOperand(RegOpIdx
).getImm();
1053 unsigned Channel
= MI
.getOperand(ChanOpIdx
).getImm();
1054 unsigned Address
= calculateIndirectAddress(RegIndex
, Channel
);
1055 unsigned OffsetReg
= MI
.getOperand(OffsetOpIdx
).getReg();
1056 if (OffsetReg
== R600::INDIRECT_BASE_ADDR
) {
1057 buildMovInstr(MBB
, MI
, getIndirectAddrRegClass()->getRegister(Address
),
1058 MI
.getOperand(ValOpIdx
).getReg());
1060 buildIndirectWrite(MBB
, MI
, MI
.getOperand(ValOpIdx
).getReg(),
1061 calculateIndirectAddress(RegIndex
, Channel
),
1071 case R600::R600_EXTRACT_ELT_V2
:
1072 case R600::R600_EXTRACT_ELT_V4
:
1073 buildIndirectRead(MI
.getParent(), MI
, MI
.getOperand(0).getReg(),
1074 RI
.getHWRegIndex(MI
.getOperand(1).getReg()), // Address
1075 MI
.getOperand(2).getReg(),
1076 RI
.getHWRegChan(MI
.getOperand(1).getReg()));
1078 case R600::R600_INSERT_ELT_V2
:
1079 case R600::R600_INSERT_ELT_V4
:
1080 buildIndirectWrite(MI
.getParent(), MI
, MI
.getOperand(2).getReg(), // Value
1081 RI
.getHWRegIndex(MI
.getOperand(1).getReg()), // Address
1082 MI
.getOperand(3).getReg(), // Offset
1083 RI
.getHWRegChan(MI
.getOperand(1).getReg())); // Channel
1086 MI
.eraseFromParent();
1090 void R600InstrInfo::reserveIndirectRegisters(BitVector
&Reserved
,
1091 const MachineFunction
&MF
,
1092 const R600RegisterInfo
&TRI
) const {
1093 const R600Subtarget
&ST
= MF
.getSubtarget
<R600Subtarget
>();
1094 const R600FrameLowering
*TFL
= ST
.getFrameLowering();
1096 unsigned StackWidth
= TFL
->getStackWidth(MF
);
1097 int End
= getIndirectIndexEnd(MF
);
1102 for (int Index
= getIndirectIndexBegin(MF
); Index
<= End
; ++Index
) {
1103 for (unsigned Chan
= 0; Chan
< StackWidth
; ++Chan
) {
1104 unsigned Reg
= R600::R600_TReg32RegClass
.getRegister((4 * Index
) + Chan
);
1105 TRI
.reserveRegisterTuples(Reserved
, Reg
);
1110 const TargetRegisterClass
*R600InstrInfo::getIndirectAddrRegClass() const {
1111 return &R600::R600_TReg32_XRegClass
;
1114 MachineInstrBuilder
R600InstrInfo::buildIndirectWrite(MachineBasicBlock
*MBB
,
1115 MachineBasicBlock::iterator I
,
1116 unsigned ValueReg
, unsigned Address
,
1117 unsigned OffsetReg
) const {
1118 return buildIndirectWrite(MBB
, I
, ValueReg
, Address
, OffsetReg
, 0);
1121 MachineInstrBuilder
R600InstrInfo::buildIndirectWrite(MachineBasicBlock
*MBB
,
1122 MachineBasicBlock::iterator I
,
1123 unsigned ValueReg
, unsigned Address
,
1125 unsigned AddrChan
) const {
1128 default: llvm_unreachable("Invalid Channel");
1129 case 0: AddrReg
= R600::R600_AddrRegClass
.getRegister(Address
); break;
1130 case 1: AddrReg
= R600::R600_Addr_YRegClass
.getRegister(Address
); break;
1131 case 2: AddrReg
= R600::R600_Addr_ZRegClass
.getRegister(Address
); break;
1132 case 3: AddrReg
= R600::R600_Addr_WRegClass
.getRegister(Address
); break;
1134 MachineInstr
*MOVA
= buildDefaultInstruction(*MBB
, I
, R600::MOVA_INT_eg
,
1135 R600::AR_X
, OffsetReg
);
1136 setImmOperand(*MOVA
, R600::OpName::write
, 0);
1138 MachineInstrBuilder Mov
= buildDefaultInstruction(*MBB
, I
, R600::MOV
,
1141 RegState::Implicit
| RegState::Kill
);
1142 setImmOperand(*Mov
, R600::OpName::dst_rel
, 1);
1146 MachineInstrBuilder
R600InstrInfo::buildIndirectRead(MachineBasicBlock
*MBB
,
1147 MachineBasicBlock::iterator I
,
1148 unsigned ValueReg
, unsigned Address
,
1149 unsigned OffsetReg
) const {
1150 return buildIndirectRead(MBB
, I
, ValueReg
, Address
, OffsetReg
, 0);
1153 MachineInstrBuilder
R600InstrInfo::buildIndirectRead(MachineBasicBlock
*MBB
,
1154 MachineBasicBlock::iterator I
,
1155 unsigned ValueReg
, unsigned Address
,
1157 unsigned AddrChan
) const {
1160 default: llvm_unreachable("Invalid Channel");
1161 case 0: AddrReg
= R600::R600_AddrRegClass
.getRegister(Address
); break;
1162 case 1: AddrReg
= R600::R600_Addr_YRegClass
.getRegister(Address
); break;
1163 case 2: AddrReg
= R600::R600_Addr_ZRegClass
.getRegister(Address
); break;
1164 case 3: AddrReg
= R600::R600_Addr_WRegClass
.getRegister(Address
); break;
1166 MachineInstr
*MOVA
= buildDefaultInstruction(*MBB
, I
, R600::MOVA_INT_eg
,
1169 setImmOperand(*MOVA
, R600::OpName::write
, 0);
1170 MachineInstrBuilder Mov
= buildDefaultInstruction(*MBB
, I
, R600::MOV
,
1174 RegState::Implicit
| RegState::Kill
);
1175 setImmOperand(*Mov
, R600::OpName::src0_rel
, 1);
1180 int R600InstrInfo::getIndirectIndexBegin(const MachineFunction
&MF
) const {
1181 const MachineRegisterInfo
&MRI
= MF
.getRegInfo();
1182 const MachineFrameInfo
&MFI
= MF
.getFrameInfo();
1185 if (MFI
.getNumObjects() == 0) {
1189 if (MRI
.livein_empty()) {
1193 const TargetRegisterClass
*IndirectRC
= getIndirectAddrRegClass();
1194 for (std::pair
<unsigned, unsigned> LI
: MRI
.liveins()) {
1195 unsigned Reg
= LI
.first
;
1196 if (TargetRegisterInfo::isVirtualRegister(Reg
) ||
1197 !IndirectRC
->contains(Reg
))
1202 for (RegIndex
= 0, RegEnd
= IndirectRC
->getNumRegs(); RegIndex
!= RegEnd
;
1204 if (IndirectRC
->getRegister(RegIndex
) == Reg
)
1207 Offset
= std::max(Offset
, (int)RegIndex
);
1213 int R600InstrInfo::getIndirectIndexEnd(const MachineFunction
&MF
) const {
1215 const MachineFrameInfo
&MFI
= MF
.getFrameInfo();
1217 // Variable sized objects are not supported
1218 if (MFI
.hasVarSizedObjects()) {
1222 if (MFI
.getNumObjects() == 0) {
1226 const R600Subtarget
&ST
= MF
.getSubtarget
<R600Subtarget
>();
1227 const R600FrameLowering
*TFL
= ST
.getFrameLowering();
1229 unsigned IgnoredFrameReg
;
1230 Offset
= TFL
->getFrameIndexReference(MF
, -1, IgnoredFrameReg
);
1232 return getIndirectIndexBegin(MF
) + Offset
;
1235 unsigned R600InstrInfo::getMaxAlusPerClause() const {
1239 MachineInstrBuilder
R600InstrInfo::buildDefaultInstruction(MachineBasicBlock
&MBB
,
1240 MachineBasicBlock::iterator I
,
1244 unsigned Src1Reg
) const {
1245 MachineInstrBuilder MIB
= BuildMI(MBB
, I
, MBB
.findDebugLoc(I
), get(Opcode
),
1249 MIB
.addImm(0) // $update_exec_mask
1250 .addImm(0); // $update_predicate
1252 MIB
.addImm(1) // $write
1254 .addImm(0) // $dst_rel
1255 .addImm(0) // $dst_clamp
1256 .addReg(Src0Reg
) // $src0
1257 .addImm(0) // $src0_neg
1258 .addImm(0) // $src0_rel
1259 .addImm(0) // $src0_abs
1260 .addImm(-1); // $src0_sel
1263 MIB
.addReg(Src1Reg
) // $src1
1264 .addImm(0) // $src1_neg
1265 .addImm(0) // $src1_rel
1266 .addImm(0) // $src1_abs
1267 .addImm(-1); // $src1_sel
1270 //XXX: The r600g finalizer expects this to be 1, once we've moved the
1271 //scheduling to the backend, we can change the default to 0.
1272 MIB
.addImm(1) // $last
1273 .addReg(R600::PRED_SEL_OFF
) // $pred_sel
1274 .addImm(0) // $literal
1275 .addImm(0); // $bank_swizzle
1280 #define OPERAND_CASE(Label) \
1282 static const unsigned Ops[] = \
1292 static unsigned getSlotedOps(unsigned Op
, unsigned Slot
) {
1294 OPERAND_CASE(R600::OpName::update_exec_mask
)
1295 OPERAND_CASE(R600::OpName::update_pred
)
1296 OPERAND_CASE(R600::OpName::write
)
1297 OPERAND_CASE(R600::OpName::omod
)
1298 OPERAND_CASE(R600::OpName::dst_rel
)
1299 OPERAND_CASE(R600::OpName::clamp
)
1300 OPERAND_CASE(R600::OpName::src0
)
1301 OPERAND_CASE(R600::OpName::src0_neg
)
1302 OPERAND_CASE(R600::OpName::src0_rel
)
1303 OPERAND_CASE(R600::OpName::src0_abs
)
1304 OPERAND_CASE(R600::OpName::src0_sel
)
1305 OPERAND_CASE(R600::OpName::src1
)
1306 OPERAND_CASE(R600::OpName::src1_neg
)
1307 OPERAND_CASE(R600::OpName::src1_rel
)
1308 OPERAND_CASE(R600::OpName::src1_abs
)
1309 OPERAND_CASE(R600::OpName::src1_sel
)
1310 OPERAND_CASE(R600::OpName::pred_sel
)
1312 llvm_unreachable("Wrong Operand");
1318 MachineInstr
*R600InstrInfo::buildSlotOfVectorInstruction(
1319 MachineBasicBlock
&MBB
, MachineInstr
*MI
, unsigned Slot
, unsigned DstReg
)
1321 assert (MI
->getOpcode() == R600::DOT_4
&& "Not Implemented");
1323 if (ST
.getGeneration() <= AMDGPUSubtarget::R700
)
1324 Opcode
= R600::DOT4_r600
;
1326 Opcode
= R600::DOT4_eg
;
1327 MachineBasicBlock::iterator I
= MI
;
1328 MachineOperand
&Src0
= MI
->getOperand(
1329 getOperandIdx(MI
->getOpcode(), getSlotedOps(R600::OpName::src0
, Slot
)));
1330 MachineOperand
&Src1
= MI
->getOperand(
1331 getOperandIdx(MI
->getOpcode(), getSlotedOps(R600::OpName::src1
, Slot
)));
1332 MachineInstr
*MIB
= buildDefaultInstruction(
1333 MBB
, I
, Opcode
, DstReg
, Src0
.getReg(), Src1
.getReg());
1334 static const unsigned Operands
[14] = {
1335 R600::OpName::update_exec_mask
,
1336 R600::OpName::update_pred
,
1337 R600::OpName::write
,
1339 R600::OpName::dst_rel
,
1340 R600::OpName::clamp
,
1341 R600::OpName::src0_neg
,
1342 R600::OpName::src0_rel
,
1343 R600::OpName::src0_abs
,
1344 R600::OpName::src0_sel
,
1345 R600::OpName::src1_neg
,
1346 R600::OpName::src1_rel
,
1347 R600::OpName::src1_abs
,
1348 R600::OpName::src1_sel
,
1351 MachineOperand
&MO
= MI
->getOperand(getOperandIdx(MI
->getOpcode(),
1352 getSlotedOps(R600::OpName::pred_sel
, Slot
)));
1353 MIB
->getOperand(getOperandIdx(Opcode
, R600::OpName::pred_sel
))
1354 .setReg(MO
.getReg());
1356 for (unsigned i
= 0; i
< 14; i
++) {
1357 MachineOperand
&MO
= MI
->getOperand(
1358 getOperandIdx(MI
->getOpcode(), getSlotedOps(Operands
[i
], Slot
)));
1359 assert (MO
.isImm());
1360 setImmOperand(*MIB
, Operands
[i
], MO
.getImm());
1362 MIB
->getOperand(20).setImm(0);
1366 MachineInstr
*R600InstrInfo::buildMovImm(MachineBasicBlock
&BB
,
1367 MachineBasicBlock::iterator I
,
1369 uint64_t Imm
) const {
1370 MachineInstr
*MovImm
= buildDefaultInstruction(BB
, I
, R600::MOV
, DstReg
,
1371 R600::ALU_LITERAL_X
);
1372 setImmOperand(*MovImm
, R600::OpName::literal
, Imm
);
1376 MachineInstr
*R600InstrInfo::buildMovInstr(MachineBasicBlock
*MBB
,
1377 MachineBasicBlock::iterator I
,
1378 unsigned DstReg
, unsigned SrcReg
) const {
1379 return buildDefaultInstruction(*MBB
, I
, R600::MOV
, DstReg
, SrcReg
);
1382 int R600InstrInfo::getOperandIdx(const MachineInstr
&MI
, unsigned Op
) const {
1383 return getOperandIdx(MI
.getOpcode(), Op
);
1386 int R600InstrInfo::getOperandIdx(unsigned Opcode
, unsigned Op
) const {
1387 return R600::getNamedOperandIdx(Opcode
, Op
);
1390 void R600InstrInfo::setImmOperand(MachineInstr
&MI
, unsigned Op
,
1391 int64_t Imm
) const {
1392 int Idx
= getOperandIdx(MI
, Op
);
1393 assert(Idx
!= -1 && "Operand not supported for this instruction.");
1394 assert(MI
.getOperand(Idx
).isImm());
1395 MI
.getOperand(Idx
).setImm(Imm
);
1398 //===----------------------------------------------------------------------===//
1399 // Instruction flag getters/setters
1400 //===----------------------------------------------------------------------===//
1402 MachineOperand
&R600InstrInfo::getFlagOp(MachineInstr
&MI
, unsigned SrcIdx
,
1403 unsigned Flag
) const {
1404 unsigned TargetFlags
= get(MI
.getOpcode()).TSFlags
;
1407 // If we pass something other than the default value of Flag to this
1408 // function, it means we are want to set a flag on an instruction
1409 // that uses native encoding.
1410 assert(HAS_NATIVE_OPERANDS(TargetFlags
));
1411 bool IsOP3
= (TargetFlags
& R600_InstFlag::OP3
) == R600_InstFlag::OP3
;
1414 FlagIndex
= getOperandIdx(MI
, R600::OpName::clamp
);
1417 FlagIndex
= getOperandIdx(MI
, R600::OpName::write
);
1419 case MO_FLAG_NOT_LAST
:
1421 FlagIndex
= getOperandIdx(MI
, R600::OpName::last
);
1426 FlagIndex
= getOperandIdx(MI
, R600::OpName::src0_neg
);
1429 FlagIndex
= getOperandIdx(MI
, R600::OpName::src1_neg
);
1432 FlagIndex
= getOperandIdx(MI
, R600::OpName::src2_neg
);
1438 assert(!IsOP3
&& "Cannot set absolute value modifier for OP3 "
1443 FlagIndex
= getOperandIdx(MI
, R600::OpName::src0_abs
);
1446 FlagIndex
= getOperandIdx(MI
, R600::OpName::src1_abs
);
1455 assert(FlagIndex
!= -1 && "Flag not supported for this instruction");
1457 FlagIndex
= GET_FLAG_OPERAND_IDX(TargetFlags
);
1458 assert(FlagIndex
!= 0 &&
1459 "Instruction flags not supported for this instruction");
1462 MachineOperand
&FlagOp
= MI
.getOperand(FlagIndex
);
1463 assert(FlagOp
.isImm());
1467 void R600InstrInfo::addFlag(MachineInstr
&MI
, unsigned Operand
,
1468 unsigned Flag
) const {
1469 unsigned TargetFlags
= get(MI
.getOpcode()).TSFlags
;
1473 if (HAS_NATIVE_OPERANDS(TargetFlags
)) {
1474 MachineOperand
&FlagOp
= getFlagOp(MI
, Operand
, Flag
);
1475 if (Flag
== MO_FLAG_NOT_LAST
) {
1476 clearFlag(MI
, Operand
, MO_FLAG_LAST
);
1477 } else if (Flag
== MO_FLAG_MASK
) {
1478 clearFlag(MI
, Operand
, Flag
);
1483 MachineOperand
&FlagOp
= getFlagOp(MI
, Operand
);
1484 FlagOp
.setImm(FlagOp
.getImm() | (Flag
<< (NUM_MO_FLAGS
* Operand
)));
1488 void R600InstrInfo::clearFlag(MachineInstr
&MI
, unsigned Operand
,
1489 unsigned Flag
) const {
1490 unsigned TargetFlags
= get(MI
.getOpcode()).TSFlags
;
1491 if (HAS_NATIVE_OPERANDS(TargetFlags
)) {
1492 MachineOperand
&FlagOp
= getFlagOp(MI
, Operand
, Flag
);
1495 MachineOperand
&FlagOp
= getFlagOp(MI
);
1496 unsigned InstFlags
= FlagOp
.getImm();
1497 InstFlags
&= ~(Flag
<< (NUM_MO_FLAGS
* Operand
));
1498 FlagOp
.setImm(InstFlags
);
1502 unsigned R600InstrInfo::getAddressSpaceForPseudoSourceKind(
1503 unsigned Kind
) const {
1505 case PseudoSourceValue::Stack
:
1506 case PseudoSourceValue::FixedStack
:
1507 return AMDGPUAS::PRIVATE_ADDRESS
;
1508 case PseudoSourceValue::ConstantPool
:
1509 case PseudoSourceValue::GOT
:
1510 case PseudoSourceValue::JumpTable
:
1511 case PseudoSourceValue::GlobalValueCallEntry
:
1512 case PseudoSourceValue::ExternalSymbolCallEntry
:
1513 case PseudoSourceValue::TargetCustom
:
1514 return AMDGPUAS::CONSTANT_ADDRESS
;
1517 llvm_unreachable("Invalid pseudo source kind");