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) 32 MachineInstr::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 42 MachineInstr::MachineInstr(MachineOpCode _opCode, 43 unsigned numOperands, 44 OpCodeMask _opCodeMask) 45 : opCode(_opCode), 46 opCodeMask(_opCodeMask), 47 operands(numOperands) 48 { 49 } 50 51 void 52 MachineInstr::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 62 void 63 MachineInstr::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 73 void 74 MachineInstr::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 83 void 84 MachineInstr::dump(unsigned int indent) const 85 { 86 for (unsigned i=0; i < indent; i++) 87 cout << " "; 88 89 cout << *this; 90 } 91 92 ostream& 93 operator<< (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 114 ostream& 115 operator<< (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 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 (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 273 void 274 Set3OperandsFromInstr(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 302 MachineOperand::MachineOperandType 303 ChooseRegOrImmed(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 347 void 348 PrintMachineInstructions(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