Implement new method by method assembly output & memory releasing
[oota-llvm.git] / lib / Target / SparcV9 / SparcV9Internals.h
1 // $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
11
12 #ifndef SPARC_INTERNALS_H
13 #define SPARC_INTERNALS_H
14
15
16 #include "SparcRegClassInfo.h"
17 #include "llvm/Target/TargetMachine.h"
18 #include "llvm/Target/MachineInstrInfo.h"
19 #include "llvm/Target/MachineSchedInfo.h"
20 #include "llvm/Target/MachineFrameInfo.h"
21 #include "llvm/Target/MachineCacheInfo.h"
22 #include "llvm/CodeGen/RegClass.h"
23 #include "llvm/Type.h"
24
25 #include <sys/types.h>
26
27 class UltraSparc;
28
29 // OpCodeMask definitions for the Sparc V9
30 // 
31 const OpCodeMask        Immed           = 0x00002000; // immed or reg operand?
32 const OpCodeMask        Annul           = 0x20000000; // annul delay instr?
33 const OpCodeMask        PredictTaken    = 0x00080000; // predict branch taken?
34
35
36 enum 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
52
53 //---------------------------------------------------------------------------
54 // enum SparcMachineOpCode. 
55 // const MachineInstrDescriptor SparcMachineInstrDesc[]
56 // 
57 // Purpose:
58 //   Description of UltraSparc machine instructions.
59 // 
60 //---------------------------------------------------------------------------
61
62 enum SparcMachineOpCode {
63 #define I(ENUM, OPCODESTRING, NUMOPERANDS, RESULTPOS, MAXIMM, IMMSE, \
64           NUMDELAYSLOTS, LATENCY, SCHEDCLASS, INSTFLAGS)             \
65    ENUM,
66 #include "SparcInstr.def"
67
68   // End-of-array marker
69   INVALID_OPCODE,
70   NUM_REAL_OPCODES = PHI,               // number of valid opcodes
71   NUM_TOTAL_OPCODES = INVALID_OPCODE
72 };
73
74
75 // Array of machine instruction descriptions...
76 extern const MachineInstrDescriptor SparcMachineInstrDesc[];
77
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
89 class UltraSparcInstrInfo : public MachineInstrInfo {
90 public:
91   /*ctor*/      UltraSparcInstrInfo(const TargetMachine& tgt);
92
93   //
94   // All immediate constants are in position 0 except the
95   // store instructions.
96   // 
97   virtual int getImmmedConstantPos(MachineOpCode opCode) const {
98     bool ignore;
99     if (this->maxImmedConstant(opCode, ignore) != 0)
100       {
101         assert(! this->isStore((MachineOpCode) STB - 1)); // first store is STB
102         assert(! this->isStore((MachineOpCode) STD + 1)); // last  store is STD
103         return (opCode >= STB || opCode <= STD)? 2 : 1;
104       }
105     else
106       return -1;
107   }
108   
109   virtual bool          hasResultInterlock      (MachineOpCode opCode) const
110   {
111     // All UltraSPARC instructions have interlocks (note that delay slots
112     // are not considered here).
113     // However, instructions that use the result of an FCMP produce a
114     // 9-cycle stall if they are issued less than 3 cycles after the FCMP.
115     // Force the compiler to insert a software interlock (i.e., gap of
116     // 2 other groups, including NOPs if necessary).
117     return (opCode == FCMPS || opCode == FCMPD || opCode == FCMPQ);
118   }
119
120   //-------------------------------------------------------------------------
121   // Code generation support for creating individual machine instructions
122   //-------------------------------------------------------------------------
123   
124   // Create an instruction sequence to put the constant `val' into
125   // the virtual register `dest'.  The generated instructions are
126   // returned in `minstrVec'.  Any temporary registers (TmpInstruction)
127   // created are returned in `tempVec'.
128   // 
129   virtual void  CreateCodeToLoadConst(Value* val,
130                                       Instruction* dest,
131                                       std::vector<MachineInstr*>& minstrVec,
132                                       std::vector<TmpInstruction*>& tmp) const;
133
134   
135   // Create an instruction sequence to copy an integer value `val'
136   // to a floating point value `dest' by copying to memory and back.
137   // val must be an integral type.  dest must be a Float or Double.
138   // The generated instructions are returned in `minstrVec'.
139   // Any temp. registers (TmpInstruction) created are returned in `tempVec'.
140   // 
141   virtual void  CreateCodeToCopyIntToFloat(Method* method,
142                                            Value* val,
143                                            Instruction* dest,
144                                            std::vector<MachineInstr*>& minstr,
145                                            std::vector<TmpInstruction*>& temp,
146                                            TargetMachine& target) const;
147
148   // Similarly, create an instruction sequence to copy an FP value
149   // `val' to an integer value `dest' by copying to memory and back.
150   // See the previous function for information about return values.
151   // 
152   virtual void  CreateCodeToCopyFloatToInt(Method* method,
153                                            Value* val,
154                                            Instruction* dest,
155                                            std::vector<MachineInstr*>& minstr,
156                                            std::vector<TmpInstruction*>& temp,
157                                            TargetMachine& target) const;
158
159  // create copy instruction(s)
160   virtual void
161   CreateCopyInstructionsByType(const TargetMachine& target,
162                              Value* src,
163                              Instruction* dest,
164                              std::vector<MachineInstr*>& minstr) const;
165
166
167 };
168
169
170 //----------------------------------------------------------------------------
171 // class UltraSparcRegInfo
172 //
173 // This class implements the virtual class MachineRegInfo for Sparc.
174 //
175 //----------------------------------------------------------------------------
176
177
178 class LiveRange;
179 class UltraSparc;
180 class PhyRegAlloc;
181
182
183 class UltraSparcRegInfo : public MachineRegInfo
184 {
185  private:
186
187   // The actual register classes in the Sparc
188   //
189   enum RegClassIDs { 
190     IntRegClassID,                      // Integer
191     FloatRegClassID,                    // Float (both single/double)
192     IntCCRegClassID,                    // Int Condition Code
193     FloatCCRegClassID                   // Float Condition code
194   };
195
196
197   // Type of registers available in Sparc. There can be several reg types
198   // in the same class. For instace, the float reg class has Single/Double
199   // types
200   //
201   enum RegTypes {
202     IntRegType,
203     FPSingleRegType,
204     FPDoubleRegType,
205     IntCCRegType,
206     FloatCCRegType
207   };
208
209   // **** WARNING: If the above enum order is changed, also modify 
210   // getRegisterClassOfValue method below since it assumes this particular 
211   // order for efficiency.
212
213
214   // reverse pointer to get info about the ultra sparc machine
215   //
216   const UltraSparc *const UltraSparcInfo;
217
218   // Number of registers used for passing int args (usually 6: %o0 - %o5)
219   //
220   unsigned const NumOfIntArgRegs;
221
222   // Number of registers used for passing float args (usually 32: %f0 - %f31)
223   //
224   unsigned const NumOfFloatArgRegs;
225
226   // An out of bound register number that can be used to initialize register
227   // numbers. Useful for error detection.
228   //
229   int const InvalidRegNum;
230
231
232   // ========================  Private Methods =============================
233
234   // The following methods are used to color special live ranges (e.g.
235   // method args and return values etc.) with specific hardware registers
236   // as required. See SparcRegInfo.cpp for the implementation.
237   //
238   void setCallOrRetArgCol(LiveRange *const LR, const unsigned RegNo,
239                          const MachineInstr *MI,AddedInstrMapType &AIMap)const;
240
241   MachineInstr * getCopy2RegMI(const Value *SrcVal, const unsigned Reg,
242                                unsigned RegClassID) const ;
243
244   void suggestReg4RetAddr(const MachineInstr * RetMI, 
245                           LiveRangeInfo& LRI) const;
246
247   void suggestReg4CallAddr(const MachineInstr * CallMI, LiveRangeInfo& LRI,
248                            std::vector<RegClass *> RCList) const;
249
250
251
252   // The following methods are used to find the addresses etc. contained
253   // in specail machine instructions like CALL/RET
254   //
255   Value *getValue4ReturnAddr( const MachineInstr * MInst ) const ;
256   const Value *getCallInstRetAddr(const MachineInstr *CallMI) const;
257   const unsigned getCallInstNumArgs(const MachineInstr *CallMI) const;
258
259
260   // The following 3  methods are used to find the RegType (see enum above)
261   // of a LiveRange, Value and using the unified RegClassID
262
263   int getRegType(const LiveRange *const LR) const {
264
265     unsigned Typ;
266
267     switch(  (LR->getRegClass())->getID() ) {
268
269     case IntRegClassID: return IntRegType; 
270
271     case FloatRegClassID: 
272                           Typ =  LR->getTypeID();
273                           if( Typ == Type::FloatTyID ) 
274                             return FPSingleRegType;
275                           else if( Typ == Type::DoubleTyID )
276                             return FPDoubleRegType;
277                           else assert(0 && "Unknown type in FloatRegClass");
278
279     case IntCCRegClassID: return IntCCRegType; 
280       
281     case FloatCCRegClassID: return FloatCCRegType ; 
282
283     default: assert( 0 && "Unknown reg class ID");
284       return 0;
285     }
286   }
287
288
289   int getRegType(const Value *const Val) const {
290
291     unsigned Typ;
292
293     switch( getRegClassIDOfValue(Val)  ) {
294
295     case IntRegClassID: return IntRegType; 
296
297     case FloatRegClassID: 
298                           Typ =  (Val->getType())->getPrimitiveID();
299                           if( Typ == Type::FloatTyID ) 
300                             return FPSingleRegType;
301                           else if( Typ == Type::DoubleTyID )
302                             return FPDoubleRegType;
303                           else assert(0 && "Unknown type in FloatRegClass");
304
305     case IntCCRegClassID: return IntCCRegType; 
306       
307     case FloatCCRegClassID: return FloatCCRegType ; 
308
309     default: assert( 0 && "Unknown reg class ID");
310       return 0;
311     }
312
313   }
314
315
316   int getRegType(int reg) const {
317     if( reg < 32 ) 
318       return IntRegType;
319     else if ( reg < (32 + 32) )
320       return FPSingleRegType;
321     else if ( reg < (64 + 32) )
322       return FPDoubleRegType;
323     else if( reg < (64+32+4) )
324       return FloatCCRegType;
325     else if( reg < (64+32+4+2) )  
326       return IntCCRegType;             
327     else 
328       assert(0 && "Invalid register number in getRegType");
329   }
330
331
332
333
334   // The following methods are used to generate copy instructions to move
335   // data between condition code registers
336   //
337   MachineInstr * cpCCR2IntMI(const unsigned IntReg) const;
338   MachineInstr * cpInt2CCRMI(const unsigned IntReg) const;
339
340   // Used to generate a copy instruction based on the register class of
341   // value.
342   //
343   MachineInstr * cpValue2RegMI(Value * Val,  const unsigned DestReg,
344                                const int RegType) const;
345
346
347   // The following 2 methods are used to order the instructions addeed by
348   // the register allocator in association with method calling. See
349   // SparcRegInfo.cpp for more details
350   //
351   void moveInst2OrdVec(std::vector<MachineInstr *> &OrdVec,
352                        MachineInstr *UnordInst,
353                        PhyRegAlloc &PRA) const;
354
355   void OrderAddedInstrns(std::vector<MachineInstr *> &UnordVec, 
356                          std::vector<MachineInstr *> &OrdVec,
357                          PhyRegAlloc &PRA) const;
358
359
360   // To find whether a particular call is to a var arg method
361   //
362   bool isVarArgCall(const MachineInstr *CallMI) const;
363
364
365
366  public:
367
368   // constructor
369   //
370   UltraSparcRegInfo(const TargetMachine& tgt ) :    
371     MachineRegInfo(tgt),
372     UltraSparcInfo(& (const UltraSparc&) tgt), 
373     NumOfIntArgRegs(6), 
374     NumOfFloatArgRegs(32),
375     InvalidRegNum(1000) {
376    
377     MachineRegClassArr.push_back( new SparcIntRegClass(IntRegClassID) );
378     MachineRegClassArr.push_back( new SparcFloatRegClass(FloatRegClassID) );
379     MachineRegClassArr.push_back( new SparcIntCCRegClass(IntCCRegClassID) );
380     MachineRegClassArr.push_back( new SparcFloatCCRegClass(FloatCCRegClassID));
381
382     assert( SparcFloatRegOrder::StartOfNonVolatileRegs == 32 && 
383             "32 Float regs are used for float arg passing");
384
385   }
386
387
388   ~UltraSparcRegInfo(void) { }          // empty destructor 
389
390
391   // To get complete machine information structure using the machine register
392   // information
393   //
394   inline const UltraSparc & getUltraSparcInfo() const { 
395     return *UltraSparcInfo;
396   }
397
398
399   // To find the register class of a Value
400   //
401   inline unsigned getRegClassIDOfValue (const Value *const Val,
402                                  bool isCCReg = false) const {
403
404     Type::PrimitiveID ty = (Val->getType())->getPrimitiveID();
405
406     unsigned res;
407     
408     if( (ty && ty <= Type::LongTyID) || (ty == Type::LabelTyID) ||
409         (ty == Type::MethodTyID) ||  (ty == Type::PointerTyID) )
410       res =  IntRegClassID;             // sparc int reg (ty=0: void)
411     else if( ty <= Type::DoubleTyID)
412       res = FloatRegClassID;           // sparc float reg class
413     else { 
414       std::cerr << "TypeID: " << ty << "\n";
415       assert(0 && "Cannot resolve register class for type");
416       return 0;
417     }
418
419     if(isCCReg)
420       return res + 2;      // corresponidng condition code regiser 
421     else 
422       return res;
423   }
424
425
426
427   // returns the register that contains always zero
428   // this is the unified register number
429   //
430   inline int getZeroRegNum() const { return SparcIntRegOrder::g0; }
431
432   // returns the reg used for pushing the address when a method is called.
433   // This can be used for other purposes between calls
434   //
435   unsigned getCallAddressReg() const  { return SparcIntRegOrder::o7; }
436
437   // Returns the register containing the return address.
438   // It should be made sure that this  register contains the return 
439   // value when a return instruction is reached.
440   //
441   unsigned getReturnAddressReg()  const { return SparcIntRegOrder::i7; }
442
443
444
445   // The following methods are used to color special live ranges (e.g.
446   // method args and return values etc.) with specific hardware registers
447   // as required. See SparcRegInfo.cpp for the implementation for Sparc.
448   //
449   void suggestRegs4MethodArgs(const Method *const Meth, 
450                               LiveRangeInfo& LRI) const;
451
452   void suggestRegs4CallArgs(const MachineInstr *const CallMI, 
453                             LiveRangeInfo& LRI,
454                             std::vector<RegClass *> RCL) const; 
455
456   void suggestReg4RetValue(const MachineInstr *const RetMI, 
457                            LiveRangeInfo& LRI) const;
458
459
460   void colorMethodArgs(const Method *const Meth,  LiveRangeInfo& LRI,
461                        AddedInstrns *const FirstAI) const;
462
463   void colorCallArgs(const MachineInstr *const CallMI, LiveRangeInfo& LRI,
464                      AddedInstrns *const CallAI,  PhyRegAlloc &PRA,
465                      const BasicBlock *BB) const;
466
467   void colorRetValue(const MachineInstr *const RetI,   LiveRangeInfo& LRI,
468                      AddedInstrns *const RetAI) const;
469
470
471
472   // method used for printing a register for debugging purposes
473   //
474   static void printReg(const LiveRange *const LR)  ;
475
476   // this method provides a unique number for each register 
477   //
478   inline int getUnifiedRegNum(int RegClassID, int reg) const {
479
480     if( RegClassID == IntRegClassID && reg < 32 ) 
481       return reg;
482     else if ( RegClassID == FloatRegClassID && reg < 64)
483       return reg + 32;                  // we have 32 int regs
484     else if( RegClassID == FloatCCRegClassID && reg < 4)
485       return reg + 32 + 64;             // 32 int, 64 float
486     else if( RegClassID == IntCCRegClassID ) 
487       return 4+ 32 + 64;                // only int cc reg
488     else if (reg==InvalidRegNum)                
489       return InvalidRegNum;
490     else  
491       assert(0 && "Invalid register class or reg number");
492     return 0;
493   }
494
495   // given the unified register number, this gives the name
496   // for generating assembly code or debugging.
497   //
498   inline const std::string getUnifiedRegName(int reg) const {
499     if( reg < 32 ) 
500       return SparcIntRegOrder::getRegName(reg);
501     else if ( reg < (64 + 32) )
502       return SparcFloatRegOrder::getRegName( reg  - 32);                  
503     else if( reg < (64+32+4) )
504       return SparcFloatCCRegOrder::getRegName( reg -32 - 64);
505     else if( reg < (64+32+4+2) )    // two names: %xcc and %ccr
506       return SparcIntCCRegOrder::getRegName( reg -32 - 64 - 4);             
507     else if (reg== InvalidRegNum)       //****** TODO: Remove */
508       return "<*NoReg*>";
509     else 
510       assert(0 && "Invalid register number");
511     return "";
512   }
513
514
515
516   // The fllowing methods are used by instruction selection
517   //
518   inline unsigned getRegNumInCallersWindow(int reg) {
519     if (reg == InvalidRegNum || reg >= 32)
520       return reg;
521     return SparcIntRegOrder::getRegNumInCallersWindow(reg);
522   }
523   
524   inline bool mustBeRemappedInCallersWindow(int reg) {
525     return (reg != InvalidRegNum && reg < 32);
526   }
527   
528
529
530   // returns the # of bytes of stack space allocated for each register
531   // type. For Sparc, currently we allocate 8 bytes on stack for all 
532   // register types. We can optimize this later if necessary to save stack
533   // space (However, should make sure that stack alignment is correct)
534   //
535   inline int getSpilledRegSize(const int RegType) const {
536     return 8;
537   }
538
539
540   // To obtain the return value contained in a CALL machine instruction
541   //
542   const Value * getCallInstRetVal(const MachineInstr *CallMI) const;
543
544
545   // The following methods are used to generate "copy" machine instructions
546   // for an architecture.
547   //
548   MachineInstr * cpReg2RegMI(const unsigned SrcReg, const unsigned DestReg,
549                              const int RegType) const;
550
551   MachineInstr * cpReg2MemMI(const unsigned SrcReg,  const unsigned DestPtrReg,
552                              const int Offset, const int RegType) const;
553
554   MachineInstr * cpMem2RegMI(const unsigned SrcPtrReg, const int Offset,
555                              const unsigned DestReg, const int RegType) const;
556
557   MachineInstr* cpValue2Value(Value *Src, Value *Dest) const;
558
559
560   // To see whether a register is a volatile (i.e., whehter it must be
561   // preserved acorss calls)
562   //
563   inline bool isRegVolatile(const int RegClassID, const int Reg) const {
564     return  (MachineRegClassArr[RegClassID])->isRegVolatile(Reg);
565   }
566
567
568   inline unsigned getFramePointer() const {
569     return SparcIntRegOrder::i6;
570   }
571
572   inline unsigned getStackPointer() const {
573     return SparcIntRegOrder::o6;
574   }
575
576   inline int getInvalidRegNum() const {
577     return InvalidRegNum;
578   }
579
580
581
582   // This method inserts the caller saving code for call instructions
583   //
584   void insertCallerSavingCode(const MachineInstr *MInst, 
585                               const BasicBlock *BB, PhyRegAlloc &PRA ) const;
586
587 };
588
589
590
591 /*---------------------------------------------------------------------------
592 Scheduling guidelines for SPARC IIi:
593
594 I-Cache alignment rules (pg 326)
595 -- Align a branch target instruction so that it's entire group is within
596    the same cache line (may be 1-4 instructions).
597 ** Don't let a branch that is predicted taken be the last instruction
598    on an I-cache line: delay slot will need an entire line to be fetched
599 -- Make a FP instruction or a branch be the 4th instruction in a group.
600    For branches, there are tradeoffs in reordering to make this happen
601    (see pg. 327).
602 ** Don't put a branch in a group that crosses a 32-byte boundary!
603    An artificial branch is inserted after every 32 bytes, and having
604    another branch will force the group to be broken into 2 groups. 
605
606 iTLB rules:
607 -- Don't let a loop span two memory pages, if possible
608
609 Branch prediction performance:
610 -- Don't make the branch in a delay slot the target of a branch
611 -- Try not to have 2 predicted branches within a group of 4 instructions
612    (because each such group has a single branch target field).
613 -- Try to align branches in slots 0, 2, 4 or 6 of a cache line (to avoid
614    the wrong prediction bits being used in some cases).
615
616 D-Cache timing constraints:
617 -- Signed int loads of less than 64 bits have 3 cycle latency, not 2
618 -- All other loads that hit in D-Cache have 2 cycle latency
619 -- All loads are returned IN ORDER, so a D-Cache miss will delay a later hit
620 -- Mis-aligned loads or stores cause a trap.  In particular, replace
621    mis-aligned FP double precision l/s with 2 single-precision l/s.
622 -- Simulations of integer codes show increase in avg. group size of
623    33% when code (including esp. non-faulting loads) is moved across
624    one branch, and 50% across 2 branches.
625
626 E-Cache timing constraints:
627 -- Scheduling for E-cache (D-Cache misses) is effective (due to load buffering)
628
629 Store buffer timing constraints:
630 -- Stores can be executed in same cycle as instruction producing the value
631 -- Stores are buffered and have lower priority for E-cache until
632    highwater mark is reached in the store buffer (5 stores)
633
634 Pipeline constraints:
635 -- Shifts can only use IEU0.
636 -- CC setting instructions can only use IEU1.
637 -- Several other instructions must only use IEU1:
638    EDGE(?), ARRAY(?), CALL, JMPL, BPr, PST, and FCMP.
639 -- Two instructions cannot store to the same register file in a single cycle
640    (single write port per file).
641
642 Issue and grouping constraints:
643 -- FP and branch instructions must use slot 4.
644 -- Shift instructions cannot be grouped with other IEU0-specific instructions.
645 -- CC setting instructions cannot be grouped with other IEU1-specific instrs.
646 -- Several instructions must be issued in a single-instruction group:
647         MOVcc or MOVr, MULs/x and DIVs/x, SAVE/RESTORE, many others
648 -- A CALL or JMPL breaks a group, ie, is not combined with subsequent instrs.
649 -- 
650 -- 
651
652 Branch delay slot scheduling rules:
653 -- A CTI couple (two back-to-back CTI instructions in the dynamic stream)
654    has a 9-instruction penalty: the entire pipeline is flushed when the
655    second instruction reaches stage 9 (W-Writeback).
656 -- Avoid putting multicycle instructions, and instructions that may cause
657    load misses, in the delay slot of an annulling branch.
658 -- Avoid putting WR, SAVE..., RESTORE and RETURN instructions in the
659    delay slot of an annulling branch.
660
661  *--------------------------------------------------------------------------- */
662
663 //---------------------------------------------------------------------------
664 // List of CPUResources for UltraSPARC IIi.
665 //---------------------------------------------------------------------------
666
667 const CPUResource  AllIssueSlots(   "All Instr Slots", 4);
668 const CPUResource  IntIssueSlots(   "Int Instr Slots", 3);
669 const CPUResource  First3IssueSlots("Instr Slots 0-3", 3);
670 const CPUResource  LSIssueSlots(    "Load-Store Instr Slot", 1);
671 const CPUResource  CTIIssueSlots(   "Ctrl Transfer Instr Slot", 1);
672 const CPUResource  FPAIssueSlots(   "Int Instr Slot 1", 1);
673 const CPUResource  FPMIssueSlots(   "Int Instr Slot 1", 1);
674
675 // IEUN instructions can use either Alu and should use IAluN.
676 // IEU0 instructions must use Alu 1 and should use both IAluN and IAlu0. 
677 // IEU1 instructions must use Alu 2 and should use both IAluN and IAlu1. 
678 const CPUResource  IAluN("Int ALU 1or2", 2);
679 const CPUResource  IAlu0("Int ALU 1",    1);
680 const CPUResource  IAlu1("Int ALU 2",    1);
681
682 const CPUResource  LSAluC1("Load/Store Unit Addr Cycle", 1);
683 const CPUResource  LSAluC2("Load/Store Unit Issue Cycle", 1);
684 const CPUResource  LdReturn("Load Return Unit", 1);
685
686 const CPUResource  FPMAluC1("FP Mul/Div Alu Cycle 1", 1);
687 const CPUResource  FPMAluC2("FP Mul/Div Alu Cycle 2", 1);
688 const CPUResource  FPMAluC3("FP Mul/Div Alu Cycle 3", 1);
689
690 const CPUResource  FPAAluC1("FP Other Alu Cycle 1", 1);
691 const CPUResource  FPAAluC2("FP Other Alu Cycle 2", 1);
692 const CPUResource  FPAAluC3("FP Other Alu Cycle 3", 1);
693
694 const CPUResource  IRegReadPorts("Int Reg ReadPorts", INT_MAX);  // CHECK
695 const CPUResource  IRegWritePorts("Int Reg WritePorts", 2);      // CHECK
696 const CPUResource  FPRegReadPorts("FP Reg Read Ports", INT_MAX); // CHECK
697 const CPUResource  FPRegWritePorts("FP Reg Write Ports", 1);     // CHECK
698
699 const CPUResource  CTIDelayCycle( "CTI  delay cycle", 1);
700 const CPUResource  FCMPDelayCycle("FCMP delay cycle", 1);
701
702
703 //---------------------------------------------------------------------------
704 // const InstrClassRUsage SparcRUsageDesc[]
705 // 
706 // Purpose:
707 //   Resource usage information for instruction in each scheduling class.
708 //   The InstrRUsage Objects for individual classes are specified first.
709 //   Note that fetch and decode are decoupled from the execution pipelines
710 //   via an instr buffer, so they are not included in the cycles below.
711 //---------------------------------------------------------------------------
712
713 const InstrClassRUsage NoneClassRUsage = {
714   SPARC_NONE,
715   /*totCycles*/ 7,
716   
717   /* maxIssueNum */ 4,
718   /* isSingleIssue */ false,
719   /* breaksGroup */ false,
720   /* numBubbles */ 0,
721   
722   /*numSlots*/ 4,
723   /* feasibleSlots[] */ { 0, 1, 2, 3 },
724   
725   /*numEntries*/ 0,
726   /* V[] */ {
727     /*Cycle G */
728     /*Ccle E */
729     /*Cycle C */
730     /*Cycle N1*/
731     /*Cycle N1*/
732     /*Cycle N1*/
733     /*Cycle W */
734   }
735 };
736
737 const InstrClassRUsage IEUNClassRUsage = {
738   SPARC_IEUN,
739   /*totCycles*/ 7,
740   
741   /* maxIssueNum */ 3,
742   /* isSingleIssue */ false,
743   /* breaksGroup */ false,
744   /* numBubbles */ 0,
745   
746   /*numSlots*/ 3,
747   /* feasibleSlots[] */ { 0, 1, 2 },
748   
749   /*numEntries*/ 4,
750   /* V[] */ {
751     /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
752                  { IntIssueSlots.rid, 0, 1 },
753     /*Cycle E */ { IAluN.rid, 1, 1 },
754     /*Cycle C */
755     /*Cycle N1*/
756     /*Cycle N1*/
757     /*Cycle N1*/
758     /*Cycle W */ { IRegWritePorts.rid, 6, 1  }
759   }
760 };
761
762 const InstrClassRUsage IEU0ClassRUsage = {
763   SPARC_IEU0,
764   /*totCycles*/ 7,
765   
766   /* maxIssueNum */ 1,
767   /* isSingleIssue */ false,
768   /* breaksGroup */ false,
769   /* numBubbles */ 0,
770   
771   /*numSlots*/ 3,
772   /* feasibleSlots[] */ { 0, 1, 2 },
773   
774   /*numEntries*/ 5,
775   /* V[] */ {
776     /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
777                  { IntIssueSlots.rid, 0, 1 },
778     /*Cycle E */ { IAluN.rid, 1, 1 },
779                  { IAlu0.rid, 1, 1 },
780     /*Cycle C */
781     /*Cycle N1*/
782     /*Cycle N1*/
783     /*Cycle N1*/
784     /*Cycle W */ { IRegWritePorts.rid, 6, 1 }
785   }
786 };
787
788 const InstrClassRUsage IEU1ClassRUsage = {
789   SPARC_IEU1,
790   /*totCycles*/ 7,
791   
792   /* maxIssueNum */ 1,
793   /* isSingleIssue */ false,
794   /* breaksGroup */ false,
795   /* numBubbles */ 0,
796   
797   /*numSlots*/ 3,
798   /* feasibleSlots[] */ { 0, 1, 2 },
799   
800   /*numEntries*/ 5,
801   /* V[] */ {
802     /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
803                { IntIssueSlots.rid, 0, 1 },
804     /*Cycle E */ { IAluN.rid, 1, 1 },
805                { IAlu1.rid, 1, 1 },
806     /*Cycle C */
807     /*Cycle N1*/
808     /*Cycle N1*/
809     /*Cycle N1*/
810     /*Cycle W */ { IRegWritePorts.rid, 6, 1 }
811   }
812 };
813
814 const InstrClassRUsage FPMClassRUsage = {
815   SPARC_FPM,
816   /*totCycles*/ 7,
817   
818   /* maxIssueNum */ 1,
819   /* isSingleIssue */ false,
820   /* breaksGroup */ false,
821   /* numBubbles */ 0,
822   
823   /*numSlots*/ 4,
824   /* feasibleSlots[] */ { 0, 1, 2, 3 },
825   
826   /*numEntries*/ 7,
827   /* V[] */ {
828     /*Cycle G */ { AllIssueSlots.rid,   0, 1 },
829                  { FPMIssueSlots.rid,   0, 1 },
830     /*Cycle E */ { FPRegReadPorts.rid,  1, 1 },
831     /*Cycle C */ { FPMAluC1.rid,        2, 1 },
832     /*Cycle N1*/ { FPMAluC2.rid,        3, 1 },
833     /*Cycle N1*/ { FPMAluC3.rid,        4, 1 },
834     /*Cycle N1*/
835     /*Cycle W */ { FPRegWritePorts.rid, 6, 1 }
836   }
837 };
838
839 const InstrClassRUsage FPAClassRUsage = {
840   SPARC_FPA,
841   /*totCycles*/ 7,
842   
843   /* maxIssueNum */ 1,
844   /* isSingleIssue */ false,
845   /* breaksGroup */ false,
846   /* numBubbles */ 0,
847   
848   /*numSlots*/ 4,
849   /* feasibleSlots[] */ { 0, 1, 2, 3 },
850   
851   /*numEntries*/ 7,
852   /* V[] */ {
853     /*Cycle G */ { AllIssueSlots.rid,   0, 1 },
854                  { FPAIssueSlots.rid,   0, 1 },
855     /*Cycle E */ { FPRegReadPorts.rid,  1, 1 },
856     /*Cycle C */ { FPAAluC1.rid,        2, 1 },
857     /*Cycle N1*/ { FPAAluC2.rid,        3, 1 },
858     /*Cycle N1*/ { FPAAluC3.rid,        4, 1 },
859     /*Cycle N1*/
860     /*Cycle W */ { FPRegWritePorts.rid, 6, 1 }
861   }
862 };
863
864 const InstrClassRUsage LDClassRUsage = {
865   SPARC_LD,
866   /*totCycles*/ 7,
867   
868   /* maxIssueNum */ 1,
869   /* isSingleIssue */ false,
870   /* breaksGroup */ false,
871   /* numBubbles */ 0,
872   
873   /*numSlots*/ 3,
874   /* feasibleSlots[] */ { 0, 1, 2, },
875   
876   /*numEntries*/ 6,
877   /* V[] */ {
878     /*Cycle G */ { AllIssueSlots.rid,    0, 1 },
879                  { First3IssueSlots.rid, 0, 1 },
880                  { LSIssueSlots.rid,     0, 1 },
881     /*Cycle E */ { LSAluC1.rid,          1, 1 },
882     /*Cycle C */ { LSAluC2.rid,          2, 1 },
883                  { LdReturn.rid,         2, 1 },
884     /*Cycle N1*/
885     /*Cycle N1*/
886     /*Cycle N1*/
887     /*Cycle W */ { IRegWritePorts.rid,   6, 1 }
888   }
889 };
890
891 const InstrClassRUsage STClassRUsage = {
892   SPARC_ST,
893   /*totCycles*/ 7,
894   
895   /* maxIssueNum */ 1,
896   /* isSingleIssue */ false,
897   /* breaksGroup */ false,
898   /* numBubbles */ 0,
899   
900   /*numSlots*/ 3,
901   /* feasibleSlots[] */ { 0, 1, 2 },
902   
903   /*numEntries*/ 4,
904   /* V[] */ {
905     /*Cycle G */ { AllIssueSlots.rid,    0, 1 },
906                  { First3IssueSlots.rid, 0, 1 },
907                  { LSIssueSlots.rid,     0, 1 },
908     /*Cycle E */ { LSAluC1.rid,          1, 1 },
909     /*Cycle C */ { LSAluC2.rid,          2, 1 }
910     /*Cycle N1*/
911     /*Cycle N1*/
912     /*Cycle N1*/
913     /*Cycle W */
914   }
915 };
916
917 const InstrClassRUsage CTIClassRUsage = {
918   SPARC_CTI,
919   /*totCycles*/ 7,
920   
921   /* maxIssueNum */ 1,
922   /* isSingleIssue */ false,
923   /* breaksGroup */ false,
924   /* numBubbles */ 0,
925   
926   /*numSlots*/ 4,
927   /* feasibleSlots[] */ { 0, 1, 2, 3 },
928   
929   /*numEntries*/ 4,
930   /* V[] */ {
931     /*Cycle G */ { AllIssueSlots.rid,    0, 1 },
932                  { CTIIssueSlots.rid,    0, 1 },
933     /*Cycle E */ { IAlu0.rid,            1, 1 },
934     /*Cycles E-C */ { CTIDelayCycle.rid, 1, 2 }
935     /*Cycle C */             
936     /*Cycle N1*/
937     /*Cycle N1*/
938     /*Cycle N1*/
939     /*Cycle W */
940   }
941 };
942
943 const InstrClassRUsage SingleClassRUsage = {
944   SPARC_SINGLE,
945   /*totCycles*/ 7,
946   
947   /* maxIssueNum */ 1,
948   /* isSingleIssue */ true,
949   /* breaksGroup */ false,
950   /* numBubbles */ 0,
951   
952   /*numSlots*/ 1,
953   /* feasibleSlots[] */ { 0 },
954   
955   /*numEntries*/ 5,
956   /* V[] */ {
957     /*Cycle G */ { AllIssueSlots.rid,    0, 1 },
958                  { AllIssueSlots.rid,    0, 1 },
959                  { AllIssueSlots.rid,    0, 1 },
960                  { AllIssueSlots.rid,    0, 1 },
961     /*Cycle E */ { IAlu0.rid,            1, 1 }
962     /*Cycle C */
963     /*Cycle N1*/
964     /*Cycle N1*/
965     /*Cycle N1*/
966     /*Cycle W */
967   }
968 };
969
970
971 const InstrClassRUsage SparcRUsageDesc[] = {
972   NoneClassRUsage,
973   IEUNClassRUsage,
974   IEU0ClassRUsage,
975   IEU1ClassRUsage,
976   FPMClassRUsage,
977   FPAClassRUsage,
978   CTIClassRUsage,
979   LDClassRUsage,
980   STClassRUsage,
981   SingleClassRUsage
982 };
983
984
985 //---------------------------------------------------------------------------
986 // const InstrIssueDelta  SparcInstrIssueDeltas[]
987 // 
988 // Purpose:
989 //   Changes to issue restrictions information in InstrClassRUsage for
990 //   instructions that differ from other instructions in their class.
991 //---------------------------------------------------------------------------
992
993 const InstrIssueDelta  SparcInstrIssueDeltas[] = {
994
995   // opCode,  isSingleIssue,  breaksGroup,  numBubbles
996
997                                 // Special cases for single-issue only
998                                 // Other single issue cases are below.
999 //{ LDDA,       true,   true,   0 },
1000 //{ STDA,       true,   true,   0 },
1001 //{ LDDF,       true,   true,   0 },
1002 //{ LDDFA,      true,   true,   0 },
1003   { ADDC,       true,   true,   0 },
1004   { ADDCcc,     true,   true,   0 },
1005   { SUBC,       true,   true,   0 },
1006   { SUBCcc,     true,   true,   0 },
1007 //{ LDSTUB,     true,   true,   0 },
1008 //{ SWAP,       true,   true,   0 },
1009 //{ SWAPA,      true,   true,   0 },
1010 //{ CAS,        true,   true,   0 },
1011 //{ CASA,       true,   true,   0 },
1012 //{ CASX,       true,   true,   0 },
1013 //{ CASXA,      true,   true,   0 },
1014 //{ LDFSR,      true,   true,   0 },
1015 //{ LDFSRA,     true,   true,   0 },
1016 //{ LDXFSR,     true,   true,   0 },
1017 //{ LDXFSRA,    true,   true,   0 },
1018 //{ STFSR,      true,   true,   0 },
1019 //{ STFSRA,     true,   true,   0 },
1020 //{ STXFSR,     true,   true,   0 },
1021 //{ STXFSRA,    true,   true,   0 },
1022 //{ SAVED,      true,   true,   0 },
1023 //{ RESTORED,   true,   true,   0 },
1024 //{ FLUSH,      true,   true,   9 },
1025 //{ FLUSHW,     true,   true,   9 },
1026 //{ ALIGNADDR,  true,   true,   0 },
1027   { RETURN,     true,   true,   0 },
1028 //{ DONE,       true,   true,   0 },
1029 //{ RETRY,      true,   true,   0 },
1030 //{ TCC,        true,   true,   0 },
1031 //{ SHUTDOWN,   true,   true,   0 },
1032   
1033                                 // Special cases for breaking group *before*
1034                                 // CURRENTLY NOT SUPPORTED!
1035   { CALL,       false,  false,  0 },
1036   { JMPLCALL,   false,  false,  0 },
1037   { JMPLRET,    false,  false,  0 },
1038   
1039                                 // Special cases for breaking the group *after*
1040   { MULX,       true,   true,   (4+34)/2 },
1041   { FDIVS,      false,  true,   0 },
1042   { FDIVD,      false,  true,   0 },
1043   { FDIVQ,      false,  true,   0 },
1044   { FSQRTS,     false,  true,   0 },
1045   { FSQRTD,     false,  true,   0 },
1046   { FSQRTQ,     false,  true,   0 },
1047 //{ FCMP{LE,GT,NE,EQ}, false, true, 0 },
1048   
1049                                 // Instructions that introduce bubbles
1050 //{ MULScc,     true,   true,   2 },
1051 //{ SMULcc,     true,   true,   (4+18)/2 },
1052 //{ UMULcc,     true,   true,   (4+19)/2 },
1053   { SDIVX,      true,   true,   68 },
1054   { UDIVX,      true,   true,   68 },
1055 //{ SDIVcc,     true,   true,   36 },
1056 //{ UDIVcc,     true,   true,   37 },
1057   { WRCCR,      true,   true,   4 },
1058 //{ WRPR,       true,   true,   4 },
1059 //{ RDCCR,      true,   true,   0 }, // no bubbles after, but see below
1060 //{ RDPR,       true,   true,   0 },
1061 };
1062
1063
1064 //---------------------------------------------------------------------------
1065 // const InstrRUsageDelta SparcInstrUsageDeltas[]
1066 // 
1067 // Purpose:
1068 //   Changes to resource usage information in InstrClassRUsage for
1069 //   instructions that differ from other instructions in their class.
1070 //---------------------------------------------------------------------------
1071
1072 const InstrRUsageDelta SparcInstrUsageDeltas[] = {
1073
1074   // MachineOpCode, Resource, Start cycle, Num cycles
1075
1076   // 
1077   // JMPL counts as a load/store instruction for issue!
1078   //
1079   { JMPLCALL, LSIssueSlots.rid,  0,  1 },
1080   { JMPLRET,  LSIssueSlots.rid,  0,  1 },
1081   
1082   // 
1083   // Many instructions cannot issue for the next 2 cycles after an FCMP
1084   // We model that with a fake resource FCMPDelayCycle.
1085   // 
1086   { FCMPS,    FCMPDelayCycle.rid, 1, 3 },
1087   { FCMPD,    FCMPDelayCycle.rid, 1, 3 },
1088   { FCMPQ,    FCMPDelayCycle.rid, 1, 3 },
1089   
1090   { MULX,     FCMPDelayCycle.rid, 1, 1 },
1091   { SDIVX,    FCMPDelayCycle.rid, 1, 1 },
1092   { UDIVX,    FCMPDelayCycle.rid, 1, 1 },
1093 //{ SMULcc,   FCMPDelayCycle.rid, 1, 1 },
1094 //{ UMULcc,   FCMPDelayCycle.rid, 1, 1 },
1095 //{ SDIVcc,   FCMPDelayCycle.rid, 1, 1 },
1096 //{ UDIVcc,   FCMPDelayCycle.rid, 1, 1 },
1097   { STD,      FCMPDelayCycle.rid, 1, 1 },
1098   { FMOVRSZ,  FCMPDelayCycle.rid, 1, 1 },
1099   { FMOVRSLEZ,FCMPDelayCycle.rid, 1, 1 },
1100   { FMOVRSLZ, FCMPDelayCycle.rid, 1, 1 },
1101   { FMOVRSNZ, FCMPDelayCycle.rid, 1, 1 },
1102   { FMOVRSGZ, FCMPDelayCycle.rid, 1, 1 },
1103   { FMOVRSGEZ,FCMPDelayCycle.rid, 1, 1 },
1104   
1105   // 
1106   // Some instructions are stalled in the GROUP stage if a CTI is in
1107   // the E or C stage.  We model that with a fake resource CTIDelayCycle.
1108   // 
1109   { LDD,      CTIDelayCycle.rid,  1, 1 },
1110 //{ LDDA,     CTIDelayCycle.rid,  1, 1 },
1111 //{ LDDSTUB,  CTIDelayCycle.rid,  1, 1 },
1112 //{ LDDSTUBA, CTIDelayCycle.rid,  1, 1 },
1113 //{ SWAP,     CTIDelayCycle.rid,  1, 1 },
1114 //{ SWAPA,    CTIDelayCycle.rid,  1, 1 },
1115 //{ CAS,      CTIDelayCycle.rid,  1, 1 },
1116 //{ CASA,     CTIDelayCycle.rid,  1, 1 },
1117 //{ CASX,     CTIDelayCycle.rid,  1, 1 },
1118 //{ CASXA,    CTIDelayCycle.rid,  1, 1 },
1119   
1120   //
1121   // Signed int loads of less than dword size return data in cycle N1 (not C)
1122   // and put all loads in consecutive cycles into delayed load return mode.
1123   //
1124   { LDSB,    LdReturn.rid,  2, -1 },
1125   { LDSB,    LdReturn.rid,  3,  1 },
1126   
1127   { LDSH,    LdReturn.rid,  2, -1 },
1128   { LDSH,    LdReturn.rid,  3,  1 },
1129   
1130   { LDSW,    LdReturn.rid,  2, -1 },
1131   { LDSW,    LdReturn.rid,  3,  1 },
1132
1133   //
1134   // RDPR from certain registers and RD from any register are not dispatchable
1135   // until four clocks after they reach the head of the instr. buffer.
1136   // Together with their single-issue requirement, this means all four issue
1137   // slots are effectively blocked for those cycles, plus the issue cycle.
1138   // This does not increase the latency of the instruction itself.
1139   // 
1140   { RDCCR,   AllIssueSlots.rid,     0,  5 },
1141   { RDCCR,   AllIssueSlots.rid,     0,  5 },
1142   { RDCCR,   AllIssueSlots.rid,     0,  5 },
1143   { RDCCR,   AllIssueSlots.rid,     0,  5 },
1144
1145 #undef EXPLICIT_BUBBLES_NEEDED
1146 #ifdef EXPLICIT_BUBBLES_NEEDED
1147   // 
1148   // MULScc inserts one bubble.
1149   // This means it breaks the current group (captured in UltraSparcSchedInfo)
1150   // *and occupies all issue slots for the next cycle
1151   // 
1152 //{ MULScc,  AllIssueSlots.rid, 2, 2-1 },
1153 //{ MULScc,  AllIssueSlots.rid, 2, 2-1 },
1154 //{ MULScc,  AllIssueSlots.rid, 2, 2-1 },
1155 //{ MULScc,  AllIssueSlots.rid,  2, 2-1 },
1156   
1157   // 
1158   // SMULcc inserts between 4 and 18 bubbles, depending on #leading 0s in rs1.
1159   // We just model this with a simple average.
1160   // 
1161 //{ SMULcc,  AllIssueSlots.rid, 2, ((4+18)/2)-1 },
1162 //{ SMULcc,  AllIssueSlots.rid, 2, ((4+18)/2)-1 },
1163 //{ SMULcc,  AllIssueSlots.rid, 2, ((4+18)/2)-1 },
1164 //{ SMULcc,  AllIssueSlots.rid,  2, ((4+18)/2)-1 },
1165   
1166   // SMULcc inserts between 4 and 19 bubbles, depending on #leading 0s in rs1.
1167 //{ UMULcc,  AllIssueSlots.rid, 2, ((4+19)/2)-1 },
1168 //{ UMULcc,  AllIssueSlots.rid, 2, ((4+19)/2)-1 },
1169 //{ UMULcc,  AllIssueSlots.rid, 2, ((4+19)/2)-1 },
1170 //{ UMULcc,  AllIssueSlots.rid,  2, ((4+19)/2)-1 },
1171   
1172   // 
1173   // MULX inserts between 4 and 34 bubbles, depending on #leading 0s in rs1.
1174   // 
1175   { MULX,    AllIssueSlots.rid, 2, ((4+34)/2)-1 },
1176   { MULX,    AllIssueSlots.rid, 2, ((4+34)/2)-1 },
1177   { MULX,    AllIssueSlots.rid, 2, ((4+34)/2)-1 },
1178   { MULX,    AllIssueSlots.rid,  2, ((4+34)/2)-1 },
1179   
1180   // 
1181   // SDIVcc inserts 36 bubbles.
1182   // 
1183 //{ SDIVcc,  AllIssueSlots.rid, 2, 36-1 },
1184 //{ SDIVcc,  AllIssueSlots.rid, 2, 36-1 },
1185 //{ SDIVcc,  AllIssueSlots.rid, 2, 36-1 },
1186 //{ SDIVcc,  AllIssueSlots.rid,  2, 36-1 },
1187   
1188   // UDIVcc inserts 37 bubbles.
1189 //{ UDIVcc,  AllIssueSlots.rid, 2, 37-1 },
1190 //{ UDIVcc,  AllIssueSlots.rid, 2, 37-1 },
1191 //{ UDIVcc,  AllIssueSlots.rid, 2, 37-1 },
1192 //{ UDIVcc,  AllIssueSlots.rid,  2, 37-1 },
1193   
1194   // 
1195   // SDIVX inserts 68 bubbles.
1196   // 
1197   { SDIVX,   AllIssueSlots.rid, 2, 68-1 },
1198   { SDIVX,   AllIssueSlots.rid, 2, 68-1 },
1199   { SDIVX,   AllIssueSlots.rid, 2, 68-1 },
1200   { SDIVX,   AllIssueSlots.rid,  2, 68-1 },
1201   
1202   // 
1203   // UDIVX inserts 68 bubbles.
1204   // 
1205   { UDIVX,   AllIssueSlots.rid, 2, 68-1 },
1206   { UDIVX,   AllIssueSlots.rid, 2, 68-1 },
1207   { UDIVX,   AllIssueSlots.rid, 2, 68-1 },
1208   { UDIVX,   AllIssueSlots.rid,  2, 68-1 },
1209   
1210   // 
1211   // WR inserts 4 bubbles.
1212   // 
1213 //{ WR,     AllIssueSlots.rid, 2, 68-1 },
1214 //{ WR,     AllIssueSlots.rid, 2, 68-1 },
1215 //{ WR,     AllIssueSlots.rid, 2, 68-1 },
1216 //{ WR,     AllIssueSlots.rid,  2, 68-1 },
1217   
1218   // 
1219   // WRPR inserts 4 bubbles.
1220   // 
1221 //{ WRPR,   AllIssueSlots.rid, 2, 68-1 },
1222 //{ WRPR,   AllIssueSlots.rid, 2, 68-1 },
1223 //{ WRPR,   AllIssueSlots.rid, 2, 68-1 },
1224 //{ WRPR,   AllIssueSlots.rid,  2, 68-1 },
1225   
1226   // 
1227   // DONE inserts 9 bubbles.
1228   // 
1229 //{ DONE,   AllIssueSlots.rid, 2, 9-1 },
1230 //{ DONE,   AllIssueSlots.rid, 2, 9-1 },
1231 //{ DONE,   AllIssueSlots.rid, 2, 9-1 },
1232 //{ DONE,   AllIssueSlots.rid, 2, 9-1 },
1233   
1234   // 
1235   // RETRY inserts 9 bubbles.
1236   // 
1237 //{ RETRY,   AllIssueSlots.rid, 2, 9-1 },
1238 //{ RETRY,   AllIssueSlots.rid, 2, 9-1 },
1239 //{ RETRY,   AllIssueSlots.rid, 2, 9-1 },
1240 //{ RETRY,   AllIssueSlots.rid,  2, 9-1 },
1241
1242 #endif  /*EXPLICIT_BUBBLES_NEEDED */
1243 };
1244
1245
1246
1247 // Additional delays to be captured in code:
1248 // 1. RDPR from several state registers (page 349)
1249 // 2. RD   from *any* register (page 349)
1250 // 3. Writes to TICK, PSTATE, TL registers and FLUSH{W} instr (page 349)
1251 // 4. Integer store can be in same group as instr producing value to store.
1252 // 5. BICC and BPICC can be in the same group as instr producing CC (pg 350)
1253 // 6. FMOVr cannot be in the same or next group as an IEU instr (pg 351).
1254 // 7. The second instr. of a CTI group inserts 9 bubbles (pg 351)
1255 // 8. WR{PR}, SVAE, SAVED, RESTORE, RESTORED, RETURN, RETRY, and DONE that
1256 //    follow an annulling branch cannot be issued in the same group or in
1257 //    the 3 groups following the branch.
1258 // 9. A predicted annulled load does not stall dependent instructions.
1259 //    Other annulled delay slot instructions *do* stall dependents, so
1260 //    nothing special needs to be done for them during scheduling.
1261 //10. Do not put a load use that may be annulled in the same group as the
1262 //    branch.  The group will stall until the load returns.
1263 //11. Single-prec. FP loads lock 2 registers, for dependency checking.
1264 //
1265 // 
1266 // Additional delays we cannot or will not capture:
1267 // 1. If DCTI is last word of cache line, it is delayed until next line can be
1268 //    fetched.  Also, other DCTI alignment-related delays (pg 352)
1269 // 2. Load-after-store is delayed by 7 extra cycles if load hits in D-Cache.
1270 //    Also, several other store-load and load-store conflicts (pg 358)
1271 // 3. MEMBAR, LD{X}FSR, LDD{A} and a bunch of other load stalls (pg 358)
1272 // 4. There can be at most 8 outstanding buffered store instructions
1273 //     (including some others like MEMBAR, LDSTUB, CAS{AX}, and FLUSH)
1274
1275
1276
1277 //---------------------------------------------------------------------------
1278 // class UltraSparcSchedInfo
1279 // 
1280 // Purpose:
1281 //   Interface to instruction scheduling information for UltraSPARC.
1282 //   The parameter values above are based on UltraSPARC IIi.
1283 //---------------------------------------------------------------------------
1284
1285
1286 class UltraSparcSchedInfo: public MachineSchedInfo {
1287 public:
1288   /*ctor*/         UltraSparcSchedInfo  (const TargetMachine& tgt);
1289   /*dtor*/ virtual ~UltraSparcSchedInfo () {}
1290 protected:
1291   virtual void  initializeResources     ();
1292 };
1293
1294
1295 //---------------------------------------------------------------------------
1296 // class UltraSparcFrameInfo 
1297 // 
1298 // Purpose:
1299 //   Interface to stack frame layout info for the UltraSPARC.
1300 //   Starting offsets for each area of the stack frame are aligned at
1301 //   a multiple of getStackFrameSizeAlignment().
1302 //---------------------------------------------------------------------------
1303
1304 class UltraSparcFrameInfo: public MachineFrameInfo {
1305 public:
1306   /*ctor*/ UltraSparcFrameInfo(const TargetMachine& tgt) : MachineFrameInfo(tgt) {}
1307   
1308 public:
1309   int  getStackFrameSizeAlignment   () const { return StackFrameSizeAlignment;}
1310   int  getMinStackFrameSize         () const { return MinStackFrameSize; }
1311   int  getNumFixedOutgoingArgs      () const { return NumFixedOutgoingArgs; }
1312   int  getSizeOfEachArgOnStack      () const { return SizeOfEachArgOnStack; }
1313   bool argsOnStackHaveFixedSize     () const { return true; }
1314
1315   //
1316   // These methods compute offsets using the frame contents for a
1317   // particular method.  The frame contents are obtained from the
1318   // MachineCodeInfoForMethod object for the given method.
1319   // 
1320   int getFirstIncomingArgOffset  (MachineCodeForMethod& mcInfo,
1321                                   bool& pos) const
1322   {
1323     pos = true;                         // arguments area grows upwards
1324     return FirstIncomingArgOffsetFromFP;
1325   }
1326   int getFirstOutgoingArgOffset  (MachineCodeForMethod& mcInfo,
1327                                   bool& pos) const
1328   {
1329     pos = true;                         // arguments area grows upwards
1330     return FirstOutgoingArgOffsetFromSP;
1331   }
1332   int getFirstOptionalOutgoingArgOffset(MachineCodeForMethod& mcInfo,
1333                                         bool& pos)const
1334   {
1335     pos = true;                         // arguments area grows upwards
1336     return FirstOptionalOutgoingArgOffsetFromSP;
1337   }
1338   
1339   int getFirstAutomaticVarOffset (MachineCodeForMethod& mcInfo,
1340                                   bool& pos) const;
1341   int getRegSpillAreaOffset      (MachineCodeForMethod& mcInfo,
1342                                   bool& pos) const;
1343   int getTmpAreaOffset           (MachineCodeForMethod& mcInfo,
1344                                   bool& pos) const;
1345   int getDynamicAreaOffset       (MachineCodeForMethod& mcInfo,
1346                                   bool& pos) const;
1347
1348   //
1349   // These methods specify the base register used for each stack area
1350   // (generally FP or SP)
1351   // 
1352   virtual int getIncomingArgBaseRegNum()               const {
1353     return (int) target.getRegInfo().getFramePointer();
1354   }
1355   virtual int getOutgoingArgBaseRegNum()               const {
1356     return (int) target.getRegInfo().getStackPointer();
1357   }
1358   virtual int getOptionalOutgoingArgBaseRegNum()       const {
1359     return (int) target.getRegInfo().getStackPointer();
1360   }
1361   virtual int getAutomaticVarBaseRegNum()              const {
1362     return (int) target.getRegInfo().getFramePointer();
1363   }
1364   virtual int getRegSpillAreaBaseRegNum()              const {
1365     return (int) target.getRegInfo().getFramePointer();
1366   }
1367   virtual int getDynamicAreaBaseRegNum()               const {
1368     return (int) target.getRegInfo().getStackPointer();
1369   }
1370   
1371 private:
1372   // All stack addresses must be offset by 0x7ff (2047) on Sparc V9.
1373   static const int OFFSET                                  = (int) 0x7ff;
1374   static const int StackFrameSizeAlignment                 =  16;
1375   static const int MinStackFrameSize                       = 176;
1376   static const int NumFixedOutgoingArgs                    =   6;
1377   static const int SizeOfEachArgOnStack                    =   8;
1378   static const int StaticAreaOffsetFromFP                  =  0 + OFFSET;
1379   static const int FirstIncomingArgOffsetFromFP            = 128 + OFFSET;
1380   static const int FirstOptionalIncomingArgOffsetFromFP    = 176 + OFFSET;
1381   static const int FirstOutgoingArgOffsetFromSP            = 128 + OFFSET;
1382   static const int FirstOptionalOutgoingArgOffsetFromSP    = 176 + OFFSET;
1383 };
1384
1385
1386 //---------------------------------------------------------------------------
1387 // class UltraSparcCacheInfo 
1388 // 
1389 // Purpose:
1390 //   Interface to cache parameters for the UltraSPARC.
1391 //   Just use defaults for now.
1392 //---------------------------------------------------------------------------
1393
1394 class UltraSparcCacheInfo: public MachineCacheInfo {
1395 public:
1396   /*ctor*/          UltraSparcCacheInfo  (const TargetMachine& target) :
1397     MachineCacheInfo(target) {} 
1398 };
1399
1400
1401 //---------------------------------------------------------------------------
1402 // class UltraSparcMachine 
1403 // 
1404 // Purpose:
1405 //   Primary interface to machine description for the UltraSPARC.
1406 //   Primarily just initializes machine-dependent parameters in
1407 //   class TargetMachine, and creates machine-dependent subclasses
1408 //   for classes such as InstrInfo, SchedInfo and RegInfo. 
1409 //---------------------------------------------------------------------------
1410
1411 class UltraSparc : public TargetMachine {
1412 private:
1413   UltraSparcInstrInfo instrInfo;
1414   UltraSparcSchedInfo schedInfo;
1415   UltraSparcRegInfo   regInfo;
1416   UltraSparcFrameInfo frameInfo;
1417   UltraSparcCacheInfo cacheInfo;
1418 public:
1419   UltraSparc();
1420   virtual ~UltraSparc() {}
1421   
1422   virtual const MachineInstrInfo &getInstrInfo() const { return instrInfo; }
1423   virtual const MachineSchedInfo &getSchedInfo() const { return schedInfo; }
1424   virtual const MachineRegInfo   &getRegInfo()   const { return regInfo; }
1425   virtual const MachineFrameInfo &getFrameInfo() const { return frameInfo; }
1426   virtual const MachineCacheInfo &getCacheInfo() const { return cacheInfo; }
1427   
1428   // compileMethod - For the sparc, we do instruction selection, followed by
1429   // delay slot scheduling, then register allocation.
1430   //
1431   virtual bool compileMethod(Method *M);
1432
1433   //
1434   // emitAssembly - Output assembly language code (a .s file) for the specified
1435   // module. The specified module must have been compiled before this may be
1436   // used.
1437   //
1438   virtual void emitAssembly(const Method *M, std::ostream &OutStr) const;
1439
1440   //
1441   // emitAssembly - Output assembly language code (a .s file) for global
1442   // components of the specified module.  This assumes that methods have been
1443   // previously output.
1444   //
1445   virtual void emitAssembly(const Module *M, std::ostream &OutStr) const;
1446
1447   //
1448   // freeCompiledMethod - Release all memory associated with the compiled image
1449   // for this method.
1450   //
1451   virtual void freeCompiledMethod(Method *M);
1452 };
1453
1454 #endif