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 return os << "%disp(label " << mop.getVRegValue() << ")"; 143 default: 144 assert(0 && "Unrecognized operand type"); 145 break; 146 } 147 148 return os; 149 } 150 151 152 //--------------------------------------------------------------------------- 153 // Target-independent utility routines for creating machine instructions 154 //--------------------------------------------------------------------------- 155 156 157 //------------------------------------------------------------------------ 158 // Function Set2OperandsFromInstr 159 // Function Set3OperandsFromInstr 160 // 161 // For the common case of 2- and 3-operand arithmetic/logical instructions, 162 // set the m/c instr. operands directly from the VM instruction's operands. 163 // Check whether the first or second operand is 0 and can use a dedicated "0" 164 // 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 181 void 182 Set2OperandsFromInstr(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 196 unsigned 197 Set3OperandsFromInstrJUNK(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->isConstant()) 219 { 220 // value is constant and must be loaded from constant pool 221 returnFlags = returnFlags | (1 << op1Position); 222 } 223 minstr->SetMachineOperand(op1Position, MachineOperand::MO_VirtualRegister, 224 op1Value); 225 } 226 227 // Check if operand 2 (if any) fits in the immed. field of the instruction, 228 // or if it is 0 and can use a dedicated machine register 229 if (op2Position >= 0) 230 { 231 Value* op2Value = vmInstrNode->rightChild()->getValue(); 232 int64_t immedValue; 233 unsigned int machineRegNum; 234 235 MachineOperand::MachineOperandType 236 op2type = ChooseRegOrImmed(op2Value, minstr->getOpCode(), target, 237 /*canUseImmed*/ true, 238 machineRegNum, immedValue); 239 240 if (op2type == MachineOperand::MO_MachineRegister) 241 minstr->SetMachineOperand(op2Position, machineRegNum); 242 else if (op2type == MachineOperand::MO_VirtualRegister) 243 { 244 if (op2Value->isConstant()) 245 { 246 // value is constant and must be loaded from constant pool 247 returnFlags = returnFlags | (1 << op2Position); 248 } 249 minstr->SetMachineOperand(op2Position, op2type, op2Value); 250 } 251 else 252 { 253 assert(op2type != MO_CCRegister); 254 minstr->SetMachineOperand(op2Position, op2type, immedValue); 255 } 256 } 257 258 // If operand 3 (result) can be discarded, use a dead register if one exists 259 if (canDiscardResult && target.zeroRegNum >= 0) 260 minstr->SetMachineOperand(resultPosition, target.zeroRegNum); 261 else 262 minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue()); 263 264 return returnFlags; 265 } 266 #endif 267 268 269 void 270 Set3OperandsFromInstr(MachineInstr* minstr, 271 InstructionNode* vmInstrNode, 272 const TargetMachine& target, 273 bool canDiscardResult, 274 int op1Position, 275 int op2Position, 276 int resultPosition) 277 { 278 assert(op1Position >= 0); 279 assert(resultPosition >= 0); 280 281 // operand 1 282 minstr->SetMachineOperand(op1Position, MachineOperand::MO_VirtualRegister, 283 vmInstrNode->leftChild()->getValue()); 284 285 // operand 2 (if any) 286 if (op2Position >= 0) 287 minstr->SetMachineOperand(op2Position, MachineOperand::MO_VirtualRegister, 288 vmInstrNode->rightChild()->getValue()); 289 290 // result operand: if it can be discarded, use a dead register if one exists 291 if (canDiscardResult && target.getRegInfo().getZeroRegNum() >= 0) 292 minstr->SetMachineOperand(resultPosition, 293 target.getRegInfo().getZeroRegNum()); 294 else 295 minstr->SetMachineOperand(resultPosition, 296 MachineOperand::MO_VirtualRegister, vmInstrNode->getValue()); 297 } 298 299 300 MachineOperand::MachineOperandType 301 ChooseRegOrImmed(Value* val, 302 MachineOpCode opCode, 303 const TargetMachine& target, 304 bool canUseImmed, 305 unsigned int& getMachineRegNum, 306 int64_t& getImmedValue) 307 { 308 MachineOperand::MachineOperandType opType = 309 MachineOperand::MO_VirtualRegister; 310 getMachineRegNum = 0; 311 getImmedValue = 0; 312 313 // Check for the common case first: argument is not constant 314 // 315 ConstPoolVal *CPV = val->castConstant(); 316 if (!CPV) return opType; 317 318 if (CPV->getType() == Type::BoolTy) 319 { 320 ConstPoolBool *CPB = (ConstPoolBool*)CPV; 321 if (!CPB->getValue() && target.getRegInfo().getZeroRegNum() >= 0) 322 { 323 getMachineRegNum = target.getRegInfo().getZeroRegNum(); 324 return MachineOperand::MO_MachineRegister; 325 } 326 327 getImmedValue = 1; 328 return MachineOperand::MO_SignExtendedImmed; 329 } 330 331 if (!CPV->getType()->isIntegral()) return opType; 332 333 // Now get the constant value and check if it fits in the IMMED field. 334 // Take advantage of the fact that the max unsigned value will rarely 335 // fit into any IMMED field and ignore that case (i.e., cast smaller 336 // unsigned constants to signed). 337 // 338 int64_t intValue; 339 if (CPV->getType()->isSigned()) 340 { 341 intValue = ((ConstPoolSInt*)CPV)->getValue(); 342 } 343 else 344 { 345 uint64_t V = ((ConstPoolUInt*)CPV)->getValue(); 346 if (V >= INT64_MAX) return opType; 347 intValue = (int64_t)V; 348 } 349 350 if (intValue == 0 && target.getRegInfo().getZeroRegNum() >= 0) 351 { 352 opType = MachineOperand::MO_MachineRegister; 353 getMachineRegNum = target.getRegInfo().getZeroRegNum(); 354 } 355 else if (canUseImmed && 356 target.getInstrInfo().constantFitsInImmedField(opCode, intValue)) 357 { 358 opType = MachineOperand::MO_SignExtendedImmed; 359 getImmedValue = intValue; 360 } 361 362 return opType; 363 } 364 365 366 void 367 PrintMachineInstructions(const Method *const method) 368 { 369 cout << "\n" << method->getReturnType() 370 << " \"" << method->getName() << "\"" << endl; 371 372 for (Method::const_iterator BI = method->begin(); BI != method->end(); ++BI) 373 { 374 BasicBlock* bb = *BI; 375 cout << "\n" 376 << (bb->hasName()? bb->getName() : "Label") 377 << " (" << bb << ")" << ":" 378 << endl; 379 380 MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec(); 381 for (unsigned i=0; i < mvec.size(); i++) 382 cout << "\t" << *mvec[i] << endl; 383 } 384 cout << endl << "End method \"" << method->getName() << "\"" 385 << endl << endl; 386 } 387