1 //===- ARMRegisterInfo.cpp - ARM Register Information -----------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains the ARM implementation of the TargetRegisterInfo class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "ARM.h" 15 #include "ARMAddressingModes.h" 16 #include "ARMInstrInfo.h" 17 #include "ARMMachineFunctionInfo.h" 18 #include "ARMRegisterInfo.h" 19 #include "ARMSubtarget.h" 20 #include "llvm/Constants.h" 21 #include "llvm/DerivedTypes.h" 22 #include "llvm/CodeGen/MachineConstantPool.h" 23 #include "llvm/CodeGen/MachineFrameInfo.h" 24 #include "llvm/CodeGen/MachineFunction.h" 25 #include "llvm/CodeGen/MachineInstrBuilder.h" 26 #include "llvm/CodeGen/MachineLocation.h" 27 #include "llvm/CodeGen/MachineRegisterInfo.h" 28 #include "llvm/CodeGen/RegisterScavenging.h" 29 #include "llvm/Target/TargetFrameInfo.h" 30 #include "llvm/Target/TargetMachine.h" 31 #include "llvm/Target/TargetOptions.h" 32 #include "llvm/ADT/BitVector.h" 33 #include "llvm/ADT/SmallVector.h" 34 using namespace llvm; 35 36 ARMRegisterInfo::ARMRegisterInfo(const TargetInstrInfo &tii, 37 const ARMSubtarget &sti) 38 : ARMBaseRegisterInfo(tii, sti) { 39 } 40 41 static inline 42 const MachineInstrBuilder &AddDefaultPred(const MachineInstrBuilder &MIB) { 43 return MIB.addImm((int64_t)ARMCC::AL).addReg(0); 44 } 45 46 static inline 47 const MachineInstrBuilder &AddDefaultCC(const MachineInstrBuilder &MIB) { 48 return MIB.addReg(0); 49 } 50 51 /// emitLoadConstPool - Emits a load from constpool to materialize the 52 /// specified immediate. 53 void ARMRegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB, 54 MachineBasicBlock::iterator &MBBI, 55 const TargetInstrInfo *TII, DebugLoc dl, 56 unsigned DestReg, int Val, 57 ARMCC::CondCodes Pred, 58 unsigned PredReg) const { 59 MachineFunction &MF = *MBB.getParent(); 60 MachineConstantPool *ConstantPool = MF.getConstantPool(); 61 Constant *C = ConstantInt::get(Type::Int32Ty, Val); 62 unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4); 63 64 BuildMI(MBB, MBBI, dl, TII->get(ARM::LDRcp), DestReg) 65 .addConstantPoolIndex(Idx) 66 .addReg(0).addImm(0).addImm(Pred).addReg(PredReg); 67 } 68 69 bool 70 ARMRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const { 71 return true; 72 } 73 74 // hasReservedCallFrame - Under normal circumstances, when a frame pointer is 75 // not required, we reserve argument space for call sites in the function 76 // immediately on entry to the current function. This eliminates the need for 77 // add/sub sp brackets around call sites. Returns true if the call frame is 78 // included as part of the stack frame. 79 bool ARMRegisterInfo::hasReservedCallFrame(MachineFunction &MF) const { 80 const MachineFrameInfo *FFI = MF.getFrameInfo(); 81 unsigned CFSize = FFI->getMaxCallFrameSize(); 82 // It's not always a good idea to include the call frame as part of the 83 // stack frame. ARM (especially Thumb) has small immediate offset to 84 // address the stack frame. So a large call frame can cause poor codegen 85 // and may even makes it impossible to scavenge a register. 86 if (CFSize >= ((1 << 12) - 1) / 2) // Half of imm12 87 return false; 88 89 return !MF.getFrameInfo()->hasVarSizedObjects(); 90 } 91 92 /// emitARMRegPlusImmediate - Emits a series of instructions to materialize 93 /// a destreg = basereg + immediate in ARM code. 94 static 95 void emitARMRegPlusImmediate(MachineBasicBlock &MBB, 96 MachineBasicBlock::iterator &MBBI, 97 unsigned DestReg, unsigned BaseReg, int NumBytes, 98 ARMCC::CondCodes Pred, unsigned PredReg, 99 const TargetInstrInfo &TII, 100 DebugLoc dl) { 101 bool isSub = NumBytes < 0; 102 if (isSub) NumBytes = -NumBytes; 103 104 while (NumBytes) { 105 unsigned RotAmt = ARM_AM::getSOImmValRotate(NumBytes); 106 unsigned ThisVal = NumBytes & ARM_AM::rotr32(0xFF, RotAmt); 107 assert(ThisVal && "Didn't extract field correctly"); 108 109 // We will handle these bits from offset, clear them. 110 NumBytes &= ~ThisVal; 111 112 // Get the properly encoded SOImmVal field. 113 int SOImmVal = ARM_AM::getSOImmVal(ThisVal); 114 assert(SOImmVal != -1 && "Bit extraction didn't work?"); 115 116 // Build the new ADD / SUB. 117 BuildMI(MBB, MBBI, dl, TII.get(isSub ? ARM::SUBri : ARM::ADDri), DestReg) 118 .addReg(BaseReg, RegState::Kill).addImm(SOImmVal) 119 .addImm((unsigned)Pred).addReg(PredReg).addReg(0); 120 BaseReg = DestReg; 121 } 122 } 123 124 static void 125 emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, 126 const TargetInstrInfo &TII, DebugLoc dl, 127 int NumBytes, 128 ARMCC::CondCodes Pred = ARMCC::AL, unsigned PredReg = 0) { 129 emitARMRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes, 130 Pred, PredReg, TII, dl); 131 } 132 133 void ARMRegisterInfo:: 134 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 135 MachineBasicBlock::iterator I) const { 136 if (!hasReservedCallFrame(MF)) { 137 // If we have alloca, convert as follows: 138 // ADJCALLSTACKDOWN -> sub, sp, sp, amount 139 // ADJCALLSTACKUP -> add, sp, sp, amount 140 MachineInstr *Old = I; 141 DebugLoc dl = Old->getDebugLoc(); 142 unsigned Amount = Old->getOperand(0).getImm(); 143 if (Amount != 0) { 144 // We need to keep the stack aligned properly. To do this, we round the 145 // amount of space needed for the outgoing arguments up to the next 146 // alignment boundary. 147 unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); 148 Amount = (Amount+Align-1)/Align*Align; 149 150 // Replace the pseudo instruction with a new instruction... 151 unsigned Opc = Old->getOpcode(); 152 ARMCC::CondCodes Pred = (ARMCC::CondCodes)Old->getOperand(1).getImm(); 153 if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) { 154 // Note: PredReg is operand 2 for ADJCALLSTACKDOWN. 155 unsigned PredReg = Old->getOperand(2).getReg(); 156 emitSPUpdate(MBB, I, TII, dl, -Amount, Pred, PredReg); 157 } else { 158 // Note: PredReg is operand 3 for ADJCALLSTACKUP. 159 unsigned PredReg = Old->getOperand(3).getReg(); 160 assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP); 161 emitSPUpdate(MBB, I, TII, dl, Amount, Pred, PredReg); 162 } 163 } 164 } 165 MBB.erase(I); 166 } 167 168 /// findScratchRegister - Find a 'free' ARM register. If register scavenger 169 /// is not being used, R12 is available. Otherwise, try for a call-clobbered 170 /// register first and then a spilled callee-saved register if that fails. 171 static 172 unsigned findScratchRegister(RegScavenger *RS, const TargetRegisterClass *RC, 173 ARMFunctionInfo *AFI) { 174 unsigned Reg = RS ? RS->FindUnusedReg(RC, true) : (unsigned) ARM::R12; 175 assert (!AFI->isThumbFunction()); 176 if (Reg == 0) 177 // Try a already spilled CS register. 178 Reg = RS->FindUnusedReg(RC, AFI->getSpilledCSRegisters()); 179 180 return Reg; 181 } 182 183 void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 184 int SPAdj, RegScavenger *RS) const{ 185 unsigned i = 0; 186 MachineInstr &MI = *II; 187 MachineBasicBlock &MBB = *MI.getParent(); 188 MachineFunction &MF = *MBB.getParent(); 189 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 190 DebugLoc dl = MI.getDebugLoc(); 191 192 while (!MI.getOperand(i).isFI()) { 193 ++i; 194 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 195 } 196 197 unsigned FrameReg = ARM::SP; 198 int FrameIndex = MI.getOperand(i).getIndex(); 199 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) + 200 MF.getFrameInfo()->getStackSize() + SPAdj; 201 202 if (AFI->isGPRCalleeSavedArea1Frame(FrameIndex)) 203 Offset -= AFI->getGPRCalleeSavedArea1Offset(); 204 else if (AFI->isGPRCalleeSavedArea2Frame(FrameIndex)) 205 Offset -= AFI->getGPRCalleeSavedArea2Offset(); 206 else if (AFI->isDPRCalleeSavedAreaFrame(FrameIndex)) 207 Offset -= AFI->getDPRCalleeSavedAreaOffset(); 208 else if (hasFP(MF)) { 209 assert(SPAdj == 0 && "Unexpected"); 210 // There is alloca()'s in this function, must reference off the frame 211 // pointer instead. 212 FrameReg = getFrameRegister(MF); 213 Offset -= AFI->getFramePtrSpillOffset(); 214 } 215 216 unsigned Opcode = MI.getOpcode(); 217 const TargetInstrDesc &Desc = MI.getDesc(); 218 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); 219 bool isSub = false; 220 221 // Memory operands in inline assembly always use AddrMode2. 222 if (Opcode == ARM::INLINEASM) 223 AddrMode = ARMII::AddrMode2; 224 225 if (Opcode == ARM::ADDri) { 226 Offset += MI.getOperand(i+1).getImm(); 227 if (Offset == 0) { 228 // Turn it into a move. 229 MI.setDesc(TII.get(ARM::MOVr)); 230 MI.getOperand(i).ChangeToRegister(FrameReg, false); 231 MI.RemoveOperand(i+1); 232 return; 233 } else if (Offset < 0) { 234 Offset = -Offset; 235 isSub = true; 236 MI.setDesc(TII.get(ARM::SUBri)); 237 } 238 239 // Common case: small offset, fits into instruction. 240 int ImmedOffset = ARM_AM::getSOImmVal(Offset); 241 if (ImmedOffset != -1) { 242 // Replace the FrameIndex with sp / fp 243 MI.getOperand(i).ChangeToRegister(FrameReg, false); 244 MI.getOperand(i+1).ChangeToImmediate(ImmedOffset); 245 return; 246 } 247 248 // Otherwise, we fallback to common code below to form the imm offset with 249 // a sequence of ADDri instructions. First though, pull as much of the imm 250 // into this ADDri as possible. 251 unsigned RotAmt = ARM_AM::getSOImmValRotate(Offset); 252 unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xFF, RotAmt); 253 254 // We will handle these bits from offset, clear them. 255 Offset &= ~ThisImmVal; 256 257 // Get the properly encoded SOImmVal field. 258 int ThisSOImmVal = ARM_AM::getSOImmVal(ThisImmVal); 259 assert(ThisSOImmVal != -1 && "Bit extraction didn't work?"); 260 MI.getOperand(i+1).ChangeToImmediate(ThisSOImmVal); 261 } else { 262 unsigned ImmIdx = 0; 263 int InstrOffs = 0; 264 unsigned NumBits = 0; 265 unsigned Scale = 1; 266 switch (AddrMode) { 267 case ARMII::AddrMode2: { 268 ImmIdx = i+2; 269 InstrOffs = ARM_AM::getAM2Offset(MI.getOperand(ImmIdx).getImm()); 270 if (ARM_AM::getAM2Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub) 271 InstrOffs *= -1; 272 NumBits = 12; 273 break; 274 } 275 case ARMII::AddrMode3: { 276 ImmIdx = i+2; 277 InstrOffs = ARM_AM::getAM3Offset(MI.getOperand(ImmIdx).getImm()); 278 if (ARM_AM::getAM3Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub) 279 InstrOffs *= -1; 280 NumBits = 8; 281 break; 282 } 283 case ARMII::AddrMode5: { 284 ImmIdx = i+1; 285 InstrOffs = ARM_AM::getAM5Offset(MI.getOperand(ImmIdx).getImm()); 286 if (ARM_AM::getAM5Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub) 287 InstrOffs *= -1; 288 NumBits = 8; 289 Scale = 4; 290 break; 291 } 292 default: 293 assert(0 && "Unsupported addressing mode!"); 294 abort(); 295 break; 296 } 297 298 Offset += InstrOffs * Scale; 299 assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!"); 300 if (Offset < 0) { 301 Offset = -Offset; 302 isSub = true; 303 } 304 305 // Common case: small offset, fits into instruction. 306 MachineOperand &ImmOp = MI.getOperand(ImmIdx); 307 int ImmedOffset = Offset / Scale; 308 unsigned Mask = (1 << NumBits) - 1; 309 if ((unsigned)Offset <= Mask * Scale) { 310 // Replace the FrameIndex with sp 311 MI.getOperand(i).ChangeToRegister(FrameReg, false); 312 if (isSub) 313 ImmedOffset |= 1 << NumBits; 314 ImmOp.ChangeToImmediate(ImmedOffset); 315 return; 316 } 317 318 // Otherwise, it didn't fit. Pull in what we can to simplify the immed. 319 ImmedOffset = ImmedOffset & Mask; 320 if (isSub) 321 ImmedOffset |= 1 << NumBits; 322 ImmOp.ChangeToImmediate(ImmedOffset); 323 Offset &= ~(Mask*Scale); 324 } 325 326 // If we get here, the immediate doesn't fit into the instruction. We folded 327 // as much as possible above, handle the rest, providing a register that is 328 // SP+LargeImm. 329 assert(Offset && "This code isn't needed if offset already handled!"); 330 331 // Insert a set of r12 with the full address: r12 = sp + offset 332 // If the offset we have is too large to fit into the instruction, we need 333 // to form it with a series of ADDri's. Do this by taking 8-bit chunks 334 // out of 'Offset'. 335 unsigned ScratchReg = findScratchRegister(RS, &ARM::GPRRegClass, AFI); 336 if (ScratchReg == 0) 337 // No register is "free". Scavenge a register. 338 ScratchReg = RS->scavengeRegister(&ARM::GPRRegClass, II, SPAdj); 339 int PIdx = MI.findFirstPredOperandIdx(); 340 ARMCC::CondCodes Pred = (PIdx == -1) 341 ? ARMCC::AL : (ARMCC::CondCodes)MI.getOperand(PIdx).getImm(); 342 unsigned PredReg = (PIdx == -1) ? 0 : MI.getOperand(PIdx+1).getReg(); 343 emitARMRegPlusImmediate(MBB, II, ScratchReg, FrameReg, 344 isSub ? -Offset : Offset, Pred, PredReg, TII, dl); 345 MI.getOperand(i).ChangeToRegister(ScratchReg, false, false, true); 346 } 347 348 /// Move iterator pass the next bunch of callee save load / store ops for 349 /// the particular spill area (1: integer area 1, 2: integer area 2, 350 /// 3: fp area, 0: don't care). 351 static void movePastCSLoadStoreOps(MachineBasicBlock &MBB, 352 MachineBasicBlock::iterator &MBBI, 353 int Opc, unsigned Area, 354 const ARMSubtarget &STI) { 355 while (MBBI != MBB.end() && 356 MBBI->getOpcode() == Opc && MBBI->getOperand(1).isFI()) { 357 if (Area != 0) { 358 bool Done = false; 359 unsigned Category = 0; 360 switch (MBBI->getOperand(0).getReg()) { 361 case ARM::R4: case ARM::R5: case ARM::R6: case ARM::R7: 362 case ARM::LR: 363 Category = 1; 364 break; 365 case ARM::R8: case ARM::R9: case ARM::R10: case ARM::R11: 366 Category = STI.isTargetDarwin() ? 2 : 1; 367 break; 368 case ARM::D8: case ARM::D9: case ARM::D10: case ARM::D11: 369 case ARM::D12: case ARM::D13: case ARM::D14: case ARM::D15: 370 Category = 3; 371 break; 372 default: 373 Done = true; 374 break; 375 } 376 if (Done || Category != Area) 377 break; 378 } 379 380 ++MBBI; 381 } 382 } 383 384 void ARMRegisterInfo::emitPrologue(MachineFunction &MF) const { 385 MachineBasicBlock &MBB = MF.front(); 386 MachineBasicBlock::iterator MBBI = MBB.begin(); 387 MachineFrameInfo *MFI = MF.getFrameInfo(); 388 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 389 unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize(); 390 unsigned NumBytes = MFI->getStackSize(); 391 const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 392 DebugLoc dl = (MBBI != MBB.end() ? 393 MBBI->getDebugLoc() : DebugLoc::getUnknownLoc()); 394 395 // Determine the sizes of each callee-save spill areas and record which frame 396 // belongs to which callee-save spill areas. 397 unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0; 398 int FramePtrSpillFI = 0; 399 400 if (VARegSaveSize) 401 emitSPUpdate(MBB, MBBI, TII, dl, -VARegSaveSize); 402 403 if (!AFI->hasStackFrame()) { 404 if (NumBytes != 0) 405 emitSPUpdate(MBB, MBBI, TII, dl, -NumBytes); 406 return; 407 } 408 409 for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 410 unsigned Reg = CSI[i].getReg(); 411 int FI = CSI[i].getFrameIdx(); 412 switch (Reg) { 413 case ARM::R4: 414 case ARM::R5: 415 case ARM::R6: 416 case ARM::R7: 417 case ARM::LR: 418 if (Reg == FramePtr) 419 FramePtrSpillFI = FI; 420 AFI->addGPRCalleeSavedArea1Frame(FI); 421 GPRCS1Size += 4; 422 break; 423 case ARM::R8: 424 case ARM::R9: 425 case ARM::R10: 426 case ARM::R11: 427 if (Reg == FramePtr) 428 FramePtrSpillFI = FI; 429 if (STI.isTargetDarwin()) { 430 AFI->addGPRCalleeSavedArea2Frame(FI); 431 GPRCS2Size += 4; 432 } else { 433 AFI->addGPRCalleeSavedArea1Frame(FI); 434 GPRCS1Size += 4; 435 } 436 break; 437 default: 438 AFI->addDPRCalleeSavedAreaFrame(FI); 439 DPRCSSize += 8; 440 } 441 } 442 443 // Build the new SUBri to adjust SP for integer callee-save spill area 1. 444 emitSPUpdate(MBB, MBBI, TII, dl, -GPRCS1Size); 445 movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, 1, STI); 446 447 // Darwin ABI requires FP to point to the stack slot that contains the 448 // previous FP. 449 if (STI.isTargetDarwin() || hasFP(MF)) { 450 MachineInstrBuilder MIB = 451 BuildMI(MBB, MBBI, dl, TII.get(ARM::ADDri), FramePtr) 452 .addFrameIndex(FramePtrSpillFI).addImm(0); 453 AddDefaultCC(AddDefaultPred(MIB)); 454 } 455 456 // Build the new SUBri to adjust SP for integer callee-save spill area 2. 457 emitSPUpdate(MBB, MBBI, TII, dl, -GPRCS2Size); 458 459 // Build the new SUBri to adjust SP for FP callee-save spill area. 460 movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, 2, STI); 461 emitSPUpdate(MBB, MBBI, TII, dl, -DPRCSSize); 462 463 // Determine starting offsets of spill areas. 464 unsigned DPRCSOffset = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize); 465 unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize; 466 unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size; 467 AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI) + NumBytes); 468 AFI->setGPRCalleeSavedArea1Offset(GPRCS1Offset); 469 AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset); 470 AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset); 471 472 NumBytes = DPRCSOffset; 473 if (NumBytes) { 474 // Insert it after all the callee-save spills. 475 movePastCSLoadStoreOps(MBB, MBBI, ARM::FSTD, 3, STI); 476 emitSPUpdate(MBB, MBBI, TII, dl, -NumBytes); 477 } 478 479 if (STI.isTargetELF() && hasFP(MF)) { 480 MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() - 481 AFI->getFramePtrSpillOffset()); 482 } 483 484 AFI->setGPRCalleeSavedArea1Size(GPRCS1Size); 485 AFI->setGPRCalleeSavedArea2Size(GPRCS2Size); 486 AFI->setDPRCalleeSavedAreaSize(DPRCSSize); 487 } 488 489 static bool isCalleeSavedRegister(unsigned Reg, const unsigned *CSRegs) { 490 for (unsigned i = 0; CSRegs[i]; ++i) 491 if (Reg == CSRegs[i]) 492 return true; 493 return false; 494 } 495 496 static bool isCSRestore(MachineInstr *MI, const unsigned *CSRegs) { 497 return ((MI->getOpcode() == ARM::FLDD || 498 MI->getOpcode() == ARM::LDR) && 499 MI->getOperand(1).isFI() && 500 isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs)); 501 } 502 503 void ARMRegisterInfo::emitEpilogue(MachineFunction &MF, 504 MachineBasicBlock &MBB) const { 505 MachineBasicBlock::iterator MBBI = prior(MBB.end()); 506 assert(MBBI->getOpcode() == ARM::BX_RET && 507 "Can only insert epilog into returning blocks"); 508 DebugLoc dl = MBBI->getDebugLoc(); 509 MachineFrameInfo *MFI = MF.getFrameInfo(); 510 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 511 unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize(); 512 int NumBytes = (int)MFI->getStackSize(); 513 514 if (!AFI->hasStackFrame()) { 515 if (NumBytes != 0) 516 emitSPUpdate(MBB, MBBI, TII, dl, NumBytes); 517 } else { 518 // Unwind MBBI to point to first LDR / FLDD. 519 const unsigned *CSRegs = getCalleeSavedRegs(); 520 if (MBBI != MBB.begin()) { 521 do 522 --MBBI; 523 while (MBBI != MBB.begin() && isCSRestore(MBBI, CSRegs)); 524 if (!isCSRestore(MBBI, CSRegs)) 525 ++MBBI; 526 } 527 528 // Move SP to start of FP callee save spill area. 529 NumBytes -= (AFI->getGPRCalleeSavedArea1Size() + 530 AFI->getGPRCalleeSavedArea2Size() + 531 AFI->getDPRCalleeSavedAreaSize()); 532 533 // Darwin ABI requires FP to point to the stack slot that contains the 534 // previous FP. 535 if ((STI.isTargetDarwin() && NumBytes) || hasFP(MF)) { 536 NumBytes = AFI->getFramePtrSpillOffset() - NumBytes; 537 // Reset SP based on frame pointer only if the stack frame extends beyond 538 // frame pointer stack slot or target is ELF and the function has FP. 539 if (AFI->getGPRCalleeSavedArea2Size() || 540 AFI->getDPRCalleeSavedAreaSize() || 541 AFI->getDPRCalleeSavedAreaOffset()|| 542 hasFP(MF)) { 543 if (NumBytes) 544 BuildMI(MBB, MBBI, dl, TII.get(ARM::SUBri), ARM::SP).addReg(FramePtr) 545 .addImm(NumBytes) 546 .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0); 547 else 548 BuildMI(MBB, MBBI, dl, TII.get(ARM::MOVr), ARM::SP).addReg(FramePtr) 549 .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0); 550 } 551 } else if (NumBytes) { 552 emitSPUpdate(MBB, MBBI, TII, dl, NumBytes); 553 } 554 555 // Move SP to start of integer callee save spill area 2. 556 movePastCSLoadStoreOps(MBB, MBBI, ARM::FLDD, 3, STI); 557 emitSPUpdate(MBB, MBBI, TII, dl, AFI->getDPRCalleeSavedAreaSize()); 558 559 // Move SP to start of integer callee save spill area 1. 560 movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, 2, STI); 561 emitSPUpdate(MBB, MBBI, TII, dl, AFI->getGPRCalleeSavedArea2Size()); 562 563 // Move SP to SP upon entry to the function. 564 movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, 1, STI); 565 emitSPUpdate(MBB, MBBI, TII, dl, AFI->getGPRCalleeSavedArea1Size()); 566 } 567 568 if (VARegSaveSize) 569 emitSPUpdate(MBB, MBBI, TII, dl, VARegSaveSize); 570 571 } 572 573