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