blob: ad04eb3ee73da68648bff2c469834903221d58ae [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
Ruchira Sasanka868cf822001-11-09 23:49:14 +0000287 void OrderAddedInstrns( vector<MachineInstr *> &UnordVec,
288 vector<MachineInstr *> &OrdVec) const;
289
290
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000291 public:
292
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000293
Vikram S. Adve7f37fe52001-11-08 04:55:13 +0000294 UltraSparcRegInfo(const TargetMachine& tgt ) : MachineRegInfo(tgt),
295 UltraSparcInfo(& (const UltraSparc&) tgt),
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000296 NumOfIntArgRegs(6),
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000297 NumOfFloatArgRegs(32),
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000298 InvalidRegNum(1000),
299 SizeOfOperandOnStack(8)
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000300 {
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000301 MachineRegClassArr.push_back( new SparcIntRegClass(IntRegClassID) );
302 MachineRegClassArr.push_back( new SparcFloatRegClass(FloatRegClassID) );
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000303 MachineRegClassArr.push_back( new SparcIntCCRegClass(IntCCRegClassID) );
304 MachineRegClassArr.push_back( new SparcFloatCCRegClass(FloatCCRegClassID));
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000305
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000306 assert( SparcFloatRegOrder::StartOfNonVolatileRegs == 32 &&
307 "32 Float regs are used for float arg passing");
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000308
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000309 }
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000310
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000311 // ***** TODO Delete
312 ~UltraSparcRegInfo(void) { } // empty destructor
313
314
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000315 inline const UltraSparc & getUltraSparcInfo() const {
316 return *UltraSparcInfo;
317 }
318
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000319
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000320
321 inline unsigned getRegClassIDOfValue (const Value *const Val,
322 bool isCCReg = false) const {
323
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000324 Type::PrimitiveID ty = (Val->getType())->getPrimitiveID();
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000325
326 unsigned res;
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000327
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000328 if( (ty && ty <= Type::LongTyID) || (ty == Type::LabelTyID) ||
329 (ty == Type::MethodTyID) || (ty == Type::PointerTyID) )
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000330 res = IntRegClassID; // sparc int reg (ty=0: void)
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000331 else if( ty <= Type::DoubleTyID)
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000332 res = FloatRegClassID; // sparc float reg class
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000333 else {
Chris Lattner1e23ed72001-10-15 18:15:27 +0000334 cerr << "TypeID: " << ty << endl;
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000335 assert(0 && "Cannot resolve register class for type");
Chris Lattner8e5c0b42001-11-07 14:01:59 +0000336 return 0;
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000337 }
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000338
339 if(isCCReg)
340 return res + 2; // corresponidng condition code regiser
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000341 else
342 return res;
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000343 }
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000344
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000345 // returns the register tha contains always zero
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000346 // this is the unified register number
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000347 inline int getZeroRegNum() const { return SparcIntRegOrder::g0; }
348
349 // returns the reg used for pushing the address when a method is called.
350 // This can be used for other purposes between calls
351 unsigned getCallAddressReg() const { return SparcIntRegOrder::o7; }
352
353
354 // and when we return from a method. It should be made sure that this
355 // register contains the return value when a return instruction is reached.
356 unsigned getReturnAddressReg() const { return SparcIntRegOrder::i7; }
357
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000358 void suggestRegs4MethodArgs(const Method *const Meth,
359 LiveRangeInfo& LRI) const;
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000360
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000361 void suggestRegs4CallArgs(const MachineInstr *const CallMI,
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000362 LiveRangeInfo& LRI, vector<RegClass *> RCL) const;
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000363
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000364 void suggestReg4RetValue(const MachineInstr *const RetMI,
365 LiveRangeInfo& LRI ) const;
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000366
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000367
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000368 void colorMethodArgs(const Method *const Meth, LiveRangeInfo& LRI,
369 AddedInstrns *const FirstAI) const;
370
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000371 void colorCallArgs(const MachineInstr *const CallMI, LiveRangeInfo& LRI,
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000372 AddedInstrns *const CallAI, PhyRegAlloc &PRA) const;
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000373
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000374 void colorRetValue(const MachineInstr *const RetI, LiveRangeInfo& LRI,
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000375 AddedInstrns *const RetAI) const;
376
377
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000378 // bool handleSpecialMInstr(const MachineInstr * MInst,
379 // LiveRangeInfo& LRI, vector<RegClass *> RCL) const;
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000380
381
382 static void printReg(const LiveRange *const LR) ;
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000383
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000384 // this method provides a unique number for each register
385 inline int getUnifiedRegNum(int RegClassID, int reg) const {
386
387 if( RegClassID == IntRegClassID && reg < 32 )
388 return reg;
389 else if ( RegClassID == FloatRegClassID && reg < 64)
390 return reg + 32; // we have 32 int regs
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000391 else if( RegClassID == FloatCCRegClassID && reg < 4)
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000392 return reg + 32 + 64; // 32 int, 64 float
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000393 else if( RegClassID == IntCCRegClassID )
394 return 4+ 32 + 64; // only int cc reg
Ruchira Sasankac4d4b762001-10-16 01:23:19 +0000395 else if (reg==InvalidRegNum)
396 return InvalidRegNum;
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000397 else
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000398 assert(0 && "Invalid register class or reg number");
Chris Lattner6dad5062001-11-07 13:49:12 +0000399 return 0;
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000400 }
401
402 // given the unified register number, this gives the name
403 inline const string getUnifiedRegName(int reg) const {
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000404 if( reg < 32 )
405 return SparcIntRegOrder::getRegName(reg);
406 else if ( reg < (64 + 32) )
407 return SparcFloatRegOrder::getRegName( reg - 32);
408 else if( reg < (64+32+4) )
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000409 return SparcFloatCCRegOrder::getRegName( reg -32 - 64);
Ruchira Sasanka3839e6e2001-11-03 19:59:59 +0000410 else if( reg < (64+32+4+2) ) // two names: %xcc and %ccr
411 return SparcIntCCRegOrder::getRegName( reg -32 - 64 - 4);
Vikram S. Advec1521632001-10-22 13:31:53 +0000412 else if (reg== InvalidRegNum) //****** TODO: Remove */
Ruchira Sasankaab304c42001-09-30 23:19:57 +0000413 return "<*NoReg*>";
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000414 else
415 assert(0 && "Invalid register number");
Chris Lattner6dad5062001-11-07 13:49:12 +0000416 return "";
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000417 }
418
Vikram S. Advec1521632001-10-22 13:31:53 +0000419 inline unsigned int getRegNumInCallersWindow(int reg) {
420 if (reg == InvalidRegNum || reg >= 32)
421 return reg;
422 return SparcIntRegOrder::getRegNumInCallersWindow(reg);
423 }
424
425 inline bool mustBeRemappedInCallersWindow(int reg) {
426 return (reg != InvalidRegNum && reg < 32);
427 }
428
Ruchira Sasankab3b6f532001-10-21 16:43:41 +0000429 const Value * getCallInstRetVal(const MachineInstr *CallMI) const;
430
Ruchira Sasankac4d4b762001-10-16 01:23:19 +0000431 MachineInstr * cpReg2RegMI(const unsigned SrcReg, const unsigned DestReg,
432 const int RegType) const;
433
434 MachineInstr * cpReg2MemMI(const unsigned SrcReg, const unsigned DestPtrReg,
435 const int Offset, const int RegType) const;
436
437 MachineInstr * cpMem2RegMI(const unsigned SrcPtrReg, const int Offset,
438 const unsigned DestReg, const int RegType) const;
439
Ruchira Sasankaef1b0cb2001-11-03 17:13:27 +0000440 MachineInstr* cpValue2Value(Value *Src, Value *Dest) const;
441
442
Ruchira Sasankac4d4b762001-10-16 01:23:19 +0000443 inline bool isRegVolatile(const int RegClassID, const int Reg) const {
444 return (MachineRegClassArr[RegClassID])->isRegVolatile(Reg);
445 }
446
447
448 inline unsigned getFramePointer() const {
449 return SparcIntRegOrder::i6;
450 }
451
452 inline unsigned getStackPointer() const {
453 return SparcIntRegOrder::o6;
454 }
455
456 inline int getInvalidRegNum() const {
457 return InvalidRegNum;
458 }
459
Ruchira Sasanka20c82b12001-10-28 18:15:12 +0000460
461 void insertCallerSavingCode(const MachineInstr *MInst,
462 const BasicBlock *BB, PhyRegAlloc &PRA ) const;
463
464
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000465};
466
467
468
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000469/*---------------------------------------------------------------------------
470Scheduling guidelines for SPARC IIi:
471
472I-Cache alignment rules (pg 326)
473-- Align a branch target instruction so that it's entire group is within
474 the same cache line (may be 1-4 instructions).
475** Don't let a branch that is predicted taken be the last instruction
476 on an I-cache line: delay slot will need an entire line to be fetched
477-- Make a FP instruction or a branch be the 4th instruction in a group.
478 For branches, there are tradeoffs in reordering to make this happen
479 (see pg. 327).
480** Don't put a branch in a group that crosses a 32-byte boundary!
481 An artificial branch is inserted after every 32 bytes, and having
482 another branch will force the group to be broken into 2 groups.
483
484iTLB rules:
485-- Don't let a loop span two memory pages, if possible
486
487Branch prediction performance:
488-- Don't make the branch in a delay slot the target of a branch
489-- Try not to have 2 predicted branches within a group of 4 instructions
490 (because each such group has a single branch target field).
491-- Try to align branches in slots 0, 2, 4 or 6 of a cache line (to avoid
492 the wrong prediction bits being used in some cases).
493
494D-Cache timing constraints:
495-- Signed int loads of less than 64 bits have 3 cycle latency, not 2
496-- All other loads that hit in D-Cache have 2 cycle latency
497-- All loads are returned IN ORDER, so a D-Cache miss will delay a later hit
498-- Mis-aligned loads or stores cause a trap. In particular, replace
499 mis-aligned FP double precision l/s with 2 single-precision l/s.
500-- Simulations of integer codes show increase in avg. group size of
501 33% when code (including esp. non-faulting loads) is moved across
502 one branch, and 50% across 2 branches.
503
504E-Cache timing constraints:
505-- Scheduling for E-cache (D-Cache misses) is effective (due to load buffering)
506
507Store buffer timing constraints:
508-- Stores can be executed in same cycle as instruction producing the value
509-- Stores are buffered and have lower priority for E-cache until
510 highwater mark is reached in the store buffer (5 stores)
511
512Pipeline constraints:
513-- Shifts can only use IEU0.
514-- CC setting instructions can only use IEU1.
515-- Several other instructions must only use IEU1:
516 EDGE(?), ARRAY(?), CALL, JMPL, BPr, PST, and FCMP.
517-- Two instructions cannot store to the same register file in a single cycle
518 (single write port per file).
519
520Issue and grouping constraints:
521-- FP and branch instructions must use slot 4.
522-- Shift instructions cannot be grouped with other IEU0-specific instructions.
523-- CC setting instructions cannot be grouped with other IEU1-specific instrs.
524-- Several instructions must be issued in a single-instruction group:
525 MOVcc or MOVr, MULs/x and DIVs/x, SAVE/RESTORE, many others
526-- A CALL or JMPL breaks a group, ie, is not combined with subsequent instrs.
527--
528--
529
530Branch delay slot scheduling rules:
531-- A CTI couple (two back-to-back CTI instructions in the dynamic stream)
532 has a 9-instruction penalty: the entire pipeline is flushed when the
533 second instruction reaches stage 9 (W-Writeback).
534-- Avoid putting multicycle instructions, and instructions that may cause
535 load misses, in the delay slot of an annulling branch.
536-- Avoid putting WR, SAVE..., RESTORE and RETURN instructions in the
537 delay slot of an annulling branch.
538
539 *--------------------------------------------------------------------------- */
540
541//---------------------------------------------------------------------------
542// List of CPUResources for UltraSPARC IIi.
543//---------------------------------------------------------------------------
544
545const CPUResource AllIssueSlots( "All Instr Slots", 4);
546const CPUResource IntIssueSlots( "Int Instr Slots", 3);
547const CPUResource First3IssueSlots("Instr Slots 0-3", 3);
548const CPUResource LSIssueSlots( "Load-Store Instr Slot", 1);
549const CPUResource CTIIssueSlots( "Ctrl Transfer Instr Slot", 1);
550const CPUResource FPAIssueSlots( "Int Instr Slot 1", 1);
551const CPUResource FPMIssueSlots( "Int Instr Slot 1", 1);
552
553// IEUN instructions can use either Alu and should use IAluN.
554// IEU0 instructions must use Alu 1 and should use both IAluN and IAlu0.
555// IEU1 instructions must use Alu 2 and should use both IAluN and IAlu1.
556const CPUResource IAluN("Int ALU 1or2", 2);
557const CPUResource IAlu0("Int ALU 1", 1);
558const CPUResource IAlu1("Int ALU 2", 1);
559
560const CPUResource LSAluC1("Load/Store Unit Addr Cycle", 1);
561const CPUResource LSAluC2("Load/Store Unit Issue Cycle", 1);
562const CPUResource LdReturn("Load Return Unit", 1);
563
564const CPUResource FPMAluC1("FP Mul/Div Alu Cycle 1", 1);
565const CPUResource FPMAluC2("FP Mul/Div Alu Cycle 2", 1);
566const CPUResource FPMAluC3("FP Mul/Div Alu Cycle 3", 1);
567
568const CPUResource FPAAluC1("FP Other Alu Cycle 1", 1);
569const CPUResource FPAAluC2("FP Other Alu Cycle 2", 1);
570const CPUResource FPAAluC3("FP Other Alu Cycle 3", 1);
571
572const CPUResource IRegReadPorts("Int Reg ReadPorts", INT_MAX); // CHECK
573const CPUResource IRegWritePorts("Int Reg WritePorts", 2); // CHECK
574const CPUResource FPRegReadPorts("FP Reg Read Ports", INT_MAX); // CHECK
575const CPUResource FPRegWritePorts("FP Reg Write Ports", 1); // CHECK
576
577const CPUResource CTIDelayCycle( "CTI delay cycle", 1);
578const CPUResource FCMPDelayCycle("FCMP delay cycle", 1);
579
580
581//---------------------------------------------------------------------------
582// const InstrClassRUsage SparcRUsageDesc[]
583//
584// Purpose:
585// Resource usage information for instruction in each scheduling class.
586// The InstrRUsage Objects for individual classes are specified first.
587// Note that fetch and decode are decoupled from the execution pipelines
588// via an instr buffer, so they are not included in the cycles below.
589//---------------------------------------------------------------------------
590
591const InstrClassRUsage NoneClassRUsage = {
592 SPARC_NONE,
593 /*totCycles*/ 7,
594
595 /* maxIssueNum */ 4,
596 /* isSingleIssue */ false,
597 /* breaksGroup */ false,
598 /* numBubbles */ 0,
599
600 /*numSlots*/ 4,
601 /* feasibleSlots[] */ { 0, 1, 2, 3 },
602
603 /*numEntries*/ 0,
604 /* V[] */ {
605 /*Cycle G */
Ruchira Sasankac4d4b762001-10-16 01:23:19 +0000606 /*Ccle E */
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000607 /*Cycle C */
608 /*Cycle N1*/
609 /*Cycle N1*/
610 /*Cycle N1*/
611 /*Cycle W */
612 }
613};
614
615const InstrClassRUsage IEUNClassRUsage = {
616 SPARC_IEUN,
617 /*totCycles*/ 7,
618
619 /* maxIssueNum */ 3,
620 /* isSingleIssue */ false,
621 /* breaksGroup */ false,
622 /* numBubbles */ 0,
623
624 /*numSlots*/ 3,
625 /* feasibleSlots[] */ { 0, 1, 2 },
626
627 /*numEntries*/ 4,
628 /* V[] */ {
629 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
630 { IntIssueSlots.rid, 0, 1 },
631 /*Cycle E */ { IAluN.rid, 1, 1 },
632 /*Cycle C */
633 /*Cycle N1*/
634 /*Cycle N1*/
635 /*Cycle N1*/
636 /*Cycle W */ { IRegWritePorts.rid, 6, 1 }
637 }
638};
639
640const InstrClassRUsage IEU0ClassRUsage = {
641 SPARC_IEU0,
642 /*totCycles*/ 7,
643
644 /* maxIssueNum */ 1,
645 /* isSingleIssue */ false,
646 /* breaksGroup */ false,
647 /* numBubbles */ 0,
648
649 /*numSlots*/ 3,
650 /* feasibleSlots[] */ { 0, 1, 2 },
651
652 /*numEntries*/ 5,
653 /* V[] */ {
654 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
655 { IntIssueSlots.rid, 0, 1 },
656 /*Cycle E */ { IAluN.rid, 1, 1 },
657 { IAlu0.rid, 1, 1 },
658 /*Cycle C */
659 /*Cycle N1*/
660 /*Cycle N1*/
661 /*Cycle N1*/
662 /*Cycle W */ { IRegWritePorts.rid, 6, 1 }
663 }
664};
665
666const InstrClassRUsage IEU1ClassRUsage = {
667 SPARC_IEU1,
668 /*totCycles*/ 7,
669
670 /* maxIssueNum */ 1,
671 /* isSingleIssue */ false,
672 /* breaksGroup */ false,
673 /* numBubbles */ 0,
674
675 /*numSlots*/ 3,
676 /* feasibleSlots[] */ { 0, 1, 2 },
677
678 /*numEntries*/ 5,
679 /* V[] */ {
680 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
681 { IntIssueSlots.rid, 0, 1 },
682 /*Cycle E */ { IAluN.rid, 1, 1 },
683 { IAlu1.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 FPMClassRUsage = {
693 SPARC_FPM,
694 /*totCycles*/ 7,
695
696 /* maxIssueNum */ 1,
697 /* isSingleIssue */ false,
698 /* breaksGroup */ false,
699 /* numBubbles */ 0,
700
701 /*numSlots*/ 4,
702 /* feasibleSlots[] */ { 0, 1, 2, 3 },
703
704 /*numEntries*/ 7,
705 /* V[] */ {
706 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
707 { FPMIssueSlots.rid, 0, 1 },
708 /*Cycle E */ { FPRegReadPorts.rid, 1, 1 },
709 /*Cycle C */ { FPMAluC1.rid, 2, 1 },
710 /*Cycle N1*/ { FPMAluC2.rid, 3, 1 },
711 /*Cycle N1*/ { FPMAluC3.rid, 4, 1 },
712 /*Cycle N1*/
713 /*Cycle W */ { FPRegWritePorts.rid, 6, 1 }
714 }
715};
716
717const InstrClassRUsage FPAClassRUsage = {
718 SPARC_FPA,
719 /*totCycles*/ 7,
720
721 /* maxIssueNum */ 1,
722 /* isSingleIssue */ false,
723 /* breaksGroup */ false,
724 /* numBubbles */ 0,
725
726 /*numSlots*/ 4,
727 /* feasibleSlots[] */ { 0, 1, 2, 3 },
728
729 /*numEntries*/ 7,
730 /* V[] */ {
731 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
732 { FPAIssueSlots.rid, 0, 1 },
733 /*Cycle E */ { FPRegReadPorts.rid, 1, 1 },
734 /*Cycle C */ { FPAAluC1.rid, 2, 1 },
735 /*Cycle N1*/ { FPAAluC2.rid, 3, 1 },
736 /*Cycle N1*/ { FPAAluC3.rid, 4, 1 },
737 /*Cycle N1*/
738 /*Cycle W */ { FPRegWritePorts.rid, 6, 1 }
739 }
740};
741
742const InstrClassRUsage LDClassRUsage = {
743 SPARC_LD,
744 /*totCycles*/ 7,
745
746 /* maxIssueNum */ 1,
747 /* isSingleIssue */ false,
748 /* breaksGroup */ false,
749 /* numBubbles */ 0,
750
751 /*numSlots*/ 3,
752 /* feasibleSlots[] */ { 0, 1, 2, },
753
754 /*numEntries*/ 6,
755 /* V[] */ {
756 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
757 { First3IssueSlots.rid, 0, 1 },
758 { LSIssueSlots.rid, 0, 1 },
759 /*Cycle E */ { LSAluC1.rid, 1, 1 },
760 /*Cycle C */ { LSAluC2.rid, 2, 1 },
761 { LdReturn.rid, 2, 1 },
762 /*Cycle N1*/
763 /*Cycle N1*/
764 /*Cycle N1*/
765 /*Cycle W */ { IRegWritePorts.rid, 6, 1 }
766 }
767};
768
769const InstrClassRUsage STClassRUsage = {
770 SPARC_ST,
771 /*totCycles*/ 7,
772
773 /* maxIssueNum */ 1,
774 /* isSingleIssue */ false,
775 /* breaksGroup */ false,
776 /* numBubbles */ 0,
777
778 /*numSlots*/ 3,
779 /* feasibleSlots[] */ { 0, 1, 2 },
780
781 /*numEntries*/ 4,
782 /* V[] */ {
783 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
784 { First3IssueSlots.rid, 0, 1 },
785 { LSIssueSlots.rid, 0, 1 },
786 /*Cycle E */ { LSAluC1.rid, 1, 1 },
787 /*Cycle C */ { LSAluC2.rid, 2, 1 }
788 /*Cycle N1*/
789 /*Cycle N1*/
790 /*Cycle N1*/
791 /*Cycle W */
792 }
793};
794
795const InstrClassRUsage CTIClassRUsage = {
796 SPARC_CTI,
797 /*totCycles*/ 7,
798
799 /* maxIssueNum */ 1,
800 /* isSingleIssue */ false,
801 /* breaksGroup */ false,
802 /* numBubbles */ 0,
803
804 /*numSlots*/ 4,
805 /* feasibleSlots[] */ { 0, 1, 2, 3 },
806
807 /*numEntries*/ 4,
808 /* V[] */ {
809 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
810 { CTIIssueSlots.rid, 0, 1 },
811 /*Cycle E */ { IAlu0.rid, 1, 1 },
812 /*Cycles E-C */ { CTIDelayCycle.rid, 1, 2 }
813 /*Cycle C */
814 /*Cycle N1*/
815 /*Cycle N1*/
816 /*Cycle N1*/
817 /*Cycle W */
818 }
819};
820
821const InstrClassRUsage SingleClassRUsage = {
822 SPARC_SINGLE,
823 /*totCycles*/ 7,
824
825 /* maxIssueNum */ 1,
826 /* isSingleIssue */ true,
827 /* breaksGroup */ false,
828 /* numBubbles */ 0,
829
830 /*numSlots*/ 1,
831 /* feasibleSlots[] */ { 0 },
832
833 /*numEntries*/ 5,
834 /* V[] */ {
835 /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
836 { AllIssueSlots.rid, 0, 1 },
837 { AllIssueSlots.rid, 0, 1 },
838 { AllIssueSlots.rid, 0, 1 },
839 /*Cycle E */ { IAlu0.rid, 1, 1 }
840 /*Cycle C */
841 /*Cycle N1*/
842 /*Cycle N1*/
843 /*Cycle N1*/
844 /*Cycle W */
845 }
846};
847
848
849const InstrClassRUsage SparcRUsageDesc[] = {
850 NoneClassRUsage,
851 IEUNClassRUsage,
852 IEU0ClassRUsage,
853 IEU1ClassRUsage,
854 FPMClassRUsage,
855 FPAClassRUsage,
856 CTIClassRUsage,
857 LDClassRUsage,
858 STClassRUsage,
859 SingleClassRUsage
860};
861
862
863//---------------------------------------------------------------------------
864// const InstrIssueDelta SparcInstrIssueDeltas[]
865//
866// Purpose:
867// Changes to issue restrictions information in InstrClassRUsage for
868// instructions that differ from other instructions in their class.
869//---------------------------------------------------------------------------
870
871const InstrIssueDelta SparcInstrIssueDeltas[] = {
872
873 // opCode, isSingleIssue, breaksGroup, numBubbles
874
875 // Special cases for single-issue only
876 // Other single issue cases are below.
877//{ LDDA, true, true, 0 },
878//{ STDA, true, true, 0 },
879//{ LDDF, true, true, 0 },
880//{ LDDFA, true, true, 0 },
881 { ADDC, true, true, 0 },
882 { ADDCcc, true, true, 0 },
883 { SUBC, true, true, 0 },
884 { SUBCcc, true, true, 0 },
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000885//{ LDSTUB, true, true, 0 },
886//{ SWAP, true, true, 0 },
887//{ SWAPA, true, true, 0 },
888//{ CAS, true, true, 0 },
889//{ CASA, true, true, 0 },
890//{ CASX, true, true, 0 },
891//{ CASXA, true, true, 0 },
892//{ LDFSR, true, true, 0 },
893//{ LDFSRA, true, true, 0 },
894//{ LDXFSR, true, true, 0 },
895//{ LDXFSRA, true, true, 0 },
896//{ STFSR, true, true, 0 },
897//{ STFSRA, true, true, 0 },
898//{ STXFSR, true, true, 0 },
899//{ STXFSRA, true, true, 0 },
900//{ SAVED, true, true, 0 },
901//{ RESTORED, true, true, 0 },
902//{ FLUSH, true, true, 9 },
903//{ FLUSHW, true, true, 9 },
904//{ ALIGNADDR, true, true, 0 },
905 { RETURN, true, true, 0 },
906//{ DONE, true, true, 0 },
907//{ RETRY, true, true, 0 },
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000908//{ TCC, true, true, 0 },
909//{ SHUTDOWN, true, true, 0 },
910
911 // Special cases for breaking group *before*
912 // CURRENTLY NOT SUPPORTED!
913 { CALL, false, false, 0 },
Vikram S. Advec1521632001-10-22 13:31:53 +0000914 { JMPLCALL, false, false, 0 },
915 { JMPLRET, false, false, 0 },
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000916
917 // Special cases for breaking the group *after*
918 { MULX, true, true, (4+34)/2 },
919 { FDIVS, false, true, 0 },
920 { FDIVD, false, true, 0 },
921 { FDIVQ, false, true, 0 },
922 { FSQRTS, false, true, 0 },
923 { FSQRTD, false, true, 0 },
924 { FSQRTQ, false, true, 0 },
925//{ FCMP{LE,GT,NE,EQ}, false, true, 0 },
926
927 // Instructions that introduce bubbles
928//{ MULScc, true, true, 2 },
929//{ SMULcc, true, true, (4+18)/2 },
930//{ UMULcc, true, true, (4+19)/2 },
931 { SDIVX, true, true, 68 },
932 { UDIVX, true, true, 68 },
933//{ SDIVcc, true, true, 36 },
934//{ UDIVcc, true, true, 37 },
Vikram S. Adveb7f06f42001-11-04 19:34:49 +0000935 { WRCCR, true, true, 4 },
936//{ WRPR, true, true, 4 },
937//{ RDCCR, true, true, 0 }, // no bubbles after, but see below
938//{ RDPR, true, true, 0 },
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000939};
940
941
942//---------------------------------------------------------------------------
943// const InstrRUsageDelta SparcInstrUsageDeltas[]
944//
945// Purpose:
946// Changes to resource usage information in InstrClassRUsage for
947// instructions that differ from other instructions in their class.
948//---------------------------------------------------------------------------
949
950const InstrRUsageDelta SparcInstrUsageDeltas[] = {
951
952 // MachineOpCode, Resource, Start cycle, Num cycles
953
954 //
955 // JMPL counts as a load/store instruction for issue!
956 //
Vikram S. Advec1521632001-10-22 13:31:53 +0000957 { JMPLCALL, LSIssueSlots.rid, 0, 1 },
958 { JMPLRET, LSIssueSlots.rid, 0, 1 },
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000959
960 //
961 // Many instructions cannot issue for the next 2 cycles after an FCMP
962 // We model that with a fake resource FCMPDelayCycle.
963 //
964 { FCMPS, FCMPDelayCycle.rid, 1, 3 },
965 { FCMPD, FCMPDelayCycle.rid, 1, 3 },
966 { FCMPQ, FCMPDelayCycle.rid, 1, 3 },
967
968 { MULX, FCMPDelayCycle.rid, 1, 1 },
969 { SDIVX, FCMPDelayCycle.rid, 1, 1 },
970 { UDIVX, FCMPDelayCycle.rid, 1, 1 },
971//{ SMULcc, FCMPDelayCycle.rid, 1, 1 },
972//{ UMULcc, FCMPDelayCycle.rid, 1, 1 },
973//{ SDIVcc, FCMPDelayCycle.rid, 1, 1 },
974//{ UDIVcc, FCMPDelayCycle.rid, 1, 1 },
975 { STD, FCMPDelayCycle.rid, 1, 1 },
976 { FMOVRSZ, FCMPDelayCycle.rid, 1, 1 },
977 { FMOVRSLEZ,FCMPDelayCycle.rid, 1, 1 },
978 { FMOVRSLZ, FCMPDelayCycle.rid, 1, 1 },
979 { FMOVRSNZ, FCMPDelayCycle.rid, 1, 1 },
980 { FMOVRSGZ, FCMPDelayCycle.rid, 1, 1 },
981 { FMOVRSGEZ,FCMPDelayCycle.rid, 1, 1 },
982
983 //
984 // Some instructions are stalled in the GROUP stage if a CTI is in
Vikram S. Adveb7f06f42001-11-04 19:34:49 +0000985 // the E or C stage. We model that with a fake resource CTIDelayCycle.
Chris Lattnerc6495ee2001-09-14 03:56:45 +0000986 //
987 { LDD, CTIDelayCycle.rid, 1, 1 },
988//{ LDDA, CTIDelayCycle.rid, 1, 1 },
989//{ LDDSTUB, CTIDelayCycle.rid, 1, 1 },
990//{ LDDSTUBA, CTIDelayCycle.rid, 1, 1 },
991//{ SWAP, CTIDelayCycle.rid, 1, 1 },
992//{ SWAPA, CTIDelayCycle.rid, 1, 1 },
993//{ CAS, CTIDelayCycle.rid, 1, 1 },
994//{ CASA, CTIDelayCycle.rid, 1, 1 },
995//{ CASX, CTIDelayCycle.rid, 1, 1 },
996//{ CASXA, CTIDelayCycle.rid, 1, 1 },
997
998 //
999 // Signed int loads of less than dword size return data in cycle N1 (not C)
1000 // and put all loads in consecutive cycles into delayed load return mode.
1001 //
1002 { LDSB, LdReturn.rid, 2, -1 },
1003 { LDSB, LdReturn.rid, 3, 1 },
1004
1005 { LDSH, LdReturn.rid, 2, -1 },
1006 { LDSH, LdReturn.rid, 3, 1 },
1007
1008 { LDSW, LdReturn.rid, 2, -1 },
1009 { LDSW, LdReturn.rid, 3, 1 },
1010
Vikram S. Adveb7f06f42001-11-04 19:34:49 +00001011 //
1012 // RDPR from certain registers and RD from any register are not dispatchable
1013 // until four clocks after they reach the head of the instr. buffer.
1014 // Together with their single-issue requirement, this means all four issue
1015 // slots are effectively blocked for those cycles, plus the issue cycle.
1016 // This does not increase the latency of the instruction itself.
1017 //
1018 { RDCCR, AllIssueSlots.rid, 0, 5 },
1019 { RDCCR, AllIssueSlots.rid, 0, 5 },
1020 { RDCCR, AllIssueSlots.rid, 0, 5 },
1021 { RDCCR, AllIssueSlots.rid, 0, 5 },
Chris Lattnerc6495ee2001-09-14 03:56:45 +00001022
1023#undef EXPLICIT_BUBBLES_NEEDED
1024#ifdef EXPLICIT_BUBBLES_NEEDED
1025 //
1026 // MULScc inserts one bubble.
1027 // This means it breaks the current group (captured in UltraSparcSchedInfo)
1028 // *and occupies all issue slots for the next cycle
1029 //
1030//{ MULScc, AllIssueSlots.rid, 2, 2-1 },
1031//{ MULScc, AllIssueSlots.rid, 2, 2-1 },
1032//{ MULScc, AllIssueSlots.rid, 2, 2-1 },
1033//{ MULScc, AllIssueSlots.rid, 2, 2-1 },
1034
1035 //
1036 // SMULcc inserts between 4 and 18 bubbles, depending on #leading 0s in rs1.
1037 // We just model this with a simple average.
1038 //
1039//{ SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 },
1040//{ SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 },
1041//{ SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 },
1042//{ SMULcc, AllIssueSlots.rid, 2, ((4+18)/2)-1 },
1043
1044 // SMULcc inserts between 4 and 19 bubbles, depending on #leading 0s in rs1.
1045//{ UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 },
1046//{ UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 },
1047//{ UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 },
1048//{ UMULcc, AllIssueSlots.rid, 2, ((4+19)/2)-1 },
1049
1050 //
1051 // MULX inserts between 4 and 34 bubbles, depending on #leading 0s in rs1.
1052 //
1053 { MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 },
1054 { MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 },
1055 { MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 },
1056 { MULX, AllIssueSlots.rid, 2, ((4+34)/2)-1 },
1057
1058 //
1059 // SDIVcc inserts 36 bubbles.
1060 //
1061//{ SDIVcc, AllIssueSlots.rid, 2, 36-1 },
1062//{ SDIVcc, AllIssueSlots.rid, 2, 36-1 },
1063//{ SDIVcc, AllIssueSlots.rid, 2, 36-1 },
1064//{ SDIVcc, AllIssueSlots.rid, 2, 36-1 },
1065
1066 // UDIVcc inserts 37 bubbles.
1067//{ UDIVcc, AllIssueSlots.rid, 2, 37-1 },
1068//{ UDIVcc, AllIssueSlots.rid, 2, 37-1 },
1069//{ UDIVcc, AllIssueSlots.rid, 2, 37-1 },
1070//{ UDIVcc, AllIssueSlots.rid, 2, 37-1 },
1071
1072 //
1073 // SDIVX inserts 68 bubbles.
1074 //
1075 { SDIVX, AllIssueSlots.rid, 2, 68-1 },
1076 { SDIVX, AllIssueSlots.rid, 2, 68-1 },
1077 { SDIVX, AllIssueSlots.rid, 2, 68-1 },
1078 { SDIVX, AllIssueSlots.rid, 2, 68-1 },
1079
1080 //
1081 // UDIVX inserts 68 bubbles.
1082 //
1083 { UDIVX, AllIssueSlots.rid, 2, 68-1 },
1084 { UDIVX, AllIssueSlots.rid, 2, 68-1 },
1085 { UDIVX, AllIssueSlots.rid, 2, 68-1 },
1086 { UDIVX, AllIssueSlots.rid, 2, 68-1 },
1087
1088 //
1089 // WR inserts 4 bubbles.
1090 //
1091//{ WR, AllIssueSlots.rid, 2, 68-1 },
1092//{ WR, AllIssueSlots.rid, 2, 68-1 },
1093//{ WR, AllIssueSlots.rid, 2, 68-1 },
1094//{ WR, AllIssueSlots.rid, 2, 68-1 },
1095
1096 //
1097 // WRPR inserts 4 bubbles.
1098 //
1099//{ WRPR, AllIssueSlots.rid, 2, 68-1 },
1100//{ WRPR, AllIssueSlots.rid, 2, 68-1 },
1101//{ WRPR, AllIssueSlots.rid, 2, 68-1 },
1102//{ WRPR, AllIssueSlots.rid, 2, 68-1 },
1103
1104 //
1105 // DONE inserts 9 bubbles.
1106 //
1107//{ DONE, AllIssueSlots.rid, 2, 9-1 },
1108//{ DONE, AllIssueSlots.rid, 2, 9-1 },
1109//{ DONE, AllIssueSlots.rid, 2, 9-1 },
1110//{ DONE, AllIssueSlots.rid, 2, 9-1 },
1111
1112 //
1113 // RETRY inserts 9 bubbles.
1114 //
1115//{ RETRY, AllIssueSlots.rid, 2, 9-1 },
1116//{ RETRY, AllIssueSlots.rid, 2, 9-1 },
1117//{ RETRY, AllIssueSlots.rid, 2, 9-1 },
1118//{ RETRY, AllIssueSlots.rid, 2, 9-1 },
1119
Chris Lattnere369fcb2001-10-13 06:54:54 +00001120#endif /*EXPLICIT_BUBBLES_NEEDED */
Chris Lattnerc6495ee2001-09-14 03:56:45 +00001121};
1122
1123
1124
1125// Additional delays to be captured in code:
1126// 1. RDPR from several state registers (page 349)
1127// 2. RD from *any* register (page 349)
1128// 3. Writes to TICK, PSTATE, TL registers and FLUSH{W} instr (page 349)
1129// 4. Integer store can be in same group as instr producing value to store.
1130// 5. BICC and BPICC can be in the same group as instr producing CC (pg 350)
1131// 6. FMOVr cannot be in the same or next group as an IEU instr (pg 351).
1132// 7. The second instr. of a CTI group inserts 9 bubbles (pg 351)
1133// 8. WR{PR}, SVAE, SAVED, RESTORE, RESTORED, RETURN, RETRY, and DONE that
1134// follow an annulling branch cannot be issued in the same group or in
1135// the 3 groups following the branch.
1136// 9. A predicted annulled load does not stall dependent instructions.
1137// Other annulled delay slot instructions *do* stall dependents, so
1138// nothing special needs to be done for them during scheduling.
1139//10. Do not put a load use that may be annulled in the same group as the
1140// branch. The group will stall until the load returns.
1141//11. Single-prec. FP loads lock 2 registers, for dependency checking.
1142//
1143//
1144// Additional delays we cannot or will not capture:
1145// 1. If DCTI is last word of cache line, it is delayed until next line can be
1146// fetched. Also, other DCTI alignment-related delays (pg 352)
1147// 2. Load-after-store is delayed by 7 extra cycles if load hits in D-Cache.
1148// Also, several other store-load and load-store conflicts (pg 358)
1149// 3. MEMBAR, LD{X}FSR, LDD{A} and a bunch of other load stalls (pg 358)
1150// 4. There can be at most 8 outstanding buffered store instructions
1151// (including some others like MEMBAR, LDSTUB, CAS{AX}, and FLUSH)
1152
1153
1154
1155//---------------------------------------------------------------------------
1156// class UltraSparcSchedInfo
1157//
1158// Purpose:
1159// Interface to instruction scheduling information for UltraSPARC.
1160// The parameter values above are based on UltraSPARC IIi.
1161//---------------------------------------------------------------------------
1162
1163
1164class UltraSparcSchedInfo: public MachineSchedInfo {
1165public:
Vikram S. Adve7f37fe52001-11-08 04:55:13 +00001166 /*ctor*/ UltraSparcSchedInfo (const TargetMachine& tgt);
Chris Lattnerc6495ee2001-09-14 03:56:45 +00001167 /*dtor*/ virtual ~UltraSparcSchedInfo () {}
1168protected:
1169 virtual void initializeResources ();
1170};
1171
Chris Lattnerf6e0e282001-09-14 04:32:55 +00001172
1173//---------------------------------------------------------------------------
Vikram S. Advec1521632001-10-22 13:31:53 +00001174// class UltraSparcFrameInfo
1175//
1176// Purpose:
1177// Interface to stack frame layout info for the UltraSPARC.
Vikram S. Advec1521632001-10-22 13:31:53 +00001178//---------------------------------------------------------------------------
1179
Vikram S. Adve7f37fe52001-11-08 04:55:13 +00001180class UltraSparcFrameInfo: public MachineFrameInfo {
Vikram S. Advec1521632001-10-22 13:31:53 +00001181public:
Vikram S. Adve7f37fe52001-11-08 04:55:13 +00001182 /*ctor*/ UltraSparcFrameInfo(const TargetMachine& tgt) : MachineFrameInfo(tgt) {}
1183
1184public:
1185 int getStackFrameSizeAlignment () const { return StackFrameSizeAlignment;}
1186 int getMinStackFrameSize () const { return MinStackFrameSize; }
1187 int getNumFixedOutgoingArgs () const { return NumFixedOutgoingArgs; }
1188 int getSizeOfEachArgOnStack () const { return SizeOfEachArgOnStack; }
1189 bool argsOnStackHaveFixedSize () const { return true; }
1190
1191 //
1192 // These methods compute offsets using the frame contents for a
1193 // particular method. The frame contents are obtained from the
1194 // MachineCodeInfoForMethod object for the given method.
1195 //
1196 int getFirstIncomingArgOffset (MachineCodeForMethod& mcInfo,
1197 bool& pos) const
1198 {
1199 pos = true; // arguments area grows upwards
1200 return FirstIncomingArgOffsetFromFP;
1201 }
1202 int getFirstOutgoingArgOffset (MachineCodeForMethod& mcInfo,
1203 bool& pos) const
1204 {
1205 pos = true; // arguments area grows upwards
1206 return FirstOutgoingArgOffsetFromSP;
1207 }
1208 int getFirstOptionalOutgoingArgOffset(MachineCodeForMethod& mcInfo,
1209 bool& pos)const
1210 {
1211 pos = true; // arguments area grows upwards
1212 return FirstOptionalOutgoingArgOffsetFromSP;
1213 }
1214
1215 int getFirstAutomaticVarOffset (MachineCodeForMethod& mcInfo,
1216 bool& pos) const;
1217 int getRegSpillAreaOffset (MachineCodeForMethod& mcInfo,
1218 bool& pos) const;
1219 int getTmpAreaOffset (MachineCodeForMethod& mcInfo,
1220 bool& pos) const;
1221 int getDynamicAreaOffset (MachineCodeForMethod& mcInfo,
1222 bool& pos) const;
1223
1224 //
1225 // These methods specify the base register used for each stack area
1226 // (generally FP or SP)
1227 //
1228 virtual int getIncomingArgBaseRegNum() const {
1229 return (int) target.getRegInfo().getFramePointer();
1230 }
1231 virtual int getOutgoingArgBaseRegNum() const {
1232 return (int) target.getRegInfo().getStackPointer();
1233 }
1234 virtual int getOptionalOutgoingArgBaseRegNum() const {
1235 return (int) target.getRegInfo().getStackPointer();
1236 }
1237 virtual int getAutomaticVarBaseRegNum() const {
1238 return (int) target.getRegInfo().getFramePointer();
1239 }
1240 virtual int getRegSpillAreaBaseRegNum() const {
1241 return (int) target.getRegInfo().getFramePointer();
1242 }
1243 virtual int getDynamicAreaBaseRegNum() const {
1244 return (int) target.getRegInfo().getStackPointer();
1245 }
1246
1247private:
Vikram S. Adve5afff3b2001-11-09 02:15:52 +00001248 // All stack addresses must be offset by 0x7ff (2047) on Sparc V9.
1249 static const int OFFSET = (int) 0x7ff;
Vikram S. Adve7f37fe52001-11-08 04:55:13 +00001250 static const int StackFrameSizeAlignment = 16;
Vikram S. Advec1521632001-10-22 13:31:53 +00001251 static const int MinStackFrameSize = 176;
Vikram S. Adve7f37fe52001-11-08 04:55:13 +00001252 static const int NumFixedOutgoingArgs = 6;
1253 static const int SizeOfEachArgOnStack = 8;
Vikram S. Adve5afff3b2001-11-09 02:15:52 +00001254 static const int StaticAreaOffsetFromFP = -1 + OFFSET;
1255 static const int FirstIncomingArgOffsetFromFP = 128 + OFFSET;
1256 static const int FirstOptionalIncomingArgOffsetFromFP = 176 + OFFSET;
1257 static const int FirstOutgoingArgOffsetFromSP = 128 + OFFSET;
1258 static const int FirstOptionalOutgoingArgOffsetFromSP = 176 + OFFSET;
Vikram S. Advec1521632001-10-22 13:31:53 +00001259};
1260
1261
Vikram S. Adve5afff3b2001-11-09 02:15:52 +00001262//---------------------------------------------------------------------------
1263// class UltraSparcCacheInfo
1264//
1265// Purpose:
1266// Interface to cache parameters for the UltraSPARC.
1267// Just use defaults for now.
1268//---------------------------------------------------------------------------
1269
1270class UltraSparcCacheInfo: public MachineCacheInfo {
1271public:
1272 /*ctor*/ UltraSparcCacheInfo (const TargetMachine& target) :
1273 MachineCacheInfo(target) {}
1274};
1275
Vikram S. Advec1521632001-10-22 13:31:53 +00001276
1277//---------------------------------------------------------------------------
Chris Lattnerf6e0e282001-09-14 04:32:55 +00001278// class UltraSparcMachine
1279//
1280// Purpose:
1281// Primary interface to machine description for the UltraSPARC.
1282// Primarily just initializes machine-dependent parameters in
1283// class TargetMachine, and creates machine-dependent subclasses
Vikram S. Adve339084b2001-09-18 13:04:24 +00001284// for classes such as InstrInfo, SchedInfo and RegInfo.
Chris Lattnerf6e0e282001-09-14 04:32:55 +00001285//---------------------------------------------------------------------------
1286
1287class UltraSparc : public TargetMachine {
Vikram S. Adve339084b2001-09-18 13:04:24 +00001288private:
1289 UltraSparcInstrInfo instrInfo;
1290 UltraSparcSchedInfo schedInfo;
1291 UltraSparcRegInfo regInfo;
Vikram S. Advec1521632001-10-22 13:31:53 +00001292 UltraSparcFrameInfo frameInfo;
Vikram S. Adve5afff3b2001-11-09 02:15:52 +00001293 UltraSparcCacheInfo cacheInfo;
Chris Lattnerf6e0e282001-09-14 04:32:55 +00001294public:
1295 UltraSparc();
1296 virtual ~UltraSparc() {}
Vikram S. Adve339084b2001-09-18 13:04:24 +00001297
Chris Lattner32f600a2001-09-19 13:47:12 +00001298 virtual const MachineInstrInfo &getInstrInfo() const { return instrInfo; }
1299 virtual const MachineSchedInfo &getSchedInfo() const { return schedInfo; }
1300 virtual const MachineRegInfo &getRegInfo() const { return regInfo; }
Vikram S. Adve7f37fe52001-11-08 04:55:13 +00001301 virtual const MachineFrameInfo &getFrameInfo() const { return frameInfo; }
Vikram S. Adve5afff3b2001-11-09 02:15:52 +00001302 virtual const MachineCacheInfo &getCacheInfo() const { return cacheInfo; }
Vikram S. Adve339084b2001-09-18 13:04:24 +00001303
Chris Lattnerf6e0e282001-09-14 04:32:55 +00001304 // compileMethod - For the sparc, we do instruction selection, followed by
1305 // delay slot scheduling, then register allocation.
1306 //
1307 virtual bool compileMethod(Method *M);
Chris Lattner32f600a2001-09-19 13:47:12 +00001308
1309 //
1310 // emitAssembly - Output assembly language code (a .s file) for the specified
1311 // module. The specified module must have been compiled before this may be
1312 // used.
1313 //
Chris Lattnerec0a95f2001-10-15 15:54:43 +00001314 virtual void emitAssembly(const Module *M, ostream &OutStr) const;
Chris Lattnerf6e0e282001-09-14 04:32:55 +00001315};
1316
1317
Chris Lattnerc6495ee2001-09-14 03:56:45 +00001318#endif