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