LLVM API Documentation
00001 //===- ARMRegisterInfo.cpp - ARM Register Information -----------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains the ARM implementation of the TargetRegisterInfo class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "ARM.h" 00015 #include "ARMAddressingModes.h" 00016 #include "ARMInstrInfo.h" 00017 #include "ARMMachineFunctionInfo.h" 00018 #include "ARMRegisterInfo.h" 00019 #include "ARMSubtarget.h" 00020 #include "llvm/Constants.h" 00021 #include "llvm/DerivedTypes.h" 00022 #include "llvm/CodeGen/MachineConstantPool.h" 00023 #include "llvm/CodeGen/MachineFrameInfo.h" 00024 #include "llvm/CodeGen/MachineFunction.h" 00025 #include "llvm/CodeGen/MachineInstrBuilder.h" 00026 #include "llvm/CodeGen/MachineLocation.h" 00027 #include "llvm/CodeGen/MachineRegisterInfo.h" 00028 #include "llvm/CodeGen/RegisterScavenging.h" 00029 #include "llvm/Target/TargetFrameInfo.h" 00030 #include "llvm/Target/TargetMachine.h" 00031 #include "llvm/Target/TargetOptions.h" 00032 #include "llvm/ADT/BitVector.h" 00033 #include "llvm/ADT/SmallVector.h" 00034 #include "llvm/ADT/STLExtras.h" 00035 #include "llvm/Support/CommandLine.h" 00036 #include <algorithm> 00037 using namespace llvm; 00038 00039 static cl::opt<bool> ThumbRegScavenging("enable-thumb-reg-scavenging", 00040 cl::Hidden, 00041 cl::desc("Enable register scavenging on Thumb")); 00042 00043 unsigned ARMRegisterInfo::getRegisterNumbering(unsigned RegEnum) { 00044 using namespace ARM; 00045 switch (RegEnum) { 00046 case R0: case S0: case D0: return 0; 00047 case R1: case S1: case D1: return 1; 00048 case R2: case S2: case D2: return 2; 00049 case R3: case S3: case D3: return 3; 00050 case R4: case S4: case D4: return 4; 00051 case R5: case S5: case D5: return 5; 00052 case R6: case S6: case D6: return 6; 00053 case R7: case S7: case D7: return 7; 00054 case R8: case S8: case D8: return 8; 00055 case R9: case S9: case D9: return 9; 00056 case R10: case S10: case D10: return 10; 00057 case R11: case S11: case D11: return 11; 00058 case R12: case S12: case D12: return 12; 00059 case SP: case S13: case D13: return 13; 00060 case LR: case S14: case D14: return 14; 00061 case PC: case S15: case D15: return 15; 00062 case S16: return 16; 00063 case S17: return 17; 00064 case S18: return 18; 00065 case S19: return 19; 00066 case S20: return 20; 00067 case S21: return 21; 00068 case S22: return 22; 00069 case S23: return 23; 00070 case S24: return 24; 00071 case S25: return 25; 00072 case S26: return 26; 00073 case S27: return 27; 00074 case S28: return 28; 00075 case S29: return 29; 00076 case S30: return 30; 00077 case S31: return 31; 00078 default: 00079 assert(0 && "Unknown ARM register!"); 00080 abort(); 00081 } 00082 } 00083 00084 unsigned ARMRegisterInfo::getRegisterNumbering(unsigned RegEnum, 00085 bool &isSPVFP) { 00086 isSPVFP = false; 00087 00088 using namespace ARM; 00089 switch (RegEnum) { 00090 default: 00091 assert(0 && "Unknown ARM register!"); 00092 abort(); 00093 case R0: case D0: return 0; 00094 case R1: case D1: return 1; 00095 case R2: case D2: return 2; 00096 case R3: case D3: return 3; 00097 case R4: case D4: return 4; 00098 case R5: case D5: return 5; 00099 case R6: case D6: return 6; 00100 case R7: case D7: return 7; 00101 case R8: case D8: return 8; 00102 case R9: case D9: return 9; 00103 case R10: case D10: return 10; 00104 case R11: case D11: return 11; 00105 case R12: case D12: return 12; 00106 case SP: case D13: return 13; 00107 case LR: case D14: return 14; 00108 case PC: case D15: return 15; 00109 00110 case S0: case S1: case S2: case S3: 00111 case S4: case S5: case S6: case S7: 00112 case S8: case S9: case S10: case S11: 00113 case S12: case S13: case S14: case S15: 00114 case S16: case S17: case S18: case S19: 00115 case S20: case S21: case S22: case S23: 00116 case S24: case S25: case S26: case S27: 00117 case S28: case S29: case S30: case S31: { 00118 isSPVFP = true; 00119 switch (RegEnum) { 00120 default: return 0; // Avoid compile time warning. 00121 case S0: return 0; 00122 case S1: return 1; 00123 case S2: return 2; 00124 case S3: return 3; 00125 case S4: return 4; 00126 case S5: return 5; 00127 case S6: return 6; 00128 case S7: return 7; 00129 case S8: return 8; 00130 case S9: return 9; 00131 case S10: return 10; 00132 case S11: return 11; 00133 case S12: return 12; 00134 case S13: return 13; 00135 case S14: return 14; 00136 case S15: return 15; 00137 case S16: return 16; 00138 case S17: return 17; 00139 case S18: return 18; 00140 case S19: return 19; 00141 case S20: return 20; 00142 case S21: return 21; 00143 case S22: return 22; 00144 case S23: return 23; 00145 case S24: return 24; 00146 case S25: return 25; 00147 case S26: return 26; 00148 case S27: return 27; 00149 case S28: return 28; 00150 case S29: return 29; 00151 case S30: return 30; 00152 case S31: return 31; 00153 } 00154 } 00155 } 00156 } 00157 00158 ARMRegisterInfo::ARMRegisterInfo(const TargetInstrInfo &tii, 00159 const ARMSubtarget &sti) 00160 : ARMGenRegisterInfo(ARM::ADJCALLSTACKDOWN, ARM::ADJCALLSTACKUP), 00161 TII(tii), STI(sti), 00162 FramePtr((STI.useThumbBacktraces() || STI.isThumb()) ? ARM::R7 : ARM::R11) { 00163 } 00164 00165 static inline 00166 const MachineInstrBuilder &AddDefaultPred(const MachineInstrBuilder &MIB) { 00167 return MIB.addImm((int64_t)ARMCC::AL).addReg(0); 00168 } 00169 00170 static inline 00171 const MachineInstrBuilder &AddDefaultCC(const MachineInstrBuilder &MIB) { 00172 return MIB.addReg(0); 00173 } 00174 00175 /// emitLoadConstPool - Emits a load from constpool to materialize the 00176 /// specified immediate. 00177 void ARMRegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB, 00178 MachineBasicBlock::iterator &MBBI, 00179 unsigned DestReg, int Val, 00180 unsigned Pred, unsigned PredReg, 00181 const TargetInstrInfo *TII, 00182 bool isThumb) const { 00183 MachineFunction &MF = *MBB.getParent(); 00184 MachineConstantPool *ConstantPool = MF.getConstantPool(); 00185 Constant *C = ConstantInt::get(Type::Int32Ty, Val); 00186 unsigned Idx = ConstantPool->getConstantPoolIndex(C, 2); 00187 if (isThumb) 00188 BuildMI(MBB, MBBI, TII->get(ARM::tLDRcp),DestReg).addConstantPoolIndex(Idx); 00189 else 00190 BuildMI(MBB, MBBI, TII->get(ARM::LDRcp), DestReg).addConstantPoolIndex(Idx) 00191 .addReg(0).addImm(0).addImm(Pred).addReg(PredReg); 00192 } 00193 00194 /// isLowRegister - Returns true if the register is low register r0-r7. 00195 /// 00196 bool ARMRegisterInfo::isLowRegister(unsigned Reg) const { 00197 using namespace ARM; 00198 switch (Reg) { 00199 case R0: case R1: case R2: case R3: 00200 case R4: case R5: case R6: case R7: 00201 return true; 00202 default: 00203 return false; 00204 } 00205 } 00206 00207 const unsigned* 00208 ARMRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { 00209 static const unsigned CalleeSavedRegs[] = { 00210 ARM::LR, ARM::R11, ARM::R10, ARM::R9, ARM::R8, 00211 ARM::R7, ARM::R6, ARM::R5, ARM::R4, 00212 00213 ARM::D15, ARM::D14, ARM::D13, ARM::D12, 00214 ARM::D11, ARM::D10, ARM::D9, ARM::D8, 00215 0 00216 }; 00217 00218 static const unsigned DarwinCalleeSavedRegs[] = { 00219 ARM::LR, ARM::R7, ARM::R6, ARM::R5, ARM::R4, 00220 ARM::R11, ARM::R10, ARM::R9, ARM::R8, 00221 00222 ARM::D15, ARM::D14, ARM::D13, ARM::D12, 00223 ARM::D11, ARM::D10, ARM::D9, ARM::D8, 00224 0 00225 }; 00226 return STI.isTargetDarwin() ? DarwinCalleeSavedRegs : CalleeSavedRegs; 00227 } 00228 00229 const TargetRegisterClass* const * 00230 ARMRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const { 00231 static const TargetRegisterClass * const CalleeSavedRegClasses[] = { 00232 &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass, 00233 &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass, 00234 &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass, 00235 00236 &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, 00237 &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, 00238 0 00239 }; 00240 return CalleeSavedRegClasses; 00241 } 00242 00243 BitVector ARMRegisterInfo::getReservedRegs(const MachineFunction &MF) const { 00244 // FIXME: avoid re-calculating this everytime. 00245 BitVector Reserved(getNumRegs()); 00246 Reserved.set(ARM::SP); 00247 Reserved.set(ARM::PC); 00248 if (STI.isTargetDarwin() || hasFP(MF)) 00249 Reserved.set(FramePtr); 00250 // Some targets reserve R9. 00251 if (STI.isR9Reserved()) 00252 Reserved.set(ARM::R9); 00253 return Reserved; 00254 } 00255 00256 bool 00257 ARMRegisterInfo::isReservedReg(const MachineFunction &MF, unsigned Reg) const { 00258 switch (Reg) { 00259 default: break; 00260 case ARM::SP: 00261 case ARM::PC: 00262 return true; 00263 case ARM::R7: 00264 case ARM::R11: 00265 if (FramePtr == Reg && (STI.isTargetDarwin() || hasFP(MF))) 00266 return true; 00267 break; 00268 case ARM::R9: 00269 return STI.isR9Reserved(); 00270 } 00271 00272 return false; 00273 } 00274 00275 bool 00276 ARMRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const { 00277 const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 00278 return ThumbRegScavenging || !AFI->isThumbFunction(); 00279 } 00280 00281 /// hasFP - Return true if the specified function should have a dedicated frame 00282 /// pointer register. This is true if the function has variable sized allocas 00283 /// or if frame pointer elimination is disabled. 00284 /// 00285 bool ARMRegisterInfo::hasFP(const MachineFunction &MF) const { 00286 const MachineFrameInfo *MFI = MF.getFrameInfo(); 00287 return NoFramePointerElim || MFI->hasVarSizedObjects(); 00288 } 00289 00290 // hasReservedCallFrame - Under normal circumstances, when a frame pointer is 00291 // not required, we reserve argument space for call sites in the function 00292 // immediately on entry to the current function. This eliminates the need for 00293 // add/sub sp brackets around call sites. Returns true if the call frame is 00294 // included as part of the stack frame. 00295 bool ARMRegisterInfo::hasReservedCallFrame(MachineFunction &MF) const { 00296 const MachineFrameInfo *FFI = MF.getFrameInfo(); 00297 unsigned CFSize = FFI->getMaxCallFrameSize(); 00298 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 00299 // It's not always a good idea to include the call frame as part of the 00300 // stack frame. ARM (especially Thumb) has small immediate offset to 00301 // address the stack frame. So a large call frame can cause poor codegen 00302 // and may even makes it impossible to scavenge a register. 00303 if (AFI->isThumbFunction()) { 00304 if (CFSize >= ((1 << 8) - 1) * 4 / 2) // Half of imm8 * 4 00305 return false; 00306 } else { 00307 if (CFSize >= ((1 << 12) - 1) / 2) // Half of imm12 00308 return false; 00309 } 00310 return !MF.getFrameInfo()->hasVarSizedObjects(); 00311 } 00312 00313 /// emitARMRegPlusImmediate - Emits a series of instructions to materialize 00314 /// a destreg = basereg + immediate in ARM code. 00315 static 00316 void emitARMRegPlusImmediate(MachineBasicBlock &MBB, 00317 MachineBasicBlock::iterator &MBBI, 00318 unsigned DestReg, unsigned BaseReg, int NumBytes, 00319 ARMCC::CondCodes Pred, unsigned PredReg, 00320 const TargetInstrInfo &TII) { 00321 bool isSub = NumBytes < 0; 00322 if (isSub) NumBytes = -NumBytes; 00323 00324 while (NumBytes) { 00325 unsigned RotAmt = ARM_AM::getSOImmValRotate(NumBytes); 00326 unsigned ThisVal = NumBytes & ARM_AM::rotr32(0xFF, RotAmt); 00327 assert(ThisVal && "Didn't extract field correctly"); 00328 00329 // We will handle these bits from offset, clear them. 00330 NumBytes &= ~ThisVal; 00331 00332 // Get the properly encoded SOImmVal field. 00333 int SOImmVal = ARM_AM::getSOImmVal(ThisVal); 00334 assert(SOImmVal != -1 && "Bit extraction didn't work?"); 00335 00336 // Build the new ADD / SUB. 00337 BuildMI(MBB, MBBI, TII.get(isSub ? ARM::SUBri : ARM::ADDri), DestReg) 00338 .addReg(BaseReg, false, false, true).addImm(SOImmVal) 00339 .addImm((unsigned)Pred).addReg(PredReg).addReg(0); 00340 BaseReg = DestReg; 00341 } 00342 } 00343 00344 /// calcNumMI - Returns the number of instructions required to materialize 00345 /// the specific add / sub r, c instruction. 00346 static unsigned calcNumMI(int Opc, int ExtraOpc, unsigned Bytes, 00347 unsigned NumBits, unsigned Scale) { 00348 unsigned NumMIs = 0; 00349 unsigned Chunk = ((1 << NumBits) - 1) * Scale; 00350 00351 if (Opc == ARM::tADDrSPi) { 00352 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes; 00353 Bytes -= ThisVal; 00354 NumMIs++; 00355 NumBits = 8; 00356 Scale = 1; // Followed by a number of tADDi8. 00357 Chunk = ((1 << NumBits) - 1) * Scale; 00358 } 00359 00360 NumMIs += Bytes / Chunk; 00361 if ((Bytes % Chunk) != 0) 00362 NumMIs++; 00363 if (ExtraOpc) 00364 NumMIs++; 00365 return NumMIs; 00366 } 00367 00368 /// emitThumbRegPlusImmInReg - Emits a series of instructions to materialize 00369 /// a destreg = basereg + immediate in Thumb code. Materialize the immediate 00370 /// in a register using mov / mvn sequences or load the immediate from a 00371 /// constpool entry. 00372 static 00373 void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB, 00374 MachineBasicBlock::iterator &MBBI, 00375 unsigned DestReg, unsigned BaseReg, 00376 int NumBytes, bool CanChangeCC, 00377 const TargetInstrInfo &TII, 00378 const ARMRegisterInfo& MRI) { 00379 bool isHigh = !MRI.isLowRegister(DestReg) || 00380 (BaseReg != 0 && !MRI.isLowRegister(BaseReg)); 00381 bool isSub = false; 00382 // Subtract doesn't have high register version. Load the negative value 00383 // if either base or dest register is a high register. Also, if do not 00384 // issue sub as part of the sequence if condition register is to be 00385 // preserved. 00386 if (NumBytes < 0 && !isHigh && CanChangeCC) { 00387 isSub = true; 00388 NumBytes = -NumBytes; 00389 } 00390 unsigned LdReg = DestReg; 00391 if (DestReg == ARM::SP) { 00392 assert(BaseReg == ARM::SP && "Unexpected!"); 00393 LdReg = ARM::R3; 00394 BuildMI(MBB, MBBI, TII.get(ARM::tMOVr), ARM::R12) 00395 .addReg(ARM::R3, false, false, true); 00396 } 00397 00398 if (NumBytes <= 255 && NumBytes >= 0) 00399 BuildMI(MBB, MBBI, TII.get(ARM::tMOVi8), LdReg).addImm(NumBytes); 00400 else if (NumBytes < 0 && NumBytes >= -255) { 00401 BuildMI(MBB, MBBI, TII.get(ARM::tMOVi8), LdReg).addImm(NumBytes); 00402 BuildMI(MBB, MBBI, TII.get(ARM::tNEG), LdReg) 00403 .addReg(LdReg, false, false, true); 00404 } else 00405 MRI.emitLoadConstPool(MBB, MBBI, LdReg, NumBytes, ARMCC::AL, 0,&TII,true); 00406 00407 // Emit add / sub. 00408 int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr); 00409 const MachineInstrBuilder MIB = BuildMI(MBB, MBBI, TII.get(Opc), DestReg); 00410 if (DestReg == ARM::SP || isSub) 00411 MIB.addReg(BaseReg).addReg(LdReg, false, false, true); 00412 else 00413 MIB.addReg(LdReg).addReg(BaseReg, false, false, true); 00414 if (DestReg == ARM::SP) 00415 BuildMI(MBB, MBBI, TII.get(ARM::tMOVr), ARM::R3) 00416 .addReg(ARM::R12, false, false, true); 00417 } 00418 00419 /// emitThumbRegPlusImmediate - Emits a series of instructions to materialize 00420 /// a destreg = basereg + immediate in Thumb code. 00421 static 00422 void emitThumbRegPlusImmediate(MachineBasicBlock &MBB, 00423 MachineBasicBlock::iterator &MBBI, 00424 unsigned DestReg, unsigned BaseReg, 00425 int NumBytes, const TargetInstrInfo &TII, 00426 const ARMRegisterInfo& MRI) { 00427 bool isSub = NumBytes < 0; 00428 unsigned Bytes = (unsigned)NumBytes; 00429 if (isSub) Bytes = -NumBytes; 00430 bool isMul4 = (Bytes & 3) == 0; 00431 bool isTwoAddr = false; 00432 bool DstNotEqBase = false; 00433 unsigned NumBits = 1; 00434 unsigned Scale = 1; 00435 int Opc = 0; 00436 int ExtraOpc = 0; 00437 00438 if (DestReg == BaseReg && BaseReg == ARM::SP) { 00439 assert(isMul4 && "Thumb sp inc / dec size must be multiple of 4!"); 00440 NumBits = 7; 00441 Scale = 4; 00442 Opc = isSub ? ARM::tSUBspi : ARM::tADDspi; 00443 isTwoAddr = true; 00444 } else if (!isSub && BaseReg == ARM::SP) { 00445 // r1 = add sp, 403 00446 // => 00447 // r1 = add sp, 100 * 4 00448 // r1 = add r1, 3 00449 if (!isMul4) { 00450 Bytes &= ~3; 00451 ExtraOpc = ARM::tADDi3; 00452 } 00453 NumBits = 8; 00454 Scale = 4; 00455 Opc = ARM::tADDrSPi; 00456 } else { 00457 // sp = sub sp, c 00458 // r1 = sub sp, c 00459 // r8 = sub sp, c 00460 if (DestReg != BaseReg) 00461 DstNotEqBase = true; 00462 NumBits = 8; 00463 Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8; 00464 isTwoAddr = true; 00465 } 00466 00467 unsigned NumMIs = calcNumMI(Opc, ExtraOpc, Bytes, NumBits, Scale); 00468 unsigned Threshold = (DestReg == ARM::SP) ? 3 : 2; 00469 if (NumMIs > Threshold) { 00470 // This will expand into too many instructions. Load the immediate from a 00471 // constpool entry. 00472 emitThumbRegPlusImmInReg(MBB, MBBI, DestReg, BaseReg, NumBytes, true, TII, MRI); 00473 return; 00474 } 00475 00476 if (DstNotEqBase) { 00477 if (MRI.isLowRegister(DestReg) && MRI.isLowRegister(BaseReg)) { 00478 // If both are low registers, emit DestReg = add BaseReg, max(Imm, 7) 00479 unsigned Chunk = (1 << 3) - 1; 00480 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes; 00481 Bytes -= ThisVal; 00482 BuildMI(MBB, MBBI, TII.get(isSub ? ARM::tSUBi3 : ARM::tADDi3), DestReg) 00483 .addReg(BaseReg, false, false, true).addImm(ThisVal); 00484 } else { 00485 BuildMI(MBB, MBBI, TII.get(ARM::tMOVr), DestReg) 00486 .addReg(BaseReg, false, false, true); 00487 } 00488 BaseReg = DestReg; 00489 } 00490 00491 unsigned Chunk = ((1 << NumBits) - 1) * Scale; 00492 while (Bytes) { 00493 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes; 00494 Bytes -= ThisVal; 00495 ThisVal /= Scale; 00496 // Build the new tADD / tSUB. 00497 if (isTwoAddr) 00498 BuildMI(MBB, MBBI, TII.get(Opc), DestReg).addReg(DestReg).addImm(ThisVal); 00499 else { 00500 bool isKill = BaseReg != ARM::SP; 00501 BuildMI(MBB, MBBI, TII.get(Opc), DestReg) 00502 .addReg(BaseReg, false, false, isKill).addImm(ThisVal); 00503 BaseReg = DestReg; 00504 00505 if (Opc == ARM::tADDrSPi) { 00506 // r4 = add sp, imm 00507 // r4 = add r4, imm 00508 // ... 00509 NumBits = 8; 00510 Scale = 1; 00511 Chunk = ((1 << NumBits) - 1) * Scale; 00512 Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8; 00513 isTwoAddr = true; 00514 } 00515 } 00516 } 00517 00518 if (ExtraOpc) 00519 BuildMI(MBB, MBBI, TII.get(ExtraOpc), DestReg) 00520 .addReg(DestReg, false, false, true) 00521 .addImm(((unsigned)NumBytes) & 3); 00522 } 00523 00524 static 00525 void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, 00526 int NumBytes, ARMCC::CondCodes Pred, unsigned PredReg, 00527 bool isThumb, const TargetInstrInfo &TII, 00528 const ARMRegisterInfo& MRI) { 00529 if (isThumb) 00530 emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes, TII, MRI); 00531 else 00532 emitARMRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes, 00533 Pred, PredReg, TII); 00534 } 00535 00536 void ARMRegisterInfo:: 00537 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 00538 MachineBasicBlock::iterator I) const { 00539 if (!hasReservedCallFrame(MF)) { 00540 // If we have alloca, convert as follows: 00541 // ADJCALLSTACKDOWN -> sub, sp, sp, amount 00542 // ADJCALLSTACKUP -> add, sp, sp, amount 00543 MachineInstr *Old = I; 00544 unsigned Amount = Old->getOperand(0).getImm(); 00545 if (Amount != 0) { 00546 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 00547 // We need to keep the stack aligned properly. To do this, we round the 00548 // amount of space needed for the outgoing arguments up to the next 00549 // alignment boundary. 00550 unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); 00551 Amount = (Amount+Align-1)/Align*Align; 00552 00553 // Replace the pseudo instruction with a new instruction... 00554 unsigned Opc = Old->getOpcode(); 00555 bool isThumb = AFI->isThumbFunction(); 00556 ARMCC::CondCodes Pred = isThumb 00557 ? ARMCC::AL : (ARMCC::CondCodes)Old->getOperand(1).getImm(); 00558 if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) { 00559 // Note: PredReg is operand 2 for ADJCALLSTACKDOWN. 00560 unsigned PredReg = isThumb ? 0 : Old->getOperand(2).getReg(); 00561 emitSPUpdate(MBB, I, -Amount, Pred, PredReg, isThumb, TII, *this); 00562 } else { 00563 // Note: PredReg is operand 3 for ADJCALLSTACKUP. 00564 unsigned PredReg = isThumb ? 0 : Old->getOperand(3).getReg(); 00565 assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP); 00566 emitSPUpdate(MBB, I, Amount, Pred, PredReg, isThumb, TII, *this); 00567 } 00568 } 00569 } 00570 MBB.erase(I); 00571 } 00572 00573 /// emitThumbConstant - Emit a series of instructions to materialize a 00574 /// constant. 00575 static void emitThumbConstant(MachineBasicBlock &MBB, 00576 MachineBasicBlock::iterator &MBBI, 00577 unsigned DestReg, int Imm, 00578 const TargetInstrInfo &TII, 00579 const ARMRegisterInfo& MRI) { 00580 bool isSub = Imm < 0; 00581 if (isSub) Imm = -Imm; 00582 00583 int Chunk = (1 << 8) - 1; 00584 int ThisVal = (Imm > Chunk) ? Chunk : Imm; 00585 Imm -= ThisVal; 00586 BuildMI(MBB, MBBI, TII.get(ARM::tMOVi8), DestReg).addImm(ThisVal); 00587 if (Imm > 0) 00588 emitThumbRegPlusImmediate(MBB, MBBI, DestReg, DestReg, Imm, TII, MRI); 00589 if (isSub) 00590 BuildMI(MBB, MBBI, TII.get(ARM::tNEG), DestReg) 00591 .addReg(DestReg, false, false, true); 00592 } 00593 00594 /// findScratchRegister - Find a 'free' ARM register. If register scavenger 00595 /// is not being used, R12 is available. Otherwise, try for a call-clobbered 00596 /// register first and then a spilled callee-saved register if that fails. 00597 static 00598 unsigned findScratchRegister(RegScavenger *RS, const TargetRegisterClass *RC, 00599 ARMFunctionInfo *AFI) { 00600 unsigned Reg = RS ? RS->FindUnusedReg(RC, true) : (unsigned) ARM::R12; 00601 if (Reg == 0) 00602 // Try a already spilled CS register. 00603 Reg = RS->FindUnusedReg(RC, AFI->getSpilledCSRegisters()); 00604 00605 return Reg; 00606 } 00607 00608 void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 00609 int SPAdj, RegScavenger *RS) const{ 00610 unsigned i = 0; 00611 MachineInstr &MI = *II; 00612 MachineBasicBlock &MBB = *MI.getParent(); 00613 MachineFunction &MF = *MBB.getParent(); 00614 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 00615 bool isThumb = AFI->isThumbFunction(); 00616 00617 while (!MI.getOperand(i).isFI()) { 00618 ++i; 00619 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 00620 } 00621 00622 unsigned FrameReg = ARM::SP; 00623 int FrameIndex = MI.getOperand(i).getIndex(); 00624 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) + 00625 MF.getFrameInfo()->getStackSize() + SPAdj; 00626 00627 if (AFI->isGPRCalleeSavedArea1Frame(FrameIndex)) 00628 Offset -= AFI->getGPRCalleeSavedArea1Offset(); 00629 else if (AFI->isGPRCalleeSavedArea2Frame(FrameIndex)) 00630 Offset -= AFI->getGPRCalleeSavedArea2Offset(); 00631 else if (AFI->isDPRCalleeSavedAreaFrame(FrameIndex)) 00632 Offset -= AFI->getDPRCalleeSavedAreaOffset(); 00633 else if (hasFP(MF)) { 00634 assert(SPAdj == 0 && "Unexpected"); 00635 // There is alloca()'s in this function, must reference off the frame 00636 // pointer instead. 00637 FrameReg = getFrameRegister(MF); 00638 Offset -= AFI->getFramePtrSpillOffset(); 00639 } 00640 00641 unsigned Opcode = MI.getOpcode(); 00642 const TargetInstrDesc &Desc = MI.getDesc(); 00643 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); 00644 bool isSub = false; 00645 00646 if (Opcode == ARM::ADDri) { 00647 Offset += MI.getOperand(i+1).getImm(); 00648 if (Offset == 0) { 00649 // Turn it into a move. 00650 MI.setDesc(TII.get(ARM::MOVr)); 00651 MI.getOperand(i).ChangeToRegister(FrameReg, false); 00652 MI.RemoveOperand(i+1); 00653 return; 00654 } else if (Offset < 0) { 00655 Offset = -Offset; 00656 isSub = true; 00657 MI.setDesc(TII.get(ARM::SUBri)); 00658 } 00659 00660 // Common case: small offset, fits into instruction. 00661 int ImmedOffset = ARM_AM::getSOImmVal(Offset); 00662 if (ImmedOffset != -1) { 00663 // Replace the FrameIndex with sp / fp 00664 MI.getOperand(i).ChangeToRegister(FrameReg, false); 00665 MI.getOperand(i+1).ChangeToImmediate(ImmedOffset); 00666 return; 00667 } 00668 00669 // Otherwise, we fallback to common code below to form the imm offset with 00670 // a sequence of ADDri instructions. First though, pull as much of the imm 00671 // into this ADDri as possible. 00672 unsigned RotAmt = ARM_AM::getSOImmValRotate(Offset); 00673 unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xFF, RotAmt); 00674 00675 // We will handle these bits from offset, clear them. 00676 Offset &= ~ThisImmVal; 00677 00678 // Get the properly encoded SOImmVal field. 00679 int ThisSOImmVal = ARM_AM::getSOImmVal(ThisImmVal); 00680 assert(ThisSOImmVal != -1 && "Bit extraction didn't work?"); 00681 MI.getOperand(i+1).ChangeToImmediate(ThisSOImmVal); 00682 } else if (Opcode == ARM::tADDrSPi) { 00683 Offset += MI.getOperand(i+1).getImm(); 00684 00685 // Can't use tADDrSPi if it's based off the frame pointer. 00686 unsigned NumBits = 0; 00687 unsigned Scale = 1; 00688 if (FrameReg != ARM::SP) { 00689 Opcode = ARM::tADDi3; 00690 MI.setDesc(TII.get(ARM::tADDi3)); 00691 NumBits = 3; 00692 } else { 00693 NumBits = 8; 00694 Scale = 4; 00695 assert((Offset & 3) == 0 && 00696 "Thumb add/sub sp, #imm immediate must be multiple of 4!"); 00697 } 00698 00699 if (Offset == 0) { 00700 // Turn it into a move. 00701 MI.setDesc(TII.get(ARM::tMOVr)); 00702 MI.getOperand(i).ChangeToRegister(FrameReg, false); 00703 MI.RemoveOperand(i+1); 00704 return; 00705 } 00706 00707 // Common case: small offset, fits into instruction. 00708 unsigned Mask = (1 << NumBits) - 1; 00709 if (((Offset / Scale) & ~Mask) == 0) { 00710 // Replace the FrameIndex with sp / fp 00711 MI.getOperand(i).ChangeToRegister(FrameReg, false); 00712 MI.getOperand(i+1).ChangeToImmediate(Offset / Scale); 00713 return; 00714 } 00715 00716 unsigned DestReg = MI.getOperand(0).getReg(); 00717 unsigned Bytes = (Offset > 0) ? Offset : -Offset; 00718 unsigned NumMIs = calcNumMI(Opcode, 0, Bytes, NumBits, Scale); 00719 // MI would expand into a large number of instructions. Don't try to 00720 // simplify the immediate. 00721 if (NumMIs > 2) { 00722 emitThumbRegPlusImmediate(MBB, II, DestReg, FrameReg, Offset, TII, *this); 00723 MBB.erase(II); 00724 return; 00725 } 00726 00727 if (Offset > 0) { 00728 // Translate r0 = add sp, imm to 00729 // r0 = add sp, 255*4 00730 // r0 = add r0, (imm - 255*4) 00731 MI.getOperand(i).ChangeToRegister(FrameReg, false); 00732 MI.getOperand(i+1).ChangeToImmediate(Mask); 00733 Offset = (Offset - Mask * Scale); 00734 MachineBasicBlock::iterator NII = next(II); 00735 emitThumbRegPlusImmediate(MBB, NII, DestReg, DestReg, Offset, TII, *this); 00736 } else { 00737 // Translate r0 = add sp, -imm to 00738 // r0 = -imm (this is then translated into a series of instructons) 00739 // r0 = add r0, sp 00740 emitThumbConstant(MBB, II, DestReg, Offset, TII, *this); 00741 MI.setDesc(TII.get(ARM::tADDhirr)); 00742 MI.getOperand(i).ChangeToRegister(DestReg, false, false, true); 00743 MI.getOperand(i+1).ChangeToRegister(FrameReg, false); 00744 } 00745 return; 00746 } else { 00747 unsigned ImmIdx = 0; 00748 int InstrOffs = 0; 00749 unsigned NumBits = 0; 00750 unsigned Scale = 1; 00751 switch (AddrMode) { 00752 case ARMII::AddrMode2: { 00753 ImmIdx = i+2; 00754 InstrOffs = ARM_AM::getAM2Offset(MI.getOperand(ImmIdx).getImm()); 00755 if (ARM_AM::getAM2Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub) 00756 InstrOffs *= -1; 00757 NumBits = 12; 00758 break; 00759 } 00760 case ARMII::AddrMode3: { 00761 ImmIdx = i+2; 00762 InstrOffs = ARM_AM::getAM3Offset(MI.getOperand(ImmIdx).getImm()); 00763 if (ARM_AM::getAM3Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub) 00764 InstrOffs *= -1; 00765 NumBits = 8; 00766 break; 00767 } 00768 case ARMII::AddrMode5: { 00769 ImmIdx = i+1; 00770 InstrOffs = ARM_AM::getAM5Offset(MI.getOperand(ImmIdx).getImm()); 00771 if (ARM_AM::getAM5Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub) 00772 InstrOffs *= -1; 00773 NumBits = 8; 00774 Scale = 4; 00775 break; 00776 } 00777 case ARMII::AddrModeTs: { 00778 ImmIdx = i+1; 00779 InstrOffs = MI.getOperand(ImmIdx).getImm(); 00780 NumBits = (FrameReg == ARM::SP) ? 8 : 5; 00781 Scale = 4; 00782 break; 00783 } 00784 default: 00785 assert(0 && "Unsupported addressing mode!"); 00786 abort(); 00787 break; 00788 } 00789 00790 Offset += InstrOffs * Scale; 00791 assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!"); 00792 if (Offset < 0 && !isThumb) { 00793 Offset = -Offset; 00794 isSub = true; 00795 } 00796 00797 // Common case: small offset, fits into instruction. 00798 MachineOperand &ImmOp = MI.getOperand(ImmIdx); 00799 int ImmedOffset = Offset / Scale; 00800 unsigned Mask = (1 << NumBits) - 1; 00801 if ((unsigned)Offset <= Mask * Scale) { 00802 // Replace the FrameIndex with sp 00803 MI.getOperand(i).ChangeToRegister(FrameReg, false); 00804 if (isSub) 00805 ImmedOffset |= 1 << NumBits; 00806 ImmOp.ChangeToImmediate(ImmedOffset); 00807 return; 00808 } 00809 00810 bool isThumSpillRestore = Opcode == ARM::tRestore || Opcode == ARM::tSpill; 00811 if (AddrMode == ARMII::AddrModeTs) { 00812 // Thumb tLDRspi, tSTRspi. These will change to instructions that use 00813 // a different base register. 00814 NumBits = 5; 00815 Mask = (1 << NumBits) - 1; 00816 } 00817 // If this is a thumb spill / restore, we will be using a constpool load to 00818 // materialize the offset. 00819 if (AddrMode == ARMII::AddrModeTs && isThumSpillRestore) 00820 ImmOp.ChangeToImmediate(0); 00821 else { 00822 // Otherwise, it didn't fit. Pull in what we can to simplify the immed. 00823 ImmedOffset = ImmedOffset & Mask; 00824 if (isSub) 00825 ImmedOffset |= 1 << NumBits; 00826 ImmOp.ChangeToImmediate(ImmedOffset); 00827 Offset &= ~(Mask*Scale); 00828 } 00829 } 00830 00831 // If we get here, the immediate doesn't fit into the instruction. We folded 00832 // as much as possible above, handle the rest, providing a register that is 00833 // SP+LargeImm. 00834 assert(Offset && "This code isn't needed if offset already handled!"); 00835 00836 if (isThumb) { 00837 if (Desc.mayLoad()) { 00838 // Use the destination register to materialize sp + offset. 00839 unsigned TmpReg = MI.getOperand(0).getReg(); 00840 bool UseRR = false; 00841 if (Opcode == ARM::tRestore) { 00842 if (FrameReg == ARM::SP) 00843 emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg, 00844 Offset, false, TII, *this); 00845 else { 00846 emitLoadConstPool(MBB, II, TmpReg, Offset, ARMCC::AL, 0, &TII, true); 00847 UseRR = true; 00848 } 00849 } else 00850 emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII, *this); 00851 MI.setDesc(TII.get(ARM::tLDR)); 00852 MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true); 00853 if (UseRR) 00854 // Use [reg, reg] addrmode. 00855 MI.addOperand(MachineOperand::CreateReg(FrameReg, false)); 00856 else // tLDR has an extra register operand. 00857 MI.addOperand(MachineOperand::CreateReg(0, false)); 00858 } else if (Desc.mayStore()) { 00859 // FIXME! This is horrific!!! We need register scavenging. 00860 // Our temporary workaround has marked r3 unavailable. Of course, r3 is 00861 // also a ABI register so it's possible that is is the register that is 00862 // being storing here. If that's the case, we do the following: 00863 // r12 = r2 00864 // Use r2 to materialize sp + offset 00865 // str r3, r2 00866 // r2 = r12 00867 unsigned ValReg = MI.getOperand(0).getReg(); 00868 unsigned TmpReg = ARM::R3; 00869 bool UseRR = false; 00870 if (ValReg == ARM::R3) { 00871 BuildMI(MBB, II, TII.get(ARM::tMOVr), ARM::R12) 00872 .addReg(ARM::R2, false, false, true); 00873 TmpReg = ARM::R2; 00874 } 00875 if (TmpReg == ARM::R3 && AFI->isR3LiveIn()) 00876 BuildMI(MBB, II, TII.get(ARM::tMOVr), ARM::R12) 00877 .addReg(ARM::R3, false, false, true); 00878 if (Opcode == ARM::tSpill) { 00879 if (FrameReg == ARM::SP) 00880 emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg, 00881 Offset, false, TII, *this); 00882 else { 00883 emitLoadConstPool(MBB, II, TmpReg, Offset, ARMCC::AL, 0, &TII, true); 00884 UseRR = true; 00885 } 00886 } else 00887 emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII, *this); 00888 MI.setDesc(TII.get(ARM::tSTR)); 00889 MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true); 00890 if (UseRR) // Use [reg, reg] addrmode. 00891 MI.addOperand(MachineOperand::CreateReg(FrameReg, false)); 00892 else // tSTR has an extra register operand. 00893 MI.addOperand(MachineOperand::CreateReg(0, false)); 00894 00895 MachineBasicBlock::iterator NII = next(II); 00896 if (ValReg == ARM::R3) 00897 BuildMI(MBB, NII, TII.get(ARM::tMOVr), ARM::R2) 00898 .addReg(ARM::R12, false, false, true); 00899 if (TmpReg == ARM::R3 && AFI->isR3LiveIn()) 00900 BuildMI(MBB, NII, TII.get(ARM::tMOVr), ARM::R3) 00901 .addReg(ARM::R12, false, false, true); 00902 } else 00903 assert(false && "Unexpected opcode!"); 00904 } else { 00905 // Insert a set of r12 with the full address: r12 = sp + offset 00906 // If the offset we have is too large to fit into the instruction, we need 00907 // to form it with a series of ADDri's. Do this by taking 8-bit chunks 00908 // out of 'Offset'. 00909 unsigned ScratchReg = findScratchRegister(RS, &ARM::GPRRegClass, AFI); 00910 if (ScratchReg == 0) 00911 // No register is "free". Scavenge a register. 00912 ScratchReg = RS->scavengeRegister(&ARM::GPRRegClass, II, SPAdj); 00913 int PIdx = MI.findFirstPredOperandIdx(); 00914 ARMCC::CondCodes Pred = (PIdx == -1) 00915 ? ARMCC::AL : (ARMCC::CondCodes)MI.getOperand(PIdx).getImm(); 00916 unsigned PredReg = (PIdx == -1) ? 0 : MI.getOperand(PIdx+1).getReg(); 00917 emitARMRegPlusImmediate(MBB, II, ScratchReg, FrameReg, 00918 isSub ? -Offset : Offset, Pred, PredReg, TII); 00919 MI.getOperand(i).ChangeToRegister(ScratchReg, false, false, true); 00920 } 00921 } 00922 00923 static unsigned estimateStackSize(MachineFunction &MF, MachineFrameInfo *MFI) { 00924 const MachineFrameInfo *FFI = MF.getFrameInfo(); 00925 int Offset = 0; 00926 for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) { 00927 int FixedOff = -FFI->getObjectOffset(i); 00928 if (FixedOff > Offset) Offset = FixedOff; 00929 } 00930 for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) { 00931 if (FFI->isDeadObjectIndex(i)) 00932 continue; 00933 Offset += FFI->getObjectSize(i); 00934 unsigned Align = FFI->getObjectAlignment(i); 00935 // Adjust to alignment boundary 00936 Offset = (Offset+Align-1)/Align*Align; 00937 } 00938 return (unsigned)Offset; 00939 } 00940 00941 void 00942 ARMRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, 00943 RegScavenger *RS) const { 00944 // This tells PEI to spill the FP as if it is any other callee-save register 00945 // to take advantage the eliminateFrameIndex machinery. This also ensures it 00946 // is spilled in the order specified by getCalleeSavedRegs() to make it easier 00947 // to combine multiple loads / stores. 00948 bool CanEliminateFrame = true; 00949 bool CS1Spilled = false; 00950 bool LRSpilled = false; 00951 unsigned NumGPRSpills = 0; 00952 SmallVector<unsigned, 4> UnspilledCS1GPRs; 00953 SmallVector<unsigned, 4> UnspilledCS2GPRs; 00954 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 00955 00956 // Don't spill FP if the frame can be eliminated. This is determined 00957 // by scanning the callee-save registers to see if any is used. 00958 const unsigned *CSRegs = getCalleeSavedRegs(); 00959 const TargetRegisterClass* const *CSRegClasses = getCalleeSavedRegClasses(); 00960 for (unsigned i = 0; CSRegs[i]; ++i) { 00961 unsigned Reg = CSRegs[i]; 00962 bool Spilled = false; 00963 if (MF.getRegInfo().isPhysRegUsed(Reg)) { 00964 AFI->setCSRegisterIsSpilled(Reg); 00965 Spilled = true; 00966 CanEliminateFrame = false; 00967 } else { 00968 // Check alias registers too. 00969 for (const unsigned *Aliases = getAliasSet(Reg); *Aliases; ++Aliases) { 00970 if (MF.getRegInfo().isPhysRegUsed(*Aliases)) { 00971 Spilled = true; 00972 CanEliminateFrame = false; 00973 } 00974 } 00975 } 00976 00977 if (CSRegClasses[i] == &ARM::GPRRegClass) { 00978 if (Spilled) { 00979 NumGPRSpills++; 00980 00981 if (!STI.isTargetDarwin()) { 00982 if (Reg == ARM::LR) 00983 LRSpilled = true; 00984 CS1Spilled = true; 00985 continue; 00986 } 00987 00988 // Keep track if LR and any of R4, R5, R6, and R7 is spilled. 00989 switch (Reg) { 00990 case ARM::LR: 00991 LRSpilled = true; 00992 // Fallthrough 00993 case ARM::R4: 00994 case ARM::R5: 00995 case ARM::R6: 00996 case ARM::R7: 00997 CS1Spilled = true; 00998 break; 00999 default: 01000 break; 01001 } 01002 } else { 01003 if (!STI.isTargetDarwin()) { 01004 UnspilledCS1GPRs.push_back(Reg); 01005 continue; 01006 } 01007 01008 switch (Reg) { 01009 case ARM::R4: 01010 case ARM::R5: 01011 case ARM::R6: 01012 case ARM::R7: 01013 case ARM::LR: 01014 UnspilledCS1GPRs.push_back(Reg); 01015 break; 01016 default: 01017 UnspilledCS2GPRs.push_back(Reg); 01018 break; 01019 } 01020 } 01021 } 01022 } 01023 01024 bool ForceLRSpill = false; 01025 if (!LRSpilled && AFI->isThumbFunction()) { 01026 unsigned FnSize = TII.GetFunctionSizeInBytes(MF); 01027 // Force LR to be spilled if the Thumb function size is > 2048. This enables 01028 // use of BL to implement far jump. If it turns out that it's not needed 01029 // then the branch fix up path will undo it. 01030 if (FnSize >= (1 << 11)) { 01031 CanEliminateFrame = false; 01032 ForceLRSpill = true; 01033 } 01034 } 01035 01036 bool ExtraCSSpill = false; 01037 if (!CanEliminateFrame || hasFP(MF)) { 01038 AFI->setHasStackFrame(true); 01039 01040 // If LR is not spilled, but at least one of R4, R5, R6, and R7 is spilled. 01041 // Spill LR as well so we can fold BX_RET to the registers restore (LDM). 01042 if (!LRSpilled && CS1Spilled) { 01043 MF.getRegInfo().setPhysRegUsed(ARM::LR); 01044 AFI->setCSRegisterIsSpilled(ARM::LR); 01045 NumGPRSpills++; 01046 UnspilledCS1GPRs.erase(std::find(UnspilledCS1GPRs.begin(), 01047 UnspilledCS1GPRs.end(), (unsigned)ARM::LR)); 01048 ForceLRSpill = false; 01049 ExtraCSSpill = true; 01050 } 01051 01052 // Darwin ABI requires FP to point to the stack slot that contains the 01053 // previous FP. 01054 if (STI.isTargetDarwin() || hasFP(MF)) { 01055 MF.getRegInfo().setPhysRegUsed(FramePtr); 01056 NumGPRSpills++; 01057 } 01058 01059 // If stack and double are 8-byte aligned and we are spilling an odd number 01060 // of GPRs. Spill one extra callee save GPR so we won't have to pad between 01061 // the integer and double callee save areas. 01062 unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment(); 01063 if (TargetAlign == 8 && (NumGPRSpills & 1)) { 01064 if (CS1Spilled && !UnspilledCS1GPRs.empty()) { 01065 for (unsigned i = 0, e = UnspilledCS1GPRs.size(); i != e; ++i) { 01066 unsigned Reg = UnspilledCS1GPRs[i]; 01067 // Don't spiil high register if the function is thumb 01068 if (!AFI->isThumbFunction() || isLowRegister(Reg) || Reg == ARM::LR) { 01069 MF.getRegInfo().setPhysRegUsed(Reg); 01070 AFI->setCSRegisterIsSpilled(Reg); 01071 if (!isReservedReg(MF, Reg)) 01072 ExtraCSSpill = true; 01073 break; 01074 } 01075 } 01076 } else if (!UnspilledCS2GPRs.empty() && 01077 !AFI->isThumbFunction()) { 01078 unsigned Reg = UnspilledCS2GPRs.front(); 01079 MF.getRegInfo().setPhysRegUsed(Reg); 01080 AFI->setCSRegisterIsSpilled(Reg); 01081 if (!isReservedReg(MF, Reg)) 01082 ExtraCSSpill = true; 01083 } 01084 } 01085 01086 // Estimate if we might need to scavenge a register at some point in order 01087 // to materialize a stack offset. If so, either spill one additiona 01088 // callee-saved register or reserve a special spill slot to facilitate 01089 // register scavenging. 01090 if (RS && !ExtraCSSpill && !AFI->isThumbFunction()) { 01091 MachineFrameInfo *MFI = MF.getFrameInfo(); 01092 unsigned Size = estimateStackSize(MF, MFI); 01093 unsigned Limit = (1 << 12) - 1; 01094 for (MachineFunction::iterator BB = MF.begin(),E = MF.end();BB != E; ++BB) 01095 for (MachineBasicBlock::iterator I= BB->begin(); I != BB->end(); ++I) { 01096 for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) 01097 if (I->getOperand(i).isFI()) { 01098 unsigned Opcode = I->getOpcode(); 01099 const TargetInstrDesc &Desc = TII.get(Opcode); 01100 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); 01101 if (AddrMode == ARMII::AddrMode3) { 01102 Limit = (1 << 8) - 1; 01103 goto DoneEstimating; 01104 } else if (AddrMode == ARMII::AddrMode5) { 01105 unsigned ThisLimit = ((1 << 8) - 1) * 4; 01106 if (ThisLimit < Limit) 01107 Limit = ThisLimit; 01108 } 01109 } 01110 } 01111 DoneEstimating: 01112 if (Size >= Limit) { 01113 // If any non-reserved CS register isn't spilled, just spill one or two 01114 // extra. That should take care of it! 01115 unsigned NumExtras = TargetAlign / 4; 01116 SmallVector<unsigned, 2> Extras; 01117 while (NumExtras && !UnspilledCS1GPRs.empty()) { 01118 unsigned Reg = UnspilledCS1GPRs.back(); 01119 UnspilledCS1GPRs.pop_back(); 01120 if (!isReservedReg(MF, Reg)) { 01121 Extras.push_back(Reg); 01122 NumExtras--; 01123 } 01124 } 01125 while (NumExtras && !UnspilledCS2GPRs.empty()) { 01126 unsigned Reg = UnspilledCS2GPRs.back(); 01127 UnspilledCS2GPRs.pop_back(); 01128 if (!isReservedReg(MF, Reg)) { 01129 Extras.push_back(Reg); 01130 NumExtras--; 01131 } 01132 } 01133 if (Extras.size() && NumExtras == 0) { 01134 for (unsigned i = 0, e = Extras.size(); i != e; ++i) { 01135 MF.getRegInfo().setPhysRegUsed(Extras[i]); 01136 AFI->setCSRegisterIsSpilled(Extras[i]); 01137 } 01138 } else { 01139 // Reserve a slot closest to SP or frame pointer. 01140 const TargetRegisterClass *RC = &ARM::GPRRegClass; 01141 RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), 01142 RC->getAlignment())); 01143 } 01144 } 01145 } 01146 } 01147 01148 if (ForceLRSpill) { 01149 MF.getRegInfo().setPhysRegUsed(ARM::LR); 01150 AFI->setCSRegisterIsSpilled(ARM::LR); 01151 AFI->setLRIsSpilledForFarJump(true); 01152 } 01153 } 01154 01155 /// Move iterator pass the next bunch of callee save load / store ops for 01156 /// the particular spill area (1: integer area 1, 2: integer area 2, 01157 /// 3: fp area, 0: don't care). 01158 static void movePastCSLoadStoreOps(MachineBasicBlock &MBB, 01159 MachineBasicBlock::iterator &MBBI, 01160 int Opc, unsigned Area, 01161 const ARMSubtarget &STI) { 01162 while (MBBI != MBB.end() && 01163 MBBI->getOpcode() == Opc && MBBI->getOperand(1).isFI()) { 01164 if (Area != 0) { 01165 bool Done = false; 01166 unsigned Category = 0; 01167 switch (MBBI->getOperand(0).getReg()) { 01168 case ARM::R4: case ARM::R5: case ARM::R6: case ARM::R7: 01169 case ARM::LR: 01170 Category = 1; 01171 break; 01172 case ARM::R8: case ARM::R9: case ARM::R10: case ARM::R11: 01173 Category = STI.isTargetDarwin() ? 2 : 1; 01174 break; 01175 case ARM::D8: case ARM::D9: case ARM::D10: case ARM::D11: 01176 case ARM::D12: case ARM::D13: case ARM::D14: case ARM::D15: 01177 Category = 3; 01178 break; 01179 default: 01180 Done = true; 01181 break; 01182 } 01183 if (Done || Category != Area) 01184 break; 01185 } 01186 01187 ++MBBI; 01188 } 01189 } 01190 01191 void ARMRegisterInfo::emitPrologue(MachineFunction &MF) const { 01192 MachineBasicBlock &MBB = MF.front(); 01193 MachineBasicBlock::iterator MBBI = MBB.begin(); 01194 MachineFrameInfo *MFI = MF.getFrameInfo(); 01195 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 01196 bool isThumb = AFI->isThumbFunction(); 01197 unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize(); 01198 unsigned NumBytes = MFI->getStackSize(); 01199 const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 01200 01201 if (isThumb) { 01202 // Check if R3 is live in. It might have to be used as a scratch register. 01203 for (MachineRegisterInfo::livein_iterator I =MF.getRegInfo().livein_begin(), 01204 E = MF.getRegInfo().livein_end(); I != E; ++I) { 01205 if (I->first == ARM::R3) { 01206 AFI->setR3IsLiveIn(true); 01207 break; 01208 } 01209 } 01210 01211 // Thumb add/sub sp, imm8 instructions implicitly multiply the offset by 4. 01212 NumBytes = (NumBytes + 3) & ~3; 01213 MFI->setStackSize(NumBytes); 01214 } 01215 01216 // Determine the sizes of each callee-save spill areas and record which frame 01217 // belongs to which callee-save spill areas. 01218 unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0; 01219 int FramePtrSpillFI = 0; 01220 01221 if (VARegSaveSize) 01222 emitSPUpdate(MBB, MBBI, -VARegSaveSize, ARMCC::AL, 0, isThumb, TII, *this); 01223 01224 if (!AFI->hasStackFrame()) { 01225 if (NumBytes != 0) 01226 emitSPUpdate(MBB, MBBI, -NumBytes, ARMCC::AL, 0, isThumb, TII, *this); 01227 return; 01228 } 01229 01230 for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 01231 unsigned Reg = CSI[i].getReg(); 01232 int FI = CSI[i].getFrameIdx(); 01233 switch (Reg) { 01234 case ARM::R4: 01235 case ARM::R5: 01236 case ARM::R6: 01237 case ARM::R7: 01238 case ARM::LR: 01239 if (Reg == FramePtr) 01240 FramePtrSpillFI = FI; 01241 AFI->addGPRCalleeSavedArea1Frame(FI); 01242 GPRCS1Size += 4; 01243 break; 01244 case ARM::R8: 01245 case ARM::R9: 01246 case ARM::R10: 01247 case ARM::R11: 01248 if (Reg == FramePtr) 01249 FramePtrSpillFI = FI; 01250 if (STI.isTargetDarwin()) { 01251 AFI->addGPRCalleeSavedArea2Frame(FI); 01252 GPRCS2Size += 4; 01253 } else { 01254 AFI->addGPRCalleeSavedArea1Frame(FI); 01255 GPRCS1Size += 4; 01256 } 01257 break; 01258 default: 01259 AFI->addDPRCalleeSavedAreaFrame(FI); 01260 DPRCSSize += 8; 01261 } 01262 } 01263 01264 if (!isThumb) { 01265 // Build the new SUBri to adjust SP for integer callee-save spill area 1. 01266 emitSPUpdate(MBB, MBBI, -GPRCS1Size, ARMCC::AL, 0, isThumb, TII, *this); 01267 movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, 1, STI); 01268 } else if (MBBI != MBB.end() && MBBI->getOpcode() == ARM::tPUSH) 01269 ++MBBI; 01270 01271 // Darwin ABI requires FP to point to the stack slot that contains the 01272 // previous FP. 01273 if (STI.isTargetDarwin() || hasFP(MF)) { 01274 MachineInstrBuilder MIB = 01275 BuildMI(MBB, MBBI, TII.get(isThumb ? ARM::tADDrSPi : ARM::ADDri),FramePtr) 01276 .addFrameIndex(FramePtrSpillFI).addImm(0); 01277 if (!isThumb) AddDefaultCC(AddDefaultPred(MIB)); 01278 } 01279 01280 if (!isThumb) { 01281 // Build the new SUBri to adjust SP for integer callee-save spill area 2. 01282 emitSPUpdate(MBB, MBBI, -GPRCS2Size, ARMCC::AL, 0, false, TII, *this); 01283 01284 // Build the new SUBri to adjust SP for FP callee-save spill area. 01285 movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, 2, STI); 01286 emitSPUpdate(MBB, MBBI, -DPRCSSize, ARMCC::AL, 0, false, TII, *this); 01287 } 01288 01289 // Determine starting offsets of spill areas. 01290 unsigned DPRCSOffset = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize); 01291 unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize; 01292 unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size; 01293 AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI) + NumBytes); 01294 AFI->setGPRCalleeSavedArea1Offset(GPRCS1Offset); 01295 AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset); 01296 AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset); 01297 01298 NumBytes = DPRCSOffset; 01299 if (NumBytes) { 01300 // Insert it after all the callee-save spills. 01301 if (!isThumb) 01302 movePastCSLoadStoreOps(MBB, MBBI, ARM::FSTD, 3, STI); 01303 emitSPUpdate(MBB, MBBI, -NumBytes, ARMCC::AL, 0, isThumb, TII, *this); 01304 } 01305 01306 if(STI.isTargetELF() && hasFP(MF)) { 01307 MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() - 01308 AFI->getFramePtrSpillOffset()); 01309 } 01310 01311 AFI->setGPRCalleeSavedArea1Size(GPRCS1Size); 01312 AFI->setGPRCalleeSavedArea2Size(GPRCS2Size); 01313 AFI->setDPRCalleeSavedAreaSize(DPRCSSize); 01314 } 01315 01316 static bool isCalleeSavedRegister(unsigned Reg, const unsigned *CSRegs) { 01317 for (unsigned i = 0; CSRegs[i]; ++i) 01318 if (Reg == CSRegs[i]) 01319 return true; 01320 return false; 01321 } 01322 01323 static bool isCSRestore(MachineInstr *MI, const unsigned *CSRegs) { 01324 return ((MI->getOpcode() == ARM::FLDD || 01325 MI->getOpcode() == ARM::LDR || 01326 MI->getOpcode() == ARM::tRestore) && 01327 MI->getOperand(1).isFI() && 01328 isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs)); 01329 } 01330 01331 void ARMRegisterInfo::emitEpilogue(MachineFunction &MF, 01332 MachineBasicBlock &MBB) const { 01333 MachineBasicBlock::iterator MBBI = prior(MBB.end()); 01334 assert((MBBI->getOpcode() == ARM::BX_RET || 01335 MBBI->getOpcode() == ARM::tBX_RET || 01336 MBBI->getOpcode() == ARM::tPOP_RET) && 01337 "Can only insert epilog into returning blocks"); 01338 01339 MachineFrameInfo *MFI = MF.getFrameInfo(); 01340 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 01341 bool isThumb = AFI->isThumbFunction(); 01342 unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize(); 01343 int NumBytes = (int)MFI->getStackSize(); 01344 if (!AFI->hasStackFrame()) { 01345 if (NumBytes != 0) 01346 emitSPUpdate(MBB, MBBI, NumBytes, ARMCC::AL, 0, isThumb, TII, *this); 01347 } else { 01348 // Unwind MBBI to point to first LDR / FLDD. 01349 const unsigned *CSRegs = getCalleeSavedRegs(); 01350 if (MBBI != MBB.begin()) { 01351 do 01352 --MBBI; 01353 while (MBBI != MBB.begin() && isCSRestore(MBBI, CSRegs)); 01354 if (!isCSRestore(MBBI, CSRegs)) 01355 ++MBBI; 01356 } 01357 01358 // Move SP to start of FP callee save spill area. 01359 NumBytes -= (AFI->getGPRCalleeSavedArea1Size() + 01360 AFI->getGPRCalleeSavedArea2Size() + 01361 AFI->getDPRCalleeSavedAreaSize()); 01362 if (isThumb) { 01363 if (hasFP(MF)) { 01364 NumBytes = AFI->getFramePtrSpillOffset() - NumBytes; 01365 // Reset SP based on frame pointer only if the stack frame extends beyond 01366 // frame pointer stack slot or target is ELF and the function has FP. 01367 if (NumBytes) 01368 emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, FramePtr, -NumBytes, 01369 TII, *this); 01370 else 01371 BuildMI(MBB, MBBI, TII.get(ARM::tMOVr), ARM::SP).addReg(FramePtr); 01372 } else { 01373 if (MBBI->getOpcode() == ARM::tBX_RET && 01374 &MBB.front() != MBBI && 01375 prior(MBBI)->getOpcode() == ARM::tPOP) { 01376 MachineBasicBlock::iterator PMBBI = prior(MBBI); 01377 emitSPUpdate(MBB, PMBBI, NumBytes, ARMCC::AL, 0, isThumb, TII, *this); 01378 } else 01379 emitSPUpdate(MBB, MBBI, NumBytes, ARMCC::AL, 0, isThumb, TII, *this); 01380 } 01381 } else { 01382 // Darwin ABI requires FP to point to the stack slot that contains the 01383 // previous FP. 01384 if ((STI.isTargetDarwin() && NumBytes) || hasFP(MF)) { 01385 NumBytes = AFI->getFramePtrSpillOffset() - NumBytes; 01386 // Reset SP based on frame pointer only if the stack frame extends beyond 01387 // frame pointer stack slot or target is ELF and the function has FP. 01388 if (AFI->getGPRCalleeSavedArea2Size() || 01389 AFI->getDPRCalleeSavedAreaSize() || 01390 AFI->getDPRCalleeSavedAreaOffset()|| 01391 hasFP(MF)) { 01392 if (NumBytes) 01393 BuildMI(MBB, MBBI, TII.get(ARM::SUBri), ARM::SP).addReg(FramePtr) 01394 .addImm(NumBytes) 01395 .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0); 01396 else 01397 BuildMI(MBB, MBBI, TII.get(ARM::MOVr), ARM::SP).addReg(FramePtr) 01398 .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0); 01399 } 01400 } else if (NumBytes) { 01401 emitSPUpdate(MBB, MBBI, NumBytes, ARMCC::AL, 0, false, TII, *this); 01402 } 01403 01404 // Move SP to start of integer callee save spill area 2. 01405 movePastCSLoadStoreOps(MBB, MBBI, ARM::FLDD, 3, STI); 01406 emitSPUpdate(MBB, MBBI, AFI->getDPRCalleeSavedAreaSize(), ARMCC::AL, 0, 01407 false, TII, *this); 01408 01409 // Move SP to start of integer callee save spill area 1. 01410 movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, 2, STI); 01411 emitSPUpdate(MBB, MBBI, AFI->getGPRCalleeSavedArea2Size(), ARMCC::AL, 0, 01412 false, TII, *this); 01413 01414 // Move SP to SP upon entry to the function. 01415 movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, 1, STI); 01416 emitSPUpdate(MBB, MBBI, AFI->getGPRCalleeSavedArea1Size(), ARMCC::AL, 0, 01417 false, TII, *this); 01418 } 01419 } 01420 01421 if (VARegSaveSize) { 01422 if (isThumb) 01423 // Epilogue for vararg functions: pop LR to R3 and branch off it. 01424 // FIXME: Verify this is still ok when R3 is no longer being reserved. 01425 BuildMI(MBB, MBBI, TII.get(ARM::tPOP)).addReg(ARM::R3); 01426 01427 emitSPUpdate(MBB, MBBI, VARegSaveSize, ARMCC::AL, 0, isThumb, TII, *this); 01428 01429 if (isThumb) { 01430 BuildMI(MBB, MBBI, TII.get(ARM::tBX_RET_vararg)).addReg(ARM::R3); 01431 MBB.erase(MBBI); 01432 } 01433 } 01434 } 01435 01436 unsigned ARMRegisterInfo::getRARegister() const { 01437 return ARM::LR; 01438 } 01439 01440 unsigned ARMRegisterInfo::getFrameRegister(MachineFunction &MF) const { 01441 if (STI.isTargetDarwin() || hasFP(MF)) 01442 return (STI.useThumbBacktraces() || STI.isThumb()) ? ARM::R7 : ARM::R11; 01443 else 01444 return ARM::SP; 01445 } 01446 01447 unsigned ARMRegisterInfo::getEHExceptionRegister() const { 01448 assert(0 && "What is the exception register"); 01449 return 0; 01450 } 01451 01452 unsigned ARMRegisterInfo::getEHHandlerRegister() const { 01453 assert(0 && "What is the exception handler register"); 01454 return 0; 01455 } 01456 01457 int ARMRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const { 01458 return ARMGenRegisterInfo::getDwarfRegNumFull(RegNum, 0); 01459 } 01460 01461 #include "ARMGenRegisterInfo.inc"