LLVM API Documentation

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

SparcV9RegInfo.cpp

Go to the documentation of this file.
00001 //===-- SparcV9RegInfo.cpp - SparcV9 Target Register Information ----------===//
00002 // 
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file was developed by the LLVM research group and is distributed under
00006 // the University of Illinois Open Source License. See LICENSE.TXT for details.
00007 // 
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file contains implementations of SparcV9 specific helper methods
00011 // used for register allocation.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "llvm/CodeGen/MachineFunction.h"
00016 #include "llvm/CodeGen/MachineInstrBuilder.h"
00017 #include "MachineFunctionInfo.h"
00018 #include "MachineCodeForInstruction.h"
00019 #include "MachineInstrAnnot.h"
00020 #include "RegAlloc/LiveRangeInfo.h"
00021 #include "RegAlloc/LiveRange.h"
00022 #include "llvm/DerivedTypes.h"
00023 #include "llvm/Function.h"
00024 #include "llvm/Instructions.h"
00025 #include "SparcV9Internals.h"
00026 #include "SparcV9RegClassInfo.h"
00027 #include "SparcV9RegInfo.h"
00028 #include "SparcV9FrameInfo.h"
00029 #include "SparcV9TargetMachine.h"
00030 #include "SparcV9TmpInstr.h"
00031 #include <iostream>
00032 
00033 namespace llvm {
00034 
00035 enum {
00036   BadRegClass = ~0
00037 };
00038 
00039 SparcV9RegInfo::SparcV9RegInfo(const SparcV9TargetMachine &tgt)
00040   : target (tgt), NumOfIntArgRegs (6), NumOfFloatArgRegs (32)
00041 {
00042   MachineRegClassArr.push_back(new SparcV9IntRegClass(IntRegClassID));
00043   MachineRegClassArr.push_back(new SparcV9FloatRegClass(FloatRegClassID));
00044   MachineRegClassArr.push_back(new SparcV9IntCCRegClass(IntCCRegClassID));
00045   MachineRegClassArr.push_back(new SparcV9FloatCCRegClass(FloatCCRegClassID));
00046   MachineRegClassArr.push_back(new SparcV9SpecialRegClass(SpecialRegClassID));
00047   
00048   assert(SparcV9FloatRegClass::StartOfNonVolatileRegs == 32 && 
00049          "32 Float regs are used for float arg passing");
00050 }
00051 
00052 
00053 // getZeroRegNum - returns the register that contains always zero.
00054 // this is the unified register number
00055 //
00056 unsigned SparcV9RegInfo::getZeroRegNum() const {
00057   return getUnifiedRegNum(SparcV9RegInfo::IntRegClassID,
00058                           SparcV9IntRegClass::g0);
00059 }
00060 
00061 // getCallAddressReg - returns the reg used for pushing the address when a
00062 // method is called. This can be used for other purposes between calls
00063 //
00064 unsigned SparcV9RegInfo::getCallAddressReg() const {
00065   return getUnifiedRegNum(SparcV9RegInfo::IntRegClassID,
00066                           SparcV9IntRegClass::o7);
00067 }
00068 
00069 // Returns the register containing the return address.
00070 // It should be made sure that this  register contains the return 
00071 // value when a return instruction is reached.
00072 //
00073 unsigned SparcV9RegInfo::getReturnAddressReg() const {
00074   return getUnifiedRegNum(SparcV9RegInfo::IntRegClassID,
00075                           SparcV9IntRegClass::i7);
00076 }
00077 
00078 // Register get name implementations...
00079 
00080 // Int register names in same order as enum in class SparcV9IntRegClass
00081 static const char * const IntRegNames[] = {
00082   "o0", "o1", "o2", "o3", "o4", "o5",       "o7",
00083   "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
00084   "i0", "i1", "i2", "i3", "i4", "i5",  
00085   "i6", "i7",
00086   "g0", "g1", "g2", "g3", "g4", "g5",  "g6", "g7", 
00087   "o6"
00088 }; 
00089 
00090 const char * const SparcV9IntRegClass::getRegName(unsigned reg) const {
00091   assert(reg < NumOfAllRegs);
00092   return IntRegNames[reg];
00093 }
00094 
00095 static const char * const FloatRegNames[] = {    
00096   "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",  "f8",  "f9", 
00097   "f10", "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19",
00098   "f20", "f21", "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29",
00099   "f30", "f31", "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
00100   "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47", "f48", "f49",
00101   "f50", "f51", "f52", "f53", "f54", "f55", "f56", "f57", "f58", "f59",
00102   "f60", "f61", "f62", "f63"
00103 };
00104 
00105 const char * const SparcV9FloatRegClass::getRegName(unsigned reg) const {
00106   assert (reg < NumOfAllRegs);
00107   return FloatRegNames[reg];
00108 }
00109 
00110 static const char * const IntCCRegNames[] = {    
00111   "xcc",  "icc",  "ccr"
00112 };
00113 
00114 const char * const SparcV9IntCCRegClass::getRegName(unsigned reg) const {
00115   assert(reg < 3);
00116   return IntCCRegNames[reg];
00117 }
00118 
00119 static const char * const FloatCCRegNames[] = {    
00120   "fcc0", "fcc1",  "fcc2",  "fcc3"
00121 };
00122 
00123 const char * const SparcV9FloatCCRegClass::getRegName(unsigned reg) const {
00124   assert (reg < 4);
00125   return FloatCCRegNames[reg];
00126 }
00127 
00128 static const char * const SpecialRegNames[] = {    
00129   "fsr"
00130 };
00131 
00132 const char * const SparcV9SpecialRegClass::getRegName(unsigned reg) const {
00133   assert (reg < 1);
00134   return SpecialRegNames[reg];
00135 }
00136 
00137 // Get unified reg number for frame pointer
00138 unsigned SparcV9RegInfo::getFramePointer() const {
00139   return getUnifiedRegNum(SparcV9RegInfo::IntRegClassID,
00140                           SparcV9IntRegClass::i6);
00141 }
00142 
00143 // Get unified reg number for stack pointer
00144 unsigned SparcV9RegInfo::getStackPointer() const {
00145   return getUnifiedRegNum(SparcV9RegInfo::IntRegClassID,
00146                           SparcV9IntRegClass::o6);
00147 }
00148 
00149 
00150 //---------------------------------------------------------------------------
00151 // Finds whether a call is an indirect call
00152 //---------------------------------------------------------------------------
00153 
00154 inline bool
00155 isVarArgsFunction(const Type *funcType) {
00156   return cast<FunctionType>(cast<PointerType>(funcType)
00157                             ->getElementType())->isVarArg();
00158 }
00159 
00160 inline bool
00161 isVarArgsCall(const MachineInstr *CallMI) {
00162   Value* callee = CallMI->getOperand(0).getVRegValue();
00163   // const Type* funcType = isa<Function>(callee)? callee->getType()
00164   //   : cast<PointerType>(callee->getType())->getElementType();
00165   const Type* funcType = callee->getType();
00166   return isVarArgsFunction(funcType);
00167 }
00168 
00169 
00170 // Get the register number for the specified argument #argNo,
00171 // 
00172 // Return value:
00173 //      getInvalidRegNum(),  if there is no int register available for the arg. 
00174 //      regNum,              otherwise (this is NOT the unified reg. num).
00175 //                           regClassId is set to the register class ID.
00176 // 
00177 int
00178 SparcV9RegInfo::regNumForIntArg(bool inCallee, bool isVarArgsCall,
00179                                    unsigned argNo, unsigned& regClassId) const
00180 {
00181   regClassId = IntRegClassID;
00182   if (argNo >= NumOfIntArgRegs)
00183     return getInvalidRegNum();
00184   else
00185     return argNo + (inCallee? SparcV9IntRegClass::i0 : SparcV9IntRegClass::o0);
00186 }
00187 
00188 // Get the register number for the specified FP argument #argNo,
00189 // Use INT regs for FP args if this is a varargs call.
00190 // 
00191 // Return value:
00192 //      getInvalidRegNum(),  if there is no int register available for the arg. 
00193 //      regNum,              otherwise (this is NOT the unified reg. num).
00194 //                           regClassId is set to the register class ID.
00195 // 
00196 int
00197 SparcV9RegInfo::regNumForFPArg(unsigned regType,
00198                                   bool inCallee, bool isVarArgsCall,
00199                                   unsigned argNo, unsigned& regClassId) const
00200 {
00201   if (isVarArgsCall)
00202     return regNumForIntArg(inCallee, isVarArgsCall, argNo, regClassId);
00203   else
00204     {
00205       regClassId = FloatRegClassID;
00206       if (regType == FPSingleRegType)
00207         return (argNo*2+1 >= NumOfFloatArgRegs)?
00208           getInvalidRegNum() : SparcV9FloatRegClass::f0 + (argNo * 2 + 1);
00209       else if (regType == FPDoubleRegType)
00210         return (argNo*2 >= NumOfFloatArgRegs)?
00211           getInvalidRegNum() : SparcV9FloatRegClass::f0 + (argNo * 2);
00212       else
00213         assert(0 && "Illegal FP register type");
00214   return 0;
00215     }
00216 }
00217 
00218 
00219 //---------------------------------------------------------------------------
00220 // Finds the return address of a call sparc specific call instruction
00221 //---------------------------------------------------------------------------
00222 
00223 // The following 4  methods are used to find the RegType (SparcV9Internals.h)
00224 // of a LiveRange, a Value, and for a given register unified reg number.
00225 //
00226 int SparcV9RegInfo::getRegTypeForClassAndType(unsigned regClassID,
00227                                                  const Type* type) const
00228 {
00229   switch (regClassID) {
00230   case IntRegClassID:                   return IntRegType; 
00231   case FloatRegClassID:
00232     if (type == Type::FloatTy)          return FPSingleRegType;
00233     else if (type == Type::DoubleTy)    return FPDoubleRegType;
00234     assert(0 && "Unknown type in FloatRegClass"); return 0;
00235   case IntCCRegClassID:                 return IntCCRegType; 
00236   case FloatCCRegClassID:               return FloatCCRegType; 
00237   case SpecialRegClassID:               return SpecialRegType; 
00238   default: assert( 0 && "Unknown reg class ID"); return 0;
00239   }
00240 }
00241 
00242 int SparcV9RegInfo::getRegTypeForDataType(const Type* type) const
00243 {
00244   return getRegTypeForClassAndType(getRegClassIDOfType(type), type);
00245 }
00246 
00247 int SparcV9RegInfo::getRegTypeForLR(const LiveRange *LR) const
00248 {
00249   return getRegTypeForClassAndType(LR->getRegClassID(), LR->getType());
00250 }
00251 
00252 int SparcV9RegInfo::getRegType(int unifiedRegNum) const
00253 {
00254   if (unifiedRegNum < 32) 
00255     return IntRegType;
00256   else if (unifiedRegNum < (32 + 32))
00257     return FPSingleRegType;
00258   else if (unifiedRegNum < (64 + 32))
00259     return FPDoubleRegType;
00260   else if (unifiedRegNum < (64+32+3))
00261     return IntCCRegType;
00262   else if (unifiedRegNum < (64+32+3+4))  
00263     return FloatCCRegType;             
00264   else if (unifiedRegNum < (64+32+3+4+1))  
00265     return SpecialRegType;             
00266   else 
00267     assert(0 && "Invalid unified register number in getRegType");
00268   return 0;
00269 }
00270 
00271 
00272 // To find the register class used for a specified Type
00273 //
00274 unsigned SparcV9RegInfo::getRegClassIDOfType(const Type *type,
00275                                                 bool isCCReg) const {
00276   Type::TypeID ty = type->getTypeID();
00277   unsigned res;
00278     
00279   // FIXME: Comparing types like this isn't very safe...
00280   if ((ty && ty <= Type::LongTyID) || (ty == Type::LabelTyID) ||
00281       (ty == Type::FunctionTyID) ||  (ty == Type::PointerTyID) )
00282     res = IntRegClassID;             // sparc int reg (ty=0: void)
00283   else if (ty <= Type::DoubleTyID)
00284     res = FloatRegClassID;           // sparc float reg class
00285   else { 
00286     //std::cerr << "TypeID: " << ty << "\n";
00287     assert(0 && "Cannot resolve register class for type");
00288     return 0;
00289   }
00290   
00291   if (isCCReg)
00292     return res + 2;      // corresponding condition code register 
00293   else 
00294     return res;
00295 }
00296 
00297 unsigned SparcV9RegInfo::getRegClassIDOfRegType(int regType) const {
00298   switch(regType) {
00299   case IntRegType:      return IntRegClassID;
00300   case FPSingleRegType:
00301   case FPDoubleRegType: return FloatRegClassID;
00302   case IntCCRegType:    return IntCCRegClassID;
00303   case FloatCCRegType:  return FloatCCRegClassID;
00304   case SpecialRegType:  return SpecialRegClassID;
00305   default:
00306     assert(0 && "Invalid register type in getRegClassIDOfRegType");
00307     return 0;
00308   }
00309 }
00310 
00311 //---------------------------------------------------------------------------
00312 // Suggests a register for the ret address in the RET machine instruction.
00313 // We always suggest %i7 by convention.
00314 //---------------------------------------------------------------------------
00315 void SparcV9RegInfo::suggestReg4RetAddr(MachineInstr *RetMI, 
00316              LiveRangeInfo& LRI) const {
00317 
00318   assert(target.getInstrInfo()->isReturn(RetMI->getOpcode()));
00319   
00320   // return address is always mapped to i7 so set it immediately
00321   RetMI->SetRegForOperand(0, getUnifiedRegNum(IntRegClassID,
00322                                               SparcV9IntRegClass::i7));
00323   
00324   // Possible Optimization: 
00325   // Instead of setting the color, we can suggest one. In that case,
00326   // we have to test later whether it received the suggested color.
00327   // In that case, a LR has to be created at the start of method.
00328   // It has to be done as follows (remove the setRegVal above):
00329 
00330   // MachineOperand & MO  = RetMI->getOperand(0);
00331   // const Value *RetAddrVal = MO.getVRegValue();
00332   // assert( RetAddrVal && "LR for ret address must be created at start");
00333   // LiveRange * RetAddrLR = LRI.getLiveRangeForValue( RetAddrVal);  
00334   // RetAddrLR->setSuggestedColor(getUnifiedRegNum( IntRegClassID, 
00335   //                              SparcV9IntRegOrdr::i7) );
00336 }
00337 
00338 
00339 //---------------------------------------------------------------------------
00340 // Suggests a register for the ret address in the JMPL/CALL machine instr.
00341 // SparcV9 ABI dictates that %o7 be used for this purpose.
00342 //---------------------------------------------------------------------------
00343 void
00344 SparcV9RegInfo::suggestReg4CallAddr(MachineInstr * CallMI,
00345                                        LiveRangeInfo& LRI) const
00346 {
00347   CallArgsDescriptor* argDesc = CallArgsDescriptor::get(CallMI); 
00348   const Value *RetAddrVal = argDesc->getReturnAddrReg();
00349   assert(RetAddrVal && "INTERNAL ERROR: Return address value is required");
00350 
00351   // A LR must already exist for the return address.
00352   LiveRange *RetAddrLR = LRI.getLiveRangeForValue(RetAddrVal);
00353   assert(RetAddrLR && "INTERNAL ERROR: No LR for return address of call!");
00354 
00355   unsigned RegClassID = RetAddrLR->getRegClassID();
00356   RetAddrLR->setColor(getUnifiedRegNum(IntRegClassID, SparcV9IntRegClass::o7));
00357 }
00358 
00359 
00360 
00361 //---------------------------------------------------------------------------
00362 //  This method will suggest colors to incoming args to a method. 
00363 //  According to the SparcV9 ABI, the first 6 incoming args are in 
00364 //  %i0 - %i5 (if they are integer) OR in %f0 - %f31 (if they are float).
00365 //  If the arg is passed on stack due to the lack of regs, NOTHING will be
00366 //  done - it will be colored (or spilled) as a normal live range.
00367 //---------------------------------------------------------------------------
00368 void SparcV9RegInfo::suggestRegs4MethodArgs(const Function *Meth, 
00369                  LiveRangeInfo& LRI) const 
00370 {
00371   // Check if this is a varArgs function. needed for choosing regs.
00372   bool isVarArgs = isVarArgsFunction(Meth->getType());
00373   
00374   // Count the arguments, *ignoring* whether they are int or FP args.
00375   // Use this common arg numbering to pick the right int or fp register.
00376   unsigned argNo=0;
00377   for(Function::const_aiterator I = Meth->abegin(), E = Meth->aend();
00378       I != E; ++I, ++argNo) {
00379     LiveRange *LR = LRI.getLiveRangeForValue(I);
00380     assert(LR && "No live range found for method arg");
00381     
00382     unsigned regType = getRegTypeForLR(LR);
00383     unsigned regClassIDOfArgReg = BadRegClass; // for chosen reg (unused)
00384     
00385     int regNum = (regType == IntRegType)
00386       ? regNumForIntArg(/*inCallee*/ true, isVarArgs, argNo, regClassIDOfArgReg)
00387       : regNumForFPArg(regType, /*inCallee*/ true, isVarArgs, argNo,
00388                        regClassIDOfArgReg); 
00389     
00390     if (regNum != getInvalidRegNum())
00391       LR->setSuggestedColor(regNum);
00392   }
00393 }
00394 
00395 
00396 //---------------------------------------------------------------------------
00397 // This method is called after graph coloring to move incoming args to
00398 // the correct hardware registers if they did not receive the correct
00399 // (suggested) color through graph coloring.
00400 //---------------------------------------------------------------------------
00401 void SparcV9RegInfo::colorMethodArgs(const Function *Meth, 
00402                             LiveRangeInfo &LRI,
00403                             std::vector<MachineInstr*>& InstrnsBefore,
00404                             std::vector<MachineInstr*>& InstrnsAfter) const {
00405 
00406   // check if this is a varArgs function. needed for choosing regs.
00407   bool isVarArgs = isVarArgsFunction(Meth->getType());
00408   MachineInstr *AdMI;
00409 
00410   // for each argument
00411   // for each argument.  count INT and FP arguments separately.
00412   unsigned argNo=0, intArgNo=0, fpArgNo=0;
00413   for(Function::const_aiterator I = Meth->abegin(), E = Meth->aend();
00414       I != E; ++I, ++argNo) {
00415     // get the LR of arg
00416     LiveRange *LR = LRI.getLiveRangeForValue(I);
00417     assert( LR && "No live range found for method arg");
00418 
00419     unsigned regType = getRegTypeForLR(LR);
00420     unsigned RegClassID = LR->getRegClassID();
00421     
00422     // Find whether this argument is coming in a register (if not, on stack)
00423     // Also find the correct register the argument must use (UniArgReg)
00424     //
00425     bool isArgInReg = false;
00426     unsigned UniArgReg = getInvalidRegNum(); // reg that LR MUST be colored with
00427     unsigned regClassIDOfArgReg = BadRegClass; // reg class of chosen reg
00428     
00429     int regNum = (regType == IntRegType)
00430       ? regNumForIntArg(/*inCallee*/ true, isVarArgs,
00431                         argNo, regClassIDOfArgReg)
00432       : regNumForFPArg(regType, /*inCallee*/ true, isVarArgs,
00433                        argNo, regClassIDOfArgReg);
00434     
00435     if(regNum != getInvalidRegNum()) {
00436       isArgInReg = true;
00437       UniArgReg = getUnifiedRegNum( regClassIDOfArgReg, regNum);
00438     }
00439     
00440     if( ! LR->isMarkedForSpill() ) {    // if this arg received a register
00441 
00442       unsigned UniLRReg = getUnifiedRegNum(  RegClassID, LR->getColor() );
00443 
00444       // if LR received the correct color, nothing to do
00445       //
00446       if( UniLRReg == UniArgReg )
00447   continue;
00448 
00449       // We are here because the LR did not receive the suggested 
00450       // but LR received another register.
00451       // Now we have to copy the %i reg (or stack pos of arg) 
00452       // to the register the LR was colored with.
00453       
00454       // if the arg is coming in UniArgReg register, it MUST go into
00455       // the UniLRReg register
00456       //
00457       if( isArgInReg ) {
00458   if( regClassIDOfArgReg != RegClassID ) {
00459     // NOTE: This code has not been well-tested.
00460           
00461     // It is a variable argument call: the float reg must go in a %o reg.
00462     // We have to move an int reg to a float reg via memory.
00463           // 
00464           assert(isVarArgs &&
00465                  RegClassID == FloatRegClassID && 
00466                  regClassIDOfArgReg == IntRegClassID &&
00467                  "This should only be an Int register for an FP argument");
00468           
00469     int TmpOff = MachineFunction::get(Meth).getInfo<SparcV9FunctionInfo>()->pushTempValue(
00470                                                 getSpilledRegSize(regType));
00471     cpReg2MemMI(InstrnsBefore,
00472                       UniArgReg, getFramePointer(), TmpOff, IntRegType);
00473           
00474     cpMem2RegMI(InstrnsBefore,
00475                       getFramePointer(), TmpOff, UniLRReg, regType);
00476   }
00477   else {  
00478     cpReg2RegMI(InstrnsBefore, UniArgReg, UniLRReg, regType);
00479   }
00480       }
00481       else {
00482 
00483   // Now the arg is coming on stack. Since the LR received a register,
00484   // we just have to load the arg on stack into that register
00485   //
00486         const TargetFrameInfo& frameInfo = *target.getFrameInfo();
00487   int offsetFromFP =
00488           frameInfo.getIncomingArgOffset(MachineFunction::get(Meth),
00489                                          argNo);
00490 
00491         // float arguments on stack are right justified so adjust the offset!
00492         // int arguments are also right justified but they are always loaded as
00493         // a full double-word so the offset does not need to be adjusted.
00494         if (regType == FPSingleRegType) {
00495           unsigned argSize = target.getTargetData().getTypeSize(LR->getType());
00496           unsigned slotSize = SparcV9FrameInfo::SizeOfEachArgOnStack;
00497           assert(argSize <= slotSize && "Insufficient slot size!");
00498           offsetFromFP += slotSize - argSize;
00499         }
00500 
00501   cpMem2RegMI(InstrnsBefore,
00502                     getFramePointer(), offsetFromFP, UniLRReg, regType);
00503       }
00504       
00505     } // if LR received a color
00506 
00507     else {                             
00508 
00509       // Now, the LR did not receive a color. But it has a stack offset for
00510       // spilling.
00511       // So, if the arg is coming in UniArgReg register,  we can just move
00512       // that on to the stack pos of LR
00513 
00514       if( isArgInReg ) {
00515         
00516   if( regClassIDOfArgReg != RegClassID ) {
00517           assert(0 &&
00518                  "FP arguments to a varargs function should be explicitly "
00519                  "copied to/from int registers by instruction selection!");
00520           
00521     // It must be a float arg for a variable argument call, which
00522           // must come in a %o reg.  Move the int reg to the stack.
00523           // 
00524           assert(isVarArgs && regClassIDOfArgReg == IntRegClassID &&
00525                  "This should only be an Int register for an FP argument");
00526           
00527           cpReg2MemMI(InstrnsBefore, UniArgReg,
00528                       getFramePointer(), LR->getSpillOffFromFP(), IntRegType);
00529         }
00530         else {
00531            cpReg2MemMI(InstrnsBefore, UniArgReg,
00532                        getFramePointer(), LR->getSpillOffFromFP(), regType);
00533         }
00534       }
00535 
00536       else {
00537 
00538   // Now the arg is coming on stack. Since the LR did NOT 
00539   // received a register as well, it is allocated a stack position. We
00540   // can simply change the stack position of the LR. We can do this,
00541   // since this method is called before any other method that makes
00542   // uses of the stack pos of the LR (e.g., updateMachineInstr)
00543         // 
00544         const TargetFrameInfo& frameInfo = *target.getFrameInfo();
00545   int offsetFromFP =
00546           frameInfo.getIncomingArgOffset(MachineFunction::get(Meth),
00547                                          argNo);
00548 
00549         // FP arguments on stack are right justified so adjust offset!
00550         // int arguments are also right justified but they are always loaded as
00551         // a full double-word so the offset does not need to be adjusted.
00552         if (regType == FPSingleRegType) {
00553           unsigned argSize = target.getTargetData().getTypeSize(LR->getType());
00554           unsigned slotSize = SparcV9FrameInfo::SizeOfEachArgOnStack;
00555           assert(argSize <= slotSize && "Insufficient slot size!");
00556           offsetFromFP += slotSize - argSize;
00557         }
00558         
00559   LR->modifySpillOffFromFP( offsetFromFP );
00560       }
00561 
00562     }
00563 
00564   }  // for each incoming argument
00565 
00566 }
00567 
00568 
00569 
00570 //---------------------------------------------------------------------------
00571 // This method is called before graph coloring to suggest colors to the
00572 // outgoing call args and the return value of the call.
00573 //---------------------------------------------------------------------------
00574 void SparcV9RegInfo::suggestRegs4CallArgs(MachineInstr *CallMI, 
00575                LiveRangeInfo& LRI) const {
00576   assert ( (target.getInstrInfo())->isCall(CallMI->getOpcode()) );
00577 
00578   CallArgsDescriptor* argDesc = CallArgsDescriptor::get(CallMI); 
00579   
00580   suggestReg4CallAddr(CallMI, LRI);
00581 
00582   // First color the return value of the call instruction, if any.
00583   // The return value will be in %o0 if the value is an integer type,
00584   // or in %f0 if the value is a float type.
00585   // 
00586   if (const Value *RetVal = argDesc->getReturnValue()) {
00587     LiveRange *RetValLR = LRI.getLiveRangeForValue(RetVal);
00588     assert(RetValLR && "No LR for return Value of call!");
00589 
00590     unsigned RegClassID = RetValLR->getRegClassID();
00591 
00592     // now suggest a register depending on the register class of ret arg
00593     if( RegClassID == IntRegClassID ) 
00594       RetValLR->setSuggestedColor(SparcV9IntRegClass::o0);
00595     else if (RegClassID == FloatRegClassID ) 
00596       RetValLR->setSuggestedColor(SparcV9FloatRegClass::f0 );
00597     else assert( 0 && "Unknown reg class for return value of call\n");
00598   }
00599 
00600   // Now suggest colors for arguments (operands) of the call instruction.
00601   // Colors are suggested only if the arg number is smaller than the
00602   // the number of registers allocated for argument passing.
00603   // Now, go thru call args - implicit operands of the call MI
00604 
00605   unsigned NumOfCallArgs = argDesc->getNumArgs();
00606   
00607   for(unsigned argNo=0, i=0, intArgNo=0, fpArgNo=0;
00608        i < NumOfCallArgs; ++i, ++argNo) {    
00609 
00610     const Value *CallArg = argDesc->getArgInfo(i).getArgVal();
00611     
00612     // get the LR of call operand (parameter)
00613     LiveRange *const LR = LRI.getLiveRangeForValue(CallArg); 
00614     if (!LR)
00615       continue;                    // no live ranges for constants and labels
00616 
00617     unsigned regType = getRegTypeForLR(LR);
00618     unsigned regClassIDOfArgReg = BadRegClass; // chosen reg class (unused)
00619 
00620     // Choose a register for this arg depending on whether it is
00621     // an INT or FP value.  Here we ignore whether or not it is a
00622     // varargs calls, because FP arguments will be explicitly copied
00623     // to an integer Value and handled under (argCopy != NULL) below.
00624     int regNum = (regType == IntRegType)
00625       ? regNumForIntArg(/*inCallee*/ false, /*isVarArgs*/ false,
00626                         argNo, regClassIDOfArgReg)
00627       : regNumForFPArg(regType, /*inCallee*/ false, /*isVarArgs*/ false,
00628                        argNo, regClassIDOfArgReg); 
00629     
00630     // If a register could be allocated, use it.
00631     // If not, do NOTHING as this will be colored as a normal value.
00632     if(regNum != getInvalidRegNum())
00633       LR->setSuggestedColor(regNum);
00634   } // for all call arguments
00635 }
00636 
00637 
00638 //---------------------------------------------------------------------------
00639 // this method is called for an LLVM return instruction to identify which
00640 // values will be returned from this method and to suggest colors.
00641 //---------------------------------------------------------------------------
00642 void SparcV9RegInfo::suggestReg4RetValue(MachineInstr *RetMI, 
00643                                             LiveRangeInfo& LRI) const {
00644 
00645   assert( target.getInstrInfo()->isReturn( RetMI->getOpcode() ) );
00646 
00647   suggestReg4RetAddr(RetMI, LRI);
00648 
00649   // To find the return value (if any), we can get the LLVM return instr.
00650   // from the return address register, which is the first operand
00651   Value* tmpI = RetMI->getOperand(0).getVRegValue();
00652   ReturnInst* retI=cast<ReturnInst>(cast<TmpInstruction>(tmpI)->getOperand(0));
00653   if (const Value *RetVal = retI->getReturnValue())
00654     if (LiveRange *const LR = LRI.getLiveRangeForValue(RetVal))
00655       LR->setSuggestedColor(LR->getRegClassID() == IntRegClassID
00656                             ? (unsigned) SparcV9IntRegClass::i0
00657                             : (unsigned) SparcV9FloatRegClass::f0);
00658 }
00659 
00660 //---------------------------------------------------------------------------
00661 // Check if a specified register type needs a scratch register to be
00662 // copied to/from memory.  If it does, the reg. type that must be used
00663 // for scratch registers is returned in scratchRegType.
00664 //
00665 // Only the int CC register needs such a scratch register.
00666 // The FP CC registers can (and must) be copied directly to/from memory.
00667 //---------------------------------------------------------------------------
00668 
00669 bool
00670 SparcV9RegInfo::regTypeNeedsScratchReg(int RegType,
00671                                           int& scratchRegType) const
00672 {
00673   if (RegType == IntCCRegType)
00674     {
00675       scratchRegType = IntRegType;
00676       return true;
00677     }
00678   return false;
00679 }
00680 
00681 //---------------------------------------------------------------------------
00682 // Copy from a register to register. Register number must be the unified
00683 // register number.
00684 //---------------------------------------------------------------------------
00685 
00686 void
00687 SparcV9RegInfo::cpReg2RegMI(std::vector<MachineInstr*>& mvec,
00688                                unsigned SrcReg,
00689                                unsigned DestReg,
00690                                int RegType) const {
00691   assert( ((int)SrcReg != getInvalidRegNum()) && 
00692           ((int)DestReg != getInvalidRegNum()) &&
00693     "Invalid Register");
00694   
00695   MachineInstr * MI = NULL;
00696   
00697   switch( RegType ) {
00698     
00699   case IntCCRegType:
00700     if (getRegType(DestReg) == IntRegType) {
00701       // copy intCC reg to int reg
00702       MI = (BuildMI(V9::RDCCR, 2)
00703             .addMReg(getUnifiedRegNum(SparcV9RegInfo::IntCCRegClassID,
00704                                       SparcV9IntCCRegClass::ccr))
00705             .addMReg(DestReg,MachineOperand::Def));
00706     } else {
00707       // copy int reg to intCC reg
00708       assert(getRegType(SrcReg) == IntRegType
00709              && "Can only copy CC reg to/from integer reg");
00710       MI = (BuildMI(V9::WRCCRr, 3)
00711             .addMReg(SrcReg)
00712             .addMReg(SparcV9IntRegClass::g0)
00713             .addMReg(getUnifiedRegNum(SparcV9RegInfo::IntCCRegClassID,
00714                                       SparcV9IntCCRegClass::ccr),
00715                      MachineOperand::Def));
00716     }
00717     break;
00718     
00719   case FloatCCRegType: 
00720     assert(0 && "Cannot copy FPCC register to any other register");
00721     break;
00722     
00723   case IntRegType:
00724     MI = BuildMI(V9::ADDr, 3).addMReg(SrcReg).addMReg(getZeroRegNum())
00725       .addMReg(DestReg, MachineOperand::Def);
00726     break;
00727     
00728   case FPSingleRegType:
00729     MI = BuildMI(V9::FMOVS, 2).addMReg(SrcReg)
00730            .addMReg(DestReg, MachineOperand::Def);
00731     break;
00732 
00733   case FPDoubleRegType:
00734     MI = BuildMI(V9::FMOVD, 2).addMReg(SrcReg)
00735            .addMReg(DestReg, MachineOperand::Def);
00736     break;
00737 
00738   default:
00739     assert(0 && "Unknown RegType");
00740     break;
00741   }
00742   
00743   if (MI)
00744     mvec.push_back(MI);
00745 }
00746 
00747 /// cpReg2MemMI - Generate SparcV9 MachineInstrs to store a register
00748 /// (SrcReg) to memory, at [PtrReg + Offset].  Register numbers must be the
00749 /// unified register numbers.  RegType must be the SparcV9 register type
00750 /// of SrcReg. When SrcReg is %ccr, scratchReg must be the
00751 /// number of a free integer register.  The newly-generated MachineInstrs
00752 /// are appended to mvec.
00753 ///
00754 void SparcV9RegInfo::cpReg2MemMI(std::vector<MachineInstr*>& mvec,
00755                                  unsigned SrcReg, unsigned PtrReg, int Offset,
00756                                  int RegType, int scratchReg) const {
00757   unsigned OffReg = SparcV9::g4; // Use register g4 for holding large offsets
00758   bool useImmediateOffset = true;
00759 
00760   // If the Offset will not fit in the signed-immediate field, we put it in
00761   // register g4. This takes advantage of the fact that all the opcodes
00762   // used below have the same size immed. field.
00763   if (RegType != IntCCRegType
00764       && !target.getInstrInfo()->constantFitsInImmedField(V9::LDXi, Offset)) {
00765     // Put the offset into a register. We could do this in fewer steps,
00766     // in some cases (see CreateSETSWConst()) but we're being lazy.
00767     MachineInstr *MI = BuildMI(V9::SETHI, 2).addZImm(Offset).addMReg(OffReg,
00768       MachineOperand::Def);
00769     MI->getOperand(0).markHi32();
00770     mvec.push_back(MI);
00771     MI = BuildMI(V9::ORi,3).addMReg(OffReg).addZImm(Offset).addMReg(OffReg,
00772       MachineOperand::Def);
00773     MI->getOperand(1).markLo32();
00774     mvec.push_back(MI);
00775     MI = BuildMI(V9::SRAi5,3).addMReg(OffReg).addZImm(0).addMReg(OffReg,
00776       MachineOperand::Def);
00777     mvec.push_back(MI);
00778     useImmediateOffset = false;
00779   }
00780 
00781   MachineInstr *MI = 0;
00782   switch (RegType) {
00783   case IntRegType:
00784     if (useImmediateOffset)
00785       MI = BuildMI(V9::STXi,3).addMReg(SrcReg).addMReg(PtrReg).addSImm(Offset);
00786     else
00787       MI = BuildMI(V9::STXr,3).addMReg(SrcReg).addMReg(PtrReg).addMReg(OffReg);
00788     break;
00789 
00790   case FPSingleRegType:
00791     if (useImmediateOffset)
00792       MI = BuildMI(V9::STFi, 3).addMReg(SrcReg).addMReg(PtrReg).addSImm(Offset);
00793     else
00794       MI = BuildMI(V9::STFr, 3).addMReg(SrcReg).addMReg(PtrReg).addMReg(OffReg);
00795     break;
00796 
00797   case FPDoubleRegType:
00798     if (useImmediateOffset)
00799       MI = BuildMI(V9::STDFi,3).addMReg(SrcReg).addMReg(PtrReg).addSImm(Offset);
00800     else
00801       MI = BuildMI(V9::STDFr,3).addMReg(SrcReg).addMReg(PtrReg).addSImm(OffReg);
00802     break;
00803 
00804   case IntCCRegType:
00805     assert(scratchReg >= 0 && getRegType(scratchReg) == IntRegType
00806            && "Need a scratch reg of integer type to load or store %ccr");
00807     MI = BuildMI(V9::RDCCR, 2).addMReg(SparcV9::ccr)
00808            .addMReg(scratchReg, MachineOperand::Def);
00809     mvec.push_back(MI);
00810     cpReg2MemMI(mvec, scratchReg, PtrReg, Offset, IntRegType);
00811     return;
00812 
00813   case SpecialRegType: // used only for %fsr itself.
00814   case FloatCCRegType: {
00815     if (useImmediateOffset)
00816       MI = BuildMI(V9::STXFSRi,3).addMReg(SparcV9::fsr).addMReg(PtrReg)
00817              .addSImm(Offset);
00818     else
00819       MI = BuildMI(V9::STXFSRr,3).addMReg(SparcV9::fsr).addMReg(PtrReg)
00820              .addMReg(OffReg);
00821     break;
00822   }
00823   default:
00824     assert(0 && "Unknown RegType in cpReg2MemMI");
00825   }
00826   mvec.push_back(MI);
00827 }
00828 
00829 /// cpMem2RegMI - Generate SparcV9 MachineInstrs to load a register
00830 /// (DestReg) from memory, at [PtrReg + Offset].  Register numbers must be the
00831 /// unified register numbers.  RegType must be the SparcV9 register type
00832 /// of DestReg. When DestReg is %ccr, scratchReg must be the
00833 /// number of a free integer register.  The newly-generated MachineInstrs
00834 /// are appended to mvec.
00835 ///
00836 void SparcV9RegInfo::cpMem2RegMI(std::vector<MachineInstr*>& mvec,
00837                                  unsigned PtrReg, int Offset, unsigned DestReg,
00838                                  int RegType, int scratchReg) const {
00839   unsigned OffReg = SparcV9::g4; // Use register g4 for holding large offsets
00840   bool useImmediateOffset = true;
00841 
00842   // If the Offset will not fit in the signed-immediate field, we put it in
00843   // register g4. This takes advantage of the fact that all the opcodes
00844   // used below have the same size immed. field.
00845   if (RegType != IntCCRegType
00846       && !target.getInstrInfo()->constantFitsInImmedField(V9::LDXi, Offset)) {
00847     MachineInstr *MI = BuildMI(V9::SETHI, 2).addZImm(Offset).addMReg(OffReg,
00848       MachineOperand::Def);
00849     MI->getOperand(0).markHi32();
00850     mvec.push_back(MI);
00851     MI = BuildMI(V9::ORi,3).addMReg(OffReg).addZImm(Offset).addMReg(OffReg,
00852       MachineOperand::Def);
00853     MI->getOperand(1).markLo32();
00854     mvec.push_back(MI);
00855     MI = BuildMI(V9::SRAi5,3).addMReg(OffReg).addZImm(0).addMReg(OffReg,
00856       MachineOperand::Def);
00857     mvec.push_back(MI);
00858     useImmediateOffset = false;
00859   }
00860 
00861   MachineInstr *MI = 0;
00862   switch (RegType) {
00863   case IntRegType:
00864     if (useImmediateOffset)
00865       MI = BuildMI(V9::LDXi, 3).addMReg(PtrReg).addSImm(Offset)
00866           .addMReg(DestReg, MachineOperand::Def);
00867     else
00868       MI = BuildMI(V9::LDXr, 3).addMReg(PtrReg).addMReg(OffReg)
00869           .addMReg(DestReg, MachineOperand::Def);
00870     break;
00871 
00872   case FPSingleRegType:
00873     if (useImmediateOffset)
00874       MI = BuildMI(V9::LDFi, 3).addMReg(PtrReg).addSImm(Offset)
00875           .addMReg(DestReg, MachineOperand::Def);
00876     else
00877       MI = BuildMI(V9::LDFr, 3).addMReg(PtrReg).addMReg(OffReg)
00878           .addMReg(DestReg, MachineOperand::Def);
00879     break;
00880 
00881   case FPDoubleRegType:
00882     if (useImmediateOffset)
00883       MI= BuildMI(V9::LDDFi, 3).addMReg(PtrReg).addSImm(Offset)
00884           .addMReg(DestReg, MachineOperand::Def);
00885     else
00886       MI= BuildMI(V9::LDDFr, 3).addMReg(PtrReg).addMReg(OffReg)
00887           .addMReg(DestReg, MachineOperand::Def);
00888     break;
00889 
00890   case IntCCRegType:
00891     assert(scratchReg >= 0 && getRegType(scratchReg) == IntRegType
00892            && "Need a scratch reg of integer type to load or store %ccr");
00893     cpMem2RegMI(mvec, PtrReg, Offset, scratchReg, IntRegType);
00894     MI = BuildMI(V9::WRCCRr, 3).addMReg(scratchReg).addMReg(SparcV9::g0)
00895            .addMReg(SparcV9::ccr, MachineOperand::Def);
00896     break;
00897     
00898   case SpecialRegType: // used only for %fsr itself
00899   case FloatCCRegType: {
00900     if (useImmediateOffset)
00901       MI = BuildMI(V9::LDXFSRi, 3).addMReg(PtrReg).addSImm(Offset)
00902         .addMReg(SparcV9::fsr, MachineOperand::Def);
00903     else
00904       MI = BuildMI(V9::LDXFSRr, 3).addMReg(PtrReg).addMReg(OffReg)
00905         .addMReg(SparcV9::fsr, MachineOperand::Def);
00906     break;
00907   }
00908   default:
00909     assert(0 && "Unknown RegType in cpMem2RegMI");
00910   }
00911   mvec.push_back(MI);
00912 }
00913 
00914 
00915 //---------------------------------------------------------------------------
00916 // Generate a copy instruction to copy a value to another. Temporarily
00917 // used by PhiElimination code.
00918 //---------------------------------------------------------------------------
00919 
00920 
00921 void
00922 SparcV9RegInfo::cpValue2Value(Value *Src, Value *Dest,
00923                               std::vector<MachineInstr*>& mvec) const {
00924   int RegType = getRegTypeForDataType(Src->getType());
00925   MachineInstr * MI = NULL;
00926 
00927   switch (RegType) {
00928   case IntRegType:
00929     MI = BuildMI(V9::ADDr, 3).addReg(Src).addMReg(getZeroRegNum())
00930       .addRegDef(Dest);
00931     break;
00932   case FPSingleRegType:
00933     MI = BuildMI(V9::FMOVS, 2).addReg(Src).addRegDef(Dest);
00934     break;
00935   case FPDoubleRegType:
00936     MI = BuildMI(V9::FMOVD, 2).addReg(Src).addRegDef(Dest);
00937     break;
00938   default:
00939     assert(0 && "Unknown RegType in cpValue2Value");
00940   }
00941 
00942   mvec.push_back(MI);
00943 }
00944 
00945 
00946 
00947 //---------------------------------------------------------------------------
00948 // Print the register assigned to a LR
00949 //---------------------------------------------------------------------------
00950 
00951 void SparcV9RegInfo::printReg(const LiveRange *LR) const {
00952   unsigned RegClassID = LR->getRegClassID();
00953   std::cerr << " Node ";
00954 
00955   if (!LR->hasColor()) {
00956     std::cerr << " - could not find a color\n";
00957     return;
00958   }
00959   
00960   // if a color is found
00961 
00962   std::cerr << " colored with color "<< LR->getColor();
00963 
00964   unsigned uRegName = getUnifiedRegNum(RegClassID, LR->getColor());
00965   
00966   std::cerr << "[";
00967   std::cerr<< getUnifiedRegName(uRegName);
00968   if (RegClassID == FloatRegClassID && LR->getType() == Type::DoubleTy)
00969     std::cerr << "+" << getUnifiedRegName(uRegName+1);
00970   std::cerr << "]\n";
00971 }
00972 
00973 } // End llvm namespace