Move a ton of tables out of SparcInternals.h and move them to Sparc.cpp.
[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 //---------------------------------------------------------------------------
589 // class UltraSparcSchedInfo
590 // 
591 // Purpose:
592 //   Interface to instruction scheduling information for UltraSPARC.
593 //   The parameter values above are based on UltraSPARC IIi.
594 //---------------------------------------------------------------------------
595
596
597 class UltraSparcSchedInfo: public MachineSchedInfo {
598 public:
599   /*ctor*/         UltraSparcSchedInfo  (const TargetMachine& tgt);
600   /*dtor*/ virtual ~UltraSparcSchedInfo () {}
601 protected:
602   virtual void  initializeResources     ();
603 };
604
605
606 //---------------------------------------------------------------------------
607 // class UltraSparcFrameInfo 
608 // 
609 // Purpose:
610 //   Interface to stack frame layout info for the UltraSPARC.
611 //   Starting offsets for each area of the stack frame are aligned at
612 //   a multiple of getStackFrameSizeAlignment().
613 //---------------------------------------------------------------------------
614
615 class UltraSparcFrameInfo: public MachineFrameInfo {
616 public:
617   /*ctor*/ UltraSparcFrameInfo(const TargetMachine& tgt) : MachineFrameInfo(tgt) {}
618   
619 public:
620   int  getStackFrameSizeAlignment   () const { return StackFrameSizeAlignment;}
621   int  getMinStackFrameSize         () const { return MinStackFrameSize; }
622   int  getNumFixedOutgoingArgs      () const { return NumFixedOutgoingArgs; }
623   int  getSizeOfEachArgOnStack      () const { return SizeOfEachArgOnStack; }
624   bool argsOnStackHaveFixedSize     () const { return true; }
625
626   //
627   // These methods compute offsets using the frame contents for a
628   // particular method.  The frame contents are obtained from the
629   // MachineCodeInfoForMethod object for the given method.
630   // 
631   int getFirstIncomingArgOffset  (MachineCodeForMethod& mcInfo,
632                                   bool& pos) const
633   {
634     pos = true;                         // arguments area grows upwards
635     return FirstIncomingArgOffsetFromFP;
636   }
637   int getFirstOutgoingArgOffset  (MachineCodeForMethod& mcInfo,
638                                   bool& pos) const
639   {
640     pos = true;                         // arguments area grows upwards
641     return FirstOutgoingArgOffsetFromSP;
642   }
643   int getFirstOptionalOutgoingArgOffset(MachineCodeForMethod& mcInfo,
644                                         bool& pos)const
645   {
646     pos = true;                         // arguments area grows upwards
647     return FirstOptionalOutgoingArgOffsetFromSP;
648   }
649   
650   int getFirstAutomaticVarOffset (MachineCodeForMethod& mcInfo,
651                                   bool& pos) const;
652   int getRegSpillAreaOffset      (MachineCodeForMethod& mcInfo,
653                                   bool& pos) const;
654   int getTmpAreaOffset           (MachineCodeForMethod& mcInfo,
655                                   bool& pos) const;
656   int getDynamicAreaOffset       (MachineCodeForMethod& mcInfo,
657                                   bool& pos) const;
658
659   //
660   // These methods specify the base register used for each stack area
661   // (generally FP or SP)
662   // 
663   virtual int getIncomingArgBaseRegNum()               const {
664     return (int) target.getRegInfo().getFramePointer();
665   }
666   virtual int getOutgoingArgBaseRegNum()               const {
667     return (int) target.getRegInfo().getStackPointer();
668   }
669   virtual int getOptionalOutgoingArgBaseRegNum()       const {
670     return (int) target.getRegInfo().getStackPointer();
671   }
672   virtual int getAutomaticVarBaseRegNum()              const {
673     return (int) target.getRegInfo().getFramePointer();
674   }
675   virtual int getRegSpillAreaBaseRegNum()              const {
676     return (int) target.getRegInfo().getFramePointer();
677   }
678   virtual int getDynamicAreaBaseRegNum()               const {
679     return (int) target.getRegInfo().getStackPointer();
680   }
681   
682 private:
683   // All stack addresses must be offset by 0x7ff (2047) on Sparc V9.
684   static const int OFFSET                                  = (int) 0x7ff;
685   static const int StackFrameSizeAlignment                 =  16;
686   static const int MinStackFrameSize                       = 176;
687   static const int NumFixedOutgoingArgs                    =   6;
688   static const int SizeOfEachArgOnStack                    =   8;
689   static const int StaticAreaOffsetFromFP                  =  0 + OFFSET;
690   static const int FirstIncomingArgOffsetFromFP            = 128 + OFFSET;
691   static const int FirstOptionalIncomingArgOffsetFromFP    = 176 + OFFSET;
692   static const int FirstOutgoingArgOffsetFromSP            = 128 + OFFSET;
693   static const int FirstOptionalOutgoingArgOffsetFromSP    = 176 + OFFSET;
694 };
695
696
697 //---------------------------------------------------------------------------
698 // class UltraSparcCacheInfo 
699 // 
700 // Purpose:
701 //   Interface to cache parameters for the UltraSPARC.
702 //   Just use defaults for now.
703 //---------------------------------------------------------------------------
704
705 class UltraSparcCacheInfo: public MachineCacheInfo {
706 public:
707   UltraSparcCacheInfo(const TargetMachine &T) : MachineCacheInfo(T) {} 
708 };
709
710
711 //---------------------------------------------------------------------------
712 // class UltraSparcMachine 
713 // 
714 // Purpose:
715 //   Primary interface to machine description for the UltraSPARC.
716 //   Primarily just initializes machine-dependent parameters in
717 //   class TargetMachine, and creates machine-dependent subclasses
718 //   for classes such as InstrInfo, SchedInfo and RegInfo. 
719 //---------------------------------------------------------------------------
720
721 class UltraSparc : public TargetMachine {
722 private:
723   UltraSparcInstrInfo instrInfo;
724   UltraSparcSchedInfo schedInfo;
725   UltraSparcRegInfo   regInfo;
726   UltraSparcFrameInfo frameInfo;
727   UltraSparcCacheInfo cacheInfo;
728 public:
729   UltraSparc();
730   
731   virtual const MachineInstrInfo &getInstrInfo() const { return instrInfo; }
732   virtual const MachineSchedInfo &getSchedInfo() const { return schedInfo; }
733   virtual const MachineRegInfo   &getRegInfo()   const { return regInfo; }
734   virtual const MachineFrameInfo &getFrameInfo() const { return frameInfo; }
735   virtual const MachineCacheInfo &getCacheInfo() const { return cacheInfo; }
736
737   //
738   // addPassesToEmitAssembly - Add passes to the specified pass manager to get
739   // assembly langage code emited.  For sparc, we have to do ...
740   //
741   virtual void addPassesToEmitAssembly(PassManager &PM, std::ostream &Out);
742
743 private:
744   Pass *getMethodAsmPrinterPass(PassManager &PM, std::ostream &Out);
745   Pass *getModuleAsmPrinterPass(PassManager &PM, std::ostream &Out);
746 };
747
748 #endif