blob: 4a632587b626d503c752d4bc91e9aeaae3bd5272 [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. Adve5b795912001-08-28 23:02:39 +000017#include "llvm/Method.h"
Chris Lattner68498ce2001-07-21 23:24:48 +000018#include "llvm/ConstPoolVals.h"
19#include "llvm/Instruction.h"
Chris Lattner822b4fb2001-09-07 17:18:30 +000020#include <strstream>
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 ||
53 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 ||
64 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 ||
74 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
108ostream&
109operator<< (ostream& os, const MachineOperand& mop)
110{
111 strstream regInfo;
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000112 if (mop.opType == MachineOperand::MO_VirtualRegister)
113 regInfo << "(val " << mop.value << ")" << ends;
114 else if (mop.opType == MachineOperand::MO_MachineRegister)
115 regInfo << "(" << mop.regNum << ")" << ends;
116 else if (mop.opType == MachineOperand::MO_CCRegister)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000117 regInfo << "(val " << mop.value << ")" << ends;
118
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000119 switch(mop.opType)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000120 {
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000121 case MachineOperand::MO_VirtualRegister:
122 case MachineOperand::MO_MachineRegister:
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000123 os << "%reg" << regInfo.str();
124 free(regInfo.str());
125 break;
126
127 case MachineOperand::MO_CCRegister:
128 os << "%ccreg" << regInfo.str();
129 free(regInfo.str());
130 break;
131
132 case MachineOperand::MO_SignExtendedImmed:
133 os << mop.immedVal;
134 break;
135
136 case MachineOperand::MO_UnextendedImmed:
137 os << mop.immedVal;
138 break;
139
140 case MachineOperand::MO_PCRelativeDisp:
141 os << "%disp(label " << mop.value << ")";
142 break;
143
144 default:
145 assert(0 && "Unrecognized operand type");
146 break;
147 }
148
149 return os;
150}
151
152
153//---------------------------------------------------------------------------
154// Target-independent utility routines for creating machine instructions
155//---------------------------------------------------------------------------
156
157
158//------------------------------------------------------------------------
159// Function Set2OperandsFromInstr
160// Function Set3OperandsFromInstr
161//
162// For the common case of 2- and 3-operand arithmetic/logical instructions,
163// set the m/c instr. operands directly from the VM instruction's operands.
164// Check whether the first or second operand is 0 and can use a dedicated "0" register.
165// 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,
198 InstructionNode* vmInstrNode,
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000199 const TargetMachine& target,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000200 bool canDiscardResult,
201 int op1Position,
202 int op2Position,
203 int resultPosition)
204{
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 {
218 if (op1Value->getValueType() == Value::ConstantVal)
219 {// value is constant and must be loaded from constant pool
220 returnFlags = returnFlags | (1 << op1Position);
221 }
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000222 minstr->SetMachineOperand(op1Position,MachineOperand::MO_VirtualRegister,
223 op1Value);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000224 }
225
Vikram S. Adve5b795912001-08-28 23:02:39 +0000226 // Check if operand 2 (if any) fits in the immed. field of the instruction,
227 // or if it is 0 and can use a dedicated machine register
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000228 if (op2Position >= 0)
229 {
230 Value* op2Value = vmInstrNode->rightChild()->getValue();
231 int64_t immedValue;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000232 unsigned int machineRegNum;
233
234 MachineOperand::MachineOperandType
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000235 op2type = ChooseRegOrImmed(op2Value, minstr->getOpCode(), target,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000236 /*canUseImmed*/ true,
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000237 machineRegNum, immedValue);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000238
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000239 if (op2type == MachineOperand::MO_MachineRegister)
240 minstr->SetMachineOperand(op2Position, machineRegNum);
241 else if (op2type == MachineOperand::MO_VirtualRegister)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000242 {
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000243 if (op2Value->getValueType() == Value::ConstantVal)
244 {// value is constant and must be loaded from constant pool
245 returnFlags = returnFlags | (1 << op2Position);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000246 }
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000247 minstr->SetMachineOperand(op2Position, op2type, op2Value);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000248 }
249 else
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000250 {
251 assert(op2type != MO_CCRegister);
252 minstr->SetMachineOperand(op2Position, op2type, immedValue);
253 }
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000254 }
255
256 // If operand 3 (result) can be discarded, use a dead register if one exists
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000257 if (canDiscardResult && target.zeroRegNum >= 0)
Vikram S. Adve149977b2001-08-13 16:32:45 +0000258 minstr->SetMachineOperand(resultPosition, target.zeroRegNum);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000259 else
Vikram S. Adve149977b2001-08-13 16:32:45 +0000260 minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000261
262 return returnFlags;
263}
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000264#endif
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000265
266
267void
268Set3OperandsFromInstr(MachineInstr* minstr,
269 InstructionNode* vmInstrNode,
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000270 const TargetMachine& target,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000271 bool canDiscardResult,
272 int op1Position,
273 int op2Position,
274 int resultPosition)
275{
276 assert(op1Position >= 0);
277 assert(resultPosition >= 0);
278
279 // operand 1
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000280 minstr->SetMachineOperand(op1Position, MachineOperand::MO_VirtualRegister,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000281 vmInstrNode->leftChild()->getValue());
282
283 // operand 2 (if any)
284 if (op2Position >= 0)
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000285 minstr->SetMachineOperand(op2Position, MachineOperand::MO_VirtualRegister,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000286 vmInstrNode->rightChild()->getValue());
287
288 // result operand: if it can be discarded, use a dead register if one exists
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000289 if (canDiscardResult && target.zeroRegNum >= 0)
Vikram S. Adve149977b2001-08-13 16:32:45 +0000290 minstr->SetMachineOperand(resultPosition, target.zeroRegNum);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000291 else
Vikram S. Adve149977b2001-08-13 16:32:45 +0000292 minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000293}
294
295
296MachineOperand::MachineOperandType
297ChooseRegOrImmed(Value* val,
298 MachineOpCode opCode,
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000299 const TargetMachine& target,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000300 bool canUseImmed,
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000301 unsigned int& getMachineRegNum,
302 int64_t& getImmedValue)
303{
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000304 MachineOperand::MachineOperandType opType =
305 MachineOperand::MO_VirtualRegister;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000306 getMachineRegNum = 0;
307 getImmedValue = 0;
308
309 // Check for the common case first: argument is not constant
310 //
311 if (val->getValueType() != Value::ConstantVal)
312 return opType;
313
314 // Now get the constant value and check if it fits in the IMMED field.
315 // Take advantage of the fact that the max unsigned value will rarely
316 // fit into any IMMED field and ignore that case (i.e., cast smaller
317 // unsigned constants to signed).
318 //
319 bool isValidConstant;
320 int64_t intValue = GetConstantValueAsSignedInt(val, isValidConstant);
321
322 if (isValidConstant)
323 {
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000324 if (intValue == 0 && target.zeroRegNum >= 0)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000325 {
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000326 opType = MachineOperand::MO_MachineRegister;
327 getMachineRegNum = target.zeroRegNum;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000328 }
329 else if (canUseImmed &&
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000330 target.getInstrInfo().constantFitsInImmedField(opCode,intValue))
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000331 {
332 opType = MachineOperand::MO_SignExtendedImmed;
333 getImmedValue = intValue;
334 }
335 }
336
337 return opType;
338}
Vikram S. Adve5b795912001-08-28 23:02:39 +0000339
340
341void
342PrintMachineInstructions(Method* method)
343{
344 cout << "\n" << method->getReturnType()
345 << " \"" << method->getName() << "\"" << endl;
346
347 for (Method::const_iterator BI = method->begin(); BI != method->end(); ++BI)
348 {
349 BasicBlock* bb = *BI;
350 cout << "\n"
351 << (bb->hasName()? bb->getName() : "Label")
352 << " (" << bb << ")" << ":"
353 << endl;
354
355 MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec();
356 for (unsigned i=0; i < mvec.size(); i++)
357 cout << "\t" << *mvec[i] << endl;
358 }
359 cout << endl << "End method \"" << method->getName() << "\""
360 << endl << endl;
361}