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