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/Target/MachineRegInfo.h" 18 #include "llvm/Method.h" 19 #include "llvm/ConstPoolVals.h" 20 #include "llvm/Instruction.h" 21 22 23 //************************ Class Implementations **************************/ 24 25 // Constructor for instructions with fixed #operands (nearly all) 26 MachineInstr::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 36 MachineInstr::MachineInstr(MachineOpCode _opCode, 37 unsigned numOperands, 38 OpCodeMask _opCodeMask) 39 : opCode(_opCode), 40 opCodeMask(_opCodeMask), 41 operands(numOperands) 42 { 43 } 44 45 void 46 MachineInstr::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 56 void 57 MachineInstr::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 67 void 68 MachineInstr::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 77 void 78 MachineInstr::dump(unsigned int indent) const 79 { 80 for (unsigned i=0; i < indent; i++) 81 cout << " "; 82 83 cout << *this; 84 } 85 86 ostream& 87 operator<< (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 108 static inline ostream& 109 OutputOperand(ostream &os, const MachineOperand &mop) 110 { 111 switch (mop.getOperandType()) 112 { 113 case MachineOperand::MO_CCRegister: 114 case MachineOperand::MO_VirtualRegister: 115 return os << "(val " << mop.getVRegValue() << ")"; 116 case MachineOperand::MO_MachineRegister: 117 return os << "(" << mop.getMachineRegNum() << ")"; 118 default: 119 assert(0 && "Unknown operand type"); 120 return os; 121 } 122 } 123 124 125 ostream& 126 operator<<(ostream &os, const MachineOperand &mop) 127 { 128 switch(mop.opType) 129 { 130 case MachineOperand::MO_VirtualRegister: 131 case MachineOperand::MO_MachineRegister: 132 os << "%reg"; 133 return OutputOperand(os, mop); 134 case MachineOperand::MO_CCRegister: 135 os << "%ccreg"; 136 return OutputOperand(os, mop); 137 case MachineOperand::MO_SignExtendedImmed: 138 return os << mop.immedVal; 139 case MachineOperand::MO_UnextendedImmed: 140 return os << mop.immedVal; 141 case MachineOperand::MO_PCRelativeDisp: 142 { 143 const Value* opVal = mop.getVRegValue(); 144 bool isLabel = isa<Method>(opVal) || isa<BasicBlock>(opVal); 145 return os << "%disp(" 146 << (isLabel? "label " : "addr-of-val ") 147 << opVal << ")"; 148 } 149 default: 150 assert(0 && "Unrecognized operand type"); 151 break; 152 } 153 154 return os; 155 } 156 157 158 //--------------------------------------------------------------------------- 159 // Target-independent utility routines for creating machine instructions 160 //--------------------------------------------------------------------------- 161 162 163 //------------------------------------------------------------------------ 164 // Function Set2OperandsFromInstr 165 // Function Set3OperandsFromInstr 166 // 167 // For the common case of 2- and 3-operand arithmetic/logical instructions, 168 // set the m/c instr. operands directly from the VM instruction's operands. 169 // Check whether the first or second operand is 0 and can use a dedicated "0" 170 // 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 187 void 188 Set2OperandsFromInstr(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 202 unsigned 203 Set3OperandsFromInstrJUNK(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 (isa<ConstPoolVal>(op1Value)) 225 { 226 // value is constant and must be loaded from constant pool 227 returnFlags = returnFlags | (1 << op1Position); 228 } 229 minstr->SetMachineOperand(op1Position, MachineOperand::MO_VirtualRegister, 230 op1Value); 231 } 232 233 // Check if operand 2 (if any) fits in the immed. field of the instruction, 234 // or if it is 0 and can use a dedicated machine register 235 if (op2Position >= 0) 236 { 237 Value* op2Value = vmInstrNode->rightChild()->getValue(); 238 int64_t immedValue; 239 unsigned int machineRegNum; 240 241 MachineOperand::MachineOperandType 242 op2type = ChooseRegOrImmed(op2Value, minstr->getOpCode(), target, 243 /*canUseImmed*/ true, 244 machineRegNum, immedValue); 245 246 if (op2type == MachineOperand::MO_MachineRegister) 247 minstr->SetMachineOperand(op2Position, machineRegNum); 248 else if (op2type == MachineOperand::MO_VirtualRegister) 249 { 250 if (isa<ConstPoolVal>(op2Value)) 251 { 252 // value is constant and must be loaded from constant pool 253 returnFlags = returnFlags | (1 << op2Position); 254 } 255 minstr->SetMachineOperand(op2Position, op2type, op2Value); 256 } 257 else 258 { 259 assert(op2type != MO_CCRegister); 260 minstr->SetMachineOperand(op2Position, op2type, immedValue); 261 } 262 } 263 264 // If operand 3 (result) can be discarded, use a dead register if one exists 265 if (canDiscardResult && target.zeroRegNum >= 0) 266 minstr->SetMachineOperand(resultPosition, target.zeroRegNum); 267 else 268 minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue()); 269 270 return returnFlags; 271 } 272 #endif 273 274 275 void 276 Set3OperandsFromInstr(MachineInstr* minstr, 277 InstructionNode* vmInstrNode, 278 const TargetMachine& target, 279 bool canDiscardResult, 280 int op1Position, 281 int op2Position, 282 int resultPosition) 283 { 284 assert(op1Position >= 0); 285 assert(resultPosition >= 0); 286 287 // operand 1 288 minstr->SetMachineOperand(op1Position, MachineOperand::MO_VirtualRegister, 289 vmInstrNode->leftChild()->getValue()); 290 291 // operand 2 (if any) 292 if (op2Position >= 0) 293 minstr->SetMachineOperand(op2Position, MachineOperand::MO_VirtualRegister, 294 vmInstrNode->rightChild()->getValue()); 295 296 // result operand: if it can be discarded, use a dead register if one exists 297 if (canDiscardResult && target.getRegInfo().getZeroRegNum() >= 0) 298 minstr->SetMachineOperand(resultPosition, 299 target.getRegInfo().getZeroRegNum()); 300 else 301 minstr->SetMachineOperand(resultPosition, 302 MachineOperand::MO_VirtualRegister, vmInstrNode->getValue()); 303 } 304 305 306 MachineOperand::MachineOperandType 307 ChooseRegOrImmed(Value* val, 308 MachineOpCode opCode, 309 const TargetMachine& target, 310 bool canUseImmed, 311 unsigned int& getMachineRegNum, 312 int64_t& getImmedValue) 313 { 314 MachineOperand::MachineOperandType opType = 315 MachineOperand::MO_VirtualRegister; 316 getMachineRegNum = 0; 317 getImmedValue = 0; 318 319 // Check for the common case first: argument is not constant 320 // 321 ConstPoolVal *CPV = dyn_cast<ConstPoolVal>(val); 322 if (!CPV) return opType; 323 324 if (CPV->getType() == Type::BoolTy) 325 { 326 ConstPoolBool *CPB = (ConstPoolBool*)CPV; 327 if (!CPB->getValue() && target.getRegInfo().getZeroRegNum() >= 0) 328 { 329 getMachineRegNum = target.getRegInfo().getZeroRegNum(); 330 return MachineOperand::MO_MachineRegister; 331 } 332 333 getImmedValue = 1; 334 return MachineOperand::MO_SignExtendedImmed; 335 } 336 337 if (!CPV->getType()->isIntegral()) return opType; 338 339 // Now get the constant value and check if it fits in the IMMED field. 340 // Take advantage of the fact that the max unsigned value will rarely 341 // fit into any IMMED field and ignore that case (i.e., cast smaller 342 // unsigned constants to signed). 343 // 344 int64_t intValue; 345 if (CPV->getType()->isSigned()) 346 { 347 intValue = ((ConstPoolSInt*)CPV)->getValue(); 348 } 349 else 350 { 351 uint64_t V = ((ConstPoolUInt*)CPV)->getValue(); 352 if (V >= INT64_MAX) return opType; 353 intValue = (int64_t)V; 354 } 355 356 if (intValue == 0 && target.getRegInfo().getZeroRegNum() >= 0) 357 { 358 opType = MachineOperand::MO_MachineRegister; 359 getMachineRegNum = target.getRegInfo().getZeroRegNum(); 360 } 361 else if (canUseImmed && 362 target.getInstrInfo().constantFitsInImmedField(opCode, intValue)) 363 { 364 opType = MachineOperand::MO_SignExtendedImmed; 365 getImmedValue = intValue; 366 } 367 368 return opType; 369 } 370 371 372 void 373 PrintMachineInstructions(const Method *const method) 374 { 375 cout << "\n" << method->getReturnType() 376 << " \"" << method->getName() << "\"" << endl; 377 378 for (Method::const_iterator BI = method->begin(); BI != method->end(); ++BI) 379 { 380 BasicBlock* bb = *BI; 381 cout << "\n" 382 << (bb->hasName()? bb->getName() : "Label") 383 << " (" << bb << ")" << ":" 384 << endl; 385 386 MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec(); 387 for (unsigned i=0; i < mvec.size(); i++) 388 cout << "\t" << *mvec[i] << endl; 389 } 390 cout << endl << "End method \"" << method->getName() << "\"" 391 << endl << endl; 392 } 393