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