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 static inline std::ostream &OutputValue(std::ostream &os, 88 const Value* val) 89 { 90 os << "(val "; 91 if (val && val->hasName()) 92 return os << val->getName(); 93 else 94 return os << (void*) val; // print address only 95 os << ")"; 96 } 97 98 std::ostream &operator<<(std::ostream& os, const MachineInstr& minstr) 99 { 100 os << TargetInstrDescriptors[minstr.opCode].opCodeString; 101 102 for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++) { 103 os << "\t" << minstr.getOperand(i); 104 if( minstr.getOperand(i).opIsDef() ) 105 os << "*"; 106 } 107 108 // code for printing implict references 109 unsigned NumOfImpRefs = minstr.getNumImplicitRefs(); 110 if( NumOfImpRefs > 0 ) { 111 os << "\tImplicit: "; 112 for(unsigned z=0; z < NumOfImpRefs; z++) { 113 OutputValue(os, minstr.getImplicitRef(z)); 114 if( minstr.implicitRefIsDefined(z)) os << "*"; 115 os << "\t"; 116 } 117 } 118 119 return os << "\n"; 120 } 121 122 static inline std::ostream &OutputOperand(std::ostream &os, 123 const MachineOperand &mop) 124 { 125 Value* val; 126 switch (mop.getOperandType()) 127 { 128 case MachineOperand::MO_CCRegister: 129 case MachineOperand::MO_VirtualRegister: 130 return OutputValue(os, mop.getVRegValue()); 131 case MachineOperand::MO_MachineRegister: 132 return os << "(" << mop.getMachineRegNum() << ")"; 133 default: 134 assert(0 && "Unknown operand type"); 135 return os; 136 } 137 } 138 139 140 std::ostream &operator<<(std::ostream &os, const MachineOperand &mop) 141 { 142 switch(mop.opType) 143 { 144 case MachineOperand::MO_VirtualRegister: 145 case MachineOperand::MO_MachineRegister: 146 os << "%reg"; 147 return OutputOperand(os, mop); 148 case MachineOperand::MO_CCRegister: 149 os << "%ccreg"; 150 return OutputOperand(os, mop); 151 case MachineOperand::MO_SignExtendedImmed: 152 return os << (long)mop.immedVal; 153 case MachineOperand::MO_UnextendedImmed: 154 return os << (long)mop.immedVal; 155 case MachineOperand::MO_PCRelativeDisp: 156 { 157 const Value* opVal = mop.getVRegValue(); 158 bool isLabel = isa<Function>(opVal) || isa<BasicBlock>(opVal); 159 os << "%disp(" << (isLabel? "label " : "addr-of-val "); 160 if (opVal->hasName()) 161 os << opVal->getName(); 162 else 163 os << opVal; 164 return os << ")"; 165 } 166 default: 167 assert(0 && "Unrecognized operand type"); 168 break; 169 } 170 171 return os; 172 } 173