MachineInstr.cpp revision e2a78e31862c2b6142491db5a67065756d6870be
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 &OutputValue(std::ostream &os, 116 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 125std::ostream &operator<<(std::ostream& os, const MachineInstr& minstr) 126{ 127 os << TargetInstrDescriptors[minstr.opCode].opCodeString; 128 129 for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++) { 130 os << "\t" << minstr.getOperand(i); 131 if( minstr.operandIsDefined(i) ) 132 os << "*"; 133 if( minstr.operandIsDefinedAndUsed(i) ) 134 os << "*"; 135 } 136 137 // code for printing implict references 138 unsigned NumOfImpRefs = minstr.getNumImplicitRefs(); 139 if( NumOfImpRefs > 0 ) { 140 os << "\tImplicit: "; 141 for(unsigned z=0; z < NumOfImpRefs; z++) { 142 OutputValue(os, minstr.getImplicitRef(z)); 143 if( minstr.implicitRefIsDefined(z)) os << "*"; 144 if( minstr.implicitRefIsDefinedAndUsed(z)) os << "*"; 145 os << "\t"; 146 } 147 } 148 149 return os << "\n"; 150} 151 152std::ostream &operator<<(std::ostream &os, const MachineOperand &mop) 153{ 154 if (mop.opHiBits32()) 155 os << "%lm("; 156 else if (mop.opLoBits32()) 157 os << "%lo("; 158 else if (mop.opHiBits64()) 159 os << "%hh("; 160 else if (mop.opLoBits64()) 161 os << "%hm("; 162 163 switch(mop.opType) 164 { 165 case MachineOperand::MO_VirtualRegister: 166 os << "%reg"; 167 OutputValue(os, mop.getVRegValue()); 168 break; 169 case MachineOperand::MO_CCRegister: 170 os << "%ccreg"; 171 OutputValue(os, mop.getVRegValue()); 172 break; 173 case MachineOperand::MO_MachineRegister: 174 os << "%reg"; 175 os << "(" << mop.getMachineRegNum() << ")"; 176 break; 177 case MachineOperand::MO_SignExtendedImmed: 178 os << (long)mop.immedVal; 179 break; 180 case MachineOperand::MO_UnextendedImmed: 181 os << (long)mop.immedVal; 182 break; 183 case MachineOperand::MO_PCRelativeDisp: 184 { 185 const Value* opVal = mop.getVRegValue(); 186 bool isLabel = isa<Function>(opVal) || isa<BasicBlock>(opVal); 187 os << "%disp(" << (isLabel? "label " : "addr-of-val "); 188 if (opVal->hasName()) 189 os << opVal->getName(); 190 else 191 os << (const void*) opVal; 192 os << ")"; 193 break; 194 } 195 default: 196 assert(0 && "Unrecognized operand type"); 197 break; 198 } 199 200 if (mop.flags & 201 (MachineOperand::HIFLAG32 | MachineOperand::LOFLAG32 | 202 MachineOperand::HIFLAG64 | MachineOperand::LOFLAG64)) 203 os << ")"; 204 205 return os; 206} 207