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