blob: 8c2145d26c7126e8eee8b4cffb88b45b30f8636e [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 Chioub48f2c22010-10-19 13:14:40 +000014#include "PTX.h"
Eric Christopher50880d02010-09-18 18:52:28 +000015#include "PTXInstrInfo.h"
Che-Liang Chioub48f2c22010-10-19 13:14:40 +000016#include "llvm/CodeGen/MachineInstrBuilder.h"
Che-Liang Chiouc2ec0f92011-03-13 17:26:00 +000017#include "llvm/CodeGen/SelectionDAG.h"
18#include "llvm/CodeGen/SelectionDAGNodes.h"
Eric Christopher50880d02010-09-18 18:52:28 +000019
20using namespace llvm;
21
22#include "PTXGenInstrInfo.inc"
23
24PTXInstrInfo::PTXInstrInfo(PTXTargetMachine &_TM)
25 : TargetInstrInfoImpl(PTXInsts, array_lengthof(PTXInsts)),
26 RI(_TM, *this), TM(_TM) {}
Che-Liang Chioub48f2c22010-10-19 13:14:40 +000027
28static const struct map_entry {
29 const TargetRegisterClass *cls;
30 const int opcode;
31} map[] = {
Che-Liang Chioufd8978b2011-03-02 03:20:28 +000032 { &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 }
Che-Liang Chioub48f2c22010-10-19 13:14:40 +000038};
39
40void PTXInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
41 MachineBasicBlock::iterator I, DebugLoc DL,
42 unsigned DstReg, unsigned SrcReg,
43 bool KillSrc) const {
Che-Liang Chiouf7172022011-02-28 06:34:09 +000044 for (int i = 0, e = sizeof(map)/sizeof(map[0]); i != e; ++ i) {
45 if (map[i].cls->contains(DstReg, SrcReg)) {
Che-Liang Chiouc2ec0f92011-03-13 17:26:00 +000046 const TargetInstrDesc &TID = get(map[i].opcode);
47 MachineInstr *MI = BuildMI(MBB, I, DL, TID, DstReg).
48 addReg(SrcReg, getKillRegState(KillSrc));
49 AddDefaultPredicate(MI);
Che-Liang Chioub48f2c22010-10-19 13:14:40 +000050 return;
51 }
Che-Liang Chiouf7172022011-02-28 06:34:09 +000052 }
Che-Liang Chioub48f2c22010-10-19 13:14:40 +000053
54 llvm_unreachable("Impossible reg-to-reg copy");
55}
56
57bool 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) {
Che-Liang Chiouc2ec0f92011-03-13 17:26:00 +000068 const TargetInstrDesc &TID = get(map[i].opcode);
69 MachineInstr *MI = BuildMI(MBB, I, DL, TID, DstReg).addReg(SrcReg);
70 AddDefaultPredicate(MI);
Che-Liang Chioub48f2c22010-10-19 13:14:40 +000071 return true;
72 }
73
74 return false;
75}
76
77bool 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;
Che-Liang Chioufd8978b2011-03-02 03:20:28 +000083 case PTX::MOVU16rr:
84 case PTX::MOVU32rr:
85 case PTX::MOVU64rr:
86 case PTX::MOVF32rr:
87 case PTX::MOVF64rr:
88 case PTX::MOVPREDrr:
Che-Liang Chioub48f2c22010-10-19 13:14:40 +000089 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}
Che-Liang Chiouc2ec0f92011-03-13 17:26:00 +000098
99// predicate support
100
101bool 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
109bool PTXInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const {
110 return !isPredicated(MI) && get(MI->getOpcode()).isTerminator();
111}
112
113bool PTXInstrInfo::
114PredicateInstruction(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
129bool PTXInstrInfo::
130SubsumesPredicate(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
139bool PTXInstrInfo::
140DefinesPredicate(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
151MachineSDNode *PTXInstrInfo::
152GetPTXMachineNode(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
160MachineSDNode *PTXInstrInfo::
161GetPTXMachineNode(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
169void 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}