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 if (isdef || TargetInstrDescriptors[opCode].resultPos == (int) i) 53 operands[i].markDef(); 54 if (isDefAndUse) 55 operands[i].markDefAndUse(); 56 } 57 58 void 59 MachineInstr::SetMachineOperandConst(unsigned int i, 60 MachineOperand::MachineOperandType operandType, 61 int64_t intValue) 62 { 63 assert(i < operands.size()); 64 assert(TargetInstrDescriptors[opCode].resultPos != (int) i && 65 "immed. constant cannot be defined"); 66 operands[i].InitializeConst(operandType, intValue); 67 } 68 69 void 70 MachineInstr::SetMachineOperandReg(unsigned int i, 71 int regNum, 72 bool isdef=false, 73 bool isDefAndUse=false, 74 bool isCCReg=false) 75 { 76 assert(i < operands.size()); 77 operands[i].InitializeReg(regNum, isCCReg); 78 if (isdef || TargetInstrDescriptors[opCode].resultPos == (int) i) 79 operands[i].markDef(); 80 if (isDefAndUse) 81 operands[i].markDefAndUse(); 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 } 108 109 std::ostream &operator<<(std::ostream& os, const MachineInstr& minstr) 110 { 111 os << TargetInstrDescriptors[minstr.opCode].opCodeString; 112 113 for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++) { 114 os << "\t" << minstr.getOperand(i); 115 if( minstr.operandIsDefined(i) ) 116 os << "*"; 117 if( minstr.operandIsDefinedAndUsed(i) ) 118 os << "*"; 119 } 120 121 // code for printing implict references 122 unsigned NumOfImpRefs = minstr.getNumImplicitRefs(); 123 if( NumOfImpRefs > 0 ) { 124 os << "\tImplicit: "; 125 for(unsigned z=0; z < NumOfImpRefs; z++) { 126 OutputValue(os, minstr.getImplicitRef(z)); 127 if( minstr.implicitRefIsDefined(z)) os << "*"; 128 if( minstr.implicitRefIsDefinedAndUsed(z)) os << "*"; 129 os << "\t"; 130 } 131 } 132 133 return os << "\n"; 134 } 135 136 std::ostream &operator<<(std::ostream &os, const MachineOperand &mop) 137 { 138 if (mop.opHiBits32()) 139 os << "%lm("; 140 else if (mop.opLoBits32()) 141 os << "%lo("; 142 else if (mop.opHiBits64()) 143 os << "%hh("; 144 else if (mop.opLoBits64()) 145 os << "%hm("; 146 147 switch(mop.opType) 148 { 149 case MachineOperand::MO_VirtualRegister: 150 os << "%reg"; 151 OutputValue(os, mop.getVRegValue()); 152 break; 153 case MachineOperand::MO_CCRegister: 154 os << "%ccreg"; 155 OutputValue(os, mop.getVRegValue()); 156 break; 157 case MachineOperand::MO_MachineRegister: 158 os << "%reg"; 159 os << "(" << mop.getMachineRegNum() << ")"; 160 break; 161 case MachineOperand::MO_SignExtendedImmed: 162 os << (long)mop.immedVal; 163 break; 164 case MachineOperand::MO_UnextendedImmed: 165 os << (long)mop.immedVal; 166 break; 167 case MachineOperand::MO_PCRelativeDisp: 168 { 169 const Value* opVal = mop.getVRegValue(); 170 bool isLabel = isa<Function>(opVal) || isa<BasicBlock>(opVal); 171 os << "%disp(" << (isLabel? "label " : "addr-of-val "); 172 if (opVal->hasName()) 173 os << opVal->getName(); 174 else 175 os << (const void*) opVal; 176 os << ")"; 177 break; 178 } 179 default: 180 assert(0 && "Unrecognized operand type"); 181 break; 182 } 183 184 if (mop.flags & 185 (MachineOperand::HIFLAG32 | MachineOperand::LOFLAG32 | 186 MachineOperand::HIFLAG64 | MachineOperand::LOFLAG64)) 187 os << ")"; 188 189 return os; 190 } 191