1 // $Id$ 2 //*************************************************************************** 3 // File: 4 // MachineInstr.cpp 5 // 6 // Purpose: 7 // 8 // 9 // Strategy: 10 // 11 // History: 12 // 7/2/01 - Vikram Adve - Created 13 //**************************************************************************/ 14 15 #include "llvm/CodeGen/MachineInstr.h" 16 #include "llvm/Value.h" 17 #include <iostream> 18 using std::cerr; 19 20 21 //************************ Class Implementations **************************/ 22 23 // Constructor for instructions with fixed #operands (nearly all) 24 MachineInstr::MachineInstr(MachineOpCode _opCode, 25 OpCodeMask _opCodeMask) 26 : opCode(_opCode), 27 opCodeMask(_opCodeMask), 28 operands(TargetInstrDescriptors[_opCode].numOperands) 29 { 30 assert(TargetInstrDescriptors[_opCode].numOperands >= 0); 31 } 32 33 // Constructor for instructions with variable #operands 34 MachineInstr::MachineInstr(MachineOpCode _opCode, 35 unsigned numOperands, 36 OpCodeMask _opCodeMask) 37 : opCode(_opCode), 38 opCodeMask(_opCodeMask), 39 operands(numOperands) 40 { 41 } 42 43 void 44 MachineInstr::SetMachineOperand(unsigned int i, 45 MachineOperand::MachineOperandType operandType, 46 Value* _val, bool isdef=false) 47 { 48 assert(i < operands.size()); 49 operands[i].Initialize(operandType, _val); 50 operands[i].isDef = isdef || 51 TargetInstrDescriptors[opCode].resultPos == (int) i; 52 } 53 54 void 55 MachineInstr::SetMachineOperand(unsigned int i, 56 MachineOperand::MachineOperandType operandType, 57 int64_t intValue, bool isdef=false) 58 { 59 assert(i < operands.size()); 60 operands[i].InitializeConst(operandType, intValue); 61 operands[i].isDef = isdef || 62 TargetInstrDescriptors[opCode].resultPos == (int) i; 63 } 64 65 void 66 MachineInstr::SetMachineOperand(unsigned int i, 67 int regNum, bool isdef=false) 68 { 69 assert(i < operands.size()); 70 operands[i].InitializeReg(regNum); 71 operands[i].isDef = isdef || 72 TargetInstrDescriptors[opCode].resultPos == (int) i; 73 } 74 75 void 76 MachineInstr::dump(unsigned int indent) const 77 { 78 for (unsigned i=0; i < indent; i++) 79 cerr << " "; 80 81 cerr << *this; 82 } 83 84 std::ostream &operator<<(std::ostream& os, const MachineInstr& minstr) 85 { 86 os << TargetInstrDescriptors[minstr.opCode].opCodeString; 87 88 for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++) { 89 os << "\t" << minstr.getOperand(i); 90 if( minstr.getOperand(i).opIsDef() ) 91 os << "*"; 92 } 93 94 #undef DEBUG_VAL_OP_ITERATOR 95 #ifdef DEBUG_VAL_OP_ITERATOR 96 os << "\n\tValue operands are: "; 97 for (MachineInstr::val_const_op_iterator vo(&minstr); ! vo.done(); ++vo) 98 { 99 const Value* val = *vo; 100 os << val << (vo.isDef()? "(def), " : ", "); 101 } 102 #endif 103 104 105 106 #if 1 107 // code for printing implict references 108 109 unsigned NumOfImpRefs = minstr.getNumImplicitRefs(); 110 if( NumOfImpRefs > 0 ) { 111 112 os << "\tImplicit:"; 113 114 for(unsigned z=0; z < NumOfImpRefs; z++) { 115 os << minstr.getImplicitRef(z); 116 if( minstr.implicitRefIsDefined(z)) os << "*"; 117 os << "\t"; 118 } 119 } 120 121 #endif 122 return os << "\n"; 123 } 124 125 static inline std::ostream &OutputOperand(std::ostream &os, 126 const MachineOperand &mop) 127 { 128 Value* val; 129 switch (mop.getOperandType()) 130 { 131 case MachineOperand::MO_CCRegister: 132 case MachineOperand::MO_VirtualRegister: 133 val = mop.getVRegValue(); 134 os << "(val "; 135 if (val && val->hasName()) 136 os << val->getName(); 137 else 138 os << val; 139 return os << ")"; 140 case MachineOperand::MO_MachineRegister: 141 return os << "(" << mop.getMachineRegNum() << ")"; 142 default: 143 assert(0 && "Unknown operand type"); 144 return os; 145 } 146 } 147 148 149 std::ostream &operator<<(std::ostream &os, const MachineOperand &mop) 150 { 151 switch(mop.opType) 152 { 153 case MachineOperand::MO_VirtualRegister: 154 case MachineOperand::MO_MachineRegister: 155 os << "%reg"; 156 return OutputOperand(os, mop); 157 case MachineOperand::MO_CCRegister: 158 os << "%ccreg"; 159 return OutputOperand(os, mop); 160 case MachineOperand::MO_SignExtendedImmed: 161 return os << (long)mop.immedVal; 162 case MachineOperand::MO_UnextendedImmed: 163 return os << (long)mop.immedVal; 164 case MachineOperand::MO_PCRelativeDisp: 165 { 166 const Value* opVal = mop.getVRegValue(); 167 bool isLabel = isa<Method>(opVal) || isa<BasicBlock>(opVal); 168 os << "%disp(" << (isLabel? "label " : "addr-of-val "); 169 if (opVal->hasName()) 170 os << opVal->getName(); 171 else 172 os << opVal; 173 return os << ")"; 174 } 175 default: 176 assert(0 && "Unrecognized operand type"); 177 break; 178 } 179 180 return os; 181 } 182