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(); |
| 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 | } |