2 //***************************************************************************
12 // 7/2/01 - Vikram Adve - Created
13 //**************************************************************************/
16 #include "llvm/CodeGen/MachineInstr.h"
17 #include "llvm/Target/MachineRegInfo.h"
18 #include "llvm/Method.h"
19 #include "llvm/ConstPoolVals.h"
20 #include "llvm/Instruction.h"
23 //************************ Class Implementations **************************/
25 // Constructor for instructions with fixed #operands (nearly all)
26 MachineInstr::MachineInstr(MachineOpCode _opCode,
27 OpCodeMask _opCodeMask)
29 opCodeMask(_opCodeMask),
30 operands(TargetInstrDescriptors[_opCode].numOperands)
32 assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
35 // Constructor for instructions with variable #operands
36 MachineInstr::MachineInstr(MachineOpCode _opCode,
38 OpCodeMask _opCodeMask)
40 opCodeMask(_opCodeMask),
46 MachineInstr::SetMachineOperand(unsigned int i,
47 MachineOperand::MachineOperandType operandType,
48 Value* _val, bool isdef=false)
50 assert(i < operands.size());
51 operands[i].Initialize(operandType, _val);
52 operands[i].isDef = isdef ||
53 TargetInstrDescriptors[opCode].resultPos == (int) i;
57 MachineInstr::SetMachineOperand(unsigned int i,
58 MachineOperand::MachineOperandType operandType,
59 int64_t intValue, bool isdef=false)
61 assert(i < operands.size());
62 operands[i].InitializeConst(operandType, intValue);
63 operands[i].isDef = isdef ||
64 TargetInstrDescriptors[opCode].resultPos == (int) i;
68 MachineInstr::SetMachineOperand(unsigned int i,
69 unsigned int regNum, bool isdef=false)
71 assert(i < operands.size());
72 operands[i].InitializeReg(regNum);
73 operands[i].isDef = isdef ||
74 TargetInstrDescriptors[opCode].resultPos == (int) i;
78 MachineInstr::dump(unsigned int indent) const
80 for (unsigned i=0; i < indent; i++)
87 operator<< (ostream& os, const MachineInstr& minstr)
89 os << TargetInstrDescriptors[minstr.opCode].opCodeString;
91 for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++)
92 os << "\t" << minstr.getOperand(i);
94 #undef DEBUG_VAL_OP_ITERATOR
95 #ifdef DEBUG_VAL_OP_ITERATOR
96 os << endl << "\tValue operands are: ";
97 for (MachineInstr::val_op_const_iterator vo(&minstr); ! vo.done(); ++vo)
99 const Value* val = *vo;
100 os << val << (vo.isDef()? "(def), " : ", ");
108 static inline ostream&
109 OutputOperand(ostream &os, const MachineOperand &mop)
111 switch (mop.getOperandType())
113 case MachineOperand::MO_CCRegister:
114 case MachineOperand::MO_VirtualRegister:
115 return os << "(val " << mop.getVRegValue() << ")";
116 case MachineOperand::MO_MachineRegister:
117 return os << "(" << mop.getMachineRegNum() << ")";
119 assert(0 && "Unknown operand type");
126 operator<<(ostream &os, const MachineOperand &mop)
130 case MachineOperand::MO_VirtualRegister:
131 case MachineOperand::MO_MachineRegister:
133 return OutputOperand(os, mop);
134 case MachineOperand::MO_CCRegister:
136 return OutputOperand(os, mop);
137 case MachineOperand::MO_SignExtendedImmed:
138 return os << mop.immedVal;
139 case MachineOperand::MO_UnextendedImmed:
140 return os << mop.immedVal;
141 case MachineOperand::MO_PCRelativeDisp:
143 const Value* opVal = mop.getVRegValue();
144 bool isLabel = isa<Method>(opVal) || isa<BasicBlock>(opVal);
145 return os << "%disp("
146 << (isLabel? "label " : "addr-of-val ")
150 assert(0 && "Unrecognized operand type");
158 //---------------------------------------------------------------------------
159 // Target-independent utility routines for creating machine instructions
160 //---------------------------------------------------------------------------
163 //------------------------------------------------------------------------
164 // Function Set2OperandsFromInstr
165 // Function Set3OperandsFromInstr
167 // For the common case of 2- and 3-operand arithmetic/logical instructions,
168 // set the m/c instr. operands directly from the VM instruction's operands.
169 // Check whether the first or second operand is 0 and can use a dedicated "0"
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 (isa<ConstPoolVal>(op1Value))
226 // value is constant and must be loaded from constant pool
227 returnFlags = returnFlags | (1 << op1Position);
229 minstr->SetMachineOperand(op1Position, MachineOperand::MO_VirtualRegister,
233 // Check if operand 2 (if any) fits in the immed. field of the instruction,
234 // or if it is 0 and can use a dedicated machine register
235 if (op2Position >= 0)
237 Value* op2Value = vmInstrNode->rightChild()->getValue();
239 unsigned int machineRegNum;
241 MachineOperand::MachineOperandType
242 op2type = ChooseRegOrImmed(op2Value, minstr->getOpCode(), target,
243 /*canUseImmed*/ true,
244 machineRegNum, immedValue);
246 if (op2type == MachineOperand::MO_MachineRegister)
247 minstr->SetMachineOperand(op2Position, machineRegNum);
248 else if (op2type == MachineOperand::MO_VirtualRegister)
250 if (isa<ConstPoolVal>(op2Value))
252 // value is constant and must be loaded from constant pool
253 returnFlags = returnFlags | (1 << op2Position);
255 minstr->SetMachineOperand(op2Position, op2type, op2Value);
259 assert(op2type != MO_CCRegister);
260 minstr->SetMachineOperand(op2Position, op2type, immedValue);
264 // If operand 3 (result) can be discarded, use a dead register if one exists
265 if (canDiscardResult && target.zeroRegNum >= 0)
266 minstr->SetMachineOperand(resultPosition, target.zeroRegNum);
268 minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
276 Set3OperandsFromInstr(MachineInstr* minstr,
277 InstructionNode* vmInstrNode,
278 const TargetMachine& target,
279 bool canDiscardResult,
284 assert(op1Position >= 0);
285 assert(resultPosition >= 0);
288 minstr->SetMachineOperand(op1Position, MachineOperand::MO_VirtualRegister,
289 vmInstrNode->leftChild()->getValue());
291 // operand 2 (if any)
292 if (op2Position >= 0)
293 minstr->SetMachineOperand(op2Position, MachineOperand::MO_VirtualRegister,
294 vmInstrNode->rightChild()->getValue());
296 // result operand: if it can be discarded, use a dead register if one exists
297 if (canDiscardResult && target.getRegInfo().getZeroRegNum() >= 0)
298 minstr->SetMachineOperand(resultPosition,
299 target.getRegInfo().getZeroRegNum());
301 minstr->SetMachineOperand(resultPosition,
302 MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
306 MachineOperand::MachineOperandType
307 ChooseRegOrImmed(Value* val,
308 MachineOpCode opCode,
309 const TargetMachine& target,
311 unsigned int& getMachineRegNum,
312 int64_t& getImmedValue)
314 MachineOperand::MachineOperandType opType =
315 MachineOperand::MO_VirtualRegister;
316 getMachineRegNum = 0;
319 // Check for the common case first: argument is not constant
321 ConstPoolVal *CPV = dyn_cast<ConstPoolVal>(val);
322 if (!CPV) return opType;
324 if (CPV->getType() == Type::BoolTy)
326 ConstPoolBool *CPB = (ConstPoolBool*)CPV;
327 if (!CPB->getValue() && target.getRegInfo().getZeroRegNum() >= 0)
329 getMachineRegNum = target.getRegInfo().getZeroRegNum();
330 return MachineOperand::MO_MachineRegister;
334 return MachineOperand::MO_SignExtendedImmed;
337 if (!CPV->getType()->isIntegral()) return opType;
339 // Now get the constant value and check if it fits in the IMMED field.
340 // Take advantage of the fact that the max unsigned value will rarely
341 // fit into any IMMED field and ignore that case (i.e., cast smaller
342 // unsigned constants to signed).
345 if (CPV->getType()->isSigned())
347 intValue = ((ConstPoolSInt*)CPV)->getValue();
351 uint64_t V = ((ConstPoolUInt*)CPV)->getValue();
352 if (V >= INT64_MAX) return opType;
353 intValue = (int64_t)V;
356 if (intValue == 0 && target.getRegInfo().getZeroRegNum() >= 0)
358 opType = MachineOperand::MO_MachineRegister;
359 getMachineRegNum = target.getRegInfo().getZeroRegNum();
361 else if (canUseImmed &&
362 target.getInstrInfo().constantFitsInImmedField(opCode, intValue))
364 opType = MachineOperand::MO_SignExtendedImmed;
365 getImmedValue = intValue;
373 PrintMachineInstructions(const Method *const method)
375 cout << "\n" << method->getReturnType()
376 << " \"" << method->getName() << "\"" << endl;
378 for (Method::const_iterator BI = method->begin(); BI != method->end(); ++BI)
380 BasicBlock* bb = *BI;
382 << (bb->hasName()? bb->getName() : "Label")
383 << " (" << bb << ")" << ":"
386 MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec();
387 for (unsigned i=0; i < mvec.size(); i++)
388 cout << "\t" << *mvec[i] << endl;
390 cout << endl << "End method \"" << method->getName() << "\""