diff --git a/llvm/lib/Target/Sparc/SparcRegInfo.cpp b/llvm/lib/Target/Sparc/SparcRegInfo.cpp
index 8254b00..0a2570e 100644
--- a/llvm/lib/Target/Sparc/SparcRegInfo.cpp
+++ b/llvm/lib/Target/Sparc/SparcRegInfo.cpp
@@ -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"
 
@@ -15,448 +16,740 @@
 // 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
-
-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.
-
-*/
-
 
 
 //---------------------------------------------------------------------------
-//   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 method sets the hidden operand for return address in RETURN and 
+// JMPL machine instructions.
 //---------------------------------------------------------------------------
 
-void UltraSparcRegInfo::colorArgs(const Method *const Meth, 
-				  LiveRangeInfo& LRI) const 
+bool UltraSparcRegInfo::handleSpecialMInstr(const MachineInstr * MInst, 
+					    LiveRangeInfo& LRI,
+					    vector<RegClass *>RCList) const {
+  
+  unsigned OpCode = MInst->getOpCode();
+
+
+  // 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 gets the hidden value in a return register which is used to
+// pass the return address.
+//---------------------------------------------------------------------------
+
+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 ) {
-
-	// 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
-
-	  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] ) {
-	    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");
-	}
-
-      }
-      else 
-	assert(0 && "unknown float type in method arg");
-
-    } // float register class
-
-    else 
-      assert(0 && "Unknown RegClassID");
   }
   
 }
 
+//---------------------------------------------------------------------------
+// 
+//---------------------------------------------------------------------------
+
+void UltraSparcRegInfo::colorMethodArgs(const Method *const Meth, 
+					LiveRangeInfo& LRI,
+					AddedInstrns *const FirstAI) const {
+
+                                                 // get the argument list
+  const Method::ArgumentListType& ArgList = Meth->getArgumentList();           
+                                                 // get an iterator to arg list
+  Method::ArgumentListType::const_iterator ArgIt = ArgList.begin(); 
+
+  MachineInstr *AdMI;
+
+
+  // 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 && "TODO: Color an Incoming arg on stack");
+
+      // Now add the instruction
+      FirstAI->InstrnsBefore.push_back( AdMI );
+
+    }
+
+    else {                                // LR is not colored (i.e., spilled)
+      
+      assert(0 && "TODO: Color a spilled arg ");
+      
+    }
+
+
+  }  // for each incoming argument
+
+}
+
 
 
 
+//---------------------------------------------------------------------------
+// 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 {
 
 
-void UltraSparcRegInfo::colorCallArgs(vector<const Instruction *> & 
-				      CallInstrList, LiveRangeInfo& LRI,
-				      AddedInstrMapType &AddedInstrMap) const
-{
+  assert( (CallI->getOpcode() == Instruction::Call) && "Not a call instr");
 
-  vector<const Instruction *>::const_iterator InstIt;
-
-  // First color the return value of all call instructions. The return value
+  // 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 );
-      }
-    }
-    else {
-      cout << "Warning: No Live Range for return value of CALL" << endl;
-    }
+    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");
+
   }
 
 
-  for( InstIt=CallInstrList.begin(); InstIt != CallInstrList.end(); ++InstIt) {
+  // 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.
 
-    // Inst = LLVM call instruction
-    const Instruction *const CallI = *InstIt;
+  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); 
 
-    // find the CALL/JMMPL machine instruction
-    MachineCodeForVMInstr &  MInstVec = CallI->getMachineInstrVec();
-    MachineCodeForVMInstr::const_iterator MIIt = MInstVec.begin();
-
-    /*
-    for( ; MIIt != MInstVec.end() && 
-	   ! getUltraSparcInfo().getInstrInfo().isCall((*MIIt)->getOpCode()); 
-	 ++MIIt );
-
-    assert( (MIIt != MInstVec.end())  && "CALL/JMPL not found");
-    */
-
-    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;
-
-    Instruction::op_const_iterator OpIt = CallI->op_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;
-
-    // go thru all the operands of LLVM instruction
-    for( ; OpIt != CallI->op_end(); ++OpIt ) {
-
-      // get the LR of call operand (parameter)
-      LiveRange *const LR = LRI.getLiveRangeForValue((const Value *) *OpIt); 
-
-      if ( !LR ) {
-	cout << " Warning: In call instr, no LR for arg: " ;
-	printValue(*OpIt);
-	cout << endl;
-	continue;
+    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;
+    }
+    
+    unsigned RegType = getRegType( LR );
 
-      unsigned RegClassID = (LR->getRegClass())->getID();
+    // 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;
       
-      // 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);
-	}
-	
-	else {
-	  // TODO: Insert push code here
-	  assert( 0 && "Insert push code here!");
+    }
+    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) ); 
+    
 
