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::SetMachineOperandVal(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::SetMachineOperandConst(unsigned int i, 56 MachineOperand::MachineOperandType operandType, 57 int64_t intValue) 58 { 59 assert(i < operands.size()); 60 assert(TargetInstrDescriptors[opCode].resultPos != (int) i && 61 "immed. constant cannot be defined"); 62 operands[i].InitializeConst(operandType, intValue); 63 operands[i].isDef = false; 64 } 65 66 void 67 MachineInstr::SetMachineOperandReg(unsigned int i, 68 int regNum, 69 bool isdef=false, 70 bool isCCReg=false) 71 { 72 assert(i < operands.size()); 73 operands[i].InitializeReg(regNum, isCCReg); 74 operands[i].isDef = isdef || 75 TargetInstrDescriptors[opCode].resultPos == (int) i; 76 } 77 78 void 79 MachineInstr::dump(unsigned int indent) const 80 { 81 for (unsigned i=0; i < indent; i++) 82 cerr << " "; 83 84 cerr << *this; 85 } 86 87 std::ostream &operator<<(std::ostream& os, const MachineInstr& minstr) 88 { 89 os << TargetInstrDescriptors[minstr.opCode].opCodeString; 90 91 for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++) { 92 os << "\t" << minstr.getOperand(i); 93 if( minstr.getOperand(i).opIsDef() ) 94 os << "*"; 95 } 96 97 #undef DEBUG_VAL_OP_ITERATOR 98 #ifdef DEBUG_VAL_OP_ITERATOR 99 os << "\n\tValue operands are: "; 100 for (MachineInstr::val_const_op_iterator vo(&minstr); ! vo.done(); ++vo) 101 { 102 const Value* val = *vo; 103 os << val << (vo.isDef()? "(def), " : ", "); 104 } 105 #endif 106 107 108 109 #if 1 110 // code for printing implict references 111 112 unsigned NumOfImpRefs = minstr.getNumImplicitRefs(); 113 if( NumOfImpRefs > 0 ) { 114 115 os << "\tImplicit:"; 116 117 for(unsigned z=0; z < NumOfImpRefs; z++) { 118 os << minstr.getImplicitRef(z); 119 if( minstr.implicitRefIsDefined(z)) os << "*"; 120 os << "\t"; 121 } 122 } 123 124 #endif 125 return os << "\n"; 126 } 127 128 static inline std::ostream &OutputOperand(std::ostream &os, 129 const MachineOperand &mop) 130 { 131 Value* val; 132 switch (mop.getOperandType()) 133 { 134 case MachineOperand::MO_CCRegister: 135 case MachineOperand::MO_VirtualRegister: 136 val = mop.getVRegValue(); 137 os << "(val "; 138 if (val && val->hasName()) 139 os << val->getName(); 140 else 141 os << val; 142 return os << ")"; 143 case MachineOperand::MO_MachineRegister: 144 return os << "(" << mop.getMachineRegNum() << ")"; 145 default: 146 assert(0 && "Unknown operand type"); 147 return os; 148 } 149 } 150 151 152 std::ostream &operator<<(std::ostream &os, const MachineOperand &mop) 153 { 154 switch(mop.opType) 155 { 156 case MachineOperand::MO_VirtualRegister: 157 case MachineOperand::MO_MachineRegister: 158 os << "%reg"; 159 return OutputOperand(os, mop); 160 case MachineOperand::MO_CCRegister: 161 os << "%ccreg"; 162 return OutputOperand(os, mop); 163 case MachineOperand::MO_SignExtendedImmed: 164 return os << (long)mop.immedVal; 165 case MachineOperand::MO_UnextendedImmed: 166 return os << (long)mop.immedVal; 167 case MachineOperand::MO_PCRelativeDisp: 168 { 169 const Value* opVal = mop.getVRegValue(); 170 bool isLabel = isa<Method>(opVal) || isa<BasicBlock>(opVal); 171 os << "%disp(" << (isLabel? "label " : "addr-of-val "); 172 if (opVal->hasName()) 173 os << opVal->getName(); 174 else 175 os << opVal; 176 return os << ")"; 177 } 178 default: 179 assert(0 && "Unrecognized operand type"); 180 break; 181 } 182 183 return os; 184 } 185