blob: c24b9bd3841975ea08f08402b289f230236568ed [file] [log] [blame]
Vikram S. Adve6fcb2892001-11-08 04:55:13 +00001// $Id$ -*- C++ -*--
2//***************************************************************************
3// File:
4// SparcInternals.h
5//
6// Purpose:
7// This file defines stuff that is to be private to the Sparc
8// backend, but is shared among different portions of the backend.
9//**************************************************************************/
10
Chris Lattner5fae0de2001-09-14 03:56:45 +000011
12#ifndef SPARC_INTERNALS_H
13#define SPARC_INTERNALS_H
14
Ruchira Sasankadfc6c882001-09-18 22:52:44 +000015
16#include "SparcRegClassInfo.h"
17#include "llvm/Target/TargetMachine.h"
18#include "llvm/Target/MachineInstrInfo.h"
Vikram S. Adve514180e2001-09-18 13:04:24 +000019#include "llvm/Target/MachineSchedInfo.h"
Vikram S. Adve367f34f2001-11-09 02:15:52 +000020#include "llvm/Target/MachineFrameInfo.h"
21#include "llvm/Target/MachineCacheInfo.h"
Ruchira Sasanka560b0ad2001-09-30 23:19:57 +000022#include "llvm/CodeGen/RegClass.h"
Chris Lattner5fae0de2001-09-14 03:56:45 +000023#include "llvm/Type.h"
Vikram S. Adve514180e2001-09-18 13:04:24 +000024
Chris Lattner8d44b992001-09-14 16:56:32 +000025#include <sys/types.h>
Chris Lattner5fae0de2001-09-14 03:56:45 +000026
Chris Lattnerf8464e42001-09-14 04:32:55 +000027class UltraSparc;
28
Chris Lattner5fae0de2001-09-14 03:56:45 +000029// OpCodeMask definitions for the Sparc V9
30//
31const OpCodeMask Immed = 0x00002000; // immed or reg operand?
32const OpCodeMask Annul = 0x20000000; // annul delay instr?
33const OpCodeMask PredictTaken = 0x00080000; // predict branch taken?
34
35
36enum SparcInstrSchedClass {
37 SPARC_NONE, /* Instructions with no scheduling restrictions */
38 SPARC_IEUN, /* Integer class that can use IEU0 or IEU1 */
39 SPARC_IEU0, /* Integer class IEU0 */
40 SPARC_IEU1, /* Integer class IEU1 */
41 SPARC_FPM, /* FP Multiply or Divide instructions */
42 SPARC_FPA, /* All other FP instructions */
43 SPARC_CTI, /* Control-transfer instructions */
44 SPARC_LD, /* Load instructions */
45 SPARC_ST, /* Store instructions */
46 SPARC_SINGLE, /* Instructions that must issue by themselves */
47
48 SPARC_INV, /* This should stay at the end for the next value */
49 SPARC_NUM_SCHED_CLASSES = SPARC_INV
50};
51
Chris Lattner5fae0de2001-09-14 03:56:45 +000052
53//---------------------------------------------------------------------------
54// enum SparcMachineOpCode.
55// const MachineInstrDescriptor SparcMachineInstrDesc[]
56//
57// Purpose:
58// Description of UltraSparc machine instructions.
59//
60//---------------------------------------------------------------------------
61
Chris Lattner5fae0de2001-09-14 03:56:45 +000062enum SparcMachineOpCode {
Chris Lattnere86a0232001-09-19 15:56:23 +000063#define I(ENUM, OPCODESTRING, NUMOPERANDS, RESULTPOS, MAXIMM, IMMSE, \
64 NUMDELAYSLOTS, LATENCY, SCHEDCLASS, INSTFLAGS) \
65 ENUM,
66#include "SparcInstr.def"
Chris Lattner5fae0de2001-09-14 03:56:45 +000067
Chris Lattner5fae0de2001-09-14 03:56:45 +000068 // End-of-array marker
69 INVALID_OPCODE,
Vikram S. Adve7c1a8d62001-10-22 13:31:53 +000070 NUM_REAL_OPCODES = PHI, // number of valid opcodes
Chris Lattner5fae0de2001-09-14 03:56:45 +000071 NUM_TOTAL_OPCODES = INVALID_OPCODE
72};
73
Chris Lattner5fae0de2001-09-14 03:56:45 +000074
Chris Lattnere86a0232001-09-19 15:56:23 +000075// Array of machine instruction descriptions...
76extern const MachineInstrDescriptor SparcMachineInstrDesc[];
Chris Lattner5fae0de2001-09-14 03:56:45 +000077
78
79//---------------------------------------------------------------------------
80// class UltraSparcInstrInfo
81//
82// Purpose:
83// Information about individual instructions.
84// Most information is stored in the SparcMachineInstrDesc array above.
85// Other information is computed on demand, and most such functions
86// default to member functions in base class MachineInstrInfo.
87//---------------------------------------------------------------------------
88
89class UltraSparcInstrInfo : public MachineInstrInfo {
90public:
Vikram S. Adve6fcb2892001-11-08 04:55:13 +000091 /*ctor*/ UltraSparcInstrInfo(const TargetMachine& tgt);
Vikram S. Adve7e833072001-11-14 18:48:36 +000092
93 //
94 // All immediate constants are in position 0 except the
95 // store instructions.
96 //
97 virtual int getImmmedConstantPos(MachineOpCode opCode) const {
98 bool ignore;
99 if (this->maxImmedConstant(opCode, ignore) != 0)
100 {
101 assert(! this->isStore((MachineOpCode) STB - 1)); // first store is STB
102 assert(! this->isStore((MachineOpCode) STD + 1)); // last store is STD
103 return (opCode >= STB || opCode <= STD)? 2 : 1;
104 }
105 else
106 return -1;
107 }
Chris Lattner5fae0de2001-09-14 03:56:45 +0000108
Vikram S. Adve505130c2001-10-18 00:02:06 +0000109 virtual bool hasResultInterlock (MachineOpCode opCode) const
Chris Lattner5fae0de2001-09-14 03:56:45 +0000110 {
111 // All UltraSPARC instructions have interlocks (note that delay slots
112 // are not considered here).
113 // However, instructions that use the result of an FCMP produce a
114 // 9-cycle stall if they are issued less than 3 cycles after the FCMP.
115 // Force the compiler to insert a software interlock (i.e., gap of
116 // 2 other groups, including NOPs if necessary).
117 return (opCode == FCMPS || opCode == FCMPD || opCode == FCMPQ);
118 }
119
Vikram S. Adve505130c2001-10-18 00:02:06 +0000120 //-------------------------------------------------------------------------
121 // Code generation support for creating individual machine instructions
122 //-------------------------------------------------------------------------
Ruchira Sasanka560b0ad2001-09-30 23:19:57 +0000123
Vikram S. Adve505130c2001-10-18 00:02:06 +0000124 // Create an instruction sequence to put the constant `val' into
125 // the virtual register `dest'. The generated instructions are
126 // returned in `minstrVec'. Any temporary registers (TmpInstruction)
127 // created are returned in `tempVec'.
128 //
129 virtual void CreateCodeToLoadConst(Value* val,
130 Instruction* dest,
131 vector<MachineInstr*>& minstrVec,
132 vector<TmpInstruction*>& tempVec) const;
Vikram S. Adve6fcb2892001-11-08 04:55:13 +0000133
134
Vikram S. Adve367f34f2001-11-09 02:15:52 +0000135 // Create an instruction sequence to copy an integer value `val'
136 // to a floating point value `dest' by copying to memory and back.
137 // val must be an integral type. dest must be a Float or Double.
Vikram S. Adve6fcb2892001-11-08 04:55:13 +0000138 // The generated instructions are returned in `minstrVec'.
139 // Any temp. registers (TmpInstruction) created are returned in `tempVec'.
140 //
141 virtual void CreateCodeToCopyIntToFloat(Method* method,
142 Value* val,
143 Instruction* dest,
144 vector<MachineInstr*>& minstrVec,
145 vector<TmpInstruction*>& tempVec,
146 TargetMachine& target) const;
Vikram S. Adve367f34f2001-11-09 02:15:52 +0000147
148 // Similarly, create an instruction sequence to copy an FP value
149 // `val' to an integer value `dest' by copying to memory and back.
150 // See the previous function for information about return values.
151 //
152 virtual void CreateCodeToCopyFloatToInt(Method* method,
153 Value* val,
154 Instruction* dest,
155 vector<MachineInstr*>& minstrVec,
156 vector<TmpInstruction*>& tempVec,
157 TargetMachine& target) const;
Ruchira Sasankafcdc2ff2001-11-12 14:45:33 +0000158
159 // create copy instruction(s)
160 virtual void
161 CreateCopyInstructionsByType(const TargetMachine& target,
162 Value* src,
163 Instruction* dest,
164 vector<MachineInstr*>& minstrVec) const;
165
166
Chris Lattner5fae0de2001-09-14 03:56:45 +0000167};
168
Ruchira Sasanka7d144a82001-09-15 00:30:44 +0000169
Ruchira Sasanka9c38dbc2001-10-28 18:15:12 +0000170//----------------------------------------------------------------------------
171// class UltraSparcRegInfo
172//
173//----------------------------------------------------------------------------
174
175
Chris Lattner5fae0de2001-09-14 03:56:45 +0000176class LiveRange;
Ruchira Sasanka7d144a82001-09-15 00:30:44 +0000177class UltraSparc;
Ruchira Sasanka9c38dbc2001-10-28 18:15:12 +0000178class PhyRegAlloc;
Chris Lattner5fae0de2001-09-14 03:56:45 +0000179
Ruchira Sasankadfc6c882001-09-18 22:52:44 +0000180
Chris Lattner5fae0de2001-09-14 03:56:45 +0000181class UltraSparcRegInfo : public MachineRegInfo
182{
183
184 private:
Ruchira Sasanka7d144a82001-09-15 00:30:44 +0000185
Ruchira Sasanka560b0ad2001-09-30 23:19:57 +0000186 // The actual register classes in the Sparc
187
Ruchira Sasanka7d144a82001-09-15 00:30:44 +0000188 enum RegClassIDs {
189 IntRegClassID,
190 FloatRegClassID,
191 IntCCRegClassID,
192 FloatCCRegClassID
193 };
194
Ruchira Sasanka560b0ad2001-09-30 23:19:57 +0000195
196 // Type of registers available in Sparc. There can be several reg types
197 // in the same class. For instace, the float reg class has Single/Double
198 // types
199 enum RegTypes {
200 IntRegType,
201 FPSingleRegType,
202 FPDoubleRegType,
203 IntCCRegType,
204 FloatCCRegType
205 };
206
Ruchira Sasanka9c38dbc2001-10-28 18:15:12 +0000207 // the size of a value (int, float, etc..) stored in the stack frame
208
209
Ruchira Sasanka560b0ad2001-09-30 23:19:57 +0000210
Ruchira Sasanka7d144a82001-09-15 00:30:44 +0000211 // WARNING: If the above enum order must be changed, also modify
212 // getRegisterClassOfValue method below since it assumes this particular
213 // order for efficiency.
214
Chris Lattner5fae0de2001-09-14 03:56:45 +0000215
216 // reverse pointer to get info about the ultra sparc machine
217 const UltraSparc *const UltraSparcInfo;
218
Ruchira Sasanka560b0ad2001-09-30 23:19:57 +0000219 // Both int and float rguments can be passed in 6 int regs -
220 // %o0 to %o5 (cannot be changed)
Chris Lattner5fae0de2001-09-14 03:56:45 +0000221 unsigned const NumOfIntArgRegs;
Chris Lattner5fae0de2001-09-14 03:56:45 +0000222 unsigned const NumOfFloatArgRegs;
Ruchira Sasanka5b8971f2001-10-16 01:23:19 +0000223 int const InvalidRegNum;
Ruchira Sasanka9c38dbc2001-10-28 18:15:12 +0000224 int SizeOfOperandOnStack;
225
226
Chris Lattner5fae0de2001-09-14 03:56:45 +0000227
Ruchira Sasankadfc6c882001-09-18 22:52:44 +0000228 //void setCallArgColor(LiveRange *const LR, const unsigned RegNo) const;
229
230 void setCallOrRetArgCol(LiveRange *const LR, const unsigned RegNo,
231 const MachineInstr *MI,AddedInstrMapType &AIMap)const;
232
233 MachineInstr * getCopy2RegMI(const Value *SrcVal, const unsigned Reg,
234 unsigned RegClassID) const ;
235
Ruchira Sasanka086bf0f2001-10-15 16:25:28 +0000236
237 void suggestReg4RetAddr(const MachineInstr * RetMI,
238 LiveRangeInfo& LRI) const;
239
Ruchira Sasanka24729a32001-10-21 16:43:41 +0000240 void suggestReg4CallAddr(const MachineInstr * CallMI, LiveRangeInfo& LRI,
241 vector<RegClass *> RCList) const;
Ruchira Sasanka086bf0f2001-10-15 16:25:28 +0000242
243
Ruchira Sasanka560b0ad2001-09-30 23:19:57 +0000244 Value *getValue4ReturnAddr( const MachineInstr * MInst ) const ;
245
246 int getRegType(const LiveRange *const LR) const {
247
248 unsigned Typ;
249
250 switch( (LR->getRegClass())->getID() ) {
251
252 case IntRegClassID: return IntRegType;
253
254 case FloatRegClassID:
255 Typ = LR->getTypeID();
256 if( Typ == Type::FloatTyID )
257 return FPSingleRegType;
258 else if( Typ == Type::DoubleTyID )
259 return FPDoubleRegType;
260 else assert(0 && "Unknown type in FloatRegClass");
261
262 case IntCCRegClassID: return IntCCRegType;
263
264 case FloatCCRegClassID: return FloatCCRegType ;
265
266 default: assert( 0 && "Unknown reg class ID");
Chris Lattner5e030832001-11-07 13:49:12 +0000267 return 0;
Ruchira Sasanka560b0ad2001-09-30 23:19:57 +0000268 }
269
270 }
271
272 int getRegType(const Value *const Val) const {
273
274 unsigned Typ;
275
276 switch( getRegClassIDOfValue(Val) ) {
277
278 case IntRegClassID: return IntRegType;
279
280 case FloatRegClassID:
281 Typ = (Val->getType())->getPrimitiveID();
282 if( Typ == Type::FloatTyID )
283 return FPSingleRegType;
284 else if( Typ == Type::DoubleTyID )
285 return FPDoubleRegType;
286 else assert(0 && "Unknown type in FloatRegClass");
287
288 case IntCCRegClassID: return IntCCRegType;
289
290 case FloatCCRegClassID: return FloatCCRegType ;
291
292 default: assert( 0 && "Unknown reg class ID");
Chris Lattner5e030832001-11-07 13:49:12 +0000293 return 0;
Ruchira Sasanka560b0ad2001-09-30 23:19:57 +0000294 }
295
296 }
297
298
Ruchira Sasanka0c085982001-11-10 21:20:43 +0000299 int getRegType(int reg) const {
300 if( reg < 32 )
301 return IntRegType;
302 else if ( reg < (32 + 32) )
303 return FPSingleRegType;
304 else if ( reg < (64 + 32) )
305 return FPDoubleRegType;
306 else if( reg < (64+32+4) )
307 return FloatCCRegType;
308 else if( reg < (64+32+4+2) )
309 return IntCCRegType;
310 else
311 assert(0 && "Invalid register number in getRegType");
312 }
313
314
Ruchira Sasanka560b0ad2001-09-30 23:19:57 +0000315
Ruchira Sasanka5b8971f2001-10-16 01:23:19 +0000316 // ***TODO: See this method is necessary
Ruchira Sasanka560b0ad2001-09-30 23:19:57 +0000317
318 MachineInstr * cpValue2RegMI(Value * Val, const unsigned DestReg,
319 const int RegType) const;
320
Ruchira Sasanka24729a32001-10-21 16:43:41 +0000321 const Value *getCallInstRetAddr(const MachineInstr *CallMI) const;
322 const unsigned getCallInstNumArgs(const MachineInstr *CallMI) const;
323
Ruchira Sasanka560b0ad2001-09-30 23:19:57 +0000324
Ruchira Sasanka9d8950d2001-11-03 19:59:59 +0000325 MachineInstr * cpCCR2IntMI(const unsigned IntReg) const;
326 MachineInstr * cpInt2CCRMI(const unsigned IntReg) const;
327
Ruchira Sasanka0c085982001-11-10 21:20:43 +0000328
329
330 void moveInst2OrdVec(vector<MachineInstr *> &OrdVec, MachineInstr *UnordInst,
331 PhyRegAlloc &PRA ) const;
332
Ruchira Sasankad0d294a2001-11-09 23:49:14 +0000333 void OrderAddedInstrns( vector<MachineInstr *> &UnordVec,
Ruchira Sasanka0c085982001-11-10 21:20:43 +0000334 vector<MachineInstr *> &OrdVec,
335 PhyRegAlloc &PRA) const;
336
337
338
339
340
Ruchira Sasankad0d294a2001-11-09 23:49:14 +0000341
342
Chris Lattner5fae0de2001-09-14 03:56:45 +0000343 public:
344
Chris Lattner5fae0de2001-09-14 03:56:45 +0000345
Vikram S. Adve6fcb2892001-11-08 04:55:13 +0000346 UltraSparcRegInfo(const TargetMachine& tgt ) : MachineRegInfo(tgt),
347 UltraSparcInfo(& (const UltraSparc&) tgt),
Ruchira Sasankadfc6c882001-09-18 22:52:44 +0000348 NumOfIntArgRegs(6),
Ruchira Sasanka560b0ad2001-09-30 23:19:57 +0000349 NumOfFloatArgRegs(32),
Ruchira Sasanka9c38dbc2001-10-28 18:15:12 +0000350 InvalidRegNum(1000),
351 SizeOfOperandOnStack(8)
Ruchira Sasanka7d144a82001-09-15 00:30:44 +0000352 {
Chris Lattner5fae0de2001-09-14 03:56:45 +0000353 MachineRegClassArr.push_back( new SparcIntRegClass(IntRegClassID) );
354 MachineRegClassArr.push_back( new SparcFloatRegClass(FloatRegClassID) );
Ruchira Sasanka7d144a82001-09-15 00:30:44 +0000355 MachineRegClassArr.push_back( new SparcIntCCRegClass(IntCCRegClassID) );
356 MachineRegClassArr.push_back( new SparcFloatCCRegClass(FloatCCRegClassID));
Ruchira Sasankadfc6c882001-09-18 22:52:44 +0000357
Ruchira Sasanka560b0ad2001-09-30 23:19:57 +0000358 assert( SparcFloatRegOrder::StartOfNonVolatileRegs == 32 &&
359 "32 Float regs are used for float arg passing");
Ruchira Sasanka9c38dbc2001-10-28 18:15:12 +0000360
Chris Lattner5fae0de2001-09-14 03:56:45 +0000361 }
Ruchira Sasankadfc6c882001-09-18 22:52:44 +0000362
Ruchira Sasanka7d144a82001-09-15 00:30:44 +0000363 // ***** TODO Delete
364 ~UltraSparcRegInfo(void) { } // empty destructor
365
366
Chris Lattner5fae0de2001-09-14 03:56:45 +0000367 inline const UltraSparc & getUltraSparcInfo() const {
368 return *UltraSparcInfo;
369 }
370
Ruchira Sasankadfc6c882001-09-18 22:52:44 +0000371
Ruchira Sasanka7d144a82001-09-15 00:30:44 +0000372
373 inline unsigned getRegClassIDOfValue (const Value *const Val,
374 bool isCCReg = false) const {
375
Chris Lattner5fae0de2001-09-14 03:56:45 +0000376 Type::PrimitiveID ty = (Val->getType())->getPrimitiveID();
Ruchira Sasanka7d144a82001-09-15 00:30:44 +0000377
378 unsigned res;
Chris Lattner5fae0de2001-09-14 03:56:45 +0000379
Ruchira Sasanka560b0ad2001-09-30 23:19:57 +0000380 if( (ty && ty <= Type::LongTyID) || (ty == Type::LabelTyID) ||
381 (ty == Type::MethodTyID) || (ty == Type::PointerTyID) )
Ruchira Sasanka7d144a82001-09-15 00:30:44 +0000382 res = IntRegClassID; // sparc int reg (ty=0: void)
Chris Lattner5fae0de2001-09-14 03:56:45 +0000383 else if( ty <= Type::DoubleTyID)
Ruchira Sasanka7d144a82001-09-15 00:30:44 +0000384 res = FloatRegClassID; // sparc float reg class
Chris Lattner5fae0de2001-09-14 03:56:45 +0000385 else {
Chris Lattnerf3f1e452001-10-15 18:15:27 +0000386 cerr << "TypeID: " << ty << endl;
Chris Lattner5fae0de2001-09-14 03:56:45 +0000387 assert(0 && "Cannot resolve register class for type");
Chris Lattnere147d062001-11-07 14:01:59 +0000388 return 0;
Chris Lattner5fae0de2001-09-14 03:56:45 +0000389 }
Ruchira Sasanka7d144a82001-09-15 00:30:44 +0000390
391 if(isCCReg)
392 return res + 2; // corresponidng condition code regiser
Ruchira Sasanka7d144a82001-09-15 00:30:44 +0000393 else
394 return res;
Chris Lattner5fae0de2001-09-14 03:56:45 +0000395 }
Ruchira Sasanka7d144a82001-09-15 00:30:44 +0000396
Ruchira Sasankadfc6c882001-09-18 22:52:44 +0000397 // returns the register tha contains always zero
Ruchira Sasanka560b0ad2001-09-30 23:19:57 +0000398 // this is the unified register number
Ruchira Sasankadfc6c882001-09-18 22:52:44 +0000399 inline int getZeroRegNum() const { return SparcIntRegOrder::g0; }
400
401 // returns the reg used for pushing the address when a method is called.
402 // This can be used for other purposes between calls
403 unsigned getCallAddressReg() const { return SparcIntRegOrder::o7; }
404
405
406 // and when we return from a method. It should be made sure that this
407 // register contains the return value when a return instruction is reached.
408 unsigned getReturnAddressReg() const { return SparcIntRegOrder::i7; }
409
Ruchira Sasanka560b0ad2001-09-30 23:19:57 +0000410 void suggestRegs4MethodArgs(const Method *const Meth,
411 LiveRangeInfo& LRI) const;
Chris Lattner5fae0de2001-09-14 03:56:45 +0000412
Ruchira Sasanka086bf0f2001-10-15 16:25:28 +0000413 void suggestRegs4CallArgs(const MachineInstr *const CallMI,
Ruchira Sasanka560b0ad2001-09-30 23:19:57 +0000414 LiveRangeInfo& LRI, vector<RegClass *> RCL) const;
Chris Lattner5fae0de2001-09-14 03:56:45 +0000415
Ruchira Sasanka086bf0f2001-10-15 16:25:28 +0000416 void suggestReg4RetValue(const MachineInstr *const RetMI,
417 LiveRangeInfo& LRI ) const;
Chris Lattner5fae0de2001-09-14 03:56:45 +0000418
Ruchira Sasankadfc6c882001-09-18 22:52:44 +0000419
Ruchira Sasanka560b0ad2001-09-30 23:19:57 +0000420 void colorMethodArgs(const Method *const Meth, LiveRangeInfo& LRI,
421 AddedInstrns *const FirstAI) const;
422
Ruchira Sasanka086bf0f2001-10-15 16:25:28 +0000423 void colorCallArgs(const MachineInstr *const CallMI, LiveRangeInfo& LRI,
Ruchira Sasanka9c38dbc2001-10-28 18:15:12 +0000424 AddedInstrns *const CallAI, PhyRegAlloc &PRA) const;
Ruchira Sasanka560b0ad2001-09-30 23:19:57 +0000425
Ruchira Sasanka086bf0f2001-10-15 16:25:28 +0000426 void colorRetValue(const MachineInstr *const RetI, LiveRangeInfo& LRI,
Ruchira Sasanka560b0ad2001-09-30 23:19:57 +0000427 AddedInstrns *const RetAI) const;
428
429
Ruchira Sasanka086bf0f2001-10-15 16:25:28 +0000430 // bool handleSpecialMInstr(const MachineInstr * MInst,
431 // LiveRangeInfo& LRI, vector<RegClass *> RCL) const;
Ruchira Sasanka560b0ad2001-09-30 23:19:57 +0000432
433
434 static void printReg(const LiveRange *const LR) ;
Ruchira Sasankadfc6c882001-09-18 22:52:44 +0000435
Chris Lattner5fae0de2001-09-14 03:56:45 +0000436 // this method provides a unique number for each register
437 inline int getUnifiedRegNum(int RegClassID, int reg) const {
438
439 if( RegClassID == IntRegClassID && reg < 32 )
440 return reg;
441 else if ( RegClassID == FloatRegClassID && reg < 64)
442 return reg + 32; // we have 32 int regs
Ruchira Sasanka7d144a82001-09-15 00:30:44 +0000443 else if( RegClassID == FloatCCRegClassID && reg < 4)
Chris Lattner5fae0de2001-09-14 03:56:45 +0000444 return reg + 32 + 64; // 32 int, 64 float
Ruchira Sasanka7d144a82001-09-15 00:30:44 +0000445 else if( RegClassID == IntCCRegClassID )
446 return 4+ 32 + 64; // only int cc reg
Ruchira Sasanka5b8971f2001-10-16 01:23:19 +0000447 else if (reg==InvalidRegNum)
448 return InvalidRegNum;
Ruchira Sasanka7d144a82001-09-15 00:30:44 +0000449 else
Chris Lattner5fae0de2001-09-14 03:56:45 +0000450 assert(0 && "Invalid register class or reg number");
Chris Lattner5e030832001-11-07 13:49:12 +0000451 return 0;
Chris Lattner5fae0de2001-09-14 03:56:45 +0000452 }
453
454 // given the unified register number, this gives the name
455 inline const string getUnifiedRegName(int reg) const {
Chris Lattner5fae0de2001-09-14 03:56:45 +0000456 if( reg < 32 )
457 return SparcIntRegOrder::getRegName(reg);
458 else if ( reg < (64 + 32) )
459 return SparcFloatRegOrder::getRegName( reg - 32);
460 else if( reg < (64+32+4) )
Ruchira Sasanka7d144a82001-09-15 00:30:44 +0000461 return SparcFloatCCRegOrder::getRegName( reg -32 - 64);
Ruchira Sasanka9d8950d2001-11-03 19:59:59 +0000462 else if( reg < (64+32+4+2) ) // two names: %xcc and %ccr
463 return SparcIntCCRegOrder::getRegName( reg -32 - 64 - 4);
Vikram S. Adve7c1a8d62001-10-22 13:31:53 +0000464 else if (reg== InvalidRegNum) //****** TODO: Remove */
Ruchira Sasanka560b0ad2001-09-30 23:19:57 +0000465 return "<*NoReg*>";
Chris Lattner5fae0de2001-09-14 03:56:45 +0000466 else
467 assert(0 && "Invalid register number");
Chris Lattner5e030832001-11-07 13:49:12 +0000468 return "";
Chris Lattner5fae0de2001-09-14 03:56:45 +0000469 }
470
Vikram S. Adve7c1a8d62001-10-22 13:31:53 +0000471 inline unsigned int getRegNumInCallersWindow(int reg) {
472 if (reg == InvalidRegNum || reg >= 32)
473 return reg;
474 return SparcIntRegOrder::getRegNumInCallersWindow(reg);
475 }
476
477 inline bool mustBeRemappedInCallersWindow(int reg) {
478 return (reg != InvalidRegNum && reg < 32);
479 }
480
Ruchira Sasanka24729a32001-10-21 16:43:41 +0000481 const Value * getCallInstRetVal(const MachineInstr *CallMI) const;
482
Ruchira Sasanka5b8971f2001-10-16 01:23:19 +0000483 MachineInstr * cpReg2RegMI(const unsigned SrcReg, const unsigned DestReg,
484 const int RegType) const;
485
486 MachineInstr * cpReg2MemMI(const unsigned SrcReg, const unsigned DestPtrReg,
487 const int Offset, const int RegType) const;
488
489 MachineInstr * cpMem2RegMI(const unsigned SrcPtrReg, const int Offset,
490 const unsigned DestReg, const int RegType) const;
491
Ruchira Sasankab7a39722001-11-03 17:13:27 +0000492 MachineInstr* cpValue2Value(Value *Src, Value *Dest) const;
493
494
Ruchira Sasanka5b8971f2001-10-16 01:23:19 +0000495 inline bool isRegVolatile(const int RegClassID, const int Reg) const {
496 return (MachineRegClassArr[RegClassID])->isRegVolatile(Reg);
497 }
498
499
500 inline unsigned getFramePointer() const {
501 return SparcIntRegOrder::i6;
502 }
503
504 inline unsigned getStackPointer() const {
505 return SparcIntRegOrder::o6;
506 }
507
508 inline int getInvalidRegNum() const {
509 return InvalidRegNum;
510 }
511
Ruchira Sasanka9c38dbc2001-10-28 18:15:12 +0000512
513 void insertCallerSavingCode(const MachineInstr *MInst,
514 const BasicBlock *BB, PhyRegAlloc &PRA ) const;
515
516
Chris Lattner5fae0de2001-09-14 03:56:45 +0000517};
518
519
520
Chris Lattner5fae0de2001-09-14 03:56:45 +0000521/*---------------------------------------------------------------------------
522Scheduling guidelines for SPARC IIi:
523
524I-Cache alignment rules (pg 326)
525-- Align a branch target instruction so that it's entire group is within
526 the same cache line (may be 1-4 instructions).
527** Don't let a branch that is predicted taken be the last instruction
528 on an I-cache line: delay slot will need an entire line to be fetched
529-- Make a FP instruction or a branch be the 4th instruction in a group.
530 For branches, there are tradeoffs in reordering to make this happen
531 (see pg. 327).
532** Don't put a branch in a group that crosses a 32-byte boundary!
533 An artificial branch is inserted after every 32 bytes, and having
534 another branch will force the group to be broken into 2 groups.
535
536iTLB rules:
537-- Don't let a loop span two memory pages, if possible
538
539Branch prediction performance:
540-- Don't make the branch in a delay slot the target of a branch
541-- Try not to have 2 predicted branches within a group of 4 instructions
542 (because each such group has a single branch target field).
543-- Try to align branches in slots 0, 2, 4 or 6 of a cache line (to avoid
544 the wrong prediction bits being used in some cases).
545
546D-Cache timing constraints:
547-- Signed int loads of less than 64 bits have 3 cycle latency, not 2
548-- All other loads that hit in D-Cache have 2 cycle latency
549-- All loads are returned IN ORDER, so a D-Cache miss will delay a later hit
550-- Mis-aligned loads or stores cause a trap. In particular, replace
551 mis-aligned FP double precision l/s with 2 single-precision l/s.
552-- Simulations of integer codes show increase in avg. group size of
553 33% when code (including esp. non-faulting loads) is moved across
554 one branch, and 50% across 2 branches.
555
556E-Cache timing constraints:
557-- Scheduling for E-cache (D-Cache misses) is effective (due to load buffering)
558
559Store buffer timing constraints:
560-- Stores can be executed in same cycle as instruction producing the value
561-- Stores are buffered and have lower priority for E-cache until
562 highwater mark is reached in the store buffer (5 stores)
563
564Pipeline constraints:
565-- Shifts can only use IEU0.
566-- CC setting instructions can only use IEU1.
567-- Several other instructions must only use IEU1:
568 EDGE(?), ARRAY(?), CALL, JMPL, BPr, PST, and FCMP.
569-- Two instructions cannot store to the same register file in a single cycle
570 (single write port per file).
571
572Issue and grouping constraints:
573-- FP and branch instructions must use slot 4.
574-- Shift instructions cannot be grouped with other IEU0-specific instructions.
575-- CC setting instructions cannot be grouped with other IEU1-specific instrs.
576-- Several instructions must be issued in a single-instruction group:
577 MOVcc or MOVr, MULs/x and DIVs/x, SAVE/RESTORE, many others
578-- A CALL or JMPL breaks a group, ie, is not combined with subsequent instrs.
579--
580--
581
582Branch delay slot scheduling rules:
583-- A CTI couple (two back-to-back CTI instructions in the dynamic stream)
584 has a 9-instruction penalty: the entire pipeline is flushed when the
585 second instruction reaches stage 9 (W-Writeback).
586-- Avoid putting multicycle instructions, and instructions that may cause
587 load misses, in the delay slot of an annulling branch.
588-- Avoid putting WR, SAVE..., RESTORE and RETURN instructions in the
589 delay slot of an annulling branch.
590
591 *--------------------------------------------------------------------------- */
592
593//---------------------------------------------------------------------------
594// List of CPUResources for UltraSPARC IIi.
595//---------------------------------------------------------------------------
596
597const CPUResource AllIssueSlots( "All Instr Slots", 4);
598const CPUResource IntIssueSlots( "Int Instr Slots", 3);
599const CPUResource First3IssueSlots("Instr Slots 0-3", 3);
600const CPUResource LSIssueSlots( "Load-Store Instr Slot", 1);
601const CPUResource CTIIssueSlots( "Ctrl Transfer Instr Slot", 1);
602const CPUResource FPAIssueSlots( "Int Instr Slot 1", 1);
603const CPUResource FPMIssueSlots( "Int Instr Slot 1", 1);
604
605// IEUN instructions can use either Alu and should use IAluN.
606// IEU0 instructions must use Alu 1 and should use both IAluN and IAlu0.
607// IEU1 instructions must use Alu 2 and should use both IAluN and IAlu1.
608const CPUResource IAluN("Int ALU 1or2", 2);
609const CPUResource IAlu0("Int ALU 1", 1);
610const CPUResource IAlu1("Int ALU 2", 1);
611
612const CPUResource LSAluC1("Load/Store Unit Addr Cycle", 1);
613const CPUResource LSAluC2("Load/Store Unit Issue Cycle", 1);
614const CPUResource LdReturn("Load Return Unit", 1);
615
616const CPUResource FPMAluC1("FP Mul/Div Alu Cycle 1", 1);
617const CPUResource FPMAluC2("FP Mul/Div Alu Cycle 2", 1);
618const CPUResource FPMAluC3("FP Mul/Div Alu Cycle 3", 1);
619
620const CPUResource FPAAluC1("FP Other Alu Cycle 1", 1);
621const CPUResource FPAAluC2("FP Other Alu Cycle 2", 1);
622const CPUResource FPAAluC3("FP Other Alu Cycle 3", 1);
623
624const CPUResource IRegReadPorts("Int Reg ReadPorts", INT_MAX); // CHECK
625const CPUResource IRegWritePorts("Int Reg WritePorts", 2); // CHECK
626const CPUResource FPRegReadPorts("FP Reg Read Ports", INT_MAX); // CHECK
627const CPUResource FPRegWritePorts("FP Reg Write Ports", 1); // CHECK
628
629const CPUResource CTIDelayCycle( "CTI delay cycle", 1);
630const CPUResource FCMPDelayCycle("FCMP delay cycle", 1);
631
632
633//---------------------------------------------------------------------------
634// const InstrClassRUsage SparcRUsageDesc[]
635//
636// Purpose:
637// Resource usage information for instruction in each scheduling class.
638// The InstrRUsage Objects for individual classes are specified first.
639// Note that fetch and decode are decoupled from the execution pipelines
640// via an instr buffer, so they are not included in the cycles below.
641//---------------------------------------------------------------------------
642
643const InstrClassRUsage NoneClassRUsage = {
644 SPARC_NONE,
645 /*totCycles*/ 7,
646
647 /* maxIssueNum */ 4,
648 /* isSingleIssue */ false,
649 /* breaksGroup */ false,
650 /* numBubbles */ 0,
651
652 /*numSlots*/ 4,
653 /* feasibleSlots[] */ { 0, 1, 2, 3 },
654
655 /*numEntries*/ 0,
656 /* V[] */ {
657 /*Cycle G */
Ruchira Sasanka5b8971f2001-10-16 01:23:19 +0000658 /*Ccle E */
Chris Lattner5fae0de2001-09-14 03:56:45 +0000659 /*Cycle C */
660 /*Cycle N1*/
661 /*Cycle N1*/
662 /*Cycle N1*/
663 /*Cycle W */
664 }
665};
666
667const InstrClassRUsage IEUNClassRUsage = {
668 SPARC_IEUN,
669 /*totCycles*/ 7,
670
671 /* maxIssueNum */ 3,
672 /* isSingleIssue */ false,
673 /* breaksGroup */ false,
674 /* numBubbles */ 0,
675
676 /*numSlots*/ 3,
677 /* feasibleSlots[] */ { 0, 1, 2 },
678
679 /*numEntries*/ 4,
680 /* V[] */ {
681 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
682 { IntIssueSlots.rid, 0, 1 },
683 /*Cycle E */ { IAluN.rid, 1, 1 },
684 /*Cycle C */
685 /*Cycle N1*/
686 /*Cycle N1*/
687 /*Cycle N1*/
688 /*Cycle W */ { IRegWritePorts.rid, 6, 1 }
689 }
690};
691
692const InstrClassRUsage IEU0ClassRUsage = {
693 SPARC_IEU0,
694 /*totCycles*/ 7,
695
696 /* maxIssueNum */ 1,
697 /* isSingleIssue */ false,
698 /* breaksGroup */ false,
699 /* numBubbles */ 0,
700
701 /*numSlots*/ 3,
702 /* feasibleSlots[] */ { 0, 1, 2 },
703
704 /*numEntries*/ 5,
705 /* V[] */ {
706 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
707 { IntIssueSlots.rid, 0, 1 },
708 /*Cycle E */ { IAluN.rid, 1, 1 },
709 { IAlu0.rid, 1, 1 },
710 /*Cycle C */
711 /*Cycle N1*/
712 /*Cycle N1*/
713 /*Cycle N1*/
714 /*Cycle W */ { IRegWritePorts.rid, 6, 1 }
715 }
716};
717
718const InstrClassRUsage IEU1ClassRUsage = {
719 SPARC_IEU1,
720 /*totCycles*/ 7,
721
722 /* maxIssueNum */ 1,
723 /* isSingleIssue */ false,
724 /* breaksGroup */ false,
725 /* numBubbles */ 0,
726
727 /*numSlots*/ 3,
728 /* feasibleSlots[] */ { 0, 1, 2 },
729
730 /*numEntries*/ 5,
731 /* V[] */ {
732 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
733 { IntIssueSlots.rid, 0, 1 },
734 /*Cycle E */ { IAluN.rid, 1, 1 },
735 { IAlu1.rid, 1, 1 },
736 /*Cycle C */
737 /*Cycle N1*/
738 /*Cycle N1*/
739 /*Cycle N1*/
740 /*Cycle W */ { IRegWritePorts.rid, 6, 1 }
741 }
742};
743
744const InstrClassRUsage FPMClassRUsage = {
745 SPARC_FPM,
746 /*totCycles*/ 7,
747
748 /* maxIssueNum */ 1,
749 /* isSingleIssue */ false,
750 /* breaksGroup */ false,
751 /* numBubbles */ 0,
752
753 /*numSlots*/ 4,
754 /* feasibleSlots[] */ { 0, 1, 2, 3 },
755
756 /*numEntries*/ 7,
757 /* V[] */ {
758 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
759 { FPMIssueSlots.rid, 0, 1 },
760 /*Cycle E */ { FPRegReadPorts.rid, 1, 1 },
761 /*Cycle C */ { FPMAluC1.rid, 2, 1 },
762 /*Cycle N1*/ { FPMAluC2.rid, 3, 1 },
763 /*Cycle N1*/ { FPMAluC3.rid, 4, 1 },
764 /*Cycle N1*/
765 /*Cycle W */ { FPRegWritePorts.rid, 6, 1 }
766 }
767};
768
769const InstrClassRUsage FPAClassRUsage = {
770 SPARC_FPA,
771 /*totCycles*/ 7,
772
773 /* maxIssueNum */ 1,
774 /* isSingleIssue */ false,
775 /* breaksGroup */ false,
776 /* numBubbles */ 0,
777
778 /*numSlots*/ 4,
779 /* feasibleSlots[] */ { 0, 1, 2, 3 },
780
781 /*numEntries*/ 7,
782 /* V[] */ {
783 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
784 { FPAIssueSlots.rid, 0, 1 },
785 /*Cycle E */ { FPRegReadPorts.rid, 1, 1 },
786 /*Cycle C */ { FPAAluC1.rid, 2, 1 },
787 /*Cycle N1*/ { FPAAluC2.rid, 3, 1 },
788 /*Cycle N1*/ { FPAAluC3.rid, 4, 1 },
789 /*Cycle N1*/
790 /*Cycle W */ { FPRegWritePorts.rid, 6, 1 }
791 }
792};
793
794const InstrClassRUsage LDClassRUsage = {
795 SPARC_LD,
796 /*totCycles*/ 7,
797
798 /* maxIssueNum */ 1,
799 /* isSingleIssue */ false,
800 /* breaksGroup */ false,
801 /* numBubbles */ 0,
802
803 /*numSlots*/ 3,
804 /* feasibleSlots[] */ { 0, 1, 2, },
805
806 /*numEntries*/ 6,
807 /* V[] */ {
808 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
809 { First3IssueSlots.rid, 0, 1 },
810 { LSIssueSlots.rid, 0, 1 },
811 /*Cycle E */ { LSAluC1.rid, 1, 1 },
812 /*Cycle C */ { LSAluC2.rid, 2, 1 },
813 { LdReturn.rid, 2, 1 },
814 /*Cycle N1*/
815 /*Cycle N1*/
816 /*Cycle N1*/
817 /*Cycle W */ { IRegWritePorts.rid, 6, 1 }
818 }
819};
820
821const InstrClassRUsage STClassRUsage = {
822 SPARC_ST,
823 /*totCycles*/ 7,
824
825 /* maxIssueNum */ 1,
826 /* isSingleIssue */ false,
827 /* breaksGroup */ false,
828 /* numBubbles */ 0,
829
830 /*numSlots*/ 3,
831 /* feasibleSlots[] */ { 0, 1, 2 },
832
833 /*numEntries*/ 4,
834 /* V[] */ {
835 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
836 { First3IssueSlots.rid, 0, 1 },
837 { LSIssueSlots.rid, 0, 1 },
838 /*Cycle E */ { LSAluC1.rid, 1, 1 },
839 /*Cycle C */ { LSAluC2.rid, 2, 1 }
840 /*Cycle N1*/
841 /*Cycle N1*/
842 /*Cycle N1*/
843 /*Cycle W */
844 }
845};
846
847const InstrClassRUsage CTIClassRUsage = {
848 SPARC_CTI,
849 /*totCycles*/ 7,
850
851 /* maxIssueNum */ 1,
852 /* isSingleIssue */ false,
853 /* breaksGroup */ false,
854 /* numBubbles */ 0,
855
856 /*numSlots*/ 4,
857 /* feasibleSlots[] */ { 0, 1, 2, 3 },
858
859 /*numEntries*/ 4,
860 /* V[] */ {
861 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
862 { CTIIssueSlots.rid, 0, 1 },
863 /*Cycle E */ { IAlu0.rid, 1, 1 },
864 /*Cycles E-C */ { CTIDelayCycle.rid, 1, 2 }
865 /*Cycle C */
866 /*Cycle N1*/
867 /*Cycle N1*/
868 /*Cycle N1*/
869 /*Cycle W */
870 }
871};
872
873const InstrClassRUsage SingleClassRUsage = {
874 SPARC_SINGLE,
875 /*totCycles*/ 7,
876
877 /* maxIssueNum */ 1,
878 /* isSingleIssue */ true,
879 /* breaksGroup */ false,
880 /* numBubbles */ 0,
881
882 /*numSlots*/ 1,
883 /* feasibleSlots[] */ { 0 },
884
885 /*numEntries*/ 5,
886 /* V[] */ {
887 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
888 { AllIssueSlots.rid, 0, 1 },
889 { AllIssueSlots.rid, 0, 1 },
890 { AllIssueSlots.rid, 0, 1 },
891 /*Cycle E */ { IAlu0.rid, 1, 1 }
892 /*Cycle C */
893 /*Cycle N1*/
894 /*Cycle N1*/
895 /*Cycle N1*/
896 /*Cycle W */
897 }
898};
899
900
901const InstrClassRUsage SparcRUsageDesc[] = {
902 NoneClassRUsage,
903 IEUNClassRUsage,
904 IEU0ClassRUsage,
905 IEU1ClassRUsage,
906 FPMClassRUsage,
907 FPAClassRUsage,
908 CTIClassRUsage,
909 LDClassRUsage,
910 STClassRUsage,
911 SingleClassRUsage
912};
913
914
915//---------------------------------------------------------------------------
916// const InstrIssueDelta SparcInstrIssueDeltas[]
917//
918// Purpose:
919// Changes to issue restrictions information in InstrClassRUsage for
920// instructions that differ from other instructions in their class.
921//---------------------------------------------------------------------------
922
923const InstrIssueDelta SparcInstrIssueDeltas[] = {
924
925 // opCode, isSingleIssue, breaksGroup, numBubbles
926
927 // Special cases for single-issue only
928 // Other single issue cases are below.
929//{ LDDA, true, true, 0 },
930//{ STDA, true, true, 0 },
931//{ LDDF, true, true, 0 },
932//{ LDDFA, true, true, 0 },
933 { ADDC, true, true, 0 },
934 { ADDCcc, true, true, 0 },
935 { SUBC, true, true, 0 },
936 { SUBCcc, true, true, 0 },
Chris Lattner5fae0de2001-09-14 03:56:45 +0000937//{ LDSTUB, true, true, 0 },
938//{ SWAP, true, true, 0 },
939//{ SWAPA, true, true, 0 },
940//{ CAS, true, true, 0 },
941//{ CASA, true, true, 0 },
942//{ CASX, true, true, 0 },
943//{ CASXA, true, true, 0 },
944//{ LDFSR, true, true, 0 },
945//{ LDFSRA, true, true, 0 },
946//{ LDXFSR, true, true, 0 },
947//{ LDXFSRA, true, true, 0 },
948//{ STFSR, true, true, 0 },
949//{ STFSRA, true, true, 0 },
950//{ STXFSR, true, true, 0 },
951//{ STXFSRA, true, true, 0 },
952//{ SAVED, true, true, 0 },
953//{ RESTORED, true, true, 0 },
954//{ FLUSH, true, true, 9 },
955//{ FLUSHW, true, true, 9 },
956//{ ALIGNADDR, true, true, 0 },
957 { RETURN, true, true, 0 },
958//{ DONE, true, true, 0 },
959//{ RETRY, true, true, 0 },
Chris Lattner5fae0de2001-09-14 03:56:45 +0000960//{ TCC, true, true, 0 },
961//{ SHUTDOWN, true, true, 0 },
962
963 // Special cases for breaking group *before*
964 // CURRENTLY NOT SUPPORTED!
965 { CALL, false, false, 0 },
Vikram S. Adve7c1a8d62001-10-22 13:31:53 +0000966 { JMPLCALL, false, false, 0 },
967 { JMPLRET, false, false, 0 },
Chris Lattner5fae0de2001-09-14 03:56:45 +0000968
969 // Special cases for breaking the group *after*
970 { MULX, true, true, (4+34)/2 },
971 { FDIVS, false, true, 0 },
972 { FDIVD, false, true, 0 },
973 { FDIVQ, false, true, 0 },
974 { FSQRTS, false, true, 0 },
975 { FSQRTD, false, true, 0 },
976 { FSQRTQ, false, true, 0 },
977//{ FCMP{LE,GT,NE,EQ}, false, true, 0 },
978
979 // Instructions that introduce bubbles
980//{ MULScc, true, true, 2 },
981//{ SMULcc, true, true, (4+18)/2 },
982//{ UMULcc, true, true, (4+19)/2 },
983 { SDIVX, true, true, 68 },
984 { UDIVX, true, true, 68 },
985//{ SDIVcc, true, true, 36 },
986//{ UDIVcc, true, true, 37 },
Vikram S. Adveea5d1f52001-11-04 19:34:49 +0000987 { WRCCR, true, true, 4 },
988//{ WRPR, true, true, 4 },
989//{ RDCCR, true, true, 0 }, // no bubbles after, but see below
990//{ RDPR, true, true, 0 },
Chris Lattner5fae0de2001-09-14 03:56:45 +0000991};
992
993
994//---------------------------------------------------------------------------
995// const InstrRUsageDelta SparcInstrUsageDeltas[]
996//
997// Purpose:
998// Changes to resource usage information in InstrClassRUsage for
999// instructions that differ from other instructions in their class.
1000//---------------------------------------------------------------------------
1001
1002const InstrRUsageDelta SparcInstrUsageDeltas[] = {
1003
1004 // MachineOpCode, Resource, Start cycle, Num cycles
1005
1006 //
1007 // JMPL counts as a load/store instruction for issue!
1008 //
Vikram S. Adve7c1a8d62001-10-22 13:31:53 +00001009 { JMPLCALL, LSIssueSlots.rid, 0, 1 },
1010 { JMPLRET, LSIssueSlots.rid, 0, 1 },
Chris Lattner5fae0de2001-09-14 03:56:45 +00001011
1012 //
1013 // Many instructions cannot issue for the next 2 cycles after an FCMP
1014 // We model that with a fake resource FCMPDelayCycle.
1015 //
1016 { FCMPS, FCMPDelayCycle.rid, 1, 3 },
1017 { FCMPD, FCMPDelayCycle.rid, 1, 3 },
1018 { FCMPQ, FCMPDelayCycle.rid, 1, 3 },
1019
1020 { MULX, FCMPDelayCycle.rid, 1, 1 },
1021 { SDIVX, FCMPDelayCycle.rid, 1, 1 },
1022 { UDIVX, FCMPDelayCycle.rid, 1, 1 },
1023//{ SMULcc, FCMPDelayCycle.rid, 1, 1 },
1024//{ UMULcc, FCMPDelayCycle.rid, 1, 1 },
1025//{ SDIVcc, FCMPDelayCycle.rid, 1, 1 },
1026//{ UDIVcc, FCMPDelayCycle.rid, 1, 1 },
1027 { STD, FCMPDelayCycle.rid, 1, 1 },
1028 { FMOVRSZ, FCMPDelayCycle.rid, 1, 1 },
1029 { FMOVRSLEZ,FCMPDelayCycle.rid, 1, 1 },
1030 { FMOVRSLZ, FCMPDelayCycle.rid, 1, 1 },
1031 { FMOVRSNZ, FCMPDelayCycle.rid, 1, 1 },
1032 { FMOVRSGZ, FCMPDelayCycle.rid, 1, 1 },
1033 { FMOVRSGEZ,FCMPDelayCycle.rid, 1, 1 },
1034
1035 //
1036 // Some instructions are stalled in the GROUP stage if a CTI is in
Vikram S. Adveea5d1f52001-11-04 19:34:49 +00001037 // the E or C stage. We model that with a fake resource CTIDelayCycle.
Chris Lattner5fae0de2001-09-14 03:56:45 +00001038 //
1039 { LDD, CTIDelayCycle.rid, 1, 1 },
1040//{ LDDA, CTIDelayCycle.rid, 1, 1 },
1041//{ LDDSTUB, CTIDelayCycle.rid, 1, 1 },
1042//{ LDDSTUBA, CTIDelayCycle.rid, 1, 1 },
1043//{ SWAP, CTIDelayCycle.rid, 1, 1 },
1044//{ SWAPA, CTIDelayCycle.rid, 1, 1 },
1045//{ CAS, CTIDelayCycle.rid, 1, 1 },
1046//{ CASA, CTIDelayCycle.rid, 1, 1 },
1047//{ CASX, CTIDelayCycle.rid, 1, 1 },
1048//{ CASXA, CTIDelayCycle.rid, 1, 1 },
1049
1050 //
1051 // Signed int loads of less than dword size return data in cycle N1 (not C)
1052 // and put all loads in consecutive cycles into delayed load return mode.
1053 //
1054 { LDSB, LdReturn.rid, 2, -1 },
1055 { LDSB, LdReturn.rid, 3, 1 },
1056
1057 { LDSH, LdReturn.rid, 2, -1 },
1058 { LDSH, LdReturn.rid, 3, 1 },
1059
1060 { LDSW, LdReturn.rid, 2, -1 },
1061 { LDSW, LdReturn.rid, 3, 1 },
1062
Vikram S. Adveea5d1f52001-11-04 19:34:49 +00001063 //
1064 // RDPR from certain registers and RD from any register are not dispatchable
1065 // until four clocks after they reach the head of the instr. buffer.
1066 // Together with their single-issue requirement, this means all four issue
1067 // slots are effectively blocked for those cycles, plus the issue cycle.
1068 // This does not increase the latency of the instruction itself.
1069 //
1070 { RDCCR, AllIssueSlots.rid, 0, 5 },
1071 { RDCCR, AllIssueSlots.rid, 0, 5 },
1072 { RDCCR, AllIssueSlots.rid, 0, 5 },
1073 { RDCCR, AllIssueSlots.rid, 0, 5 },
Chris Lattner5fae0de2001-09-14 03:56:45 +00001074
1075#undef EXPLICIT_BUBBLES_NEEDED
1076#ifdef EXPLICIT_BUBBLES_NEEDED
1077 //
1078 // MULScc inserts one bubble.
1079 // This means it breaks the current group (captured in UltraSparcSchedInfo)
1080 // *and occupies all issue slots for the next cycle
1081 //
1082//{ MULScc, AllIssueSlots.rid, 2, 2-1 },
1083//{ MULScc, AllIssueSlots.rid, 2, 2-1 },
1084//{ MULScc, AllIssueSlots.rid, 2, 2-1 },
1085//{ MULScc, AllIssueSlots.rid, 2, 2-1 },
1086
1087 //
1088 // SMULcc inserts between 4 and 18 bubbles, depending on #leading 0s in rs1.
1089 // We just model this with a simple average.
1090 //
1091//{ SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 },
1092//{ SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 },
1093//{ SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 },
1094//{ SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 },
1095
1096 // SMULcc inserts between 4 and 19 bubbles, depending on #leading 0s in rs1.
1097//{ UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 },
1098//{ UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 },
1099//{ UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 },
1100//{ UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 },
1101
1102 //
1103 // MULX inserts between 4 and 34 bubbles, depending on #leading 0s in rs1.
1104 //
1105 { MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 },
1106 { MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 },
1107 { MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 },
1108 { MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 },
1109
1110 //
1111 // SDIVcc inserts 36 bubbles.
1112 //
1113//{ SDIVcc, AllIssueSlots.rid, 2, 36-1 },
1114//{ SDIVcc, AllIssueSlots.rid, 2, 36-1 },
1115//{ SDIVcc, AllIssueSlots.rid, 2, 36-1 },
1116//{ SDIVcc, AllIssueSlots.rid, 2, 36-1 },
1117
1118 // UDIVcc inserts 37 bubbles.
1119//{ UDIVcc, AllIssueSlots.rid, 2, 37-1 },
1120//{ UDIVcc, AllIssueSlots.rid, 2, 37-1 },
1121//{ UDIVcc, AllIssueSlots.rid, 2, 37-1 },
1122//{ UDIVcc, AllIssueSlots.rid, 2, 37-1 },
1123
1124 //
1125 // SDIVX inserts 68 bubbles.
1126 //
1127 { SDIVX, AllIssueSlots.rid, 2, 68-1 },
1128 { SDIVX, AllIssueSlots.rid, 2, 68-1 },
1129 { SDIVX, AllIssueSlots.rid, 2, 68-1 },
1130 { SDIVX, AllIssueSlots.rid, 2, 68-1 },
1131
1132 //
1133 // UDIVX inserts 68 bubbles.
1134 //
1135 { UDIVX, AllIssueSlots.rid, 2, 68-1 },
1136 { UDIVX, AllIssueSlots.rid, 2, 68-1 },
1137 { UDIVX, AllIssueSlots.rid, 2, 68-1 },
1138 { UDIVX, AllIssueSlots.rid, 2, 68-1 },
1139
1140 //
1141 // WR inserts 4 bubbles.
1142 //
1143//{ WR, AllIssueSlots.rid, 2, 68-1 },
1144//{ WR, AllIssueSlots.rid, 2, 68-1 },
1145//{ WR, AllIssueSlots.rid, 2, 68-1 },
1146//{ WR, AllIssueSlots.rid, 2, 68-1 },
1147
1148 //
1149 // WRPR inserts 4 bubbles.
1150 //
1151//{ WRPR, AllIssueSlots.rid, 2, 68-1 },
1152//{ WRPR, AllIssueSlots.rid, 2, 68-1 },
1153//{ WRPR, AllIssueSlots.rid, 2, 68-1 },
1154//{ WRPR, AllIssueSlots.rid, 2, 68-1 },
1155
1156 //
1157 // DONE inserts 9 bubbles.
1158 //
1159//{ DONE, AllIssueSlots.rid, 2, 9-1 },
1160//{ DONE, AllIssueSlots.rid, 2, 9-1 },
1161//{ DONE, AllIssueSlots.rid, 2, 9-1 },
1162//{ DONE, AllIssueSlots.rid, 2, 9-1 },
1163
1164 //
1165 // RETRY inserts 9 bubbles.
1166 //
1167//{ RETRY, AllIssueSlots.rid, 2, 9-1 },
1168//{ RETRY, AllIssueSlots.rid, 2, 9-1 },
1169//{ RETRY, AllIssueSlots.rid, 2, 9-1 },
1170//{ RETRY, AllIssueSlots.rid, 2, 9-1 },
1171
Chris Lattner8deb9e52001-10-13 06:54:54 +00001172#endif /*EXPLICIT_BUBBLES_NEEDED */
Chris Lattner5fae0de2001-09-14 03:56:45 +00001173};
1174
1175
1176
1177// Additional delays to be captured in code:
1178// 1. RDPR from several state registers (page 349)
1179// 2. RD from *any* register (page 349)
1180// 3. Writes to TICK, PSTATE, TL registers and FLUSH{W} instr (page 349)
1181// 4. Integer store can be in same group as instr producing value to store.
1182// 5. BICC and BPICC can be in the same group as instr producing CC (pg 350)
1183// 6. FMOVr cannot be in the same or next group as an IEU instr (pg 351).
1184// 7. The second instr. of a CTI group inserts 9 bubbles (pg 351)
1185// 8. WR{PR}, SVAE, SAVED, RESTORE, RESTORED, RETURN, RETRY, and DONE that
1186// follow an annulling branch cannot be issued in the same group or in
1187// the 3 groups following the branch.
1188// 9. A predicted annulled load does not stall dependent instructions.
1189// Other annulled delay slot instructions *do* stall dependents, so
1190// nothing special needs to be done for them during scheduling.
1191//10. Do not put a load use that may be annulled in the same group as the
1192// branch. The group will stall until the load returns.
1193//11. Single-prec. FP loads lock 2 registers, for dependency checking.
1194//
1195//
1196// Additional delays we cannot or will not capture:
1197// 1. If DCTI is last word of cache line, it is delayed until next line can be
1198// fetched. Also, other DCTI alignment-related delays (pg 352)
1199// 2. Load-after-store is delayed by 7 extra cycles if load hits in D-Cache.
1200// Also, several other store-load and load-store conflicts (pg 358)
1201// 3. MEMBAR, LD{X}FSR, LDD{A} and a bunch of other load stalls (pg 358)
1202// 4. There can be at most 8 outstanding buffered store instructions
1203// (including some others like MEMBAR, LDSTUB, CAS{AX}, and FLUSH)
1204
1205
1206
1207//---------------------------------------------------------------------------
1208// class UltraSparcSchedInfo
1209//
1210// Purpose:
1211// Interface to instruction scheduling information for UltraSPARC.
1212// The parameter values above are based on UltraSPARC IIi.
1213//---------------------------------------------------------------------------
1214
1215
1216class UltraSparcSchedInfo: public MachineSchedInfo {
1217public:
Vikram S. Adve6fcb2892001-11-08 04:55:13 +00001218 /*ctor*/ UltraSparcSchedInfo (const TargetMachine& tgt);
Chris Lattner5fae0de2001-09-14 03:56:45 +00001219 /*dtor*/ virtual ~UltraSparcSchedInfo () {}
1220protected:
1221 virtual void initializeResources ();
1222};
1223
Chris Lattnerf8464e42001-09-14 04:32:55 +00001224
1225//---------------------------------------------------------------------------
Vikram S. Adve7c1a8d62001-10-22 13:31:53 +00001226// class UltraSparcFrameInfo
1227//
1228// Purpose:
1229// Interface to stack frame layout info for the UltraSPARC.
Vikram S. Adve6e9422e2001-11-12 23:26:35 +00001230// Starting offsets for each area of the stack frame are aligned at
1231// a multiple of getStackFrameSizeAlignment().
Vikram S. Adve7c1a8d62001-10-22 13:31:53 +00001232//---------------------------------------------------------------------------
1233
Vikram S. Adve6fcb2892001-11-08 04:55:13 +00001234class UltraSparcFrameInfo: public MachineFrameInfo {
Vikram S. Adve7c1a8d62001-10-22 13:31:53 +00001235public:
Vikram S. Adve6fcb2892001-11-08 04:55:13 +00001236 /*ctor*/ UltraSparcFrameInfo(const TargetMachine& tgt) : MachineFrameInfo(tgt) {}
1237
1238public:
1239 int getStackFrameSizeAlignment () const { return StackFrameSizeAlignment;}
1240 int getMinStackFrameSize () const { return MinStackFrameSize; }
1241 int getNumFixedOutgoingArgs () const { return NumFixedOutgoingArgs; }
1242 int getSizeOfEachArgOnStack () const { return SizeOfEachArgOnStack; }
1243 bool argsOnStackHaveFixedSize () const { return true; }
1244
1245 //
1246 // These methods compute offsets using the frame contents for a
1247 // particular method. The frame contents are obtained from the
1248 // MachineCodeInfoForMethod object for the given method.
1249 //
1250 int getFirstIncomingArgOffset (MachineCodeForMethod& mcInfo,
1251 bool& pos) const
1252 {
1253 pos = true; // arguments area grows upwards
1254 return FirstIncomingArgOffsetFromFP;
1255 }
1256 int getFirstOutgoingArgOffset (MachineCodeForMethod& mcInfo,
1257 bool& pos) const
1258 {
1259 pos = true; // arguments area grows upwards
1260 return FirstOutgoingArgOffsetFromSP;
1261 }
1262 int getFirstOptionalOutgoingArgOffset(MachineCodeForMethod& mcInfo,
1263 bool& pos)const
1264 {
1265 pos = true; // arguments area grows upwards
1266 return FirstOptionalOutgoingArgOffsetFromSP;
1267 }
1268
1269 int getFirstAutomaticVarOffset (MachineCodeForMethod& mcInfo,
1270 bool& pos) const;
1271 int getRegSpillAreaOffset (MachineCodeForMethod& mcInfo,
1272 bool& pos) const;
1273 int getTmpAreaOffset (MachineCodeForMethod& mcInfo,
1274 bool& pos) const;
1275 int getDynamicAreaOffset (MachineCodeForMethod& mcInfo,
1276 bool& pos) const;
1277
1278 //
1279 // These methods specify the base register used for each stack area
1280 // (generally FP or SP)
1281 //
1282 virtual int getIncomingArgBaseRegNum() const {
1283 return (int) target.getRegInfo().getFramePointer();
1284 }
1285 virtual int getOutgoingArgBaseRegNum() const {
1286 return (int) target.getRegInfo().getStackPointer();
1287 }
1288 virtual int getOptionalOutgoingArgBaseRegNum() const {
1289 return (int) target.getRegInfo().getStackPointer();
1290 }
1291 virtual int getAutomaticVarBaseRegNum() const {
1292 return (int) target.getRegInfo().getFramePointer();
1293 }
1294 virtual int getRegSpillAreaBaseRegNum() const {
1295 return (int) target.getRegInfo().getFramePointer();
1296 }
1297 virtual int getDynamicAreaBaseRegNum() const {
1298 return (int) target.getRegInfo().getStackPointer();
1299 }
1300
1301private:
Vikram S. Adve367f34f2001-11-09 02:15:52 +00001302 // All stack addresses must be offset by 0x7ff (2047) on Sparc V9.
1303 static const int OFFSET = (int) 0x7ff;
Vikram S. Adve6fcb2892001-11-08 04:55:13 +00001304 static const int StackFrameSizeAlignment = 16;
Vikram S. Adve7c1a8d62001-10-22 13:31:53 +00001305 static const int MinStackFrameSize = 176;
Vikram S. Adve6fcb2892001-11-08 04:55:13 +00001306 static const int NumFixedOutgoingArgs = 6;
1307 static const int SizeOfEachArgOnStack = 8;
Ruchira Sasankafcdc2ff2001-11-12 14:45:33 +00001308 static const int StaticAreaOffsetFromFP = 0 + OFFSET;
Vikram S. Adve367f34f2001-11-09 02:15:52 +00001309 static const int FirstIncomingArgOffsetFromFP = 128 + OFFSET;
1310 static const int FirstOptionalIncomingArgOffsetFromFP = 176 + OFFSET;
1311 static const int FirstOutgoingArgOffsetFromSP = 128 + OFFSET;
1312 static const int FirstOptionalOutgoingArgOffsetFromSP = 176 + OFFSET;
Vikram S. Adve7c1a8d62001-10-22 13:31:53 +00001313};
1314
1315
Vikram S. Adve367f34f2001-11-09 02:15:52 +00001316//---------------------------------------------------------------------------
1317// class UltraSparcCacheInfo
1318//
1319// Purpose:
1320// Interface to cache parameters for the UltraSPARC.
1321// Just use defaults for now.
1322//---------------------------------------------------------------------------
1323
1324class UltraSparcCacheInfo: public MachineCacheInfo {
1325public:
1326 /*ctor*/ UltraSparcCacheInfo (const TargetMachine& target) :
1327 MachineCacheInfo(target) {}
1328};
1329
Vikram S. Adve7c1a8d62001-10-22 13:31:53 +00001330
1331//---------------------------------------------------------------------------
Chris Lattnerf8464e42001-09-14 04:32:55 +00001332// class UltraSparcMachine
1333//
1334// Purpose:
1335// Primary interface to machine description for the UltraSPARC.
1336// Primarily just initializes machine-dependent parameters in
1337// class TargetMachine, and creates machine-dependent subclasses
Vikram S. Adve514180e2001-09-18 13:04:24 +00001338// for classes such as InstrInfo, SchedInfo and RegInfo.
Chris Lattnerf8464e42001-09-14 04:32:55 +00001339//---------------------------------------------------------------------------
1340
1341class UltraSparc : public TargetMachine {
Vikram S. Adve514180e2001-09-18 13:04:24 +00001342private:
1343 UltraSparcInstrInfo instrInfo;
1344 UltraSparcSchedInfo schedInfo;
1345 UltraSparcRegInfo regInfo;
Vikram S. Adve7c1a8d62001-10-22 13:31:53 +00001346 UltraSparcFrameInfo frameInfo;
Vikram S. Adve367f34f2001-11-09 02:15:52 +00001347 UltraSparcCacheInfo cacheInfo;
Chris Lattnerf8464e42001-09-14 04:32:55 +00001348public:
1349 UltraSparc();
1350 virtual ~UltraSparc() {}
Vikram S. Adve514180e2001-09-18 13:04:24 +00001351
Chris Lattner518da4f2001-09-19 13:47:12 +00001352 virtual const MachineInstrInfo &getInstrInfo() const { return instrInfo; }
1353 virtual const MachineSchedInfo &getSchedInfo() const { return schedInfo; }
1354 virtual const MachineRegInfo &getRegInfo() const { return regInfo; }
Vikram S. Adve6fcb2892001-11-08 04:55:13 +00001355 virtual const MachineFrameInfo &getFrameInfo() const { return frameInfo; }
Vikram S. Adve367f34f2001-11-09 02:15:52 +00001356 virtual const MachineCacheInfo &getCacheInfo() const { return cacheInfo; }
Vikram S. Adve514180e2001-09-18 13:04:24 +00001357
Chris Lattnerf8464e42001-09-14 04:32:55 +00001358 // compileMethod - For the sparc, we do instruction selection, followed by
1359 // delay slot scheduling, then register allocation.
1360 //
1361 virtual bool compileMethod(Method *M);
Chris Lattner518da4f2001-09-19 13:47:12 +00001362
1363 //
1364 // emitAssembly - Output assembly language code (a .s file) for the specified
1365 // module. The specified module must have been compiled before this may be
1366 // used.
1367 //
Chris Lattner02b67132001-10-15 15:54:43 +00001368 virtual void emitAssembly(const Module *M, ostream &OutStr) const;
Chris Lattnerf8464e42001-09-14 04:32:55 +00001369};
1370
1371
Chris Lattner5fae0de2001-09-14 03:56:45 +00001372#endif