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