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