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