• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "llvm/CodeGen/MachineInstrBuilder.h"
19 #include "llvm/CodeGen/MachineRegisterInfo.h"
20 #include "llvm/MC/MCInstrDesc.h"
21 #include <stdio.h>
22 
23 using namespace llvm;
24 
SIInstrInfo(AMDGPUTargetMachine & tm)25 SIInstrInfo::SIInstrInfo(AMDGPUTargetMachine &tm)
26   : AMDGPUInstrInfo(tm),
27     RI(tm)
28     { }
29 
getRegisterInfo() const30 const SIRegisterInfo &SIInstrInfo::getRegisterInfo() const {
31   return RI;
32 }
33 
34 void
copyPhysReg(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,DebugLoc DL,unsigned DestReg,unsigned SrcReg,bool KillSrc) const35 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 
commuteOpcode(unsigned Opcode) const170 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 
commuteInstruction(MachineInstr * MI,bool NewMI) const185 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 
getMovImmInstr(MachineFunction * MF,unsigned DstReg,int64_t Imm) const200 MachineInstr * SIInstrInfo::getMovImmInstr(MachineFunction *MF, unsigned DstReg,
201                                            int64_t Imm) const {
202   MachineInstr * MI = MF->CreateMachineInstr(get(AMDGPU::V_MOV_B32_e32), DebugLoc());
203   MachineInstrBuilder MIB(*MF, MI);
204   MIB.addReg(DstReg, RegState::Define);
205   MIB.addImm(Imm);
206 
207   return MI;
208 
209 }
210 
isMov(unsigned Opcode) const211 bool SIInstrInfo::isMov(unsigned Opcode) const {
212   switch(Opcode) {
213   default: return false;
214   case AMDGPU::S_MOV_B32:
215   case AMDGPU::S_MOV_B64:
216   case AMDGPU::V_MOV_B32_e32:
217   case AMDGPU::V_MOV_B32_e64:
218     return true;
219   }
220 }
221 
222 bool
isSafeToMoveRegClassDefs(const TargetRegisterClass * RC) const223 SIInstrInfo::isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const {
224   return RC != &AMDGPU::EXECRegRegClass;
225 }
226 
227 //===----------------------------------------------------------------------===//
228 // Indirect addressing callbacks
229 //===----------------------------------------------------------------------===//
230 
calculateIndirectAddress(unsigned RegIndex,unsigned Channel) const231 unsigned SIInstrInfo::calculateIndirectAddress(unsigned RegIndex,
232                                                  unsigned Channel) const {
233   assert(Channel == 0);
234   return RegIndex;
235 }
236 
237 
getIndirectIndexBegin(const MachineFunction & MF) const238 int SIInstrInfo::getIndirectIndexBegin(const MachineFunction &MF) const {
239   llvm_unreachable("Unimplemented");
240 }
241 
getIndirectIndexEnd(const MachineFunction & MF) const242 int SIInstrInfo::getIndirectIndexEnd(const MachineFunction &MF) const {
243   llvm_unreachable("Unimplemented");
244 }
245 
getIndirectAddrStoreRegClass(unsigned SourceReg) const246 const TargetRegisterClass *SIInstrInfo::getIndirectAddrStoreRegClass(
247                                                      unsigned SourceReg) const {
248   llvm_unreachable("Unimplemented");
249 }
250 
getIndirectAddrLoadRegClass() const251 const TargetRegisterClass *SIInstrInfo::getIndirectAddrLoadRegClass() const {
252   llvm_unreachable("Unimplemented");
253 }
254 
buildIndirectWrite(MachineBasicBlock * MBB,MachineBasicBlock::iterator I,unsigned ValueReg,unsigned Address,unsigned OffsetReg) const255 MachineInstrBuilder SIInstrInfo::buildIndirectWrite(
256                                    MachineBasicBlock *MBB,
257                                    MachineBasicBlock::iterator I,
258                                    unsigned ValueReg,
259                                    unsigned Address, unsigned OffsetReg) const {
260   llvm_unreachable("Unimplemented");
261 }
262 
buildIndirectRead(MachineBasicBlock * MBB,MachineBasicBlock::iterator I,unsigned ValueReg,unsigned Address,unsigned OffsetReg) const263 MachineInstrBuilder SIInstrInfo::buildIndirectRead(
264                                    MachineBasicBlock *MBB,
265                                    MachineBasicBlock::iterator I,
266                                    unsigned ValueReg,
267                                    unsigned Address, unsigned OffsetReg) const {
268   llvm_unreachable("Unimplemented");
269 }
270 
getSuperIndirectRegClass() const271 const TargetRegisterClass *SIInstrInfo::getSuperIndirectRegClass() const {
272   llvm_unreachable("Unimplemented");
273 }
274