blob: f8707c2d5210439bdf2ce87a1708437bc915541b [file] [log] [blame]
Vikram S. Adve7f37fe52001-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 Lattnerc6495ee2001-09-14 03:56:45 +000011
12#ifndef SPARC_INTERNALS_H
13#define SPARC_INTERNALS_H
14
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +000015
16#include "SparcRegClassInfo.h"
17#include "llvm/Target/TargetMachine.h"
18#include "llvm/Target/MachineInstrInfo.h"
Vikram S. Adve339084b2001-09-18 13:04:24 +000019#include "llvm/Target/MachineSchedInfo.h"
Vikram S. Adve5afff3b2001-11-09 02:15:52 +000020#include "llvm/Target/MachineFrameInfo.h"
21#include "llvm/Target/MachineCacheInfo.h"
Ruchira Sasankaab304c42001-09-30 23:19:57 +000022#include "llvm/CodeGen/RegClass.h"
Chris Lattnerc6495ee2001-09-14 03:56:45 +000023#include "llvm/Type.h"
Vikram S. Adve339084b2001-09-18 13:04:24 +000024
Chris Lattner46cbff62001-09-14 16:56:32 +000025#include <sys/types.h>
Chris Lattnerc6495ee2001-09-14 03:56:45 +000026
Chris Lattnerf6e0e282001-09-14 04:32:55 +000027class UltraSparc;
28
Chris Lattnerc6495ee2001-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 Lattnerc6495ee2001-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 Lattnerc6495ee2001-09-14 03:56:45 +000062enum SparcMachineOpCode {
Chris Lattner9a3d63b2001-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 Lattnerc6495ee2001-09-14 03:56:45 +000067
Chris Lattnerc6495ee2001-09-14 03:56:45 +000068 // End-of-array marker
69 INVALID_OPCODE,
Vikram S. Advec1521632001-10-22 13:31:53 +000070 NUM_REAL_OPCODES = PHI, // number of valid opcodes
Chris Lattnerc6495ee2001-09-14 03:56:45 +000071 NUM_TOTAL_OPCODES = INVALID_OPCODE
72};
73
Chris Lattnerc6495ee2001-09-14 03:56:45 +000074
Chris Lattner9a3d63b2001-09-19 15:56:23 +000075// Array of machine instruction descriptions...
76extern const MachineInstrDescriptor SparcMachineInstrDesc[];
Chris Lattnerc6495ee2001-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. Adve7f37fe52001-11-08 04:55:13 +000091 /*ctor*/ UltraSparcInstrInfo(const TargetMachine& tgt);
Chris Lattnerc6495ee2001-09-14 03:56:45 +000092
Vikram S. Adve5684c4e2001-10-18 00:02:06 +000093 virtual bool hasResultInterlock (MachineOpCode opCode) const
Chris Lattnerc6495ee2001-09-14 03:56:45 +000094 {
95 // All UltraSPARC instructions have interlocks (note that delay slots
96 // are not considered here).
97 // However, instructions that use the result of an FCMP produce a
98 // 9-cycle stall if they are issued less than 3 cycles after the FCMP.
99 // Force the compiler to insert a software interlock (i.e., gap of
100 // 2 other groups, including NOPs if necessary).
101 return (opCode == FCMPS || opCode == FCMPD || opCode == FCMPQ);
102 }
103
Vikram S. Adve5684c4e2001-10-18 00:02:06 +0000104 //-------------------------------------------------------------------------
105 // Code generation support for creating individual machine instructions
106 //-------------------------------------------------------------------------
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000107
Vikram S. Adve5684c4e2001-10-18 00:02:06 +0000108 // Create an instruction sequence to put the constant `val' into
109 // the virtual register `dest'. The generated instructions are
110 // returned in `minstrVec'. Any temporary registers (TmpInstruction)
111 // created are returned in `tempVec'.
112 //
113 virtual void CreateCodeToLoadConst(Value* val,
114 Instruction* dest,
115 vector<MachineInstr*>& minstrVec,
116 vector<TmpInstruction*>& tempVec) const;
Vikram S. Adve7f37fe52001-11-08 04:55:13 +0000117
118
Vikram S. Adve5afff3b2001-11-09 02:15:52 +0000119 // Create an instruction sequence to copy an integer value `val'
120 // to a floating point value `dest' by copying to memory and back.
121 // val must be an integral type. dest must be a Float or Double.
Vikram S. Adve7f37fe52001-11-08 04:55:13 +0000122 // The generated instructions are returned in `minstrVec'.
123 // Any temp. registers (TmpInstruction) created are returned in `tempVec'.
124 //
125 virtual void CreateCodeToCopyIntToFloat(Method* method,
126 Value* val,
127 Instruction* dest,
128 vector<MachineInstr*>& minstrVec,
129 vector<TmpInstruction*>& tempVec,
130 TargetMachine& target) const;
Vikram S. Adve5afff3b2001-11-09 02:15:52 +0000131
132 // Similarly, create an instruction sequence to copy an FP value
133 // `val' to an integer value `dest' by copying to memory and back.
134 // See the previous function for information about return values.
135 //
136 virtual void CreateCodeToCopyFloatToInt(Method* method,
137 Value* val,
138 Instruction* dest,
139 vector<MachineInstr*>& minstrVec,
140 vector<TmpInstruction*>& tempVec,
141 TargetMachine& target) const;
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000142};
143
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000144
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000145//----------------------------------------------------------------------------
146// class UltraSparcRegInfo
147//
148//----------------------------------------------------------------------------
149
150
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000151class LiveRange;
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000152class UltraSparc;
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000153class PhyRegAlloc;
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000154
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000155
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000156class UltraSparcRegInfo : public MachineRegInfo
157{
158
159 private:
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000160
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000161 // The actual register classes in the Sparc
162
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000163 enum RegClassIDs {
164 IntRegClassID,
165 FloatRegClassID,
166 IntCCRegClassID,
167 FloatCCRegClassID
168 };
169
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000170
171 // Type of registers available in Sparc. There can be several reg types
172 // in the same class. For instace, the float reg class has Single/Double
173 // types
174 enum RegTypes {
175 IntRegType,
176 FPSingleRegType,
177 FPDoubleRegType,
178 IntCCRegType,
179 FloatCCRegType
180 };
181
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000182 // the size of a value (int, float, etc..) stored in the stack frame
183
184
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000185
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000186 // WARNING: If the above enum order must be changed, also modify
187 // getRegisterClassOfValue method below since it assumes this particular
188 // order for efficiency.
189
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000190
191 // reverse pointer to get info about the ultra sparc machine
192 const UltraSparc *const UltraSparcInfo;
193
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000194 // Both int and float rguments can be passed in 6 int regs -
195 // %o0 to %o5 (cannot be changed)
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000196 unsigned const NumOfIntArgRegs;
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000197 unsigned const NumOfFloatArgRegs;
Ruchira Sasankac4d4b762001-10-16 01:23:19 +0000198 int const InvalidRegNum;
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000199 int SizeOfOperandOnStack;
200
201
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000202
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000203 //void setCallArgColor(LiveRange *const LR, const unsigned RegNo) const;
204
205 void setCallOrRetArgCol(LiveRange *const LR, const unsigned RegNo,
206 const MachineInstr *MI,AddedInstrMapType &AIMap)const;
207
208 MachineInstr * getCopy2RegMI(const Value *SrcVal, const unsigned Reg,
209 unsigned RegClassID) const ;
210
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000211
212 void suggestReg4RetAddr(const MachineInstr * RetMI,
213 LiveRangeInfo& LRI) const;
214
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000215 void suggestReg4CallAddr(const MachineInstr * CallMI, LiveRangeInfo& LRI,
216 vector<RegClass *> RCList) const;
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000217
218
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000219 Value *getValue4ReturnAddr( const MachineInstr * MInst ) const ;
220
221 int getRegType(const LiveRange *const LR) const {
222
223 unsigned Typ;
224
225 switch( (LR->getRegClass())->getID() ) {
226
227 case IntRegClassID: return IntRegType;
228
229 case FloatRegClassID:
230 Typ = LR->getTypeID();
231 if( Typ == Type::FloatTyID )
232 return FPSingleRegType;
233 else if( Typ == Type::DoubleTyID )
234 return FPDoubleRegType;
235 else assert(0 && "Unknown type in FloatRegClass");
236
237 case IntCCRegClassID: return IntCCRegType;
238
239 case FloatCCRegClassID: return FloatCCRegType ;
240
241 default: assert( 0 && "Unknown reg class ID");
Chris Lattner6dad5062001-11-07 13:49:12 +0000242 return 0;
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000243 }
244
245 }
246
247 int getRegType(const Value *const Val) const {
248
249 unsigned Typ;
250
251 switch( getRegClassIDOfValue(Val) ) {
252
253 case IntRegClassID: return IntRegType;
254
255 case FloatRegClassID:
256 Typ = (Val->getType())->getPrimitiveID();
257 if( Typ == Type::FloatTyID )
258 return FPSingleRegType;
259 else if( Typ == Type::DoubleTyID )
260 return FPDoubleRegType;
261 else assert(0 && "Unknown type in FloatRegClass");
262
263 case IntCCRegClassID: return IntCCRegType;
264
265 case FloatCCRegClassID: return FloatCCRegType ;
266
267 default: assert( 0 && "Unknown reg class ID");
Chris Lattner6dad5062001-11-07 13:49:12 +0000268 return 0;
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000269 }
270
271 }
272
273
274
Ruchira Sasankac4d4b762001-10-16 01:23:19 +0000275 // ***TODO: See this method is necessary
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000276
277 MachineInstr * cpValue2RegMI(Value * Val, const unsigned DestReg,
278 const int RegType) const;
279
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000280 const Value *getCallInstRetAddr(const MachineInstr *CallMI) const;
281 const unsigned getCallInstNumArgs(const MachineInstr *CallMI) const;
282
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000283
Ruchira Sasanka3839e6e2001-11-03 19:59:59 +0000284 MachineInstr * cpCCR2IntMI(const unsigned IntReg) const;
285 MachineInstr * cpInt2CCRMI(const unsigned IntReg) const;
286
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000287 public:
288
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000289
Vikram S. Adve7f37fe52001-11-08 04:55:13 +0000290 UltraSparcRegInfo(const TargetMachine& tgt ) : MachineRegInfo(tgt),
291 UltraSparcInfo(& (const UltraSparc&) tgt),
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000292 NumOfIntArgRegs(6),
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000293 NumOfFloatArgRegs(32),
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000294 InvalidRegNum(1000),
295 SizeOfOperandOnStack(8)
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000296 {
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000297 MachineRegClassArr.push_back( new SparcIntRegClass(IntRegClassID) );
298 MachineRegClassArr.push_back( new SparcFloatRegClass(FloatRegClassID) );
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000299 MachineRegClassArr.push_back( new SparcIntCCRegClass(IntCCRegClassID) );
300 MachineRegClassArr.push_back( new SparcFloatCCRegClass(FloatCCRegClassID));
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000301
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000302 assert( SparcFloatRegOrder::StartOfNonVolatileRegs == 32 &&
303 "32 Float regs are used for float arg passing");
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000304
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000305 }
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000306
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000307 // ***** TODO Delete
308 ~UltraSparcRegInfo(void) { } // empty destructor
309
310
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000311 inline const UltraSparc & getUltraSparcInfo() const {
312 return *UltraSparcInfo;
313 }
314
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000315
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000316
317 inline unsigned getRegClassIDOfValue (const Value *const Val,
318 bool isCCReg = false) const {
319
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000320 Type::PrimitiveID ty = (Val->getType())->getPrimitiveID();
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000321
322 unsigned res;
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000323
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000324 if( (ty && ty <= Type::LongTyID) || (ty == Type::LabelTyID) ||
325 (ty == Type::MethodTyID) || (ty == Type::PointerTyID) )
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000326 res = IntRegClassID; // sparc int reg (ty=0: void)
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000327 else if( ty <= Type::DoubleTyID)
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000328 res = FloatRegClassID; // sparc float reg class
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000329 else {
Chris Lattner1e23ed72001-10-15 18:15:27 +0000330 cerr << "TypeID: " << ty << endl;
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000331 assert(0 && "Cannot resolve register class for type");
Chris Lattner8e5c0b42001-11-07 14:01:59 +0000332 return 0;
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000333 }
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000334
335 if(isCCReg)
336 return res + 2; // corresponidng condition code regiser
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000337 else
338 return res;
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000339 }
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000340
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000341 // returns the register tha contains always zero
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000342 // this is the unified register number
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000343 inline int getZeroRegNum() const { return SparcIntRegOrder::g0; }
344
345 // returns the reg used for pushing the address when a method is called.
346 // This can be used for other purposes between calls
347 unsigned getCallAddressReg() const { return SparcIntRegOrder::o7; }
348
349
350 // and when we return from a method. It should be made sure that this
351 // register contains the return value when a return instruction is reached.
352 unsigned getReturnAddressReg() const { return SparcIntRegOrder::i7; }
353
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000354 void suggestRegs4MethodArgs(const Method *const Meth,
355 LiveRangeInfo& LRI) const;
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000356
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000357 void suggestRegs4CallArgs(const MachineInstr *const CallMI,
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000358 LiveRangeInfo& LRI, vector<RegClass *> RCL) const;
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000359
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000360 void suggestReg4RetValue(const MachineInstr *const RetMI,
361 LiveRangeInfo& LRI ) const;
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000362
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000363
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000364 void colorMethodArgs(const Method *const Meth, LiveRangeInfo& LRI,
365 AddedInstrns *const FirstAI) const;
366
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000367 void colorCallArgs(const MachineInstr *const CallMI, LiveRangeInfo& LRI,
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000368 AddedInstrns *const CallAI, PhyRegAlloc &PRA) const;
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000369
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000370 void colorRetValue(const MachineInstr *const RetI, LiveRangeInfo& LRI,
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000371 AddedInstrns *const RetAI) const;
372
373
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000374 // bool handleSpecialMInstr(const MachineInstr * MInst,
375 // LiveRangeInfo& LRI, vector<RegClass *> RCL) const;
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000376
377
378 static void printReg(const LiveRange *const LR) ;
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000379
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000380 // this method provides a unique number for each register
381 inline int getUnifiedRegNum(int RegClassID, int reg) const {
382
383 if( RegClassID == IntRegClassID && reg < 32 )
384 return reg;
385 else if ( RegClassID == FloatRegClassID && reg < 64)
386 return reg + 32; // we have 32 int regs
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000387 else if( RegClassID == FloatCCRegClassID && reg < 4)
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000388 return reg + 32 + 64; // 32 int, 64 float
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000389 else if( RegClassID == IntCCRegClassID )
390 return 4+ 32 + 64; // only int cc reg
Ruchira Sasankac4d4b762001-10-16 01:23:19 +0000391 else if (reg==InvalidRegNum)
392 return InvalidRegNum;
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000393 else
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000394 assert(0 && "Invalid register class or reg number");
Chris Lattner6dad5062001-11-07 13:49:12 +0000395 return 0;
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000396 }
397
398 // given the unified register number, this gives the name
399 inline const string getUnifiedRegName(int reg) const {
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000400 if( reg < 32 )
401 return SparcIntRegOrder::getRegName(reg);
402 else if ( reg < (64 + 32) )
403 return SparcFloatRegOrder::getRegName( reg - 32);
404 else if( reg < (64+32+4) )
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000405 return SparcFloatCCRegOrder::getRegName( reg -32 - 64);
Ruchira Sasanka3839e6e2001-11-03 19:59:59 +0000406 else if( reg < (64+32+4+2) ) // two names: %xcc and %ccr
407 return SparcIntCCRegOrder::getRegName( reg -32 - 64 - 4);
Vikram S. Advec1521632001-10-22 13:31:53 +0000408 else if (reg== InvalidRegNum) //****** TODO: Remove */
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000409 return "<*NoReg*>";
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000410 else
411 assert(0 && "Invalid register number");
Chris Lattner6dad5062001-11-07 13:49:12 +0000412 return "";
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000413 }
414
Vikram S. Advec1521632001-10-22 13:31:53 +0000415 inline unsigned int getRegNumInCallersWindow(int reg) {
416 if (reg == InvalidRegNum || reg >= 32)
417 return reg;
418 return SparcIntRegOrder::getRegNumInCallersWindow(reg);
419 }
420
421 inline bool mustBeRemappedInCallersWindow(int reg) {
422 return (reg != InvalidRegNum && reg < 32);
423 }
424
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000425 const Value * getCallInstRetVal(const MachineInstr *CallMI) const;
426
Ruchira Sasankac4d4b762001-10-16 01:23:19 +0000427 MachineInstr * cpReg2RegMI(const unsigned SrcReg, const unsigned DestReg,
428 const int RegType) const;
429
430 MachineInstr * cpReg2MemMI(const unsigned SrcReg, const unsigned DestPtrReg,
431 const int Offset, const int RegType) const;
432
433 MachineInstr * cpMem2RegMI(const unsigned SrcPtrReg, const int Offset,
434 const unsigned DestReg, const int RegType) const;
435
Ruchira Sasankaef1b0cb2001-11-03 17:13:27 +0000436 MachineInstr* cpValue2Value(Value *Src, Value *Dest) const;
437
438
Ruchira Sasankac4d4b762001-10-16 01:23:19 +0000439 inline bool isRegVolatile(const int RegClassID, const int Reg) const {
440 return (MachineRegClassArr[RegClassID])->isRegVolatile(Reg);
441 }
442
443
444 inline unsigned getFramePointer() const {
445 return SparcIntRegOrder::i6;
446 }
447
448 inline unsigned getStackPointer() const {
449 return SparcIntRegOrder::o6;
450 }
451
452 inline int getInvalidRegNum() const {
453 return InvalidRegNum;
454 }
455
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000456
457 void insertCallerSavingCode(const MachineInstr *MInst,
458 const BasicBlock *BB, PhyRegAlloc &PRA ) const;
459
460
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000461};
462
463
464
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000465/*---------------------------------------------------------------------------
466Scheduling guidelines for SPARC IIi:
467
468I-Cache alignment rules (pg 326)
469-- Align a branch target instruction so that it's entire group is within
470 the same cache line (may be 1-4 instructions).
471** Don't let a branch that is predicted taken be the last instruction
472 on an I-cache line: delay slot will need an entire line to be fetched
473-- Make a FP instruction or a branch be the 4th instruction in a group.
474 For branches, there are tradeoffs in reordering to make this happen
475 (see pg. 327).
476** Don't put a branch in a group that crosses a 32-byte boundary!
477 An artificial branch is inserted after every 32 bytes, and having
478 another branch will force the group to be broken into 2 groups.
479
480iTLB rules:
481-- Don't let a loop span two memory pages, if possible
482
483Branch prediction performance:
484-- Don't make the branch in a delay slot the target of a branch
485-- Try not to have 2 predicted branches within a group of 4 instructions
486 (because each such group has a single branch target field).
487-- Try to align branches in slots 0, 2, 4 or 6 of a cache line (to avoid
488 the wrong prediction bits being used in some cases).
489
490D-Cache timing constraints:
491-- Signed int loads of less than 64 bits have 3 cycle latency, not 2
492-- All other loads that hit in D-Cache have 2 cycle latency
493-- All loads are returned IN ORDER, so a D-Cache miss will delay a later hit
494-- Mis-aligned loads or stores cause a trap. In particular, replace
495 mis-aligned FP double precision l/s with 2 single-precision l/s.
496-- Simulations of integer codes show increase in avg. group size of
497 33% when code (including esp. non-faulting loads) is moved across
498 one branch, and 50% across 2 branches.
499
500E-Cache timing constraints:
501-- Scheduling for E-cache (D-Cache misses) is effective (due to load buffering)
502
503Store buffer timing constraints:
504-- Stores can be executed in same cycle as instruction producing the value
505-- Stores are buffered and have lower priority for E-cache until
506 highwater mark is reached in the store buffer (5 stores)
507
508Pipeline constraints:
509-- Shifts can only use IEU0.
510-- CC setting instructions can only use IEU1.
511-- Several other instructions must only use IEU1:
512 EDGE(?), ARRAY(?), CALL, JMPL, BPr, PST, and FCMP.
513-- Two instructions cannot store to the same register file in a single cycle
514 (single write port per file).
515
516Issue and grouping constraints:
517-- FP and branch instructions must use slot 4.
518-- Shift instructions cannot be grouped with other IEU0-specific instructions.
519-- CC setting instructions cannot be grouped with other IEU1-specific instrs.
520-- Several instructions must be issued in a single-instruction group:
521 MOVcc or MOVr, MULs/x and DIVs/x, SAVE/RESTORE, many others
522-- A CALL or JMPL breaks a group, ie, is not combined with subsequent instrs.
523--
524--
525
526Branch delay slot scheduling rules:
527-- A CTI couple (two back-to-back CTI instructions in the dynamic stream)
528 has a 9-instruction penalty: the entire pipeline is flushed when the
529 second instruction reaches stage 9 (W-Writeback).
530-- Avoid putting multicycle instructions, and instructions that may cause
531 load misses, in the delay slot of an annulling branch.
532-- Avoid putting WR, SAVE..., RESTORE and RETURN instructions in the
533 delay slot of an annulling branch.
534
535 *--------------------------------------------------------------------------- */
536
537//---------------------------------------------------------------------------
538// List of CPUResources for UltraSPARC IIi.
539//---------------------------------------------------------------------------
540
541const CPUResource AllIssueSlots( "All Instr Slots", 4);
542const CPUResource IntIssueSlots( "Int Instr Slots", 3);
543const CPUResource First3IssueSlots("Instr Slots 0-3", 3);
544const CPUResource LSIssueSlots( "Load-Store Instr Slot", 1);
545const CPUResource CTIIssueSlots( "Ctrl Transfer Instr Slot", 1);
546const CPUResource FPAIssueSlots( "Int Instr Slot 1", 1);
547const CPUResource FPMIssueSlots( "Int Instr Slot 1", 1);
548
549// IEUN instructions can use either Alu and should use IAluN.
550// IEU0 instructions must use Alu 1 and should use both IAluN and IAlu0.
551// IEU1 instructions must use Alu 2 and should use both IAluN and IAlu1.
552const CPUResource IAluN("Int ALU 1or2", 2);
553const CPUResource IAlu0("Int ALU 1", 1);
554const CPUResource IAlu1("Int ALU 2", 1);
555
556const CPUResource LSAluC1("Load/Store Unit Addr Cycle", 1);
557const CPUResource LSAluC2("Load/Store Unit Issue Cycle", 1);
558const CPUResource LdReturn("Load Return Unit", 1);
559
560const CPUResource FPMAluC1("FP Mul/Div Alu Cycle 1", 1);
561const CPUResource FPMAluC2("FP Mul/Div Alu Cycle 2", 1);
562const CPUResource FPMAluC3("FP Mul/Div Alu Cycle 3", 1);
563
564const CPUResource FPAAluC1("FP Other Alu Cycle 1", 1);
565const CPUResource FPAAluC2("FP Other Alu Cycle 2", 1);
566const CPUResource FPAAluC3("FP Other Alu Cycle 3", 1);
567
568const CPUResource IRegReadPorts("Int Reg ReadPorts", INT_MAX); // CHECK
569const CPUResource IRegWritePorts("Int Reg WritePorts", 2); // CHECK
570const CPUResource FPRegReadPorts("FP Reg Read Ports", INT_MAX); // CHECK
571const CPUResource FPRegWritePorts("FP Reg Write Ports", 1); // CHECK
572
573const CPUResource CTIDelayCycle( "CTI delay cycle", 1);
574const CPUResource FCMPDelayCycle("FCMP delay cycle", 1);
575
576
577//---------------------------------------------------------------------------
578// const InstrClassRUsage SparcRUsageDesc[]
579//
580// Purpose:
581// Resource usage information for instruction in each scheduling class.
582// The InstrRUsage Objects for individual classes are specified first.
583// Note that fetch and decode are decoupled from the execution pipelines
584// via an instr buffer, so they are not included in the cycles below.
585//---------------------------------------------------------------------------
586
587const InstrClassRUsage NoneClassRUsage = {
588 SPARC_NONE,
589 /*totCycles*/ 7,
590
591 /* maxIssueNum */ 4,
592 /* isSingleIssue */ false,
593 /* breaksGroup */ false,
594 /* numBubbles */ 0,
595
596 /*numSlots*/ 4,
597 /* feasibleSlots[] */ { 0, 1, 2, 3 },
598
599 /*numEntries*/ 0,
600 /* V[] */ {
601 /*Cycle G */
Ruchira Sasankac4d4b762001-10-16 01:23:19 +0000602 /*Ccle E */
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000603 /*Cycle C */
604 /*Cycle N1*/
605 /*Cycle N1*/
606 /*Cycle N1*/
607 /*Cycle W */
608 }
609};
610
611const InstrClassRUsage IEUNClassRUsage = {
612 SPARC_IEUN,
613 /*totCycles*/ 7,
614
615 /* maxIssueNum */ 3,
616 /* isSingleIssue */ false,
617 /* breaksGroup */ false,
618 /* numBubbles */ 0,
619
620 /*numSlots*/ 3,
621 /* feasibleSlots[] */ { 0, 1, 2 },
622
623 /*numEntries*/ 4,
624 /* V[] */ {
625 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
626 { IntIssueSlots.rid, 0, 1 },
627 /*Cycle E */ { IAluN.rid, 1, 1 },
628 /*Cycle C */
629 /*Cycle N1*/
630 /*Cycle N1*/
631 /*Cycle N1*/
632 /*Cycle W */ { IRegWritePorts.rid, 6, 1 }
633 }
634};
635
636const InstrClassRUsage IEU0ClassRUsage = {
637 SPARC_IEU0,
638 /*totCycles*/ 7,
639
640 /* maxIssueNum */ 1,
641 /* isSingleIssue */ false,
642 /* breaksGroup */ false,
643 /* numBubbles */ 0,
644
645 /*numSlots*/ 3,
646 /* feasibleSlots[] */ { 0, 1, 2 },
647
648 /*numEntries*/ 5,
649 /* V[] */ {
650 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
651 { IntIssueSlots.rid, 0, 1 },
652 /*Cycle E */ { IAluN.rid, 1, 1 },
653 { IAlu0.rid, 1, 1 },
654 /*Cycle C */
655 /*Cycle N1*/
656 /*Cycle N1*/
657 /*Cycle N1*/
658 /*Cycle W */ { IRegWritePorts.rid, 6, 1 }
659 }
660};
661
662const InstrClassRUsage IEU1ClassRUsage = {
663 SPARC_IEU1,
664 /*totCycles*/ 7,
665
666 /* maxIssueNum */ 1,
667 /* isSingleIssue */ false,
668 /* breaksGroup */ false,
669 /* numBubbles */ 0,
670
671 /*numSlots*/ 3,
672 /* feasibleSlots[] */ { 0, 1, 2 },
673
674 /*numEntries*/ 5,
675 /* V[] */ {
676 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
677 { IntIssueSlots.rid, 0, 1 },
678 /*Cycle E */ { IAluN.rid, 1, 1 },
679 { IAlu1.rid, 1, 1 },
680 /*Cycle C */
681 /*Cycle N1*/
682 /*Cycle N1*/
683 /*Cycle N1*/
684 /*Cycle W */ { IRegWritePorts.rid, 6, 1 }
685 }
686};
687
688const InstrClassRUsage FPMClassRUsage = {
689 SPARC_FPM,
690 /*totCycles*/ 7,
691
692 /* maxIssueNum */ 1,
693 /* isSingleIssue */ false,
694 /* breaksGroup */ false,
695 /* numBubbles */ 0,
696
697 /*numSlots*/ 4,
698 /* feasibleSlots[] */ { 0, 1, 2, 3 },
699
700 /*numEntries*/ 7,
701 /* V[] */ {
702 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
703 { FPMIssueSlots.rid, 0, 1 },
704 /*Cycle E */ { FPRegReadPorts.rid, 1, 1 },
705 /*Cycle C */ { FPMAluC1.rid, 2, 1 },
706 /*Cycle N1*/ { FPMAluC2.rid, 3, 1 },
707 /*Cycle N1*/ { FPMAluC3.rid, 4, 1 },
708 /*Cycle N1*/
709 /*Cycle W */ { FPRegWritePorts.rid, 6, 1 }
710 }
711};
712
713const InstrClassRUsage FPAClassRUsage = {
714 SPARC_FPA,
715 /*totCycles*/ 7,
716
717 /* maxIssueNum */ 1,
718 /* isSingleIssue */ false,
719 /* breaksGroup */ false,
720 /* numBubbles */ 0,
721
722 /*numSlots*/ 4,
723 /* feasibleSlots[] */ { 0, 1, 2, 3 },
724
725 /*numEntries*/ 7,
726 /* V[] */ {
727 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
728 { FPAIssueSlots.rid, 0, 1 },
729 /*Cycle E */ { FPRegReadPorts.rid, 1, 1 },
730 /*Cycle C */ { FPAAluC1.rid, 2, 1 },
731 /*Cycle N1*/ { FPAAluC2.rid, 3, 1 },
732 /*Cycle N1*/ { FPAAluC3.rid, 4, 1 },
733 /*Cycle N1*/
734 /*Cycle W */ { FPRegWritePorts.rid, 6, 1 }
735 }
736};
737
738const InstrClassRUsage LDClassRUsage = {
739 SPARC_LD,
740 /*totCycles*/ 7,
741
742 /* maxIssueNum */ 1,
743 /* isSingleIssue */ false,
744 /* breaksGroup */ false,
745 /* numBubbles */ 0,
746
747 /*numSlots*/ 3,
748 /* feasibleSlots[] */ { 0, 1, 2, },
749
750 /*numEntries*/ 6,
751 /* V[] */ {
752 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
753 { First3IssueSlots.rid, 0, 1 },
754 { LSIssueSlots.rid, 0, 1 },
755 /*Cycle E */ { LSAluC1.rid, 1, 1 },
756 /*Cycle C */ { LSAluC2.rid, 2, 1 },
757 { LdReturn.rid, 2, 1 },
758 /*Cycle N1*/
759 /*Cycle N1*/
760 /*Cycle N1*/
761 /*Cycle W */ { IRegWritePorts.rid, 6, 1 }
762 }
763};
764
765const InstrClassRUsage STClassRUsage = {
766 SPARC_ST,
767 /*totCycles*/ 7,
768
769 /* maxIssueNum */ 1,
770 /* isSingleIssue */ false,
771 /* breaksGroup */ false,
772 /* numBubbles */ 0,
773
774 /*numSlots*/ 3,
775 /* feasibleSlots[] */ { 0, 1, 2 },
776
777 /*numEntries*/ 4,
778 /* V[] */ {
779 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
780 { First3IssueSlots.rid, 0, 1 },
781 { LSIssueSlots.rid, 0, 1 },
782 /*Cycle E */ { LSAluC1.rid, 1, 1 },
783 /*Cycle C */ { LSAluC2.rid, 2, 1 }
784 /*Cycle N1*/
785 /*Cycle N1*/
786 /*Cycle N1*/
787 /*Cycle W */
788 }
789};
790
791const InstrClassRUsage CTIClassRUsage = {
792 SPARC_CTI,
793 /*totCycles*/ 7,
794
795 /* maxIssueNum */ 1,
796 /* isSingleIssue */ false,
797 /* breaksGroup */ false,
798 /* numBubbles */ 0,
799
800 /*numSlots*/ 4,
801 /* feasibleSlots[] */ { 0, 1, 2, 3 },
802
803 /*numEntries*/ 4,
804 /* V[] */ {
805 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
806 { CTIIssueSlots.rid, 0, 1 },
807 /*Cycle E */ { IAlu0.rid, 1, 1 },
808 /*Cycles E-C */ { CTIDelayCycle.rid, 1, 2 }
809 /*Cycle C */
810 /*Cycle N1*/
811 /*Cycle N1*/
812 /*Cycle N1*/
813 /*Cycle W */
814 }
815};
816
817const InstrClassRUsage SingleClassRUsage = {
818 SPARC_SINGLE,
819 /*totCycles*/ 7,
820
821 /* maxIssueNum */ 1,
822 /* isSingleIssue */ true,
823 /* breaksGroup */ false,
824 /* numBubbles */ 0,
825
826 /*numSlots*/ 1,
827 /* feasibleSlots[] */ { 0 },
828
829 /*numEntries*/ 5,
830 /* V[] */ {
831 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
832 { AllIssueSlots.rid, 0, 1 },
833 { AllIssueSlots.rid, 0, 1 },
834 { AllIssueSlots.rid, 0, 1 },
835 /*Cycle E */ { IAlu0.rid, 1, 1 }
836 /*Cycle C */
837 /*Cycle N1*/
838 /*Cycle N1*/
839 /*Cycle N1*/
840 /*Cycle W */
841 }
842};
843
844
845const InstrClassRUsage SparcRUsageDesc[] = {
846 NoneClassRUsage,
847 IEUNClassRUsage,
848 IEU0ClassRUsage,
849 IEU1ClassRUsage,
850 FPMClassRUsage,
851 FPAClassRUsage,
852 CTIClassRUsage,
853 LDClassRUsage,
854 STClassRUsage,
855 SingleClassRUsage
856};
857
858
859//---------------------------------------------------------------------------
860// const InstrIssueDelta SparcInstrIssueDeltas[]
861//
862// Purpose:
863// Changes to issue restrictions information in InstrClassRUsage for
864// instructions that differ from other instructions in their class.
865//---------------------------------------------------------------------------
866
867const InstrIssueDelta SparcInstrIssueDeltas[] = {
868
869 // opCode, isSingleIssue, breaksGroup, numBubbles
870
871 // Special cases for single-issue only
872 // Other single issue cases are below.
873//{ LDDA, true, true, 0 },
874//{ STDA, true, true, 0 },
875//{ LDDF, true, true, 0 },
876//{ LDDFA, true, true, 0 },
877 { ADDC, true, true, 0 },
878 { ADDCcc, true, true, 0 },
879 { SUBC, true, true, 0 },
880 { SUBCcc, true, true, 0 },
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000881//{ LDSTUB, true, true, 0 },
882//{ SWAP, true, true, 0 },
883//{ SWAPA, true, true, 0 },
884//{ CAS, true, true, 0 },
885//{ CASA, true, true, 0 },
886//{ CASX, true, true, 0 },
887//{ CASXA, true, true, 0 },
888//{ LDFSR, true, true, 0 },
889//{ LDFSRA, true, true, 0 },
890//{ LDXFSR, true, true, 0 },
891//{ LDXFSRA, true, true, 0 },
892//{ STFSR, true, true, 0 },
893//{ STFSRA, true, true, 0 },
894//{ STXFSR, true, true, 0 },
895//{ STXFSRA, true, true, 0 },
896//{ SAVED, true, true, 0 },
897//{ RESTORED, true, true, 0 },
898//{ FLUSH, true, true, 9 },
899//{ FLUSHW, true, true, 9 },
900//{ ALIGNADDR, true, true, 0 },
901 { RETURN, true, true, 0 },
902//{ DONE, true, true, 0 },
903//{ RETRY, true, true, 0 },
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000904//{ TCC, true, true, 0 },
905//{ SHUTDOWN, true, true, 0 },
906
907 // Special cases for breaking group *before*
908 // CURRENTLY NOT SUPPORTED!
909 { CALL, false, false, 0 },
Vikram S. Advec1521632001-10-22 13:31:53 +0000910 { JMPLCALL, false, false, 0 },
911 { JMPLRET, false, false, 0 },
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000912
913 // Special cases for breaking the group *after*
914 { MULX, true, true, (4+34)/2 },
915 { FDIVS, false, true, 0 },
916 { FDIVD, false, true, 0 },
917 { FDIVQ, false, true, 0 },
918 { FSQRTS, false, true, 0 },
919 { FSQRTD, false, true, 0 },
920 { FSQRTQ, false, true, 0 },
921//{ FCMP{LE,GT,NE,EQ}, false, true, 0 },
922
923 // Instructions that introduce bubbles
924//{ MULScc, true, true, 2 },
925//{ SMULcc, true, true, (4+18)/2 },
926//{ UMULcc, true, true, (4+19)/2 },
927 { SDIVX, true, true, 68 },
928 { UDIVX, true, true, 68 },
929//{ SDIVcc, true, true, 36 },
930//{ UDIVcc, true, true, 37 },
Vikram S. Adveb7f06f42001-11-04 19:34:49 +0000931 { WRCCR, true, true, 4 },
932//{ WRPR, true, true, 4 },
933//{ RDCCR, true, true, 0 }, // no bubbles after, but see below
934//{ RDPR, true, true, 0 },
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000935};
936
937
938//---------------------------------------------------------------------------
939// const InstrRUsageDelta SparcInstrUsageDeltas[]
940//
941// Purpose:
942// Changes to resource usage information in InstrClassRUsage for
943// instructions that differ from other instructions in their class.
944//---------------------------------------------------------------------------
945
946const InstrRUsageDelta SparcInstrUsageDeltas[] = {
947
948 // MachineOpCode, Resource, Start cycle, Num cycles
949
950 //
951 // JMPL counts as a load/store instruction for issue!
952 //
Vikram S. Advec1521632001-10-22 13:31:53 +0000953 { JMPLCALL, LSIssueSlots.rid, 0, 1 },
954 { JMPLRET, LSIssueSlots.rid, 0, 1 },
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000955
956 //
957 // Many instructions cannot issue for the next 2 cycles after an FCMP
958 // We model that with a fake resource FCMPDelayCycle.
959 //
960 { FCMPS, FCMPDelayCycle.rid, 1, 3 },
961 { FCMPD, FCMPDelayCycle.rid, 1, 3 },
962 { FCMPQ, FCMPDelayCycle.rid, 1, 3 },
963
964 { MULX, FCMPDelayCycle.rid, 1, 1 },
965 { SDIVX, FCMPDelayCycle.rid, 1, 1 },
966 { UDIVX, FCMPDelayCycle.rid, 1, 1 },
967//{ SMULcc, FCMPDelayCycle.rid, 1, 1 },
968//{ UMULcc, FCMPDelayCycle.rid, 1, 1 },
969//{ SDIVcc, FCMPDelayCycle.rid, 1, 1 },
970//{ UDIVcc, FCMPDelayCycle.rid, 1, 1 },
971 { STD, FCMPDelayCycle.rid, 1, 1 },
972 { FMOVRSZ, FCMPDelayCycle.rid, 1, 1 },
973 { FMOVRSLEZ,FCMPDelayCycle.rid, 1, 1 },
974 { FMOVRSLZ, FCMPDelayCycle.rid, 1, 1 },
975 { FMOVRSNZ, FCMPDelayCycle.rid, 1, 1 },
976 { FMOVRSGZ, FCMPDelayCycle.rid, 1, 1 },
977 { FMOVRSGEZ,FCMPDelayCycle.rid, 1, 1 },
978
979 //
980 // Some instructions are stalled in the GROUP stage if a CTI is in
Vikram S. Adveb7f06f42001-11-04 19:34:49 +0000981 // the E or C stage. We model that with a fake resource CTIDelayCycle.
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000982 //
983 { LDD, CTIDelayCycle.rid, 1, 1 },
984//{ LDDA, CTIDelayCycle.rid, 1, 1 },
985//{ LDDSTUB, CTIDelayCycle.rid, 1, 1 },
986//{ LDDSTUBA, CTIDelayCycle.rid, 1, 1 },
987//{ SWAP, CTIDelayCycle.rid, 1, 1 },
988//{ SWAPA, CTIDelayCycle.rid, 1, 1 },
989//{ CAS, CTIDelayCycle.rid, 1, 1 },
990//{ CASA, CTIDelayCycle.rid, 1, 1 },
991//{ CASX, CTIDelayCycle.rid, 1, 1 },
992//{ CASXA, CTIDelayCycle.rid, 1, 1 },
993
994 //
995 // Signed int loads of less than dword size return data in cycle N1 (not C)
996 // and put all loads in consecutive cycles into delayed load return mode.
997 //
998 { LDSB, LdReturn.rid, 2, -1 },
999 { LDSB, LdReturn.rid, 3, 1 },
1000
1001 { LDSH, LdReturn.rid, 2, -1 },
1002 { LDSH, LdReturn.rid, 3, 1 },
1003
1004 { LDSW, LdReturn.rid, 2, -1 },
1005 { LDSW, LdReturn.rid, 3, 1 },
1006
Vikram S. Adveb7f06f42001-11-04 19:34:49 +00001007 //
1008 // RDPR from certain registers and RD from any register are not dispatchable
1009 // until four clocks after they reach the head of the instr. buffer.
1010 // Together with their single-issue requirement, this means all four issue
1011 // slots are effectively blocked for those cycles, plus the issue cycle.
1012 // This does not increase the latency of the instruction itself.
1013 //
1014 { RDCCR, AllIssueSlots.rid, 0, 5 },
1015 { RDCCR, AllIssueSlots.rid, 0, 5 },
1016 { RDCCR, AllIssueSlots.rid, 0, 5 },
1017 { RDCCR, AllIssueSlots.rid, 0, 5 },
Chris Lattnerc6495ee2001-09-14 03:56:45 +00001018
1019#undef EXPLICIT_BUBBLES_NEEDED
1020#ifdef EXPLICIT_BUBBLES_NEEDED
1021 //
1022 // MULScc inserts one bubble.
1023 // This means it breaks the current group (captured in UltraSparcSchedInfo)
1024 // *and occupies all issue slots for the next cycle
1025 //
1026//{ MULScc, AllIssueSlots.rid, 2, 2-1 },
1027//{ MULScc, AllIssueSlots.rid, 2, 2-1 },
1028//{ MULScc, AllIssueSlots.rid, 2, 2-1 },
1029//{ MULScc, AllIssueSlots.rid, 2, 2-1 },
1030
1031 //
1032 // SMULcc inserts between 4 and 18 bubbles, depending on #leading 0s in rs1.
1033 // We just model this with a simple average.
1034 //
1035//{ SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 },
1036//{ SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 },
1037//{ SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 },
1038//{ SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 },
1039
1040 // SMULcc inserts between 4 and 19 bubbles, depending on #leading 0s in rs1.
1041//{ UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 },
1042//{ UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 },
1043//{ UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 },
1044//{ UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 },
1045
1046 //
1047 // MULX inserts between 4 and 34 bubbles, depending on #leading 0s in rs1.
1048 //
1049 { MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 },
1050 { MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 },
1051 { MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 },
1052 { MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 },
1053
1054 //
1055 // SDIVcc inserts 36 bubbles.
1056 //
1057//{ SDIVcc, AllIssueSlots.rid, 2, 36-1 },
1058//{ SDIVcc, AllIssueSlots.rid, 2, 36-1 },
1059//{ SDIVcc, AllIssueSlots.rid, 2, 36-1 },
1060//{ SDIVcc, AllIssueSlots.rid, 2, 36-1 },
1061
1062 // UDIVcc inserts 37 bubbles.
1063//{ UDIVcc, AllIssueSlots.rid, 2, 37-1 },
1064//{ UDIVcc, AllIssueSlots.rid, 2, 37-1 },
1065//{ UDIVcc, AllIssueSlots.rid, 2, 37-1 },
1066//{ UDIVcc, AllIssueSlots.rid, 2, 37-1 },
1067
1068 //
1069 // SDIVX inserts 68 bubbles.
1070 //
1071 { SDIVX, AllIssueSlots.rid, 2, 68-1 },
1072 { SDIVX, AllIssueSlots.rid, 2, 68-1 },
1073 { SDIVX, AllIssueSlots.rid, 2, 68-1 },
1074 { SDIVX, AllIssueSlots.rid, 2, 68-1 },
1075
1076 //
1077 // UDIVX inserts 68 bubbles.
1078 //
1079 { UDIVX, AllIssueSlots.rid, 2, 68-1 },
1080 { UDIVX, AllIssueSlots.rid, 2, 68-1 },
1081 { UDIVX, AllIssueSlots.rid, 2, 68-1 },
1082 { UDIVX, AllIssueSlots.rid, 2, 68-1 },
1083
1084 //
1085 // WR inserts 4 bubbles.
1086 //
1087//{ WR, AllIssueSlots.rid, 2, 68-1 },
1088//{ WR, AllIssueSlots.rid, 2, 68-1 },
1089//{ WR, AllIssueSlots.rid, 2, 68-1 },
1090//{ WR, AllIssueSlots.rid, 2, 68-1 },
1091
1092 //
1093 // WRPR inserts 4 bubbles.
1094 //
1095//{ WRPR, AllIssueSlots.rid, 2, 68-1 },
1096//{ WRPR, AllIssueSlots.rid, 2, 68-1 },
1097//{ WRPR, AllIssueSlots.rid, 2, 68-1 },
1098//{ WRPR, AllIssueSlots.rid, 2, 68-1 },
1099
1100 //
1101 // DONE inserts 9 bubbles.
1102 //
1103//{ DONE, AllIssueSlots.rid, 2, 9-1 },
1104//{ DONE, AllIssueSlots.rid, 2, 9-1 },
1105//{ DONE, AllIssueSlots.rid, 2, 9-1 },
1106//{ DONE, AllIssueSlots.rid, 2, 9-1 },
1107
1108 //
1109 // RETRY inserts 9 bubbles.
1110 //
1111//{ RETRY, AllIssueSlots.rid, 2, 9-1 },
1112//{ RETRY, AllIssueSlots.rid, 2, 9-1 },
1113//{ RETRY, AllIssueSlots.rid, 2, 9-1 },
1114//{ RETRY, AllIssueSlots.rid, 2, 9-1 },
1115
Chris Lattnere369fcb2001-10-13 06:54:54 +00001116#endif /*EXPLICIT_BUBBLES_NEEDED */
Chris Lattnerc6495ee2001-09-14 03:56:45 +00001117};
1118
1119
1120
1121// Additional delays to be captured in code:
1122// 1. RDPR from several state registers (page 349)
1123// 2. RD from *any* register (page 349)
1124// 3. Writes to TICK, PSTATE, TL registers and FLUSH{W} instr (page 349)
1125// 4. Integer store can be in same group as instr producing value to store.
1126// 5. BICC and BPICC can be in the same group as instr producing CC (pg 350)
1127// 6. FMOVr cannot be in the same or next group as an IEU instr (pg 351).
1128// 7. The second instr. of a CTI group inserts 9 bubbles (pg 351)
1129// 8. WR{PR}, SVAE, SAVED, RESTORE, RESTORED, RETURN, RETRY, and DONE that
1130// follow an annulling branch cannot be issued in the same group or in
1131// the 3 groups following the branch.
1132// 9. A predicted annulled load does not stall dependent instructions.
1133// Other annulled delay slot instructions *do* stall dependents, so
1134// nothing special needs to be done for them during scheduling.
1135//10. Do not put a load use that may be annulled in the same group as the
1136// branch. The group will stall until the load returns.
1137//11. Single-prec. FP loads lock 2 registers, for dependency checking.
1138//
1139//
1140// Additional delays we cannot or will not capture:
1141// 1. If DCTI is last word of cache line, it is delayed until next line can be
1142// fetched. Also, other DCTI alignment-related delays (pg 352)
1143// 2. Load-after-store is delayed by 7 extra cycles if load hits in D-Cache.
1144// Also, several other store-load and load-store conflicts (pg 358)
1145// 3. MEMBAR, LD{X}FSR, LDD{A} and a bunch of other load stalls (pg 358)
1146// 4. There can be at most 8 outstanding buffered store instructions
1147// (including some others like MEMBAR, LDSTUB, CAS{AX}, and FLUSH)
1148
1149
1150
1151//---------------------------------------------------------------------------
1152// class UltraSparcSchedInfo
1153//
1154// Purpose:
1155// Interface to instruction scheduling information for UltraSPARC.
1156// The parameter values above are based on UltraSPARC IIi.
1157//---------------------------------------------------------------------------
1158
1159
1160class UltraSparcSchedInfo: public MachineSchedInfo {
1161public:
Vikram S. Adve7f37fe52001-11-08 04:55:13 +00001162 /*ctor*/ UltraSparcSchedInfo (const TargetMachine& tgt);
Chris Lattnerc6495ee2001-09-14 03:56:45 +00001163 /*dtor*/ virtual ~UltraSparcSchedInfo () {}
1164protected:
1165 virtual void initializeResources ();
1166};
1167
Chris Lattnerf6e0e282001-09-14 04:32:55 +00001168
1169//---------------------------------------------------------------------------
Vikram S. Advec1521632001-10-22 13:31:53 +00001170// class UltraSparcFrameInfo
1171//
1172// Purpose:
1173// Interface to stack frame layout info for the UltraSPARC.
Vikram S. Advec1521632001-10-22 13:31:53 +00001174//---------------------------------------------------------------------------
1175
Vikram S. Adve7f37fe52001-11-08 04:55:13 +00001176class UltraSparcFrameInfo: public MachineFrameInfo {
Vikram S. Advec1521632001-10-22 13:31:53 +00001177public:
Vikram S. Adve7f37fe52001-11-08 04:55:13 +00001178 /*ctor*/ UltraSparcFrameInfo(const TargetMachine& tgt) : MachineFrameInfo(tgt) {}
1179
1180public:
1181 int getStackFrameSizeAlignment () const { return StackFrameSizeAlignment;}
1182 int getMinStackFrameSize () const { return MinStackFrameSize; }
1183 int getNumFixedOutgoingArgs () const { return NumFixedOutgoingArgs; }
1184 int getSizeOfEachArgOnStack () const { return SizeOfEachArgOnStack; }
1185 bool argsOnStackHaveFixedSize () const { return true; }
1186
1187 //
1188 // These methods compute offsets using the frame contents for a
1189 // particular method. The frame contents are obtained from the
1190 // MachineCodeInfoForMethod object for the given method.
1191 //
1192 int getFirstIncomingArgOffset (MachineCodeForMethod& mcInfo,
1193 bool& pos) const
1194 {
1195 pos = true; // arguments area grows upwards
1196 return FirstIncomingArgOffsetFromFP;
1197 }
1198 int getFirstOutgoingArgOffset (MachineCodeForMethod& mcInfo,
1199 bool& pos) const
1200 {
1201 pos = true; // arguments area grows upwards
1202 return FirstOutgoingArgOffsetFromSP;
1203 }
1204 int getFirstOptionalOutgoingArgOffset(MachineCodeForMethod& mcInfo,
1205 bool& pos)const
1206 {
1207 pos = true; // arguments area grows upwards
1208 return FirstOptionalOutgoingArgOffsetFromSP;
1209 }
1210
1211 int getFirstAutomaticVarOffset (MachineCodeForMethod& mcInfo,
1212 bool& pos) const;
1213 int getRegSpillAreaOffset (MachineCodeForMethod& mcInfo,
1214 bool& pos) const;
1215 int getTmpAreaOffset (MachineCodeForMethod& mcInfo,
1216 bool& pos) const;
1217 int getDynamicAreaOffset (MachineCodeForMethod& mcInfo,
1218 bool& pos) const;
1219
1220 //
1221 // These methods specify the base register used for each stack area
1222 // (generally FP or SP)
1223 //
1224 virtual int getIncomingArgBaseRegNum() const {
1225 return (int) target.getRegInfo().getFramePointer();
1226 }
1227 virtual int getOutgoingArgBaseRegNum() const {
1228 return (int) target.getRegInfo().getStackPointer();
1229 }
1230 virtual int getOptionalOutgoingArgBaseRegNum() const {
1231 return (int) target.getRegInfo().getStackPointer();
1232 }
1233 virtual int getAutomaticVarBaseRegNum() const {
1234 return (int) target.getRegInfo().getFramePointer();
1235 }
1236 virtual int getRegSpillAreaBaseRegNum() const {
1237 return (int) target.getRegInfo().getFramePointer();
1238 }
1239 virtual int getDynamicAreaBaseRegNum() const {
1240 return (int) target.getRegInfo().getStackPointer();
1241 }
1242
1243private:
Vikram S. Adve5afff3b2001-11-09 02:15:52 +00001244 // All stack addresses must be offset by 0x7ff (2047) on Sparc V9.
1245 static const int OFFSET = (int) 0x7ff;
Vikram S. Adve7f37fe52001-11-08 04:55:13 +00001246 static const int StackFrameSizeAlignment = 16;
Vikram S. Advec1521632001-10-22 13:31:53 +00001247 static const int MinStackFrameSize = 176;
Vikram S. Adve7f37fe52001-11-08 04:55:13 +00001248 static const int NumFixedOutgoingArgs = 6;
1249 static const int SizeOfEachArgOnStack = 8;
Vikram S. Adve5afff3b2001-11-09 02:15:52 +00001250 static const int StaticAreaOffsetFromFP = -1 + OFFSET;
1251 static const int FirstIncomingArgOffsetFromFP = 128 + OFFSET;
1252 static const int FirstOptionalIncomingArgOffsetFromFP = 176 + OFFSET;
1253 static const int FirstOutgoingArgOffsetFromSP = 128 + OFFSET;
1254 static const int FirstOptionalOutgoingArgOffsetFromSP = 176 + OFFSET;
Vikram S. Advec1521632001-10-22 13:31:53 +00001255};
1256
1257
Vikram S. Adve5afff3b2001-11-09 02:15:52 +00001258//---------------------------------------------------------------------------
1259// class UltraSparcCacheInfo
1260//
1261// Purpose:
1262// Interface to cache parameters for the UltraSPARC.
1263// Just use defaults for now.
1264//---------------------------------------------------------------------------
1265
1266class UltraSparcCacheInfo: public MachineCacheInfo {
1267public:
1268 /*ctor*/ UltraSparcCacheInfo (const TargetMachine& target) :
1269 MachineCacheInfo(target) {}
1270};
1271
Vikram S. Advec1521632001-10-22 13:31:53 +00001272
1273//---------------------------------------------------------------------------
Chris Lattnerf6e0e282001-09-14 04:32:55 +00001274// class UltraSparcMachine
1275//
1276// Purpose:
1277// Primary interface to machine description for the UltraSPARC.
1278// Primarily just initializes machine-dependent parameters in
1279// class TargetMachine, and creates machine-dependent subclasses
Vikram S. Adve339084b2001-09-18 13:04:24 +00001280// for classes such as InstrInfo, SchedInfo and RegInfo.
Chris Lattnerf6e0e282001-09-14 04:32:55 +00001281//---------------------------------------------------------------------------
1282
1283class UltraSparc : public TargetMachine {
Vikram S. Adve339084b2001-09-18 13:04:24 +00001284private:
1285 UltraSparcInstrInfo instrInfo;
1286 UltraSparcSchedInfo schedInfo;
1287 UltraSparcRegInfo regInfo;
Vikram S. Advec1521632001-10-22 13:31:53 +00001288 UltraSparcFrameInfo frameInfo;
Vikram S. Adve5afff3b2001-11-09 02:15:52 +00001289 UltraSparcCacheInfo cacheInfo;
Chris Lattnerf6e0e282001-09-14 04:32:55 +00001290public:
1291 UltraSparc();
1292 virtual ~UltraSparc() {}
Vikram S. Adve339084b2001-09-18 13:04:24 +00001293
Chris Lattner32f600a2001-09-19 13:47:12 +00001294 virtual const MachineInstrInfo &getInstrInfo() const { return instrInfo; }
1295 virtual const MachineSchedInfo &getSchedInfo() const { return schedInfo; }
1296 virtual const MachineRegInfo &getRegInfo() const { return regInfo; }
Vikram S. Adve7f37fe52001-11-08 04:55:13 +00001297 virtual const MachineFrameInfo &getFrameInfo() const { return frameInfo; }
Vikram S. Adve5afff3b2001-11-09 02:15:52 +00001298 virtual const MachineCacheInfo &getCacheInfo() const { return cacheInfo; }
Vikram S. Adve339084b2001-09-18 13:04:24 +00001299
Chris Lattnerf6e0e282001-09-14 04:32:55 +00001300 // compileMethod - For the sparc, we do instruction selection, followed by
1301 // delay slot scheduling, then register allocation.
1302 //
1303 virtual bool compileMethod(Method *M);
Chris Lattner32f600a2001-09-19 13:47:12 +00001304
1305 //
1306 // emitAssembly - Output assembly language code (a .s file) for the specified
1307 // module. The specified module must have been compiled before this may be
1308 // used.
1309 //
Chris Lattnerec0a95f2001-10-15 15:54:43 +00001310 virtual void emitAssembly(const Module *M, ostream &OutStr) const;
Chris Lattnerf6e0e282001-09-14 04:32:55 +00001311};
1312
1313
Chris Lattnerc6495ee2001-09-14 03:56:45 +00001314#endif