1 //===-- MachineInstr.cpp --------------------------------------------------===// 2 // 3 //===----------------------------------------------------------------------===// 4 5 #include "llvm/CodeGen/MachineInstr.h" 6 #include "llvm/Value.h" 7 #include "llvm/Target/MachineInstrInfo.h" // FIXME: shouldn't need this! 8 using std::cerr; 9 10 11 // Constructor for instructions with fixed #operands (nearly all) 12 MachineInstr::MachineInstr(MachineOpCode _opCode, 13 OpCodeMask _opCodeMask) 14 : opCode(_opCode), 15 opCodeMask(_opCodeMask), 16 operands(TargetInstrDescriptors[_opCode].numOperands) 17 { 18 assert(TargetInstrDescriptors[_opCode].numOperands >= 0); 19 } 20 21 // Constructor for instructions with variable #operands 22 MachineInstr::MachineInstr(MachineOpCode _opCode, 23 unsigned numOperands, 24 OpCodeMask _opCodeMask) 25 : opCode(_opCode), 26 opCodeMask(_opCodeMask), 27 operands(numOperands) 28 { 29 } 30 31 // 32 // Support for replacing opcode and operands of a MachineInstr in place. 33 // This only resets the size of the operand vector and initializes it. 34 // The new operands must be set explicitly later. 35 // 36 void 37 MachineInstr::replace(MachineOpCode _opCode, 38 unsigned numOperands, 39 OpCodeMask _opCodeMask) 40 { 41 opCode = _opCode; 42 opCodeMask = _opCodeMask; 43 operands.clear(); 44 operands.resize(numOperands); 45 } 46 47 void 48 MachineInstr::SetMachineOperandVal(unsigned int i, 49 MachineOperand::MachineOperandType opType, 50 Value* V, 51 bool isdef, 52 bool isDefAndUse) 53 { 54 assert(i < operands.size()); 55 operands[i].opType = opType; 56 operands[i].value = V; 57 operands[i].regNum = -1; 58 operands[i].flags = 0; 59 60 if (isdef || TargetInstrDescriptors[opCode].resultPos == (int) i) 61 operands[i].markDef(); 62 if (isDefAndUse) 63 operands[i].markDefAndUse(); 64 } 65 66 void 67 MachineInstr::SetMachineOperandConst(unsigned i, 68 MachineOperand::MachineOperandType operandType, 69 int64_t intValue) 70 { 71 assert(i < operands.size()); 72 assert(TargetInstrDescriptors[opCode].resultPos != (int) i && 73 "immed. constant cannot be defined"); 74 75 operands[i].opType = operandType; 76 operands[i].value = NULL; 77 operands[i].immedVal = intValue; 78 operands[i].regNum = -1; 79 operands[i].flags = 0; 80 } 81 82 void 83 MachineInstr::SetMachineOperandReg(unsigned i, 84 int regNum, 85 bool isdef, 86 bool isDefAndUse, 87 bool isCCReg) 88 { 89 assert(i < operands.size()); 90 91 operands[i].opType = 92 isCCReg? MachineOperand::MO_CCRegister : MachineOperand::MO_MachineRegister; 93 operands[i].value = NULL; 94 operands[i].regNum = regNum; 95 operands[i].flags = 0; 96 97 if (isdef || TargetInstrDescriptors[opCode].resultPos == (int) i) 98 operands[i].markDef(); 99 if (isDefAndUse) 100 operands[i].markDefAndUse(); 101 insertUsedReg(regNum); 102 } 103 104 void 105 MachineInstr::SetRegForOperand(unsigned i, int regNum) 106 { 107 operands[i].setRegForValue(regNum); 108 insertUsedReg(regNum); 109 } 110 111 112 // Subsitute all occurrences of Value* oldVal with newVal in all operands 113 // and all implicit refs. If defsOnly == true, substitute defs only. 114 unsigned 115 MachineInstr::substituteValue(const Value* oldVal, Value* newVal, bool defsOnly) 116 { 117 unsigned numSubst = 0; 118 119 // Subsitute operands 120 for (MachineInstr::val_op_iterator O = begin(), E = end(); O != E; ++O) 121 if (*O == oldVal) 122 if (!defsOnly || O.isDef()) 123 { 124 O.getMachineOperand().value = newVal; 125 ++numSubst; 126 } 127 128 // Subsitute implicit refs 129 for (unsigned i=0, N=implicitRefs.size(); i < N; ++i) 130 if (getImplicitRef(i) == oldVal) 131 if (!defsOnly || implicitRefIsDefined(i)) 132 { 133 implicitRefs[i].Val = newVal; 134 ++numSubst; 135 } 136 137 return numSubst; 138 } 139 140 141 void 142 MachineInstr::dump() const 143 { 144 cerr << " " << *this; 145 } 146 147 static inline std::ostream& 148 OutputValue(std::ostream &os, const Value* val) 149 { 150 os << "(val "; 151 if (val && val->hasName()) 152 return os << val->getName() << ")"; 153 else 154 return os << (void*) val << ")"; // print address only 155 } 156 157 static inline std::ostream& 158 OutputReg(std::ostream &os, unsigned int regNum) 159 { 160 return os << "%mreg(" << regNum << ")"; 161 } 162 163 std::ostream &operator<<(std::ostream& os, const MachineInstr& minstr) 164 { 165 os << TargetInstrDescriptors[minstr.opCode].opCodeString; 166 167 for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++) { 168 os << "\t" << minstr.getOperand(i); 169 if( minstr.operandIsDefined(i) ) 170 os << "*"; 171 if( minstr.operandIsDefinedAndUsed(i) ) 172 os << "*"; 173 } 174 175 // code for printing implict references 176 unsigned NumOfImpRefs = minstr.getNumImplicitRefs(); 177 if( NumOfImpRefs > 0 ) { 178 os << "\tImplicit: "; 179 for(unsigned z=0; z < NumOfImpRefs; z++) { 180 OutputValue(os, minstr.getImplicitRef(z)); 181 if( minstr.implicitRefIsDefined(z)) os << "*"; 182 if( minstr.implicitRefIsDefinedAndUsed(z)) os << "*"; 183 os << "\t"; 184 } 185 } 186 187 return os << "\n"; 188 } 189 190 std::ostream &operator<<(std::ostream &os, const MachineOperand &mop) 191 { 192 if (mop.opHiBits32()) 193 os << "%lm("; 194 else if (mop.opLoBits32()) 195 os << "%lo("; 196 else if (mop.opHiBits64()) 197 os << "%hh("; 198 else if (mop.opLoBits64()) 199 os << "%hm("; 200 201 switch(mop.opType) 202 { 203 case MachineOperand::MO_VirtualRegister: 204 os << "%reg"; 205 OutputValue(os, mop.getVRegValue()); 206 if (mop.hasAllocatedReg()) 207 os << "==" << OutputReg(os, mop.getAllocatedRegNum()); 208 break; 209 case MachineOperand::MO_CCRegister: 210 os << "%ccreg"; 211 OutputValue(os, mop.getVRegValue()); 212 if (mop.hasAllocatedReg()) 213 os << "==" << OutputReg(os, mop.getAllocatedRegNum()); 214 break; 215 case MachineOperand::MO_MachineRegister: 216 OutputReg(os, mop.getMachineRegNum()); 217 break; 218 case MachineOperand::MO_SignExtendedImmed: 219 os << (long)mop.immedVal; 220 break; 221 case MachineOperand::MO_UnextendedImmed: 222 os << (long)mop.immedVal; 223 break; 224 case MachineOperand::MO_PCRelativeDisp: 225 { 226 const Value* opVal = mop.getVRegValue(); 227 bool isLabel = isa<Function>(opVal) || isa<BasicBlock>(opVal); 228 os << "%disp(" << (isLabel? "label " : "addr-of-val "); 229 if (opVal->hasName()) 230 os << opVal->getName(); 231 else 232 os << (const void*) opVal; 233 os << ")"; 234 break; 235 } 236 default: 237 assert(0 && "Unrecognized operand type"); 238 break; 239 } 240 241 if (mop.flags & 242 (MachineOperand::HIFLAG32 | MachineOperand::LOFLAG32 | 243 MachineOperand::HIFLAG64 | MachineOperand::LOFLAG64)) 244 os << ")"; 245 246 return os; 247 } 248