blob: 3ce7a2a7f1ba33b2fc3797162a003e803e4be803 [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. Advebe495262001-11-08 04:47:06 +000017#include "llvm/Target/MachineFrameInfo.h"
Vikram S. Adve6e447182001-09-18 12:56:28 +000018#include "llvm/Target/MachineRegInfo.h"
Vikram S. Adve5b795912001-08-28 23:02:39 +000019#include "llvm/Method.h"
Vikram S. Advebe495262001-11-08 04:47:06 +000020#include "llvm/iOther.h"
Chris Lattner68498ce2001-07-21 23:24:48 +000021#include "llvm/Instruction.h"
Vikram S. Adve5b795912001-08-28 23:02:39 +000022
Vikram S. Advebe495262001-11-08 04:47:06 +000023AnnotationID MachineCodeForMethod::AID(
24 AnnotationManager::getID("MachineCodeForMethodAnnotation"));
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000025
Ruchira Sasanka69917e22001-10-18 22:40:02 +000026
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000027//************************ Class Implementations **************************/
28
Vikram S. Adve1885da42001-07-31 21:49:28 +000029// Constructor for instructions with fixed #operands (nearly all)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000030MachineInstr::MachineInstr(MachineOpCode _opCode,
31 OpCodeMask _opCodeMask)
32 : opCode(_opCode),
33 opCodeMask(_opCodeMask),
Vikram S. Adve6a175e02001-07-28 04:06:37 +000034 operands(TargetInstrDescriptors[_opCode].numOperands)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000035{
Vikram S. Adve1885da42001-07-31 21:49:28 +000036 assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
37}
38
39// Constructor for instructions with variable #operands
40MachineInstr::MachineInstr(MachineOpCode _opCode,
41 unsigned numOperands,
42 OpCodeMask _opCodeMask)
43 : opCode(_opCode),
44 opCodeMask(_opCodeMask),
45 operands(numOperands)
46{
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000047}
48
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000049void
50MachineInstr::SetMachineOperand(unsigned int i,
51 MachineOperand::MachineOperandType operandType,
Ruchira Sasanka45c171e2001-08-07 20:16:52 +000052 Value* _val, bool isdef=false)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000053{
Vikram S. Adve6a175e02001-07-28 04:06:37 +000054 assert(i < operands.size());
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000055 operands[i].Initialize(operandType, _val);
Vikram S. Adve149977b2001-08-13 16:32:45 +000056 operands[i].isDef = isdef ||
Vikram S. Adve6e447182001-09-18 12:56:28 +000057 TargetInstrDescriptors[opCode].resultPos == (int) i;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000058}
59
60void
61MachineInstr::SetMachineOperand(unsigned int i,
62 MachineOperand::MachineOperandType operandType,
Ruchira Sasanka45c171e2001-08-07 20:16:52 +000063 int64_t intValue, bool isdef=false)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000064{
Vikram S. Adve6a175e02001-07-28 04:06:37 +000065 assert(i < operands.size());
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000066 operands[i].InitializeConst(operandType, intValue);
Vikram S. Adve149977b2001-08-13 16:32:45 +000067 operands[i].isDef = isdef ||
Vikram S. Adve6e447182001-09-18 12:56:28 +000068 TargetInstrDescriptors[opCode].resultPos == (int) i;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000069}
70
71void
72MachineInstr::SetMachineOperand(unsigned int i,
Vikram S. Advedf1c3b82001-11-05 03:56:02 +000073 int regNum, bool isdef=false)
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000074{
Vikram S. Adve6a175e02001-07-28 04:06:37 +000075 assert(i < operands.size());
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000076 operands[i].InitializeReg(regNum);
Vikram S. Adve149977b2001-08-13 16:32:45 +000077 operands[i].isDef = isdef ||
Vikram S. Adve6e447182001-09-18 12:56:28 +000078 TargetInstrDescriptors[opCode].resultPos == (int) i;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000079}
80
81void
Ruchira Sasanka0b03c6a2001-08-07 21:01:23 +000082MachineInstr::dump(unsigned int indent) const
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000083{
84 for (unsigned i=0; i < indent; i++)
85 cout << " ";
86
87 cout << *this;
88}
89
90ostream&
91operator<< (ostream& os, const MachineInstr& minstr)
92{
Vikram S. Adve6a175e02001-07-28 04:06:37 +000093 os << TargetInstrDescriptors[minstr.opCode].opCodeString;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000094
95 for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++)
96 os << "\t" << minstr.getOperand(i);
97
Vikram S. Adve6a175e02001-07-28 04:06:37 +000098#undef DEBUG_VAL_OP_ITERATOR
99#ifdef DEBUG_VAL_OP_ITERATOR
100 os << endl << "\tValue operands are: ";
101 for (MachineInstr::val_op_const_iterator vo(&minstr); ! vo.done(); ++vo)
102 {
103 const Value* val = *vo;
104 os << val << (vo.isDef()? "(def), " : ", ");
105 }
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000106#endif
107
Ruchira Sasanka69917e22001-10-18 22:40:02 +0000108
109
110#if 1
111 // code for printing implict references
112
113 unsigned NumOfImpRefs = minstr.getNumImplicitRefs();
114 if( NumOfImpRefs > 0 ) {
115
116 os << "\tImplicit:";
117
118 for(unsigned z=0; z < NumOfImpRefs; z++) {
119 os << minstr.getImplicitRef(z);
120 cout << "\t";
121 }
122 }
123
124#endif
125
126
Vikram S. Adve6d353262001-10-17 23:57:50 +0000127 os << endl;
128
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000129 return os;
130}
131
Vikram S. Adve6e447182001-09-18 12:56:28 +0000132static inline ostream&
133OutputOperand(ostream &os, const MachineOperand &mop)
134{
Vikram S. Adved9beb972001-11-12 14:19:47 +0000135 Value* val;
Vikram S. Adve6e447182001-09-18 12:56:28 +0000136 switch (mop.getOperandType())
137 {
138 case MachineOperand::MO_CCRegister:
139 case MachineOperand::MO_VirtualRegister:
Vikram S. Adved9beb972001-11-12 14:19:47 +0000140 val = mop.getVRegValue();
141 os << "(val ";
142 if (val && val->hasName())
143 os << val->getName().c_str();
144 else
145 os << val;
146 return os << ")";
Vikram S. Adve6e447182001-09-18 12:56:28 +0000147 case MachineOperand::MO_MachineRegister:
148 return os << "(" << mop.getMachineRegNum() << ")";
149 default:
150 assert(0 && "Unknown operand type");
151 return os;
152 }
Chris Lattnere6fdb112001-09-09 22:26:29 +0000153}
154
155
Vikram S. Adve6e447182001-09-18 12:56:28 +0000156ostream&
157operator<<(ostream &os, const MachineOperand &mop)
158{
159 switch(mop.opType)
160 {
161 case MachineOperand::MO_VirtualRegister:
162 case MachineOperand::MO_MachineRegister:
163 os << "%reg";
164 return OutputOperand(os, mop);
165 case MachineOperand::MO_CCRegister:
166 os << "%ccreg";
167 return OutputOperand(os, mop);
168 case MachineOperand::MO_SignExtendedImmed:
169 return os << mop.immedVal;
170 case MachineOperand::MO_UnextendedImmed:
171 return os << mop.immedVal;
172 case MachineOperand::MO_PCRelativeDisp:
Vikram S. Advee949da52001-09-30 23:44:19 +0000173 {
174 const Value* opVal = mop.getVRegValue();
Chris Lattner1d87bcf2001-10-01 20:11:19 +0000175 bool isLabel = isa<Method>(opVal) || isa<BasicBlock>(opVal);
Vikram S. Adved9beb972001-11-12 14:19:47 +0000176 os << "%disp(" << (isLabel? "label " : "addr-of-val ");
177 if (opVal->hasName())
178 os << opVal->getName().c_str();
179 else
180 os << opVal;
181 return os << ")";
Vikram S. Advee949da52001-09-30 23:44:19 +0000182 }
Vikram S. Adve6e447182001-09-18 12:56:28 +0000183 default:
184 assert(0 && "Unrecognized operand type");
185 break;
186 }
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000187
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000188 return os;
189}
190
Vikram S. Advebe495262001-11-08 04:47:06 +0000191static unsigned int
192ComputeMaxOptionalArgsSize(const TargetMachine& target, const Method* method)
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000193{
Vikram S. Advebe495262001-11-08 04:47:06 +0000194 const MachineFrameInfo& frameInfo = target.getFrameInfo();
195
196 unsigned int maxSize = 0;
197
198 for (Method::inst_const_iterator I=method->inst_begin(),E=method->inst_end();
199 I != E; ++I)
200 if ((*I)->getOpcode() == Instruction::Call)
201 {
202 CallInst* callInst = cast<CallInst>(*I);
203 unsigned int numOperands = callInst->getNumOperands() - 1;
Vikram S. Advef1a0a102001-11-11 21:23:33 +0000204 int numExtra = (int) numOperands - frameInfo.getNumFixedOutgoingArgs();
205 if (numExtra <= 0)
206 continue;
Vikram S. Advebe495262001-11-08 04:47:06 +0000207
208 unsigned int sizeForThisCall;
209 if (frameInfo.argsOnStackHaveFixedSize())
210 {
211 int argSize = frameInfo.getSizeOfEachArgOnStack();
212 sizeForThisCall = numExtra * (unsigned) argSize;
213 }
214 else
215 {
216 assert(0 && "UNTESTED CODE: Size per stack argument is not fixed on this architecture: use actual arg sizes to compute MaxOptionalArgsSize");
217 sizeForThisCall = 0;
218 for (unsigned i=0; i < numOperands; ++i)
219 sizeForThisCall += target.findOptimalStorageSize(callInst->
220 getOperand(i)->getType());
221 }
222
223 if (maxSize < sizeForThisCall)
224 maxSize = sizeForThisCall;
225 }
226
227 return maxSize;
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000228}
229
230
Vikram S. Advebe495262001-11-08 04:47:06 +0000231/*ctor*/
232MachineCodeForMethod::MachineCodeForMethod(const Method* _M,
233 const TargetMachine& target)
234 : Annotation(AID),
235 method(_M), compiledAsLeaf(false), staticStackSize(0),
236 automaticVarsSize(0), regSpillsSize(0),
237 currentOptionalArgsSize(0), maxOptionalArgsSize(0),
238 currentTmpValuesSize(0)
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000239{
Vikram S. Advebe495262001-11-08 04:47:06 +0000240 maxOptionalArgsSize = ComputeMaxOptionalArgsSize(target, method);
241 staticStackSize = maxOptionalArgsSize +
242 target.getFrameInfo().getMinStackFrameSize();
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000243}
244
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000245int
Vikram S. Advebe495262001-11-08 04:47:06 +0000246MachineCodeForMethod::allocateLocalVar(const TargetMachine& target,
247 const Value* val)
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000248{
Vikram S. Advebe495262001-11-08 04:47:06 +0000249 // Check if we've allocated a stack slot for this value already
250 //
251 int offset = getOffset(val);
252 if (offset == INVALID_FRAME_OFFSET)
253 {
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000254 bool growUp;
255 int firstOffset =target.getFrameInfo().getFirstAutomaticVarOffset(*this,
256 growUp);
Vikram S. Adve5567e942001-11-12 05:17:23 +0000257 unsigned int size = target.findOptimalStorageSize(val->getType());
258 unsigned char align = target.DataLayout.getTypeAlignment(val->getType());
259
260 offset = getAutomaticVarsSize();
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000261 if (! growUp)
262 offset += size;
263
Vikram S. Adve5567e942001-11-12 05:17:23 +0000264 if (unsigned int mod = offset % align)
265 {
266 offset += align - mod;
267 size += align - mod;
268 }
269
Vikram S. Adve5567e942001-11-12 05:17:23 +0000270 offset = growUp? firstOffset + offset
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000271 : firstOffset - offset;
Vikram S. Advef1a0a102001-11-11 21:23:33 +0000272
Vikram S. Advebe495262001-11-08 04:47:06 +0000273 offsets[val] = offset;
274
Vikram S. Advebe495262001-11-08 04:47:06 +0000275 incrementAutomaticVarsSize(size);
276 }
277 return offset;
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000278}
279
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000280int
Vikram S. Advebe495262001-11-08 04:47:06 +0000281MachineCodeForMethod::allocateSpilledValue(const TargetMachine& target,
282 const Type* type)
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000283{
Vikram S. Adve5567e942001-11-12 05:17:23 +0000284 unsigned int size = target.findOptimalStorageSize(type);
285 unsigned char align = target.DataLayout.getTypeAlignment(type);
286
Vikram S. Advebe495262001-11-08 04:47:06 +0000287 bool growUp;
288 int firstOffset = target.getFrameInfo().getRegSpillAreaOffset(*this, growUp);
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000289
290 int offset = getRegSpillsSize();
291 if (! growUp)
292 offset += size;
293
294 if (unsigned int mod = offset % align)
295 {
296 offset += align - mod;
297 size += align - mod;
298 }
299
Vikram S. Adve5567e942001-11-12 05:17:23 +0000300 offset = growUp? firstOffset + offset
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000301 : firstOffset - offset;
Vikram S. Advef1a0a102001-11-11 21:23:33 +0000302
Vikram S. Advebe495262001-11-08 04:47:06 +0000303 incrementRegSpillsSize(size);
304
305 return offset;
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000306}
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000307
Vikram S. Advebe495262001-11-08 04:47:06 +0000308int
309MachineCodeForMethod::allocateOptionalArg(const TargetMachine& target,
310 const Type* type)
311{
312 const MachineFrameInfo& frameInfo = target.getFrameInfo();
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000313
Vikram S. Advebe495262001-11-08 04:47:06 +0000314 int size = MAXINT;
315 if (frameInfo.argsOnStackHaveFixedSize())
316 size = frameInfo.getSizeOfEachArgOnStack();
317 else
318 {
Vikram S. Advebe495262001-11-08 04:47:06 +0000319 size = target.findOptimalStorageSize(type);
Vikram S. Advef1a0a102001-11-11 21:23:33 +0000320 assert(0 && "UNTESTED CODE: Size per stack argument is not fixed on this architecture: use actual argument sizes for computing optional arg offsets");
Vikram S. Advebe495262001-11-08 04:47:06 +0000321 }
Vikram S. Adve5567e942001-11-12 05:17:23 +0000322 unsigned char align = target.DataLayout.getTypeAlignment(type);
Vikram S. Advebe495262001-11-08 04:47:06 +0000323
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000324 bool growUp;
325 int firstOffset = frameInfo.getFirstOptionalOutgoingArgOffset(*this, growUp);
326
Vikram S. Adve5567e942001-11-12 05:17:23 +0000327 int offset = getCurrentOptionalArgsSize();
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000328 if (! growUp)
329 offset += size;
330
Vikram S. Adve5567e942001-11-12 05:17:23 +0000331 if (unsigned int mod = offset % align)
332 {
333 offset += align - mod;
334 size += align - mod;
335 }
336
Vikram S. Adve5567e942001-11-12 05:17:23 +0000337 offset = growUp? firstOffset + offset
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000338 : firstOffset - offset;
Vikram S. Adve5567e942001-11-12 05:17:23 +0000339
Vikram S. Advebe495262001-11-08 04:47:06 +0000340 incrementCurrentOptionalArgsSize(size);
341
342 return offset;
343}
344
345void
346MachineCodeForMethod::resetOptionalArgs(const TargetMachine& target)
347{
348 currentOptionalArgsSize = 0;
349}
350
351int
352MachineCodeForMethod::pushTempValue(const TargetMachine& target,
353 unsigned int size)
354{
Vikram S. Adve5567e942001-11-12 05:17:23 +0000355 // Compute a power-of-2 alignment according to the possible sizes,
356 // but not greater than the alignment of the largest type we support
357 // (currently a double word -- see class TargetData).
358 unsigned char align = 1;
359 for (; align < size && align < target.DataLayout.getDoubleAlignment();
360 align = 2*align)
361 ;
362
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000363 bool growUp;
364 int firstTmpOffset = target.getFrameInfo().getTmpAreaOffset(*this, growUp);
365
Vikram S. Adve5567e942001-11-12 05:17:23 +0000366 int offset = currentTmpValuesSize;
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000367 if (! growUp)
368 offset += size;
369
Vikram S. Adve5567e942001-11-12 05:17:23 +0000370 if (unsigned int mod = offset % align)
371 {
372 offset += align - mod;
373 size += align - mod;
374 }
375
Vikram S. Adve5567e942001-11-12 05:17:23 +0000376 offset = growUp? firstTmpOffset + offset
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000377 : firstTmpOffset - offset;
Vikram S. Adve5567e942001-11-12 05:17:23 +0000378
Vikram S. Advebe495262001-11-08 04:47:06 +0000379 currentTmpValuesSize += size;
380 return offset;
381}
382
383void
384MachineCodeForMethod::popAllTempValues(const TargetMachine& target)
385{
386 currentTmpValuesSize = 0;
387}
388
Vikram S. Advebe495262001-11-08 04:47:06 +0000389int
390MachineCodeForMethod::getOffset(const Value* val) const
391{
392 hash_map<const Value*, int>::const_iterator pair = offsets.find(val);
393 return (pair == offsets.end())? INVALID_FRAME_OFFSET : (*pair).second;
394}
395
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000396void
397MachineCodeForMethod::dump() const
Ruchira Sasankaed8f6742001-09-15 19:07:45 +0000398{
399 cout << "\n" << method->getReturnType()
400 << " \"" << method->getName() << "\"" << endl;
401
402 for (Method::const_iterator BI = method->begin(); BI != method->end(); ++BI)
403 {
404 BasicBlock* bb = *BI;
405 cout << "\n"
406 << (bb->hasName()? bb->getName() : "Label")
407 << " (" << bb << ")" << ":"
408 << endl;
409
410 MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec();
411 for (unsigned i=0; i < mvec.size(); i++)
Vikram S. Adve6d353262001-10-17 23:57:50 +0000412 cout << "\t" << *mvec[i];
Ruchira Sasankaed8f6742001-09-15 19:07:45 +0000413 }
414 cout << endl << "End method \"" << method->getName() << "\""
415 << endl << endl;
416}