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