-	  AddedInstrns * AI = AddedInstrMap[ CallMI ];
-	  if( ! AI ) AI = new AddedInstrns();
-
-	  // AI->InstrnsBefore.push_back( getStackPushInstr(LR) );
-	  AddedInstrMap[ CallMI ] = AI;
-	  
-	}
-	++intArgNo;
-      }
-      
-      // 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");
-
-
-    } // for each operand in a call instruction
-
-
-
-
-
-  } // for all call instrctions in CallInstrList
+  } // for all call arguments
 
 }
 
 
+//---------------------------------------------------------------------------
+// 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.
+//---------------------------------------------------------------------------
 
 
-
-void UltraSparcRegInfo::colorRetArg(vector<const Instruction *> & 
-				    RetInstrList, LiveRangeInfo& LRI,
-				    AddedInstrMapType &AddedInstrMap) const
-{
-
-  vector<const Instruction *>::const_iterator InstIt;
+void UltraSparcRegInfo::colorCallArgs(const CallInst *const CallI,
+				      LiveRangeInfo& LRI,
+				      AddedInstrns *const CallAI) const {
 
 
-  for(InstIt=RetInstrList.begin(); InstIt != RetInstrList.end(); ++InstIt) {
+  // 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 );
 
-    const ReturnInst *const RetI = (ReturnInst *) *InstIt;
+  if( RetValLR ) {
 
-    // get the return value of this return instruction
-    const Value *RetVal =  (RetI)->getReturnValue();
+    bool recvSugColor = false;
 
-    if( RetVal ) {
+    if( RetValLR->hasSuggestedColor() && RetValLR->hasColor() )
+      if( RetValLR->getSuggestedColor() == RetValLR->getColor())
+	recvSugColor = true;
 
-      // find the CALL/JMMPL machine instruction
-      MachineCodeForVMInstr &  MInstVec = RetI->getMachineInstrVec();
-      MachineCodeForVMInstr::const_iterator MIIt = MInstVec.begin();
+    // if we didn't receive the suggested color for some reason, 
+    // put copy instruction
 
+    if( !recvSugColor ) {
+
+      if( RetValLR->hasColor() ) {
+
+	unsigned RegType = getRegType( RetValLR );
+	unsigned RegClassID = (RetValLR->getRegClass())->getID();
+
+	unsigned UniRetLRReg=getUnifiedRegNum(RegClassID,RetValLR->getColor());
+	unsigned UniRetReg = InvalidRegNum;
+
+	// 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 );
       
-      /*
-      for( ; MIIt != MInstVec.end() && 
-	   !getUltraSparcInfo().getInstrInfo().isReturn((*MIIt)->getOpCode()); 
-	   ++MIIt ) {
-
-	cout << "Inst = "<< TargetInstrDescriptors[(*MIIt)->getOpCode()].opCodeString << endl;
-
-
-      }
-      assert((MIIt != MInstVec.end()) &&"No return machine instruction found");
-      
-      */
-
-      
-      assert(getUltraSparcInfo().getInstrInfo().isReturn((*MIIt)->getOpCode())
-	     &&	   "First machine inst is not a RETURN Machine Instr");
-      
-
-      // RET machine isntruction
-      const MachineInstr *const RetMI = *MIIt;
-
-      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);
-	}
 	
-      }
+      } // if LR has color
       else {
-	cout << "Warning: No LR for return value" << endl;
+	
+	assert(0 && "LR of return value is splilled");
       }
+      
 
+    } // the LR didn't receive the suggested color  
+    
+  } // if there is a LR - i.e., return value is not void
+  
+
+
+  // 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;
+
+    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;
+      }
+
+      //AdMI = cpValue2RegMI( ArgVal, UniArgReg, RegType);
+      //(CallAI->InstrnsBefore).push_back( AdMI );
+      //cout << " *Constant moved to an output register\n";
+
+      continue;
+    }
+    
+
+    // if the LR received the suggested color, NOTHING to do
+
+    if( LR->hasSuggestedColor() && LR->hasColor() )
+      if( LR->getSuggestedColor() == LR->getColor() )
+	continue;
+	
 
 
 
