GCC 3.1 changes, finally the burm file builds the FIRST time a clean directory is...
[oota-llvm.git] / lib / Target / SparcV9 / SparcV9Internals.h
index de8643a3358ad4577e43eb5411efc1b8b071d41d..aea653ebdb2897de623684f5635445e85a593567 100644 (file)
@@ -1,4 +1,3 @@
-// $Id$ -*- C++ -*--
 //***************************************************************************
 // File:
 //     SparcInternals.h
 #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/Type.h"
 #include <sys/types.h>
 
 class LiveRange;
 class UltraSparc;
 class PhyRegAlloc;
+class Pass;
 
+Pass *createPrologEpilogCodeInserter(TargetMachine &TM);
 
 // OpCodeMask definitions for the Sparc V9
 // 
@@ -93,16 +91,16 @@ public:
   /*ctor*/     UltraSparcInstrInfo(const TargetMachine& tgt);
 
   //
-  // All immediate constants are in position 0 except the
+  // All immediate constants are in position 1 except the
   // store instructions.
   // 
-  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
+        return (opCode >= STB && opCode <= STXFSR)? 2 : 1;
       }
     else
       return -1;
@@ -124,48 +122,69 @@ public:
   //-------------------------------------------------------------------------
   
   // 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'.
-  // 
-  virtual void  CreateCodeToLoadConst(Value* val,
+  // 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(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.
-  // 
-  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;
-
-
+  // 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 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).
+  // Any stack space required is allocated via mcff.
+  // 
+  virtual void CreateSignExtensionInstructions(const TargetMachine& target,
+                                       Function* F,
+                                       Value* unsignedSrcVal,
+                                       unsigned int srcSizeInBits,
+                                       Value* dest,
+                                       std::vector<MachineInstr*>& mvec,
+                                       MachineCodeForInstruction& mcfi) const;
 };
 
 
@@ -176,10 +195,7 @@ public:
 //
 //----------------------------------------------------------------------------
 
