1 //===-- MachineInstr.cpp --------------------------------------------------===// 2 // 3 //===----------------------------------------------------------------------===// 4 5 #include "llvm/CodeGen/MachineInstr.h" 6 #include "llvm/CodeGen/MachineBasicBlock.h" 7 #include "llvm/Value.h" 8 #include "llvm/Target/MachineInstrInfo.h" // FIXME: shouldn't need this! 9 #include "llvm/Target/TargetMachine.h" 10 using std::cerr; 11 12 // Global variable holding an array of descriptors for machine instructions. 13 // The actual object needs to be created separately for each target machine. 14 // This variable is initialized and reset by class MachineInstrInfo. 15 // 16 // FIXME: This should be a property of the target so that more than one target 17 // at a time can be active... 18 // 19 extern const MachineInstrDescriptor *TargetInstrDescriptors; 20 21 // Constructor for instructions with fixed #operands (nearly all) 22 MachineInstr::MachineInstr(MachineOpCode _opCode) 23 : opCode(_opCode), 24 operands(TargetInstrDescriptors[_opCode].numOperands, MachineOperand()), 25 numImplicitRefs(0) 26 { 27 assert(TargetInstrDescriptors[_opCode].numOperands >= 0); 28 } 29 30 // Constructor for instructions with variable #operands 31 MachineInstr::MachineInstr(MachineOpCode OpCode, unsigned numOperands) 32 : opCode(OpCode), 33 operands(numOperands, MachineOperand()), 34 numImplicitRefs(0) 35 { 36 } 37 38 /// MachineInstr ctor - This constructor only does a _reserve_ of the operands, 39 /// not a resize for them. It is expected that if you use this that you call 40 /// add* methods below to fill up the operands, instead of the Set methods. 41 /// Eventually, the "resizing" ctors will be phased out. 42 /// 43 MachineInstr::MachineInstr(MachineOpCode Opcode, unsigned numOperands, 44 bool XX, bool YY) 45 : opCode(Opcode), 46 numImplicitRefs(0) 47 { 48 operands.reserve(numOperands); 49 } 50 51 /// MachineInstr ctor - Work exactly the same as the ctor above, except that the 52 /// MachineInstr is created and added to the end of the specified basic block. 53 /// 54 MachineInstr::MachineInstr(MachineBasicBlock *MBB, MachineOpCode Opcode, 55 unsigned numOperands) 56 : opCode(Opcode), 57 numImplicitRefs(0) 58 { 59 assert(MBB && "Cannot use inserting ctor with null basic block!"); 60 operands.reserve(numOperands); 61 MBB->push_back(this); // Add instruction to end of basic block! 62 } 63 64 65 // OperandComplete - Return true if it's illegal to add a new operand 66 bool MachineInstr::OperandsComplete() const 67 { 68 int NumOperands = TargetInstrDescriptors[opCode].numOperands; 69 if (NumOperands >= 0 && getNumOperands() >= (unsigned)NumOperands) 70 return true; // Broken! 71 return false; 72 } 73 74 75 // 76 // Support for replacing opcode and operands of a MachineInstr in place. 77 // This only resets the size of the operand vector and initializes it. 78 // The new operands must be set explicitly later. 79 // 80 void MachineInstr::replace(MachineOpCode Opcode, unsigned numOperands) 81 { 82 assert(getNumImplicitRefs() == 0 && 83 "This is probably broken because implicit refs are going to be lost."); 84 opCode = Opcode; 85 operands.clear(); 86 operands.resize(numOperands, MachineOperand()); 87 } 88 89 void 90 MachineInstr::SetMachineOperandVal(unsigned i, 91 MachineOperand::MachineOperandType opType, 92 Value* V, 93 bool isdef, 94 bool isDefAndUse) 95 { 96 assert(i < operands.size()); // may be explicit or implicit op 97 operands[i].opType = opType; 98 operands[i].value = V; 99 operands[i].regNum = -1; 100 operands[i].flags = 0; 101 102 if (isdef || TargetInstrDescriptors[opCode].resultPos == (int) i) 103 operands[i].markDef(); 104 if (isDefAndUse) 105 operands[i].markDefAndUse(); 106 } 107 108 void 109 MachineInstr::SetMachineOperandConst(unsigned i, 110 MachineOperand::MachineOperandType operandType, 111 int64_t intValue) 112 { 113 assert(i < getNumOperands()); // must be explicit op 114 assert(TargetInstrDescriptors[opCode].resultPos != (int) i && 115 "immed. constant cannot be defined"); 116 117 operands[i].opType = operandType; 118 operands[i].value = NULL; 119 operands[i].immedVal = intValue; 120 operands[i].regNum = -1; 121 operands[i].flags = 0; 122 } 123 124 void 125 MachineInstr::SetMachineOperandReg(unsigned i, 126 int regNum, 127 bool isdef) { 128 assert(i < getNumOperands()); // must be explicit op 129 130 operands[i].opType = MachineOperand::MO_MachineRegister; 131 operands[i].value = NULL; 132 operands[i].regNum = regNum; 133 operands[i].flags = 0; 134 135 if (isdef || TargetInstrDescriptors[opCode].resultPos == (int) i) 136 operands[i].markDef(); 137 insertUsedReg(regNum); 138 } 139 140 void 141 MachineInstr::SetRegForOperand(unsigned i, int regNum) 142 { 143 assert(i < getNumOperands()); // must be explicit op 144 operands[i].setRegForValue(regNum); 145 insertUsedReg(regNum); 146 } 147 148 149 // Subsitute all occurrences of Value* oldVal with newVal in all operands 150 // and all implicit refs. If defsOnly == true, substitute defs only. 151 unsigned 152 MachineInstr::substituteValue(const Value* oldVal, Value* newVal, bool defsOnly) 153 { 154 unsigned numSubst = 0; 155 156 // Subsitute operands 157 for (MachineInstr::val_op_iterator O = begin(), E = end(); O != E; ++O) 158 if (*O == oldVal) 159 if (!defsOnly || O.isDef()) 160 { 161 O.getMachineOperand().value = newVal; 162 ++numSubst; 163 } 164 165 // Subsitute implicit refs 166 for (unsigned i=0, N=getNumImplicitRefs(); i < N; ++i) 167 if (getImplicitRef(i) == oldVal) 168 if (!defsOnly || implicitRefIsDefined(i)) 169 { 170 getImplicitOp(i).value = newVal; 171 ++numSubst; 172 } 173 174 return numSubst; 175 } 176 177 178 void 179 MachineInstr::dump() const 180 { 181 cerr << " " << *this; 182 } 183 184 static inline std::ostream& 185 OutputValue(std::ostream &os, const Value* val) 186 { 187 os << "(val "; 188 if (val && val->hasName()) 189 return os << val->getName() << ")"; 190 else 191 return os << (void*) val << ")"; // print address only 192 } 193 194 static inline std::ostream& 195 OutputReg(std::ostream &os, unsigned int regNum) 196 { 197 return os << "%mreg(" << regNum << ")"; 198 } 199 200 static void print(const MachineOperand &MO, std::ostream &OS, 201 const TargetMachine &TM) { 202 bool CloseParen = true; 203 if (MO.opHiBits32()) 204 OS << "%lm("; 205 else if (MO.opLoBits32()) 206 OS << "%lo("; 207 else if (MO.opHiBits64()) 208 OS << "%hh("; 209 else if (MO.opLoBits64()) 210 OS << "%hm("; 211 else 212 CloseParen = false; 213 214 switch (MO.getType()) { 215 case MachineOperand::MO_VirtualRegister: 216 if (MO.getVRegValue()) { 217 OS << "%reg"; 218 OutputValue(OS, MO.getVRegValue()); 219 if (MO.hasAllocatedReg()) 220 OS << "=="; 221 } 222 if (MO.hasAllocatedReg()) 223 OutputReg(OS, MO.getAllocatedRegNum()); 224 break; 225 case MachineOperand::MO_CCRegister: 226 OS << "%ccreg"; 227 OutputValue(OS, MO.getVRegValue()); 228 if (MO.hasAllocatedReg()) { 229 OS << "=="; 230 OutputReg(OS, MO.getAllocatedRegNum()); 231 } 232 break; 233 case MachineOperand::MO_MachineRegister: 234 OutputReg(OS, MO.getMachineRegNum()); 235 break; 236 case MachineOperand::MO_SignExtendedImmed: 237 OS << (long)MO.getImmedValue(); 238 break; 239 case MachineOperand::MO_UnextendedImmed: 240 OS << (long)MO.getImmedValue(); 241 break; 242 case MachineOperand::MO_PCRelativeDisp: { 243 const Value* opVal = MO.getVRegValue(); 244 bool isLabel = isa<Function>(opVal) || isa<BasicBlock>(opVal); 245 OS << "%disp(" << (isLabel? "label " : "addr-of-val "); 246 if (opVal->hasName()) 247 OS << opVal->getName(); 248 else 249 OS << (const void*) opVal; 250 OS << ")"; 251 break; 252 } 253 default: 254 assert(0 && "Unrecognized operand type"); 255 } 256 257 if (CloseParen) 258 OS << ")"; 259 } 260 261 void MachineInstr::print(std::ostream &OS, const TargetMachine &TM) { 262 OS << TM.getInstrInfo().getName(getOpcode()); 263 for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 264 OS << "\t"; 265 ::print(getOperand(i), OS, TM); 266 267 if (operandIsDefinedAndUsed(i)) 268 OS << "<def&use>"; 269 else if (operandIsDefined(i)) 270 OS << "<def>"; 271 } 272 273 // code for printing implict references 274 if (getNumImplicitRefs()) { 275 OS << "\tImplicitRefs: "; 276 for(unsigned i = 0, e = getNumImplicitRefs(); i != e; ++i) { 277 OS << "\t"; 278 OutputValue(OS, getImplicitRef(i)); 279 if (implicitRefIsDefinedAndUsed(i)) 280 OS << "<def&use>"; 281 else if (implicitRefIsDefined(i)) 282 OS << "<def>"; 283 } 284 } 285 286 OS << "\n"; 287 } 288 289 290 std::ostream &operator<<(std::ostream& os, const MachineInstr& minstr) 291 { 292 os << TargetInstrDescriptors[minstr.opCode].Name; 293 294 for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++) { 295 os << "\t" << minstr.getOperand(i); 296 if( minstr.operandIsDefined(i) ) 297 os << "*"; 298 if( minstr.operandIsDefinedAndUsed(i) ) 299 os << "*"; 300 } 301 302 // code for printing implict references 303 unsigned NumOfImpRefs = minstr.getNumImplicitRefs(); 304 if( NumOfImpRefs > 0 ) { 305 os << "\tImplicit: "; 306 for(unsigned z=0; z < NumOfImpRefs; z++) { 307 OutputValue(os, minstr.getImplicitRef(z)); 308 if( minstr.implicitRefIsDefined(z)) os << "*"; 309 if( minstr.implicitRefIsDefinedAndUsed(z)) os << "*"; 310 os << "\t"; 311 } 312 } 313 314 return os << "\n"; 315 } 316 317 std::ostream &operator<<(std::ostream &os, const MachineOperand &mop) 318 { 319 if (mop.opHiBits32()) 320 os << "%lm("; 321 else if (mop.opLoBits32()) 322 os << "%lo("; 323 else if (mop.opHiBits64()) 324 os << "%hh("; 325 else if (mop.opLoBits64()) 326 os << "%hm("; 327 328 switch (mop.getType()) 329 { 330 case MachineOperand::MO_VirtualRegister: 331 os << "%reg"; 332 OutputValue(os, mop.getVRegValue()); 333 if (mop.hasAllocatedReg()) { 334 os << "=="; 335 OutputReg(os, mop.getAllocatedRegNum()); 336 } 337 break; 338 case MachineOperand::MO_CCRegister: 339 os << "%ccreg"; 340 OutputValue(os, mop.getVRegValue()); 341 if (mop.hasAllocatedReg()) { 342 os << "=="; 343 OutputReg(os, mop.getAllocatedRegNum()); 344 } 345 break; 346 case MachineOperand::MO_MachineRegister: 347 OutputReg(os, mop.getMachineRegNum()); 348 break; 349 case MachineOperand::MO_SignExtendedImmed: 350 os << (long)mop.getImmedValue(); 351 break; 352 case MachineOperand::MO_UnextendedImmed: 353 os << (long)mop.getImmedValue(); 354 break; 355 case MachineOperand::MO_PCRelativeDisp: 356 { 357 const Value* opVal = mop.getVRegValue(); 358 bool isLabel = isa<Function>(opVal) || isa<BasicBlock>(opVal); 359 os << "%disp(" << (isLabel? "label " : "addr-of-val "); 360 if (opVal->hasName()) 361 os << opVal->getName(); 362 else 363 os << (const void*) opVal; 364 os << ")"; 365 break; 366 } 367 default: 368 assert(0 && "Unrecognized operand type"); 369 break; 370 } 371 372 if (mop.flags & 373 (MachineOperand::HIFLAG32 | MachineOperand::LOFLAG32 | 374 MachineOperand::HIFLAG64 | MachineOperand::LOFLAG64)) 375 os << ")"; 376 377 return os; 378 } 379