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! 8 using 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 // 17 extern const MachineInstrDescriptor *TargetInstrDescriptors; 18 19 // Constructor for instructions with fixed #operands (nearly all) 20 MachineInstr::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 29 MachineInstr::MachineInstr(MachineOpCode OpCode, unsigned numOperands) 30 : opCode(OpCode), 31 operands(numOperands, MachineOperand()), 32 numImplicitRefs(0) 33 { 34 } 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 // OperandComplete - Return true if it's illegal to add a new operand 45 bool 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 // 59 void 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 68 void 69 MachineInstr::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 87 void 88 MachineInstr::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 103 void 104 MachineInstr::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 119 void 120 MachineInstr::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. 130 unsigned 131 MachineInstr::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 157 void 158 MachineInstr::dump() const 159 { 160 cerr << " " << *this; 161 } 162 163 static inline std::ostream& 164 OutputValue(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 173 static inline std::ostream& 174 OutputReg(std::ostream &os, unsigned int regNum) 175 { 176 return os << "%mreg(" << regNum << ")"; 177 } 178 179 std::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 206 std::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