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