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