2 //***************************************************************************
12 // 7/2/01 - Vikram Adve - Created
13 //**************************************************************************/
16 //************************** System Include Files ***************************/
21 //*************************** User Include Files ***************************/
23 #include "llvm/Method.h"
24 #include "llvm/ConstPoolVals.h"
25 #include "llvm/Instruction.h"
26 #include "llvm/CodeGen/MachineInstr.h"
29 //************************ Class Implementations **************************/
31 // Constructor for instructions with fixed #operands (nearly all)
32 MachineInstr::MachineInstr(MachineOpCode _opCode,
33 OpCodeMask _opCodeMask)
35 opCodeMask(_opCodeMask),
36 operands(TargetInstrDescriptors[_opCode].numOperands)
38 assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
41 // Constructor for instructions with variable #operands
42 MachineInstr::MachineInstr(MachineOpCode _opCode,
44 OpCodeMask _opCodeMask)
46 opCodeMask(_opCodeMask),
52 MachineInstr::SetMachineOperand(unsigned int i,
53 MachineOperand::MachineOperandType operandType,
54 Value* _val, bool isdef=false)
56 assert(i < operands.size());
57 operands[i].Initialize(operandType, _val);
58 operands[i].isDef = isdef ||
59 TargetInstrDescriptors[opCode].resultPos == (int) i;
63 MachineInstr::SetMachineOperand(unsigned int i,
64 MachineOperand::MachineOperandType operandType,
65 int64_t intValue, bool isdef=false)
67 assert(i < operands.size());
68 operands[i].InitializeConst(operandType, intValue);
69 operands[i].isDef = isdef ||
70 TargetInstrDescriptors[opCode].resultPos == (int) i;
74 MachineInstr::SetMachineOperand(unsigned int i,
75 unsigned int regNum, bool isdef=false)
77 assert(i < operands.size());
78 operands[i].InitializeReg(regNum);
79 operands[i].isDef = isdef ||
80 TargetInstrDescriptors[opCode].resultPos == (int) i;
84 MachineInstr::dump(unsigned int indent) const
86 for (unsigned i=0; i < indent; i++)
93 operator<< (ostream& os, const MachineInstr& minstr)
95 os << TargetInstrDescriptors[minstr.opCode].opCodeString;
97 for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++)
98 os << "\t" << minstr.getOperand(i);
100 #undef DEBUG_VAL_OP_ITERATOR
101 #ifdef DEBUG_VAL_OP_ITERATOR
102 os << endl << "\tValue operands are: ";
103 for (MachineInstr::val_op_const_iterator vo(&minstr); ! vo.done(); ++vo)
105 const Value* val = *vo;
106 os << val << (vo.isDef()? "(def), " : ", ");
115 operator<< (ostream& os, const MachineOperand& mop)
118 if (mop.opType == MachineOperand::MO_VirtualRegister)
119 regInfo << "(val " << mop.value << ")" << ends;
120 else if (mop.opType == MachineOperand::MO_MachineRegister)
121 regInfo << "(" << mop.regNum << ")" << ends;
122 else if (mop.opType == MachineOperand::MO_CCRegister)
123 regInfo << "(val " << mop.value << ")" << ends;
127 case MachineOperand::MO_VirtualRegister:
128 case MachineOperand::MO_MachineRegister:
129 os << "%reg" << regInfo.str();
133 case MachineOperand::MO_CCRegister:
134 os << "%ccreg" << regInfo.str();
138 case MachineOperand::MO_SignExtendedImmed:
142 case MachineOperand::MO_UnextendedImmed:
146 case MachineOperand::MO_PCRelativeDisp:
147 os << "%disp(label " << mop.value << ")";
151 assert(0 && "Unrecognized operand type");
159 //---------------------------------------------------------------------------
160 // Target-independent utility routines for creating machine instructions
161 //---------------------------------------------------------------------------
164 //------------------------------------------------------------------------
165 // Function Set2OperandsFromInstr
166 // Function Set3OperandsFromInstr
168 // For the common case of 2- and 3-operand arithmetic/logical instructions,
169 // set the m/c instr. operands directly from the VM instruction's operands.
170 // Check whether the first or second operand is 0 and can use a dedicated "0" register.
171 // Check whether the second operand should use an immediate field or register.
172 // (First and third operands are never immediates for such instructions.)
175 // canDiscardResult: Specifies that the result operand can be discarded
176 // by using the dedicated "0"
178 // op1position, op2position and resultPosition: Specify in which position
179 // in the machine instruction the 3 operands (arg1, arg2
180 // and result) should go.
182 // RETURN VALUE: unsigned int flags, where
183 // flags & 0x01 => operand 1 is constant and needs a register
184 // flags & 0x02 => operand 2 is constant and needs a register
185 //------------------------------------------------------------------------
188 Set2OperandsFromInstr(MachineInstr* minstr,
189 InstructionNode* vmInstrNode,
190 const TargetMachine& target,
191 bool canDiscardResult,
195 Set3OperandsFromInstr(minstr, vmInstrNode, target,
196 canDiscardResult, op1Position,
197 /*op2Position*/ -1, resultPosition);
200 #undef REVERT_TO_EXPLICIT_CONSTANT_CHECKS
201 #ifdef REVERT_TO_EXPLICIT_CONSTANT_CHECKS
203 Set3OperandsFromInstrJUNK(MachineInstr* minstr,
204 InstructionNode* vmInstrNode,
205 const TargetMachine& target,
206 bool canDiscardResult,
211 assert(op1Position >= 0);
212 assert(resultPosition >= 0);
214 unsigned returnFlags = 0x0;
216 // Check if operand 1 is 0. If so, try to use a hardwired 0 register.
217 Value* op1Value = vmInstrNode->leftChild()->getValue();
218 bool isValidConstant;
219 int64_t intValue = GetConstantValueAsSignedInt(op1Value, isValidConstant);
220 if (isValidConstant && intValue == 0 && target.zeroRegNum >= 0)
221 minstr->SetMachineOperand(op1Position, /*regNum*/ target.zeroRegNum);
224 if (op1Value->getValueType() == Value::ConstantVal)
225 {// value is constant and must be loaded from constant pool
226 returnFlags = returnFlags | (1 << op1Position);
228 minstr->SetMachineOperand(op1Position,MachineOperand::MO_VirtualRegister,
232 // Check if operand 2 (if any) fits in the immed. field of the instruction,
233 // or if it is 0 and can use a dedicated machine register
234 if (op2Position >= 0)
236 Value* op2Value = vmInstrNode->rightChild()->getValue();
238 unsigned int machineRegNum;
240 MachineOperand::MachineOperandType
241 op2type = ChooseRegOrImmed(op2Value, minstr->getOpCode(), target,
242 /*canUseImmed*/ true,
243 machineRegNum, immedValue);
245 if (op2type == MachineOperand::MO_MachineRegister)
246 minstr->SetMachineOperand(op2Position, machineRegNum);
247 else if (op2type == MachineOperand::MO_VirtualRegister)
249 if (op2Value->getValueType() == Value::ConstantVal)
250 {// value is constant and must be loaded from constant pool
251 returnFlags = returnFlags | (1 << op2Position);
253 minstr->SetMachineOperand(op2Position, op2type, op2Value);
257 assert(op2type != MO_CCRegister);
258 minstr->SetMachineOperand(op2Position, op2type, immedValue);
262 // If operand 3 (result) can be discarded, use a dead register if one exists
263 if (canDiscardResult && target.zeroRegNum >= 0)
264 minstr->SetMachineOperand(resultPosition, target.zeroRegNum);
266 minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
274 Set3OperandsFromInstr(MachineInstr* minstr,
275 InstructionNode* vmInstrNode,
276 const TargetMachine& target,
277 bool canDiscardResult,
282 assert(op1Position >= 0);
283 assert(resultPosition >= 0);
286 minstr->SetMachineOperand(op1Position, MachineOperand::MO_VirtualRegister,
287 vmInstrNode->leftChild()->getValue());
289 // operand 2 (if any)
290 if (op2Position >= 0)
291 minstr->SetMachineOperand(op2Position, MachineOperand::MO_VirtualRegister,
292 vmInstrNode->rightChild()->getValue());
294 // result operand: if it can be discarded, use a dead register if one exists
295 if (canDiscardResult && target.zeroRegNum >= 0)
296 minstr->SetMachineOperand(resultPosition, target.zeroRegNum);
298 minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
302 MachineOperand::MachineOperandType
303 ChooseRegOrImmed(Value* val,
304 MachineOpCode opCode,
305 const TargetMachine& target,
307 unsigned int& getMachineRegNum,
308 int64_t& getImmedValue)
310 MachineOperand::MachineOperandType opType =
311 MachineOperand::MO_VirtualRegister;
312 getMachineRegNum = 0;
315 // Check for the common case first: argument is not constant
317 if (val->getValueType() != Value::ConstantVal)
320 // Now get the constant value and check if it fits in the IMMED field.
321 // Take advantage of the fact that the max unsigned value will rarely
322 // fit into any IMMED field and ignore that case (i.e., cast smaller
323 // unsigned constants to signed).
325 bool isValidConstant;
326 int64_t intValue = GetConstantValueAsSignedInt(val, isValidConstant);
330 if (intValue == 0 && target.zeroRegNum >= 0)
332 opType = MachineOperand::MO_MachineRegister;
333 getMachineRegNum = target.zeroRegNum;
335 else if (canUseImmed &&
336 target.getInstrInfo().constantFitsInImmedField(opCode,intValue))
338 opType = MachineOperand::MO_SignExtendedImmed;
339 getImmedValue = intValue;
348 PrintMachineInstructions(Method* method)
350 cout << "\n" << method->getReturnType()
351 << " \"" << method->getName() << "\"" << endl;
353 for (Method::const_iterator BI = method->begin(); BI != method->end(); ++BI)
355 BasicBlock* bb = *BI;
357 << (bb->hasName()? bb->getName() : "Label")
358 << " (" << bb << ")" << ":"
361 MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec();
362 for (unsigned i=0; i < mvec.size(); i++)
363 cout << "\t" << *mvec[i] << endl;
365 cout << endl << "End method \"" << method->getName() << "\""