1 //===-- Thumb1RegisterInfo.cpp - Thumb-1 Register Information -------------===// 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-1 implementation of the TargetRegisterInfo 11 // class. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "Thumb1RegisterInfo.h" 16 #include "ARM.h" 17 #include "ARMBaseInstrInfo.h" 18 #include "ARMMachineFunctionInfo.h" 19 #include "ARMSubtarget.h" 20 #include "MCTargetDesc/ARMAddressingModes.h" 21 #include "llvm/Constants.h" 22 #include "llvm/DerivedTypes.h" 23 #include "llvm/Function.h" 24 #include "llvm/LLVMContext.h" 25 #include "llvm/CodeGen/MachineConstantPool.h" 26 #include "llvm/CodeGen/MachineFrameInfo.h" 27 #include "llvm/CodeGen/MachineFunction.h" 28 #include "llvm/CodeGen/MachineInstrBuilder.h" 29 #include "llvm/CodeGen/MachineRegisterInfo.h" 30 #include "llvm/CodeGen/RegisterScavenging.h" 31 #include "llvm/Target/TargetFrameLowering.h" 32 #include "llvm/Target/TargetMachine.h" 33 #include "llvm/Support/CommandLine.h" 34 #include "llvm/Support/ErrorHandling.h" 35 #include "llvm/Support/raw_ostream.h" 36 37 namespace llvm { 38 extern cl::opt<bool> ReuseFrameIndexVals; 39 } 40 41 using namespace llvm; 42 43 Thumb1RegisterInfo::Thumb1RegisterInfo(const ARMBaseInstrInfo &tii, 44 const ARMSubtarget &sti) 45 : ARMBaseRegisterInfo(tii, sti) { 46 } 47 48 const TargetRegisterClass* 49 Thumb1RegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC) 50 const { 51 if (ARM::tGPRRegClass.hasSubClassEq(RC)) 52 return ARM::tGPRRegisterClass; 53 return ARMBaseRegisterInfo::getLargestLegalSuperClass(RC); 54 } 55 56 const TargetRegisterClass * 57 Thumb1RegisterInfo::getPointerRegClass(unsigned Kind) const { 58 return ARM::tGPRRegisterClass; 59 } 60 61 /// emitLoadConstPool - Emits a load from constpool to materialize the 62 /// specified immediate. 63 void 64 Thumb1RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB, 65 MachineBasicBlock::iterator &MBBI, 66 DebugLoc dl, 67 unsigned DestReg, unsigned SubIdx, 68 int Val, 69 ARMCC::CondCodes Pred, unsigned PredReg, 70 unsigned MIFlags) const { 71 MachineFunction &MF = *MBB.getParent(); 72 MachineConstantPool *ConstantPool = MF.getConstantPool(); 73 const Constant *C = ConstantInt::get( 74 Type::getInt32Ty(MBB.getParent()->getFunction()->getContext()), Val); 75 unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4); 76 77 BuildMI(MBB, MBBI, dl, TII.get(ARM::tLDRpci)) 78 .addReg(DestReg, getDefRegState(true), SubIdx) 79 .addConstantPoolIndex(Idx).addImm(Pred).addReg(PredReg) 80 .setMIFlags(MIFlags); 81 } 82 83 84 /// emitThumbRegPlusImmInReg - Emits a series of instructions to materialize 85 /// a destreg = basereg + immediate in Thumb code. Materialize the immediate 86 /// in a register using mov / mvn sequences or load the immediate from a 87 /// constpool entry. 88 static 89 void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB, 90 MachineBasicBlock::iterator &MBBI, 91 DebugLoc dl, 92 unsigned DestReg, unsigned BaseReg, 93 int NumBytes, bool CanChangeCC, 94 const TargetInstrInfo &TII, 95 const ARMBaseRegisterInfo& MRI, 96 unsigned MIFlags = MachineInstr::NoFlags) { 97 MachineFunction &MF = *MBB.getParent(); 98 bool isHigh = !isARMLowRegister(DestReg) || 99 (BaseReg != 0 && !isARMLowRegister(BaseReg)); 100 bool isSub = false; 101 // Subtract doesn't have high register version. Load the negative value 102 // if either base or dest register is a high register. Also, if do not 103 // issue sub as part of the sequence if condition register is to be 104 // preserved. 105 if (NumBytes < 0 && !isHigh && CanChangeCC) { 106 isSub = true; 107 NumBytes = -NumBytes; 108 } 109 unsigned LdReg = DestReg; 110 if (DestReg == ARM::SP) { 111 assert(BaseReg == ARM::SP && "Unexpected!"); 112 LdReg = MF.getRegInfo().createVirtualRegister(ARM::tGPRRegisterClass); 113 } 114 115 if (NumBytes <= 255 && NumBytes >= 0) 116 AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg)) 117 .addImm(NumBytes).setMIFlags(MIFlags); 118 else if (NumBytes < 0 && NumBytes >= -255) { 119 AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg)) 120 .addImm(NumBytes).setMIFlags(MIFlags); 121 AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tRSB), LdReg)) 122 .addReg(LdReg, RegState::Kill).setMIFlags(MIFlags); 123 } else 124 MRI.emitLoadConstPool(MBB, MBBI, dl, LdReg, 0, NumBytes, 125 ARMCC::AL, 0, MIFlags); 126 127 // Emit add / sub. 128 int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr); 129 MachineInstrBuilder MIB = 130 BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg); 131 if (Opc != ARM::tADDhirr) 132 MIB = AddDefaultT1CC(MIB); 133 if (DestReg == ARM::SP || isSub) 134 MIB.addReg(BaseReg).addReg(LdReg, RegState::Kill); 135 else 136 MIB.addReg(LdReg).addReg(BaseReg, RegState::Kill); 137 AddDefaultPred(MIB); 138 } 139 140 /// calcNumMI - Returns the number of instructions required to materialize 141 /// the specific add / sub r, c instruction. 142 static unsigned calcNumMI(int Opc, int ExtraOpc, unsigned Bytes, 143 unsigned NumBits, unsigned Scale) { 144 unsigned NumMIs = 0; 145 unsigned Chunk = ((1 << NumBits) - 1) * Scale; 146 147 if (Opc == ARM::tADDrSPi) { 148 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes; 149 Bytes -= ThisVal; 150 NumMIs++; 151 NumBits = 8; 152 Scale = 1; // Followed by a number of tADDi8. 153 Chunk = ((1 << NumBits) - 1) * Scale; 154 } 155 156 NumMIs += Bytes / Chunk; 157 if ((Bytes % Chunk) != 0) 158 NumMIs++; 159 if (ExtraOpc) 160 NumMIs++; 161 return NumMIs; 162 } 163 164 /// emitThumbRegPlusImmediate - Emits a series of instructions to materialize 165 /// a destreg = basereg + immediate in Thumb code. 166 void llvm::emitThumbRegPlusImmediate(MachineBasicBlock &MBB, 167 MachineBasicBlock::iterator &MBBI, 168 DebugLoc dl, 169 unsigned DestReg, unsigned BaseReg, 170 int NumBytes, const TargetInstrInfo &TII, 171 const ARMBaseRegisterInfo& MRI, 172 unsigned MIFlags) { 173 bool isSub = NumBytes < 0; 174 unsigned Bytes = (unsigned)NumBytes; 175 if (isSub) Bytes = -NumBytes; 176 bool isMul4 = (Bytes & 3) == 0; 177 bool isTwoAddr = false; 178 bool DstNotEqBase = false; 179 unsigned NumBits = 1; 180 unsigned Scale = 1; 181 int Opc = 0; 182 int ExtraOpc = 0; 183 bool NeedCC = false; 184 185 if (DestReg == BaseReg && BaseReg == ARM::SP) { 186 assert(isMul4 && "Thumb sp inc / dec size must be multiple of 4!"); 187 NumBits = 7; 188 Scale = 4; 189 Opc = isSub ? ARM::tSUBspi : ARM::tADDspi; 190 isTwoAddr = true; 191 } else if (!isSub && BaseReg == ARM::SP) { 192 // r1 = add sp, 403 193 // => 194 // r1 = add sp, 100 * 4 195 // r1 = add r1, 3 196 if (!isMul4) { 197 Bytes &= ~3; 198 ExtraOpc = ARM::tADDi3; 199 } 200 NumBits = 8; 201 Scale = 4; 202 Opc = ARM::tADDrSPi; 203 } else { 204 // sp = sub sp, c 205 // r1 = sub sp, c 206 // r8 = sub sp, c 207 if (DestReg != BaseReg) 208 DstNotEqBase = true; 209 NumBits = 8; 210 if (DestReg == ARM::SP) { 211 Opc = isSub ? ARM::tSUBspi : ARM::tADDspi; 212 assert(isMul4 && "Thumb sp inc / dec size must be multiple of 4!"); 213 NumBits = 7; 214 Scale = 4; 215 } else { 216 Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8; 217 NumBits = 8; 218 NeedCC = true; 219 } 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, dl, 229 DestReg, BaseReg, NumBytes, true, 230 TII, MRI, MIFlags); 231 return; 232 } 233 234 if (DstNotEqBase) { 235 if (isARMLowRegister(DestReg) && isARMLowRegister(BaseReg)) { 236 // If both are low registers, emit DestReg = add BaseReg, max(Imm, 7) 237 unsigned Chunk = (1 << 3) - 1; 238 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes; 239 Bytes -= ThisVal; 240 const MCInstrDesc &MCID = TII.get(isSub ? ARM::tSUBi3 : ARM::tADDi3); 241 const MachineInstrBuilder MIB = 242 AddDefaultT1CC(BuildMI(MBB, MBBI, dl, MCID, DestReg) 243 .setMIFlags(MIFlags)); 244 AddDefaultPred(MIB.addReg(BaseReg, RegState::Kill).addImm(ThisVal)); 245 } else { 246 AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg) 247 .addReg(BaseReg, RegState::Kill)) 248 .setMIFlags(MIFlags); 249 } 250 BaseReg = DestReg; 251 } 252 253 unsigned Chunk = ((1 << NumBits) - 1) * Scale; 254 while (Bytes) { 255 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes; 256 Bytes -= ThisVal; 257 ThisVal /= Scale; 258 // Build the new tADD / tSUB. 259 if (isTwoAddr) { 260 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg); 261 if (NeedCC) 262 MIB = AddDefaultT1CC(MIB); 263 MIB.addReg(DestReg).addImm(ThisVal); 264 MIB = AddDefaultPred(MIB); 265 MIB.setMIFlags(MIFlags); 266 } else { 267 bool isKill = BaseReg != ARM::SP; 268 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg); 269 if (NeedCC) 270 MIB = AddDefaultT1CC(MIB); 271 MIB.addReg(BaseReg, getKillRegState(isKill)).addImm(ThisVal); 272 MIB = AddDefaultPred(MIB); 273 MIB.setMIFlags(MIFlags); 274 275 BaseReg = DestReg; 276 if (Opc == ARM::tADDrSPi) { 277 // r4 = add sp, imm 278 // r4 = add r4, imm 279 // ... 280 NumBits = 8; 281 Scale = 1; 282 Chunk = ((1 << NumBits) - 1) * Scale; 283 Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8; 284 NeedCC = isTwoAddr = true; 285 } 286 } 287 } 288 289 if (ExtraOpc) { 290 const MCInstrDesc &MCID = TII.get(ExtraOpc); 291 AddDefaultPred(AddDefaultT1CC(BuildMI(MBB, MBBI, dl, MCID, DestReg)) 292 .addReg(DestReg, RegState::Kill) 293 .addImm(((unsigned)NumBytes) & 3) 294 .setMIFlags(MIFlags)); 295 } 296 } 297 298 static void emitSPUpdate(MachineBasicBlock &MBB, 299 MachineBasicBlock::iterator &MBBI, 300 const TargetInstrInfo &TII, DebugLoc dl, 301 const Thumb1RegisterInfo &MRI, 302 int NumBytes) { 303 emitThumbRegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes, TII, 304 MRI); 305 } 306 307 void Thumb1RegisterInfo:: 308 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 309 MachineBasicBlock::iterator I) const { 310 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 311 312 if (!TFI->hasReservedCallFrame(MF)) { 313 // If we have alloca, convert as follows: 314 // ADJCALLSTACKDOWN -> sub, sp, sp, amount 315 // ADJCALLSTACKUP -> add, sp, sp, amount 316 MachineInstr *Old = I; 317 DebugLoc dl = Old->getDebugLoc(); 318 unsigned Amount = Old->getOperand(0).getImm(); 319 if (Amount != 0) { 320 // We need to keep the stack aligned properly. To do this, we round the 321 // amount of space needed for the outgoing arguments up to the next 322 // alignment boundary. 323 unsigned Align = TFI->getStackAlignment(); 324 Amount = (Amount+Align-1)/Align*Align; 325 326 // Replace the pseudo instruction with a new instruction... 327 unsigned Opc = Old->getOpcode(); 328 if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) { 329 emitSPUpdate(MBB, I, TII, dl, *this, -Amount); 330 } else { 331 assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP); 332 emitSPUpdate(MBB, I, TII, dl, *this, Amount); 333 } 334 } 335 } 336 MBB.erase(I); 337 } 338 339 /// emitThumbConstant - Emit a series of instructions to materialize a 340 /// constant. 341 static void emitThumbConstant(MachineBasicBlock &MBB, 342 MachineBasicBlock::iterator &MBBI, 343 unsigned DestReg, int Imm, 344 const TargetInstrInfo &TII, 345 const Thumb1RegisterInfo& MRI, 346 DebugLoc dl) { 347 bool isSub = Imm < 0; 348 if (isSub) Imm = -Imm; 349 350 int Chunk = (1 << 8) - 1; 351 int ThisVal = (Imm > Chunk) ? Chunk : Imm; 352 Imm -= ThisVal; 353 AddDefaultPred(AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), 354 DestReg)) 355 .addImm(ThisVal)); 356 if (Imm > 0) 357 emitThumbRegPlusImmediate(MBB, MBBI, dl, DestReg, DestReg, Imm, TII, MRI); 358 if (isSub) { 359 const MCInstrDesc &MCID = TII.get(ARM::tRSB); 360 AddDefaultPred(AddDefaultT1CC(BuildMI(MBB, MBBI, dl, MCID, DestReg)) 361 .addReg(DestReg, RegState::Kill)); 362 } 363 } 364 365 static void removeOperands(MachineInstr &MI, unsigned i) { 366 unsigned Op = i; 367 for (unsigned e = MI.getNumOperands(); i != e; ++i) 368 MI.RemoveOperand(Op); 369 } 370 371 /// convertToNonSPOpcode - Change the opcode to the non-SP version, because 372 /// we're replacing the frame index with a non-SP register. 373 static unsigned convertToNonSPOpcode(unsigned Opcode) { 374 switch (Opcode) { 375 case ARM::tLDRspi: 376 return ARM::tLDRi; 377 378 case ARM::tSTRspi: 379 return ARM::tSTRi; 380 } 381 382 return Opcode; 383 } 384 385 bool Thumb1RegisterInfo:: 386 rewriteFrameIndex(MachineBasicBlock::iterator II, unsigned FrameRegIdx, 387 unsigned FrameReg, int &Offset, 388 const ARMBaseInstrInfo &TII) const { 389 MachineInstr &MI = *II; 390 MachineBasicBlock &MBB = *MI.getParent(); 391 DebugLoc dl = MI.getDebugLoc(); 392 unsigned Opcode = MI.getOpcode(); 393 const MCInstrDesc &Desc = MI.getDesc(); 394 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); 395 396 if (Opcode == ARM::tADDrSPi) { 397 Offset += MI.getOperand(FrameRegIdx+1).getImm(); 398 399 // Can't use tADDrSPi if it's based off the frame pointer. 400 unsigned NumBits = 0; 401 unsigned Scale = 1; 402 if (FrameReg != ARM::SP) { 403 Opcode = ARM::tADDi3; 404 NumBits = 3; 405 } else { 406 NumBits = 8; 407 Scale = 4; 408 assert((Offset & 3) == 0 && 409 "Thumb add/sub sp, #imm immediate must be multiple of 4!"); 410 } 411 412 unsigned PredReg; 413 if (Offset == 0 && getInstrPredicate(&MI, PredReg) == ARMCC::AL) { 414 // Turn it into a move. 415 MI.setDesc(TII.get(ARM::tMOVr)); 416 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 417 // Remove offset 418 MI.RemoveOperand(FrameRegIdx+1); 419 MachineInstrBuilder MIB(&MI); 420 return true; 421 } 422 423 // Common case: small offset, fits into instruction. 424 unsigned Mask = (1 << NumBits) - 1; 425 if (((Offset / Scale) & ~Mask) == 0) { 426 // Replace the FrameIndex with sp / fp 427 if (Opcode == ARM::tADDi3) { 428 MI.setDesc(TII.get(Opcode)); 429 removeOperands(MI, FrameRegIdx); 430 MachineInstrBuilder MIB(&MI); 431 AddDefaultPred(AddDefaultT1CC(MIB).addReg(FrameReg) 432 .addImm(Offset / Scale)); 433 } else { 434 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 435 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset / Scale); 436 } 437 return true; 438 } 439 440 unsigned DestReg = MI.getOperand(0).getReg(); 441 unsigned Bytes = (Offset > 0) ? Offset : -Offset; 442 unsigned NumMIs = calcNumMI(Opcode, 0, Bytes, NumBits, Scale); 443 // MI would expand into a large number of instructions. Don't try to 444 // simplify the immediate. 445 if (NumMIs > 2) { 446 emitThumbRegPlusImmediate(MBB, II, dl, DestReg, FrameReg, Offset, TII, 447 *this); 448 MBB.erase(II); 449 return true; 450 } 451 452 if (Offset > 0) { 453 // Translate r0 = add sp, imm to 454 // r0 = add sp, 255*4 455 // r0 = add r0, (imm - 255*4) 456 if (Opcode == ARM::tADDi3) { 457 MI.setDesc(TII.get(Opcode)); 458 removeOperands(MI, FrameRegIdx); 459 MachineInstrBuilder MIB(&MI); 460 AddDefaultPred(AddDefaultT1CC(MIB).addReg(FrameReg).addImm(Mask)); 461 } else { 462 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 463 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Mask); 464 } 465 Offset = (Offset - Mask * Scale); 466 MachineBasicBlock::iterator NII = llvm::next(II); 467 emitThumbRegPlusImmediate(MBB, NII, dl, DestReg, DestReg, Offset, TII, 468 *this); 469 } else { 470 // Translate r0 = add sp, -imm to 471 // r0 = -imm (this is then translated into a series of instructons) 472 // r0 = add r0, sp 473 emitThumbConstant(MBB, II, DestReg, Offset, TII, *this, dl); 474 475 MI.setDesc(TII.get(ARM::tADDhirr)); 476 MI.getOperand(FrameRegIdx).ChangeToRegister(DestReg, false, false, true); 477 MI.getOperand(FrameRegIdx+1).ChangeToRegister(FrameReg, false); 478 } 479 return true; 480 } else { 481 if (AddrMode != ARMII::AddrModeT1_s) 482 llvm_unreachable("Unsupported addressing mode!"); 483 484 unsigned ImmIdx = FrameRegIdx + 1; 485 int InstrOffs = MI.getOperand(ImmIdx).getImm(); 486 unsigned NumBits = (FrameReg == ARM::SP) ? 8 : 5; 487 unsigned Scale = 4; 488 489 Offset += InstrOffs * Scale; 490 assert((Offset & (Scale - 1)) == 0 && "Can't encode this offset!"); 491 492 // Common case: small offset, fits into instruction. 493 MachineOperand &ImmOp = MI.getOperand(ImmIdx); 494 int ImmedOffset = Offset / Scale; 495 unsigned Mask = (1 << NumBits) - 1; 496 497 if ((unsigned)Offset <= Mask * Scale) { 498 // Replace the FrameIndex with the frame register (e.g., sp). 499 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 500 ImmOp.ChangeToImmediate(ImmedOffset); 501 502 // If we're using a register where sp was stored, convert the instruction 503 // to the non-SP version. 504 unsigned NewOpc = convertToNonSPOpcode(Opcode); 505 if (NewOpc != Opcode && FrameReg != ARM::SP) 506 MI.setDesc(TII.get(NewOpc)); 507 508 return true; 509 } 510 511 NumBits = 5; 512 Mask = (1 << NumBits) - 1; 513 514 // If this is a thumb spill / restore, we will be using a constpool load to 515 // materialize the offset. 516 if (Opcode == ARM::tLDRspi || Opcode == ARM::tSTRspi) { 517 ImmOp.ChangeToImmediate(0); 518 } else { 519 // Otherwise, it didn't fit. Pull in what we can to simplify the immed. 520 ImmedOffset = ImmedOffset & Mask; 521 ImmOp.ChangeToImmediate(ImmedOffset); 522 Offset &= ~(Mask * Scale); 523 } 524 } 525 526 return Offset == 0; 527 } 528 529 void 530 Thumb1RegisterInfo::resolveFrameIndex(MachineBasicBlock::iterator I, 531 unsigned BaseReg, int64_t Offset) const { 532 MachineInstr &MI = *I; 533 int Off = Offset; // ARM doesn't need the general 64-bit offsets 534 unsigned i = 0; 535 536 while (!MI.getOperand(i).isFI()) { 537 ++i; 538 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 539 } 540 bool Done = rewriteFrameIndex(MI, i, BaseReg, Off, TII); 541 assert (Done && "Unable to resolve frame index!"); 542 (void)Done; 543 } 544 545 /// saveScavengerRegister - Spill the register so it can be used by the 546 /// register scavenger. Return true. 547 bool 548 Thumb1RegisterInfo::saveScavengerRegister(MachineBasicBlock &MBB, 549 MachineBasicBlock::iterator I, 550 MachineBasicBlock::iterator &UseMI, 551 const TargetRegisterClass *RC, 552 unsigned Reg) const { 553 // Thumb1 can't use the emergency spill slot on the stack because 554 // ldr/str immediate offsets must be positive, and if we're referencing 555 // off the frame pointer (if, for example, there are alloca() calls in 556 // the function, the offset will be negative. Use R12 instead since that's 557 // a call clobbered register that we know won't be used in Thumb1 mode. 558 DebugLoc DL; 559 AddDefaultPred(BuildMI(MBB, I, DL, TII.get(ARM::tMOVr)) 560 .addReg(ARM::R12, RegState::Define) 561 .addReg(Reg, RegState::Kill)); 562 563 // The UseMI is where we would like to restore the register. If there's 564 // interference with R12 before then, however, we'll need to restore it 565 // before that instead and adjust the UseMI. 566 bool done = false; 567 for (MachineBasicBlock::iterator II = I; !done && II != UseMI ; ++II) { 568 if (II->isDebugValue()) 569 continue; 570 // If this instruction affects R12, adjust our restore point. 571 for (unsigned i = 0, e = II->getNumOperands(); i != e; ++i) { 572 const MachineOperand &MO = II->getOperand(i); 573 if (MO.isRegMask() && MO.clobbersPhysReg(ARM::R12)) { 574 UseMI = II; 575 done = true; 576 break; 577 } 578 if (!MO.isReg() || MO.isUndef() || !MO.getReg() || 579 TargetRegisterInfo::isVirtualRegister(MO.getReg())) 580 continue; 581 if (MO.getReg() == ARM::R12) { 582 UseMI = II; 583 done = true; 584 break; 585 } 586 } 587 } 588 // Restore the register from R12 589 AddDefaultPred(BuildMI(MBB, UseMI, DL, TII.get(ARM::tMOVr)). 590 addReg(Reg, RegState::Define).addReg(ARM::R12, RegState::Kill)); 591 592 return true; 593 } 594 595 void 596 Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 597 int SPAdj, RegScavenger *RS) const { 598 unsigned VReg = 0; 599 unsigned i = 0; 600 MachineInstr &MI = *II; 601 MachineBasicBlock &MBB = *MI.getParent(); 602 MachineFunction &MF = *MBB.getParent(); 603 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 604 DebugLoc dl = MI.getDebugLoc(); 605 606 while (!MI.getOperand(i).isFI()) { 607 ++i; 608 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 609 } 610 611 unsigned FrameReg = ARM::SP; 612 int FrameIndex = MI.getOperand(i).getIndex(); 613 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) + 614 MF.getFrameInfo()->getStackSize() + SPAdj; 615 616 if (AFI->isGPRCalleeSavedArea1Frame(FrameIndex)) 617 Offset -= AFI->getGPRCalleeSavedArea1Offset(); 618 else if (AFI->isGPRCalleeSavedArea2Frame(FrameIndex)) 619 Offset -= AFI->getGPRCalleeSavedArea2Offset(); 620 else if (MF.getFrameInfo()->hasVarSizedObjects()) { 621 assert(SPAdj == 0 && MF.getTarget().getFrameLowering()->hasFP(MF) && 622 "Unexpected"); 623 // There are alloca()'s in this function, must reference off the frame 624 // pointer or base pointer instead. 625 if (!hasBasePointer(MF)) { 626 FrameReg = getFrameRegister(MF); 627 Offset -= AFI->getFramePtrSpillOffset(); 628 } else 629 FrameReg = BasePtr; 630 } 631 632 // PEI::scavengeFrameVirtualRegs() cannot accurately track SPAdj because the 633 // call frame setup/destroy instructions have already been eliminated. That 634 // means the stack pointer cannot be used to access the emergency spill slot 635 // when !hasReservedCallFrame(). 636 #ifndef NDEBUG 637 if (RS && FrameReg == ARM::SP && FrameIndex == RS->getScavengingFrameIndex()){ 638 assert(MF.getTarget().getFrameLowering()->hasReservedCallFrame(MF) && 639 "Cannot use SP to access the emergency spill slot in " 640 "functions without a reserved call frame"); 641 assert(!MF.getFrameInfo()->hasVarSizedObjects() && 642 "Cannot use SP to access the emergency spill slot in " 643 "functions with variable sized frame objects"); 644 } 645 #endif // NDEBUG 646 647 // Special handling of dbg_value instructions. 648 if (MI.isDebugValue()) { 649 MI.getOperand(i). ChangeToRegister(FrameReg, false /*isDef*/); 650 MI.getOperand(i+1).ChangeToImmediate(Offset); 651 return; 652 } 653 654 // Modify MI as necessary to handle as much of 'Offset' as possible 655 assert(AFI->isThumbFunction() && 656 "This eliminateFrameIndex only supports Thumb1!"); 657 if (rewriteFrameIndex(MI, i, FrameReg, Offset, TII)) 658 return; 659 660 // If we get here, the immediate doesn't fit into the instruction. We folded 661 // as much as possible above, handle the rest, providing a register that is 662 // SP+LargeImm. 663 assert(Offset && "This code isn't needed if offset already handled!"); 664 665 unsigned Opcode = MI.getOpcode(); 666 667 // Remove predicate first. 668 int PIdx = MI.findFirstPredOperandIdx(); 669 if (PIdx != -1) 670 removeOperands(MI, PIdx); 671 672 if (MI.mayLoad()) { 673 // Use the destination register to materialize sp + offset. 674 unsigned TmpReg = MI.getOperand(0).getReg(); 675 bool UseRR = false; 676 if (Opcode == ARM::tLDRspi) { 677 if (FrameReg == ARM::SP) 678 emitThumbRegPlusImmInReg(MBB, II, dl, TmpReg, FrameReg, 679 Offset, false, TII, *this); 680 else { 681 emitLoadConstPool(MBB, II, dl, TmpReg, 0, Offset); 682 UseRR = true; 683 } 684 } else { 685 emitThumbRegPlusImmediate(MBB, II, dl, TmpReg, FrameReg, Offset, TII, 686 *this); 687 } 688 689 MI.setDesc(TII.get(UseRR ? ARM::tLDRr : ARM::tLDRi)); 690 MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true); 691 if (UseRR) 692 // Use [reg, reg] addrmode. Replace the immediate operand w/ the frame 693 // register. The offset is already handled in the vreg value. 694 MI.getOperand(i+1).ChangeToRegister(FrameReg, false, false, false); 695 } else if (MI.mayStore()) { 696 VReg = MF.getRegInfo().createVirtualRegister(ARM::tGPRRegisterClass); 697 bool UseRR = false; 698 699 if (Opcode == ARM::tSTRspi) { 700 if (FrameReg == ARM::SP) 701 emitThumbRegPlusImmInReg(MBB, II, dl, VReg, FrameReg, 702 Offset, false, TII, *this); 703 else { 704 emitLoadConstPool(MBB, II, dl, VReg, 0, Offset); 705 UseRR = true; 706 } 707 } else 708 emitThumbRegPlusImmediate(MBB, II, dl, VReg, FrameReg, Offset, TII, 709 *this); 710 MI.setDesc(TII.get(UseRR ? ARM::tSTRr : ARM::tSTRi)); 711 MI.getOperand(i).ChangeToRegister(VReg, false, false, true); 712 if (UseRR) 713 // Use [reg, reg] addrmode. Replace the immediate operand w/ the frame 714 // register. The offset is already handled in the vreg value. 715 MI.getOperand(i+1).ChangeToRegister(FrameReg, false, false, false); 716 } else { 717 llvm_unreachable("Unexpected opcode!"); 718 } 719 720 // Add predicate back if it's needed. 721 if (MI.isPredicable()) { 722 MachineInstrBuilder MIB(&MI); 723 AddDefaultPred(MIB); 724 } 725 } 726