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::DEFONLYFLAG; 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::DEFONLYFLAG; 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.isUseOnly()) 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 || !getImplicitOp(i).opIsUse()) 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() && 285 (getOperand(0).opIsDefOnly() || getOperand(0).opIsDefAndUse())) { 286 ::print(getOperand(0), OS, TM); 287 OS << " = "; 288 ++StartOp; // Don't print this operand again! 289 } 290 OS << TM.getInstrInfo().getName(getOpcode()); 291 292 for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) { 293 const MachineOperand& mop = getOperand(i); 294 if (i != StartOp) 295 OS << ","; 296 OS << " "; 297 ::print(mop, OS, TM); 298 299 if (mop.opIsDefAndUse()) 300 OS << "<def&use>"; 301 else if (mop.opIsDefOnly()) 302 OS << "<def>"; 303 } 304 305 // code for printing implict references 306 if (getNumImplicitRefs()) { 307 OS << "\tImplicitRefs: "; 308 for(unsigned i = 0, e = getNumImplicitRefs(); i != e; ++i) { 309 OS << "\t"; 310 OutputValue(OS, getImplicitRef(i)); 311 if (getImplicitOp(i).opIsDefAndUse()) 312 OS << "<def&use>"; 313 else if (getImplicitOp(i).opIsDefOnly()) 314 OS << "<def>"; 315 } 316 } 317 318 OS << "\n"; 319 } 320 321 322 std::ostream &operator<<(std::ostream& os, const MachineInstr& MI) 323 { 324 os << TargetInstrDescriptors[MI.opCode].Name; 325 326 for (unsigned i=0, N=MI.getNumOperands(); i < N; i++) { 327 os << "\t" << MI.getOperand(i); 328 if (MI.getOperand(i).opIsDefOnly()) 329 os << "<d>"; 330 if (MI.getOperand(i).opIsDefAndUse()) 331 os << "<d&u>"; 332 } 333 334 // code for printing implict references 335 unsigned NumOfImpRefs = MI.getNumImplicitRefs(); 336 if (NumOfImpRefs > 0) { 337 os << "\tImplicit: "; 338 for (unsigned z=0; z < NumOfImpRefs; z++) { 339 OutputValue(os, MI.getImplicitRef(z)); 340 if (MI.getImplicitOp(z).opIsDefOnly()) os << "<d>"; 341 if (MI.getImplicitOp(z).opIsDefAndUse()) os << "<d&u>"; 342 os << "\t"; 343 } 344 } 345 346 return os << "\n"; 347 } 348 349 std::ostream &operator<<(std::ostream &OS, const MachineOperand &MO) 350 { 351 if (MO.opHiBits32()) 352 OS << "%lm("; 353 else if (MO.opLoBits32()) 354 OS << "%lo("; 355 else if (MO.opHiBits64()) 356 OS << "%hh("; 357 else if (MO.opLoBits64()) 358 OS << "%hm("; 359 360 switch (MO.getType()) 361 { 362 case MachineOperand::MO_VirtualRegister: 363 if (MO.hasAllocatedReg()) 364 OutputReg(OS, MO.getAllocatedRegNum()); 365 366 if (MO.getVRegValue()) { 367 if (MO.hasAllocatedReg()) OS << "=="; 368 OS << "%vreg"; 369 OutputValue(OS, MO.getVRegValue()); 370 } 371 break; 372 case MachineOperand::MO_CCRegister: 373 OS << "%ccreg"; 374 OutputValue(OS, MO.getVRegValue()); 375 if (MO.hasAllocatedReg()) { 376 OS << "=="; 377 OutputReg(OS, MO.getAllocatedRegNum()); 378 } 379 break; 380 case MachineOperand::MO_MachineRegister: 381 OutputReg(OS, MO.getMachineRegNum()); 382 break; 383 case MachineOperand::MO_SignExtendedImmed: 384 OS << (long)MO.getImmedValue(); 385 break; 386 case MachineOperand::MO_UnextendedImmed: 387 OS << (long)MO.getImmedValue(); 388 break; 389 case MachineOperand::MO_PCRelativeDisp: 390 { 391 const Value* opVal = MO.getVRegValue(); 392 bool isLabel = isa<Function>(opVal) || isa<BasicBlock>(opVal); 393 OS << "%disp(" << (isLabel? "label " : "addr-of-val "); 394 if (opVal->hasName()) 395 OS << opVal->getName(); 396 else 397 OS << (const void*) opVal; 398 OS << ")"; 399 break; 400 } 401 case MachineOperand::MO_MachineBasicBlock: 402 OS << "bb<" 403 << ((Value*)MO.getMachineBasicBlock()->getBasicBlock())->getName() 404 << "," << (void*)MO.getMachineBasicBlock()->getBasicBlock() << ">"; 405 break; 406 case MachineOperand::MO_FrameIndex: 407 OS << "<fi#" << MO.getFrameIndex() << ">"; 408 break; 409 case MachineOperand::MO_ConstantPoolIndex: 410 OS << "<cp#" << MO.getConstantPoolIndex() << ">"; 411 break; 412 case MachineOperand::MO_GlobalAddress: 413 OS << "<ga:" << ((Value*)MO.getGlobal())->getName() << ">"; 414 break; 415 case MachineOperand::MO_ExternalSymbol: 416 OS << "<es:" << MO.getSymbolName() << ">"; 417 break; 418 default: 419 assert(0 && "Unrecognized operand type"); 420 break; 421 } 422 423 if (MO.flags & 424 (MachineOperand::HIFLAG32 | MachineOperand::LOFLAG32 | 425 MachineOperand::HIFLAG64 | MachineOperand::LOFLAG64)) 426 OS << ")"; 427 428 return OS; 429 } 430