added support for suggesting colors
authorRuchira Sasanka <sasanka@students.uiuc.edu>
Sun, 30 Sep 2001 23:16:47 +0000 (23:16 +0000)
committerRuchira Sasanka <sasanka@students.uiuc.edu>
Sun, 30 Sep 2001 23:16:47 +0000 (23:16 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@671 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/SparcV9/SparcV9RegClassInfo.cpp
lib/Target/SparcV9/SparcV9RegClassInfo.h
lib/Target/SparcV9/SparcV9RegInfo.cpp

index a6d7f9e060c384c7fb1fb2d742d7761dc7cb82e3..883ed52d0fc3c0ee5faa44e786221b939f27ad72 100644 (file)
@@ -11,31 +11,48 @@ void SparcIntRegClass::colorIGNode(IGNode * Node, bool IsColorUsedArr[]) const
 {
 
   /* Algorithm:
-  Record the color of all neighbors.
+     Record the colors/suggested colors of all neighbors.
 
-  If there is no call interf, try to allocate volatile, then non volatile
-  If there is call interf, try to allocate non-volatile. If that fails
+     If there is a suggested color, try to allocate it
+     If there is no call interf, try to allocate volatile, then non volatile
+     If there is call interf, try to allocate non-volatile. If that fails
      try to allocate a volatile and insert save across calls
-  If both above fail, spill.
+     If both above fail, spill.
 
   */
 
+  LiveRange * LR = Node->getParentLR();
   unsigned NumNeighbors =  Node->getNumOfNeighbors();   // total # of neighbors
 
   for(unsigned n=0; n < NumNeighbors; n++) {            // for each neigh 
     IGNode *NeighIGNode = Node->getAdjIGNode(n);
-    if( NeighIGNode->hasColor() ) {                     // if neigh has a color
-      IsColorUsedArr[ NeighIGNode->getColor() ] = true; // record that color
-    }
+    LiveRange *NeighLR = NeighIGNode->getParentLR();
+
+    if( NeighLR->hasColor() )                        // if has a color
+      IsColorUsedArr[ NeighLR->getColor() ] = true; // record that color
+
+    else if( NeighLR->hasSuggestedColor() )        // or has a suggest col   
+      IsColorUsedArr[ NeighLR->getSuggestedColor() ] = true; 
+    
   }
 
 
+  if( LR->hasSuggestedColor() ) {
+    if( ! IsColorUsedArr[ LR->getSuggestedColor() ] ) {
+      LR->setColor(  LR->getSuggestedColor() );
+      return;
+    }
+    else {                              // can't allocate the suggested col
+      cout << " Coud NOT allocate the suggested color for LR ";
+      LR->printSet(); cout << endl;
+    }
+  }
 
   unsigned SearchStart;                 // start pos of color in pref-order
   bool ColorFound= false;               // have we found a color yet?
 
   //if this Node is between calls
-  if( Node->getNumOfCallInterferences() == 0) { 
+  if( LR->getNumOfCallInterferences() == 0) { 
 
     // start with volatiles (we can  allocate volatiles safely)
     SearchStart = SparcIntRegOrder::StartOfAllRegs;  
@@ -53,11 +70,12 @@ void SparcIntRegClass::colorIGNode(IGNode * Node, bool IsColorUsedArr[]) const
   }
 
   if( ColorFound) 
-    Node->setColor(c);                  // first color found in preffered order
+    LR->setColor(c);                  // first color found in preffered order
+
 
   // if color is not found because of call interference
   // try even finding a volatile color and insert save across calls
-  else if( Node->getNumOfCallInterferences() ) 
+  else if( LR->getNumOfCallInterferences() ) 
   { 
     // start from 0 - try to find even a volatile this time
     SearchStart = SparcIntRegOrder::StartOfAllRegs;  
@@ -68,21 +86,22 @@ void SparcIntRegClass::colorIGNode(IGNode * Node, bool IsColorUsedArr[]) const
     }
 
     if( ColorFound) { 
-      Node->setColor(c);  
+      LR->setColor(c);  
       // since LR span across calls, must save across calls 
-      Node->markForSaveAcrossCalls();       
+      LR->markForSaveAcrossCalls();       
     }
 
   }
 
+
   // If we couldn't find a color regardless of call interference - i.e., we
   // don't have either a volatile or non-volatile color left
   if( !ColorFound )  
-    Node->markForSpill();               // no color found - must spill
+    LR->markForSpill();               // no color found - must spill
 
 
   if( DEBUG_RA)                  
-    UltraSparcRegInfo::printReg( Node->getParentLR() );
+      UltraSparcRegInfo::printReg(  LR  );
 
 }
 
@@ -98,7 +117,8 @@ void SparcIntRegClass::colorIGNode(IGNode * Node, bool IsColorUsedArr[]) const
 // find the first available color in the range [Start,End] depending on the
 // type of the Node (i.e., float/double)
 
-int SparcFloatRegClass::findFloatColor(const IGNode *const Node, unsigned Start,
+int SparcFloatRegClass::findFloatColor(const LiveRange *const LR, 
+                                      unsigned Start,
                                       unsigned End, 
                                       bool IsColorUsedArr[] ) const
 {
@@ -106,7 +126,7 @@ int SparcFloatRegClass::findFloatColor(const IGNode *const Node, unsigned Start,
   bool ColorFound = false;
   unsigned c;
 
-  if( Node->getTypeID() == Type::DoubleTyID ) { 
+  if( LR->getTypeID() == Type::DoubleTyID ) { 
       
     // find first unused color for a double 
     for( c=Start; c < End ;c+= 2){
@@ -146,28 +166,50 @@ void SparcFloatRegClass::colorIGNode(IGNode * Node,bool IsColorUsedArr[]) const
   */
 
 
+  LiveRange * LR = Node->getParentLR();
   unsigned NumNeighbors =  Node->getNumOfNeighbors();   // total # of neighbors
 
   for(unsigned n=0; n < NumNeighbors; n++) {            // for each neigh 
     IGNode *NeighIGNode = Node->getAdjIGNode(n);
-    if( NeighIGNode->hasColor() ) {                     // if neigh has a color
-      IsColorUsedArr[ NeighIGNode->getColor() ] = true; // record that color
-      if( NeighIGNode->getTypeID() == Type::DoubleTyID )
-       IsColorUsedArr[ (NeighIGNode->getColor()) + 1 ] = true;  
+    LiveRange *NeighLR = NeighIGNode->getParentLR();
+
+      if( NeighLR->hasColor() )   {                     // if neigh has a color
+       IsColorUsedArr[ NeighLR->getColor() ] = true; // record that color
+       if( NeighLR->getTypeID() == Type::DoubleTyID )
+         IsColorUsedArr[ (NeighLR->getColor()) + 1 ] = true;  
+      }
+      else if( NeighLR->hasSuggestedColor() )   {   // if neigh has sugg color
+       IsColorUsedArr[ NeighLR->getSuggestedColor() ] = true;
+       if( NeighLR->getTypeID() == Type::DoubleTyID )
+         IsColorUsedArr[ (NeighLR->getSuggestedColor()) + 1 ] = true;  
+      }
+
+  }
+
+
+  if( LR->hasSuggestedColor() ) {
+    if( ! IsColorUsedArr[ LR->getSuggestedColor() ] ) {
+      LR->setColor(  LR->getSuggestedColor() );
+      return;
+    }
+    else {                              // can't allocate the suggested col
+      cout << " Coud NOT allocate the suggested color for LR ";
+      LR->printSet(); cout << endl;
     }
   }
 
+
   int ColorFound = -1;               // have we found a color yet?
-  unsigned NumOfCallInterf = Node->getNumOfCallInterferences();
+  unsigned NumOfCallInterf = LR->getNumOfCallInterferences();
 
   // if value is a double - search the double only reigon (f32 - f63)
-  if( Node->getTypeID() == Type::DoubleTyID )       
-    ColorFound = findFloatColor( Node, 32, 64, IsColorUsedArr );
+  if( LR->getTypeID() == Type::DoubleTyID )       
+    ColorFound = findFloatColor( LR, 32, 64, IsColorUsedArr );
     
 
   if( ColorFound >= 0 ) {
-    Node->setColor(ColorFound);                
-    if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() );
+    LR->setColor(ColorFound);                
+    if( DEBUG_RA) UltraSparcRegInfo::printReg( LR );
     return;
   }
 
@@ -185,38 +227,42 @@ void SparcFloatRegClass::colorIGNode(IGNode * Node,bool IsColorUsedArr[]) const
       SearchStart =  SparcFloatRegOrder::StartOfNonVolatileRegs;  
     }
     
-    ColorFound = findFloatColor( Node, SearchStart, 32, IsColorUsedArr );
+    ColorFound = findFloatColor( LR, SearchStart, 32, IsColorUsedArr );
 
   }
 
   if( ColorFound >= 0 ) {
-    Node->setColor(ColorFound);                  
-    if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() );
+    LR->setColor(ColorFound);                  
+    if( DEBUG_RA) UltraSparcRegInfo::printReg( LR );
     return;
   }
 
+
   else if( NumOfCallInterf ) { 
 
     // We are here because there is a call interference and no non-volatile
     // color could be found.
     // Now try to allocate even a volatile color
 
-    ColorFound = findFloatColor( Node, SparcFloatRegOrder::StartOfAllRegs, 
+    ColorFound = findFloatColor( LR, SparcFloatRegOrder::StartOfAllRegs, 
                                SparcFloatRegOrder::StartOfNonVolatileRegs,
                                IsColorUsedArr);
   }
 
+
+
   if( ColorFound >= 0 ) {
-    Node->setColor(ColorFound);         // first color found in preffered order
-    Node->markForSaveAcrossCalls();  
-    if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() );
+    LR->setColor(ColorFound);         // first color found in preffered order
+    LR->markForSaveAcrossCalls();  
+    if( DEBUG_RA) UltraSparcRegInfo::printReg( LR );
     return;
   }
 
-  else {
-    Node->markForSpill();               // no color found - must spill
-    if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() );
-  }
+
+  // we are here because no color could be found
+
+  LR->markForSpill();               // no color found - must spill
+  if( DEBUG_RA) UltraSparcRegInfo::printReg( LR );
   
 
 }
index 4a00cb560ca75067c2895714367b8f40bc6eff73..d613582c87afa91355a4346864f685e130c8f5fb 100644 (file)
 // Int register names in same order as enum in class SparcIntRegOrder
 
 static string const IntRegNames[] = 
-  {       "g1", "g2", "g3", "g4", "g5", "g6", "g7",
+  {       "g1", "g2", "g3", "g4", "g5",
     "o0", "o1", "o2", "o3", "o4", "o5",       "o7",
     "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
-    "i0", "i1", "i2", "i3", "i4", "i5", 
-    "g0", "i6", "i7",  "o6" }; 
+    "i0", "i1", "i2", "i3", "i4", "i5",       "i7",
+    "g0", "g6", "g7", "i6", "o6" }; 
 
 
 
@@ -36,7 +36,7 @@ class SparcIntRegOrder{
      // --- following colors are volatile across function calls
      // %g0 can't be used for coloring - always 0
                      
-     g1, g2, g3, g4, g5, g6, g7,  //%g1-%g7  
+     g1, g2, g3, g4, g5,  //%g1-%g5  (g6-7 are reserved for system)  
      o0, o1, o2, o3, o4, o5, o7,  // %o0-%o5, 
 
      // %o6 is sp, 
@@ -45,17 +45,17 @@ class SparcIntRegOrder{
      // --- following colors are NON-volatile across function calls
       
      l0, l1, l2, l3, l4, l5, l6, l7,    //  %l0-%l7
-     i0, i1, i2, i3, i4, i5,            // %i0-%i5: i's need not be preserved 
+     i0, i1, i2, i3, i4, i5, i7,         // %i0-%i5: i's need not be preserved 
       
      // %i6 is the fp - so not allocated
-     // %i7 is the ret address - can be used if saved
+     // %i7 is the ret address by convention - can be used for others
 
      // max # of colors reg coloring  can allocate (NumOfAvailRegs)
 
      // --- following colors are not available for allocation within this phase
      // --- but can appear for pre-colored ranges 
 
-     g0, i6, i7,  o6
+     g0, g6, g7, i6,  o6
 
  
 
@@ -130,7 +130,7 @@ class SparcFloatRegOrder{
   static unsigned int const NumOfAvailRegs = 32;
   static unsigned int const NumOfAllRegs = 64;
 
-  static unsigned int const StartOfNonVolatileRegs = f6;
+  static unsigned int const StartOfNonVolatileRegs = f32;
   static unsigned int const StartOfAllRegs = f0;
 
 
@@ -149,7 +149,7 @@ class SparcFloatRegClass : public MachineRegClassInfo
 {
  private:
 
-  int findFloatColor(const IGNode *const Node, unsigned Start,
+  int findFloatColor(const LiveRange *const LR, unsigned Start,
                     unsigned End, bool IsColorUsedArr[] ) const;
 
  public:
index 8254b00a5b090771106e2ccf8b2db8e5d71d421a..0a2570e5a4221f6963bd74558f3f583eba8e99d1 100644 (file)
@@ -2,6 +2,7 @@
 #include "SparcInternals.h"
 #include "llvm/Method.h"
 #include "llvm/iTerminators.h"
+#include "llvm/iOther.h"
 #include "llvm/CodeGen/InstrScheduling.h"
 #include "llvm/CodeGen/InstrSelection.h"
 
 // UltraSparcRegInfo
 //---------------------------------------------------------------------------
 
-/*
-Rules for coloring values with sepcial registers:
-=================================================
 
-The following are the cases we color values with special regs:
 
-1) Incoming Method Arguements
-2) Outgoing Call Arguments
-3) Return Value of a call
-4) Return Value of a return statement
+//---------------------------------------------------------------------------
+// This method sets the hidden operand for return address in RETURN and 
+// JMPL machine instructions.
+//---------------------------------------------------------------------------
+
+bool UltraSparcRegInfo::handleSpecialMInstr(const MachineInstr * MInst, 
+                                           LiveRangeInfo& LRI,
+                                           vector<RegClass *>RCList) const {
+  
+  unsigned OpCode = MInst->getOpCode();
 
-Both 1 and 3 are defs. Therefore, they can be set directly. For case 1, 
-incoming args are colored to %i0-%i5 and %f0 - %fx. For case 3, the return
-value of the call must be colored to %o0 or %f0.
 
-For case 2 we can use %o0-%o6 and %f0- %fx and for case 4 we can use %i0 or
-%f0. However, we cannot pre-color them directly to those regs
-if there are call interferences or they can be already colred by case 1.
-(Note that a return value is call is already colored and it is registered
-as a call interference as well if it is live after the call). Otherwise, they
-can be precolored. In cases where we cannot precolor, we just have to insert 
-a copy instruction to copy the LR to the required register.
+  // if the instruction is a RETURN instruction, suggest %i7
+
+  if( (UltraSparcInfo->getInstrInfo()).isReturn( OpCode ) ) {
+
+    const Value *RetAddrVal = getValue4ReturnAddr(MInst);
+    
+    if( (getRegClassIDOfValue( RetAddrVal) == IntRegClassID) ) {
+      if( DEBUG_RA) {
+       cout <<  "\n$?$Return Address Value is not of Integer Type. Type =";
+       cout << (RetAddrVal->getType())->getPrimitiveID() << endl;
+      }
+    }
+
+  
+    LiveRange * RetAddrLR = new LiveRange();  
+    RetAddrLR->add(RetAddrVal);
+    RetAddrLR->setRegClass( RCList[IntRegClassID] );
+    LRI.addLRToMap( RetAddrVal, RetAddrLR);
+    
+    RetAddrLR->setSuggestedColor(SparcIntRegOrder::i7);
 
-*/
+    return true;
+  }
 
+  // else if the instruction is a JMPL instruction, color it with %o7
+  // this can be permenently colored since the LR is very short (one instr)
+  // TODO: Directly change the machine register instead of creating a LR
+
+  else if( (UltraSparcInfo->getInstrInfo()).isCall(MInst->getOpCode() ) ) {
+
+    const Value *RetAddrVal = getValue4ReturnAddr(MInst);
+    
+    if( (getRegClassIDOfValue( RetAddrVal) == IntRegClassID) ) {
+      if( DEBUG_RA) {
+       cout <<  "\n$?$Return Address Value is not of Integer Type. Type =";
+       cout << (RetAddrVal->getType())->getPrimitiveID() << endl;
+      }
+    }
+
+    LiveRange * RetAddrLR = new LiveRange();      
+    RetAddrLR->add(RetAddrVal);
+    RetAddrLR->setRegClass( RCList[IntRegClassID] );
+    LRI.addLRToMap( RetAddrVal, RetAddrLR);
+
+    RetAddrLR->setColor(SparcIntRegOrder::o7);
+
+    return true;                    
+    
+  }
+  
+  else return false;   // not a special machine instruction
+
+}
 
 
 //---------------------------------------------------------------------------
-//   This method will color incoming args to a method. If there are more
-//   args than that can fit in regs, code will be inserted to pop them from
-//   stack
+// This gets the hidden value in a return register which is used to
+// pass the return address.
 //---------------------------------------------------------------------------
 
-void UltraSparcRegInfo::colorArgs(const Method *const Meth, 
-                                 LiveRangeInfo& LRI) const 
+Value *  
+UltraSparcRegInfo::getValue4ReturnAddr( const MachineInstr * MInst ) const {
+  
+  if( (UltraSparcInfo->getInstrInfo()).isReturn(MInst->getOpCode()) ) {
+    
+    assert( (MInst->getNumOperands() == 2) && "RETURN must have 2 operands");
+    const MachineOperand & MO  = MInst->getOperand(0);
+    return MO.getVRegValue();
+   
+  }
+  else if(  (UltraSparcInfo->getInstrInfo()).isCall(MInst->getOpCode()) ) {
+        
+    assert( (MInst->getNumOperands() == 3) && "JMPL must have 3 operands");
+    const MachineOperand & MO  = MInst->getOperand(2);
+    return MO.getVRegValue();
+  }
+
+  else
+    assert(0 && "Machine Instr is not a CALL/RET");
+}
+
+       
+
+//---------------------------------------------------------------------------
+//  This method will suggest colors to incoming args to a method. 
+//  If the arg is passed on stack due to the lack of regs, NOTHING will be
+//  done - it will be colored (or spilled) as a normal value.
+//---------------------------------------------------------------------------
+
+void UltraSparcRegInfo::suggestRegs4MethodArgs(const Method *const Meth, 
+                                              LiveRangeInfo& LRI) const 
 {
 
                                                  // get the argument list
   const Method::ArgumentListType& ArgList = Meth->getArgumentList();           
                                                  // get an iterator to arg list
   Method::ArgumentListType::const_iterator ArgIt = ArgList.begin(); 
-  unsigned intArgNo=0;
-
-  // to keep track of which float regs are allocated for argument passing
-  bool FloatArgUsedArr[NumOfFloatArgRegs];
-
-  // init float arg used array
-  for(unsigned i=0; i < NumOfFloatArgRegs; ++i) 
-    FloatArgUsedArr[i] = false;
 
   // for each argument
-  for( ; ArgIt != ArgList.end() ; ++ArgIt) {    
+  for( unsigned argNo=0; ArgIt != ArgList.end() ; ++ArgIt, ++argNo) {    
 
     // get the LR of arg
     LiveRange *const LR = LRI.getLiveRangeForValue((const Value *) *ArgIt); 
-    unsigned RegClassID = (LR->getRegClass())->getID();
+    assert( LR && "No live range found for method arg");
+
+    unsigned RegType = getRegType( LR );
+
 
     // if the arg is in int class - allocate a reg for an int arg
-    if( RegClassID == IntRegClassID ) {
+    if( RegType == IntRegType ) {
 
-      if( intArgNo < NumOfIntArgRegs) {
-       LR->setColor( SparcIntRegOrder::i0 + intArgNo );
+      if( argNo < NumOfIntArgRegs) {
+       LR->setSuggestedColor( SparcIntRegOrder::i0 + argNo );
 
-       if( DEBUG_RA) printReg( LR );
       }
   
       else {
-       // TODO: Insert push code here
-       assert( 0 && "Insert push code here!");
+       // Do NOTHING as this will be colored as a normal value.
+       if (DEBUG_RA) cout << " Int Regr not suggested for method arg\n";
       }
-      ++intArgNo;
+     
     }
+    else if( RegType==FPSingleRegType && (argNo*2+1) < NumOfFloatArgRegs) 
+      LR->setSuggestedColor( SparcFloatRegOrder::f0 + (argNo * 2 + 1) );
+    
+    else if( RegType == FPDoubleRegType && (argNo*2) < NumOfFloatArgRegs) 
+      LR->setSuggestedColor( SparcFloatRegOrder::f0 + (argNo * 2) ); 
+    
+
+  }
+  
+}
 
-    // if the arg is float/double 
-    else if ( RegClassID == FloatRegClassID) {
+//---------------------------------------------------------------------------
+// 
+//---------------------------------------------------------------------------
 
-      if( LR->getTypeID() == Type::DoubleTyID ) {
+void UltraSparcRegInfo::colorMethodArgs(const Method *const Meth, 
+                                       LiveRangeInfo& LRI,
+                                       AddedInstrns *const FirstAI) const {
 
-       // find the first reg # we can pass a double arg
-       for(unsigned i=0; i < NumOfFloatArgRegs; i+= 2) {
-         if ( !FloatArgUsedArr[i] && !FloatArgUsedArr[i+1] ) {
-           LR->setColor( SparcFloatRegOrder::f0 + i );
-           FloatArgUsedArr[i] = true;
-           FloatArgUsedArr[i+1] = true;
-           if( DEBUG_RA) printReg( LR );
-           break;
-         }
-       }
-       if( ! LR->hasColor() ) { // if LR was not colored above
+                                                 // get the argument list
+  const Method::ArgumentListType& ArgList = Meth->getArgumentList();           
+                                                 // get an iterator to arg list
+  Method::ArgumentListType::const_iterator ArgIt = ArgList.begin(); 
 
-         assert(0 && "insert push code here for a double");
+  MachineInstr *AdMI;
 
-       }
 
-      }
-      else if( LR->getTypeID() == Type::FloatTyID ) { 
-
-       // find the first reg # we can pass a float arg
-       for(unsigned i=0; i < NumOfFloatArgRegs; ++i) {
-         if ( !FloatArgUsedArr[i] ) {
-           LR->setColor( SparcFloatRegOrder::f0 + i );
-           FloatArgUsedArr[i] = true;
-           if( DEBUG_RA) printReg( LR );
-           break;
-         }
-       }
-       if( ! LR->hasColor() ) { // if LR was not colored above
-         assert(0 && "insert push code here for a float");
-       }
+  // for each argument
+  for( unsigned argNo=0; ArgIt != ArgList.end() ; ++ArgIt, ++argNo) {    
+
+    // get the LR of arg
+    LiveRange *const LR = LRI.getLiveRangeForValue((const Value *) *ArgIt); 
+    assert( LR && "No live range found for method arg");
+
+
+    // if the LR received the suggested color, NOTHING to be done
+    if( LR->hasSuggestedColor() && LR->hasColor() )
+      if( LR->getSuggestedColor() == LR->getColor() )
+       continue;
+
+    // We are here because the LR did not have a suggested 
+    // color or did not receive the suggested color. Now handle
+    // individual cases.
+
+
+    unsigned RegType = getRegType( LR );
+    unsigned RegClassID = (LR->getRegClass())->getID();
+
+
+    // find whether this argument is coming in a register (if not, on stack)
+
+    bool isArgInReg = false;
+    unsigned UniArgReg = InvalidRegNum;
+
+    if( (RegType== IntRegType && argNo <  NumOfIntArgRegs)) {
+      isArgInReg = true;
+      UniArgReg = getUnifiedRegNum( RegClassID, SparcIntRegOrder::o0 + argNo );
+    }
+    else if(RegType == FPSingleRegType && argNo < NumOfFloatArgRegs)  { 
+      isArgInReg = true;
+      UniArgReg = getUnifiedRegNum( RegClassID, 
+                                   SparcFloatRegOrder::f0 + argNo*2 + 1 ) ;
+    }
+    else if(RegType == FPDoubleRegType && argNo < NumOfFloatArgRegs)  { 
+      isArgInReg = true;
+      UniArgReg = getUnifiedRegNum(RegClassID, SparcFloatRegOrder::f0+argNo*2);
+    }
+
+    
+    if( LR->hasColor() ) {
+
+      // We are here because the LR did not have a suggested 
+      // color or did not receive the suggested color but LR got a register.
+      // Now we have to copy %ix reg (or stack pos of arg) 
+      // to the register it was colored with.
+
+      unsigned UniLRReg = getUnifiedRegNum(  RegClassID, LR->getColor() );
+       
+      // if the arg is coming in a register and goes into a register
+      if( isArgInReg ) 
+       AdMI = cpReg2RegMI(UniArgReg, UniLRReg, RegType );
 
-      }
       else 
-       assert(0 && "unknown float type in method arg");
+       assert(0 && "TODO: Color an Incoming arg on stack");
 
-    } // float register class
+      // Now add the instruction
+      FirstAI->InstrnsBefore.push_back( AdMI );
 
-    else 
-      assert(0 && "Unknown RegClassID");
-  }
-  
-}
+    }
+
+    else {                                // LR is not colored (i.e., spilled)
+      
+      assert(0 && "TODO: Color a spilled arg ");
+      
+    }
 
 
+  }  // for each incoming argument
 
+}
 
 
 
-void UltraSparcRegInfo::colorCallArgs(vector<const Instruction *> & 
-                                     CallInstrList, LiveRangeInfo& LRI,
-                                     AddedInstrMapType &AddedInstrMap) const
-{
 
-  vector<const Instruction *>::const_iterator InstIt;
+//---------------------------------------------------------------------------
+// This method is called before graph coloring to suggest colors to the
+// outgoing call args and the return value of the call.
+//---------------------------------------------------------------------------
+void UltraSparcRegInfo::suggestRegs4CallArgs(const CallInst *const CallI, 
+                                            LiveRangeInfo& LRI,
+                                            vector<RegClass *> RCList) const {
+
 
-  // First color the return value of all call instructions. The return value
+  assert( (CallI->getOpcode() == Instruction::Call) && "Not a call instr");
+
+  // First color the return value of the call instruction. The return value
   // will be in %o0 if the value is an integer type, or in %f0 if the 
   // value is a float type.
 
-  for(InstIt=CallInstrList.begin(); InstIt != CallInstrList.end(); ++InstIt) {
+  // the return value cannot have a LR in machine instruction since it is
+  // only defined by the call instruction
 
-    const Instruction *const CallI = *InstIt;
+  assert( (! LRI.getLiveRangeForValue( CallI ) ) && 
+         "LR for ret Value of call already definded!");
 
-    // get the live range of return value of this call
-    LiveRange *const LR = LRI.getLiveRangeForValue( CallI ); 
+  // if type is not void,  create a new live range and set its 
+  // register class and add to LRI
 
-    if ( LR ) {
+  if( ! ((CallI->getType())->getPrimitiveID() == Type::VoidTyID) ) {
+  
+    // create a new LR for the return value
 
-      // Since the call is a def, it cannot be colored by some other instr.
-      // Therefore, we can definitely set a color here.
-      // However, this def can be used by some other instr like another call
-      // or return which places that in a special register. In that case
-      // it has to put a copy. Note that, the def will have a call interference
-      // with this call instr itself if it is live after this call.
+    LiveRange * RetValLR = new LiveRange();  
+    RetValLR->add( CallI );
+    unsigned RegClassID = getRegClassIDOfValue( CallI );
+    RetValLR->setRegClass( RCList[RegClassID] );
+    LRI.addLRToMap( CallI, RetValLR);
 
-      assert( ! LR->hasColor() && "Can't have a color since this is a def");
+    // now suggest a register depending on the register class of ret arg
 
-      unsigned RegClassID = (LR->getRegClass())->getID();
-      
-      if( RegClassID == IntRegClassID ) {
-       LR->setColor(SparcIntRegOrder::o0);
-      }
-      else if (RegClassID == FloatRegClassID ) {
-       LR->setColor(SparcFloatRegOrder::f0 );
+    if( RegClassID == IntRegClassID ) 
+      RetValLR->setSuggestedColor(SparcIntRegOrder::o0);
+    else if (RegClassID == FloatRegClassID ) 
+      RetValLR->setSuggestedColor(SparcFloatRegOrder::f0 );
+    else assert( 0 && "Unknown reg class for return value of call\n");
+
+  }
+
+
+  // Now suggest colors for arguments (operands) of the call instruction.
+  // Colors are suggested only if the arg number is smaller than the
+  // the number of registers allocated for argument passing.
+
+  Instruction::op_const_iterator OpIt = CallI->op_begin();
+  ++OpIt;   // first operand is the called method - skip it
+  
+  // go thru all the operands of LLVM instruction
+  for(unsigned argNo=0; OpIt != CallI->op_end(); ++OpIt, ++argNo ) {
+    
+    // get the LR of call operand (parameter)
+    LiveRange *const LR = LRI.getLiveRangeForValue((const Value *) *OpIt); 
+
+    if( !LR ) {              // possible because arg can be a const
+      if( DEBUG_RA) {
+       cout << " Warning: In call instr, no LR for arg:  " ;
+       printValue(*OpIt); cout << endl;
       }
+      continue;
     }
-    else {
-      cout << "Warning: No Live Range for return value of CALL" << endl;
+    
+    unsigned RegType = getRegType( LR );
+
+    // if the arg is in int class - allocate a reg for an int arg
+    if( RegType == IntRegType ) {
+
+      if( argNo < NumOfIntArgRegs) 
+       LR->setSuggestedColor( SparcIntRegOrder::o0 + argNo );
+
+      else if (DEBUG_RA) 
+       // Do NOTHING as this will be colored as a normal value.
+       cout << " Regr not suggested for int call arg" << endl;
+      
     }
-  }
+    else if( RegType == FPSingleRegType &&  (argNo*2 +1)< NumOfFloatArgRegs) 
+      LR->setSuggestedColor( SparcFloatRegOrder::f0 + (argNo * 2 + 1) );
+    
+    else if( RegType == FPDoubleRegType && (argNo*2) < NumOfFloatArgRegs) 
+      LR->setSuggestedColor( SparcFloatRegOrder::f0 + (argNo * 2) ); 
+    
 
+  } // for all call arguments
 
-  for( InstIt=CallInstrList.begin(); InstIt != CallInstrList.end(); ++InstIt) {
+}
 
-    // Inst = LLVM call instruction
-    const Instruction *const CallI = *InstIt;
 
-    // find the CALL/JMMPL machine instruction
-    MachineCodeForVMInstr &  MInstVec = CallI->getMachineInstrVec();
-    MachineCodeForVMInstr::const_iterator MIIt = MInstVec.begin();
+//---------------------------------------------------------------------------
+// After graph coloring, we have call this method to see whehter the return
+// value and the call args received the correct colors. If not, we have
+// to instert copy instructions.
+//---------------------------------------------------------------------------
 
-    /*
-    for( ; MIIt != MInstVec.end() && 
-          ! getUltraSparcInfo().getInstrInfo().isCall((*MIIt)->getOpCode()); 
-        ++MIIt );
 
-    assert( (MIIt != MInstVec.end())  && "CALL/JMPL not found");
-    */
+void UltraSparcRegInfo::colorCallArgs(const CallInst *const CallI,
+                                     LiveRangeInfo& LRI,
+                                     AddedInstrns *const CallAI) const {
 
-    assert(getUltraSparcInfo().getInstrInfo().isCall((*MIIt)->getOpCode()) &&
-          "First machine instruction is not a Call/JMPL Machine Instr");
 
-    // CallMI = CALL/JMPL machine isntruction
-    const MachineInstr *const CallMI = *MIIt;
+  // First color the return value of the call.
+  // If there is a LR for the return value, it means this
+  // method returns a value
+  
+  MachineInstr *AdMI;
+  LiveRange * RetValLR = LRI.getLiveRangeForValue( CallI );
 
-    Instruction::op_const_iterator OpIt = CallI->op_begin();
+  if( RetValLR ) {
 
-    unsigned intArgNo=0;
+    bool recvSugColor = false;
 
+    if( RetValLR->hasSuggestedColor() && RetValLR->hasColor() )
+      if( RetValLR->getSuggestedColor() == RetValLR->getColor())
+       recvSugColor = true;
 
-    // to keep track of which float regs are allocated for argument passing
-    bool FloatArgUsedArr[NumOfFloatArgRegs];
+    // if we didn't receive the suggested color for some reason, 
+    // put copy instruction
 
-    // init float arg used array
-    for(unsigned i=0; i < NumOfFloatArgRegs; ++i) 
-      FloatArgUsedArr[i] = false;
+    if( !recvSugColor ) {
 
-    // go thru all the operands of LLVM instruction
-    for( ; OpIt != CallI->op_end(); ++OpIt ) {
+      if( RetValLR->hasColor() ) {
 
-      // get the LR of call operand (parameter)
-      LiveRange *const LR = LRI.getLiveRangeForValue((const Value *) *OpIt); 
+       unsigned RegType = getRegType( RetValLR );
+       unsigned RegClassID = (RetValLR->getRegClass())->getID();
 
-      if ( !LR ) {
-       cout << " Warning: In call instr, no LR for arg: " ;
-       printValue(*OpIt);
-       cout << endl;
-       continue;
-      }
+       unsigned UniRetLRReg=getUnifiedRegNum(RegClassID,RetValLR->getColor());
+       unsigned UniRetReg = InvalidRegNum;
 
-      unsigned RegClassID = (LR->getRegClass())->getID();
+       // find where we receive the return value depending on
+       // register class
+           
+       if(RegClassID == IntRegClassID)
+         UniRetReg = getUnifiedRegNum( RegClassID, SparcIntRegOrder::o0);
+       else if(RegClassID == FloatRegClassID)
+         UniRetReg = getUnifiedRegNum( RegClassID, SparcFloatRegOrder::f0);
+
+
+       AdMI = cpReg2RegMI(UniRetLRReg, UniRetReg, RegType );   
+       CallAI->InstrnsAfter.push_back( AdMI );
       
-      // if the arg is in int class - allocate a reg for an int arg
-      if( RegClassID == IntRegClassID ) {
        
-       if( intArgNo < NumOfIntArgRegs) {
-         setCallOrRetArgCol( LR, SparcIntRegOrder::o0 + intArgNo, 
-                             CallMI, AddedInstrMap);
-       }
+      } // if LR has color
+      else {
        
-       else {
-         // TODO: Insert push code here
-         assert( 0 && "Insert push code here!");
-
-         AddedInstrns * AI = AddedInstrMap[ CallMI ];
-         if( ! AI ) AI = new AddedInstrns();
-
-         // AI->InstrnsBefore.push_back( getStackPushInstr(LR) );
-         AddedInstrMap[ CallMI ] = AI;
-         
-       }
-       ++intArgNo;
+       assert(0 && "LR of return value is splilled");
       }
       
-      // if the arg is float/double 
-      else if ( RegClassID == FloatRegClassID) {
-       
-       if( LR->getTypeID() == Type::DoubleTyID ) {
-         
-         // find the first reg # we can pass a double arg
-         for(unsigned i=0; i < NumOfFloatArgRegs; i+= 2) {
-           if ( !FloatArgUsedArr[i] && !FloatArgUsedArr[i+1] ) {
-             setCallOrRetArgCol(LR, SparcFloatRegOrder::f0 + i,
-                                CallMI, AddedInstrMap);                    
-             FloatArgUsedArr[i] = true;
-             FloatArgUsedArr[i+1] = true;
-             //if( DEBUG_RA) printReg( LR );
-             break;
-           }
-         }
-         if( ! LR->hasColor() ) { // if LR was not colored above
-           
-           assert(0 && "insert push code here for a double");
-           
-         }
-         
-       }
-       else if( LR->getTypeID() == Type::FloatTyID ) { 
-         
-         // find the first reg # we can pass a float arg
-         for(unsigned i=0; i < NumOfFloatArgRegs; ++i) {
-           if ( !FloatArgUsedArr[i] ) {
-             setCallOrRetArgCol(LR, SparcFloatRegOrder::f0 + i,
-                                CallMI, AddedInstrMap);
-             FloatArgUsedArr[i] = true;
-             // LR->setColor( SparcFloatRegOrder::f0 + i );
-             // if( DEBUG_RA) printReg( LR );
-             break;
-           }
-         }
-         if( ! LR->hasColor() ) { // if LR was not colored above
-           assert(0 && "insert push code here for a float");
-         }
-         
-       }
-       else 
-         assert(0 && "unknown float type in method arg");
-       
-      } // float register class
-      
-      else 
-       assert(0 && "Unknown RegClassID");
 
+    } // the LR didn't receive the suggested color  
+    
+  } // if there is a LR - i.e., return value is not void
+  
 
-    } // for each operand in a call instruction
 
+  // Now color all the operands of the call instruction
 
+  Instruction::op_const_iterator OpIt = CallI->op_begin();
+  ++OpIt;   // first operand is the called method - skip it
 
+  // go thru all the operands of LLVM instruction
+  for(unsigned argNo=0; OpIt != CallI->op_end(); ++OpIt, ++argNo ) {
+    
+    // get the LR of call operand (parameter)
+    LiveRange *const LR = LRI.getLiveRangeForValue((const Value *) *OpIt); 
 
+    Value *ArgVal = (Value *) *OpIt;
 
-  } // for all call instrctions in CallInstrList
+    unsigned RegType = getRegType( ArgVal );
+    unsigned RegClassID =  getRegClassIDOfValue( ArgVal );
+    
+    // find whether this argument is coming in a register (if not, on stack)
 
-}
+    bool isArgInReg = false;
+    unsigned UniArgReg = InvalidRegNum;
 
+    if( (RegType== IntRegType && argNo <  NumOfIntArgRegs)) {
+      isArgInReg = true;
+      UniArgReg = getUnifiedRegNum(RegClassID, SparcIntRegOrder::o0 + argNo );
+    }
+    else if(RegType == FPSingleRegType && argNo < NumOfFloatArgRegs)  { 
+      isArgInReg = true;
+      UniArgReg = getUnifiedRegNum(RegClassID, 
+                                  SparcFloatRegOrder::f0 + (argNo*2 + 1) );
+    }
+    else if(RegType == FPDoubleRegType && argNo < NumOfFloatArgRegs)  { 
+      isArgInReg = true;
+      UniArgReg = getUnifiedRegNum(RegClassID, SparcFloatRegOrder::f0+argNo*2);
+    }
 
 
+   
+    if( !LR ) {              // possible because arg can be a const
 
+      if( DEBUG_RA) {
+       cout << " Warning: In call instr, no LR for arg:  " ;
+       printValue(*OpIt); cout << endl;
+      }
 
-void UltraSparcRegInfo::colorRetArg(vector<const Instruction *> & 
-                                   RetInstrList, LiveRangeInfo& LRI,
-                                   AddedInstrMapType &AddedInstrMap) const
-{
+      //AdMI = cpValue2RegMI( ArgVal, UniArgReg, RegType);
+      //(CallAI->InstrnsBefore).push_back( AdMI );
+      //cout << " *Constant moved to an output register\n";
 
-  vector<const Instruction *>::const_iterator InstIt;
+      continue;
+    }
+    
 
+    // if the LR received the suggested color, NOTHING to do
 
-  for(InstIt=RetInstrList.begin(); InstIt != RetInstrList.end(); ++InstIt) {
+    if( LR->hasSuggestedColor() && LR->hasColor() )
+      if( LR->getSuggestedColor() == LR->getColor() )
+       continue;
+       
 
-    const ReturnInst *const RetI = (ReturnInst *) *InstIt;
 
-    // get the return value of this return instruction
-    const Value *RetVal =  (RetI)->getReturnValue();
 
-    if( RetVal ) {
+    
+    if( LR->hasColor() ) {
 
-      // find the CALL/JMMPL machine instruction
-      MachineCodeForVMInstr &  MInstVec = RetI->getMachineInstrVec();
-      MachineCodeForVMInstr::const_iterator MIIt = MInstVec.begin();
+      // We are here because though the LR is allocated a register, it
+      // was not allocated the suggested register. So, we have to copy %ix reg 
+      // (or stack pos of arg) to the register it was colored with
 
-      
-      /*
-      for( ; MIIt != MInstVec.end() && 
-          !getUltraSparcInfo().getInstrInfo().isReturn((*MIIt)->getOpCode()); 
-          ++MIIt ) {
 
-       cout << "Inst = "<< TargetInstrDescriptors[(*MIIt)->getOpCode()].opCodeString << endl;
+      unsigned UniLRReg = getUnifiedRegNum( RegClassID,  LR->getColor() );
 
+      if( isArgInReg ) 
+       AdMI = cpReg2RegMI(UniLRReg, UniArgReg, RegType );
 
-      }
-      assert((MIIt != MInstVec.end()) &&"No return machine instruction found");
-      
-      */
+      else 
+       assert(0 && "TODO: Push an outgoing arg on stack");
+
+      // Now add the instruction
+      CallAI->InstrnsBefore.push_back( AdMI );
 
+    }
+
+    else {                                // LR is not colored (i.e., spilled)
       
-      assert(getUltraSparcInfo().getInstrInfo().isReturn((*MIIt)->getOpCode())
-            &&    "First machine inst is not a RETURN Machine Instr");
+      assert(0 && "TODO: Copy a spilled call arg to an output reg ");
       
+    }
 
-      // RET machine isntruction
-      const MachineInstr *const RetMI = *MIIt;
+  }  // for each parameter in call instruction
 
-      LiveRange *const LR = LRI.getLiveRangeForValue( RetVal ); 
-      unsigned RegClassID = (LR->getRegClass())->getID();
+}
 
-      if ( LR ) {      
-       if( RegClassID == IntRegClassID ) {
-         setCallOrRetArgCol( LR, SparcIntRegOrder::i0, RetMI, AddedInstrMap);
-       }
-       else if (RegClassID==FloatRegClassID ) {
-         setCallOrRetArgCol(LR, SparcFloatRegOrder::f0, RetMI, AddedInstrMap);
-       }
-       
-      }
-      else {
-       cout << "Warning: No LR for return value" << endl;
-      }
+//---------------------------------------------------------------------------
+// This method is called for an LLVM return instruction to identify which
+// values will be returned from this method and to suggest colors.
+//---------------------------------------------------------------------------
+void UltraSparcRegInfo::suggestReg4RetValue(const ReturnInst *const RetI, 
+                                            LiveRangeInfo& LRI) const {
+
+
+
+  assert( (RetI->getOpcode() == Instruction::Ret) && "Not a ret instr");
+
+  // get the return value of this return instruction
 
+  const Value *RetVal =  (RetI)->getReturnValue();
+
+  // if the method returns a value
+  if( RetVal ) {
+
+    MachineInstr *AdMI;
+    LiveRange *const LR = LRI.getLiveRangeForValue( RetVal ); 
+  
+
+    if ( LR ) {     
+
+      unsigned RegClassID = (LR->getRegClass())->getID();
+      
+      if( RegClassID == IntRegClassID ) 
+       LR->setSuggestedColor(SparcIntRegOrder::i0);
+      
+      else if ( RegClassID == FloatRegClassID ) 
+       LR->setSuggestedColor(SparcFloatRegOrder::f0);
+      
+    }
+    else {
+      if( DEBUG_RA )
+      cout << "Warning: No LR for return value" << endl;
+      // possible since this can be returning a constant
     }
 
+
+
   }
 
+
+
 }
 
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+void UltraSparcRegInfo::colorRetValue(const  ReturnInst *const RetI, 
+                                     LiveRangeInfo& LRI,
+                                     AddedInstrns *const RetAI) const {
 
 
-void UltraSparcRegInfo::setCallOrRetArgCol(LiveRange *const LR, 
-                                          const unsigned RegNo,
-                                          const MachineInstr *MI,
-                                          AddedInstrMapType &AIMap) const {
+  // get the return value of this return instruction
+  Value *RetVal =  (Value *) (RetI)->getReturnValue();
 
-  // if no call interference and LR is NOT previously colored (e.g., as an 
-  // incoming arg)
-  if( ! LR->getNumOfCallInterferences() && ! LR->hasColor() ) { 
-    // we can directly allocate a %o register
-    LR->setColor( RegNo);
-    if( DEBUG_RA) printReg( LR );
-  }
-  else {        
+  // if the method returns a value
+  if( RetVal ) {
+
+    MachineInstr *AdMI;
+    LiveRange *const LR = LRI.getLiveRangeForValue( RetVal ); 
+
+    unsigned RegClassID =  getRegClassIDOfValue(RetVal);
+    unsigned RegType = getRegType( RetVal );
+    unsigned UniRetReg = InvalidRegNum;
+    
+    if(RegClassID == IntRegClassID)
+      UniRetReg = getUnifiedRegNum( RegClassID, SparcIntRegOrder::i0 );
+    else if(RegClassID == FloatRegClassID)
+      UniRetReg = getUnifiedRegNum( RegClassID, SparcFloatRegOrder::f0);
+     
+    if ( LR ) {      
+
+      // if the LR received the suggested color, NOTHING to do
 
-    // there are call interferences (e.g., live across a call or produced
-    // by a call instr) or this LR is already colored as an incoming argument
+      if( LR->hasSuggestedColor() && LR->hasColor() )
+       if( LR->getSuggestedColor() == LR->getColor() )
+         return;
 
-    MachineInstr *MI = getCopy2RegMI((*(LR->begin())), RegNo, 
-                                    (LR->getRegClass())->getID());
+      if( LR->hasColor() ) {
 
-    AddedInstrns * AI = AIMap[ MI ];    // get already added instrns for MI
-    if( ! AI ) AI = new AddedInstrns(); 
+       // We are here because the LR was allocted a regiter, but NOT
+       // the correct register.
 
-    AI->InstrnsBefore.push_back( MI );  // add the new MI yp AMI
-    AIMap[ MI ] = AI;
+       // copy the LR of retun value to i0 or f0
 
+               unsigned UniLRReg =getUnifiedRegNum( RegClassID, LR->getColor());
+
+       if(RegClassID == IntRegClassID)
+         UniRetReg = getUnifiedRegNum( RegClassID, SparcIntRegOrder::i0);
+       else if(RegClassID == FloatRegClassID)
+         UniRetReg = getUnifiedRegNum( RegClassID, SparcFloatRegOrder::f0);
+
+       AdMI = cpReg2RegMI( UniLRReg, UniRetReg, RegType); 
+
+      }
+      else 
+       assert(0 && "TODO: Copy the return value from stack\n");
     
-    cout << "Inserted a copy instr for a RET/CALL instr " << endl;
+    } else { 
 
-    // We don't color LR here. It's colored as any other normal LR or
-    // as an incoming arg or a return value of a call.
-  }
+      // if NO LR we have to add an explicit copy to move the value to 
+      // the return register.
+
+      //AdMI = cpValue2RegMI( RetVal, UniRetReg, RegType);
+      //(RetAI->InstrnsBefore).push_back( AdMI );
+      // assert( 0 && "Returned constant must be moved to the ret reg\n");
+    }
+
+
+  } // if there is a return value
 
 }
 
-// Generates a copy machine instruction to copy a value to a given
-// register.
 
-MachineInstr * UltraSparcRegInfo::getCopy2RegMI(const Value *SrcVal,
-                                               const unsigned Reg,
-                                               unsigned RegClassID) const {
-  MachineInstr * MI;
+//---------------------------------------------------------------------------
+// Copy from a register to register. Register number must be the unified
+// register number
+//---------------------------------------------------------------------------
+
 
-  if(  RegClassID == IntRegClassID ) {  // if integer move
+MachineInstr * UltraSparcRegInfo::cpReg2RegMI(const unsigned SrcReg, 
+                                             const unsigned DestReg,
+                                             const int RegType) const {
+
+  assert( (SrcReg != InvalidRegNum) && (DestReg != InvalidRegNum) &&
+         "Invalid Register");
+  
+  MachineInstr * MI = NULL;
 
+  switch( RegType ) {
+    
+  case IntRegType:
     MI = new MachineInstr(ADD, 3);
-    MI->SetMachineOperand(0, MachineOperand::MO_VirtualRegister, SrcVal);
+    MI->SetMachineOperand(0, SrcReg, false);
     MI->SetMachineOperand(1, SparcIntRegOrder::g0, false);
-    MI->SetMachineOperand(2, Reg, true);
+    MI->SetMachineOperand(2, DestReg, true);
+    break;
+
+  case FPSingleRegType:
+    MI = new MachineInstr(FMOVS, 2);
+    MI->SetMachineOperand(0, SrcReg, false);
+    MI->SetMachineOperand(1, DestReg, true);
+    break;
+
+  case FPDoubleRegType:
+    MI = new MachineInstr(FMOVD, 2);
+    MI->SetMachineOperand(0, SrcReg, false);    
+    MI->SetMachineOperand(1, DestReg, true);
+    break;
+
+  default:
+    assert(0 && "Unknow RegType");
   }
-  else {                                // if FP move
 
-    if(SrcVal->getType()-> getPrimitiveID() == Type::FloatTyID )
-      MI = new MachineInstr(FMOVS, 2);
-    else if(SrcVal->getType()-> getPrimitiveID() == Type::DoubleTyID)
-      MI = new MachineInstr(FMOVD, 2);
-    else assert( 0 && "Unknown Type");
+  return MI;
+}
+
+
+
 
-    MI->SetMachineOperand(0, MachineOperand::MO_VirtualRegister, SrcVal);
-    MI->SetMachineOperand(1, Reg, true);
+//---------------------------------------------------------------------------
+// Only  constant/label values are accepted.
+// ***This code is temporary ***
+//---------------------------------------------------------------------------
+
+
+MachineInstr * UltraSparcRegInfo::cpValue2RegMI(Value * Val, 
+                                               const unsigned DestReg,
+                                               const int RegType) const {
+
+  assert( (DestReg != InvalidRegNum) && "Invalid Register");
+
+  /*
+  unsigned MReg;
+  int64_t Imm;
+
+  MachineOperand::MachineOperandType MOTypeInt = 
+    ChooseRegOrImmed(Val, ADD,  *UltraSparcInfo, true, MReg, Imm);
+  */
+
+  MachineOperand::MachineOperandType MOType;
+
+  switch( Val->getValueType() ) {
+
+  case Value::ConstantVal: 
+  case Value::GlobalVal:
+    MOType = MachineOperand:: MO_UnextendedImmed;  // TODO**** correct???
+    break;
+
+  case Value::BasicBlockVal:
+  case Value::MethodVal:
+    MOType = MachineOperand::MO_PCRelativeDisp;
+    break;
+
+  default:
+    cout << "Value Type: " << Val->getValueType() << endl;
+    assert(0 && "Unknown val type - Only constants/globals/labels are valid");
   }
 
-  return MI;
 
+
+  MachineInstr * MI = NULL;
+
+  switch( RegType ) {
+    
+  case IntRegType:
+    MI = new MachineInstr(ADD);
+    MI->SetMachineOperand(0, MOType, Val, false);
+    MI->SetMachineOperand(1, SparcIntRegOrder::g0, false);
+    MI->SetMachineOperand(2, DestReg, true);
+    break;
+
+  case FPSingleRegType:
+    assert(0 && "FP const move not yet implemented");
+    MI = new MachineInstr(FMOVS);
+    MI->SetMachineOperand(0, MachineOperand::MO_SignExtendedImmed, Val, false);
+    MI->SetMachineOperand(1, DestReg, true);
+    break;
+
+  case FPDoubleRegType:    
+    assert(0 && "FP const move not yet implemented");
+    MI = new MachineInstr(FMOVD);
+    MI->SetMachineOperand(0, MachineOperand::MO_SignExtendedImmed, Val, false);
+    MI->SetMachineOperand(1, DestReg, true);
+    break;
+
+  default:
+    assert(0 && "Unknow RegType");
+  }
+
+  return MI;
 }
 
 
+
+
+
+
+
 //---------------------------------------------------------------------------
 // Print the register assigned to a LR
 //---------------------------------------------------------------------------
@@ -490,3 +783,8 @@ void UltraSparcRegInfo::printReg(const LiveRange *const LR) {
 
 
 }
+
+
+
+
+