Printing support for more stuff
[oota-llvm.git] / lib / Target / SparcV9 / SparcV9Internals.h
index b89fd8c8b54405ef2c310c7e1041e837a03ba479..31ec6a25b2a283965b18b106205730f2bdc266cc 100644 (file)
@@ -1,39 +1,26 @@
-// $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 "SparcRegClassInfo.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/CodeGen/RegClass.h"
+#include "llvm/Target/MachineRegInfo.h"
+#include "llvm/Target/MachineOptInfo.h"
 #include "llvm/Type.h"
 #include <sys/types.h>
 
 class LiveRange;
 class UltraSparc;
 class PhyRegAlloc;
-
-
-// OpCodeMask definitions for the Sparc V9
-// 
-const OpCodeMask       Immed           = 0x00002000; // immed or reg operand?
-const OpCodeMask       Annul           = 0x20000000; // annul delay instr?
-const OpCodeMask       PredictTaken    = 0x00080000; // predict branch taken?
-
+class Pass;
 
 enum SparcInstrSchedClass {
   SPARC_NONE,          /* Instructions with no scheduling restrictions */
@@ -88,21 +75,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();
 
   //
-  // All immediate constants are in position 0 except the
-  // store instructions.
+  // All immediate constants are in position 1 except the
+  // store instructions and SETxx.
   // 
-  virtual int getImmmedConstantPos(MachineOpCode opCode) const {
+  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,53 +109,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(Value* val,
+  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(Method* 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(Method* 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,
-                             Value* src,
-                             Instruction* dest,
-                             std::vector<MachineInstr*>& minstr) const;
-
-
+  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 CreateCopyInstructionsByType(const TargetMachine& target,
+                                       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;
 };
 
 
@@ -176,10 +215,7 @@ public:
 //
 //----------------------------------------------------------------------------
 
-class UltraSparcRegInfo : public MachineRegInfo
-{
- private:
-
+class UltraSparcRegInfo : public MachineRegInfo {
   // The actual register classes in the Sparc
   //
   enum RegClassIDs { 
@@ -207,10 +243,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;
@@ -228,120 +260,40 @@ 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 *const LR, const unsigned RegNo,
-                        const MachineInstr *MI,AddedInstrMapType &AIMap)const;
-
-  MachineInstr * getCopy2RegMI(const Value *SrcVal, const unsigned Reg,
-                              unsigned RegClassID) const ;
-
-  void suggestReg4RetAddr(const 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;
-  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
-
-  int getRegType(const LiveRange *const LR) const {
+  void suggestReg4RetAddr(MachineInstr *RetMI, 
+                         LiveRangeInfo &LRI) const;
 
-    unsigned Typ;
-
-    switch(  (LR->getRegClass())->getID() ) {
-
-    case IntRegClassID: return IntRegType; 
-
-    case FloatRegClassID: 
-                          Typ =  LR->getTypeID();
-                         if( Typ == Type::FloatTyID ) 
-                           return FPSingleRegType;
-                          else if( Typ == Type::DoubleTyID )
-                           return FPDoubleRegType;
-                          else assert(0 && "Unknown type in FloatRegClass");
-
-    case IntCCRegClassID: return IntCCRegType; 
-      
-    case FloatCCRegClassID: return FloatCCRegType ; 
-
-    default: assert( 0 && "Unknown reg class ID");
-      return 0;
-    }
-  }
-
-
-  int getRegType(const Value *const Val) const {
-
-    unsigned Typ;
-
-    switch( getRegClassIDOfValue(Val)  ) {
-
-    case IntRegClassID: return IntRegType; 
-
-    case FloatRegClassID: 
-                          Typ =  (Val->getType())->getPrimitiveID();
-                         if( Typ == Type::FloatTyID ) 
-                           return FPSingleRegType;
-                          else if( Typ == Type::DoubleTyID )
-                           return FPDoubleRegType;
-                          else assert(0 && "Unknown type in FloatRegClass");
-
-    case IntCCRegClassID: return IntCCRegType; 
-      
-    case FloatCCRegClassID: return FloatCCRegType ; 
-
-    default: assert( 0 && "Unknown reg class ID");
-      return 0;
-    }
-
-  }
-
-
-  int getRegType(int reg) const {
-    if( reg < 32 ) 
-      return IntRegType;
-    else if ( reg < (32 + 32) )
-      return FPSingleRegType;
-    else if ( reg < (64 + 32) )
-      return FPDoubleRegType;
-    else if( reg < (64+32+4) )
-      return FloatCCRegType;
-    else if( reg < (64+32+4+2) )  
-      return IntCCRegType;             
-    else 
-      assert(0 && "Invalid register number in getRegType");
-  }
-
-
-
-
-  // The following methods are used to generate copy instructions to move
-  // data between condition code registers
-  //
-  MachineInstr * cpCCR2IntMI(const unsigned IntReg) const;
-  MachineInstr * cpInt2CCRMI(const unsigned IntReg) const;
+  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 unifiedRegNum) const;
 
   // Used to generate a copy instruction based on the register class of
   // value.
   //
-  MachineInstr * cpValue2RegMI(Value * Val,  const unsigned DestReg,
-                              const int RegType) const;
+  MachineInstr *cpValue2RegMI(Value *Val,  unsigned DestReg,
+                              int RegType) const;
 
 
   // 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,
@@ -353,174 +305,132 @@ 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;
-
-
-
- public:
-
-  // constructor
-  //
-  UltraSparcRegInfo(const TargetMachine& tgt ) :    
-    MachineRegInfo(tgt),
-    UltraSparcInfo(& (const UltraSparc&) tgt), 
-    NumOfIntArgRegs(6), 
-    NumOfFloatArgRegs(32),
-    InvalidRegNum(1000) {
-   
-    MachineRegClassArr.push_back( new SparcIntRegClass(IntRegClassID) );
-    MachineRegClassArr.push_back( new SparcFloatRegClass(FloatRegClassID) );
-    MachineRegClassArr.push_back( new SparcIntCCRegClass(IntCCRegClassID) );
-    MachineRegClassArr.push_back( new SparcFloatCCRegClass(FloatCCRegClassID));
-
-    assert( SparcFloatRegOrder::StartOfNonVolatileRegs == 32 && 
-           "32 Float regs are used for float arg passing");
-
-  }
-
-
-  ~UltraSparcRegInfo(void) { }          // empty destructor 
+  // 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
+  // To find the register class used for a specified Type
   //
-  inline const UltraSparc & getUltraSparcInfo() const { 
-    return *UltraSparcInfo;
-  }
-
+  unsigned getRegClassIDOfType(const Type *type,
+                               bool isCCReg = false) const;
 
   // To find the register class of a Value
   //
-  inline unsigned getRegClassIDOfValue (const Value *const Val,
-                                bool isCCReg = false) const {
-
-    Type::PrimitiveID ty = (Val->getType())->getPrimitiveID();
-
-    unsigned res;
-    
-    if( (ty && ty <= Type::LongTyID) || (ty == Type::LabelTyID) ||
-       (ty == Type::MethodTyID) ||  (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;
+  inline unsigned getRegClassIDOfValue(const Value *Val,
+                                       bool isCCReg = false) const {
+    return getRegClassIDOfType(Val->getType(), isCCReg);
   }
 
-
-
-  // returns the register that contains always zero
-  // this is the unified register number
+  // To find the register class to which a specified register belongs
   //
-  inline int getZeroRegNum() const { return SparcIntRegOrder::g0; }
+  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;
 
-  // returns the reg used for pushing the address when a method is called.
-  // This can be used for other purposes between calls
+  // getCallAddressReg - returns the reg used for pushing the address when a
+  // function is called. This can be used for other purposes between calls
   //
-  unsigned getCallAddressReg() const  { return SparcIntRegOrder::o7; }
+  unsigned getCallAddressReg() const;
 
   // Returns the register containing the return address.
   // It should be made sure that this  register contains the return 
   // value when a return instruction is reached.
   //
-  unsigned getReturnAddressReg()  const { return SparcIntRegOrder::i7; }
-
-
+  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 Method *const Meth, 
+  void suggestRegs4MethodArgs(const Function *Meth, 
                              LiveRangeInfo& LRI) const;
 
-  void suggestRegs4CallArgs(const MachineInstr *const CallMI, 
-                           LiveRangeInfo& LRI,
-                            std::vector<RegClass *> RCL) const; 
+  void suggestRegs4CallArgs(MachineInstr *CallMI, 
+                           LiveRangeInfo& LRI) const; 
 
-  void suggestReg4RetValue(const MachineInstr *const RetMI, 
+  void suggestReg4RetValue(MachineInstr *RetMI, 
                            LiveRangeInfo& LRI) const;
+  
+  void colorMethodArgs(const Function *Meth,  LiveRangeInfo &LRI,
+                      AddedInstrns *FirstAI) const;
 
-
-  void colorMethodArgs(const Method *const Meth,  LiveRangeInfo& LRI,
-                      AddedInstrns *const FirstAI) const;
-
-  void colorCallArgs(const MachineInstr *const CallMI, LiveRangeInfo& LRI,
-                    AddedInstrns *const CallAI,  PhyRegAlloc &PRA,
+  void colorCallArgs(MachineInstr *CallMI, LiveRangeInfo &LRI,
+                    AddedInstrns *CallAI,  PhyRegAlloc &PRA,
                     const BasicBlock *BB) const;
 
-  void colorRetValue(const MachineInstr *const RetI,   LiveRangeInfo& LRI,
-                    AddedInstrns *const RetAI) const;
-
+  void colorRetValue(MachineInstr *RetI,   LiveRangeInfo& LRI,
+                    AddedInstrns *RetAI) const;
 
 
   // method used for printing a register for debugging purposes
   //
-  static void printReg(const LiveRange *const LR)  ;
+  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 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.
-  //
-  inline const std::string getUnifiedRegName(int reg) const {
-    if( reg < 32 ) 
-      return SparcIntRegOrder::getRegName(reg);
-    else if ( reg < (64 + 32) )
-      return SparcFloatRegOrder::getRegName( reg  - 32);                  
-    else if( reg < (64+32+4) )
-      return SparcFloatCCRegOrder::getRegName( reg -32 - 64);
-    else if( reg < (64+32+4+2) )    // two names: %xcc and %ccr
-      return SparcIntCCRegOrder::getRegName( reg -32 - 64 - 4);             
-    else if (reg== InvalidRegNum)       //****** TODO: Remove */
-      return "<*NoReg*>";
-    else 
-      assert(0 && "Invalid register number");
-    return "";
-  }
-
-
-
-  // The fllowing methods are used by instruction selection
-  //
-  inline unsigned getRegNumInCallersWindow(int reg) {
-    if (reg == InvalidRegNum || reg >= 32)
-      return reg;
-    return SparcIntRegOrder::getRegNumInCallersWindow(reg);
-  }
   
-  inline bool mustBeRemappedInCallersWindow(int reg) {
-    return (reg != InvalidRegNum && reg < 32);
+  // 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 char * const getUnifiedRegName(int reg) const;
 
 
   // returns the # of bytes of stack space allocated for each register
@@ -528,58 +438,65 @@ class UltraSparcRegInfo : public MachineRegInfo
   // register types. We can optimize this later if necessary to save stack
   // space (However, should make sure that stack alignment is correct)
   //
-  inline int getSpilledRegSize(const int RegType) const {
+  inline int getSpilledRegSize(int RegType) const {
     return 8;
   }
 
 
-  // To obtain the return value contained in a CALL machine instruction
+  // To obtain the return value and the indirect call address (if any)
+  // contained in a CALL machine instruction
   //
   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(const unsigned SrcReg, const unsigned DestReg,
-                            const 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(const unsigned SrcReg,  const unsigned DestPtrReg,
-                            const int Offset, const int RegType) const;
+  void cpReg2RegMI(std::vector<MachineInstr*>& mvec,
+                   unsigned SrcReg, unsigned DestReg,
+                   int RegType) const;
 
-  MachineInstr * cpMem2RegMI(const unsigned SrcPtrReg, const int Offset,
-                            const unsigned DestReg, const 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)
   //
-  inline bool isRegVolatile(const int RegClassID, const int Reg) const {
-    return  (MachineRegClassArr[RegClassID])->isRegVolatile(Reg);
+  inline bool isRegVolatile(int RegClassID, int Reg) const {
+    return MachineRegClassArr[RegClassID]->isRegVolatile(Reg);
   }
 
 
-  inline unsigned getFramePointer() const {
-    return SparcIntRegOrder::i6;
-  }
-
-  inline unsigned getStackPointer() const {
-    return SparcIntRegOrder::o6;
-  }
+  virtual unsigned getFramePointer() const;
+  virtual unsigned getStackPointer() const;
 
-  inline int getInvalidRegNum() const {
+  virtual int getInvalidRegNum() const {
     return InvalidRegNum;
   }
 
-
-
   // 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;
-
 };
 
 
@@ -596,10 +513,9 @@ class UltraSparcRegInfo : public MachineRegInfo
 
 class UltraSparcSchedInfo: public MachineSchedInfo {
 public:
-  /*ctor*/        UltraSparcSchedInfo  (const TargetMachine& tgt);
-  /*dtor*/ virtual ~UltraSparcSchedInfo        () {}
+  UltraSparcSchedInfo(const TargetMachine &tgt);
 protected:
-  virtual void initializeResources     ();
+  virtual void initializeResources();
 };
 
 
@@ -614,47 +530,56 @@ protected:
 
 class UltraSparcFrameInfo: public MachineFrameInfo {
 public:
-  /*ctor*/ UltraSparcFrameInfo(const TargetMachine& tgt) : MachineFrameInfo(tgt) {}
+  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
@@ -680,15 +605,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;
 };
@@ -708,6 +676,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 
 // 
@@ -719,30 +702,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);
+  virtual bool addPassesToEmitAssembly(PassManager &PM, std::ostream &Out);
 
-private:
-  Pass *getMethodAsmPrinterPass(PassManager &PM, std::ostream &Out);
-  Pass *getModuleAsmPrinterPass(PassManager &PM, std::ostream &Out);
+  // getPrologEpilogInsertionPass - Inserts prolog/epilog code.
+  Pass* getPrologEpilogInsertionPass();
+
+  // getFunctionAsmPrinterPass - Writes out machine code for a single function
+  Pass* getFunctionAsmPrinterPass(std::ostream &Out);
+
+  // getModuleAsmPrinterPass - Writes generated machine code to assembly file.
+  Pass* getModuleAsmPrinterPass(std::ostream &Out);
+
+  // getEmitBytecodeToAsmPass - Emits final LLVM bytecode to assembly file.
+  Pass* getEmitBytecodeToAsmPass(std::ostream &Out);
 };
 
 #endif