Merge XXXGenRegisterNames.inc into XXXGenRegisterInfo.inc
[oota-llvm.git] / lib / Target / PTX / PTXInstrInfo.cpp
1 //===- PTXInstrInfo.cpp - PTX 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 // This file contains the PTX implementation of the TargetInstrInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #define DEBUG_TYPE "ptx-instrinfo"
15
16 #include "PTX.h"
17 #include "PTXInstrInfo.h"
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
19 #include "llvm/CodeGen/SelectionDAG.h"
20 #include "llvm/CodeGen/SelectionDAGNodes.h"
21 #include "llvm/Support/Debug.h"
22 #include "llvm/Support/raw_ostream.h"
23
24 #define GET_INSTRINFO_MC_DESC
25 #include "PTXGenInstrInfo.inc"
26
27 using namespace llvm;
28
29 PTXInstrInfo::PTXInstrInfo(PTXTargetMachine &_TM)
30   : TargetInstrInfoImpl(PTXInsts, array_lengthof(PTXInsts)),
31     RI(_TM, *this), TM(_TM) {}
32
33 static const struct map_entry {
34   const TargetRegisterClass *cls;
35   const int opcode;
36 } map[] = {
37   { &PTX::RegI16RegClass, PTX::MOVU16rr },
38   { &PTX::RegI32RegClass, PTX::MOVU32rr },
39   { &PTX::RegI64RegClass, PTX::MOVU64rr },
40   { &PTX::RegF32RegClass, PTX::MOVF32rr },
41   { &PTX::RegF64RegClass, PTX::MOVF64rr },
42   { &PTX::RegPredRegClass,   PTX::MOVPREDrr }
43 };
44
45 void PTXInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
46                                MachineBasicBlock::iterator I, DebugLoc DL,
47                                unsigned DstReg, unsigned SrcReg,
48                                bool KillSrc) const {
49   for (int i = 0, e = sizeof(map)/sizeof(map[0]); i != e; ++ i) {
50     if (map[i].cls->contains(DstReg, SrcReg)) {
51       const MCInstrDesc &MCID = get(map[i].opcode);
52       MachineInstr *MI = BuildMI(MBB, I, DL, MCID, DstReg).
53         addReg(SrcReg, getKillRegState(KillSrc));
54       AddDefaultPredicate(MI);
55       return;
56     }
57   }
58
59   llvm_unreachable("Impossible reg-to-reg copy");
60 }
61
62 bool PTXInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
63                                 MachineBasicBlock::iterator I,
64                                 unsigned DstReg, unsigned SrcReg,
65                                 const TargetRegisterClass *DstRC,
66                                 const TargetRegisterClass *SrcRC,
67                                 DebugLoc DL) const {
68   if (DstRC != SrcRC)
69     return false;
70
71   for (int i = 0, e = sizeof(map)/sizeof(map[0]); i != e; ++ i)
72     if (DstRC == map[i].cls) {
73       const MCInstrDesc &MCID = get(map[i].opcode);
74       MachineInstr *MI = BuildMI(MBB, I, DL, MCID, DstReg).addReg(SrcReg);
75       AddDefaultPredicate(MI);
76       return true;
77     }
78
79   return false;
80 }
81
82 bool PTXInstrInfo::isMoveInstr(const MachineInstr& MI,
83                                unsigned &SrcReg, unsigned &DstReg,
84                                unsigned &SrcSubIdx, unsigned &DstSubIdx) const {
85   switch (MI.getOpcode()) {
86     default:
87       return false;
88     case PTX::MOVU16rr:
89     case PTX::MOVU32rr:
90     case PTX::MOVU64rr:
91     case PTX::MOVF32rr:
92     case PTX::MOVF64rr:
93     case PTX::MOVPREDrr:
94       assert(MI.getNumOperands() >= 2 &&
95              MI.getOperand(0).isReg() && MI.getOperand(1).isReg() &&
96              "Invalid register-register move instruction");
97       SrcSubIdx = DstSubIdx = 0; // No sub-registers
98       DstReg = MI.getOperand(0).getReg();
99       SrcReg = MI.getOperand(1).getReg();
100       return true;
101   }
102 }
103
104 // predicate support
105
106 bool PTXInstrInfo::isPredicated(const MachineInstr *MI) const {
107   int i = MI->findFirstPredOperandIdx();
108   return i != -1 && MI->getOperand(i).getReg() != PTX::NoRegister;
109 }
110
111 bool PTXInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const {
112   return !isPredicated(MI) && get(MI->getOpcode()).isTerminator();
113 }
114
115 bool PTXInstrInfo::
116 PredicateInstruction(MachineInstr *MI,
117                      const SmallVectorImpl<MachineOperand> &Pred) const {
118   if (Pred.size() < 2)
119     llvm_unreachable("lesser than 2 predicate operands are provided");
120
121   int i = MI->findFirstPredOperandIdx();
122   if (i == -1)
123     llvm_unreachable("missing predicate operand");
124
125   MI->getOperand(i).setReg(Pred[0].getReg());
126   MI->getOperand(i+1).setImm(Pred[1].getImm());
127
128   return true;
129 }
130
131 bool PTXInstrInfo::
132 SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
133                   const SmallVectorImpl<MachineOperand> &Pred2) const {
134   const MachineOperand &PredReg1 = Pred1[0];
135   const MachineOperand &PredReg2 = Pred2[0];
136   if (PredReg1.getReg() != PredReg2.getReg())
137     return false;
138
139   const MachineOperand &PredOp1 = Pred1[1];
140   const MachineOperand &PredOp2 = Pred2[1];
141   if (PredOp1.getImm() != PredOp2.getImm())
142     return false;
143
144   return true;
145 }
146
147 bool PTXInstrInfo::
148 DefinesPredicate(MachineInstr *MI,
149                  std::vector<MachineOperand> &Pred) const {
150   // If an instruction sets a predicate register, it defines a predicate.
151
152   // TODO supprot 5-operand format of setp instruction
153
154   if (MI->getNumOperands() < 1)
155     return false;
156
157   const MachineOperand &MO = MI->getOperand(0);
158
159   if (!MO.isReg() || RI.getRegClass(MO.getReg()) != &PTX::RegPredRegClass)
160     return false;
161
162   Pred.push_back(MO);
163   Pred.push_back(MachineOperand::CreateImm(PTX::PRED_NORMAL));
164   return true;
165 }
166
167 // branch support
168
169 bool PTXInstrInfo::
170 AnalyzeBranch(MachineBasicBlock &MBB,
171               MachineBasicBlock *&TBB,
172               MachineBasicBlock *&FBB,
173               SmallVectorImpl<MachineOperand> &Cond,
174               bool AllowModify) const {
175   // TODO implement cases when AllowModify is true
176
177   if (MBB.empty())
178     return true;
179
180   MachineBasicBlock::const_iterator iter = MBB.end();
181   const MachineInstr& instLast1 = *--iter;
182   const MCInstrDesc &desc1 = instLast1.getDesc();
183   // for special case that MBB has only 1 instruction
184   const bool IsSizeOne = MBB.size() == 1;
185   // if IsSizeOne is true, *--iter and instLast2 are invalid
186   // we put a dummy value in instLast2 and desc2 since they are used
187   const MachineInstr& instLast2 = IsSizeOne ? instLast1 : *--iter;
188   const MCInstrDesc &desc2 = IsSizeOne ? desc1 : instLast2.getDesc();
189
190   DEBUG(dbgs() << "\n");
191   DEBUG(dbgs() << "AnalyzeBranch: opcode: " << instLast1.getOpcode() << "\n");
192   DEBUG(dbgs() << "AnalyzeBranch: MBB:    " << MBB.getName().str() << "\n");
193   DEBUG(dbgs() << "AnalyzeBranch: TBB:    " << TBB << "\n");
194   DEBUG(dbgs() << "AnalyzeBranch: FBB:    " << FBB << "\n");
195
196   // this block ends with no branches
197   if (!IsAnyKindOfBranch(instLast1)) {
198     DEBUG(dbgs() << "AnalyzeBranch: ends with no branch\n");
199     return false;
200   }
201
202   // this block ends with only an unconditional branch
203   if (desc1.isUnconditionalBranch() &&
204       // when IsSizeOne is true, it "absorbs" the evaluation of instLast2
205       (IsSizeOne || !IsAnyKindOfBranch(instLast2))) {
206     DEBUG(dbgs() << "AnalyzeBranch: ends with only uncond branch\n");
207     TBB = GetBranchTarget(instLast1);
208     return false;
209   }
210
211   // this block ends with a conditional branch and
212   // it falls through to a successor block
213   if (desc1.isConditionalBranch() &&
214       IsAnySuccessorAlsoLayoutSuccessor(MBB)) {
215     DEBUG(dbgs() << "AnalyzeBranch: ends with cond branch and fall through\n");
216     TBB = GetBranchTarget(instLast1);
217     int i = instLast1.findFirstPredOperandIdx();
218     Cond.push_back(instLast1.getOperand(i));
219     Cond.push_back(instLast1.getOperand(i+1));
220     return false;
221   }
222
223   // when IsSizeOne is true, we are done
224   if (IsSizeOne)
225     return true;
226
227   // this block ends with a conditional branch
228   // followed by an unconditional branch
229   if (desc2.isConditionalBranch() &&
230       desc1.isUnconditionalBranch()) {
231     DEBUG(dbgs() << "AnalyzeBranch: ends with cond and uncond branch\n");
232     TBB = GetBranchTarget(instLast2);
233     FBB = GetBranchTarget(instLast1);
234     int i = instLast2.findFirstPredOperandIdx();
235     Cond.push_back(instLast2.getOperand(i));
236     Cond.push_back(instLast2.getOperand(i+1));
237     return false;
238   }
239
240   // branch cannot be understood
241   DEBUG(dbgs() << "AnalyzeBranch: cannot be understood\n");
242   return true;
243 }
244
245 unsigned PTXInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
246   unsigned count = 0;
247   while (!MBB.empty())
248     if (IsAnyKindOfBranch(MBB.back())) {
249       MBB.pop_back();
250       ++count;
251     } else
252       break;
253   DEBUG(dbgs() << "RemoveBranch: MBB:   " << MBB.getName().str() << "\n");
254   DEBUG(dbgs() << "RemoveBranch: remove " << count << " branch inst\n");
255   return count;
256 }
257
258 unsigned PTXInstrInfo::
259 InsertBranch(MachineBasicBlock &MBB,
260              MachineBasicBlock *TBB,
261              MachineBasicBlock *FBB,
262              const SmallVectorImpl<MachineOperand> &Cond,
263              DebugLoc DL) const {
264   DEBUG(dbgs() << "InsertBranch: MBB: " << MBB.getName().str() << "\n");
265   DEBUG(if (TBB) dbgs() << "InsertBranch: TBB: " << TBB->getName().str()
266                         << "\n";
267         else     dbgs() << "InsertBranch: TBB: (NULL)\n");
268   DEBUG(if (FBB) dbgs() << "InsertBranch: FBB: " << FBB->getName().str()
269                         << "\n";
270         else     dbgs() << "InsertBranch: FBB: (NULL)\n");
271   DEBUG(dbgs() << "InsertBranch: Cond size: " << Cond.size() << "\n");
272
273   assert(TBB && "TBB is NULL");
274
275   if (FBB) {
276     BuildMI(&MBB, DL, get(PTX::BRAdp))
277       .addMBB(TBB).addReg(Cond[0].getReg()).addImm(Cond[1].getImm());
278     BuildMI(&MBB, DL, get(PTX::BRAd))
279       .addMBB(FBB).addReg(PTX::NoRegister).addImm(PTX::PRED_NORMAL);
280     return 2;
281   } else if (Cond.size()) {
282     BuildMI(&MBB, DL, get(PTX::BRAdp))
283       .addMBB(TBB).addReg(Cond[0].getReg()).addImm(Cond[1].getImm());
284     return 1;
285   } else {
286     BuildMI(&MBB, DL, get(PTX::BRAd))
287       .addMBB(TBB).addReg(PTX::NoRegister).addImm(PTX::PRED_NORMAL);
288     return 1;
289   }
290 }
291
292 // Memory operand folding for spills
293 void PTXInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
294                                        MachineBasicBlock::iterator MII,
295                                      unsigned SrcReg, bool isKill, int FrameIdx,
296                                        const TargetRegisterClass *RC,
297                                        const TargetRegisterInfo *TRI) const {
298   MachineInstr& MI = *MII;
299   DebugLoc DL = MI.getDebugLoc();
300
301   DEBUG(dbgs() << "storeRegToStackSlot: " << MI);
302
303   int OpCode;
304
305   // Select the appropriate opcode based on the register class
306   if (RC == PTX::RegI16RegisterClass) {
307     OpCode = PTX::STACKSTOREI16;
308   }  else if (RC == PTX::RegI32RegisterClass) {
309     OpCode = PTX::STACKSTOREI32;
310   }  else if (RC == PTX::RegI64RegisterClass) {
311     OpCode = PTX::STACKSTOREI32;
312   }  else if (RC == PTX::RegF32RegisterClass) {
313     OpCode = PTX::STACKSTOREF32;
314   }  else if (RC == PTX::RegF64RegisterClass) {
315     OpCode = PTX::STACKSTOREF64;
316   } else {
317     llvm_unreachable("Unknown PTX register class!");
318   }
319
320   // Build the store instruction (really a mov)
321   MachineInstrBuilder MIB = BuildMI(MBB, MII, DL, get(OpCode));
322   MIB.addFrameIndex(FrameIdx);
323   MIB.addReg(SrcReg);
324
325   AddDefaultPredicate(MIB);
326 }
327
328 void PTXInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
329                                         MachineBasicBlock::iterator MII,
330                                         unsigned DestReg, int FrameIdx,
331                                         const TargetRegisterClass *RC,
332                                         const TargetRegisterInfo *TRI) const {
333   MachineInstr& MI = *MII;
334   DebugLoc DL = MI.getDebugLoc();
335
336   DEBUG(dbgs() << "loadRegToStackSlot: " << MI);
337
338   int OpCode;
339
340   // Select the appropriate opcode based on the register class
341   if (RC == PTX::RegI16RegisterClass) {
342     OpCode = PTX::STACKLOADI16;
343   } else if (RC == PTX::RegI32RegisterClass) {
344     OpCode = PTX::STACKLOADI32;
345   } else if (RC == PTX::RegI64RegisterClass) {
346     OpCode = PTX::STACKLOADI32;
347   } else if (RC == PTX::RegF32RegisterClass) {
348     OpCode = PTX::STACKLOADF32;
349   } else if (RC == PTX::RegF64RegisterClass) {
350     OpCode = PTX::STACKLOADF64;
351   } else {
352     llvm_unreachable("Unknown PTX register class!");
353   }
354
355   // Build the load instruction (really a mov)
356   MachineInstrBuilder MIB = BuildMI(MBB, MII, DL, get(OpCode));
357   MIB.addReg(DestReg);
358   MIB.addFrameIndex(FrameIdx);
359
360   AddDefaultPredicate(MIB);
361 }
362
363 // static helper routines
364
365 MachineSDNode *PTXInstrInfo::
366 GetPTXMachineNode(SelectionDAG *DAG, unsigned Opcode,
367                   DebugLoc dl, EVT VT, SDValue Op1) {
368   SDValue predReg = DAG->getRegister(PTX::NoRegister, MVT::i1);
369   SDValue predOp = DAG->getTargetConstant(PTX::PRED_NORMAL, MVT::i32);
370   SDValue ops[] = { Op1, predReg, predOp };
371   return DAG->getMachineNode(Opcode, dl, VT, ops, array_lengthof(ops));
372 }
373
374 MachineSDNode *PTXInstrInfo::
375 GetPTXMachineNode(SelectionDAG *DAG, unsigned Opcode,
376                   DebugLoc dl, EVT VT, SDValue Op1, SDValue Op2) {
377   SDValue predReg = DAG->getRegister(PTX::NoRegister, MVT::i1);
378   SDValue predOp = DAG->getTargetConstant(PTX::PRED_NORMAL, MVT::i32);
379   SDValue ops[] = { Op1, Op2, predReg, predOp };
380   return DAG->getMachineNode(Opcode, dl, VT, ops, array_lengthof(ops));
381 }
382
383 void PTXInstrInfo::AddDefaultPredicate(MachineInstr *MI) {
384   if (MI->findFirstPredOperandIdx() == -1) {
385     MI->addOperand(MachineOperand::CreateReg(PTX::NoRegister, /*IsDef=*/false));
386     MI->addOperand(MachineOperand::CreateImm(PTX::PRED_NORMAL));
387   }
388 }
389
390 bool PTXInstrInfo::IsAnyKindOfBranch(const MachineInstr& inst) {
391   const MCInstrDesc &desc = inst.getDesc();
392   return desc.isTerminator() || desc.isBranch() || desc.isIndirectBranch();
393 }
394
395 bool PTXInstrInfo::
396 IsAnySuccessorAlsoLayoutSuccessor(const MachineBasicBlock& MBB) {
397   for (MachineBasicBlock::const_succ_iterator
398       i = MBB.succ_begin(), e = MBB.succ_end(); i != e; ++i)
399     if (MBB.isLayoutSuccessor((const MachineBasicBlock*) &*i))
400       return true;
401   return false;
402 }
403
404 MachineBasicBlock *PTXInstrInfo::GetBranchTarget(const MachineInstr& inst) {
405   // FIXME So far all branch instructions put destination in 1st operand
406   const MachineOperand& target = inst.getOperand(0);
407   assert(target.isMBB() && "FIXME: detect branch target operand");
408   return target.getMBB();
409 }