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