-void UltraSparcRegInfo::setCallOrRetArgCol(LiveRange *const LR, 
-					   const unsigned RegNo,
-					   const MachineInstr *MI,
-					   AddedInstrMapType &AIMap) const {
-
-  // 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 {        
-
-    // 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
-
-    MachineInstr *MI = getCopy2RegMI((*(LR->begin())), RegNo, 
-				     (LR->getRegClass())->getID());
-
-    AddedInstrns * AI = AIMap[ MI ];    // get already added instrns for MI
-    if( ! AI ) AI = new AddedInstrns(); 
-
-    AI->InstrnsBefore.push_back( MI );  // add the new MI yp AMI
-    AIMap[ MI ] = AI;
-
     
-    cout << "Inserted a copy instr for a RET/CALL instr " << endl;
+    if( LR->hasColor() ) {
 
-    // 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.
-  }
+      // 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
+
+
+      unsigned UniLRReg = getUnifiedRegNum( RegClassID,  LR->getColor() );
+
+      if( isArgInReg ) 
+	AdMI = cpReg2RegMI(UniLRReg, UniArgReg, RegType );
+
+      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(0 && "TODO: Copy a spilled call arg to an output reg ");
+      
+    }
+
+  }  // for each parameter in call instruction
 
 }
 
-// Generates a copy machine instruction to copy a value to a given
-// register.
+//---------------------------------------------------------------------------
+// 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 {
 
-MachineInstr * UltraSparcRegInfo::getCopy2RegMI(const Value *SrcVal,
-						const unsigned Reg,
- 						unsigned RegClassID) const {
-  MachineInstr * MI;
 
-  if(  RegClassID == IntRegClassID ) {  // if integer move
 
-    MI = new MachineInstr(ADD, 3);
- 
-    MI->SetMachineOperand(0, MachineOperand::MO_VirtualRegister, SrcVal);
-    MI->SetMachineOperand(1, SparcIntRegOrder::g0, false);
-    MI->SetMachineOperand(2, Reg, true);
+  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
+    }
+
+
+
   }
-  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");
 
-    MI->SetMachineOperand(0, MachineOperand::MO_VirtualRegister, SrcVal);
-    MI->SetMachineOperand(1, Reg, true);
+
+}
+
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+void UltraSparcRegInfo::colorRetValue(const  ReturnInst *const RetI, 
+				      LiveRangeInfo& LRI,
+				      AddedInstrns *const RetAI) const {
+
+
+  // get the return value of this return instruction
+  Value *RetVal =  (Value *) (RetI)->getReturnValue();
+
+  // 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
+
+      if( LR->hasSuggestedColor() && LR->hasColor() )
+	if( LR->getSuggestedColor() == LR->getColor() )
+	  return;
+
+      if( LR->hasColor() ) {
+
+	// We are here because the LR was allocted a regiter, but NOT
+	// the correct register.
+
+	// 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");
+    
+    } else { 
+
+      // 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
+
+}
+
+
+//---------------------------------------------------------------------------
+// Copy from a register to register. Register number must be the unified
+// register number
+//---------------------------------------------------------------------------
+
+
+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, SrcReg, false);
+    MI->SetMachineOperand(1, SparcIntRegOrder::g0, false);
+    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");
   }
 
   return MI;
-
 }
 
 
+
+
+//---------------------------------------------------------------------------
+// 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");
+  }
+
+
+
+  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 @@
 
 
 }
+
+
+
+
+
