MachineInstr.cpp revision a2bae305fb5a870c4ef753ed290a7ddea73ec82b
1//===-- MachineInstr.cpp --------------------------------------------------===// 2// 3//===----------------------------------------------------------------------===// 4 5#include "llvm/CodeGen/MachineInstr.h" 6#include "llvm/Value.h" 7#include "llvm/Target/MachineInstrInfo.h" // FIXME: shouldn't need this! 8using std::cerr; 9 10// Global variable holding an array of descriptors for machine instructions. 11// The actual object needs to be created separately for each target machine. 12// This variable is initialized and reset by class MachineInstrInfo. 13// 14// FIXME: This should be a property of the target so that more than one target 15// at a time can be active... 16// 17extern const MachineInstrDescriptor *TargetInstrDescriptors; 18 19// Constructor for instructions with fixed #operands (nearly all) 20MachineInstr::MachineInstr(MachineOpCode _opCode) 21 : opCode(_opCode), 22 operands(TargetInstrDescriptors[_opCode].numOperands, MachineOperand()), 23 numImplicitRefs(0) 24{ 25 assert(TargetInstrDescriptors[_opCode].numOperands >= 0); 26} 27 28// Constructor for instructions with variable #operands 29MachineInstr::MachineInstr(MachineOpCode OpCode, unsigned numOperands) 30 : opCode(OpCode), 31 operands(numOperands, MachineOperand()), 32 numImplicitRefs(0) 33{ 34} 35 36MachineInstr::MachineInstr(MachineOpCode Opcode, unsigned numOperands, 37 bool XX, bool YY) 38 : opCode(Opcode), 39 numImplicitRefs(0) 40{ 41 operands.reserve(numOperands); 42} 43 44// OperandComplete - Return true if it's illegal to add a new operand 45bool MachineInstr::OperandsComplete() const 46{ 47 int NumOperands = TargetInstrDescriptors[opCode].numOperands; 48 if (NumOperands >= 0 && getNumOperands() >= (unsigned)NumOperands) 49 return true; // Broken! 50 return false; 51} 52 53 54// 55// Support for replacing opcode and operands of a MachineInstr in place. 56// This only resets the size of the operand vector and initializes it. 57// The new operands must be set explicitly later. 58// 59void MachineInstr::replace(MachineOpCode Opcode, unsigned numOperands) 60{ 61 assert(getNumImplicitRefs() == 0 && 62 "This is probably broken because implicit refs are going to be lost."); 63 opCode = Opcode; 64 operands.clear(); 65 operands.resize(numOperands, MachineOperand()); 66} 67 68void 69MachineInstr::SetMachineOperandVal(unsigned i, 70 MachineOperand::MachineOperandType opType, 71 Value* V, 72 bool isdef, 73 bool isDefAndUse) 74{ 75 assert(i < operands.size()); // may be explicit or implicit op 76 operands[i].opType = opType; 77 operands[i].value = V; 78 operands[i].regNum = -1; 79 operands[i].flags = 0; 80 81 if (isdef || TargetInstrDescriptors[opCode].resultPos == (int) i) 82 operands[i].markDef(); 83 if (isDefAndUse) 84 operands[i].markDefAndUse(); 85} 86 87void 88MachineInstr::SetMachineOperandConst(unsigned i, 89 MachineOperand::MachineOperandType operandType, 90 int64_t intValue) 91{ 92 assert(i < getNumOperands()); // must be explicit op 93 assert(TargetInstrDescriptors[opCode].resultPos != (int) i && 94 "immed. constant cannot be defined"); 95 96 operands[i].opType = operandType; 97 operands[i].value = NULL; 98 operands[i].immedVal = intValue; 99 operands[i].regNum = -1; 100 operands[i].flags = 0; 101} 102 103void 104MachineInstr::SetMachineOperandReg(unsigned i, 105 int regNum, 106 bool isdef) { 107 assert(i < getNumOperands()); // must be explicit op 108 109 operands[i].opType = MachineOperand::MO_MachineRegister; 110 operands[i].value = NULL; 111 operands[i].regNum = regNum; 112 operands[i].flags = 0; 113 114 if (isdef || TargetInstrDescriptors[opCode].resultPos == (int) i) 115 operands[i].markDef(); 116 insertUsedReg(regNum); 117} 118 119void 120MachineInstr::SetRegForOperand(unsigned i, int regNum) 121{ 122 assert(i < getNumOperands()); // must be explicit op 123 operands[i].setRegForValue(regNum); 124 insertUsedReg(regNum); 125} 126 127 128// Subsitute all occurrences of Value* oldVal with newVal in all operands 129// and all implicit refs. If defsOnly == true, substitute defs only. 130unsigned 131MachineInstr::substituteValue(const Value* oldVal, Value* newVal, bool defsOnly) 132{ 133 unsigned numSubst = 0; 134 135 // Subsitute operands 136 for (MachineInstr::val_op_iterator O = begin(), E = end(); O != E; ++O) 137 if (*O == oldVal) 138 if (!defsOnly || O.isDef()) 139 { 140 O.getMachineOperand().value = newVal; 141 ++numSubst; 142 } 143 144 // Subsitute implicit refs 145 for (unsigned i=0, N=getNumImplicitRefs(); i < N; ++i) 146 if (getImplicitRef(i) == oldVal) 147 if (!defsOnly || implicitRefIsDefined(i)) 148 { 149 getImplicitOp(i).value = newVal; 150 ++numSubst; 151 } 152 153 return numSubst; 154} 155 156 157void 158MachineInstr::dump() const 159{ 160 cerr << " " << *this; 161} 162 163static inline std::ostream& 164OutputValue(std::ostream &os, const Value* val) 165{ 166 os << "(val "; 167 if (val && val->hasName()) 168 return os << val->getName() << ")"; 169 else 170 return os << (void*) val << ")"; // print address only 171} 172 173static inline std::ostream& 174OutputReg(std::ostream &os, unsigned int regNum) 175{ 176 return os << "%mreg(" << regNum << ")"; 177} 178 179std::ostream &operator<<(std::ostream& os, const MachineInstr& minstr) 180{ 181 os << TargetInstrDescriptors[minstr.opCode].Name; 182 183 for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++) { 184 os << "\t" << minstr.getOperand(i); 185 if( minstr.operandIsDefined(i) ) 186 os << "*"; 187 if( minstr.operandIsDefinedAndUsed(i) ) 188 os << "*"; 189 } 190 191 // code for printing implict references 192 unsigned NumOfImpRefs = minstr.getNumImplicitRefs(); 193 if( NumOfImpRefs > 0 ) { 194 os << "\tImplicit: "; 195 for(unsigned z=0; z < NumOfImpRefs; z++) { 196 OutputValue(os, minstr.getImplicitRef(z)); 197 if( minstr.implicitRefIsDefined(z)) os << "*"; 198 if( minstr.implicitRefIsDefinedAndUsed(z)) os << "*"; 199 os << "\t"; 200 } 201 } 202 203 return os << "\n"; 204} 205 206std::ostream &operator<<(std::ostream &os, const MachineOperand &mop) 207{ 208 if (mop.opHiBits32()) 209 os << "%lm("; 210 else if (mop.opLoBits32()) 211 os << "%lo("; 212 else if (mop.opHiBits64()) 213 os << "%hh("; 214 else if (mop.opLoBits64()) 215 os << "%hm("; 216 217 switch(mop.opType) 218 { 219 case MachineOperand::MO_VirtualRegister: 220 os << "%reg"; 221 OutputValue(os, mop.getVRegValue()); 222 if (mop.hasAllocatedReg()) 223 os << "==" << OutputReg(os, mop.getAllocatedRegNum()); 224 break; 225 case MachineOperand::MO_CCRegister: 226 os << "%ccreg"; 227 OutputValue(os, mop.getVRegValue()); 228 if (mop.hasAllocatedReg()) 229 os << "==" << OutputReg(os, mop.getAllocatedRegNum()); 230 break; 231 case MachineOperand::MO_MachineRegister: 232 OutputReg(os, mop.getMachineRegNum()); 233 break; 234 case MachineOperand::MO_SignExtendedImmed: 235 os << (long)mop.immedVal; 236 break; 237 case MachineOperand::MO_UnextendedImmed: 238 os << (long)mop.immedVal; 239 break; 240 case MachineOperand::MO_PCRelativeDisp: 241 { 242 const Value* opVal = mop.getVRegValue(); 243 bool isLabel = isa<Function>(opVal) || isa<BasicBlock>(opVal); 244 os << "%disp(" << (isLabel? "label " : "addr-of-val "); 245 if (opVal->hasName()) 246 os << opVal->getName(); 247 else 248 os << (const void*) opVal; 249 os << ")"; 250 break; 251 } 252 default: 253 assert(0 && "Unrecognized operand type"); 254 break; 255 } 256 257 if (mop.flags & 258 (MachineOperand::HIFLAG32 | MachineOperand::LOFLAG32 | 259 MachineOperand::HIFLAG64 | MachineOperand::LOFLAG64)) 260 os << ")"; 261 262 return os; 263} 264