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