ptx: add basic support of predicate execution
[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 #include "PTX.h"
15 #include "PTXInstrInfo.h"
16 #include "llvm/CodeGen/MachineInstrBuilder.h"
17 #include "llvm/CodeGen/SelectionDAG.h"
18 #include "llvm/CodeGen/SelectionDAGNodes.h"
19
20 using namespace llvm;
21
22 #include "PTXGenInstrInfo.inc"
23
24 PTXInstrInfo::PTXInstrInfo(PTXTargetMachine &_TM)
25   : TargetInstrInfoImpl(PTXInsts, array_lengthof(PTXInsts)),
26     RI(_TM, *this), TM(_TM) {}
27
28 static const struct map_entry {
29   const TargetRegisterClass *cls;
30   const int opcode;
31 } map[] = {
32   { &PTX::RRegu16RegClass, PTX::MOVU16rr },
33   { &PTX::RRegu32RegClass, PTX::MOVU32rr },
34   { &PTX::RRegu64RegClass, PTX::MOVU64rr },
35   { &PTX::RRegf32RegClass, PTX::MOVF32rr },
36   { &PTX::RRegf64RegClass, PTX::MOVF64rr },
37   { &PTX::PredsRegClass,   PTX::MOVPREDrr }
38 };
39
40 void PTXInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
41                                MachineBasicBlock::iterator I, DebugLoc DL,
42                                unsigned DstReg, unsigned SrcReg,
43                                bool KillSrc) const {
44   for (int i = 0, e = sizeof(map)/sizeof(map[0]); i != e; ++ i) {
45     if (map[i].cls->contains(DstReg, SrcReg)) {
46       const TargetInstrDesc &TID = get(map[i].opcode);
47       MachineInstr *MI = BuildMI(MBB, I, DL, TID, DstReg).
48         addReg(SrcReg, getKillRegState(KillSrc));
49       AddDefaultPredicate(MI);
50       return;
51     }
52   }
53
54   llvm_unreachable("Impossible reg-to-reg copy");
55 }
56
57 bool PTXInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
58                                 MachineBasicBlock::iterator I,
59                                 unsigned DstReg, unsigned SrcReg,
60                                 const TargetRegisterClass *DstRC,
61                                 const TargetRegisterClass *SrcRC,
62                                 DebugLoc DL) const {
63   if (DstRC != SrcRC)
64     return false;
65
66   for (int i = 0, e = sizeof(map)/sizeof(map[0]); i != e; ++ i)
67     if (DstRC == map[i].cls) {
68       const TargetInstrDesc &TID = get(map[i].opcode);
69       MachineInstr *MI = BuildMI(MBB, I, DL, TID, DstReg).addReg(SrcReg);
70       AddDefaultPredicate(MI);
71       return true;
72     }
73
74   return false;
75 }
76
77 bool PTXInstrInfo::isMoveInstr(const MachineInstr& MI,
78                                unsigned &SrcReg, unsigned &DstReg,
79                                unsigned &SrcSubIdx, unsigned &DstSubIdx) const {
80   switch (MI.getOpcode()) {
81     default:
82       return false;
83     case PTX::MOVU16rr:
84     case PTX::MOVU32rr:
85     case PTX::MOVU64rr:
86     case PTX::MOVF32rr:
87     case PTX::MOVF64rr:
88     case PTX::MOVPREDrr:
89       assert(MI.getNumOperands() >= 2 &&
90              MI.getOperand(0).isReg() && MI.getOperand(1).isReg() &&
91              "Invalid register-register move instruction");
92       SrcSubIdx = DstSubIdx = 0; // No sub-registers
93       DstReg = MI.getOperand(0).getReg();
94       SrcReg = MI.getOperand(1).getReg();
95       return true;
96   }
97 }
98
99 // predicate support
100
101 bool PTXInstrInfo::isPredicated(const MachineInstr *MI) const {
102   int i = MI->findFirstPredOperandIdx();
103   if (i == -1)
104     llvm_unreachable("missing predicate operand");
105   return MI->getOperand(i).getReg() ||
106          MI->getOperand(i+1).getImm() != PTX::PRED_IGNORE;
107 }
108
109 bool PTXInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const {
110   return !isPredicated(MI) && get(MI->getOpcode()).isTerminator();
111 }
112
113 bool PTXInstrInfo::
114 PredicateInstruction(MachineInstr *MI,
115                      const SmallVectorImpl<MachineOperand> &Pred) const {
116   if (Pred.size() < 2)
117     llvm_unreachable("lesser than 2 predicate operands are provided");
118
119   int i = MI->findFirstPredOperandIdx();
120   if (i == -1)
121     llvm_unreachable("missing predicate operand");
122
123   MI->getOperand(i).setReg(Pred[0].getReg());
124   MI->getOperand(i+1).setImm(Pred[1].getImm());
125
126   return true;
127 }
128
129 bool PTXInstrInfo::
130 SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
131                   const SmallVectorImpl<MachineOperand> &Pred2) const {
132   // TODO Implement SubsumesPredicate
133   // Returns true if the first specified predicate subsumes the second,
134   // e.g. GE subsumes GT.
135   return false;
136 }
137
138
139 bool PTXInstrInfo::
140 DefinesPredicate(MachineInstr *MI,
141                  std::vector<MachineOperand> &Pred) const {
142   // TODO Implement DefinesPredicate
143   // If the specified instruction defines any predicate or condition code
144   // register(s) used for predication, returns true as well as the definition
145   // predicate(s) by reference.
146   return false;
147 }
148
149 // static helper routines
150
151 MachineSDNode *PTXInstrInfo::
152 GetPTXMachineNode(SelectionDAG *DAG, unsigned Opcode,
153                   DebugLoc dl, EVT VT, SDValue Op1) {
154   SDValue predReg = DAG->getRegister(0, MVT::i1);
155   SDValue predOp = DAG->getTargetConstant(PTX::PRED_IGNORE, MVT::i1);
156   SDValue ops[] = { Op1, predReg, predOp };
157   return DAG->getMachineNode(Opcode, dl, VT, ops, array_lengthof(ops));
158 }
159
160 MachineSDNode *PTXInstrInfo::
161 GetPTXMachineNode(SelectionDAG *DAG, unsigned Opcode,
162                   DebugLoc dl, EVT VT, SDValue Op1, SDValue Op2) {
163   SDValue predReg = DAG->getRegister(0, MVT::i1);
164   SDValue predOp = DAG->getTargetConstant(PTX::PRED_IGNORE, MVT::i1);
165   SDValue ops[] = { Op1, Op2, predReg, predOp };
166   return DAG->getMachineNode(Opcode, dl, VT, ops, array_lengthof(ops));
167 }
168
169 void PTXInstrInfo::AddDefaultPredicate(MachineInstr *MI) {
170   if (MI->findFirstPredOperandIdx() == -1) {
171     MI->addOperand(MachineOperand::CreateReg(0, /*IsDef=*/false));
172     MI->addOperand(MachineOperand::CreateImm(PTX::PRED_IGNORE));
173   }
174 }