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