Don't bother passing in default value
[oota-llvm.git] / lib / Target / SparcV9 / SparcV9Internals.h
index 52118f97611fd62b475b06d20de9a31218e1d019..72691a2613fb0b094a4a7cf312c2303c0719bc54 100644 (file)
@@ -1,23 +1,19 @@
-// $Id$ -*- C++ -*--
-//***************************************************************************
-// File:
-//     SparcInternals.h
+//===-- SparcInternals.h ----------------------------------------*- C++ -*-===//
 // 
-// Purpose:
-//       This file defines stuff that is to be private to the Sparc
-//       backend, but is shared among different portions of the backend.
-//**************************************************************************/
-
+// This file defines stuff that is to be private to the Sparc backend, but is
+// shared among different portions of the backend.
+//
+//===----------------------------------------------------------------------===//
 
 #ifndef SPARC_INTERNALS_H
 #define SPARC_INTERNALS_H
 
 #include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/MachineInstrInfo.h"
 #include "llvm/Target/MachineSchedInfo.h"
 #include "llvm/Target/MachineFrameInfo.h"
 #include "llvm/Target/MachineCacheInfo.h"
 #include "llvm/Target/MachineRegInfo.h"
+#include "llvm/Target/MachineOptInfo.h"
 #include "llvm/Type.h"
 #include <sys/types.h>
 
@@ -26,8 +22,6 @@ class UltraSparc;
 class PhyRegAlloc;
 class Pass;
 
-Pass *createPrologEpilogCodeInserter(TargetMachine &TM);
-
 // OpCodeMask definitions for the Sparc V9
 // 
 const OpCodeMask       Immed           = 0x00002000; // immed or reg operand?
@@ -88,21 +82,24 @@ extern const MachineInstrDescriptor SparcMachineInstrDesc[];
 //   default to member functions in base class MachineInstrInfo. 
 //---------------------------------------------------------------------------
 
