MachineInstr.cpp revision 1885da4f49cf32efde2d4c840365c4333a0c8579
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) 23MachineInstr::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 33MachineInstr::MachineInstr(MachineOpCode _opCode, 34 unsigned numOperands, 35 OpCodeMask _opCodeMask) 36 : opCode(_opCode), 37 opCodeMask(_opCodeMask), 38 operands(numOperands) 39{ 40} 41 42void 43MachineInstr::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 51void 52MachineInstr::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 60void 61MachineInstr::SetMachineOperand(unsigned int i, 62 unsigned int regNum) 63{ 64 assert(i < operands.size()); 65 operands[i].InitializeReg(regNum); 66} 67 68void 69MachineInstr::dump(unsigned int indent) 70{ 71 for (unsigned i=0; i < indent; i++) 72 cout << " "; 73 74 cout << *this; 75} 76 77ostream& 78operator<< (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 99ostream& 100operator<< (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 172void 173Set2OperandsFromInstr(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 187unsigned 188Set3OperandsFromInstrJUNK(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 258void 259Set3OperandsFromInstr(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 287MachineOperand::MachineOperandType 288ChooseRegOrImmed(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