blob: 0aebc820521989fff32f71d27fe84d1c05fc26e3 [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();
Che-Liang Chiouf78847e2011-03-14 11:26:01 +0000103 return i != -1 && MI->getOperand(i).getReg() != PTX::NoRegister;
Che-Liang Chiouc2ec0f92011-03-13 17:26:00 +0000104}
105
106bool PTXInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const {
107 return !isPredicated(MI) && get(MI->getOpcode()).isTerminator();
108}
109
110bool PTXInstrInfo::
111PredicateInstruction(MachineInstr *MI,
112 const SmallVectorImpl<MachineOperand> &Pred) const {
113 if (Pred.size() < 2)
114 llvm_unreachable("lesser than 2 predicate operands are provided");
115
116 int i = MI->findFirstPredOperandIdx();
117 if (i == -1)
118 llvm_unreachable("missing predicate operand");
119
120 MI->getOperand(i).setReg(Pred[0].getReg());
121 MI->getOperand(i+1).setImm(Pred[1].getImm());
122
123 return true;
124}
125
126bool PTXInstrInfo::
127SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
128 const SmallVectorImpl<MachineOperand> &Pred2) const {
129 // TODO Implement SubsumesPredicate
130 // Returns true if the first specified predicate subsumes the second,
131 // e.g. GE subsumes GT.
132 return false;
133}
134
135
136bool PTXInstrInfo::
137DefinesPredicate(MachineInstr *MI,
138 std::vector<MachineOperand> &Pred) const {
139 // TODO Implement DefinesPredicate
140 // If the specified instruction defines any predicate or condition code
141 // register(s) used for predication, returns true as well as the definition
142 // predicate(s) by reference.
Che-Liang Chiouf78847e2011-03-14 11:26:01 +0000143
144 switch (MI->getOpcode()) {
145 default:
146 return false;
147 case PTX::SETPEQu32rr:
148 case PTX::SETPEQu32ri:
149 case PTX::SETPNEu32rr:
150 case PTX::SETPNEu32ri:
151 case PTX::SETPLTu32rr:
152 case PTX::SETPLTu32ri:
153 case PTX::SETPLEu32rr:
154 case PTX::SETPLEu32ri:
155 case PTX::SETPGTu32rr:
156 case PTX::SETPGTu32ri:
157 case PTX::SETPGEu32rr:
158 case PTX::SETPGEu32ri: {
159 const MachineOperand &MO = MI->getOperand(0);
160 assert(MO.isReg() && RI.getRegClass(MO.getReg()) == &PTX::PredsRegClass);
161 Pred.push_back(MO);
162 Pred.push_back(MachineOperand::CreateImm(PTX::PRED_NORMAL));
163 return true;
164 }
165 }
Che-Liang Chiouc2ec0f92011-03-13 17:26:00 +0000166}
167
168// static helper routines
169
170MachineSDNode *PTXInstrInfo::
171GetPTXMachineNode(SelectionDAG *DAG, unsigned Opcode,
172 DebugLoc dl, EVT VT, SDValue Op1) {
Che-Liang Chiouf78847e2011-03-14 11:26:01 +0000173 SDValue predReg = DAG->getRegister(PTX::NoRegister, MVT::i1);
174 SDValue predOp = DAG->getTargetConstant(PTX::PRED_NORMAL, MVT::i32);
Che-Liang Chiouc2ec0f92011-03-13 17:26:00 +0000175 SDValue ops[] = { Op1, predReg, predOp };
176 return DAG->getMachineNode(Opcode, dl, VT, ops, array_lengthof(ops));
177}
178
179MachineSDNode *PTXInstrInfo::
180GetPTXMachineNode(SelectionDAG *DAG, unsigned Opcode,
181 DebugLoc dl, EVT VT, SDValue Op1, SDValue Op2) {
Che-Liang Chiouf78847e2011-03-14 11:26:01 +0000182 SDValue predReg = DAG->getRegister(PTX::NoRegister, MVT::i1);
183 SDValue predOp = DAG->getTargetConstant(PTX::PRED_NORMAL, MVT::i32);
Che-Liang Chiouc2ec0f92011-03-13 17:26:00 +0000184 SDValue ops[] = { Op1, Op2, predReg, predOp };
185 return DAG->getMachineNode(Opcode, dl, VT, ops, array_lengthof(ops));
186}
187
188void PTXInstrInfo::AddDefaultPredicate(MachineInstr *MI) {
189 if (MI->findFirstPredOperandIdx() == -1) {
190 MI->addOperand(MachineOperand::CreateReg(0, /*IsDef=*/false));
Che-Liang Chiouf78847e2011-03-14 11:26:01 +0000191 MI->addOperand(MachineOperand::CreateImm(PTX::PRED_NORMAL));
Che-Liang Chiouc2ec0f92011-03-13 17:26:00 +0000192 }
193}