MachineInstr.cpp revision 7a4be9580e095ca4bffd16ec6ec4882f6270fb09
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> 18using std::cerr; 19 20 21//************************ Class Implementations **************************/ 22 23// Constructor for instructions with fixed #operands (nearly all) 24MachineInstr::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 34MachineInstr::MachineInstr(MachineOpCode _opCode, 35 unsigned numOperands, 36 OpCodeMask _opCodeMask) 37 : opCode(_opCode), 38 opCodeMask(_opCodeMask), 39 operands(numOperands) 40{ 41} 42 43void 44MachineInstr::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 57void 58MachineInstr::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 70void 71MachineInstr::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 85void 86MachineInstr::SetRegForOperand(unsigned i, int regNum) 87{ 88 operands[i].setRegForValue(regNum); 89 regsUsed.insert(regNum); 90} 91 92 93void 94MachineInstr::dump() const 95{ 96 cerr << " " << *this; 97} 98 99static 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 110std::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 137static 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 154std::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