R600: silence GCC warning
[oota-llvm.git] / lib / Target / R600 / SIRegisterInfo.cpp
1 //===-- SIRegisterInfo.cpp - SI Register 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 the TargetRegisterInfo class.
12 //
13 //===----------------------------------------------------------------------===//
14
15
16 #include "SIRegisterInfo.h"
17 #include "AMDGPUSubtarget.h"
18 #include "SIInstrInfo.h"
19 #include "SIMachineFunctionInfo.h"
20 #include "llvm/CodeGen/MachineFrameInfo.h"
21 #include "llvm/CodeGen/MachineInstrBuilder.h"
22 #include "llvm/CodeGen/RegisterScavenging.h"
23
24 using namespace llvm;
25
26 SIRegisterInfo::SIRegisterInfo(const AMDGPUSubtarget &st)
27 : AMDGPURegisterInfo(st)
28   { }
29
30 BitVector SIRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
31   BitVector Reserved(getNumRegs());
32   Reserved.set(AMDGPU::EXEC);
33   Reserved.set(AMDGPU::INDIRECT_BASE_ADDR);
34   return Reserved;
35 }
36
37 unsigned SIRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC,
38                                              MachineFunction &MF) const {
39   return RC->getNumRegs();
40 }
41
42 bool SIRegisterInfo::requiresRegisterScavenging(const MachineFunction &Fn) const {
43   return Fn.getFrameInfo()->hasStackObjects();
44 }
45
46 void SIRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MI,
47                                         int SPAdj, unsigned FIOperandNum,
48                                         RegScavenger *RS) const {
49   MachineFunction *MF = MI->getParent()->getParent();
50   MachineFrameInfo *FrameInfo = MF->getFrameInfo();
51   const SIInstrInfo *TII = static_cast<const SIInstrInfo*>(ST.getInstrInfo());
52   MachineOperand &FIOp = MI->getOperand(FIOperandNum);
53   int Index = MI->getOperand(FIOperandNum).getIndex();
54   int64_t Offset = FrameInfo->getObjectOffset(Index);
55
56   FIOp.ChangeToImmediate(Offset);
57   if (!TII->isImmOperandLegal(MI, FIOperandNum, FIOp)) {
58     unsigned TmpReg = RS->scavengeRegister(&AMDGPU::VReg_32RegClass, MI, SPAdj);
59     BuildMI(*MI->getParent(), MI, MI->getDebugLoc(),
60             TII->get(AMDGPU::V_MOV_B32_e32), TmpReg)
61             .addImm(Offset);
62     FIOp.ChangeToRegister(TmpReg, false);
63   }
64 }
65
66 const TargetRegisterClass * SIRegisterInfo::getCFGStructurizerRegClass(
67                                                                    MVT VT) const {
68   switch(VT.SimpleTy) {
69     default:
70     case MVT::i32: return &AMDGPU::VReg_32RegClass;
71   }
72 }
73
74 unsigned SIRegisterInfo::getHWRegIndex(unsigned Reg) const {
75   return getEncodingValue(Reg) & 0xff;
76 }
77
78 const TargetRegisterClass *SIRegisterInfo::getPhysRegClass(unsigned Reg) const {
79   assert(!TargetRegisterInfo::isVirtualRegister(Reg));
80
81   const TargetRegisterClass *BaseClasses[] = {
82     &AMDGPU::VReg_32RegClass,
83     &AMDGPU::SReg_32RegClass,
84     &AMDGPU::VReg_64RegClass,
85     &AMDGPU::SReg_64RegClass,
86     &AMDGPU::SReg_128RegClass,
87     &AMDGPU::SReg_256RegClass
88   };
89
90   for (const TargetRegisterClass *BaseClass : BaseClasses) {
91     if (BaseClass->contains(Reg)) {
92       return BaseClass;
93     }
94   }
95   return nullptr;
96 }
97
98 bool SIRegisterInfo::isSGPRClass(const TargetRegisterClass *RC) const {
99   if (!RC) {
100     return false;
101   }
102   return !hasVGPRs(RC);
103 }
104
105 bool SIRegisterInfo::hasVGPRs(const TargetRegisterClass *RC) const {
106   return getCommonSubClass(&AMDGPU::VReg_32RegClass, RC) ||
107          getCommonSubClass(&AMDGPU::VReg_64RegClass, RC) ||
108          getCommonSubClass(&AMDGPU::VReg_96RegClass, RC) ||
109          getCommonSubClass(&AMDGPU::VReg_128RegClass, RC) ||
110          getCommonSubClass(&AMDGPU::VReg_256RegClass, RC) ||
111          getCommonSubClass(&AMDGPU::VReg_512RegClass, RC);
112 }
113
114 const TargetRegisterClass *SIRegisterInfo::getEquivalentVGPRClass(
115                                          const TargetRegisterClass *SRC) const {
116     if (hasVGPRs(SRC)) {
117       return SRC;
118     } else if (SRC == &AMDGPU::SCCRegRegClass) {
119       return &AMDGPU::VCCRegRegClass;
120     } else if (getCommonSubClass(SRC, &AMDGPU::SGPR_32RegClass)) {
121       return &AMDGPU::VReg_32RegClass;
122     } else if (getCommonSubClass(SRC, &AMDGPU::SGPR_64RegClass)) {
123       return &AMDGPU::VReg_64RegClass;
124     } else if (getCommonSubClass(SRC, &AMDGPU::SReg_128RegClass)) {
125       return &AMDGPU::VReg_128RegClass;
126     } else if (getCommonSubClass(SRC, &AMDGPU::SReg_256RegClass)) {
127       return &AMDGPU::VReg_256RegClass;
128     } else if (getCommonSubClass(SRC, &AMDGPU::SReg_512RegClass)) {
129       return &AMDGPU::VReg_512RegClass;
130     }
131     return nullptr;
132 }
133
134 const TargetRegisterClass *SIRegisterInfo::getSubRegClass(
135                          const TargetRegisterClass *RC, unsigned SubIdx) const {
136   if (SubIdx == AMDGPU::NoSubRegister)
137     return RC;
138
139   // If this register has a sub-register, we can safely assume it is a 32-bit
140   // register, because all of SI's sub-registers are 32-bit.
141   if (isSGPRClass(RC)) {
142     return &AMDGPU::SGPR_32RegClass;
143   } else {
144     return &AMDGPU::VGPR_32RegClass;
145   }
146 }
147
148 unsigned SIRegisterInfo::getPhysRegSubReg(unsigned Reg,
149                                           const TargetRegisterClass *SubRC,
150                                           unsigned Channel) const {
151   unsigned Index = getHWRegIndex(Reg);
152   return SubRC->getRegister(Index + Channel);
153 }
154
155 bool SIRegisterInfo::regClassCanUseImmediate(int RCID) const {
156   switch (RCID) {
157   default: return false;
158   case AMDGPU::SSrc_32RegClassID:
159   case AMDGPU::SSrc_64RegClassID:
160   case AMDGPU::VSrc_32RegClassID:
161   case AMDGPU::VSrc_64RegClassID:
162     return true;
163   }
164 }
165
166 bool SIRegisterInfo::regClassCanUseImmediate(
167                              const TargetRegisterClass *RC) const {
168   return regClassCanUseImmediate(RC->getID());
169 }
170
171 unsigned SIRegisterInfo::getPreloadedValue(const MachineFunction &MF,
172                                            enum PreloadedValue Value) const {
173
174   const SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();
175   switch (Value) {
176   case SIRegisterInfo::TGID_X:
177     return AMDGPU::SReg_32RegClass.getRegister(MFI->NumUserSGPRs + 0);
178   case SIRegisterInfo::TGID_Y:
179     return AMDGPU::SReg_32RegClass.getRegister(MFI->NumUserSGPRs + 1);
180   case SIRegisterInfo::TGID_Z:
181     return AMDGPU::SReg_32RegClass.getRegister(MFI->NumUserSGPRs + 2);
182   case SIRegisterInfo::SCRATCH_WAVE_OFFSET:
183     return AMDGPU::SReg_32RegClass.getRegister(MFI->NumUserSGPRs + 4);
184   case SIRegisterInfo::SCRATCH_PTR:
185     return AMDGPU::SGPR2_SGPR3;
186   }
187   llvm_unreachable("unexpected preloaded value type");
188 }