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