blob: 372b7e0dca92d1c4ad726dae24d3929418eb19f1 [file] [log] [blame]
Vikram S. Advea21cf202001-07-21 12:42:19 +00001// $Id$
2//***************************************************************************
3// File:
4// Sparc.cpp
5//
6// Purpose:
7//
8// History:
9// 7/15/01 - Vikram Adve - Created
10//**************************************************************************/
11
Ruchira Sasankaf2a64772001-08-31 20:59:58 +000012#include "llvm/Method.h"
13#include "llvm/Instruction.h"
14
15#include "llvm/CodeGen/LiveRange.h"
16#include "llvm/CodeGen/LiveRangeInfo.h"
Chris Lattner7e583cf2001-07-21 20:58:30 +000017#include "llvm/CodeGen/Sparc.h"
Ruchira Sasankaf2a64772001-08-31 20:59:58 +000018#include "llvm/CodeGen/SparcRegInfo.h"
Vikram S. Advea21cf202001-07-21 12:42:19 +000019
Vikram S. Advea21cf202001-07-21 12:42:19 +000020//************************ Class Implementations **************************/
21
22
Ruchira Sasankaf2a64772001-08-31 20:59:58 +000023
24
25
26//---------------------------------------------------------------------------
27// UltraSparcRegInfo
28// Purpose:
29// This method will color incoming args to a method. If there are more
30// args than that can fit in regs, code will be inserted to pop them from
31// stack
32//---------------------------------------------------------------------------
33
34
35void UltraSparcRegInfo::colorArgs(const Method *const Meth,
36 LiveRangeInfo& LRI) const
37{
38
39 // get the argument list
40 const Method::ArgumentListType& ArgList = Meth->getArgumentList();
41 // get an iterator to arg list
42 Method::ArgumentListType::const_iterator ArgIt = ArgList.begin();
43 unsigned intArgNo=0;
44
45 // to keep track of which float regs are allocated for argument passing
46 bool FloatArgUsedArr[NumOfFloatArgRegs];
47
48 // init float arg used array
49 for(unsigned i=0; i < NumOfFloatArgRegs; ++i)
50 FloatArgUsedArr[i] = false;
51
52 // for each argument
53 for( ; ArgIt != ArgList.end() ; ++ArgIt) {
54
55 // get the LR of arg
56 LiveRange *const LR = LRI.getLiveRangeForValue((const Value *) *ArgIt);
57 unsigned RegClassID = (LR->getRegClass())->getID();
58
59 // if the arg is in int class - allocate a reg for an int arg
60 if( RegClassID == IntRegClassID ) {
61
62 if( intArgNo < NumOfIntArgRegs) {
63 LR->setColor( SparcIntRegOrder::i0 + intArgNo );
64
65 if( DEBUG_RA) printReg( LR );
66 }
67
68 else {
69 // TODO: Insert push code here
70 assert( 0 && "Insert push code here!");
71 }
72 ++intArgNo;
73 }
74
75 // if the arg is float/double
76 else if ( RegClassID == FloatRegClassID) {
77
78 if( LR->getTypeID() == Type::DoubleTyID ) {
79
80 // find the first reg # we can pass a double arg
81 for(unsigned i=0; i < NumOfFloatArgRegs; i+= 2) {
82 if ( !FloatArgUsedArr[i] && !FloatArgUsedArr[i+1] ) {
83 LR->setColor( SparcFloatRegOrder::f0 + i );
84 FloatArgUsedArr[i] = true;
85 FloatArgUsedArr[i+1] = true;
86 if( DEBUG_RA) printReg( LR );
87 break;
88 }
89 }
90 if( ! LR->hasColor() ) { // if LR was not colored above
91
92 assert(0 && "insert push code here for a double");
93
94 }
95
96 }
97 else if( LR->getTypeID() == Type::FloatTyID ) {
98
99 // find the first reg # we can pass a float arg
100 for(unsigned i=0; i < NumOfFloatArgRegs; ++i) {
101 if ( !FloatArgUsedArr[i] ) {
102 LR->setColor( SparcFloatRegOrder::f0 + i );
103 FloatArgUsedArr[i] = true;
104 if( DEBUG_RA) printReg( LR );
105 break;
106 }
107 }
108 if( ! LR->hasColor() ) { // if LR was not colored above
109 assert(0 && "insert push code here for a float");
110 }
111
112 }
113 else
114 assert(0 && "unknown float type in method arg");
115
116 } // float register class
117
118 else
119 assert(0 && "Unknown RegClassID");
120 }
121
122}
123
124
125
126
127
128
129void UltraSparcRegInfo::printReg(const LiveRange *const LR) {
130
131 unsigned RegClassID = (LR->getRegClass())->getID();
132
133 cout << " *Node " << (LR->getUserIGNode())->getIndex();
134
135 if( ! LR->hasColor() ) {
136 cout << " - could not find a color" << endl;
137 return;
138 }
139
140 // if a color is found
141
142 cout << " colored with color "<< LR->getColor();
143
144 if( RegClassID == IntRegClassID ) {
145
146 cout<< " [" << SparcIntRegOrder::getRegName(LR->getColor()) ;
147 cout << "]" << endl;
148 }
149 else if ( RegClassID == FloatRegClassID) {
150 cout << "[" << SparcFloatRegOrder::getRegName(LR->getColor());
151 if( LR->getTypeID() == Type::DoubleTyID )
152 cout << "+" << SparcFloatRegOrder::getRegName(LR->getColor()+1);
153 cout << "]" << endl;
154 }
155
156
157}
158
159
160
161
162
163void UltraSparcRegInfo::colorCallArgs(vector<const Instruction *> &
164 CallInstrList, LiveRangeInfo& LRI ) const
165{
166
167 vector<const Instruction *>::const_iterator InstIt = CallInstrList.begin();
168
169 for( ; InstIt != CallInstrList.end(); ++InstIt) {
170
171 // Inst = LLVM call instruction
172 const Instruction *const CallI = *InstIt;
173
174 MachineCodeForVMInstr & MInstVec = CallI->getMachineInstrVec();
175 MachineCodeForVMInstr::const_iterator MIIt = MInstVec.begin();
176
177 // find the CALL/JMMPL machine instruction
178 for( ; MIIt != MInstVec.end() &&
179 ! getUltraSparcInfo().getInstrInfo().isCall((*MIIt)->getOpCode());
180 ++MIIt );
181
182 assert( (MIIt != MInstVec.end()) && "CALL/JMPL not found");
183
184 // CallMI = CALL/JMPL machine isntruction
185 const MachineInstr *const CallMI = *MIIt;
186
187 Instruction::op_const_iterator OpIt = CallI->op_begin();
188
189 unsigned intArgNo=0;
190 //unsigned NumOfCallInterfs = LR->getNumOfCallInterferences();
191
192 // to keep track of which float regs are allocated for argument passing
193 bool FloatArgUsedArr[NumOfFloatArgRegs];
194
195 // init float arg used array
196 for(unsigned i=0; i < NumOfFloatArgRegs; ++i)
197 FloatArgUsedArr[i] = false;
198
199 // go thru all the operands of LLVM instruction
200 for( ; OpIt != CallI->op_end(); ++OpIt ) {
201
202 // get the LR of call operand (parameter)
203 LiveRange *const LR = LRI.getLiveRangeForValue((const Value *) *OpIt);
204
205 if ( !LR ) {
206 cout << " Warning: In call instr, no LR for arg: " ;
207 printValue(*OpIt);
208 cout << endl;
209 continue;
210 }
211
212 unsigned RegClassID = (LR->getRegClass())->getID();
213
214 // if the arg is in int class - allocate a reg for an int arg
215 if( RegClassID == IntRegClassID ) {
216
217 if( intArgNo < NumOfIntArgRegs) {
218 setCallArgColor( LR, SparcIntRegOrder::o0 + intArgNo );
219 }
220
221 else {
222 // TODO: Insert push code here
223 assert( 0 && "Insert push code here!");
224 }
225 ++intArgNo;
226 }
227
228 // if the arg is float/double
229 else if ( RegClassID == FloatRegClassID) {
230
231 if( LR->getTypeID() == Type::DoubleTyID ) {
232
233 // find the first reg # we can pass a double arg
234 for(unsigned i=0; i < NumOfFloatArgRegs; i+= 2) {
235 if ( !FloatArgUsedArr[i] && !FloatArgUsedArr[i+1] ) {
236 setCallArgColor(LR, SparcFloatRegOrder::f0 + i );
237 FloatArgUsedArr[i] = true;
238 FloatArgUsedArr[i+1] = true;
239 //if( DEBUG_RA) printReg( LR );
240 break;
241 }
242 }
243 if( ! LR->hasColor() ) { // if LR was not colored above
244
245 assert(0 && "insert push code here for a double");
246
247 }
248
249 }
250 else if( LR->getTypeID() == Type::FloatTyID ) {
251
252 // find the first reg # we can pass a float arg
253 for(unsigned i=0; i < NumOfFloatArgRegs; ++i) {
254 if ( !FloatArgUsedArr[i] ) {
255 setCallArgColor(LR, SparcFloatRegOrder::f0 + i );
256 FloatArgUsedArr[i] = true;
257 // LR->setColor( SparcFloatRegOrder::f0 + i );
258 // if( DEBUG_RA) printReg( LR );
259 break;
260 }
261 }
262 if( ! LR->hasColor() ) { // if LR was not colored above
263 assert(0 && "insert push code here for a float");
264 }
265
266 }
267 else
268 assert(0 && "unknown float type in method arg");
269
270 } // float register class
271
272 else
273 assert(0 && "Unknown RegClassID");
274
275
276 } // for each operand in a call instruction
277
278
279
280
281 } // for all call instrctions in CallInstrList
282
283}
284
285
286void UltraSparcRegInfo::setCallArgColor(LiveRange *const LR,
287 const unsigned RegNo) const {
288
289 // if no call interference and LR is NOT previously colored (e.g., as an
290 // incoming arg)
291 if( ! LR->getNumOfCallInterferences() && ! LR->hasColor() ) {
292 // we can directly allocate a %o register
293 LR->setColor( RegNo);
294 if( DEBUG_RA) printReg( LR );
295 }
296 else { // there are call interferences
297
298 /*
299 // insert a copy machine instr to copy from LR to %o(reg)
300 PreMInstrMap[ CallMI ] =
301 getNewCopyMInstr( LR->, SparcIntRegOrder::o0 + intArgNo );
302 */
303 cout << " $$$ TODO: Insert a copy for call argument!: " << endl;
304
305 // We don't color LR here. It's colored as any other normal LR
306 }
307
308}
309
310
311
312
Vikram S. Adve24084be2001-08-28 23:10:41 +0000313//---------------------------------------------------------------------------
314// class UltraSparcInstrInfo
315//
316// Purpose:
317// Information about individual instructions.
318// Most information is stored in the SparcMachineInstrDesc array above.
319// Other information is computed on demand, and most such functions
320// default to member functions in base class MachineInstrInfo.
321//---------------------------------------------------------------------------
322
323/*ctor*/
324UltraSparcInstrInfo::UltraSparcInstrInfo()
325 : MachineInstrInfo(SparcMachineInstrDesc,
326 /*descSize = */ NUM_TOTAL_OPCODES,
327 /*numRealOpCodes = */ NUM_REAL_OPCODES)
328{
329}
330
331
332//---------------------------------------------------------------------------
333// class UltraSparcSchedInfo
334//
335// Purpose:
336// Scheduling information for the UltraSPARC.
337// Primarily just initializes machine-dependent parameters in
338// class MachineSchedInfo.
339//---------------------------------------------------------------------------
340
341/*ctor*/
342UltraSparcSchedInfo::UltraSparcSchedInfo(const MachineInstrInfo* mii)
343 : MachineSchedInfo((unsigned int) SPARC_NUM_SCHED_CLASSES,
344 mii,
345 SparcRUsageDesc,
346 SparcInstrUsageDeltas,
347 SparcInstrIssueDeltas,
348 sizeof(SparcInstrUsageDeltas)/sizeof(InstrRUsageDelta),
349 sizeof(SparcInstrIssueDeltas)/sizeof(InstrIssueDelta))
350{
351 maxNumIssueTotal = 4;
352 longestIssueConflict = 0; // computed from issuesGaps[]
353
354 branchMispredictPenalty = 4; // 4 for SPARC IIi
355 branchTargetUnknownPenalty = 2; // 2 for SPARC IIi
356 l1DCacheMissPenalty = 8; // 7 or 9 for SPARC IIi
357 l1ICacheMissPenalty = 8; // ? for SPARC IIi
358
359 inOrderLoads = true; // true for SPARC IIi
360 inOrderIssue = true; // true for SPARC IIi
361 inOrderExec = false; // false for most architectures
362 inOrderRetire= true; // true for most architectures
363
364 // must be called after above parameters are initialized.
365 this->initializeResources();
366}
367
368void
369UltraSparcSchedInfo::initializeResources()
370{
371 // Compute MachineSchedInfo::instrRUsages and MachineSchedInfo::issueGaps
372 MachineSchedInfo::initializeResources();
373
374 // Machine-dependent fixups go here. None for now.
375}
376
Vikram S. Adve3c3b7132001-07-28 04:19:10 +0000377
Ruchira Sasankaf2a64772001-08-31 20:59:58 +0000378
379
380
381
382
Vikram S. Advea21cf202001-07-21 12:42:19 +0000383//---------------------------------------------------------------------------
384// class UltraSparcMachine
385//
386// Purpose:
Vikram S. Adve3c3b7132001-07-28 04:19:10 +0000387// Primary interface to machine description for the UltraSPARC.
388// Primarily just initializes machine-dependent parameters in
389// class TargetMachine, and creates machine-dependent subclasses
390// for classes such as MachineInstrInfo.
Vikram S. Advea21cf202001-07-21 12:42:19 +0000391//
392//---------------------------------------------------------------------------
393
394UltraSparc::UltraSparc()
Ruchira Sasankaf2a64772001-08-31 20:59:58 +0000395
Vikram S. Adve24084be2001-08-28 23:10:41 +0000396 : TargetMachine("UltraSparc-Native")
397{
398 machineInstrInfo = new UltraSparcInstrInfo;
399 machineSchedInfo = new UltraSparcSchedInfo(machineInstrInfo);
Ruchira Sasankaf2a64772001-08-31 20:59:58 +0000400 machineRegInfo = new UltraSparcRegInfo(this);
Vikram S. Adve24084be2001-08-28 23:10:41 +0000401
Vikram S. Advea21cf202001-07-21 12:42:19 +0000402 optSizeForSubWordData = 4;
Vikram S. Advea21cf202001-07-21 12:42:19 +0000403 minMemOpWordSize = 8;
404 maxAtomicMemOpWordSize = 8;
Vikram S. Advea21cf202001-07-21 12:42:19 +0000405 zeroRegNum = 0; // %g0 always gives 0 on Sparc
406}
407
Vikram S. Adve24084be2001-08-28 23:10:41 +0000408UltraSparc::~UltraSparc()
409{
410 delete (UltraSparcInstrInfo*) machineInstrInfo;
Ruchira Sasankaf2a64772001-08-31 20:59:58 +0000411 delete (UltraSparcRegInfo*) machineRegInfo;
Vikram S. Adve24084be2001-08-28 23:10:41 +0000412 delete (UltraSparcSchedInfo*) machineSchedInfo;
Vikram S. Adve3c3b7132001-07-28 04:19:10 +0000413}
414
Vikram S. Advea21cf202001-07-21 12:42:19 +0000415//**************************************************************************/