-class UltraSparcRegInfo : public MachineRegInfo
-{
- private:
-
+class UltraSparcRegInfo : public MachineRegInfo {
   // The actual register classes in the Sparc
   //
   enum RegClassIDs { 
@@ -228,120 +244,41 @@ 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(MachineInstr *RetMI, 
+                         LiveRangeInfo &LRI) const;
 
-  void suggestReg4RetAddr(const MachineInstr * RetMI, 
-                         LiveRangeInfo& LRI) const;
-
-  void suggestReg4CallAddr(const MachineInstr * CallMI, LiveRangeInfo& LRI,
+  void suggestReg4CallAddr(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 {
-
-    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 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 +290,140 @@ 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
   //
-  inline const UltraSparc & getUltraSparcInfo() const { 
+  inline const UltraSparc &getUltraSparcInfo() const { 
     return *UltraSparcInfo;
   }
 
+  // To find the register class used for a specified Type
+  //
+  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, 
+  void suggestRegs4CallArgs(MachineInstr *CallMI, 
                            LiveRangeInfo& LRI,
                             std::vector<RegClass *> RCL) 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 std::string getUnifiedRegName(int reg) const;
 
 
   // returns the # of bytes of stack space allocated for each register
@@ -528,745 +431,67 @@ 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;
-
-};
-
-
-
-/*---------------------------------------------------------------------------
-Scheduling guidelines for SPARC IIi:
-
-I-Cache alignment rules (pg 326)
--- Align a branch target instruction so that it's entire group is within
-   the same cache line (may be 1-4 instructions).
-** Don't let a branch that is predicted taken be the last instruction
-   on an I-cache line: delay slot will need an entire line to be fetched
--- Make a FP instruction or a branch be the 4th instruction in a group.
-   For branches, there are tradeoffs in reordering to make this happen
-   (see pg. 327).
-** Don't put a branch in a group that crosses a 32-byte boundary!
-   An artificial branch is inserted after every 32 bytes, and having
-   another branch will force the group to be broken into 2 groups. 
-
-iTLB rules:
--- Don't let a loop span two memory pages, if possible
-
-Branch prediction performance:
--- Don't make the branch in a delay slot the target of a branch
--- Try not to have 2 predicted branches within a group of 4 instructions
-   (because each such group has a single branch target field).
--- Try to align branches in slots 0, 2, 4 or 6 of a cache line (to avoid
-   the wrong prediction bits being used in some cases).
-
-D-Cache timing constraints:
--- Signed int loads of less than 64 bits have 3 cycle latency, not 2
--- All other loads that hit in D-Cache have 2 cycle latency
--- All loads are returned IN ORDER, so a D-Cache miss will delay a later hit
--- Mis-aligned loads or stores cause a trap.  In particular, replace
-   mis-aligned FP double precision l/s with 2 single-precision l/s.
--- Simulations of integer codes show increase in avg. group size of
-   33% when code (including esp. non-faulting loads) is moved across
-   one branch, and 50% across 2 branches.
-
-E-Cache timing constraints:
--- Scheduling for E-cache (D-Cache misses) is effective (due to load buffering)
-
-Store buffer timing constraints:
--- Stores can be executed in same cycle as instruction producing the value
--- Stores are buffered and have lower priority for E-cache until
-   highwater mark is reached in the store buffer (5 stores)
-
-Pipeline constraints:
--- Shifts can only use IEU0.
--- CC setting instructions can only use IEU1.
--- Several other instructions must only use IEU1:
-   EDGE(?), ARRAY(?), CALL, JMPL, BPr, PST, and FCMP.
--- Two instructions cannot store to the same register file in a single cycle
-   (single write port per file).
-
-Issue and grouping constraints:
--- FP and branch instructions must use slot 4.
--- Shift instructions cannot be grouped with other IEU0-specific instructions.
--- CC setting instructions cannot be grouped with other IEU1-specific instrs.
--- Several instructions must be issued in a single-instruction group:
-       MOVcc or MOVr, MULs/x and DIVs/x, SAVE/RESTORE, many others
--- A CALL or JMPL breaks a group, ie, is not combined with subsequent instrs.
--- 
--- 
-
-Branch delay slot scheduling rules:
--- A CTI couple (two back-to-back CTI instructions in the dynamic stream)
-   has a 9-instruction penalty: the entire pipeline is flushed when the
-   second instruction reaches stage 9 (W-Writeback).
--- Avoid putting multicycle instructions, and instructions that may cause
-   load misses, in the delay slot of an annulling branch.
--- Avoid putting WR, SAVE..., RESTORE and RETURN instructions in the
-   delay slot of an annulling branch.
-
- *--------------------------------------------------------------------------- */
-
-//---------------------------------------------------------------------------
-// List of CPUResources for UltraSPARC IIi.
-//---------------------------------------------------------------------------
-
-const CPUResource  AllIssueSlots(   "All Instr Slots", 4);
-const CPUResource  IntIssueSlots(   "Int Instr Slots", 3);
-const CPUResource  First3IssueSlots("Instr Slots 0-3", 3);
-const CPUResource  LSIssueSlots(    "Load-Store Instr Slot", 1);
-const CPUResource  CTIIssueSlots(   "Ctrl Transfer Instr Slot", 1);
-const CPUResource  FPAIssueSlots(   "Int Instr Slot 1", 1);
-const CPUResource  FPMIssueSlots(   "Int Instr Slot 1", 1);
-
-// IEUN instructions can use either Alu and should use IAluN.
-// IEU0 instructions must use Alu 1 and should use both IAluN and IAlu0. 
-// IEU1 instructions must use Alu 2 and should use both IAluN and IAlu1. 
-const CPUResource  IAluN("Int ALU 1or2", 2);
-const CPUResource  IAlu0("Int ALU 1",    1);
-const CPUResource  IAlu1("Int ALU 2",    1);
-
-const CPUResource  LSAluC1("Load/Store Unit Addr Cycle", 1);
-const CPUResource  LSAluC2("Load/Store Unit Issue Cycle", 1);
-const CPUResource  LdReturn("Load Return Unit", 1);
-
-const CPUResource  FPMAluC1("FP Mul/Div Alu Cycle 1", 1);
-const CPUResource  FPMAluC2("FP Mul/Div Alu Cycle 2", 1);
-const CPUResource  FPMAluC3("FP Mul/Div Alu Cycle 3", 1);
-
-const CPUResource  FPAAluC1("FP Other Alu Cycle 1", 1);
-const CPUResource  FPAAluC2("FP Other Alu Cycle 2", 1);
-const CPUResource  FPAAluC3("FP Other Alu Cycle 3", 1);
-
-const CPUResource  IRegReadPorts("Int Reg ReadPorts", INT_MAX);         // CHECK
-const CPUResource  IRegWritePorts("Int Reg WritePorts", 2);     // CHECK
-const CPUResource  FPRegReadPorts("FP Reg Read Ports", INT_MAX); // CHECK
-const CPUResource  FPRegWritePorts("FP Reg Write Ports", 1);    // CHECK
-
-const CPUResource  CTIDelayCycle( "CTI  delay cycle", 1);
-const CPUResource  FCMPDelayCycle("FCMP delay cycle", 1);
-
-
-//---------------------------------------------------------------------------
-// const InstrClassRUsage SparcRUsageDesc[]
-// 
-// Purpose:
-//   Resource usage information for instruction in each scheduling class.
-//   The InstrRUsage Objects for individual classes are specified first.
-//   Note that fetch and decode are decoupled from the execution pipelines
-//   via an instr buffer, so they are not included in the cycles below.
-//---------------------------------------------------------------------------
-
-const InstrClassRUsage NoneClassRUsage = {
-  SPARC_NONE,
-  /*totCycles*/ 7,
-  
-  /* maxIssueNum */ 4,
-  /* isSingleIssue */ false,
-  /* breaksGroup */ false,
-  /* numBubbles */ 0,
-  
-  /*numSlots*/ 4,
-  /* feasibleSlots[] */ { 0, 1, 2, 3 },
-  
-  /*numEntries*/ 0,
-  /* V[] */ {
-    /*Cycle G */
-    /*Ccle E */
-    /*Cycle C */
-    /*Cycle N1*/
-    /*Cycle N1*/
-    /*Cycle N1*/
-    /*Cycle W */
-  }
-};
-
-const InstrClassRUsage IEUNClassRUsage = {
-  SPARC_IEUN,
-  /*totCycles*/ 7,
-  
-  /* maxIssueNum */ 3,
-  /* isSingleIssue */ false,
-  /* breaksGroup */ false,
-  /* numBubbles */ 0,
-  
-  /*numSlots*/ 3,
-  /* feasibleSlots[] */ { 0, 1, 2 },
-  
-  /*numEntries*/ 4,
-  /* V[] */ {
-    /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
-                 { IntIssueSlots.rid, 0, 1 },
-    /*Cycle E */ { IAluN.rid, 1, 1 },
-    /*Cycle C */
-    /*Cycle N1*/
-    /*Cycle N1*/
-    /*Cycle N1*/
-    /*Cycle W */ { IRegWritePorts.rid, 6, 1  }
-  }
-};
-
-const InstrClassRUsage IEU0ClassRUsage = {
-  SPARC_IEU0,
-  /*totCycles*/ 7,
-  
-  /* maxIssueNum */ 1,
-  /* isSingleIssue */ false,
-  /* breaksGroup */ false,
-  /* numBubbles */ 0,
-  
-  /*numSlots*/ 3,
-  /* feasibleSlots[] */ { 0, 1, 2 },
-  
-  /*numEntries*/ 5,
-  /* V[] */ {
-    /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
-                 { IntIssueSlots.rid, 0, 1 },
-    /*Cycle E */ { IAluN.rid, 1, 1 },
-                 { IAlu0.rid, 1, 1 },
-    /*Cycle C */
-    /*Cycle N1*/
-    /*Cycle N1*/
-    /*Cycle N1*/
-    /*Cycle W */ { IRegWritePorts.rid, 6, 1 }
-  }
-};
-
-const InstrClassRUsage IEU1ClassRUsage = {
-  SPARC_IEU1,
-  /*totCycles*/ 7,
-  
-  /* maxIssueNum */ 1,
-  /* isSingleIssue */ false,
-  /* breaksGroup */ false,
-  /* numBubbles */ 0,
-  
-  /*numSlots*/ 3,
-  /* feasibleSlots[] */ { 0, 1, 2 },
-  
-  /*numEntries*/ 5,
-  /* V[] */ {
-    /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
-               { IntIssueSlots.rid, 0, 1 },
-    /*Cycle E */ { IAluN.rid, 1, 1 },
-               { IAlu1.rid, 1, 1 },
-    /*Cycle C */
-    /*Cycle N1*/
-    /*Cycle N1*/
-    /*Cycle N1*/
-    /*Cycle W */ { IRegWritePorts.rid, 6, 1 }
-  }
-};
-
-const InstrClassRUsage FPMClassRUsage = {
-  SPARC_FPM,
-  /*totCycles*/ 7,
-  
-  /* maxIssueNum */ 1,
-  /* isSingleIssue */ false,
-  /* breaksGroup */ false,
-  /* numBubbles */ 0,
-  
-  /*numSlots*/ 4,
-  /* feasibleSlots[] */ { 0, 1, 2, 3 },
-  
-  /*numEntries*/ 7,
-  /* V[] */ {
-    /*Cycle G */ { AllIssueSlots.rid,   0, 1 },
-                 { FPMIssueSlots.rid,   0, 1 },
-    /*Cycle E */ { FPRegReadPorts.rid,  1, 1 },
-    /*Cycle C */ { FPMAluC1.rid,        2, 1 },
-    /*Cycle N1*/ { FPMAluC2.rid,        3, 1 },
-    /*Cycle N1*/ { FPMAluC3.rid,        4, 1 },
-    /*Cycle N1*/
-    /*Cycle W */ { FPRegWritePorts.rid, 6, 1 }
-  }
-};
-
-const InstrClassRUsage FPAClassRUsage = {
-  SPARC_FPA,
-  /*totCycles*/ 7,
-  
-  /* maxIssueNum */ 1,
-  /* isSingleIssue */ false,
-  /* breaksGroup */ false,
-  /* numBubbles */ 0,
-  
-  /*numSlots*/ 4,
-  /* feasibleSlots[] */ { 0, 1, 2, 3 },
-  
-  /*numEntries*/ 7,
-  /* V[] */ {
-    /*Cycle G */ { AllIssueSlots.rid,   0, 1 },
-                 { FPAIssueSlots.rid,   0, 1 },
-    /*Cycle E */ { FPRegReadPorts.rid,  1, 1 },
-    /*Cycle C */ { FPAAluC1.rid,        2, 1 },
-    /*Cycle N1*/ { FPAAluC2.rid,        3, 1 },
-    /*Cycle N1*/ { FPAAluC3.rid,        4, 1 },
-    /*Cycle N1*/
-    /*Cycle W */ { FPRegWritePorts.rid, 6, 1 }
-  }
-};
-
-const InstrClassRUsage LDClassRUsage = {
-  SPARC_LD,
-  /*totCycles*/ 7,
-  
-  /* maxIssueNum */ 1,
-  /* isSingleIssue */ false,
-  /* breaksGroup */ false,
-  /* numBubbles */ 0,
-  
-  /*numSlots*/ 3,
-  /* feasibleSlots[] */ { 0, 1, 2, },
-  
-  /*numEntries*/ 6,
-  /* V[] */ {
-    /*Cycle G */ { AllIssueSlots.rid,    0, 1 },
-                 { First3IssueSlots.rid, 0, 1 },
-                 { LSIssueSlots.rid,     0, 1 },
-    /*Cycle E */ { LSAluC1.rid,          1, 1 },
-    /*Cycle C */ { LSAluC2.rid,          2, 1 },
-                 { LdReturn.rid,         2, 1 },
-    /*Cycle N1*/
-    /*Cycle N1*/
-    /*Cycle N1*/
-    /*Cycle W */ { IRegWritePorts.rid,   6, 1 }
-  }
 };
 
-const InstrClassRUsage STClassRUsage = {
-  SPARC_ST,
-  /*totCycles*/ 7,
-  
-  /* maxIssueNum */ 1,
-  /* isSingleIssue */ false,
-  /* breaksGroup */ false,
-  /* numBubbles */ 0,
-  
-  /*numSlots*/ 3,
-  /* feasibleSlots[] */ { 0, 1, 2 },
-  
-  /*numEntries*/ 4,
-  /* V[] */ {
-    /*Cycle G */ { AllIssueSlots.rid,    0, 1 },
-                 { First3IssueSlots.rid, 0, 1 },
-                 { LSIssueSlots.rid,     0, 1 },
-    /*Cycle E */ { LSAluC1.rid,          1, 1 },
-    /*Cycle C */ { LSAluC2.rid,          2, 1 }
-    /*Cycle N1*/
-    /*Cycle N1*/
-    /*Cycle N1*/
-    /*Cycle W */
-  }
-};
-
-const InstrClassRUsage CTIClassRUsage = {
-  SPARC_CTI,
-  /*totCycles*/ 7,
-  
-  /* maxIssueNum */ 1,
-  /* isSingleIssue */ false,
-  /* breaksGroup */ false,
-  /* numBubbles */ 0,
-  
-  /*numSlots*/ 4,
-  /* feasibleSlots[] */ { 0, 1, 2, 3 },
-  
-  /*numEntries*/ 4,
-  /* V[] */ {
-    /*Cycle G */ { AllIssueSlots.rid,    0, 1 },
-                { CTIIssueSlots.rid,    0, 1 },
-    /*Cycle E */ { IAlu0.rid,            1, 1 },
-    /*Cycles E-C */ { CTIDelayCycle.rid, 1, 2 }
-    /*Cycle C */             
-    /*Cycle N1*/
-    /*Cycle N1*/
-    /*Cycle N1*/
-    /*Cycle W */
-  }
-};
-
-const InstrClassRUsage SingleClassRUsage = {
-  SPARC_SINGLE,
-  /*totCycles*/ 7,
-  
-  /* maxIssueNum */ 1,
-  /* isSingleIssue */ true,
-  /* breaksGroup */ false,
-  /* numBubbles */ 0,
-  
-  /*numSlots*/ 1,
-  /* feasibleSlots[] */ { 0 },
-  
-  /*numEntries*/ 5,
-  /* V[] */ {
-    /*Cycle G */ { AllIssueSlots.rid,    0, 1 },
-                 { AllIssueSlots.rid,    0, 1 },
-                 { AllIssueSlots.rid,    0, 1 },
-                 { AllIssueSlots.rid,    0, 1 },
-    /*Cycle E */ { IAlu0.rid,            1, 1 }
-    /*Cycle C */
-    /*Cycle N1*/
-    /*Cycle N1*/
-    /*Cycle N1*/
-    /*Cycle W */
-  }
-};
-
-
-const InstrClassRUsage SparcRUsageDesc[] = {
-  NoneClassRUsage,
-  IEUNClassRUsage,
-  IEU0ClassRUsage,
-  IEU1ClassRUsage,
-  FPMClassRUsage,
-  FPAClassRUsage,
-  CTIClassRUsage,
-  LDClassRUsage,
-  STClassRUsage,
-  SingleClassRUsage
-};
-
-
-//---------------------------------------------------------------------------
-// const InstrIssueDelta  SparcInstrIssueDeltas[]
-// 
-// Purpose:
-//   Changes to issue restrictions information in InstrClassRUsage for
-//   instructions that differ from other instructions in their class.
-//---------------------------------------------------------------------------
-
-const InstrIssueDelta  SparcInstrIssueDeltas[] = {
-
-  // opCode,  isSingleIssue,  breaksGroup,  numBubbles
-
-                               // Special cases for single-issue only
-                               // Other single issue cases are below.
-//{ LDDA,      true,   true,   0 },
-//{ STDA,      true,   true,   0 },
-//{ LDDF,      true,   true,   0 },
-//{ LDDFA,     true,   true,   0 },
-  { ADDC,      true,   true,   0 },
-  { ADDCcc,    true,   true,   0 },
-  { SUBC,      true,   true,   0 },
-  { SUBCcc,    true,   true,   0 },
-//{ LDSTUB,    true,   true,   0 },
-//{ SWAP,      true,   true,   0 },
-//{ SWAPA,     true,   true,   0 },
-//{ CAS,       true,   true,   0 },
-//{ CASA,      true,   true,   0 },
-//{ CASX,      true,   true,   0 },
-//{ CASXA,     true,   true,   0 },
-//{ LDFSR,     true,   true,   0 },
-//{ LDFSRA,    true,   true,   0 },
-//{ LDXFSR,    true,   true,   0 },
-//{ LDXFSRA,   true,   true,   0 },
-//{ STFSR,     true,   true,   0 },
-//{ STFSRA,    true,   true,   0 },
-//{ STXFSR,    true,   true,   0 },
-//{ STXFSRA,   true,   true,   0 },
-//{ SAVED,     true,   true,   0 },
-//{ RESTORED,  true,   true,   0 },
-//{ FLUSH,     true,   true,   9 },
-//{ FLUSHW,    true,   true,   9 },
-//{ ALIGNADDR, true,   true,   0 },
-  { RETURN,    true,   true,   0 },
-//{ DONE,      true,   true,   0 },
-//{ RETRY,     true,   true,   0 },
-//{ TCC,       true,   true,   0 },
-//{ SHUTDOWN,  true,   true,   0 },
-  
-                               // Special cases for breaking group *before*
-                               // CURRENTLY NOT SUPPORTED!
-  { CALL,      false,  false,  0 },
-  { JMPLCALL,  false,  false,  0 },
-  { JMPLRET,   false,  false,  0 },
-  
-                               // Special cases for breaking the group *after*
-  { MULX,      true,   true,   (4+34)/2 },
-  { FDIVS,     false,  true,   0 },
-  { FDIVD,     false,  true,   0 },
-  { FDIVQ,     false,  true,   0 },
-  { FSQRTS,    false,  true,   0 },
-  { FSQRTD,    false,  true,   0 },
-  { FSQRTQ,    false,  true,   0 },
-//{ FCMP{LE,GT,NE,EQ}, false, true, 0 },
-  
-                               // Instructions that introduce bubbles
-//{ MULScc,    true,   true,   2 },
-//{ SMULcc,    true,   true,   (4+18)/2 },
-//{ UMULcc,    true,   true,   (4+19)/2 },
-  { SDIVX,     true,   true,   68 },
-  { UDIVX,     true,   true,   68 },
-//{ SDIVcc,    true,   true,   36 },
-//{ UDIVcc,    true,   true,   37 },
-  { WRCCR,     true,   true,   4 },
-//{ WRPR,      true,   true,   4 },
-//{ RDCCR,     true,   true,   0 }, // no bubbles after, but see below
-//{ RDPR,      true,   true,   0 },
-};
-
-
-//---------------------------------------------------------------------------
-// const InstrRUsageDelta SparcInstrUsageDeltas[]
-// 
-// Purpose:
-//   Changes to resource usage information in InstrClassRUsage for
-//   instructions that differ from other instructions in their class.
-//---------------------------------------------------------------------------
-
-const InstrRUsageDelta SparcInstrUsageDeltas[] = {
-
-  // MachineOpCode, Resource, Start cycle, Num cycles
-
-  // 
-  // JMPL counts as a load/store instruction for issue!
-  //
-  { JMPLCALL, LSIssueSlots.rid,  0,  1 },
-  { JMPLRET,  LSIssueSlots.rid,  0,  1 },
-  
-  // 
-  // Many instructions cannot issue for the next 2 cycles after an FCMP
-  // We model that with a fake resource FCMPDelayCycle.
-  // 
-  { FCMPS,    FCMPDelayCycle.rid, 1, 3 },
-  { FCMPD,    FCMPDelayCycle.rid, 1, 3 },
-  { FCMPQ,    FCMPDelayCycle.rid, 1, 3 },
-  
-  { MULX,     FCMPDelayCycle.rid, 1, 1 },
-  { SDIVX,    FCMPDelayCycle.rid, 1, 1 },
-  { UDIVX,    FCMPDelayCycle.rid, 1, 1 },
-//{ SMULcc,   FCMPDelayCycle.rid, 1, 1 },
-//{ UMULcc,   FCMPDelayCycle.rid, 1, 1 },
-//{ SDIVcc,   FCMPDelayCycle.rid, 1, 1 },
-//{ UDIVcc,   FCMPDelayCycle.rid, 1, 1 },
-  { STD,      FCMPDelayCycle.rid, 1, 1 },
-  { FMOVRSZ,  FCMPDelayCycle.rid, 1, 1 },
-  { FMOVRSLEZ,FCMPDelayCycle.rid, 1, 1 },
-  { FMOVRSLZ, FCMPDelayCycle.rid, 1, 1 },
-  { FMOVRSNZ, FCMPDelayCycle.rid, 1, 1 },
-  { FMOVRSGZ, FCMPDelayCycle.rid, 1, 1 },
-  { FMOVRSGEZ,FCMPDelayCycle.rid, 1, 1 },
-  
-  // 
-  // Some instructions are stalled in the GROUP stage if a CTI is in
-  // the E or C stage.  We model that with a fake resource CTIDelayCycle.
-  // 
-  { LDD,      CTIDelayCycle.rid,  1, 1 },
-//{ LDDA,     CTIDelayCycle.rid,  1, 1 },
-//{ LDDSTUB,  CTIDelayCycle.rid,  1, 1 },
-//{ LDDSTUBA, CTIDelayCycle.rid,  1, 1 },
-//{ SWAP,     CTIDelayCycle.rid,  1, 1 },
-//{ SWAPA,    CTIDelayCycle.rid,  1, 1 },
-//{ CAS,      CTIDelayCycle.rid,  1, 1 },
-//{ CASA,     CTIDelayCycle.rid,  1, 1 },
-//{ CASX,     CTIDelayCycle.rid,  1, 1 },
-//{ CASXA,    CTIDelayCycle.rid,  1, 1 },
-  
-  //
-  // Signed int loads of less than dword size return data in cycle N1 (not C)
-  // and put all loads in consecutive cycles into delayed load return mode.
-  //
-  { LDSB,    LdReturn.rid,  2, -1 },
-  { LDSB,    LdReturn.rid,  3,  1 },
-  
-  { LDSH,    LdReturn.rid,  2, -1 },
-  { LDSH,    LdReturn.rid,  3,  1 },
-  
-  { LDSW,    LdReturn.rid,  2, -1 },
-  { LDSW,    LdReturn.rid,  3,  1 },
-
-  //
-  // RDPR from certain registers and RD from any register are not dispatchable
-  // until four clocks after they reach the head of the instr. buffer.
-  // Together with their single-issue requirement, this means all four issue
-  // slots are effectively blocked for those cycles, plus the issue cycle.
-  // This does not increase the latency of the instruction itself.
-  // 
-  { RDCCR,   AllIssueSlots.rid,     0,  5 },
-  { RDCCR,   AllIssueSlots.rid,     0,  5 },
-  { RDCCR,   AllIssueSlots.rid,     0,  5 },
-  { RDCCR,   AllIssueSlots.rid,     0,  5 },
-
-#undef EXPLICIT_BUBBLES_NEEDED
-#ifdef EXPLICIT_BUBBLES_NEEDED
-  // 
-  // MULScc inserts one bubble.
-  // This means it breaks the current group (captured in UltraSparcSchedInfo)
-  // *and occupies all issue slots for the next cycle
-  // 
-//{ MULScc,  AllIssueSlots.rid, 2, 2-1 },
-//{ MULScc,  AllIssueSlots.rid, 2, 2-1 },
-//{ MULScc,  AllIssueSlots.rid, 2, 2-1 },
-//{ MULScc,  AllIssueSlots.rid,  2, 2-1 },
-  
-  // 
-  // SMULcc inserts between 4 and 18 bubbles, depending on #leading 0s in rs1.
-  // We just model this with a simple average.
-  // 
-//{ SMULcc,  AllIssueSlots.rid, 2, ((4+18)/2)-1 },
-//{ SMULcc,  AllIssueSlots.rid, 2, ((4+18)/2)-1 },
-//{ SMULcc,  AllIssueSlots.rid, 2, ((4+18)/2)-1 },
-//{ SMULcc,  AllIssueSlots.rid,  2, ((4+18)/2)-1 },
-  
-  // SMULcc inserts between 4 and 19 bubbles, depending on #leading 0s in rs1.
-//{ UMULcc,  AllIssueSlots.rid, 2, ((4+19)/2)-1 },
-//{ UMULcc,  AllIssueSlots.rid, 2, ((4+19)/2)-1 },
-//{ UMULcc,  AllIssueSlots.rid, 2, ((4+19)/2)-1 },
-//{ UMULcc,  AllIssueSlots.rid,  2, ((4+19)/2)-1 },
-  
-  // 
-  // MULX inserts between 4 and 34 bubbles, depending on #leading 0s in rs1.
-  // 
-  { MULX,    AllIssueSlots.rid, 2, ((4+34)/2)-1 },
-  { MULX,    AllIssueSlots.rid, 2, ((4+34)/2)-1 },
-  { MULX,    AllIssueSlots.rid, 2, ((4+34)/2)-1 },
-  { MULX,    AllIssueSlots.rid,  2, ((4+34)/2)-1 },
-  
-  // 
-  // SDIVcc inserts 36 bubbles.
-  // 
-//{ SDIVcc,  AllIssueSlots.rid, 2, 36-1 },
-//{ SDIVcc,  AllIssueSlots.rid, 2, 36-1 },
-//{ SDIVcc,  AllIssueSlots.rid, 2, 36-1 },
-//{ SDIVcc,  AllIssueSlots.rid,  2, 36-1 },
-  
-  // UDIVcc inserts 37 bubbles.
-//{ UDIVcc,  AllIssueSlots.rid, 2, 37-1 },
-//{ UDIVcc,  AllIssueSlots.rid, 2, 37-1 },
-//{ UDIVcc,  AllIssueSlots.rid, 2, 37-1 },
-//{ UDIVcc,  AllIssueSlots.rid,  2, 37-1 },
-  
-  // 
-  // SDIVX inserts 68 bubbles.
-  // 
-  { SDIVX,   AllIssueSlots.rid, 2, 68-1 },
-  { SDIVX,   AllIssueSlots.rid, 2, 68-1 },
-  { SDIVX,   AllIssueSlots.rid, 2, 68-1 },
-  { SDIVX,   AllIssueSlots.rid,  2, 68-1 },
-  
-  // 
-  // UDIVX inserts 68 bubbles.
-  // 
-  { UDIVX,   AllIssueSlots.rid, 2, 68-1 },
-  { UDIVX,   AllIssueSlots.rid, 2, 68-1 },
-  { UDIVX,   AllIssueSlots.rid, 2, 68-1 },
-  { UDIVX,   AllIssueSlots.rid,  2, 68-1 },
-  
-  // 
-  // WR inserts 4 bubbles.
-  // 
-//{ WR,     AllIssueSlots.rid, 2, 68-1 },
-//{ WR,     AllIssueSlots.rid, 2, 68-1 },
-//{ WR,     AllIssueSlots.rid, 2, 68-1 },
-//{ WR,     AllIssueSlots.rid,  2, 68-1 },
-  
-  // 
-  // WRPR inserts 4 bubbles.
-  // 
-//{ WRPR,   AllIssueSlots.rid, 2, 68-1 },
-//{ WRPR,   AllIssueSlots.rid, 2, 68-1 },
-//{ WRPR,   AllIssueSlots.rid, 2, 68-1 },
-//{ WRPR,   AllIssueSlots.rid,  2, 68-1 },
-  
-  // 
-  // DONE inserts 9 bubbles.
-  // 
-//{ DONE,   AllIssueSlots.rid, 2, 9-1 },
-//{ DONE,   AllIssueSlots.rid, 2, 9-1 },
-//{ DONE,   AllIssueSlots.rid, 2, 9-1 },
-//{ DONE,   AllIssueSlots.rid, 2, 9-1 },
-  
-  // 
-  // RETRY inserts 9 bubbles.
-  // 
-//{ RETRY,   AllIssueSlots.rid, 2, 9-1 },
-//{ RETRY,   AllIssueSlots.rid, 2, 9-1 },
-//{ RETRY,   AllIssueSlots.rid, 2, 9-1 },
-//{ RETRY,   AllIssueSlots.rid,  2, 9-1 },
-
-#endif  /*EXPLICIT_BUBBLES_NEEDED */
-};
-
-
-
-// Additional delays to be captured in code:
-// 1. RDPR from several state registers (page 349)
-// 2. RD   from *any* register (page 349)
-// 3. Writes to TICK, PSTATE, TL registers and FLUSH{W} instr (page 349)
-// 4. Integer store can be in same group as instr producing value to store.
-// 5. BICC and BPICC can be in the same group as instr producing CC (pg 350)
-// 6. FMOVr cannot be in the same or next group as an IEU instr (pg 351).
-// 7. The second instr. of a CTI group inserts 9 bubbles (pg 351)
-// 8. WR{PR}, SVAE, SAVED, RESTORE, RESTORED, RETURN, RETRY, and DONE that
-//    follow an annulling branch cannot be issued in the same group or in
-//    the 3 groups following the branch.
-// 9. A predicted annulled load does not stall dependent instructions.
-//    Other annulled delay slot instructions *do* stall dependents, so
-//    nothing special needs to be done for them during scheduling.
-//10. Do not put a load use that may be annulled in the same group as the
-//    branch.  The group will stall until the load returns.
-//11. Single-prec. FP loads lock 2 registers, for dependency checking.
-//
-// 
-// Additional delays we cannot or will not capture:
-// 1. If DCTI is last word of cache line, it is delayed until next line can be
-//    fetched.  Also, other DCTI alignment-related delays (pg 352)
-// 2. Load-after-store is delayed by 7 extra cycles if load hits in D-Cache.
-//    Also, several other store-load and load-store conflicts (pg 358)
-// 3. MEMBAR, LD{X}FSR, LDD{A} and a bunch of other load stalls (pg 358)
-// 4. There can be at most 8 outstanding buffered store instructions
-//     (including some others like MEMBAR, LDSTUB, CAS{AX}, and FLUSH)
 
 
 
@@ -1281,10 +506,9 @@ const InstrRUsageDelta SparcInstrUsageDeltas[] = {
 
 class UltraSparcSchedInfo: public MachineSchedInfo {
 public:
-  /*ctor*/        UltraSparcSchedInfo  (const TargetMachine& tgt);
-  /*dtor*/ virtual ~UltraSparcSchedInfo        () {}
+  UltraSparcSchedInfo(const TargetMachine &tgt);
 protected:
-  virtual void initializeResources     ();
+  virtual void initializeResources();
 };
 
 
@@ -1299,47 +523,47 @@ 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; }
+  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 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
+                                  bool& growUp) const
   {
-    pos = true;                         // arguments area grows upwards
+    growUp = true;                         // arguments area grows upwards
     return FirstIncomingArgOffsetFromFP;
   }
   int getFirstOutgoingArgOffset  (MachineCodeForMethod& mcInfo,
-                                  bool& pos) const
+                                  bool& growUp) const
   {
-    pos = true;                         // arguments area grows upwards
+    growUp = true;                         // arguments area grows upwards
     return FirstOutgoingArgOffsetFromSP;
   }
   int getFirstOptionalOutgoingArgOffset(MachineCodeForMethod& mcInfo,
-                                        bool& pos)const
+                                        bool& growUp)const
   {
-    pos = true;                         // arguments area grows upwards
+    growUp = true;                         // arguments area grows upwards
     return FirstOptionalOutgoingArgOffsetFromSP;
   }
   
   int getFirstAutomaticVarOffset (MachineCodeForMethod& mcInfo,
-                                  bool& pos) const;
+                                  bool& growUp) const;
   int getRegSpillAreaOffset      (MachineCodeForMethod& mcInfo,
-                                  bool& pos) const;
+                                  bool& growUp) const;
   int getTmpAreaOffset           (MachineCodeForMethod& mcInfo,
-                                  bool& pos) const;
+                                  bool& growUp) const;
   int getDynamicAreaOffset       (MachineCodeForMethod& mcInfo,
-                                  bool& pos) const;
+                                  bool& growUp) const;
 
   //
   // These methods specify the base register used for each stack area
@@ -1389,8 +613,7 @@ private:
 
 class UltraSparcCacheInfo: public MachineCacheInfo {
 public:
-  /*ctor*/          UltraSparcCacheInfo  (const TargetMachine& target) :
-    MachineCacheInfo(target) {} 
+  UltraSparcCacheInfo(const TargetMachine &T) : MachineCacheInfo(T) {} 
 };
 
 
@@ -1427,8 +650,9 @@ public:
   virtual void addPassesToEmitAssembly(PassManager &PM, std::ostream &Out);
 
 private:
-  Pass *getMethodAsmPrinterPass(PassManager &PM, std::ostream &Out);
+  Pass *getFunctionAsmPrinterPass(PassManager &PM, std::ostream &Out);
   Pass *getModuleAsmPrinterPass(PassManager &PM, std::ostream &Out);
+  Pass *getEmitBytecodeToAsmPass(std::ostream &Out);
 };
 
 #endif