R600: Remove unused InstrInfo::getMovImmInstr() function
[oota-llvm.git] / lib / Target / R600 / SIInstrInfo.cpp
1 //===-- SIInstrInfo.cpp - SI Instruction Information  ---------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 /// \file
11 /// \brief SI Implementation of TargetInstrInfo.
12 //
13 //===----------------------------------------------------------------------===//
14
15
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"
22
23 using namespace llvm;
24
25 SIInstrInfo::SIInstrInfo(AMDGPUTargetMachine &tm)
26   : AMDGPUInstrInfo(tm),
27     RI(tm)
28     { }
29
30 const SIRegisterInfo &SIInstrInfo::getRegisterInfo() const {
31   return RI;
32 }
33
34 void
35 SIInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
36                          MachineBasicBlock::iterator MI, DebugLoc DL,
37                          unsigned DestReg, unsigned SrcReg,
38                          bool KillSrc) const {
39
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);
44
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
50   };
51
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
55   };
56
57   static const int16_t Sub0_3[] = {
58     AMDGPU::sub0, AMDGPU::sub1, AMDGPU::sub2, AMDGPU::sub3, 0
59   };
60
61   static const int16_t Sub0_2[] = {
62     AMDGPU::sub0, AMDGPU::sub1, AMDGPU::sub2, 0
63   };
64
65   static const int16_t Sub0_1[] = {
66     AMDGPU::sub0, AMDGPU::sub1, 0
67   };
68
69   unsigned Opcode;
70   const int16_t *SubIndices;
71
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) {
76
77       if (!I->definesRegister(AMDGPU::M0))
78         continue;
79
80       unsigned Opc = I->getOpcode();
81       if (Opc != TargetOpcode::COPY && Opc != AMDGPU::S_MOV_B32)
82         break;
83
84       if (!I->readsRegister(SrcReg))
85         break;
86
87       // The copy isn't necessary
88       return;
89     }
90   }
91
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));
96     return;
97
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));
102     return;
103
104   } else if (AMDGPU::SReg_128RegClass.contains(DestReg)) {
105     assert(AMDGPU::SReg_128RegClass.contains(SrcReg));
106     Opcode = AMDGPU::S_MOV_B32;
107     SubIndices = Sub0_3;
108
109   } else if (AMDGPU::SReg_256RegClass.contains(DestReg)) {
110     assert(AMDGPU::SReg_256RegClass.contains(SrcReg));
111     Opcode = AMDGPU::S_MOV_B32;
112     SubIndices = Sub0_7;
113
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;
118
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));
124     return;
125
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;
130     SubIndices = Sub0_1;
131
132   } else if (AMDGPU::VReg_96RegClass.contains(DestReg)) {
133     assert(AMDGPU::VReg_96RegClass.contains(SrcReg));
134     Opcode = AMDGPU::V_MOV_B32_e32;
135     SubIndices = Sub0_2;
136
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;
141     SubIndices = Sub0_3;
142
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;
147     SubIndices = Sub0_7;
148
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;
154
155   } else {
156     llvm_unreachable("Can't copy register!");
157   }
158
159   while (unsigned SubIdx = *SubIndices++) {
160     MachineInstrBuilder Builder = BuildMI(MBB, MI, DL,
161       get(Opcode), RI.getSubReg(DestReg, SubIdx));
162
163     Builder.addReg(RI.getSubReg(SrcReg, SubIdx), getKillRegState(KillSrc));
164
165     if (*SubIndices)
166       Builder.addReg(DestReg, RegState::Define | RegState::Implicit);
167   }
168 }
169
170 unsigned SIInstrInfo::commuteOpcode(unsigned Opcode) const {
171
172   int NewOpc;
173
174   // Try to map original to commuted opcode
175   if ((NewOpc = AMDGPU::getCommuteRev(Opcode)) != -1)
176     return NewOpc;
177
178   // Try to map commuted to original opcode
179   if ((NewOpc = AMDGPU::getCommuteOrig(Opcode)) != -1)
180     return NewOpc;
181
182   return Opcode;
183 }
184
185 MachineInstr *SIInstrInfo::commuteInstruction(MachineInstr *MI,
186                                               bool NewMI) const {
187
188   if (MI->getNumOperands() < 3 || !MI->getOperand(1).isReg() ||
189       !MI->getOperand(2).isReg())
190     return 0;
191
192   MI = TargetInstrInfo::commuteInstruction(MI, NewMI);
193
194   if (MI)
195     MI->setDesc(get(commuteOpcode(MI->getOpcode())));
196
197   return MI;
198 }
199
200 bool SIInstrInfo::isMov(unsigned Opcode) const {
201   switch(Opcode) {
202   default: return false;
203   case AMDGPU::S_MOV_B32:
204   case AMDGPU::S_MOV_B64:
205   case AMDGPU::V_MOV_B32_e32:
206   case AMDGPU::V_MOV_B32_e64:
207     return true;
208   }
209 }
210
211 bool
212 SIInstrInfo::isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const {
213   return RC != &AMDGPU::EXECRegRegClass;
214 }
215
216 int SIInstrInfo::isMIMG(uint16_t Opcode) const {
217   return get(Opcode).TSFlags & SIInstrFlags::MIMG;
218 }
219
220 int SIInstrInfo::isSMRD(uint16_t Opcode) const {
221   return get(Opcode).TSFlags & SIInstrFlags::SMRD;
222 }
223
224 bool SIInstrInfo::isVOP1(uint16_t Opcode) const {
225   return get(Opcode).TSFlags & SIInstrFlags::VOP1;
226 }
227
228 bool SIInstrInfo::isVOP2(uint16_t Opcode) const {
229   return get(Opcode).TSFlags & SIInstrFlags::VOP2;
230 }
231
232 bool SIInstrInfo::isVOP3(uint16_t Opcode) const {
233   return get(Opcode).TSFlags & SIInstrFlags::VOP3;
234 }
235
236 bool SIInstrInfo::isVOPC(uint16_t Opcode) const {
237   return get(Opcode).TSFlags & SIInstrFlags::VOPC;
238 }
239
240 bool SIInstrInfo::isInlineConstant(const MachineOperand &MO) const {
241   if(MO.isImm()) {
242     return MO.getImm() >= -16 && MO.getImm() <= 64;
243   }
244   if (MO.isFPImm()) {
245     return MO.getFPImm()->isExactlyValue(0.0)  ||
246            MO.getFPImm()->isExactlyValue(0.5)  ||
247            MO.getFPImm()->isExactlyValue(-0.5) ||
248            MO.getFPImm()->isExactlyValue(1.0)  ||
249            MO.getFPImm()->isExactlyValue(-1.0) ||
250            MO.getFPImm()->isExactlyValue(2.0)  ||
251            MO.getFPImm()->isExactlyValue(-2.0) ||
252            MO.getFPImm()->isExactlyValue(4.0)  ||
253            MO.getFPImm()->isExactlyValue(-4.0);
254   }
255   return false;
256 }
257
258 bool SIInstrInfo::isLiteralConstant(const MachineOperand &MO) const {
259   return (MO.isImm() || MO.isFPImm()) && !isInlineConstant(MO);
260 }
261
262 bool SIInstrInfo::verifyInstruction(const MachineInstr *MI,
263                                     StringRef &ErrInfo) const {
264   uint16_t Opcode = MI->getOpcode();
265   int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
266   int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
267   int Src2Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src2);
268
269   // Verify VOP*
270   if (isVOP1(Opcode) || isVOP2(Opcode) || isVOP3(Opcode) || isVOPC(Opcode)) {
271     unsigned ConstantBusCount = 0;
272     unsigned SGPRUsed = AMDGPU::NoRegister;
273     for (int i = 0, e = MI->getNumOperands(); i != e; ++i) {
274       const MachineOperand &MO = MI->getOperand(i);
275       if (MO.isReg() && MO.isUse() &&
276           !TargetRegisterInfo::isVirtualRegister(MO.getReg())) {
277
278         // EXEC register uses the constant bus.
279         if (!MO.isImplicit() && MO.getReg() == AMDGPU::EXEC)
280           ++ConstantBusCount;
281
282         // SGPRs use the constant bus
283         if (MO.getReg() == AMDGPU::M0 || MO.getReg() == AMDGPU::VCC ||
284             (!MO.isImplicit() &&
285             (AMDGPU::SGPR_32RegClass.contains(MO.getReg()) ||
286             AMDGPU::SGPR_64RegClass.contains(MO.getReg())))) {
287           if (SGPRUsed != MO.getReg()) {
288             ++ConstantBusCount;
289             SGPRUsed = MO.getReg();
290           }
291         }
292       }
293       // Literal constants use the constant bus.
294       if (isLiteralConstant(MO))
295         ++ConstantBusCount;
296     }
297     if (ConstantBusCount > 1) {
298       ErrInfo = "VOP* instruction uses the constant bus more than once";
299       return false;
300     }
301   }
302
303   // Verify SRC1 for VOP2 and VOPC
304   if (Src1Idx != -1 && (isVOP2(Opcode) || isVOPC(Opcode))) {
305     const MachineOperand &Src1 = MI->getOperand(Src1Idx);
306     if (Src1.isImm()) {
307       ErrInfo = "VOP[2C] src1 cannot be an immediate.";
308       return false;
309     }
310   }
311
312   // Verify VOP3
313   if (isVOP3(Opcode)) {
314     if (Src0Idx != -1 && isLiteralConstant(MI->getOperand(Src0Idx))) {
315       ErrInfo = "VOP3 src0 cannot be a literal constant.";
316       return false;
317     }
318     if (Src1Idx != -1 && isLiteralConstant(MI->getOperand(Src1Idx))) {
319       ErrInfo = "VOP3 src1 cannot be a literal constant.";
320       return false;
321     }
322     if (Src2Idx != -1 && isLiteralConstant(MI->getOperand(Src2Idx))) {
323       ErrInfo = "VOP3 src2 cannot be a literal constant.";
324       return false;
325     }
326   }
327   return true;
328 }
329
330 //===----------------------------------------------------------------------===//
331 // Indirect addressing callbacks
332 //===----------------------------------------------------------------------===//
333
334 unsigned SIInstrInfo::calculateIndirectAddress(unsigned RegIndex,
335                                                  unsigned Channel) const {
336   assert(Channel == 0);
337   return RegIndex;
338 }
339
340
341 int SIInstrInfo::getIndirectIndexBegin(const MachineFunction &MF) const {
342   llvm_unreachable("Unimplemented");
343 }
344
345 int SIInstrInfo::getIndirectIndexEnd(const MachineFunction &MF) const {
346   llvm_unreachable("Unimplemented");
347 }
348
349 const TargetRegisterClass *SIInstrInfo::getIndirectAddrStoreRegClass(
350                                                      unsigned SourceReg) const {
351   llvm_unreachable("Unimplemented");
352 }
353
354 const TargetRegisterClass *SIInstrInfo::getIndirectAddrLoadRegClass() const {
355   llvm_unreachable("Unimplemented");
356 }
357
358 MachineInstrBuilder SIInstrInfo::buildIndirectWrite(
359                                    MachineBasicBlock *MBB,
360                                    MachineBasicBlock::iterator I,
361                                    unsigned ValueReg,
362                                    unsigned Address, unsigned OffsetReg) const {
363   llvm_unreachable("Unimplemented");
364 }
365
366 MachineInstrBuilder SIInstrInfo::buildIndirectRead(
367                                    MachineBasicBlock *MBB,
368                                    MachineBasicBlock::iterator I,
369                                    unsigned ValueReg,
370                                    unsigned Address, unsigned OffsetReg) const {
371   llvm_unreachable("Unimplemented");
372 }
373
374 const TargetRegisterClass *SIInstrInfo::getSuperIndirectRegClass() const {
375   llvm_unreachable("Unimplemented");
376 }