-class UltraSparcInstrInfo : public MachineInstrInfo {
-public:
-  /*ctor*/     UltraSparcInstrInfo(const TargetMachine& tgt);
+struct UltraSparcInstrInfo : public MachineInstrInfo {
+  UltraSparcInstrInfo(const TargetMachine& tgt);
 
   //
   // All immediate constants are in position 1 except the
-  // store instructions.
+  // store instructions and SETxx.
   // 
   virtual int getImmedConstantPos(MachineOpCode opCode) const {
     bool ignore;
     if (this->maxImmedConstant(opCode, ignore) != 0)
       {
-        assert(! this->isStore((MachineOpCode) STB - 1)); // first store is STB
-        assert(! this->isStore((MachineOpCode) STD + 1)); // last  store is STD
-        return (opCode >= STB && opCode <= STD)? 2 : 1;
+        assert(! this->isStore((MachineOpCode) STB - 1)); // 1st  store opcode
+        assert(! this->isStore((MachineOpCode) STXFSR+1));// last store opcode
+        if (opCode==SETSW || opCode==SETUW || opCode==SETX || opCode==SETHI)
+          return 0;
+        if (opCode >= STB && opCode <= STXFSR)
+          return 2;
+        return 1;
       }
     else
       return -1;
@@ -119,52 +116,102 @@ public:
     return (opCode == FCMPS || opCode == FCMPD || opCode == FCMPQ);
   }
 
+  //-------------------------------------------------------------------------
+  // Queries about representation of LLVM quantities (e.g., constants)
+  //-------------------------------------------------------------------------
+
+  virtual bool ConstantMayNotFitInImmedField(const Constant* CV,
+                                             const Instruction* I) const;
+
   //-------------------------------------------------------------------------
   // Code generation support for creating individual machine instructions
   //-------------------------------------------------------------------------
-  
+
+  // Get certain common op codes for the current target.  This and all the
+  // Create* methods below should be moved to a machine code generation class
+  // 
+  virtual MachineOpCode getNOPOpCode() const { return NOP; }
+
   // Create an instruction sequence to put the constant `val' into
-  // the virtual register `dest'.  The generated instructions are
-  // returned in `minstrVec'.  Any temporary registers (TmpInstruction)
-  // created are returned in `tempVec'.
+  // the virtual register `dest'.  `val' may be a Constant or a
+  // GlobalValue, viz., the constant address of a global variable or function.
+  // The generated instructions are returned in `mvec'.
+  // Any temp. registers (TmpInstruction) created are recorded in mcfi.
+  // Any stack space required is allocated via mcff.
   // 
-  virtual void  CreateCodeToLoadConst(Function* method,
+  virtual void  CreateCodeToLoadConst(const TargetMachine& target,
+                                      Function* F,
                                       Value* val,
                                       Instruction* dest,
-                                      std::vector<MachineInstr*>& minstrVec,
-                                      std::vector<TmpInstruction*>& tmp) const;
+                                      std::vector<MachineInstr*>& mvec,
+                                      MachineCodeForInstruction& mcfi) const;
 
-  
   // Create an instruction sequence to copy an integer value `val'
   // to a floating point value `dest' by copying to memory and back.
   // val must be an integral type.  dest must be a Float or Double.
-  // The generated instructions are returned in `minstrVec'.
-  // Any temp. registers (TmpInstruction) created are returned in `tempVec'.
+  // The generated instructions are returned in `mvec'.
+  // Any temp. registers (TmpInstruction) created are recorded in mcfi.
+  // Any stack space required is allocated via mcff.
   // 
-  virtual void  CreateCodeToCopyIntToFloat(Function* method,
-                                           Value* val,
-                                           Instruction* dest,
-                                           std::vector<MachineInstr*>& minstr,
-                                           std::vector<TmpInstruction*>& temp,
-                                           TargetMachine& target) const;
+  virtual void  CreateCodeToCopyIntToFloat(const TargetMachine& target,
+                                       Function* F,
+                                       Value* val,
+                                       Instruction* dest,
+                                       std::vector<MachineInstr*>& mvec,
+                                       MachineCodeForInstruction& mcfi) const;
 
   // Similarly, create an instruction sequence to copy an FP value
   // `val' to an integer value `dest' by copying to memory and back.
-  // See the previous function for information about return values.
+  // The generated instructions are returned in `mvec'.
+  // Any temp. registers (TmpInstruction) created are recorded in mcfi.
+  // Any stack space required is allocated via mcff.
+  // 
+  virtual void  CreateCodeToCopyFloatToInt(const TargetMachine& target,
+                                       Function* F,
+                                       Value* val,
+                                       Instruction* dest,
+                                       std::vector<MachineInstr*>& mvec,
+                                       MachineCodeForInstruction& mcfi) const;
+  
+  // Create instruction(s) to copy src to dest, for arbitrary types
+  // The generated instructions are returned in `mvec'.
+  // Any temp. registers (TmpInstruction) created are recorded in mcfi.
+  // Any stack space required is allocated via mcff.
   // 
-  virtual void  CreateCodeToCopyFloatToInt(Function* method,
-                                           Value* val,
-                                           Instruction* dest,
-                                           std::vector<MachineInstr*>& minstr,
-                                           std::vector<TmpInstruction*>& temp,
-                                           TargetMachine& target) const;
-
- // create copy instruction(s)
   virtual void CreateCopyInstructionsByType(const TargetMachine& target,
-                                            Function* method,
-                                            Value* src,
-                                            Instruction* dest,
-                                            std::vector<MachineInstr*>& minstr) const;
+                                       Function* F,
+                                       Value* src,
+                                       Instruction* dest,
+                                       std::vector<MachineInstr*>& mvec,
+                                       MachineCodeForInstruction& mcfi) const;
+
+  // Create instruction sequence to produce a sign-extended register value
+  // from an arbitrary sized value (sized in bits, not bytes).
+  // The generated instructions are appended to `mvec'.
+  // Any temp. registers (TmpInstruction) created are recorded in mcfi.
+  // Any stack space required is allocated via mcff.
+  // 
+  virtual void CreateSignExtensionInstructions(const TargetMachine& target,
+                                       Function* F,
+                                       Value* srcVal,
+                                       Value* destVal,
+                                       unsigned int numLowBits,
+                                       std::vector<MachineInstr*>& mvec,
+                                       MachineCodeForInstruction& mcfi) const;
+
+  // Create instruction sequence to produce a zero-extended register value
+  // from an arbitrary sized value (sized in bits, not bytes).
+  // The generated instructions are appended to `mvec'.
+  // Any temp. registers (TmpInstruction) created are recorded in mcfi.
+  // Any stack space required is allocated via mcff.
+  // 
+  virtual void CreateZeroExtensionInstructions(const TargetMachine& target,
+                                       Function* F,
+                                       Value* srcVal,
+                                       Value* destVal,
+                                       unsigned int numLowBits,
+                                       std::vector<MachineInstr*>& mvec,
+                                       MachineCodeForInstruction& mcfi) const;
 };
 
 
