blob: 5993daf65a0ab46410865d180b682e5276ad97b3 [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
Ruchira Sasanka8d243372001-11-14 20:05:23 +000095 for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++) {
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000096 os << "\t" << minstr.getOperand(i);
Ruchira Sasanka8d243372001-11-14 20:05:23 +000097 if( minstr.getOperand(i).opIsDef() ) os << "*";
98
99 }
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000100
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000101#undef DEBUG_VAL_OP_ITERATOR
102#ifdef DEBUG_VAL_OP_ITERATOR
103 os << endl << "\tValue operands are: ";
104 for (MachineInstr::val_op_const_iterator vo(&minstr); ! vo.done(); ++vo)
105 {
106 const Value* val = *vo;
107 os << val << (vo.isDef()? "(def), " : ", ");
108 }
Vikram S. Adve6a175e02001-07-28 04:06:37 +0000109#endif
110
Ruchira Sasanka69917e22001-10-18 22:40:02 +0000111
112
113#if 1
114 // code for printing implict references
115
116 unsigned NumOfImpRefs = minstr.getNumImplicitRefs();
117 if( NumOfImpRefs > 0 ) {
118
119 os << "\tImplicit:";
120
121 for(unsigned z=0; z < NumOfImpRefs; z++) {
122 os << minstr.getImplicitRef(z);
Ruchira Sasanka8d243372001-11-14 20:05:23 +0000123 if( minstr.implicitRefIsDefined(z)) os << "*";
124 cout << "\t";
Ruchira Sasanka69917e22001-10-18 22:40:02 +0000125 }
126 }
127
128#endif
129
130
Vikram S. Adve6d353262001-10-17 23:57:50 +0000131 os << endl;
132
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000133 return os;
134}
135
Vikram S. Adve6e447182001-09-18 12:56:28 +0000136static inline ostream&
137OutputOperand(ostream &os, const MachineOperand &mop)
138{
Vikram S. Adved9beb972001-11-12 14:19:47 +0000139 Value* val;
Vikram S. Adve6e447182001-09-18 12:56:28 +0000140 switch (mop.getOperandType())
141 {
142 case MachineOperand::MO_CCRegister:
143 case MachineOperand::MO_VirtualRegister:
Vikram S. Adved9beb972001-11-12 14:19:47 +0000144 val = mop.getVRegValue();
145 os << "(val ";
146 if (val && val->hasName())
147 os << val->getName().c_str();
148 else
149 os << val;
150 return os << ")";
Vikram S. Adve6e447182001-09-18 12:56:28 +0000151 case MachineOperand::MO_MachineRegister:
152 return os << "(" << mop.getMachineRegNum() << ")";
153 default:
154 assert(0 && "Unknown operand type");
155 return os;
156 }
Chris Lattnere6fdb112001-09-09 22:26:29 +0000157}
158
159
Vikram S. Adve6e447182001-09-18 12:56:28 +0000160ostream&
161operator<<(ostream &os, const MachineOperand &mop)
162{
163 switch(mop.opType)
164 {
165 case MachineOperand::MO_VirtualRegister:
166 case MachineOperand::MO_MachineRegister:
167 os << "%reg";
168 return OutputOperand(os, mop);
169 case MachineOperand::MO_CCRegister:
170 os << "%ccreg";
171 return OutputOperand(os, mop);
172 case MachineOperand::MO_SignExtendedImmed:
173 return os << mop.immedVal;
174 case MachineOperand::MO_UnextendedImmed:
175 return os << mop.immedVal;
176 case MachineOperand::MO_PCRelativeDisp:
Vikram S. Advee949da52001-09-30 23:44:19 +0000177 {
178 const Value* opVal = mop.getVRegValue();
Chris Lattner1d87bcf2001-10-01 20:11:19 +0000179 bool isLabel = isa<Method>(opVal) || isa<BasicBlock>(opVal);
Vikram S. Adved9beb972001-11-12 14:19:47 +0000180 os << "%disp(" << (isLabel? "label " : "addr-of-val ");
181 if (opVal->hasName())
182 os << opVal->getName().c_str();
183 else
184 os << opVal;
185 return os << ")";
Vikram S. Advee949da52001-09-30 23:44:19 +0000186 }
Vikram S. Adve6e447182001-09-18 12:56:28 +0000187 default:
188 assert(0 && "Unrecognized operand type");
189 break;
190 }
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000191
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000192 return os;
193}
194
Vikram S. Advebe495262001-11-08 04:47:06 +0000195static unsigned int
196ComputeMaxOptionalArgsSize(const TargetMachine& target, const Method* method)
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000197{
Vikram S. Advebe495262001-11-08 04:47:06 +0000198 const MachineFrameInfo& frameInfo = target.getFrameInfo();
199
200 unsigned int maxSize = 0;
201
202 for (Method::inst_const_iterator I=method->inst_begin(),E=method->inst_end();
203 I != E; ++I)
204 if ((*I)->getOpcode() == Instruction::Call)
205 {
206 CallInst* callInst = cast<CallInst>(*I);
207 unsigned int numOperands = callInst->getNumOperands() - 1;
Vikram S. Advef1a0a102001-11-11 21:23:33 +0000208 int numExtra = (int) numOperands - frameInfo.getNumFixedOutgoingArgs();
209 if (numExtra <= 0)
210 continue;
Vikram S. Advebe495262001-11-08 04:47:06 +0000211
212 unsigned int sizeForThisCall;
213 if (frameInfo.argsOnStackHaveFixedSize())
214 {
215 int argSize = frameInfo.getSizeOfEachArgOnStack();
216 sizeForThisCall = numExtra * (unsigned) argSize;
217 }
218 else
219 {
220 assert(0 && "UNTESTED CODE: Size per stack argument is not fixed on this architecture: use actual arg sizes to compute MaxOptionalArgsSize");
221 sizeForThisCall = 0;
222 for (unsigned i=0; i < numOperands; ++i)
223 sizeForThisCall += target.findOptimalStorageSize(callInst->
224 getOperand(i)->getType());
225 }
226
227 if (maxSize < sizeForThisCall)
228 maxSize = sizeForThisCall;
229 }
230
231 return maxSize;
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000232}
233
234
Vikram S. Advebe495262001-11-08 04:47:06 +0000235/*ctor*/
236MachineCodeForMethod::MachineCodeForMethod(const Method* _M,
237 const TargetMachine& target)
238 : Annotation(AID),
239 method(_M), compiledAsLeaf(false), staticStackSize(0),
240 automaticVarsSize(0), regSpillsSize(0),
241 currentOptionalArgsSize(0), maxOptionalArgsSize(0),
242 currentTmpValuesSize(0)
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000243{
Vikram S. Advebe495262001-11-08 04:47:06 +0000244 maxOptionalArgsSize = ComputeMaxOptionalArgsSize(target, method);
245 staticStackSize = maxOptionalArgsSize +
246 target.getFrameInfo().getMinStackFrameSize();
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000247}
248
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000249int
Vikram S. Advebe495262001-11-08 04:47:06 +0000250MachineCodeForMethod::allocateLocalVar(const TargetMachine& target,
251 const Value* val)
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000252{
Vikram S. Advebe495262001-11-08 04:47:06 +0000253 // Check if we've allocated a stack slot for this value already
254 //
255 int offset = getOffset(val);
256 if (offset == INVALID_FRAME_OFFSET)
257 {
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000258 bool growUp;
259 int firstOffset =target.getFrameInfo().getFirstAutomaticVarOffset(*this,
260 growUp);
Vikram S. Adve5567e942001-11-12 05:17:23 +0000261 unsigned int size = target.findOptimalStorageSize(val->getType());
262 unsigned char align = target.DataLayout.getTypeAlignment(val->getType());
263
264 offset = getAutomaticVarsSize();
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000265 if (! growUp)
266 offset += size;
267
Vikram S. Adve5567e942001-11-12 05:17:23 +0000268 if (unsigned int mod = offset % align)
269 {
270 offset += align - mod;
271 size += align - mod;
272 }
273
Vikram S. Adve5567e942001-11-12 05:17:23 +0000274 offset = growUp? firstOffset + offset
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000275 : firstOffset - offset;
Vikram S. Advef1a0a102001-11-11 21:23:33 +0000276
Vikram S. Advebe495262001-11-08 04:47:06 +0000277 offsets[val] = offset;
278
Vikram S. Advebe495262001-11-08 04:47:06 +0000279 incrementAutomaticVarsSize(size);
280 }
281 return offset;
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000282}
283
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000284int
Vikram S. Advebe495262001-11-08 04:47:06 +0000285MachineCodeForMethod::allocateSpilledValue(const TargetMachine& target,
286 const Type* type)
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000287{
Vikram S. Adve5567e942001-11-12 05:17:23 +0000288 unsigned int size = target.findOptimalStorageSize(type);
289 unsigned char align = target.DataLayout.getTypeAlignment(type);
290
Vikram S. Advebe495262001-11-08 04:47:06 +0000291 bool growUp;
292 int firstOffset = target.getFrameInfo().getRegSpillAreaOffset(*this, growUp);
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000293
294 int offset = getRegSpillsSize();
295 if (! growUp)
296 offset += size;
297
298 if (unsigned int mod = offset % align)
299 {
300 offset += align - mod;
301 size += align - mod;
302 }
303
Vikram S. Adve5567e942001-11-12 05:17:23 +0000304 offset = growUp? firstOffset + offset
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000305 : firstOffset - offset;
Vikram S. Advef1a0a102001-11-11 21:23:33 +0000306
Vikram S. Advebe495262001-11-08 04:47:06 +0000307 incrementRegSpillsSize(size);
308
309 return offset;
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000310}
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000311
Vikram S. Advebe495262001-11-08 04:47:06 +0000312int
313MachineCodeForMethod::allocateOptionalArg(const TargetMachine& target,
314 const Type* type)
315{
316 const MachineFrameInfo& frameInfo = target.getFrameInfo();
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000317
Vikram S. Advebe495262001-11-08 04:47:06 +0000318 int size = MAXINT;
319 if (frameInfo.argsOnStackHaveFixedSize())
320 size = frameInfo.getSizeOfEachArgOnStack();
321 else
322 {
Vikram S. Advebe495262001-11-08 04:47:06 +0000323 size = target.findOptimalStorageSize(type);
Vikram S. Advef1a0a102001-11-11 21:23:33 +0000324 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 +0000325 }
Vikram S. Adve5567e942001-11-12 05:17:23 +0000326 unsigned char align = target.DataLayout.getTypeAlignment(type);
Vikram S. Advebe495262001-11-08 04:47:06 +0000327
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000328 bool growUp;
329 int firstOffset = frameInfo.getFirstOptionalOutgoingArgOffset(*this, growUp);
330
Vikram S. Adve5567e942001-11-12 05:17:23 +0000331 int offset = getCurrentOptionalArgsSize();
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000332 if (! growUp)
333 offset += size;
334
Vikram S. Adve5567e942001-11-12 05:17:23 +0000335 if (unsigned int mod = offset % align)
336 {
337 offset += align - mod;
338 size += align - mod;
339 }
340
Vikram S. Adve5567e942001-11-12 05:17:23 +0000341 offset = growUp? firstOffset + offset
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000342 : firstOffset - offset;
Vikram S. Adve5567e942001-11-12 05:17:23 +0000343
Vikram S. Advebe495262001-11-08 04:47:06 +0000344 incrementCurrentOptionalArgsSize(size);
345
346 return offset;
347}
348
349void
350MachineCodeForMethod::resetOptionalArgs(const TargetMachine& target)
351{
352 currentOptionalArgsSize = 0;
353}
354
355int
356MachineCodeForMethod::pushTempValue(const TargetMachine& target,
357 unsigned int size)
358{
Vikram S. Adve5567e942001-11-12 05:17:23 +0000359 // Compute a power-of-2 alignment according to the possible sizes,
360 // but not greater than the alignment of the largest type we support
361 // (currently a double word -- see class TargetData).
362 unsigned char align = 1;
363 for (; align < size && align < target.DataLayout.getDoubleAlignment();
364 align = 2*align)
365 ;
366
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000367 bool growUp;
368 int firstTmpOffset = target.getFrameInfo().getTmpAreaOffset(*this, growUp);
369
Vikram S. Adve5567e942001-11-12 05:17:23 +0000370 int offset = currentTmpValuesSize;
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000371 if (! growUp)
372 offset += size;
373
Vikram S. Adve5567e942001-11-12 05:17:23 +0000374 if (unsigned int mod = offset % align)
375 {
376 offset += align - mod;
377 size += align - mod;
378 }
379
Vikram S. Adve5567e942001-11-12 05:17:23 +0000380 offset = growUp? firstTmpOffset + offset
Vikram S. Advee492c9d2001-11-12 23:26:23 +0000381 : firstTmpOffset - offset;
Vikram S. Adve5567e942001-11-12 05:17:23 +0000382
Vikram S. Advebe495262001-11-08 04:47:06 +0000383 currentTmpValuesSize += size;
384 return offset;
385}
386
387void
388MachineCodeForMethod::popAllTempValues(const TargetMachine& target)
389{
390 currentTmpValuesSize = 0;
391}
392
Vikram S. Advebe495262001-11-08 04:47:06 +0000393int
394MachineCodeForMethod::getOffset(const Value* val) const
395{
396 hash_map<const Value*, int>::const_iterator pair = offsets.find(val);
397 return (pair == offsets.end())? INVALID_FRAME_OFFSET : (*pair).second;
398}
399
Vikram S. Adve1d6158f2001-10-22 13:51:33 +0000400void
401MachineCodeForMethod::dump() const
Ruchira Sasankaed8f6742001-09-15 19:07:45 +0000402{
403 cout << "\n" << method->getReturnType()
404 << " \"" << method->getName() << "\"" << endl;
405
406 for (Method::const_iterator BI = method->begin(); BI != method->end(); ++BI)
407 {
408 BasicBlock* bb = *BI;
409 cout << "\n"
410 << (bb->hasName()? bb->getName() : "Label")
411 << " (" << bb << ")" << ":"
412 << endl;
413
414 MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec();
415 for (unsigned i=0; i < mvec.size(); i++)
Vikram S. Adve6d353262001-10-17 23:57:50 +0000416 cout << "\t" << *mvec[i];
Ruchira Sasankaed8f6742001-09-15 19:07:45 +0000417 }
418 cout << endl << "End method \"" << method->getName() << "\""
419 << endl << endl;
420}