1 //===-- SIInstrInfo.cpp - SI Instruction Information ---------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// \brief SI Implementation of TargetInstrInfo.
13 //===----------------------------------------------------------------------===//
16 #include "SIInstrInfo.h"
17 #include "AMDGPUTargetMachine.h"
18 #include "SIDefines.h"
19 #include "llvm/CodeGen/MachineInstrBuilder.h"
20 #include "llvm/CodeGen/MachineRegisterInfo.h"
21 #include "llvm/MC/MCInstrDesc.h"
25 SIInstrInfo::SIInstrInfo(AMDGPUTargetMachine &tm)
26 : AMDGPUInstrInfo(tm),
30 const SIRegisterInfo &SIInstrInfo::getRegisterInfo() const {
35 SIInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
36 MachineBasicBlock::iterator MI, DebugLoc DL,
37 unsigned DestReg, unsigned SrcReg,
40 // If we are trying to copy to or from SCC, there is a bug somewhere else in
41 // the backend. While it may be theoretically possible to do this, it should
42 // never be necessary.
43 assert(DestReg != AMDGPU::SCC && SrcReg != AMDGPU::SCC);
45 static const int16_t Sub0_15[] = {
46 AMDGPU::sub0, AMDGPU::sub1, AMDGPU::sub2, AMDGPU::sub3,
47 AMDGPU::sub4, AMDGPU::sub5, AMDGPU::sub6, AMDGPU::sub7,
48 AMDGPU::sub8, AMDGPU::sub9, AMDGPU::sub10, AMDGPU::sub11,
49 AMDGPU::sub12, AMDGPU::sub13, AMDGPU::sub14, AMDGPU::sub15, 0
52 static const int16_t Sub0_7[] = {
53 AMDGPU::sub0, AMDGPU::sub1, AMDGPU::sub2, AMDGPU::sub3,
54 AMDGPU::sub4, AMDGPU::sub5, AMDGPU::sub6, AMDGPU::sub7, 0
57 static const int16_t Sub0_3[] = {
58 AMDGPU::sub0, AMDGPU::sub1, AMDGPU::sub2, AMDGPU::sub3, 0
61 static const int16_t Sub0_2[] = {
62 AMDGPU::sub0, AMDGPU::sub1, AMDGPU::sub2, 0
65 static const int16_t Sub0_1[] = {
66 AMDGPU::sub0, AMDGPU::sub1, 0
70 const int16_t *SubIndices;
72 if (AMDGPU::M0 == DestReg) {
73 // Check if M0 isn't already set to this value
74 for (MachineBasicBlock::reverse_iterator E = MBB.rend(),
75 I = MachineBasicBlock::reverse_iterator(MI); I != E; ++I) {
77 if (!I->definesRegister(AMDGPU::M0))
80 unsigned Opc = I->getOpcode();
81 if (Opc != TargetOpcode::COPY && Opc != AMDGPU::S_MOV_B32)
84 if (!I->readsRegister(SrcReg))
87 // The copy isn't necessary
92 if (AMDGPU::SReg_32RegClass.contains(DestReg)) {
93 assert(AMDGPU::SReg_32RegClass.contains(SrcReg));
94 BuildMI(MBB, MI, DL, get(AMDGPU::S_MOV_B32), DestReg)
95 .addReg(SrcReg, getKillRegState(KillSrc));
98 } else if (AMDGPU::SReg_64RegClass.contains(DestReg)) {
99 assert(AMDGPU::SReg_64RegClass.contains(SrcReg));
100 BuildMI(MBB, MI, DL, get(AMDGPU::S_MOV_B64), DestReg)
101 .addReg(SrcReg, getKillRegState(KillSrc));
104 } else if (AMDGPU::SReg_128RegClass.contains(DestReg)) {
105 assert(AMDGPU::SReg_128RegClass.contains(SrcReg));
106 Opcode = AMDGPU::S_MOV_B32;
109 } else if (AMDGPU::SReg_256RegClass.contains(DestReg)) {
110 assert(AMDGPU::SReg_256RegClass.contains(SrcReg));
111 Opcode = AMDGPU::S_MOV_B32;
114 } else if (AMDGPU::SReg_512RegClass.contains(DestReg)) {
115 assert(AMDGPU::SReg_512RegClass.contains(SrcReg));
116 Opcode = AMDGPU::S_MOV_B32;
117 SubIndices = Sub0_15;
119 } else if (AMDGPU::VReg_32RegClass.contains(DestReg)) {
120 assert(AMDGPU::VReg_32RegClass.contains(SrcReg) ||
121 AMDGPU::SReg_32RegClass.contains(SrcReg));
122 BuildMI(MBB, MI, DL, get(AMDGPU::V_MOV_B32_e32), DestReg)
123 .addReg(SrcReg, getKillRegState(KillSrc));
126 } else if (AMDGPU::VReg_64RegClass.contains(DestReg)) {
127 assert(AMDGPU::VReg_64RegClass.contains(SrcReg) ||
128 AMDGPU::SReg_64RegClass.contains(SrcReg));
129 Opcode = AMDGPU::V_MOV_B32_e32;
132 } else if (AMDGPU::VReg_96RegClass.contains(DestReg)) {
133 assert(AMDGPU::VReg_96RegClass.contains(SrcReg));
134 Opcode = AMDGPU::V_MOV_B32_e32;
137 } else if (AMDGPU::VReg_128RegClass.contains(DestReg)) {
138 assert(AMDGPU::VReg_128RegClass.contains(SrcReg) ||
139 AMDGPU::SReg_128RegClass.contains(SrcReg));
140 Opcode = AMDGPU::V_MOV_B32_e32;
143 } else if (AMDGPU::VReg_256RegClass.contains(DestReg)) {
144 assert(AMDGPU::VReg_256RegClass.contains(SrcReg) ||
145 AMDGPU::SReg_256RegClass.contains(SrcReg));
146 Opcode = AMDGPU::V_MOV_B32_e32;
149 } else if (AMDGPU::VReg_512RegClass.contains(DestReg)) {
150 assert(AMDGPU::VReg_512RegClass.contains(SrcReg) ||
151 AMDGPU::SReg_512RegClass.contains(SrcReg));
152 Opcode = AMDGPU::V_MOV_B32_e32;
153 SubIndices = Sub0_15;
156 llvm_unreachable("Can't copy register!");
159 while (unsigned SubIdx = *SubIndices++) {
160 MachineInstrBuilder Builder = BuildMI(MBB, MI, DL,
161 get(Opcode), RI.getSubReg(DestReg, SubIdx));
163 Builder.addReg(RI.getSubReg(SrcReg, SubIdx), getKillRegState(KillSrc));
166 Builder.addReg(DestReg, RegState::Define | RegState::Implicit);
170 unsigned SIInstrInfo::commuteOpcode(unsigned Opcode) const {
174 // Try to map original to commuted opcode
175 if ((NewOpc = AMDGPU::getCommuteRev(Opcode)) != -1)
178 // Try to map commuted to original opcode
179 if ((NewOpc = AMDGPU::getCommuteOrig(Opcode)) != -1)
185 MachineInstr *SIInstrInfo::commuteInstruction(MachineInstr *MI,
188 if (MI->getNumOperands() < 3 || !MI->getOperand(1).isReg() ||
189 !MI->getOperand(2).isReg())
192 MI = TargetInstrInfo::commuteInstruction(MI, NewMI);
195 MI->setDesc(get(commuteOpcode(MI->getOpcode())));
200 MachineInstr *SIInstrInfo::buildMovInstr(MachineBasicBlock *MBB,
201 MachineBasicBlock::iterator I,
203 unsigned SrcReg) const {
204 llvm_unreachable("Not Implemented");
207 bool SIInstrInfo::isMov(unsigned Opcode) const {
209 default: return false;
210 case AMDGPU::S_MOV_B32:
211 case AMDGPU::S_MOV_B64:
212 case AMDGPU::V_MOV_B32_e32:
213 case AMDGPU::V_MOV_B32_e64:
219 SIInstrInfo::isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const {
220 return RC != &AMDGPU::EXECRegRegClass;
223 int SIInstrInfo::isMIMG(uint16_t Opcode) const {
224 return get(Opcode).TSFlags & SIInstrFlags::MIMG;
227 int SIInstrInfo::isSMRD(uint16_t Opcode) const {
228 return get(Opcode).TSFlags & SIInstrFlags::SMRD;
231 bool SIInstrInfo::isVOP1(uint16_t Opcode) const {
232 return get(Opcode).TSFlags & SIInstrFlags::VOP1;
235 bool SIInstrInfo::isVOP2(uint16_t Opcode) const {
236 return get(Opcode).TSFlags & SIInstrFlags::VOP2;
239 bool SIInstrInfo::isVOP3(uint16_t Opcode) const {
240 return get(Opcode).TSFlags & SIInstrFlags::VOP3;
243 bool SIInstrInfo::isVOPC(uint16_t Opcode) const {
244 return get(Opcode).TSFlags & SIInstrFlags::VOPC;
247 bool SIInstrInfo::isInlineConstant(const MachineOperand &MO) const {
249 return MO.getImm() >= -16 && MO.getImm() <= 64;
252 return MO.getFPImm()->isExactlyValue(0.0) ||
253 MO.getFPImm()->isExactlyValue(0.5) ||
254 MO.getFPImm()->isExactlyValue(-0.5) ||
255 MO.getFPImm()->isExactlyValue(1.0) ||
256 MO.getFPImm()->isExactlyValue(-1.0) ||
257 MO.getFPImm()->isExactlyValue(2.0) ||
258 MO.getFPImm()->isExactlyValue(-2.0) ||
259 MO.getFPImm()->isExactlyValue(4.0) ||
260 MO.getFPImm()->isExactlyValue(-4.0);
265 bool SIInstrInfo::isLiteralConstant(const MachineOperand &MO) const {
266 return (MO.isImm() || MO.isFPImm()) && !isInlineConstant(MO);
269 bool SIInstrInfo::verifyInstruction(const MachineInstr *MI,
270 StringRef &ErrInfo) const {
271 uint16_t Opcode = MI->getOpcode();
272 int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
273 int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
274 int Src2Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src2);
277 if (isVOP1(Opcode) || isVOP2(Opcode) || isVOP3(Opcode) || isVOPC(Opcode)) {
278 unsigned ConstantBusCount = 0;
279 unsigned SGPRUsed = AMDGPU::NoRegister;
280 for (int i = 0, e = MI->getNumOperands(); i != e; ++i) {
281 const MachineOperand &MO = MI->getOperand(i);
282 if (MO.isReg() && MO.isUse() &&
283 !TargetRegisterInfo::isVirtualRegister(MO.getReg())) {
285 // EXEC register uses the constant bus.
286 if (!MO.isImplicit() && MO.getReg() == AMDGPU::EXEC)
289 // SGPRs use the constant bus
290 if (MO.getReg() == AMDGPU::M0 || MO.getReg() == AMDGPU::VCC ||
292 (AMDGPU::SGPR_32RegClass.contains(MO.getReg()) ||
293 AMDGPU::SGPR_64RegClass.contains(MO.getReg())))) {
294 if (SGPRUsed != MO.getReg()) {
296 SGPRUsed = MO.getReg();
300 // Literal constants use the constant bus.
301 if (isLiteralConstant(MO))
304 if (ConstantBusCount > 1) {
305 ErrInfo = "VOP* instruction uses the constant bus more than once";
310 // Verify SRC1 for VOP2 and VOPC
311 if (Src1Idx != -1 && (isVOP2(Opcode) || isVOPC(Opcode))) {
312 const MachineOperand &Src1 = MI->getOperand(Src1Idx);
314 ErrInfo = "VOP[2C] src1 cannot be an immediate.";
320 if (isVOP3(Opcode)) {
321 if (Src0Idx != -1 && isLiteralConstant(MI->getOperand(Src0Idx))) {
322 ErrInfo = "VOP3 src0 cannot be a literal constant.";
325 if (Src1Idx != -1 && isLiteralConstant(MI->getOperand(Src1Idx))) {
326 ErrInfo = "VOP3 src1 cannot be a literal constant.";
329 if (Src2Idx != -1 && isLiteralConstant(MI->getOperand(Src2Idx))) {
330 ErrInfo = "VOP3 src2 cannot be a literal constant.";
337 //===----------------------------------------------------------------------===//
338 // Indirect addressing callbacks
339 //===----------------------------------------------------------------------===//
341 unsigned SIInstrInfo::calculateIndirectAddress(unsigned RegIndex,
342 unsigned Channel) const {
343 assert(Channel == 0);
348 int SIInstrInfo::getIndirectIndexBegin(const MachineFunction &MF) const {
349 llvm_unreachable("Unimplemented");
352 int SIInstrInfo::getIndirectIndexEnd(const MachineFunction &MF) const {
353 llvm_unreachable("Unimplemented");
356 const TargetRegisterClass *SIInstrInfo::getIndirectAddrRegClass() const {
357 llvm_unreachable("Unimplemented");
360 MachineInstrBuilder SIInstrInfo::buildIndirectWrite(
361 MachineBasicBlock *MBB,
362 MachineBasicBlock::iterator I,
364 unsigned Address, unsigned OffsetReg) const {
365 llvm_unreachable("Unimplemented");
368 MachineInstrBuilder SIInstrInfo::buildIndirectRead(
369 MachineBasicBlock *MBB,
370 MachineBasicBlock::iterator I,
372 unsigned Address, unsigned OffsetReg) const {
373 llvm_unreachable("Unimplemented");