@@ -203,10 +250,6 @@ class UltraSparcRegInfo : public MachineRegInfo {
   // order for efficiency.
 
 
-  // reverse pointer to get info about the ultra sparc machine
-  //
-  const UltraSparc *const UltraSparcInfo;
-
   // Number of registers used for passing int args (usually 6: %o0 - %o5)
   //
   unsigned const NumOfIntArgRegs;
@@ -224,45 +267,30 @@ class UltraSparcRegInfo : public MachineRegInfo {
   // ========================  Private Methods =============================
 
   // The following methods are used to color special live ranges (e.g.
-  // method args and return values etc.) with specific hardware registers
+  // function args and return values etc.) with specific hardware registers
   // as required. See SparcRegInfo.cpp for the implementation.
   //
-  void setCallOrRetArgCol(LiveRange *LR, unsigned RegNo,
-                          const MachineInstr *MI, 
-                          std::hash_map<const MachineInstr *,
-                                        AddedInstrns *> &AIMap) const;
-
-  MachineInstr *getCopy2RegMI(const Value *SrcVal, unsigned Reg,
-                              unsigned RegClassID) const;
-
-  void suggestReg4RetAddr(const MachineInstr *RetMI, 
+  void suggestReg4RetAddr(MachineInstr *RetMI, 
                          LiveRangeInfo &LRI) const;
 
-  void suggestReg4CallAddr(const MachineInstr *CallMI, LiveRangeInfo &LRI,
-                          std::vector<RegClass *> RCList) const;
-
-
-
-  // The following methods are used to find the addresses etc. contained
-  // in specail machine instructions like CALL/RET
-  //
-  Value *getValue4ReturnAddr(const MachineInstr *MInst) const;
-  const Value *getCallInstRetAddr(const MachineInstr *CallMI) const;
-  unsigned getCallInstNumArgs(const MachineInstr *CallMI) const;
-
-
-  // The following 3  methods are used to find the RegType (see enum above)
-  // of a LiveRange, Value and using the unified RegClassID
+  void suggestReg4CallAddr(MachineInstr *CallMI, LiveRangeInfo &LRI) const;
+  
+  void InitializeOutgoingArg(MachineInstr* CallMI, AddedInstrns *CallAI,
+                             PhyRegAlloc &PRA, LiveRange* LR,
+                             unsigned regType, unsigned RegClassID,
+                             int  UniArgReg, unsigned int argNo,
+                             std::vector<MachineInstr *>& AddedInstrnsBefore)
+    const;
+  
+  // The following 4 methods are used to find the RegType (see enum above)
+  // for a reg class and a given primitive type, a LiveRange, a Value,
+  // or a particular machine register.
+  // The fifth function gives the reg class of the given RegType.
+  // 
+  int getRegType(unsigned regClassID, const Type* type) const;
   int getRegType(const LiveRange *LR) const;
   int getRegType(const Value *Val) const;
-  int getRegType(int reg) const;
-
-
-  // The following methods are used to generate copy instructions to move
-  // data between condition code registers
-  //
-  MachineInstr *cpCCR2IntMI(unsigned IntReg) const;
-  MachineInstr *cpInt2CCRMI(unsigned IntReg) const;
+  int getRegType(int unifiedRegNum) const;
 
   // Used to generate a copy instruction based on the register class of
   // value.
@@ -272,7 +300,7 @@ class UltraSparcRegInfo : public MachineRegInfo {
 
 
   // The following 2 methods are used to order the instructions addeed by
-  // the register allocator in association with method calling. See
+  // the register allocator in association with function calling. See
   // SparcRegInfo.cpp for more details
   //
   void moveInst2OrdVec(std::vector<MachineInstr *> &OrdVec,
@@ -284,45 +312,23 @@ class UltraSparcRegInfo : public MachineRegInfo {
                          PhyRegAlloc &PRA) const;
 
 
-  // To find whether a particular call is to a var arg method
-  //
-  bool isVarArgCall(const MachineInstr *CallMI) const;
-
+  // Compute which register can be used for an argument, if any
+  // 
+  int regNumForIntArg(bool inCallee, bool isVarArgsCall,
+                      unsigned argNo, unsigned intArgNo, unsigned fpArgNo,
+                      unsigned& regClassId) const;
 
+  int regNumForFPArg(unsigned RegType, bool inCallee, bool isVarArgsCall,
+                     unsigned argNo, unsigned intArgNo, unsigned fpArgNo,
+                     unsigned& regClassId) const;
+  
 public:
   UltraSparcRegInfo(const UltraSparc &tgt);
 
-  // To get complete machine information structure using the machine register
-  // information
-  //
-  inline const UltraSparc &getUltraSparcInfo() const { 
-    return *UltraSparcInfo;
-  }
-
   // To find the register class used for a specified Type
   //
-  inline unsigned getRegClassIDOfType(const Type *type,
-                                      bool isCCReg = false) const {
-    Type::PrimitiveID ty = type->getPrimitiveID();
-    unsigned res;
-    
-    // FIXME: Comparing types like this isn't very safe...
-    if ((ty && ty <= Type::LongTyID) || (ty == Type::LabelTyID) ||
-       (ty == Type::FunctionTyID) ||  (ty == Type::PointerTyID) )
-      res = IntRegClassID;             // sparc int reg (ty=0: void)
-    else if (ty <= Type::DoubleTyID)
-      res = FloatRegClassID;           // sparc float reg class
-    else { 
-      //std::cerr << "TypeID: " << ty << "\n";
-      assert(0 && "Cannot resolve register class for type");
-      return 0;
-    }
-
-    if(isCCReg)
-      return res + 2;      // corresponidng condition code regiser 
-    else 
-      return res;
-  }
+  unsigned getRegClassIDOfType(const Type *type,
+                               bool isCCReg = false) const;
 
   // To find the register class of a Value
   //
@@ -331,15 +337,18 @@ public:
     return getRegClassIDOfType(Val->getType(), isCCReg);
   }
 
+  // To find the register class to which a specified register belongs
+  //
+  unsigned getRegClassIDOfReg(int unifiedRegNum) const;
+  unsigned getRegClassIDOfRegType(int regType) const;
   
-
   // getZeroRegNum - returns the register that contains always zero this is the
   // unified register number
   //
   virtual int getZeroRegNum() const;
 
   // getCallAddressReg - returns the reg used for pushing the address when a
-  // method is called. This can be used for other purposes between calls
+  // function is called. This can be used for other purposes between calls
   //
   unsigned getCallAddressReg() const;
 
@@ -349,62 +358,86 @@ public:
   //
   unsigned getReturnAddressReg() const;
 
-
-
+  // Number of registers used for passing int args (usually 6: %o0 - %o5)
+  // and float args (usually 32: %f0 - %f31)
+  //
+  unsigned const GetNumOfIntArgRegs() const   { return NumOfIntArgRegs; }
+  unsigned const GetNumOfFloatArgRegs() const { return NumOfFloatArgRegs; }
+  
   // The following methods are used to color special live ranges (e.g.
-  // method args and return values etc.) with specific hardware registers
+  // function args and return values etc.) with specific hardware registers
   // as required. See SparcRegInfo.cpp for the implementation for Sparc.
   //
   void suggestRegs4MethodArgs(const Function *Meth, 
                              LiveRangeInfo& LRI) const;
 
-  void suggestRegs4CallArgs(const MachineInstr *CallMI, 
-                           LiveRangeInfo& LRI,
-                            std::vector<RegClass *> RCL) const; 
+  void suggestRegs4CallArgs(MachineInstr *CallMI, 
+                           LiveRangeInfo& LRI) const; 
 
-  void suggestReg4RetValue(const MachineInstr *RetMI, 
+  void suggestReg4RetValue(MachineInstr *RetMI, 
                            LiveRangeInfo& LRI) const;
-
-
+  
   void colorMethodArgs(const Function *Meth,  LiveRangeInfo &LRI,
                       AddedInstrns *FirstAI) const;
 
-  void colorCallArgs(const MachineInstr *CallMI, LiveRangeInfo &LRI,
+  void colorCallArgs(MachineInstr *CallMI, LiveRangeInfo &LRI,
                     AddedInstrns *CallAI,  PhyRegAlloc &PRA,
                     const BasicBlock *BB) const;
 
-  void colorRetValue(const MachineInstr *RetI,   LiveRangeInfo& LRI,
+  void colorRetValue(MachineInstr *RetI,   LiveRangeInfo& LRI,
                     AddedInstrns *RetAI) const;
 
 
-
   // method used for printing a register for debugging purposes
   //
   static void printReg(const LiveRange *LR);
 
-  // this method provides a unique number for each register 
+  // Each register class has a seperate space for register IDs. To convert
+  // a regId in a register class to a common Id, or vice versa,
+  // we use the folloing methods.
   //
-  inline int getUnifiedRegNum(int RegClassID, int reg) const {
-
-    if( RegClassID == IntRegClassID && reg < 32 ) 
+  // This method provides a unique number for each register 
+  inline int getUnifiedRegNum(unsigned regClassID, int reg) const {
+    
+    if (regClassID == IntRegClassID) {
+      assert(reg < 32 && "Invalid reg. number");
       return reg;
-    else if ( RegClassID == FloatRegClassID && reg < 64)
+    }
+    else if (regClassID == FloatRegClassID) {
+      assert(reg < 64 && "Invalid reg. number");
       return reg + 32;                  // we have 32 int regs
-    else if( RegClassID == FloatCCRegClassID && reg < 4)
+    }
+    else if (regClassID == FloatCCRegClassID) {
+      assert(reg < 4 && "Invalid reg. number");
       return reg + 32 + 64;             // 32 int, 64 float
-    else if( RegClassID == IntCCRegClassID ) 
-      return reg + 4+ 32 + 64;                // only int cc reg
-    else if (reg==InvalidRegNum)                
+    }
+    else if (regClassID == IntCCRegClassID ) {
+      assert(reg == 0 && "Invalid reg. number");
+      return reg + 4+ 32 + 64;          // only one int CC reg
+    }
+    else if (reg==InvalidRegNum) {
       return InvalidRegNum;
+    }
     else  
-      assert(0 && "Invalid register class or reg number");
+      assert(0 && "Invalid register class");
     return 0;
   }
-
-  // given the unified register number, this gives the name
-  // for generating assembly code or debugging.
+  
+  // This method converts the unified number to the number in its class,
+  // and returns the class ID in regClassID.
+  inline int getClassRegNum(int ureg, unsigned& regClassID) const {
+    if      (ureg < 32)     { regClassID = IntRegClassID;     return ureg;    }
+    else if (ureg < 32+64)  { regClassID = FloatRegClassID;   return ureg-32; }
+    else if (ureg < 4 +96)  { regClassID = FloatCCRegClassID; return ureg-96; }
+    else if (ureg < 1 +100) { regClassID = IntCCRegClassID;   return ureg-100;}
+    else if (ureg == InvalidRegNum) { return InvalidRegNum; }
+    else { assert(0 && "Invalid unified register number"); }
+    return 0;
+  }
+  
+  // Returns the assembly-language name of the specified machine register.
   //
-  virtual const std::string getUnifiedRegName(int reg) const;
+  virtual const char * const getUnifiedRegName(int reg) const;
 
 
   // returns the # of bytes of stack space allocated for each register
@@ -423,21 +456,32 @@ public:
   const Value * getCallInstRetVal(const MachineInstr *CallMI) const;
   const Value * getCallInstIndirectAddrVal(const MachineInstr *CallMI) const;
 
-
   // The following methods are used to generate "copy" machine instructions
   // for an architecture.
   //
-  MachineInstr * cpReg2RegMI(unsigned SrcReg, unsigned DestReg,
-                            int RegType) const;
+  // The function regTypeNeedsScratchReg() can be used to check whether a
+  // scratch register is needed to copy a register of type `regType' to
+  // or from memory.  If so, such a scratch register can be provided by
+  // the caller (e.g., if it knows which regsiters are free); otherwise
+  // an arbitrary one will be chosen and spilled by the copy instructions.
+  //
+  bool regTypeNeedsScratchReg(int RegType,
+                              int& scratchRegClassId) const;
 
-  MachineInstr * cpReg2MemMI(unsigned SrcReg, unsigned DestPtrReg,
-                            int Offset, int RegType) const;
+  void cpReg2RegMI(std::vector<MachineInstr*>& mvec,
+                   unsigned SrcReg, unsigned DestReg,
+                   int RegType) const;
 
-  MachineInstr * cpMem2RegMI(unsigned SrcPtrReg, int Offset,
-                            unsigned DestReg, int RegType) const;
+  void cpReg2MemMI(std::vector<MachineInstr*>& mvec,
+                   unsigned SrcReg, unsigned DestPtrReg,
+                   int Offset, int RegType, int scratchReg = -1) const;
 
-  MachineInstr* cpValue2Value(Value *Src, Value *Dest) const;
+  void cpMem2RegMI(std::vector<MachineInstr*>& mvec,
+                   unsigned SrcPtrReg, int Offset, unsigned DestReg,
+                   int RegType, int scratchReg = -1) const;
 
+  void cpValue2Value(Value *Src, Value *Dest,
+                     std::vector<MachineInstr*>& mvec) const;
 
   // To see whether a register is a volatile (i.e., whehter it must be
   // preserved acorss calls)
@@ -456,7 +500,9 @@ public:
 
   // This method inserts the caller saving code for call instructions
   //
-  void insertCallerSavingCode(const MachineInstr *MInst, 
+  void insertCallerSavingCode(std::vector<MachineInstr*>& instrnsBefore,
+                              std::vector<MachineInstr*>& instrnsAfter,
+                              MachineInstr *MInst, 
                              const BasicBlock *BB, PhyRegAlloc &PRA ) const;
 };
 
@@ -494,44 +540,53 @@ public:
   UltraSparcFrameInfo(const TargetMachine &tgt) : MachineFrameInfo(tgt) {}
   
 public:
-  int  getStackFrameSizeAlignment   () const { return StackFrameSizeAlignment;}
-  int  getMinStackFrameSize         () const { return MinStackFrameSize; }
-  int  getNumFixedOutgoingArgs      () const { return NumFixedOutgoingArgs; }
-  int  getSizeOfEachArgOnStack      () const { return SizeOfEachArgOnStack; }
-  bool argsOnStackHaveFixedSize     () const { return true; }
+  // These methods provide constant parameters of the frame layout.
+  // 
+  int  getStackFrameSizeAlignment() const { return StackFrameSizeAlignment;}
+  int  getMinStackFrameSize()       const { return MinStackFrameSize; }
+  int  getNumFixedOutgoingArgs()    const { return NumFixedOutgoingArgs; }
+  int  getSizeOfEachArgOnStack()    const { return SizeOfEachArgOnStack; }
+  bool argsOnStackHaveFixedSize()   const { return true; }
+
+  // This method adjusts a stack offset to meet alignment rules of target.
+  // The fixed OFFSET (0x7ff) must be subtracted and the result aligned.
+  virtual int  adjustAlignment                  (int unalignedOffset,
+                                                 bool growUp,
+                                                 unsigned int align) const {
+    return unalignedOffset + (growUp? +1:-1)*((unalignedOffset-OFFSET) % align);
+  }
 
-  //
   // These methods compute offsets using the frame contents for a
-  // particular method.  The frame contents are obtained from the
-  // MachineCodeInfoForMethod object for the given method.
+  // particular function.  The frame contents are obtained from the
+  // MachineCodeInfoForMethod object for the given function.
   // 
-  int getFirstIncomingArgOffset  (MachineCodeForMethod& mcInfo,
-                                  bool& pos) const
+  int getFirstIncomingArgOffset  (MachineFunction& mcInfo,
+                                  bool& growUp) const
   {
-    pos = true;                         // arguments area grows upwards
+    growUp = true;                         // arguments area grows upwards
     return FirstIncomingArgOffsetFromFP;
   }
-  int getFirstOutgoingArgOffset  (MachineCodeForMethod& mcInfo,
-                                  bool& pos) const
+  int getFirstOutgoingArgOffset  (MachineFunction& mcInfo,
+                                  bool& growUp) const
   {
-    pos = true;                         // arguments area grows upwards
+    growUp = true;                         // arguments area grows upwards
     return FirstOutgoingArgOffsetFromSP;
   }
-  int getFirstOptionalOutgoingArgOffset(MachineCodeForMethod& mcInfo,
-                                        bool& pos)const
+  int getFirstOptionalOutgoingArgOffset(MachineFunction& mcInfo,
+                                        bool& growUp)const
   {
-    pos = true;                         // arguments area grows upwards
+    growUp = true;                         // arguments area grows upwards
     return FirstOptionalOutgoingArgOffsetFromSP;
   }
   
-  int getFirstAutomaticVarOffset (MachineCodeForMethod& mcInfo,
-                                  bool& pos) const;
-  int getRegSpillAreaOffset      (MachineCodeForMethod& mcInfo,
-                                  bool& pos) const;
-  int getTmpAreaOffset           (MachineCodeForMethod& mcInfo,
-                                  bool& pos) const;
-  int getDynamicAreaOffset       (MachineCodeForMethod& mcInfo,
-                                  bool& pos) const;
+  int getFirstAutomaticVarOffset (MachineFunction& mcInfo,
+                                  bool& growUp) const;
+  int getRegSpillAreaOffset      (MachineFunction& mcInfo,
+                                  bool& growUp) const;
+  int getTmpAreaOffset           (MachineFunction& mcInfo,
+                                  bool& growUp) const;
+  int getDynamicAreaOffset       (MachineFunction& mcInfo,
+                                  bool& growUp) const;
 
   //
   // These methods specify the base register used for each stack area
@@ -557,15 +612,58 @@ public:
   }
   
 private:
+  /*----------------------------------------------------------------------
+    This diagram shows the stack frame layout used by llc on Sparc V9.
+    Note that only the location of automatic variables, spill area,
+    temporary storage, and dynamically allocated stack area are chosen
+    by us.  The rest conform to the Sparc V9 ABI.
+    All stack addresses are offset by OFFSET = 0x7ff (2047).
+
+    Alignment assumpteions and other invariants:
+    (1) %sp+OFFSET and %fp+OFFSET are always aligned on 16-byte boundary
+    (2) Variables in automatic, spill, temporary, or dynamic regions
+        are aligned according to their size as in all memory accesses.
+    (3) Everything below the dynamically allocated stack area is only used
+        during a call to another function, so it is never needed when
+        the current function is active.  This is why space can be allocated
+        dynamically by incrementing %sp any time within the function.
+    
+    STACK FRAME LAYOUT:
+
+       ...
+       %fp+OFFSET+176      Optional extra incoming arguments# 1..N
+       %fp+OFFSET+168      Incoming argument #6
+       ...                 ...
+       %fp+OFFSET+128      Incoming argument #1
+       ...                 ...
+    ---%fp+OFFSET-0--------Bottom of caller's stack frame--------------------
+       %fp+OFFSET-8        Automatic variables <-- ****TOP OF STACK FRAME****
+                           Spill area
+                           Temporary storage
+       ...
+
+       %sp+OFFSET+176+8N   Bottom of dynamically allocated stack area
+       %sp+OFFSET+168+8N   Optional extra outgoing argument# N
+       ...                 ...
+       %sp+OFFSET+176      Optional extra outgoing argument# 1
+       %sp+OFFSET+168      Outgoing argument #6
+       ...                 ...
+       %sp+OFFSET+128      Outgoing argument #1
+       %sp+OFFSET+120      Save area for %i7
+       ...                 ...
+       %sp+OFFSET+0        Save area for %l0 <-- ****BOTTOM OF STACK FRAME****
+
+   *----------------------------------------------------------------------*/
+
   // All stack addresses must be offset by 0x7ff (2047) on Sparc V9.
   static const int OFFSET                                  = (int) 0x7ff;
   static const int StackFrameSizeAlignment                 =  16;
   static const int MinStackFrameSize                       = 176;
   static const int NumFixedOutgoingArgs                    =   6;
   static const int SizeOfEachArgOnStack                    =   8;
-  static const int StaticAreaOffsetFromFP                  =  0 + OFFSET;
   static const int FirstIncomingArgOffsetFromFP            = 128 + OFFSET;
   static const int FirstOptionalIncomingArgOffsetFromFP    = 176 + OFFSET;
+  static const int StaticAreaOffsetFromFP                  =   0 + OFFSET;
   static const int FirstOutgoingArgOffsetFromSP            = 128 + OFFSET;
   static const int FirstOptionalOutgoingArgOffsetFromSP    = 176 + OFFSET;
 };
@@ -585,6 +683,21 @@ public:
 };
 
 
+//---------------------------------------------------------------------------
+// class UltraSparcOptInfo 
+// 
+// Purpose:
+//   Interface to machine-level optimization routines for the UltraSPARC.
+//---------------------------------------------------------------------------
+
+class UltraSparcOptInfo: public MachineOptInfo {
+public:
+  UltraSparcOptInfo(const TargetMachine &T) : MachineOptInfo(T) {} 
+
+  virtual bool IsUselessCopy    (const MachineInstr* MI) const;
+};
+
+
 //---------------------------------------------------------------------------
 // class UltraSparcMachine 
 // 
@@ -596,31 +709,35 @@ public:
 //---------------------------------------------------------------------------
 
 class UltraSparc : public TargetMachine {
-private:
   UltraSparcInstrInfo instrInfo;
   UltraSparcSchedInfo schedInfo;
   UltraSparcRegInfo   regInfo;
   UltraSparcFrameInfo frameInfo;
   UltraSparcCacheInfo cacheInfo;
+  UltraSparcOptInfo   optInfo;
 public:
   UltraSparc();
-  
+
   virtual const MachineInstrInfo &getInstrInfo() const { return instrInfo; }
   virtual const MachineSchedInfo &getSchedInfo() const { return schedInfo; }
   virtual const MachineRegInfo   &getRegInfo()   const { return regInfo; }
   virtual const MachineFrameInfo &getFrameInfo() const { return frameInfo; }
   virtual const MachineCacheInfo &getCacheInfo() const { return cacheInfo; }
+  virtual const MachineOptInfo   &getOptInfo()   const { return optInfo; }
 
-  //
-  // addPassesToEmitAssembly - Add passes to the specified pass manager to get
-  // assembly langage code emited.  For sparc, we have to do ...
-  //
   virtual void addPassesToEmitAssembly(PassManager &PM, std::ostream &Out);
 
-private:
-  Pass *getMethodAsmPrinterPass(PassManager &PM, std::ostream &Out);
-  Pass *getModuleAsmPrinterPass(PassManager &PM, std::ostream &Out);
-  Pass *getEmitBytecodeToAsmPass(std::ostream &Out);
+  // getPrologEpilogCodeInserter - Inserts prolog/epilog code.
+  virtual Pass* getPrologEpilogInsertionPass();
+
+  // getFunctionAsmPrinterPass - Writes out machine code for a single function
+  virtual Pass* getFunctionAsmPrinterPass(std::ostream &Out);
+
+  // getModuleAsmPrinterPass - Writes generated machine code to assembly file.
+  virtual Pass* getModuleAsmPrinterPass(std::ostream &Out);
+
+  // getEmitBytecodeToAsmPass - Emits final LLVM bytecode to assembly file.
+  virtual Pass* getEmitBytecodeToAsmPass(std::ostream &Out);
 };
 
 #endif