LLVM API Documentation
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