Thumb2RegisterInfo.cpp revision dac237e18209b697a8ba122d0ddd9cad4dfba1f8
1//===- Thumb2RegisterInfo.cpp - Thumb-2 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 Thumb-2 implementation of the TargetRegisterInfo class. 11// 12//===----------------------------------------------------------------------===// 13 14#include "ARM.h" 15#include "ARMAddressingModes.h" 16#include "ARMBaseInstrInfo.h" 17#include "ARMMachineFunctionInfo.h" 18#include "ARMSubtarget.h" 19#include "Thumb2InstrInfo.h" 20#include "Thumb2RegisterInfo.h" 21#include "llvm/Constants.h" 22#include "llvm/DerivedTypes.h" 23#include "llvm/CodeGen/MachineConstantPool.h" 24#include "llvm/CodeGen/MachineFrameInfo.h" 25#include "llvm/CodeGen/MachineFunction.h" 26#include "llvm/CodeGen/MachineInstrBuilder.h" 27#include "llvm/CodeGen/MachineLocation.h" 28#include "llvm/CodeGen/MachineRegisterInfo.h" 29#include "llvm/Target/TargetFrameInfo.h" 30#include "llvm/Target/TargetMachine.h" 31#include "llvm/ADT/BitVector.h" 32#include "llvm/ADT/SmallVector.h" 33#include "llvm/Support/CommandLine.h" 34#include "llvm/Support/ErrorHandling.h" 35using namespace llvm; 36 37static cl::opt<bool> 38Thumb2RegScavenging("enable-thumb2-reg-scavenging", 39 cl::Hidden, 40 cl::desc("Enable register scavenging on Thumb-2")); 41 42Thumb2RegisterInfo::Thumb2RegisterInfo(const ARMBaseInstrInfo &tii, 43 const ARMSubtarget &sti) 44 : ARMBaseRegisterInfo(tii, sti) { 45} 46 47/// emitLoadConstPool - Emits a load from constpool to materialize the 48/// specified immediate. 49void Thumb2RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB, 50 MachineBasicBlock::iterator &MBBI, 51 DebugLoc dl, 52 unsigned DestReg, int Val, 53 ARMCC::CondCodes Pred, 54 unsigned PredReg) const { 55 MachineFunction &MF = *MBB.getParent(); 56 MachineConstantPool *ConstantPool = MF.getConstantPool(); 57 Constant *C = ConstantInt::get(Type::Int32Ty, Val); 58 unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4); 59 60 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2LDRpci), DestReg) 61 .addConstantPoolIndex(Idx).addImm(Pred).addReg(PredReg); 62} 63 64const TargetRegisterClass* 65Thumb2RegisterInfo::getPhysicalRegisterRegClass(unsigned Reg, MVT VT) const { 66 if (isARMLowRegister(Reg)) 67 return ARM::tGPRRegisterClass; 68 switch (Reg) { 69 default: 70 break; 71 case ARM::R8: case ARM::R9: case ARM::R10: case ARM::R11: 72 case ARM::R12: case ARM::SP: case ARM::LR: case ARM::PC: 73 return ARM::GPRRegisterClass; 74 } 75 76 return TargetRegisterInfo::getPhysicalRegisterRegClass(Reg, VT); 77} 78 79bool 80Thumb2RegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const { 81 return Thumb2RegScavenging; 82} 83 84bool Thumb2RegisterInfo::hasReservedCallFrame(MachineFunction &MF) const { 85 const MachineFrameInfo *FFI = MF.getFrameInfo(); 86 unsigned CFSize = FFI->getMaxCallFrameSize(); 87 // It's not always a good idea to include the call frame as part of the 88 // stack frame. ARM (especially Thumb) has small immediate offset to 89 // address the stack frame. So a large call frame can cause poor codegen 90 // and may even makes it impossible to scavenge a register. 91 if (CFSize >= ((1 << 8) - 1) * 4 / 2) // Half of imm8 * 4 92 return false; 93 94 return !MF.getFrameInfo()->hasVarSizedObjects(); 95} 96 97/// emitThumbRegPlusImmInReg - Emits a series of instructions to materialize 98/// a destreg = basereg + immediate in Thumb code. Materialize the immediate 99/// in a register using mov / mvn sequences or load the immediate from a 100/// constpool entry. 101static 102void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB, 103 MachineBasicBlock::iterator &MBBI, 104 unsigned DestReg, unsigned BaseReg, 105 int NumBytes, bool CanChangeCC, 106 const TargetInstrInfo &TII, 107 const Thumb2RegisterInfo& MRI, 108 DebugLoc dl) { 109 bool isHigh = !isARMLowRegister(DestReg) || 110 (BaseReg != 0 && !isARMLowRegister(BaseReg)); 111 bool isSub = false; 112 // Subtract doesn't have high register version. Load the negative value 113 // if either base or dest register is a high register. Also, if do not 114 // issue sub as part of the sequence if condition register is to be 115 // preserved. 116 if (NumBytes < 0 && !isHigh && CanChangeCC) { 117 isSub = true; 118 NumBytes = -NumBytes; 119 } 120 unsigned LdReg = DestReg; 121 if (DestReg == ARM::SP) { 122 assert(BaseReg == ARM::SP && "Unexpected!"); 123 LdReg = ARM::R3; 124 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVlor2hir), ARM::R12) 125 .addReg(ARM::R3, RegState::Kill); 126 } 127 128 if (NumBytes <= 255 && NumBytes >= 0) 129 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg).addImm(NumBytes); 130 else if (NumBytes < 0 && NumBytes >= -255) { 131 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg).addImm(NumBytes); 132 BuildMI(MBB, MBBI, dl, TII.get(ARM::tNEG), LdReg) 133 .addReg(LdReg, RegState::Kill); 134 } else 135 MRI.emitLoadConstPool(MBB, MBBI, dl, LdReg, NumBytes); 136 137 // Emit add / sub. 138 int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr); 139 const MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, 140 TII.get(Opc), DestReg); 141 if (DestReg == ARM::SP || isSub) 142 MIB.addReg(BaseReg).addReg(LdReg, RegState::Kill); 143 else 144 MIB.addReg(LdReg).addReg(BaseReg, RegState::Kill); 145 if (DestReg == ARM::SP) 146 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVhir2lor), ARM::R3) 147 .addReg(ARM::R12, RegState::Kill); 148} 149 150/// calcNumMI - Returns the number of instructions required to materialize 151/// the specific add / sub r, c instruction. 152static unsigned calcNumMI(int Opc, int ExtraOpc, unsigned Bytes, 153 unsigned NumBits, unsigned Scale) { 154 unsigned NumMIs = 0; 155 unsigned Chunk = ((1 << NumBits) - 1) * Scale; 156 157 if (Opc == ARM::tADDrSPi) { 158 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes; 159 Bytes -= ThisVal; 160 NumMIs++; 161 NumBits = 8; 162 Scale = 1; // Followed by a number of tADDi8. 163 Chunk = ((1 << NumBits) - 1) * Scale; 164 } 165 166 NumMIs += Bytes / Chunk; 167 if ((Bytes % Chunk) != 0) 168 NumMIs++; 169 if (ExtraOpc) 170 NumMIs++; 171 return NumMIs; 172} 173 174/// emitThumbRegPlusImmediate - Emits a series of instructions to materialize 175/// a destreg = basereg + immediate in Thumb code. 176static 177void emitThumbRegPlusImmediate(MachineBasicBlock &MBB, 178 MachineBasicBlock::iterator &MBBI, 179 unsigned DestReg, unsigned BaseReg, 180 int NumBytes, const TargetInstrInfo &TII, 181 const Thumb2RegisterInfo& MRI, 182 DebugLoc dl) { 183 bool isSub = NumBytes < 0; 184 unsigned Bytes = (unsigned)NumBytes; 185 if (isSub) Bytes = -NumBytes; 186 bool isMul4 = (Bytes & 3) == 0; 187 bool isTwoAddr = false; 188 bool DstNotEqBase = false; 189 unsigned NumBits = 1; 190 unsigned Scale = 1; 191 int Opc = 0; 192 int ExtraOpc = 0; 193 194 if (DestReg == BaseReg && BaseReg == ARM::SP) { 195 assert(isMul4 && "Thumb sp inc / dec size must be multiple of 4!"); 196 NumBits = 7; 197 Scale = 4; 198 Opc = isSub ? ARM::tSUBspi : ARM::tADDspi; 199 isTwoAddr = true; 200 } else if (!isSub && BaseReg == ARM::SP) { 201 // r1 = add sp, 403 202 // => 203 // r1 = add sp, 100 * 4 204 // r1 = add r1, 3 205 if (!isMul4) { 206 Bytes &= ~3; 207 ExtraOpc = ARM::tADDi3; 208 } 209 NumBits = 8; 210 Scale = 4; 211 Opc = ARM::tADDrSPi; 212 } else { 213 // sp = sub sp, c 214 // r1 = sub sp, c 215 // r8 = sub sp, c 216 if (DestReg != BaseReg) 217 DstNotEqBase = true; 218 NumBits = 8; 219 Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8; 220 isTwoAddr = true; 221 } 222 223 unsigned NumMIs = calcNumMI(Opc, ExtraOpc, Bytes, NumBits, Scale); 224 unsigned Threshold = (DestReg == ARM::SP) ? 3 : 2; 225 if (NumMIs > Threshold) { 226 // This will expand into too many instructions. Load the immediate from a 227 // constpool entry. 228 emitThumbRegPlusImmInReg(MBB, MBBI, DestReg, BaseReg, NumBytes, true, TII, 229 MRI, dl); 230 return; 231 } 232 233 if (DstNotEqBase) { 234 if (isARMLowRegister(DestReg) && isARMLowRegister(BaseReg)) { 235 // If both are low registers, emit DestReg = add BaseReg, max(Imm, 7) 236 unsigned Chunk = (1 << 3) - 1; 237 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes; 238 Bytes -= ThisVal; 239 BuildMI(MBB, MBBI, dl,TII.get(isSub ? ARM::tSUBi3 : ARM::tADDi3), DestReg) 240 .addReg(BaseReg, RegState::Kill).addImm(ThisVal); 241 } else { 242 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg) 243 .addReg(BaseReg, RegState::Kill); 244 } 245 BaseReg = DestReg; 246 } 247 248 unsigned Chunk = ((1 << NumBits) - 1) * Scale; 249 while (Bytes) { 250 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes; 251 Bytes -= ThisVal; 252 ThisVal /= Scale; 253 // Build the new tADD / tSUB. 254 if (isTwoAddr) 255 BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg) 256 .addReg(DestReg).addImm(ThisVal); 257 else { 258 bool isKill = BaseReg != ARM::SP; 259 BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg) 260 .addReg(BaseReg, getKillRegState(isKill)).addImm(ThisVal); 261 BaseReg = DestReg; 262 263 if (Opc == ARM::tADDrSPi) { 264 // r4 = add sp, imm 265 // r4 = add r4, imm 266 // ... 267 NumBits = 8; 268 Scale = 1; 269 Chunk = ((1 << NumBits) - 1) * Scale; 270 Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8; 271 isTwoAddr = true; 272 } 273 } 274 } 275 276 if (ExtraOpc) 277 BuildMI(MBB, MBBI, dl, TII.get(ExtraOpc), DestReg) 278 .addReg(DestReg, RegState::Kill) 279 .addImm(((unsigned)NumBytes) & 3); 280} 281 282static void emitSPUpdate(MachineBasicBlock &MBB, 283 MachineBasicBlock::iterator &MBBI, 284 const TargetInstrInfo &TII, DebugLoc dl, 285 const Thumb2RegisterInfo &MRI, 286 int NumBytes) { 287 emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes, TII, 288 MRI, dl); 289} 290 291void Thumb2RegisterInfo:: 292eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 293 MachineBasicBlock::iterator I) const { 294 if (!hasReservedCallFrame(MF)) { 295 // If we have alloca, convert as follows: 296 // ADJCALLSTACKDOWN -> sub, sp, sp, amount 297 // ADJCALLSTACKUP -> add, sp, sp, amount 298 MachineInstr *Old = I; 299 DebugLoc dl = Old->getDebugLoc(); 300 unsigned Amount = Old->getOperand(0).getImm(); 301 if (Amount != 0) { 302 // We need to keep the stack aligned properly. To do this, we round the 303 // amount of space needed for the outgoing arguments up to the next 304 // alignment boundary. 305 unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); 306 Amount = (Amount+Align-1)/Align*Align; 307 308 // Replace the pseudo instruction with a new instruction... 309 unsigned Opc = Old->getOpcode(); 310 if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) { 311 emitSPUpdate(MBB, I, TII, dl, *this, -Amount); 312 } else { 313 assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP); 314 emitSPUpdate(MBB, I, TII, dl, *this, Amount); 315 } 316 } 317 } 318 MBB.erase(I); 319} 320 321/// emitThumbConstant - Emit a series of instructions to materialize a 322/// constant. 323static void emitThumbConstant(MachineBasicBlock &MBB, 324 MachineBasicBlock::iterator &MBBI, 325 unsigned DestReg, int Imm, 326 const TargetInstrInfo &TII, 327 const Thumb2RegisterInfo& MRI, 328 DebugLoc dl) { 329 bool isSub = Imm < 0; 330 if (isSub) Imm = -Imm; 331 332 int Chunk = (1 << 8) - 1; 333 int ThisVal = (Imm > Chunk) ? Chunk : Imm; 334 Imm -= ThisVal; 335 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), DestReg).addImm(ThisVal); 336 if (Imm > 0) 337 emitThumbRegPlusImmediate(MBB, MBBI, DestReg, DestReg, Imm, TII, MRI, dl); 338 if (isSub) 339 BuildMI(MBB, MBBI, dl, TII.get(ARM::tNEG), DestReg) 340 .addReg(DestReg, RegState::Kill); 341} 342 343void Thumb2RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 344 int SPAdj, RegScavenger *RS) const{ 345 unsigned i = 0; 346 MachineInstr &MI = *II; 347 MachineBasicBlock &MBB = *MI.getParent(); 348 MachineFunction &MF = *MBB.getParent(); 349 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 350 DebugLoc dl = MI.getDebugLoc(); 351 352 while (!MI.getOperand(i).isFI()) { 353 ++i; 354 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 355 } 356 357 unsigned FrameReg = ARM::SP; 358 int FrameIndex = MI.getOperand(i).getIndex(); 359 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) + 360 MF.getFrameInfo()->getStackSize() + SPAdj; 361 362 if (AFI->isGPRCalleeSavedArea1Frame(FrameIndex)) 363 Offset -= AFI->getGPRCalleeSavedArea1Offset(); 364 else if (AFI->isGPRCalleeSavedArea2Frame(FrameIndex)) 365 Offset -= AFI->getGPRCalleeSavedArea2Offset(); 366 else if (hasFP(MF)) { 367 assert(SPAdj == 0 && "Unexpected"); 368 // There is alloca()'s in this function, must reference off the frame 369 // pointer instead. 370 FrameReg = getFrameRegister(MF); 371 Offset -= AFI->getFramePtrSpillOffset(); 372 } 373 374 unsigned Opcode = MI.getOpcode(); 375 const TargetInstrDesc &Desc = MI.getDesc(); 376 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); 377 378 if (Opcode == ARM::tADDrSPi) { 379 Offset += MI.getOperand(i+1).getImm(); 380 381 // Can't use tADDrSPi if it's based off the frame pointer. 382 unsigned NumBits = 0; 383 unsigned Scale = 1; 384 if (FrameReg != ARM::SP) { 385 Opcode = ARM::tADDi3; 386 MI.setDesc(TII.get(ARM::tADDi3)); 387 NumBits = 3; 388 } else { 389 NumBits = 8; 390 Scale = 4; 391 assert((Offset & 3) == 0 && 392 "Thumb add/sub sp, #imm immediate must be multiple of 4!"); 393 } 394 395 if (Offset == 0) { 396 // Turn it into a move. 397 MI.setDesc(TII.get(ARM::tMOVhir2lor)); 398 MI.getOperand(i).ChangeToRegister(FrameReg, false); 399 MI.RemoveOperand(i+1); 400 return; 401 } 402 403 // Common case: small offset, fits into instruction. 404 unsigned Mask = (1 << NumBits) - 1; 405 if (((Offset / Scale) & ~Mask) == 0) { 406 // Replace the FrameIndex with sp / fp 407 MI.getOperand(i).ChangeToRegister(FrameReg, false); 408 MI.getOperand(i+1).ChangeToImmediate(Offset / Scale); 409 return; 410 } 411 412 unsigned DestReg = MI.getOperand(0).getReg(); 413 unsigned Bytes = (Offset > 0) ? Offset : -Offset; 414 unsigned NumMIs = calcNumMI(Opcode, 0, Bytes, NumBits, Scale); 415 // MI would expand into a large number of instructions. Don't try to 416 // simplify the immediate. 417 if (NumMIs > 2) { 418 emitThumbRegPlusImmediate(MBB, II, DestReg, FrameReg, Offset, TII, 419 *this, dl); 420 MBB.erase(II); 421 return; 422 } 423 424 if (Offset > 0) { 425 // Translate r0 = add sp, imm to 426 // r0 = add sp, 255*4 427 // r0 = add r0, (imm - 255*4) 428 MI.getOperand(i).ChangeToRegister(FrameReg, false); 429 MI.getOperand(i+1).ChangeToImmediate(Mask); 430 Offset = (Offset - Mask * Scale); 431 MachineBasicBlock::iterator NII = next(II); 432 emitThumbRegPlusImmediate(MBB, NII, DestReg, DestReg, Offset, TII, 433 *this, dl); 434 } else { 435 // Translate r0 = add sp, -imm to 436 // r0 = -imm (this is then translated into a series of instructons) 437 // r0 = add r0, sp 438 emitThumbConstant(MBB, II, DestReg, Offset, TII, *this, dl); 439 MI.setDesc(TII.get(ARM::tADDhirr)); 440 MI.getOperand(i).ChangeToRegister(DestReg, false, false, true); 441 MI.getOperand(i+1).ChangeToRegister(FrameReg, false); 442 } 443 return; 444 } else { 445 unsigned ImmIdx = 0; 446 int InstrOffs = 0; 447 unsigned NumBits = 0; 448 unsigned Scale = 1; 449 switch (AddrMode) { 450 case ARMII::AddrModeT1_s: { 451 ImmIdx = i+1; 452 InstrOffs = MI.getOperand(ImmIdx).getImm(); 453 NumBits = (FrameReg == ARM::SP) ? 8 : 5; 454 Scale = 4; 455 break; 456 } 457 default: 458 LLVM_UNREACHABLE("Unsupported addressing mode!"); 459 } 460 461 Offset += InstrOffs * Scale; 462 assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!"); 463 464 // Common case: small offset, fits into instruction. 465 MachineOperand &ImmOp = MI.getOperand(ImmIdx); 466 int ImmedOffset = Offset / Scale; 467 unsigned Mask = (1 << NumBits) - 1; 468 if ((unsigned)Offset <= Mask * Scale) { 469 // Replace the FrameIndex with sp 470 MI.getOperand(i).ChangeToRegister(FrameReg, false); 471 ImmOp.ChangeToImmediate(ImmedOffset); 472 return; 473 } 474 475 bool isThumSpillRestore = Opcode == ARM::tRestore || Opcode == ARM::tSpill; 476 if (AddrMode == ARMII::AddrModeT1_s) { 477 // Thumb tLDRspi, tSTRspi. These will change to instructions that use 478 // a different base register. 479 NumBits = 5; 480 Mask = (1 << NumBits) - 1; 481 } 482 // If this is a thumb spill / restore, we will be using a constpool load to 483 // materialize the offset. 484 if (AddrMode == ARMII::AddrModeT1_s && isThumSpillRestore) 485 ImmOp.ChangeToImmediate(0); 486 else { 487 // Otherwise, it didn't fit. Pull in what we can to simplify the immed. 488 ImmedOffset = ImmedOffset & Mask; 489 ImmOp.ChangeToImmediate(ImmedOffset); 490 Offset &= ~(Mask*Scale); 491 } 492 } 493 494 // If we get here, the immediate doesn't fit into the instruction. We folded 495 // as much as possible above, handle the rest, providing a register that is 496 // SP+LargeImm. 497 assert(Offset && "This code isn't needed if offset already handled!"); 498 499 if (Desc.mayLoad()) { 500 // Use the destination register to materialize sp + offset. 501 unsigned TmpReg = MI.getOperand(0).getReg(); 502 bool UseRR = false; 503 if (Opcode == ARM::tRestore) { 504 if (FrameReg == ARM::SP) 505 emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg, 506 Offset, false, TII, *this, dl); 507 else { 508 emitLoadConstPool(MBB, II, dl, TmpReg, Offset); 509 UseRR = true; 510 } 511 } else 512 emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII, 513 *this, dl); 514 MI.setDesc(TII.get(ARM::tLDR)); 515 MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true); 516 if (UseRR) 517 // Use [reg, reg] addrmode. 518 MI.addOperand(MachineOperand::CreateReg(FrameReg, false)); 519 else // tLDR has an extra register operand. 520 MI.addOperand(MachineOperand::CreateReg(0, false)); 521 } else if (Desc.mayStore()) { 522 // FIXME! This is horrific!!! We need register scavenging. 523 // Our temporary workaround has marked r3 unavailable. Of course, r3 is 524 // also a ABI register so it's possible that is is the register that is 525 // being storing here. If that's the case, we do the following: 526 // r12 = r2 527 // Use r2 to materialize sp + offset 528 // str r3, r2 529 // r2 = r12 530 unsigned ValReg = MI.getOperand(0).getReg(); 531 unsigned TmpReg = ARM::R3; 532 bool UseRR = false; 533 if (ValReg == ARM::R3) { 534 BuildMI(MBB, II, dl, TII.get(ARM::tMOVlor2hir), ARM::R12) 535 .addReg(ARM::R2, RegState::Kill); 536 TmpReg = ARM::R2; 537 } 538 if (TmpReg == ARM::R3 && AFI->isR3LiveIn()) 539 BuildMI(MBB, II, dl, TII.get(ARM::tMOVlor2hir), ARM::R12) 540 .addReg(ARM::R3, RegState::Kill); 541 if (Opcode == ARM::tSpill) { 542 if (FrameReg == ARM::SP) 543 emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg, 544 Offset, false, TII, *this, dl); 545 else { 546 emitLoadConstPool(MBB, II, dl, TmpReg, Offset); 547 UseRR = true; 548 } 549 } else 550 emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII, 551 *this, dl); 552 MI.setDesc(TII.get(ARM::tSTR)); 553 MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true); 554 if (UseRR) // Use [reg, reg] addrmode. 555 MI.addOperand(MachineOperand::CreateReg(FrameReg, false)); 556 else // tSTR has an extra register operand. 557 MI.addOperand(MachineOperand::CreateReg(0, false)); 558 559 MachineBasicBlock::iterator NII = next(II); 560 if (ValReg == ARM::R3) 561 BuildMI(MBB, NII, dl, TII.get(ARM::tMOVhir2lor), ARM::R2) 562 .addReg(ARM::R12, RegState::Kill); 563 if (TmpReg == ARM::R3 && AFI->isR3LiveIn()) 564 BuildMI(MBB, NII, dl, TII.get(ARM::tMOVhir2lor), ARM::R3) 565 .addReg(ARM::R12, RegState::Kill); 566 } else 567 assert(false && "Unexpected opcode!"); 568} 569 570void Thumb2RegisterInfo::emitPrologue(MachineFunction &MF) const { 571 MachineBasicBlock &MBB = MF.front(); 572 MachineBasicBlock::iterator MBBI = MBB.begin(); 573 MachineFrameInfo *MFI = MF.getFrameInfo(); 574 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 575 unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize(); 576 unsigned NumBytes = MFI->getStackSize(); 577 const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 578 DebugLoc dl = (MBBI != MBB.end() ? 579 MBBI->getDebugLoc() : DebugLoc::getUnknownLoc()); 580 581 // Check if R3 is live in. It might have to be used as a scratch register. 582 for (MachineRegisterInfo::livein_iterator I =MF.getRegInfo().livein_begin(), 583 E = MF.getRegInfo().livein_end(); I != E; ++I) { 584 if (I->first == ARM::R3) { 585 AFI->setR3IsLiveIn(true); 586 break; 587 } 588 } 589 590 // Thumb add/sub sp, imm8 instructions implicitly multiply the offset by 4. 591 NumBytes = (NumBytes + 3) & ~3; 592 MFI->setStackSize(NumBytes); 593 594 // Determine the sizes of each callee-save spill areas and record which frame 595 // belongs to which callee-save spill areas. 596 unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0; 597 int FramePtrSpillFI = 0; 598 599 if (VARegSaveSize) 600 emitSPUpdate(MBB, MBBI, TII, dl, *this, -VARegSaveSize); 601 602 if (!AFI->hasStackFrame()) { 603 if (NumBytes != 0) 604 emitSPUpdate(MBB, MBBI, TII, dl, *this, -NumBytes); 605 return; 606 } 607 608 for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 609 unsigned Reg = CSI[i].getReg(); 610 int FI = CSI[i].getFrameIdx(); 611 switch (Reg) { 612 case ARM::R4: 613 case ARM::R5: 614 case ARM::R6: 615 case ARM::R7: 616 case ARM::LR: 617 if (Reg == FramePtr) 618 FramePtrSpillFI = FI; 619 AFI->addGPRCalleeSavedArea1Frame(FI); 620 GPRCS1Size += 4; 621 break; 622 case ARM::R8: 623 case ARM::R9: 624 case ARM::R10: 625 case ARM::R11: 626 if (Reg == FramePtr) 627 FramePtrSpillFI = FI; 628 if (STI.isTargetDarwin()) { 629 AFI->addGPRCalleeSavedArea2Frame(FI); 630 GPRCS2Size += 4; 631 } else { 632 AFI->addGPRCalleeSavedArea1Frame(FI); 633 GPRCS1Size += 4; 634 } 635 break; 636 default: 637 AFI->addDPRCalleeSavedAreaFrame(FI); 638 DPRCSSize += 8; 639 } 640 } 641 642 if (MBBI != MBB.end() && MBBI->getOpcode() == ARM::tPUSH) { 643 ++MBBI; 644 if (MBBI != MBB.end()) 645 dl = MBBI->getDebugLoc(); 646 } 647 648 // Darwin ABI requires FP to point to the stack slot that contains the 649 // previous FP. 650 if (STI.isTargetDarwin() || hasFP(MF)) { 651 MachineInstrBuilder MIB = 652 BuildMI(MBB, MBBI, dl, TII.get(ARM::tADDrSPi), FramePtr) 653 .addFrameIndex(FramePtrSpillFI).addImm(0); 654 } 655 656 // Determine starting offsets of spill areas. 657 unsigned DPRCSOffset = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize); 658 unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize; 659 unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size; 660 AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI) + NumBytes); 661 AFI->setGPRCalleeSavedArea1Offset(GPRCS1Offset); 662 AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset); 663 AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset); 664 665 NumBytes = DPRCSOffset; 666 if (NumBytes) { 667 // Insert it after all the callee-save spills. 668 emitSPUpdate(MBB, MBBI, TII, dl, *this, -NumBytes); 669 } 670 671 if (STI.isTargetELF() && hasFP(MF)) { 672 MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() - 673 AFI->getFramePtrSpillOffset()); 674 } 675 676 AFI->setGPRCalleeSavedArea1Size(GPRCS1Size); 677 AFI->setGPRCalleeSavedArea2Size(GPRCS2Size); 678 AFI->setDPRCalleeSavedAreaSize(DPRCSSize); 679} 680 681static bool isCalleeSavedRegister(unsigned Reg, const unsigned *CSRegs) { 682 for (unsigned i = 0; CSRegs[i]; ++i) 683 if (Reg == CSRegs[i]) 684 return true; 685 return false; 686} 687 688static bool isCSRestore(MachineInstr *MI, const unsigned *CSRegs) { 689 return (MI->getOpcode() == ARM::tRestore && 690 MI->getOperand(1).isFI() && 691 isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs)); 692} 693 694void Thumb2RegisterInfo::emitEpilogue(MachineFunction &MF, 695 MachineBasicBlock &MBB) const { 696 MachineBasicBlock::iterator MBBI = prior(MBB.end()); 697 assert((MBBI->getOpcode() == ARM::tBX_RET || 698 MBBI->getOpcode() == ARM::tPOP_RET) && 699 "Can only insert epilog into returning blocks"); 700 DebugLoc dl = MBBI->getDebugLoc(); 701 MachineFrameInfo *MFI = MF.getFrameInfo(); 702 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 703 unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize(); 704 int NumBytes = (int)MFI->getStackSize(); 705 706 if (!AFI->hasStackFrame()) { 707 if (NumBytes != 0) 708 emitSPUpdate(MBB, MBBI, TII, dl, *this, NumBytes); 709 } else { 710 // Unwind MBBI to point to first LDR / FLDD. 711 const unsigned *CSRegs = getCalleeSavedRegs(); 712 if (MBBI != MBB.begin()) { 713 do 714 --MBBI; 715 while (MBBI != MBB.begin() && isCSRestore(MBBI, CSRegs)); 716 if (!isCSRestore(MBBI, CSRegs)) 717 ++MBBI; 718 } 719 720 // Move SP to start of FP callee save spill area. 721 NumBytes -= (AFI->getGPRCalleeSavedArea1Size() + 722 AFI->getGPRCalleeSavedArea2Size() + 723 AFI->getDPRCalleeSavedAreaSize()); 724 725 if (hasFP(MF)) { 726 NumBytes = AFI->getFramePtrSpillOffset() - NumBytes; 727 // Reset SP based on frame pointer only if the stack frame extends beyond 728 // frame pointer stack slot or target is ELF and the function has FP. 729 if (NumBytes) 730 emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, FramePtr, -NumBytes, 731 TII, *this, dl); 732 else 733 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVlor2hir), ARM::SP) 734 .addReg(FramePtr); 735 } else { 736 if (MBBI->getOpcode() == ARM::tBX_RET && 737 &MBB.front() != MBBI && 738 prior(MBBI)->getOpcode() == ARM::tPOP) { 739 MachineBasicBlock::iterator PMBBI = prior(MBBI); 740 emitSPUpdate(MBB, PMBBI, TII, dl, *this, NumBytes); 741 } else 742 emitSPUpdate(MBB, MBBI, TII, dl, *this, NumBytes); 743 } 744 } 745 746 if (VARegSaveSize) { 747 // Epilogue for vararg functions: pop LR to R3 and branch off it. 748 // FIXME: Verify this is still ok when R3 is no longer being reserved. 749 BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP)).addReg(ARM::R3); 750 751 emitSPUpdate(MBB, MBBI, TII, dl, *this, VARegSaveSize); 752 753 BuildMI(MBB, MBBI, dl, TII.get(ARM::tBX_RET_vararg)).addReg(ARM::R3); 754 MBB.erase(MBBI); 755 } 756} 757