Eric Christopher | 50880d0 | 2010-09-18 18:52:28 +0000 | [diff] [blame] | 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 | |
Che-Liang Chiou | b48f2c2 | 2010-10-19 13:14:40 +0000 | [diff] [blame] | 14 | #include "PTX.h" |
Eric Christopher | 50880d0 | 2010-09-18 18:52:28 +0000 | [diff] [blame] | 15 | #include "PTXInstrInfo.h" |
Che-Liang Chiou | b48f2c2 | 2010-10-19 13:14:40 +0000 | [diff] [blame] | 16 | #include "llvm/CodeGen/MachineInstrBuilder.h" |
Che-Liang Chiou | c2ec0f9 | 2011-03-13 17:26:00 +0000 | [diff] [blame] | 17 | #include "llvm/CodeGen/SelectionDAG.h" |
| 18 | #include "llvm/CodeGen/SelectionDAGNodes.h" |
Eric Christopher | 50880d0 | 2010-09-18 18:52:28 +0000 | [diff] [blame] | 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) {} |
Che-Liang Chiou | b48f2c2 | 2010-10-19 13:14:40 +0000 | [diff] [blame] | 27 | |
| 28 | static const struct map_entry { |
| 29 | const TargetRegisterClass *cls; |
| 30 | const int opcode; |
| 31 | } map[] = { |
Che-Liang Chiou | fd8978b | 2011-03-02 03:20:28 +0000 | [diff] [blame] | 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 } |
Che-Liang Chiou | b48f2c2 | 2010-10-19 13:14:40 +0000 | [diff] [blame] | 38 | }; |
| 39 | |
| 40 | void PTXInstrInfo::copyPhysReg(MachineBasicBlock &MBB, |
| 41 | MachineBasicBlock::iterator I, DebugLoc DL, |
| 42 | unsigned DstReg, unsigned SrcReg, |
| 43 | bool KillSrc) const { |
Che-Liang Chiou | f717202 | 2011-02-28 06:34:09 +0000 | [diff] [blame] | 44 | for (int i = 0, e = sizeof(map)/sizeof(map[0]); i != e; ++ i) { |
| 45 | if (map[i].cls->contains(DstReg, SrcReg)) { |
Che-Liang Chiou | c2ec0f9 | 2011-03-13 17:26:00 +0000 | [diff] [blame] | 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); |
Che-Liang Chiou | b48f2c2 | 2010-10-19 13:14:40 +0000 | [diff] [blame] | 50 | return; |
| 51 | } |
Che-Liang Chiou | f717202 | 2011-02-28 06:34:09 +0000 | [diff] [blame] | 52 | } |
Che-Liang Chiou | b48f2c2 | 2010-10-19 13:14:40 +0000 | [diff] [blame] | 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) { |
Che-Liang Chiou | c2ec0f9 | 2011-03-13 17:26:00 +0000 | [diff] [blame] | 68 | const TargetInstrDesc &TID = get(map[i].opcode); |
| 69 | MachineInstr *MI = BuildMI(MBB, I, DL, TID, DstReg).addReg(SrcReg); |
| 70 | AddDefaultPredicate(MI); |
Che-Liang Chiou | b48f2c2 | 2010-10-19 13:14:40 +0000 | [diff] [blame] | 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; |
Che-Liang Chiou | fd8978b | 2011-03-02 03:20:28 +0000 | [diff] [blame] | 83 | 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 Chiou | b48f2c2 | 2010-10-19 13:14:40 +0000 | [diff] [blame] | 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 | } |
Che-Liang Chiou | c2ec0f9 | 2011-03-13 17:26:00 +0000 | [diff] [blame] | 98 | |
| 99 | // predicate support |
| 100 | |
| 101 | bool PTXInstrInfo::isPredicated(const MachineInstr *MI) const { |
| 102 | int i = MI->findFirstPredOperandIdx(); |
Che-Liang Chiou | f78847e | 2011-03-14 11:26:01 +0000 | [diff] [blame^] | 103 | return i != -1 && MI->getOperand(i).getReg() != PTX::NoRegister; |
Che-Liang Chiou | c2ec0f9 | 2011-03-13 17:26:00 +0000 | [diff] [blame] | 104 | } |
| 105 | |
| 106 | bool PTXInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const { |
| 107 | return !isPredicated(MI) && get(MI->getOpcode()).isTerminator(); |
| 108 | } |
| 109 | |
| 110 | bool PTXInstrInfo:: |
| 111 | PredicateInstruction(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 | |
| 126 | bool PTXInstrInfo:: |
| 127 | SubsumesPredicate(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 | |
| 136 | bool PTXInstrInfo:: |
| 137 | DefinesPredicate(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 Chiou | f78847e | 2011-03-14 11:26:01 +0000 | [diff] [blame^] | 143 | |
| 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 Chiou | c2ec0f9 | 2011-03-13 17:26:00 +0000 | [diff] [blame] | 166 | } |
| 167 | |
| 168 | // static helper routines |
| 169 | |
| 170 | MachineSDNode *PTXInstrInfo:: |
| 171 | GetPTXMachineNode(SelectionDAG *DAG, unsigned Opcode, |
| 172 | DebugLoc dl, EVT VT, SDValue Op1) { |
Che-Liang Chiou | f78847e | 2011-03-14 11:26:01 +0000 | [diff] [blame^] | 173 | SDValue predReg = DAG->getRegister(PTX::NoRegister, MVT::i1); |
| 174 | SDValue predOp = DAG->getTargetConstant(PTX::PRED_NORMAL, MVT::i32); |
Che-Liang Chiou | c2ec0f9 | 2011-03-13 17:26:00 +0000 | [diff] [blame] | 175 | SDValue ops[] = { Op1, predReg, predOp }; |
| 176 | return DAG->getMachineNode(Opcode, dl, VT, ops, array_lengthof(ops)); |
| 177 | } |
| 178 | |
| 179 | MachineSDNode *PTXInstrInfo:: |
| 180 | GetPTXMachineNode(SelectionDAG *DAG, unsigned Opcode, |
| 181 | DebugLoc dl, EVT VT, SDValue Op1, SDValue Op2) { |
Che-Liang Chiou | f78847e | 2011-03-14 11:26:01 +0000 | [diff] [blame^] | 182 | SDValue predReg = DAG->getRegister(PTX::NoRegister, MVT::i1); |
| 183 | SDValue predOp = DAG->getTargetConstant(PTX::PRED_NORMAL, MVT::i32); |
Che-Liang Chiou | c2ec0f9 | 2011-03-13 17:26:00 +0000 | [diff] [blame] | 184 | SDValue ops[] = { Op1, Op2, predReg, predOp }; |
| 185 | return DAG->getMachineNode(Opcode, dl, VT, ops, array_lengthof(ops)); |
| 186 | } |
| 187 | |
| 188 | void PTXInstrInfo::AddDefaultPredicate(MachineInstr *MI) { |
| 189 | if (MI->findFirstPredOperandIdx() == -1) { |
| 190 | MI->addOperand(MachineOperand::CreateReg(0, /*IsDef=*/false)); |
Che-Liang Chiou | f78847e | 2011-03-14 11:26:01 +0000 | [diff] [blame^] | 191 | MI->addOperand(MachineOperand::CreateImm(PTX::PRED_NORMAL)); |
Che-Liang Chiou | c2ec0f9 | 2011-03-13 17:26:00 +0000 | [diff] [blame] | 192 | } |
| 193 | } |