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