R600/SI: handle all registers in copyPhysReg v2
[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 "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
25 SIInstrInfo::SIInstrInfo(AMDGPUTargetMachine &tm)
26   : AMDGPUInstrInfo(tm),
27     RI(tm, *this)
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   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   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   const int16_t Sub0_3[] = {
58     AMDGPU::sub0, AMDGPU::sub1, AMDGPU::sub2, AMDGPU::sub3, 0
59   };
60
61   const int16_t Sub0_1[] = {
62     AMDGPU::sub0, AMDGPU::sub1, 0
63   };
64
65   unsigned Opcode;
66   const int16_t *SubIndices;
67
68   if (AMDGPU::SReg_32RegClass.contains(DestReg)) {
69     assert(AMDGPU::SReg_32RegClass.contains(SrcReg));
70     BuildMI(MBB, MI, DL, get(AMDGPU::S_MOV_B32), DestReg)
71             .addReg(SrcReg, getKillRegState(KillSrc));
72     return;
73
74   } else if (AMDGPU::SReg_64RegClass.contains(DestReg)) {
75     assert(AMDGPU::SReg_64RegClass.contains(SrcReg));
76     BuildMI(MBB, MI, DL, get(AMDGPU::S_MOV_B64), DestReg)
77             .addReg(SrcReg, getKillRegState(KillSrc));
78     return;
79
80   } else if (AMDGPU::SReg_128RegClass.contains(DestReg)) {
81     assert(AMDGPU::SReg_128RegClass.contains(SrcReg));
82     Opcode = AMDGPU::S_MOV_B32;
83     SubIndices = Sub0_3;
84
85   } else if (AMDGPU::SReg_256RegClass.contains(DestReg)) {
86     assert(AMDGPU::SReg_256RegClass.contains(SrcReg));
87     Opcode = AMDGPU::S_MOV_B32;
88     SubIndices = Sub0_7;
89
90   } else if (AMDGPU::SReg_512RegClass.contains(DestReg)) {
91     assert(AMDGPU::SReg_512RegClass.contains(SrcReg));
92     Opcode = AMDGPU::S_MOV_B32;
93     SubIndices = Sub0_15;
94
95   } else if (AMDGPU::VReg_32RegClass.contains(DestReg)) {
96     assert(AMDGPU::VReg_32RegClass.contains(SrcReg) ||
97            AMDGPU::SReg_32RegClass.contains(SrcReg));
98     BuildMI(MBB, MI, DL, get(AMDGPU::V_MOV_B32_e32), DestReg)
99             .addReg(SrcReg, getKillRegState(KillSrc));
100     return;
101
102   } else if (AMDGPU::VReg_64RegClass.contains(DestReg)) {
103     assert(AMDGPU::VReg_64RegClass.contains(SrcReg) ||
104            AMDGPU::SReg_64RegClass.contains(SrcReg));
105     Opcode = AMDGPU::V_MOV_B32_e32;
106     SubIndices = Sub0_1;
107
108   } else if (AMDGPU::VReg_128RegClass.contains(DestReg)) {
109     assert(AMDGPU::VReg_128RegClass.contains(SrcReg) ||
110            AMDGPU::SReg_128RegClass.contains(SrcReg));
111     Opcode = AMDGPU::V_MOV_B32_e32;
112     SubIndices = Sub0_3;
113
114   } else if (AMDGPU::VReg_256RegClass.contains(DestReg)) {
115     assert(AMDGPU::VReg_256RegClass.contains(SrcReg) ||
116            AMDGPU::SReg_256RegClass.contains(SrcReg));
117     Opcode = AMDGPU::V_MOV_B32_e32;
118     SubIndices = Sub0_7;
119
120   } else if (AMDGPU::VReg_512RegClass.contains(DestReg)) {
121     assert(AMDGPU::VReg_512RegClass.contains(SrcReg) ||
122            AMDGPU::SReg_512RegClass.contains(SrcReg));
123     Opcode = AMDGPU::V_MOV_B32_e32;
124     SubIndices = Sub0_15;
125
126   } else {
127     llvm_unreachable("Can't copy register!");
128   }
129
130   while (unsigned SubIdx = *SubIndices++) {
131     MachineInstrBuilder Builder = BuildMI(MBB, MI, DL,
132       get(Opcode), RI.getSubReg(DestReg, SubIdx));
133
134     Builder.addReg(RI.getSubReg(SrcReg, SubIdx), getKillRegState(KillSrc));
135
136     if (*SubIndices)
137       Builder.addReg(DestReg, RegState::Define | RegState::Implicit);
138   }
139 }
140
141 MachineInstr *SIInstrInfo::commuteInstruction(MachineInstr *MI,
142                                               bool NewMI) const {
143
144   if (MI->getNumOperands() < 3 || !MI->getOperand(1).isReg() ||
145       !MI->getOperand(2).isReg())
146     return 0;
147
148   return TargetInstrInfo::commuteInstruction(MI, NewMI);
149 }
150
151 MachineInstr * SIInstrInfo::getMovImmInstr(MachineFunction *MF, unsigned DstReg,
152                                            int64_t Imm) const {
153   MachineInstr * MI = MF->CreateMachineInstr(get(AMDGPU::V_MOV_B32_e32), DebugLoc());
154   MachineInstrBuilder MIB(*MF, MI);
155   MIB.addReg(DstReg, RegState::Define);
156   MIB.addImm(Imm);
157
158   return MI;
159
160 }
161
162 bool SIInstrInfo::isMov(unsigned Opcode) const {
163   switch(Opcode) {
164   default: return false;
165   case AMDGPU::S_MOV_B32:
166   case AMDGPU::S_MOV_B64:
167   case AMDGPU::V_MOV_B32_e32:
168   case AMDGPU::V_MOV_B32_e64:
169     return true;
170   }
171 }
172
173 bool
174 SIInstrInfo::isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const {
175   return RC != &AMDGPU::EXECRegRegClass;
176 }
177
178 //===----------------------------------------------------------------------===//
179 // Indirect addressing callbacks
180 //===----------------------------------------------------------------------===//
181
182 unsigned SIInstrInfo::calculateIndirectAddress(unsigned RegIndex,
183                                                  unsigned Channel) const {
184   assert(Channel == 0);
185   return RegIndex;
186 }
187
188
189 int SIInstrInfo::getIndirectIndexBegin(const MachineFunction &MF) const {
190   llvm_unreachable("Unimplemented");
191 }
192
193 int SIInstrInfo::getIndirectIndexEnd(const MachineFunction &MF) const {
194   llvm_unreachable("Unimplemented");
195 }
196
197 const TargetRegisterClass *SIInstrInfo::getIndirectAddrStoreRegClass(
198                                                      unsigned SourceReg) const {
199   llvm_unreachable("Unimplemented");
200 }
201
202 const TargetRegisterClass *SIInstrInfo::getIndirectAddrLoadRegClass() const {
203   llvm_unreachable("Unimplemented");
204 }
205
206 MachineInstrBuilder SIInstrInfo::buildIndirectWrite(
207                                    MachineBasicBlock *MBB,
208                                    MachineBasicBlock::iterator I,
209                                    unsigned ValueReg,
210                                    unsigned Address, unsigned OffsetReg) const {
211   llvm_unreachable("Unimplemented");
212 }
213
214 MachineInstrBuilder SIInstrInfo::buildIndirectRead(
215                                    MachineBasicBlock *MBB,
216                                    MachineBasicBlock::iterator I,
217                                    unsigned ValueReg,
218                                    unsigned Address, unsigned OffsetReg) const {
219   llvm_unreachable("Unimplemented");
220 }
221
222 const TargetRegisterClass *SIInstrInfo::getSuperIndirectRegClass() const {
223   llvm_unreachable("Unimplemented");
224 }