MachineInstr.cpp revision 45c171ee25619f6650e90fa5e3102d9969fd82b3
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, bool isdef=false) 46{ 47 assert(i < operands.size()); 48 operands[i].Initialize(operandType, _val); 49 operands[i].isDef = isdef; 50} 51 52void 53MachineInstr::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 62void 63MachineInstr::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 71void 72MachineInstr::dump(unsigned int indent) 73{ 74 for (unsigned i=0; i < indent; i++) 75 cout << " "; 76 77 cout << *this; 78} 79 80ostream& 81operator<< (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 102ostream& 103operator<< (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 175void 176Set2OperandsFromInstr(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 190unsigned 191Set3OperandsFromInstrJUNK(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); 253 else 254 minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue()); 255 256 return returnFlags; 257} 258#endif 259 260 261void 262Set3OperandsFromInstr(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); 285 else 286 minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue()); 287} 288 289 290MachineOperand::MachineOperandType 291ChooseRegOrImmed(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