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