blob: caa72b45ff906c3093276c529931349612638af6 [file] [log] [blame]
Eric Christopher50880d02010-09-18 18:52:28 +00001//===- 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
Che-Liang Chiou5e0872e2011-03-22 14:12:00 +000014#define DEBUG_TYPE "ptx-instrinfo"
15
Che-Liang Chioub48f2c22010-10-19 13:14:40 +000016#include "PTX.h"
Eric Christopher50880d02010-09-18 18:52:28 +000017#include "PTXInstrInfo.h"
Che-Liang Chioub48f2c22010-10-19 13:14:40 +000018#include "llvm/CodeGen/MachineInstrBuilder.h"
Che-Liang Chiouc2ec0f92011-03-13 17:26:00 +000019#include "llvm/CodeGen/SelectionDAG.h"
20#include "llvm/CodeGen/SelectionDAGNodes.h"
Evan Cheng59ee62d2011-07-11 03:57:24 +000021#include "llvm/Target/TargetRegistry.h"
Che-Liang Chiou5e0872e2011-03-22 14:12:00 +000022#include "llvm/Support/Debug.h"
23#include "llvm/Support/raw_ostream.h"
Eric Christopher50880d02010-09-18 18:52:28 +000024
Evan Cheng4db3cff2011-07-01 17:57:27 +000025#define GET_INSTRINFO_CTOR
Evan Cheng22fee2d2011-06-28 20:07:07 +000026#define GET_INSTRINFO_MC_DESC
Eric Christopher50880d02010-09-18 18:52:28 +000027#include "PTXGenInstrInfo.inc"
28
Evan Cheng22fee2d2011-06-28 20:07:07 +000029using namespace llvm;
30
Eric Christopher50880d02010-09-18 18:52:28 +000031PTXInstrInfo::PTXInstrInfo(PTXTargetMachine &_TM)
Evan Cheng4db3cff2011-07-01 17:57:27 +000032 : PTXGenInstrInfo(),
Eric Christopher50880d02010-09-18 18:52:28 +000033 RI(_TM, *this), TM(_TM) {}
Che-Liang Chioub48f2c22010-10-19 13:14:40 +000034
35static const struct map_entry {
36 const TargetRegisterClass *cls;
37 const int opcode;
38} map[] = {
Justin Holewinski1b91bcd2011-06-16 17:49:58 +000039 { &PTX::RegI16RegClass, PTX::MOVU16rr },
40 { &PTX::RegI32RegClass, PTX::MOVU32rr },
41 { &PTX::RegI64RegClass, PTX::MOVU64rr },
42 { &PTX::RegF32RegClass, PTX::MOVF32rr },
43 { &PTX::RegF64RegClass, PTX::MOVF64rr },
44 { &PTX::RegPredRegClass, PTX::MOVPREDrr }
Che-Liang Chioub48f2c22010-10-19 13:14:40 +000045};
46
47void PTXInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
48 MachineBasicBlock::iterator I, DebugLoc DL,
49 unsigned DstReg, unsigned SrcReg,
50 bool KillSrc) const {
Che-Liang Chiouf7172022011-02-28 06:34:09 +000051 for (int i = 0, e = sizeof(map)/sizeof(map[0]); i != e; ++ i) {
52 if (map[i].cls->contains(DstReg, SrcReg)) {
Evan Chenge837dea2011-06-28 19:10:37 +000053 const MCInstrDesc &MCID = get(map[i].opcode);
54 MachineInstr *MI = BuildMI(MBB, I, DL, MCID, DstReg).
Che-Liang Chiouc2ec0f92011-03-13 17:26:00 +000055 addReg(SrcReg, getKillRegState(KillSrc));
56 AddDefaultPredicate(MI);
Che-Liang Chioub48f2c22010-10-19 13:14:40 +000057 return;
58 }
Che-Liang Chiouf7172022011-02-28 06:34:09 +000059 }
Che-Liang Chioub48f2c22010-10-19 13:14:40 +000060
61 llvm_unreachable("Impossible reg-to-reg copy");
62}
63
64bool PTXInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
65 MachineBasicBlock::iterator I,
66 unsigned DstReg, unsigned SrcReg,
67 const TargetRegisterClass *DstRC,
68 const TargetRegisterClass *SrcRC,
69 DebugLoc DL) const {
70 if (DstRC != SrcRC)
71 return false;
72
73 for (int i = 0, e = sizeof(map)/sizeof(map[0]); i != e; ++ i)
74 if (DstRC == map[i].cls) {
Evan Chenge837dea2011-06-28 19:10:37 +000075 const MCInstrDesc &MCID = get(map[i].opcode);
76 MachineInstr *MI = BuildMI(MBB, I, DL, MCID, DstReg).addReg(SrcReg);
Che-Liang Chiouc2ec0f92011-03-13 17:26:00 +000077 AddDefaultPredicate(MI);
Che-Liang Chioub48f2c22010-10-19 13:14:40 +000078 return true;
79 }
80
81 return false;
82}
83
84bool PTXInstrInfo::isMoveInstr(const MachineInstr& MI,
85 unsigned &SrcReg, unsigned &DstReg,
86 unsigned &SrcSubIdx, unsigned &DstSubIdx) const {
87 switch (MI.getOpcode()) {
88 default:
89 return false;
Che-Liang Chioufd8978b2011-03-02 03:20:28 +000090 case PTX::MOVU16rr:
91 case PTX::MOVU32rr:
92 case PTX::MOVU64rr:
93 case PTX::MOVF32rr:
94 case PTX::MOVF64rr:
95 case PTX::MOVPREDrr:
Che-Liang Chioub48f2c22010-10-19 13:14:40 +000096 assert(MI.getNumOperands() >= 2 &&
97 MI.getOperand(0).isReg() && MI.getOperand(1).isReg() &&
98 "Invalid register-register move instruction");
99 SrcSubIdx = DstSubIdx = 0; // No sub-registers
100 DstReg = MI.getOperand(0).getReg();
101 SrcReg = MI.getOperand(1).getReg();
102 return true;
103 }
104}
Che-Liang Chiouc2ec0f92011-03-13 17:26:00 +0000105
106// predicate support
107
108bool PTXInstrInfo::isPredicated(const MachineInstr *MI) const {
109 int i = MI->findFirstPredOperandIdx();
Che-Liang Chiouf78847e2011-03-14 11:26:01 +0000110 return i != -1 && MI->getOperand(i).getReg() != PTX::NoRegister;
Che-Liang Chiouc2ec0f92011-03-13 17:26:00 +0000111}
112
113bool PTXInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const {
114 return !isPredicated(MI) && get(MI->getOpcode()).isTerminator();
115}
116
117bool PTXInstrInfo::
118PredicateInstruction(MachineInstr *MI,
119 const SmallVectorImpl<MachineOperand> &Pred) const {
120 if (Pred.size() < 2)
121 llvm_unreachable("lesser than 2 predicate operands are provided");
122
123 int i = MI->findFirstPredOperandIdx();
124 if (i == -1)
125 llvm_unreachable("missing predicate operand");
126
127 MI->getOperand(i).setReg(Pred[0].getReg());
128 MI->getOperand(i+1).setImm(Pred[1].getImm());
129
130 return true;
131}
132
133bool PTXInstrInfo::
134SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
135 const SmallVectorImpl<MachineOperand> &Pred2) const {
Che-Liang Chiou357be5e2011-04-02 08:51:39 +0000136 const MachineOperand &PredReg1 = Pred1[0];
137 const MachineOperand &PredReg2 = Pred2[0];
138 if (PredReg1.getReg() != PredReg2.getReg())
139 return false;
140
141 const MachineOperand &PredOp1 = Pred1[1];
142 const MachineOperand &PredOp2 = Pred2[1];
143 if (PredOp1.getImm() != PredOp2.getImm())
144 return false;
145
146 return true;
Che-Liang Chiouc2ec0f92011-03-13 17:26:00 +0000147}
148
Che-Liang Chiouc2ec0f92011-03-13 17:26:00 +0000149bool PTXInstrInfo::
150DefinesPredicate(MachineInstr *MI,
151 std::vector<MachineOperand> &Pred) const {
Che-Liang Chiou357be5e2011-04-02 08:51:39 +0000152 // If an instruction sets a predicate register, it defines a predicate.
Che-Liang Chiouf78847e2011-03-14 11:26:01 +0000153
Che-Liang Chiou357be5e2011-04-02 08:51:39 +0000154 // TODO supprot 5-operand format of setp instruction
155
156 if (MI->getNumOperands() < 1)
Che-Liang Chiouf78847e2011-03-14 11:26:01 +0000157 return false;
Che-Liang Chiou357be5e2011-04-02 08:51:39 +0000158
159 const MachineOperand &MO = MI->getOperand(0);
160
Justin Holewinski1b91bcd2011-06-16 17:49:58 +0000161 if (!MO.isReg() || RI.getRegClass(MO.getReg()) != &PTX::RegPredRegClass)
Che-Liang Chiou357be5e2011-04-02 08:51:39 +0000162 return false;
163
164 Pred.push_back(MO);
165 Pred.push_back(MachineOperand::CreateImm(PTX::PRED_NORMAL));
166 return true;
Che-Liang Chiouc2ec0f92011-03-13 17:26:00 +0000167}
168
Che-Liang Chiou5e0872e2011-03-22 14:12:00 +0000169// branch support
170
171bool PTXInstrInfo::
172AnalyzeBranch(MachineBasicBlock &MBB,
173 MachineBasicBlock *&TBB,
174 MachineBasicBlock *&FBB,
175 SmallVectorImpl<MachineOperand> &Cond,
176 bool AllowModify) const {
177 // TODO implement cases when AllowModify is true
178
179 if (MBB.empty())
180 return true;
181
182 MachineBasicBlock::const_iterator iter = MBB.end();
183 const MachineInstr& instLast1 = *--iter;
Evan Chenge837dea2011-06-28 19:10:37 +0000184 const MCInstrDesc &desc1 = instLast1.getDesc();
Che-Liang Chiou5e0872e2011-03-22 14:12:00 +0000185 // for special case that MBB has only 1 instruction
186 const bool IsSizeOne = MBB.size() == 1;
187 // if IsSizeOne is true, *--iter and instLast2 are invalid
188 // we put a dummy value in instLast2 and desc2 since they are used
189 const MachineInstr& instLast2 = IsSizeOne ? instLast1 : *--iter;
Evan Chenge837dea2011-06-28 19:10:37 +0000190 const MCInstrDesc &desc2 = IsSizeOne ? desc1 : instLast2.getDesc();
Che-Liang Chiou5e0872e2011-03-22 14:12:00 +0000191
192 DEBUG(dbgs() << "\n");
193 DEBUG(dbgs() << "AnalyzeBranch: opcode: " << instLast1.getOpcode() << "\n");
194 DEBUG(dbgs() << "AnalyzeBranch: MBB: " << MBB.getName().str() << "\n");
195 DEBUG(dbgs() << "AnalyzeBranch: TBB: " << TBB << "\n");
196 DEBUG(dbgs() << "AnalyzeBranch: FBB: " << FBB << "\n");
197
198 // this block ends with no branches
199 if (!IsAnyKindOfBranch(instLast1)) {
200 DEBUG(dbgs() << "AnalyzeBranch: ends with no branch\n");
201 return false;
202 }
203
204 // this block ends with only an unconditional branch
205 if (desc1.isUnconditionalBranch() &&
206 // when IsSizeOne is true, it "absorbs" the evaluation of instLast2
207 (IsSizeOne || !IsAnyKindOfBranch(instLast2))) {
208 DEBUG(dbgs() << "AnalyzeBranch: ends with only uncond branch\n");
209 TBB = GetBranchTarget(instLast1);
210 return false;
211 }
212
213 // this block ends with a conditional branch and
214 // it falls through to a successor block
215 if (desc1.isConditionalBranch() &&
216 IsAnySuccessorAlsoLayoutSuccessor(MBB)) {
217 DEBUG(dbgs() << "AnalyzeBranch: ends with cond branch and fall through\n");
218 TBB = GetBranchTarget(instLast1);
219 int i = instLast1.findFirstPredOperandIdx();
220 Cond.push_back(instLast1.getOperand(i));
221 Cond.push_back(instLast1.getOperand(i+1));
222 return false;
223 }
224
225 // when IsSizeOne is true, we are done
226 if (IsSizeOne)
227 return true;
228
229 // this block ends with a conditional branch
230 // followed by an unconditional branch
231 if (desc2.isConditionalBranch() &&
232 desc1.isUnconditionalBranch()) {
233 DEBUG(dbgs() << "AnalyzeBranch: ends with cond and uncond branch\n");
234 TBB = GetBranchTarget(instLast2);
235 FBB = GetBranchTarget(instLast1);
236 int i = instLast2.findFirstPredOperandIdx();
237 Cond.push_back(instLast2.getOperand(i));
238 Cond.push_back(instLast2.getOperand(i+1));
239 return false;
240 }
241
242 // branch cannot be understood
243 DEBUG(dbgs() << "AnalyzeBranch: cannot be understood\n");
244 return true;
245}
246
247unsigned PTXInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
Che-Liang Chioufb4a8342011-03-28 10:23:13 +0000248 unsigned count = 0;
249 while (!MBB.empty())
250 if (IsAnyKindOfBranch(MBB.back())) {
251 MBB.pop_back();
252 ++count;
253 } else
254 break;
Che-Liang Chiou5e0872e2011-03-22 14:12:00 +0000255 DEBUG(dbgs() << "RemoveBranch: MBB: " << MBB.getName().str() << "\n");
Che-Liang Chioufb4a8342011-03-28 10:23:13 +0000256 DEBUG(dbgs() << "RemoveBranch: remove " << count << " branch inst\n");
Che-Liang Chiou5e0872e2011-03-22 14:12:00 +0000257 return count;
258}
259
260unsigned PTXInstrInfo::
261InsertBranch(MachineBasicBlock &MBB,
262 MachineBasicBlock *TBB,
263 MachineBasicBlock *FBB,
264 const SmallVectorImpl<MachineOperand> &Cond,
265 DebugLoc DL) const {
266 DEBUG(dbgs() << "InsertBranch: MBB: " << MBB.getName().str() << "\n");
Che-Liang Chioufb4a8342011-03-28 10:23:13 +0000267 DEBUG(if (TBB) dbgs() << "InsertBranch: TBB: " << TBB->getName().str()
268 << "\n";
269 else dbgs() << "InsertBranch: TBB: (NULL)\n");
270 DEBUG(if (FBB) dbgs() << "InsertBranch: FBB: " << FBB->getName().str()
271 << "\n";
272 else dbgs() << "InsertBranch: FBB: (NULL)\n");
Che-Liang Chiou5e0872e2011-03-22 14:12:00 +0000273 DEBUG(dbgs() << "InsertBranch: Cond size: " << Cond.size() << "\n");
274
275 assert(TBB && "TBB is NULL");
276
277 if (FBB) {
278 BuildMI(&MBB, DL, get(PTX::BRAdp))
279 .addMBB(TBB).addReg(Cond[0].getReg()).addImm(Cond[1].getImm());
280 BuildMI(&MBB, DL, get(PTX::BRAd))
281 .addMBB(FBB).addReg(PTX::NoRegister).addImm(PTX::PRED_NORMAL);
282 return 2;
283 } else if (Cond.size()) {
284 BuildMI(&MBB, DL, get(PTX::BRAdp))
285 .addMBB(TBB).addReg(Cond[0].getReg()).addImm(Cond[1].getImm());
286 return 1;
287 } else {
288 BuildMI(&MBB, DL, get(PTX::BRAd))
289 .addMBB(TBB).addReg(PTX::NoRegister).addImm(PTX::PRED_NORMAL);
290 return 1;
291 }
292}
293
Justin Holewinskidf1c8d82011-06-20 15:56:20 +0000294// Memory operand folding for spills
295void PTXInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
296 MachineBasicBlock::iterator MII,
Justin Holewinski08d03162011-06-22 16:07:03 +0000297 unsigned SrcReg, bool isKill, int FrameIdx,
Justin Holewinskidf1c8d82011-06-20 15:56:20 +0000298 const TargetRegisterClass *RC,
299 const TargetRegisterInfo *TRI) const {
300 MachineInstr& MI = *MII;
301 DebugLoc DL = MI.getDebugLoc();
302
303 DEBUG(dbgs() << "storeRegToStackSlot: " << MI);
304
305 int OpCode;
306
307 // Select the appropriate opcode based on the register class
Dan Bailey84149462011-06-25 18:16:28 +0000308 if (RC == PTX::RegI16RegisterClass) {
Justin Holewinskidf1c8d82011-06-20 15:56:20 +0000309 OpCode = PTX::STACKSTOREI16;
Justin Holewinskicad129b2011-06-20 17:08:56 +0000310 } else if (RC == PTX::RegI32RegisterClass) {
Justin Holewinskidf1c8d82011-06-20 15:56:20 +0000311 OpCode = PTX::STACKSTOREI32;
Justin Holewinskicad129b2011-06-20 17:08:56 +0000312 } else if (RC == PTX::RegI64RegisterClass) {
Justin Holewinskidf1c8d82011-06-20 15:56:20 +0000313 OpCode = PTX::STACKSTOREI32;
Justin Holewinskicad129b2011-06-20 17:08:56 +0000314 } else if (RC == PTX::RegF32RegisterClass) {
Justin Holewinskidf1c8d82011-06-20 15:56:20 +0000315 OpCode = PTX::STACKSTOREF32;
Justin Holewinskicad129b2011-06-20 17:08:56 +0000316 } else if (RC == PTX::RegF64RegisterClass) {
Justin Holewinskidf1c8d82011-06-20 15:56:20 +0000317 OpCode = PTX::STACKSTOREF64;
Justin Holewinskicad129b2011-06-20 17:08:56 +0000318 } else {
319 llvm_unreachable("Unknown PTX register class!");
Justin Holewinskidf1c8d82011-06-20 15:56:20 +0000320 }
321
322 // Build the store instruction (really a mov)
323 MachineInstrBuilder MIB = BuildMI(MBB, MII, DL, get(OpCode));
Justin Holewinski08d03162011-06-22 16:07:03 +0000324 MIB.addFrameIndex(FrameIdx);
Justin Holewinskidf1c8d82011-06-20 15:56:20 +0000325 MIB.addReg(SrcReg);
326
327 AddDefaultPredicate(MIB);
328}
329
330void PTXInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
331 MachineBasicBlock::iterator MII,
332 unsigned DestReg, int FrameIdx,
333 const TargetRegisterClass *RC,
334 const TargetRegisterInfo *TRI) const {
335 MachineInstr& MI = *MII;
336 DebugLoc DL = MI.getDebugLoc();
337
338 DEBUG(dbgs() << "loadRegToStackSlot: " << MI);
339
340 int OpCode;
341
342 // Select the appropriate opcode based on the register class
Dan Bailey84149462011-06-25 18:16:28 +0000343 if (RC == PTX::RegI16RegisterClass) {
Justin Holewinskidf1c8d82011-06-20 15:56:20 +0000344 OpCode = PTX::STACKLOADI16;
Justin Holewinskicad129b2011-06-20 17:08:56 +0000345 } else if (RC == PTX::RegI32RegisterClass) {
Justin Holewinskidf1c8d82011-06-20 15:56:20 +0000346 OpCode = PTX::STACKLOADI32;
Justin Holewinskicad129b2011-06-20 17:08:56 +0000347 } else if (RC == PTX::RegI64RegisterClass) {
Justin Holewinskidf1c8d82011-06-20 15:56:20 +0000348 OpCode = PTX::STACKLOADI32;
Justin Holewinskicad129b2011-06-20 17:08:56 +0000349 } else if (RC == PTX::RegF32RegisterClass) {
Justin Holewinskidf1c8d82011-06-20 15:56:20 +0000350 OpCode = PTX::STACKLOADF32;
Justin Holewinskicad129b2011-06-20 17:08:56 +0000351 } else if (RC == PTX::RegF64RegisterClass) {
Justin Holewinskidf1c8d82011-06-20 15:56:20 +0000352 OpCode = PTX::STACKLOADF64;
Justin Holewinskicad129b2011-06-20 17:08:56 +0000353 } else {
354 llvm_unreachable("Unknown PTX register class!");
Justin Holewinskidf1c8d82011-06-20 15:56:20 +0000355 }
356
357 // Build the load instruction (really a mov)
358 MachineInstrBuilder MIB = BuildMI(MBB, MII, DL, get(OpCode));
359 MIB.addReg(DestReg);
Justin Holewinski08d03162011-06-22 16:07:03 +0000360 MIB.addFrameIndex(FrameIdx);
Justin Holewinskidf1c8d82011-06-20 15:56:20 +0000361
362 AddDefaultPredicate(MIB);
363}
364
Che-Liang Chiouc2ec0f92011-03-13 17:26:00 +0000365// static helper routines
366
367MachineSDNode *PTXInstrInfo::
368GetPTXMachineNode(SelectionDAG *DAG, unsigned Opcode,
369 DebugLoc dl, EVT VT, SDValue Op1) {
Che-Liang Chiouf78847e2011-03-14 11:26:01 +0000370 SDValue predReg = DAG->getRegister(PTX::NoRegister, MVT::i1);
371 SDValue predOp = DAG->getTargetConstant(PTX::PRED_NORMAL, MVT::i32);
Che-Liang Chiouc2ec0f92011-03-13 17:26:00 +0000372 SDValue ops[] = { Op1, predReg, predOp };
373 return DAG->getMachineNode(Opcode, dl, VT, ops, array_lengthof(ops));
374}
375
376MachineSDNode *PTXInstrInfo::
377GetPTXMachineNode(SelectionDAG *DAG, unsigned Opcode,
378 DebugLoc dl, EVT VT, SDValue Op1, SDValue Op2) {
Che-Liang Chiouf78847e2011-03-14 11:26:01 +0000379 SDValue predReg = DAG->getRegister(PTX::NoRegister, MVT::i1);
380 SDValue predOp = DAG->getTargetConstant(PTX::PRED_NORMAL, MVT::i32);
Che-Liang Chiouc2ec0f92011-03-13 17:26:00 +0000381 SDValue ops[] = { Op1, Op2, predReg, predOp };
382 return DAG->getMachineNode(Opcode, dl, VT, ops, array_lengthof(ops));
383}
384
385void PTXInstrInfo::AddDefaultPredicate(MachineInstr *MI) {
386 if (MI->findFirstPredOperandIdx() == -1) {
Che-Liang Chiou5e0872e2011-03-22 14:12:00 +0000387 MI->addOperand(MachineOperand::CreateReg(PTX::NoRegister, /*IsDef=*/false));
Che-Liang Chiouf78847e2011-03-14 11:26:01 +0000388 MI->addOperand(MachineOperand::CreateImm(PTX::PRED_NORMAL));
Che-Liang Chiouc2ec0f92011-03-13 17:26:00 +0000389 }
390}
Che-Liang Chiou5e0872e2011-03-22 14:12:00 +0000391
392bool PTXInstrInfo::IsAnyKindOfBranch(const MachineInstr& inst) {
Evan Chenge837dea2011-06-28 19:10:37 +0000393 const MCInstrDesc &desc = inst.getDesc();
Che-Liang Chiou5e0872e2011-03-22 14:12:00 +0000394 return desc.isTerminator() || desc.isBranch() || desc.isIndirectBranch();
395}
396
397bool PTXInstrInfo::
398IsAnySuccessorAlsoLayoutSuccessor(const MachineBasicBlock& MBB) {
399 for (MachineBasicBlock::const_succ_iterator
400 i = MBB.succ_begin(), e = MBB.succ_end(); i != e; ++i)
401 if (MBB.isLayoutSuccessor((const MachineBasicBlock*) &*i))
402 return true;
403 return false;
404}
405
406MachineBasicBlock *PTXInstrInfo::GetBranchTarget(const MachineInstr& inst) {
407 // FIXME So far all branch instructions put destination in 1st operand
408 const MachineOperand& target = inst.getOperand(0);
409 assert(target.isMBB() && "FIXME: detect branch target operand");
410 return target.getMBB();
411}
Evan Cheng59ee62d2011-07-11 03:57:24 +0000412
413MCInstrInfo *createPTXMCInstrInfo() {
414 MCInstrInfo *X = new MCInstrInfo();
415 InitPTXMCInstrInfo(X);
416 return X;
417}
418
419extern "C" void LLVMInitializePTXMCInstrInfo() {
420 TargetRegistry::RegisterMCInstrInfo(ThePTX32Target, createPTXMCInstrInfo);
421 TargetRegistry::RegisterMCInstrInfo(ThePTX64Target, createPTXMCInstrInfo);
422}