blob: 1db2d48fc9e9ec8295fdf24ad430806e9183c642 [file] [log] [blame]
Vikram S. Adve70bc4b52001-07-21 12:41:50 +00001// $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
Vikram S. Adve5b795912001-08-28 23:02:39 +000015
Chris Lattner822b4fb2001-09-07 17:18:30 +000016#include "llvm/CodeGen/MachineInstr.h"
Vikram S. Adve6e447182001-09-18 12:56:28 +000017#include "llvm/Target/MachineRegInfo.h"
Vikram S. Adve5b795912001-08-28 23:02:39 +000018#include "llvm/Method.h"
Chris Lattner68498ce2001-07-21 23:24:48 +000019#include "llvm/ConstPoolVals.h"
20#include "llvm/Instruction.h"
Vikram S. Adve5b795912001-08-28 23:02:39 +000021
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000022
23//************************ Class Implementations **************************/
24
Vikram S. Adve1885da42001-07-31 21:49:28 +000025// Constructor for instructions with fixed #operands (nearly all)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000026MachineInstr::MachineInstr(MachineOpCode _opCode,
27 OpCodeMask _opCodeMask)
28 : opCode(_opCode),
29 opCodeMask(_opCodeMask),
Vikram S. Adve6a175e02001-07-28 04:06:37 +000030 operands(TargetInstrDescriptors[_opCode].numOperands)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000031{
Vikram S. Adve1885da42001-07-31 21:49:28 +000032 assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
33}
34
35// Constructor for instructions with variable #operands
36MachineInstr::MachineInstr(MachineOpCode _opCode,
37 unsigned numOperands,
38 OpCodeMask _opCodeMask)
39 : opCode(_opCode),
40 opCodeMask(_opCodeMask),
41 operands(numOperands)
42{
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000043}
44
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000045void
46MachineInstr::SetMachineOperand(unsigned int i,
47 MachineOperand::MachineOperandType operandType,
Ruchira Sasanka45c171e2001-08-07 20:16:52 +000048 Value* _val, bool isdef=false)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000049{
Vikram S. Adve6a175e02001-07-28 04:06:37 +000050 assert(i < operands.size());
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000051 operands[i].Initialize(operandType, _val);
Vikram S. Adve149977b2001-08-13 16:32:45 +000052 operands[i].isDef = isdef ||
Vikram S. Adve6e447182001-09-18 12:56:28 +000053 TargetInstrDescriptors[opCode].resultPos == (int) i;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000054}
55
56void
57MachineInstr::SetMachineOperand(unsigned int i,
58 MachineOperand::MachineOperandType operandType,
Ruchira Sasanka45c171e2001-08-07 20:16:52 +000059 int64_t intValue, bool isdef=false)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000060{
Vikram S. Adve6a175e02001-07-28 04:06:37 +000061 assert(i < operands.size());
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000062 operands[i].InitializeConst(operandType, intValue);
Vikram S. Adve149977b2001-08-13 16:32:45 +000063 operands[i].isDef = isdef ||
Vikram S. Adve6e447182001-09-18 12:56:28 +000064 TargetInstrDescriptors[opCode].resultPos == (int) i;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000065}
66
67void
68MachineInstr::SetMachineOperand(unsigned int i,
Ruchira Sasanka45c171e2001-08-07 20:16:52 +000069 unsigned int regNum, bool isdef=false)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000070{
Vikram S. Adve6a175e02001-07-28 04:06:37 +000071 assert(i < operands.size());
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000072 operands[i].InitializeReg(regNum);
Vikram S. Adve149977b2001-08-13 16:32:45 +000073 operands[i].isDef = isdef ||
Vikram S. Adve6e447182001-09-18 12:56:28 +000074 TargetInstrDescriptors[opCode].resultPos == (int) i;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000075}
76
77void
Ruchira Sasanka0b03c6a2001-08-07 21:01:23 +000078MachineInstr::dump(unsigned int indent) const
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000079{
80 for (unsigned i=0; i < indent; i++)
81 cout << " ";
82
83 cout << *this;
84}
85
86ostream&
87operator<< (ostream& os, const MachineInstr& minstr)
88{
Vikram S. Adve6a175e02001-07-28 04:06:37 +000089 os << TargetInstrDescriptors[minstr.opCode].opCodeString;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000090
91 for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++)
92 os << "\t" << minstr.getOperand(i);
93
Vikram S. Adve6a175e02001-07-28 04:06:37 +000094#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)
98 {
99 const Value* val = *vo;
100 os << val << (vo.isDef()? "(def), " : ", ");
101 }
102 os << endl;
103#endif
104
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000105 return os;
106}
107
Vikram S. Adve6e447182001-09-18 12:56:28 +0000108static inline ostream&
109OutputOperand(ostream &os, const MachineOperand &mop)
110{
111 switch (mop.getOperandType())
112 {
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() << ")";
118 default:
119 assert(0 && "Unknown operand type");
120 return os;
121 }
Chris Lattnere6fdb112001-09-09 22:26:29 +0000122}
123
124
Vikram S. Adve6e447182001-09-18 12:56:28 +0000125ostream&
126operator<<(ostream &os, const MachineOperand &mop)
127{
128 switch(mop.opType)
129 {
130 case MachineOperand::MO_VirtualRegister:
131 case MachineOperand::MO_MachineRegister:
132 os << "%reg";
133 return OutputOperand(os, mop);
134 case MachineOperand::MO_CCRegister:
135 os << "%ccreg";
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:
142 return os << "%disp(label " << mop.getVRegValue() << ")";
143 default:
144 assert(0 && "Unrecognized operand type");
145 break;
146 }
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000147
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000148 return os;
149}
150
151
152//---------------------------------------------------------------------------
153// Target-independent utility routines for creating machine instructions
154//---------------------------------------------------------------------------
155
156
157//------------------------------------------------------------------------
158// Function Set2OperandsFromInstr
159// Function Set3OperandsFromInstr
160//
161// For the common case of 2- and 3-operand arithmetic/logical instructions,
162// set the m/c instr. operands directly from the VM instruction's operands.
Chris Lattnerc2a23962001-09-11 23:22:43 +0000163// Check whether the first or second operand is 0 and can use a dedicated "0"
164// register.
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000165// Check whether the second operand should use an immediate field or register.
166// (First and third operands are never immediates for such instructions.)
167//
168// Arguments:
169// canDiscardResult: Specifies that the result operand can be discarded
170// by using the dedicated "0"
171//
172// op1position, op2position and resultPosition: Specify in which position
173// in the machine instruction the 3 operands (arg1, arg2
174// and result) should go.
175//
176// RETURN VALUE: unsigned int flags, where
177// flags & 0x01 => operand 1 is constant and needs a register
178// flags & 0x02 => operand 2 is constant and needs a register
179//------------------------------------------------------------------------
180
181void
182Set2OperandsFromInstr(MachineInstr* minstr,
183 InstructionNode* vmInstrNode,
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000184 const TargetMachine& target,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000185 bool canDiscardResult,
186 int op1Position,
187 int resultPosition)
188{
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000189 Set3OperandsFromInstr(minstr, vmInstrNode, target,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000190 canDiscardResult, op1Position,
191 /*op2Position*/ -1, resultPosition);
192}
193
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000194#undef REVERT_TO_EXPLICIT_CONSTANT_CHECKS
195#ifdef REVERT_TO_EXPLICIT_CONSTANT_CHECKS
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000196unsigned
197Set3OperandsFromInstrJUNK(MachineInstr* minstr,
Vikram S. Adve6e447182001-09-18 12:56:28 +0000198 InstructionNode* vmInstrNode,
199 const TargetMachine& target,
200 bool canDiscardResult,
201 int op1Position,
202 int op2Position,
203 int resultPosition)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000204{
205 assert(op1Position >= 0);
206 assert(resultPosition >= 0);
207
208 unsigned returnFlags = 0x0;
209
Vikram S. Adve5b795912001-08-28 23:02:39 +0000210 // Check if operand 1 is 0. If so, try to use a hardwired 0 register.
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000211 Value* op1Value = vmInstrNode->leftChild()->getValue();
212 bool isValidConstant;
213 int64_t intValue = GetConstantValueAsSignedInt(op1Value, isValidConstant);
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000214 if (isValidConstant && intValue == 0 && target.zeroRegNum >= 0)
215 minstr->SetMachineOperand(op1Position, /*regNum*/ target.zeroRegNum);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000216 else
217 {
Vikram S. Adve6e447182001-09-18 12:56:28 +0000218 if (op1Value->isConstant())
219 {
220 // value is constant and must be loaded from constant pool
221 returnFlags = returnFlags | (1 << op1Position);
222 }
Chris Lattnerb221a762001-09-10 19:43:38 +0000223 minstr->SetMachineOperand(op1Position, MachineOperand::MO_VirtualRegister,
224 op1Value);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000225 }
226
Vikram S. Adve5b795912001-08-28 23:02:39 +0000227 // Check if operand 2 (if any) fits in the immed. field of the instruction,
228 // or if it is 0 and can use a dedicated machine register
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000229 if (op2Position >= 0)
230 {
231 Value* op2Value = vmInstrNode->rightChild()->getValue();
232 int64_t immedValue;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000233 unsigned int machineRegNum;
234
235 MachineOperand::MachineOperandType
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000236 op2type = ChooseRegOrImmed(op2Value, minstr->getOpCode(), target,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000237 /*canUseImmed*/ true,
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000238 machineRegNum, immedValue);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000239
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000240 if (op2type == MachineOperand::MO_MachineRegister)
241 minstr->SetMachineOperand(op2Position, machineRegNum);
242 else if (op2type == MachineOperand::MO_VirtualRegister)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000243 {
Vikram S. Adve6e447182001-09-18 12:56:28 +0000244 if (op2Value->isConstant())
245 {
246 // value is constant and must be loaded from constant pool
247 returnFlags = returnFlags | (1 << op2Position);
248 }
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000249 minstr->SetMachineOperand(op2Position, op2type, op2Value);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000250 }
251 else
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000252 {
253 assert(op2type != MO_CCRegister);
254 minstr->SetMachineOperand(op2Position, op2type, immedValue);
255 }
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000256 }
257
258 // If operand 3 (result) can be discarded, use a dead register if one exists
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000259 if (canDiscardResult && target.zeroRegNum >= 0)
Vikram S. Adve149977b2001-08-13 16:32:45 +0000260 minstr->SetMachineOperand(resultPosition, target.zeroRegNum);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000261 else
Vikram S. Adve149977b2001-08-13 16:32:45 +0000262 minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000263
264 return returnFlags;
265}
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000266#endif
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000267
268
269void
270Set3OperandsFromInstr(MachineInstr* minstr,
271 InstructionNode* vmInstrNode,
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000272 const TargetMachine& target,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000273 bool canDiscardResult,
274 int op1Position,
275 int op2Position,
276 int resultPosition)
277{
278 assert(op1Position >= 0);
279 assert(resultPosition >= 0);
280
281 // operand 1
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000282 minstr->SetMachineOperand(op1Position, MachineOperand::MO_VirtualRegister,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000283 vmInstrNode->leftChild()->getValue());
284
285 // operand 2 (if any)
286 if (op2Position >= 0)
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000287 minstr->SetMachineOperand(op2Position, MachineOperand::MO_VirtualRegister,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000288 vmInstrNode->rightChild()->getValue());
289
290 // result operand: if it can be discarded, use a dead register if one exists
Vikram S. Adve6e447182001-09-18 12:56:28 +0000291 if (canDiscardResult && target.getRegInfo().getZeroRegNum() >= 0)
292 minstr->SetMachineOperand(resultPosition,
293 target.getRegInfo().getZeroRegNum());
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000294 else
Vikram S. Adve6e447182001-09-18 12:56:28 +0000295 minstr->SetMachineOperand(resultPosition,
296 MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000297}
298
299
300MachineOperand::MachineOperandType
301ChooseRegOrImmed(Value* val,
302 MachineOpCode opCode,
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000303 const TargetMachine& target,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000304 bool canUseImmed,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000305 unsigned int& getMachineRegNum,
306 int64_t& getImmedValue)
307{
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000308 MachineOperand::MachineOperandType opType =
309 MachineOperand::MO_VirtualRegister;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000310 getMachineRegNum = 0;
311 getImmedValue = 0;
312
313 // Check for the common case first: argument is not constant
314 //
Chris Lattner990f2a52001-09-09 23:01:32 +0000315 ConstPoolVal *CPV = val->castConstant();
316 if (!CPV) return opType;
317
Vikram S. Adve6e447182001-09-18 12:56:28 +0000318 if (CPV->getType() == Type::BoolTy)
319 {
320 ConstPoolBool *CPB = (ConstPoolBool*)CPV;
321 if (!CPB->getValue() && target.getRegInfo().getZeroRegNum() >= 0)
322 {
323 getMachineRegNum = target.getRegInfo().getZeroRegNum();
324 return MachineOperand::MO_MachineRegister;
325 }
Chris Lattner990f2a52001-09-09 23:01:32 +0000326
Vikram S. Adve6e447182001-09-18 12:56:28 +0000327 getImmedValue = 1;
328 return MachineOperand::MO_SignExtendedImmed;
329 }
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000330
Chris Lattner990f2a52001-09-09 23:01:32 +0000331 if (!CPV->getType()->isIntegral()) return opType;
332
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000333 // Now get the constant value and check if it fits in the IMMED field.
334 // Take advantage of the fact that the max unsigned value will rarely
335 // fit into any IMMED field and ignore that case (i.e., cast smaller
336 // unsigned constants to signed).
337 //
Chris Lattner990f2a52001-09-09 23:01:32 +0000338 int64_t intValue;
Vikram S. Adve6e447182001-09-18 12:56:28 +0000339 if (CPV->getType()->isSigned())
340 {
341 intValue = ((ConstPoolSInt*)CPV)->getValue();
342 }
343 else
344 {
345 uint64_t V = ((ConstPoolUInt*)CPV)->getValue();
346 if (V >= INT64_MAX) return opType;
347 intValue = (int64_t)V;
348 }
Chris Lattner990f2a52001-09-09 23:01:32 +0000349
Vikram S. Adve6e447182001-09-18 12:56:28 +0000350 if (intValue == 0 && target.getRegInfo().getZeroRegNum() >= 0)
351 {
352 opType = MachineOperand::MO_MachineRegister;
353 getMachineRegNum = target.getRegInfo().getZeroRegNum();
354 }
355 else if (canUseImmed &&
356 target.getInstrInfo().constantFitsInImmedField(opCode, intValue))
357 {
358 opType = MachineOperand::MO_SignExtendedImmed;
359 getImmedValue = intValue;
360 }
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000361
362 return opType;
363}
Vikram S. Adve5b795912001-08-28 23:02:39 +0000364
365
366void
Ruchira Sasankaed8f6742001-09-15 19:07:45 +0000367PrintMachineInstructions(const Method *const method)
368{
369 cout << "\n" << method->getReturnType()
370 << " \"" << method->getName() << "\"" << endl;
371
372 for (Method::const_iterator BI = method->begin(); BI != method->end(); ++BI)
373 {
374 BasicBlock* bb = *BI;
375 cout << "\n"
376 << (bb->hasName()? bb->getName() : "Label")
377 << " (" << bb << ")" << ":"
378 << endl;
379
380 MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec();
381 for (unsigned i=0; i < mvec.size(); i++)
382 cout << "\t" << *mvec[i] << endl;
383 }
384 cout << endl << "End method \"" << method->getName() << "\""
385 << endl << endl;
386}