MachineInstr.cpp revision 56786d268feeb6d0e895b6c4cba60139285c47d6
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 16#include "llvm/CodeGen/MachineInstr.h" 17#include "llvm/Method.h" 18#include "llvm/ConstPoolVals.h" 19#include "llvm/Instruction.h" 20#include <strstream> 21 22 23//************************ Class Implementations **************************/ 24 25// Constructor for instructions with fixed #operands (nearly all) 26MachineInstr::MachineInstr(MachineOpCode _opCode, 27 OpCodeMask _opCodeMask) 28 : opCode(_opCode), 29 opCodeMask(_opCodeMask), 30 operands(TargetInstrDescriptors[_opCode].numOperands) 31{ 32 assert(TargetInstrDescriptors[_opCode].numOperands >= 0); 33} 34 35// Constructor for instructions with variable #operands 36MachineInstr::MachineInstr(MachineOpCode _opCode, 37 unsigned numOperands, 38 OpCodeMask _opCodeMask) 39 : opCode(_opCode), 40 opCodeMask(_opCodeMask), 41 operands(numOperands) 42{ 43} 44 45void 46MachineInstr::SetMachineOperand(unsigned int i, 47 MachineOperand::MachineOperandType operandType, 48 Value* _val, bool isdef=false) 49{ 50 assert(i < operands.size()); 51 operands[i].Initialize(operandType, _val); 52 operands[i].isDef = isdef || 53 TargetInstrDescriptors[opCode].resultPos == (int) i; 54} 55 56void 57MachineInstr::SetMachineOperand(unsigned int i, 58 MachineOperand::MachineOperandType operandType, 59 int64_t intValue, bool isdef=false) 60{ 61 assert(i < operands.size()); 62 operands[i].InitializeConst(operandType, intValue); 63 operands[i].isDef = isdef || 64 TargetInstrDescriptors[opCode].resultPos == (int) i; 65} 66 67void 68MachineInstr::SetMachineOperand(unsigned int i, 69 unsigned int regNum, bool isdef=false) 70{ 71 assert(i < operands.size()); 72 operands[i].InitializeReg(regNum); 73 operands[i].isDef = isdef || 74 TargetInstrDescriptors[opCode].resultPos == (int) i; 75} 76 77void 78MachineInstr::dump(unsigned int indent) const 79{ 80 for (unsigned i=0; i < indent; i++) 81 cout << " "; 82 83 cout << *this; 84} 85 86ostream& 87operator<< (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 94#undef DEBUG_VAL_OP_ITERATOR 95#ifdef DEBUG_VAL_OP_ITERATOR 96 os << endl << "\tValue operands are: "; 97 for (MachineInstr::val_op_const_iterator vo(&minstr); ! vo.done(); ++vo) 98 { 99 const Value* val = *vo; 100 os << val << (vo.isDef()? "(def), " : ", "); 101 } 102 os << endl; 103#endif 104 105 return os; 106} 107 108ostream& 109operator<< (ostream& os, const MachineOperand& mop) 110{ 111 strstream regInfo; 112 if (mop.opType == MachineOperand::MO_VirtualRegister) 113 regInfo << "(val " << mop.value << ")" << ends; 114 else if (mop.opType == MachineOperand::MO_MachineRegister) 115 regInfo << "(" << mop.regNum << ")" << ends; 116 else if (mop.opType == MachineOperand::MO_CCRegister) 117 regInfo << "(val " << mop.value << ")" << ends; 118 119 switch(mop.opType) 120 { 121 case MachineOperand::MO_VirtualRegister: 122 case MachineOperand::MO_MachineRegister: 123 os << "%reg" << regInfo.str(); 124 free(regInfo.str()); 125 break; 126 127 case MachineOperand::MO_CCRegister: 128 os << "%ccreg" << regInfo.str(); 129 free(regInfo.str()); 130 break; 131 132 case MachineOperand::MO_SignExtendedImmed: 133 os << mop.immedVal; 134 break; 135 136 case MachineOperand::MO_UnextendedImmed: 137 os << mop.immedVal; 138 break; 139 140 case MachineOperand::MO_PCRelativeDisp: 141 os << "%disp(label " << mop.value << ")"; 142 break; 143 144 default: 145 assert(0 && "Unrecognized operand type"); 146 break; 147 } 148 149 return os; 150} 151 152 153//--------------------------------------------------------------------------- 154// Target-independent utility routines for creating machine instructions 155//--------------------------------------------------------------------------- 156 157 158//------------------------------------------------------------------------ 159// Function Set2OperandsFromInstr 160// Function Set3OperandsFromInstr 161// 162// For the common case of 2- and 3-operand arithmetic/logical instructions, 163// set the m/c instr. operands directly from the VM instruction's operands. 164// Check whether the first or second operand is 0 and can use a dedicated "0" register. 165// Check whether the second operand should use an immediate field or register. 166// (First and third operands are never immediates for such instructions.) 167// 168// Arguments: 169// canDiscardResult: Specifies that the result operand can be discarded 170// by using the dedicated "0" 171// 172// op1position, op2position and resultPosition: Specify in which position 173// in the machine instruction the 3 operands (arg1, arg2 174// and result) should go. 175// 176// RETURN VALUE: unsigned int flags, where 177// flags & 0x01 => operand 1 is constant and needs a register 178// flags & 0x02 => operand 2 is constant and needs a register 179//------------------------------------------------------------------------ 180 181void 182Set2OperandsFromInstr(MachineInstr* minstr, 183 InstructionNode* vmInstrNode, 184 const TargetMachine& target, 185 bool canDiscardResult, 186 int op1Position, 187 int resultPosition) 188{ 189 Set3OperandsFromInstr(minstr, vmInstrNode, target, 190 canDiscardResult, op1Position, 191 /*op2Position*/ -1, resultPosition); 192} 193 194#undef REVERT_TO_EXPLICIT_CONSTANT_CHECKS 195#ifdef REVERT_TO_EXPLICIT_CONSTANT_CHECKS 196unsigned 197Set3OperandsFromInstrJUNK(MachineInstr* minstr, 198 InstructionNode* vmInstrNode, 199 const TargetMachine& target, 200 bool canDiscardResult, 201 int op1Position, 202 int op2Position, 203 int resultPosition) 204{ 205 assert(op1Position >= 0); 206 assert(resultPosition >= 0); 207 208 unsigned returnFlags = 0x0; 209 210 // Check if operand 1 is 0. If so, try to use a hardwired 0 register. 211 Value* op1Value = vmInstrNode->leftChild()->getValue(); 212 bool isValidConstant; 213 int64_t intValue = GetConstantValueAsSignedInt(op1Value, isValidConstant); 214 if (isValidConstant && intValue == 0 && target.zeroRegNum >= 0) 215 minstr->SetMachineOperand(op1Position, /*regNum*/ target.zeroRegNum); 216 else 217 { 218 if (op1Value->getValueType() == Value::ConstantVal) 219 {// value is constant and must be loaded from constant pool 220 returnFlags = returnFlags | (1 << op1Position); 221 } 222 minstr->SetMachineOperand(op1Position,MachineOperand::MO_VirtualRegister, 223 op1Value); 224 } 225 226 // Check if operand 2 (if any) fits in the immed. field of the instruction, 227 // or if it is 0 and can use a dedicated machine register 228 if (op2Position >= 0) 229 { 230 Value* op2Value = vmInstrNode->rightChild()->getValue(); 231 int64_t immedValue; 232 unsigned int machineRegNum; 233 234 MachineOperand::MachineOperandType 235 op2type = ChooseRegOrImmed(op2Value, minstr->getOpCode(), target, 236 /*canUseImmed*/ true, 237 machineRegNum, immedValue); 238 239 if (op2type == MachineOperand::MO_MachineRegister) 240 minstr->SetMachineOperand(op2Position, machineRegNum); 241 else if (op2type == MachineOperand::MO_VirtualRegister) 242 { 243 if (op2Value->getValueType() == Value::ConstantVal) 244 {// value is constant and must be loaded from constant pool 245 returnFlags = returnFlags | (1 << op2Position); 246 } 247 minstr->SetMachineOperand(op2Position, op2type, op2Value); 248 } 249 else 250 { 251 assert(op2type != MO_CCRegister); 252 minstr->SetMachineOperand(op2Position, op2type, immedValue); 253 } 254 } 255 256 // If operand 3 (result) can be discarded, use a dead register if one exists 257 if (canDiscardResult && target.zeroRegNum >= 0) 258 minstr->SetMachineOperand(resultPosition, target.zeroRegNum); 259 else 260 minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue()); 261 262 return returnFlags; 263} 264#endif 265 266 267void 268Set3OperandsFromInstr(MachineInstr* minstr, 269 InstructionNode* vmInstrNode, 270 const TargetMachine& target, 271 bool canDiscardResult, 272 int op1Position, 273 int op2Position, 274 int resultPosition) 275{ 276 assert(op1Position >= 0); 277 assert(resultPosition >= 0); 278 279 // operand 1 280 minstr->SetMachineOperand(op1Position, MachineOperand::MO_VirtualRegister, 281 vmInstrNode->leftChild()->getValue()); 282 283 // operand 2 (if any) 284 if (op2Position >= 0) 285 minstr->SetMachineOperand(op2Position, MachineOperand::MO_VirtualRegister, 286 vmInstrNode->rightChild()->getValue()); 287 288 // result operand: if it can be discarded, use a dead register if one exists 289 if (canDiscardResult && target.zeroRegNum >= 0) 290 minstr->SetMachineOperand(resultPosition, target.zeroRegNum); 291 else 292 minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue()); 293} 294 295 296MachineOperand::MachineOperandType 297ChooseRegOrImmed(Value* val, 298 MachineOpCode opCode, 299 const TargetMachine& target, 300 bool canUseImmed, 301 unsigned int& getMachineRegNum, 302 int64_t& getImmedValue) 303{ 304 MachineOperand::MachineOperandType opType = 305 MachineOperand::MO_VirtualRegister; 306 getMachineRegNum = 0; 307 getImmedValue = 0; 308 309 // Check for the common case first: argument is not constant 310 // 311 if (val->getValueType() != Value::ConstantVal) 312 return opType; 313 314 // Now get the constant value and check if it fits in the IMMED field. 315 // Take advantage of the fact that the max unsigned value will rarely 316 // fit into any IMMED field and ignore that case (i.e., cast smaller 317 // unsigned constants to signed). 318 // 319 bool isValidConstant; 320 int64_t intValue = GetConstantValueAsSignedInt(val, isValidConstant); 321 322 if (isValidConstant) 323 { 324 if (intValue == 0 && target.zeroRegNum >= 0) 325 { 326 opType = MachineOperand::MO_MachineRegister; 327 getMachineRegNum = target.zeroRegNum; 328 } 329 else if (canUseImmed && 330 target.getInstrInfo().constantFitsInImmedField(opCode,intValue)) 331 { 332 opType = MachineOperand::MO_SignExtendedImmed; 333 getImmedValue = intValue; 334 } 335 } 336 337 return opType; 338} 339 340 341void 342PrintMachineInstructions(const Method* method) 343{ 344 cout << "\n" << method->getReturnType() 345 << " \"" << method->getName() << "\"" << endl; 346 347 for (Method::const_iterator BI = method->begin(); BI != method->end(); ++BI) 348 { 349 const BasicBlock* bb = *BI; 350 cout << "\n" 351 << (bb->hasName()? bb->getName() : "Label") 352 << " (" << bb << ")" << ":" 353 << endl; 354 355 const MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec(); 356 for (unsigned i=0; i < mvec.size(); i++) 357 cout << "\t" << *mvec[i] << endl; 358 } 359 cout << endl << "End method \"" << method->getName() << "\"" 360 << endl << endl; 361} 362