1//===- NVPTXRegisterInfo.cpp - NVPTX 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// This file contains the NVPTX implementation of the TargetRegisterInfo class.
11//
12//===----------------------------------------------------------------------===//
13
14#define DEBUG_TYPE "nvptx-reg-info"
15
16#include "NVPTX.h"
17#include "NVPTXRegisterInfo.h"
18#include "NVPTXSubtarget.h"
19#include "llvm/ADT/BitVector.h"
20#include "llvm/CodeGen/MachineInstrBuilder.h"
21#include "llvm/CodeGen/MachineFunction.h"
22#include "llvm/CodeGen/MachineFrameInfo.h"
23#include "llvm/MC/MachineLocation.h"
24#include "llvm/Target/TargetInstrInfo.h"
25
26
27using namespace llvm;
28
29namespace llvm
30{
31std::string getNVPTXRegClassName (TargetRegisterClass const *RC) {
32  if (RC == &NVPTX::Float32RegsRegClass) {
33    return ".f32";
34  }
35  if (RC == &NVPTX::Float64RegsRegClass) {
36    return ".f64";
37  }
38  else if (RC == &NVPTX::Int64RegsRegClass) {
39    return ".s64";
40  }
41  else if (RC == &NVPTX::Int32RegsRegClass) {
42    return ".s32";
43  }
44  else if (RC == &NVPTX::Int16RegsRegClass) {
45    return ".s16";
46  }
47  // Int8Regs become 16-bit registers in PTX
48  else if (RC == &NVPTX::Int8RegsRegClass) {
49    return ".s16";
50  }
51  else if (RC == &NVPTX::Int1RegsRegClass) {
52    return ".pred";
53  }
54  else if (RC == &NVPTX::SpecialRegsRegClass) {
55    return "!Special!";
56  }
57  else if (RC == &NVPTX::V2F32RegsRegClass) {
58    return ".v2.f32";
59  }
60  else if (RC == &NVPTX::V4F32RegsRegClass) {
61    return ".v4.f32";
62  }
63  else if (RC == &NVPTX::V2I32RegsRegClass) {
64    return ".v2.s32";
65  }
66  else if (RC == &NVPTX::V4I32RegsRegClass) {
67    return ".v4.s32";
68  }
69  else if (RC == &NVPTX::V2F64RegsRegClass) {
70    return ".v2.f64";
71  }
72  else if (RC == &NVPTX::V2I64RegsRegClass) {
73    return ".v2.s64";
74  }
75  else if (RC == &NVPTX::V2I16RegsRegClass) {
76    return ".v2.s16";
77  }
78  else if (RC == &NVPTX::V4I16RegsRegClass) {
79    return ".v4.s16";
80  }
81  else if (RC == &NVPTX::V2I8RegsRegClass) {
82    return ".v2.s16";
83  }
84  else if (RC == &NVPTX::V4I8RegsRegClass) {
85    return ".v4.s16";
86  }
87  else {
88    return "INTERNAL";
89  }
90  return "";
91}
92
93std::string getNVPTXRegClassStr (TargetRegisterClass const *RC) {
94  if (RC == &NVPTX::Float32RegsRegClass) {
95    return "%f";
96  }
97  if (RC == &NVPTX::Float64RegsRegClass) {
98    return "%fd";
99  }
100  else if (RC == &NVPTX::Int64RegsRegClass) {
101    return "%rd";
102  }
103  else if (RC == &NVPTX::Int32RegsRegClass) {
104    return "%r";
105  }
106  else if (RC == &NVPTX::Int16RegsRegClass) {
107    return "%rs";
108  }
109  else if (RC == &NVPTX::Int8RegsRegClass) {
110    return "%rc";
111  }
112  else if (RC == &NVPTX::Int1RegsRegClass) {
113    return "%p";
114  }
115  else if (RC == &NVPTX::SpecialRegsRegClass) {
116    return "!Special!";
117  }
118  else if (RC == &NVPTX::V2F32RegsRegClass) {
119    return "%v2f";
120  }
121  else if (RC == &NVPTX::V4F32RegsRegClass) {
122    return "%v4f";
123  }
124  else if (RC == &NVPTX::V2I32RegsRegClass) {
125    return "%v2r";
126  }
127  else if (RC == &NVPTX::V4I32RegsRegClass) {
128    return "%v4r";
129  }
130  else if (RC == &NVPTX::V2F64RegsRegClass) {
131    return "%v2fd";
132  }
133  else if (RC == &NVPTX::V2I64RegsRegClass) {
134    return "%v2rd";
135  }
136  else if (RC == &NVPTX::V2I16RegsRegClass) {
137    return "%v2s";
138  }
139  else if (RC == &NVPTX::V4I16RegsRegClass) {
140    return "%v4rs";
141  }
142  else if (RC == &NVPTX::V2I8RegsRegClass) {
143    return "%v2rc";
144  }
145  else if (RC == &NVPTX::V4I8RegsRegClass) {
146    return "%v4rc";
147  }
148  else {
149    return "INTERNAL";
150  }
151  return "";
152}
153
154bool isNVPTXVectorRegClass(TargetRegisterClass const *RC) {
155  if (RC->getID() == NVPTX::V2F32RegsRegClassID)
156    return true;
157  if (RC->getID() == NVPTX::V2F64RegsRegClassID)
158    return true;
159  if (RC->getID() == NVPTX::V2I16RegsRegClassID)
160    return true;
161  if (RC->getID() == NVPTX::V2I32RegsRegClassID)
162    return true;
163  if (RC->getID() == NVPTX::V2I64RegsRegClassID)
164    return true;
165  if (RC->getID() == NVPTX::V2I8RegsRegClassID)
166    return true;
167  if (RC->getID() == NVPTX::V4F32RegsRegClassID)
168    return true;
169  if (RC->getID() == NVPTX::V4I16RegsRegClassID)
170    return true;
171  if (RC->getID() == NVPTX::V4I32RegsRegClassID)
172    return true;
173  if (RC->getID() == NVPTX::V4I8RegsRegClassID)
174    return true;
175  return false;
176}
177
178std::string getNVPTXElemClassName(TargetRegisterClass const *RC) {
179  if (RC->getID() == NVPTX::V2F32RegsRegClassID)
180    return getNVPTXRegClassName(&NVPTX::Float32RegsRegClass);
181  if (RC->getID() == NVPTX::V2F64RegsRegClassID)
182    return getNVPTXRegClassName(&NVPTX::Float64RegsRegClass);
183  if (RC->getID() == NVPTX::V2I16RegsRegClassID)
184    return getNVPTXRegClassName(&NVPTX::Int16RegsRegClass);
185  if (RC->getID() == NVPTX::V2I32RegsRegClassID)
186    return getNVPTXRegClassName(&NVPTX::Int32RegsRegClass);
187  if (RC->getID() == NVPTX::V2I64RegsRegClassID)
188    return getNVPTXRegClassName(&NVPTX::Int64RegsRegClass);
189  if (RC->getID() == NVPTX::V2I8RegsRegClassID)
190    return getNVPTXRegClassName(&NVPTX::Int8RegsRegClass);
191  if (RC->getID() == NVPTX::V4F32RegsRegClassID)
192    return getNVPTXRegClassName(&NVPTX::Float32RegsRegClass);
193  if (RC->getID() == NVPTX::V4I16RegsRegClassID)
194    return getNVPTXRegClassName(&NVPTX::Int16RegsRegClass);
195  if (RC->getID() == NVPTX::V4I32RegsRegClassID)
196    return getNVPTXRegClassName(&NVPTX::Int32RegsRegClass);
197  if (RC->getID() == NVPTX::V4I8RegsRegClassID)
198    return getNVPTXRegClassName(&NVPTX::Int8RegsRegClass);
199  llvm_unreachable("Not a vector register class");
200}
201
202const TargetRegisterClass *getNVPTXElemClass(TargetRegisterClass const *RC) {
203  if (RC->getID() == NVPTX::V2F32RegsRegClassID)
204    return (&NVPTX::Float32RegsRegClass);
205  if (RC->getID() == NVPTX::V2F64RegsRegClassID)
206    return (&NVPTX::Float64RegsRegClass);
207  if (RC->getID() == NVPTX::V2I16RegsRegClassID)
208    return (&NVPTX::Int16RegsRegClass);
209  if (RC->getID() == NVPTX::V2I32RegsRegClassID)
210    return (&NVPTX::Int32RegsRegClass);
211  if (RC->getID() == NVPTX::V2I64RegsRegClassID)
212    return (&NVPTX::Int64RegsRegClass);
213  if (RC->getID() == NVPTX::V2I8RegsRegClassID)
214    return (&NVPTX::Int8RegsRegClass);
215  if (RC->getID() == NVPTX::V4F32RegsRegClassID)
216    return (&NVPTX::Float32RegsRegClass);
217  if (RC->getID() == NVPTX::V4I16RegsRegClassID)
218    return (&NVPTX::Int16RegsRegClass);
219  if (RC->getID() == NVPTX::V4I32RegsRegClassID)
220    return (&NVPTX::Int32RegsRegClass);
221  if (RC->getID() == NVPTX::V4I8RegsRegClassID)
222    return (&NVPTX::Int8RegsRegClass);
223  llvm_unreachable("Not a vector register class");
224}
225
226int getNVPTXVectorSize(TargetRegisterClass const *RC) {
227  if (RC->getID() == NVPTX::V2F32RegsRegClassID)
228    return 2;
229  if (RC->getID() == NVPTX::V2F64RegsRegClassID)
230    return 2;
231  if (RC->getID() == NVPTX::V2I16RegsRegClassID)
232    return 2;
233  if (RC->getID() == NVPTX::V2I32RegsRegClassID)
234    return 2;
235  if (RC->getID() == NVPTX::V2I64RegsRegClassID)
236    return 2;
237  if (RC->getID() == NVPTX::V2I8RegsRegClassID)
238    return 2;
239  if (RC->getID() == NVPTX::V4F32RegsRegClassID)
240    return 4;
241  if (RC->getID() == NVPTX::V4I16RegsRegClassID)
242    return 4;
243  if (RC->getID() == NVPTX::V4I32RegsRegClassID)
244    return 4;
245  if (RC->getID() == NVPTX::V4I8RegsRegClassID)
246    return 4;
247  llvm_unreachable("Not a vector register class");
248}
249}
250
251NVPTXRegisterInfo::NVPTXRegisterInfo(const TargetInstrInfo &tii,
252                                     const NVPTXSubtarget &st)
253  : NVPTXGenRegisterInfo(0),
254    Is64Bit(st.is64Bit()) {}
255
256#define GET_REGINFO_TARGET_DESC
257#include "NVPTXGenRegisterInfo.inc"
258
259/// NVPTX Callee Saved Registers
260const uint16_t* NVPTXRegisterInfo::
261getCalleeSavedRegs(const MachineFunction *MF) const {
262  static const uint16_t CalleeSavedRegs[] = { 0 };
263  return CalleeSavedRegs;
264}
265
266// NVPTX Callee Saved Reg Classes
267const TargetRegisterClass* const*
268NVPTXRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
269  static const TargetRegisterClass * const CalleeSavedRegClasses[] = { 0 };
270  return CalleeSavedRegClasses;
271}
272
273BitVector NVPTXRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
274  BitVector Reserved(getNumRegs());
275  return Reserved;
276}
277
278void NVPTXRegisterInfo::
279eliminateFrameIndex(MachineBasicBlock::iterator II,
280                    int SPAdj,
281                    RegScavenger *RS) const {
282  assert(SPAdj == 0 && "Unexpected");
283
284  unsigned i = 0;
285  MachineInstr &MI = *II;
286  while (!MI.getOperand(i).isFI()) {
287    ++i;
288    assert(i < MI.getNumOperands() &&
289           "Instr doesn't have FrameIndex operand!");
290  }
291
292  int FrameIndex = MI.getOperand(i).getIndex();
293
294  MachineFunction &MF = *MI.getParent()->getParent();
295  int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
296      MI.getOperand(i+1).getImm();
297
298  // Using I0 as the frame pointer
299  MI.getOperand(i).ChangeToRegister(NVPTX::VRFrame, false);
300  MI.getOperand(i+1).ChangeToImmediate(Offset);
301}
302
303
304int NVPTXRegisterInfo::
305getDwarfRegNum(unsigned RegNum, bool isEH) const {
306  return 0;
307}
308
309unsigned NVPTXRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
310  return NVPTX::VRFrame;
311}
312
313unsigned NVPTXRegisterInfo::getRARegister() const {
314  return 0;
315}
316
317// This function eliminates ADJCALLSTACKDOWN,
318// ADJCALLSTACKUP pseudo instructions
319void NVPTXRegisterInfo::
320eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
321                              MachineBasicBlock::iterator I) const {
322  // Simply discard ADJCALLSTACKDOWN,
323  // ADJCALLSTACKUP instructions.
324  MBB.erase(I);
325}
326