1 //===-- ThumbRegisterInfo.cpp - Thumb-1 Register Information -------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains the Thumb-1 implementation of the TargetRegisterInfo 10 // class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "ThumbRegisterInfo.h" 15 #include "ARMBaseInstrInfo.h" 16 #include "ARMMachineFunctionInfo.h" 17 #include "ARMSubtarget.h" 18 #include "MCTargetDesc/ARMAddressingModes.h" 19 #include "llvm/CodeGen/MachineConstantPool.h" 20 #include "llvm/CodeGen/MachineFrameInfo.h" 21 #include "llvm/CodeGen/MachineFunction.h" 22 #include "llvm/CodeGen/MachineInstrBuilder.h" 23 #include "llvm/CodeGen/MachineRegisterInfo.h" 24 #include "llvm/CodeGen/RegisterScavenging.h" 25 #include "llvm/IR/Constants.h" 26 #include "llvm/IR/DerivedTypes.h" 27 #include "llvm/IR/Function.h" 28 #include "llvm/IR/LLVMContext.h" 29 #include "llvm/Support/CommandLine.h" 30 #include "llvm/Support/ErrorHandling.h" 31 #include "llvm/CodeGen/TargetFrameLowering.h" 32 #include "llvm/Target/TargetMachine.h" 33 34 namespace llvm { 35 extern cl::opt<bool> ReuseFrameIndexVals; 36 } 37 38 using namespace llvm; 39 40 ThumbRegisterInfo::ThumbRegisterInfo() : ARMBaseRegisterInfo() {} 41 42 const TargetRegisterClass * 43 ThumbRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC, 44 const MachineFunction &MF) const { 45 if (!MF.getSubtarget<ARMSubtarget>().isThumb1Only()) 46 return ARMBaseRegisterInfo::getLargestLegalSuperClass(RC, MF); 47 48 if (ARM::tGPRRegClass.hasSubClassEq(RC)) 49 return &ARM::tGPRRegClass; 50 return ARMBaseRegisterInfo::getLargestLegalSuperClass(RC, MF); 51 } 52 53 const TargetRegisterClass * 54 ThumbRegisterInfo::getPointerRegClass(const MachineFunction &MF, 55 unsigned Kind) const { 56 if (!MF.getSubtarget<ARMSubtarget>().isThumb1Only()) 57 return ARMBaseRegisterInfo::getPointerRegClass(MF, Kind); 58 return &ARM::tGPRRegClass; 59 } 60 61 static void emitThumb1LoadConstPool(MachineBasicBlock &MBB, 62 MachineBasicBlock::iterator &MBBI, 63 const DebugLoc &dl, unsigned DestReg, 64 unsigned SubIdx, int Val, 65 ARMCC::CondCodes Pred, unsigned PredReg, 66 unsigned MIFlags) { 67 MachineFunction &MF = *MBB.getParent(); 68 const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>(); 69 const TargetInstrInfo &TII = *STI.getInstrInfo(); 70 MachineConstantPool *ConstantPool = MF.getConstantPool(); 71 const Constant *C = ConstantInt::get( 72 Type::getInt32Ty(MBB.getParent()->getFunction().getContext()), Val); 73 unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4); 74 75 BuildMI(MBB, MBBI, dl, TII.get(ARM::tLDRpci)) 76 .addReg(DestReg, getDefRegState(true), SubIdx) 77 .addConstantPoolIndex(Idx).addImm(Pred).addReg(PredReg) 78 .setMIFlags(MIFlags); 79 } 80 81 static void emitThumb2LoadConstPool(MachineBasicBlock &MBB, 82 MachineBasicBlock::iterator &MBBI, 83 const DebugLoc &dl, unsigned DestReg, 84 unsigned SubIdx, int Val, 85 ARMCC::CondCodes Pred, unsigned PredReg, 86 unsigned MIFlags) { 87 MachineFunction &MF = *MBB.getParent(); 88 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); 89 MachineConstantPool *ConstantPool = MF.getConstantPool(); 90 const Constant *C = ConstantInt::get( 91 Type::getInt32Ty(MBB.getParent()->getFunction().getContext()), Val); 92 unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4); 93 94 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2LDRpci)) 95 .addReg(DestReg, getDefRegState(true), SubIdx) 96 .addConstantPoolIndex(Idx) 97 .add(predOps(ARMCC::AL)) 98 .setMIFlags(MIFlags); 99 } 100 101 /// emitLoadConstPool - Emits a load from constpool to materialize the 102 /// specified immediate. 103 void ThumbRegisterInfo::emitLoadConstPool( 104 MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, 105 const DebugLoc &dl, unsigned DestReg, unsigned SubIdx, int Val, 106 ARMCC::CondCodes Pred, unsigned PredReg, unsigned MIFlags) const { 107 MachineFunction &MF = *MBB.getParent(); 108 const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>(); 109 if (STI.isThumb1Only()) { 110 assert((isARMLowRegister(DestReg) || isVirtualRegister(DestReg)) && 111 "Thumb1 does not have ldr to high register"); 112 return emitThumb1LoadConstPool(MBB, MBBI, dl, DestReg, SubIdx, Val, Pred, 113 PredReg, MIFlags); 114 } 115 return emitThumb2LoadConstPool(MBB, MBBI, dl, DestReg, SubIdx, Val, Pred, 116 PredReg, MIFlags); 117 } 118 119 /// emitThumbRegPlusImmInReg - Emits a series of instructions to materialize 120 /// a destreg = basereg + immediate in Thumb code. Materialize the immediate 121 /// in a register using mov / mvn sequences or load the immediate from a 122 /// constpool entry. 123 static void emitThumbRegPlusImmInReg( 124 MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, 125 const DebugLoc &dl, unsigned DestReg, unsigned BaseReg, int NumBytes, 126 bool CanChangeCC, const TargetInstrInfo &TII, 127 const ARMBaseRegisterInfo &MRI, unsigned MIFlags = MachineInstr::NoFlags) { 128 MachineFunction &MF = *MBB.getParent(); 129 const ARMSubtarget &ST = MF.getSubtarget<ARMSubtarget>(); 130 bool isHigh = !isARMLowRegister(DestReg) || 131 (BaseReg != 0 && !isARMLowRegister(BaseReg)); 132 bool isSub = false; 133 // Subtract doesn't have high register version. Load the negative value 134 // if either base or dest register is a high register. Also, if do not 135 // issue sub as part of the sequence if condition register is to be 136 // preserved. 137 if (NumBytes < 0 && !isHigh && CanChangeCC) { 138 isSub = true; 139 NumBytes = -NumBytes; 140 } 141 unsigned LdReg = DestReg; 142 if (DestReg == ARM::SP) 143 assert(BaseReg == ARM::SP && "Unexpected!"); 144 if (!isARMLowRegister(DestReg) && !MRI.isVirtualRegister(DestReg)) 145 LdReg = MF.getRegInfo().createVirtualRegister(&ARM::tGPRRegClass); 146 147 if (NumBytes <= 255 && NumBytes >= 0 && CanChangeCC) { 148 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg) 149 .add(t1CondCodeOp()) 150 .addImm(NumBytes) 151 .setMIFlags(MIFlags); 152 } else if (NumBytes < 0 && NumBytes >= -255 && CanChangeCC) { 153 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg) 154 .add(t1CondCodeOp()) 155 .addImm(NumBytes) 156 .setMIFlags(MIFlags); 157 BuildMI(MBB, MBBI, dl, TII.get(ARM::tRSB), LdReg) 158 .add(t1CondCodeOp()) 159 .addReg(LdReg, RegState::Kill) 160 .setMIFlags(MIFlags); 161 } else if (ST.genExecuteOnly()) { 162 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi32imm), LdReg) 163 .addImm(NumBytes).setMIFlags(MIFlags); 164 } else 165 MRI.emitLoadConstPool(MBB, MBBI, dl, LdReg, 0, NumBytes, ARMCC::AL, 0, 166 MIFlags); 167 168 // Emit add / sub. 169 int Opc = (isSub) ? ARM::tSUBrr 170 : ((isHigh || !CanChangeCC) ? ARM::tADDhirr : ARM::tADDrr); 171 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg); 172 if (Opc != ARM::tADDhirr) 173 MIB = MIB.add(t1CondCodeOp()); 174 if (DestReg == ARM::SP || isSub) 175 MIB.addReg(BaseReg).addReg(LdReg, RegState::Kill); 176 else 177 MIB.addReg(LdReg).addReg(BaseReg, RegState::Kill); 178 MIB.add(predOps(ARMCC::AL)); 179 } 180 181 /// emitThumbRegPlusImmediate - Emits a series of instructions to materialize 182 /// a destreg = basereg + immediate in Thumb code. Tries a series of ADDs or 183 /// SUBs first, and uses a constant pool value if the instruction sequence would 184 /// be too long. This is allowed to modify the condition flags. 185 void llvm::emitThumbRegPlusImmediate(MachineBasicBlock &MBB, 186 MachineBasicBlock::iterator &MBBI, 187 const DebugLoc &dl, unsigned DestReg, 188 unsigned BaseReg, int NumBytes, 189 const TargetInstrInfo &TII, 190 const ARMBaseRegisterInfo &MRI, 191 unsigned MIFlags) { 192 bool isSub = NumBytes < 0; 193 unsigned Bytes = (unsigned)NumBytes; 194 if (isSub) Bytes = -NumBytes; 195 196 int CopyOpc = 0; 197 unsigned CopyBits = 0; 198 unsigned CopyScale = 1; 199 bool CopyNeedsCC = false; 200 int ExtraOpc = 0; 201 unsigned ExtraBits = 0; 202 unsigned ExtraScale = 1; 203 bool ExtraNeedsCC = false; 204 205 // Strategy: 206 // We need to select two types of instruction, maximizing the available 207 // immediate range of each. The instructions we use will depend on whether 208 // DestReg and BaseReg are low, high or the stack pointer. 209 // * CopyOpc - DestReg = BaseReg + imm 210 // This will be emitted once if DestReg != BaseReg, and never if 211 // DestReg == BaseReg. 212 // * ExtraOpc - DestReg = DestReg + imm 213 // This will be emitted as many times as necessary to add the 214 // full immediate. 215 // If the immediate ranges of these instructions are not large enough to cover 216 // NumBytes with a reasonable number of instructions, we fall back to using a 217 // value loaded from a constant pool. 218 if (DestReg == ARM::SP) { 219 if (BaseReg == ARM::SP) { 220 // sp -> sp 221 // Already in right reg, no copy needed 222 } else { 223 // low -> sp or high -> sp 224 CopyOpc = ARM::tMOVr; 225 CopyBits = 0; 226 } 227 ExtraOpc = isSub ? ARM::tSUBspi : ARM::tADDspi; 228 ExtraBits = 7; 229 ExtraScale = 4; 230 } else if (isARMLowRegister(DestReg)) { 231 if (BaseReg == ARM::SP) { 232 // sp -> low 233 assert(!isSub && "Thumb1 does not have tSUBrSPi"); 234 CopyOpc = ARM::tADDrSPi; 235 CopyBits = 8; 236 CopyScale = 4; 237 } else if (DestReg == BaseReg) { 238 // low -> same low 239 // Already in right reg, no copy needed 240 } else if (isARMLowRegister(BaseReg)) { 241 // low -> different low 242 CopyOpc = isSub ? ARM::tSUBi3 : ARM::tADDi3; 243 CopyBits = 3; 244 CopyNeedsCC = true; 245 } else { 246 // high -> low 247 CopyOpc = ARM::tMOVr; 248 CopyBits = 0; 249 } 250 ExtraOpc = isSub ? ARM::tSUBi8 : ARM::tADDi8; 251 ExtraBits = 8; 252 ExtraNeedsCC = true; 253 } else /* DestReg is high */ { 254 if (DestReg == BaseReg) { 255 // high -> same high 256 // Already in right reg, no copy needed 257 } else { 258 // {low,high,sp} -> high 259 CopyOpc = ARM::tMOVr; 260 CopyBits = 0; 261 } 262 ExtraOpc = 0; 263 } 264 265 // We could handle an unaligned immediate with an unaligned copy instruction 266 // and an aligned extra instruction, but this case is not currently needed. 267 assert(((Bytes & 3) == 0 || ExtraScale == 1) && 268 "Unaligned offset, but all instructions require alignment"); 269 270 unsigned CopyRange = ((1 << CopyBits) - 1) * CopyScale; 271 // If we would emit the copy with an immediate of 0, just use tMOVr. 272 if (CopyOpc && Bytes < CopyScale) { 273 CopyOpc = ARM::tMOVr; 274 CopyScale = 1; 275 CopyNeedsCC = false; 276 CopyRange = 0; 277 } 278 unsigned ExtraRange = ((1 << ExtraBits) - 1) * ExtraScale; // per instruction 279 unsigned RequiredCopyInstrs = CopyOpc ? 1 : 0; 280 unsigned RangeAfterCopy = (CopyRange > Bytes) ? 0 : (Bytes - CopyRange); 281 282 // We could handle this case when the copy instruction does not require an 283 // aligned immediate, but we do not currently do this. 284 assert(RangeAfterCopy % ExtraScale == 0 && 285 "Extra instruction requires immediate to be aligned"); 286 287 unsigned RequiredExtraInstrs; 288 if (ExtraRange) 289 RequiredExtraInstrs = alignTo(RangeAfterCopy, ExtraRange) / ExtraRange; 290 else if (RangeAfterCopy > 0) 291 // We need an extra instruction but none is available 292 RequiredExtraInstrs = 1000000; 293 else 294 RequiredExtraInstrs = 0; 295 unsigned RequiredInstrs = RequiredCopyInstrs + RequiredExtraInstrs; 296 unsigned Threshold = (DestReg == ARM::SP) ? 3 : 2; 297 298 // Use a constant pool, if the sequence of ADDs/SUBs is too expensive. 299 if (RequiredInstrs > Threshold) { 300 emitThumbRegPlusImmInReg(MBB, MBBI, dl, 301 DestReg, BaseReg, NumBytes, true, 302 TII, MRI, MIFlags); 303 return; 304 } 305 306 // Emit zero or one copy instructions 307 if (CopyOpc) { 308 unsigned CopyImm = std::min(Bytes, CopyRange) / CopyScale; 309 Bytes -= CopyImm * CopyScale; 310 311 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(CopyOpc), DestReg); 312 if (CopyNeedsCC) 313 MIB = MIB.add(t1CondCodeOp()); 314 MIB.addReg(BaseReg, RegState::Kill); 315 if (CopyOpc != ARM::tMOVr) { 316 MIB.addImm(CopyImm); 317 } 318 MIB.setMIFlags(MIFlags).add(predOps(ARMCC::AL)); 319 320 BaseReg = DestReg; 321 } 322 323 // Emit zero or more in-place add/sub instructions 324 while (Bytes) { 325 unsigned ExtraImm = std::min(Bytes, ExtraRange) / ExtraScale; 326 Bytes -= ExtraImm * ExtraScale; 327 328 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(ExtraOpc), DestReg); 329 if (ExtraNeedsCC) 330 MIB = MIB.add(t1CondCodeOp()); 331 MIB.addReg(BaseReg) 332 .addImm(ExtraImm) 333 .add(predOps(ARMCC::AL)) 334 .setMIFlags(MIFlags); 335 } 336 } 337 338 static void removeOperands(MachineInstr &MI, unsigned i) { 339 unsigned Op = i; 340 for (unsigned e = MI.getNumOperands(); i != e; ++i) 341 MI.RemoveOperand(Op); 342 } 343 344 /// convertToNonSPOpcode - Change the opcode to the non-SP version, because 345 /// we're replacing the frame index with a non-SP register. 346 static unsigned convertToNonSPOpcode(unsigned Opcode) { 347 switch (Opcode) { 348 case ARM::tLDRspi: 349 return ARM::tLDRi; 350 351 case ARM::tSTRspi: 352 return ARM::tSTRi; 353 } 354 355 return Opcode; 356 } 357 358 bool ThumbRegisterInfo::rewriteFrameIndex(MachineBasicBlock::iterator II, 359 unsigned FrameRegIdx, 360 unsigned FrameReg, int &Offset, 361 const ARMBaseInstrInfo &TII) const { 362 MachineInstr &MI = *II; 363 MachineBasicBlock &MBB = *MI.getParent(); 364 assert(MBB.getParent()->getSubtarget<ARMSubtarget>().isThumb1Only() && 365 "This isn't needed for thumb2!"); 366 DebugLoc dl = MI.getDebugLoc(); 367 MachineInstrBuilder MIB(*MBB.getParent(), &MI); 368 unsigned Opcode = MI.getOpcode(); 369 const MCInstrDesc &Desc = MI.getDesc(); 370 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); 371 372 if (Opcode == ARM::tADDframe) { 373 Offset += MI.getOperand(FrameRegIdx+1).getImm(); 374 unsigned DestReg = MI.getOperand(0).getReg(); 375 376 emitThumbRegPlusImmediate(MBB, II, dl, DestReg, FrameReg, Offset, TII, 377 *this); 378 MBB.erase(II); 379 return true; 380 } else { 381 if (AddrMode != ARMII::AddrModeT1_s) 382 llvm_unreachable("Unsupported addressing mode!"); 383 384 unsigned ImmIdx = FrameRegIdx + 1; 385 int InstrOffs = MI.getOperand(ImmIdx).getImm(); 386 unsigned NumBits = (FrameReg == ARM::SP) ? 8 : 5; 387 unsigned Scale = 4; 388 389 Offset += InstrOffs * Scale; 390 assert((Offset & (Scale - 1)) == 0 && "Can't encode this offset!"); 391 392 // Common case: small offset, fits into instruction. 393 MachineOperand &ImmOp = MI.getOperand(ImmIdx); 394 int ImmedOffset = Offset / Scale; 395 unsigned Mask = (1 << NumBits) - 1; 396 397 if ((unsigned)Offset <= Mask * Scale) { 398 // Replace the FrameIndex with the frame register (e.g., sp). 399 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 400 ImmOp.ChangeToImmediate(ImmedOffset); 401 402 // If we're using a register where sp was stored, convert the instruction 403 // to the non-SP version. 404 unsigned NewOpc = convertToNonSPOpcode(Opcode); 405 if (NewOpc != Opcode && FrameReg != ARM::SP) 406 MI.setDesc(TII.get(NewOpc)); 407 408 return true; 409 } 410 411 NumBits = 5; 412 Mask = (1 << NumBits) - 1; 413 414 // If this is a thumb spill / restore, we will be using a constpool load to 415 // materialize the offset. 416 if (Opcode == ARM::tLDRspi || Opcode == ARM::tSTRspi) { 417 ImmOp.ChangeToImmediate(0); 418 } else { 419 // Otherwise, it didn't fit. Pull in what we can to simplify the immed. 420 ImmedOffset = ImmedOffset & Mask; 421 ImmOp.ChangeToImmediate(ImmedOffset); 422 Offset &= ~(Mask * Scale); 423 } 424 } 425 426 return Offset == 0; 427 } 428 429 void ThumbRegisterInfo::resolveFrameIndex(MachineInstr &MI, unsigned BaseReg, 430 int64_t Offset) const { 431 const MachineFunction &MF = *MI.getParent()->getParent(); 432 const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>(); 433 if (!STI.isThumb1Only()) 434 return ARMBaseRegisterInfo::resolveFrameIndex(MI, BaseReg, Offset); 435 436 const ARMBaseInstrInfo &TII = *STI.getInstrInfo(); 437 int Off = Offset; // ARM doesn't need the general 64-bit offsets 438 unsigned i = 0; 439 440 while (!MI.getOperand(i).isFI()) { 441 ++i; 442 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 443 } 444 bool Done = rewriteFrameIndex(MI, i, BaseReg, Off, TII); 445 assert (Done && "Unable to resolve frame index!"); 446 (void)Done; 447 } 448 449 /// saveScavengerRegister - Spill the register so it can be used by the 450 /// register scavenger. Return true. 451 bool ThumbRegisterInfo::saveScavengerRegister( 452 MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 453 MachineBasicBlock::iterator &UseMI, const TargetRegisterClass *RC, 454 unsigned Reg) const { 455 456 const ARMSubtarget &STI = MBB.getParent()->getSubtarget<ARMSubtarget>(); 457 if (!STI.isThumb1Only()) 458 return ARMBaseRegisterInfo::saveScavengerRegister(MBB, I, UseMI, RC, Reg); 459 460 // Thumb1 can't use the emergency spill slot on the stack because 461 // ldr/str immediate offsets must be positive, and if we're referencing 462 // off the frame pointer (if, for example, there are alloca() calls in 463 // the function, the offset will be negative. Use R12 instead since that's 464 // a call clobbered register that we know won't be used in Thumb1 mode. 465 const TargetInstrInfo &TII = *STI.getInstrInfo(); 466 DebugLoc DL; 467 BuildMI(MBB, I, DL, TII.get(ARM::tMOVr)) 468 .addReg(ARM::R12, RegState::Define) 469 .addReg(Reg, RegState::Kill) 470 .add(predOps(ARMCC::AL)); 471 472 // The UseMI is where we would like to restore the register. If there's 473 // interference with R12 before then, however, we'll need to restore it 474 // before that instead and adjust the UseMI. 475 bool done = false; 476 for (MachineBasicBlock::iterator II = I; !done && II != UseMI ; ++II) { 477 if (II->isDebugInstr()) 478 continue; 479 // If this instruction affects R12, adjust our restore point. 480 for (unsigned i = 0, e = II->getNumOperands(); i != e; ++i) { 481 const MachineOperand &MO = II->getOperand(i); 482 if (MO.isRegMask() && MO.clobbersPhysReg(ARM::R12)) { 483 UseMI = II; 484 done = true; 485 break; 486 } 487 if (!MO.isReg() || MO.isUndef() || !MO.getReg() || 488 TargetRegisterInfo::isVirtualRegister(MO.getReg())) 489 continue; 490 if (MO.getReg() == ARM::R12) { 491 UseMI = II; 492 done = true; 493 break; 494 } 495 } 496 } 497 // Restore the register from R12 498 BuildMI(MBB, UseMI, DL, TII.get(ARM::tMOVr)) 499 .addReg(Reg, RegState::Define) 500 .addReg(ARM::R12, RegState::Kill) 501 .add(predOps(ARMCC::AL)); 502 503 return true; 504 } 505 506 void ThumbRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 507 int SPAdj, unsigned FIOperandNum, 508 RegScavenger *RS) const { 509 MachineInstr &MI = *II; 510 MachineBasicBlock &MBB = *MI.getParent(); 511 MachineFunction &MF = *MBB.getParent(); 512 const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>(); 513 if (!STI.isThumb1Only()) 514 return ARMBaseRegisterInfo::eliminateFrameIndex(II, SPAdj, FIOperandNum, 515 RS); 516 517 unsigned VReg = 0; 518 const ARMBaseInstrInfo &TII = *STI.getInstrInfo(); 519 DebugLoc dl = MI.getDebugLoc(); 520 MachineInstrBuilder MIB(*MBB.getParent(), &MI); 521 522 unsigned FrameReg; 523 int FrameIndex = MI.getOperand(FIOperandNum).getIndex(); 524 const ARMFrameLowering *TFI = getFrameLowering(MF); 525 int Offset = TFI->ResolveFrameIndexReference(MF, FrameIndex, FrameReg, SPAdj); 526 527 // PEI::scavengeFrameVirtualRegs() cannot accurately track SPAdj because the 528 // call frame setup/destroy instructions have already been eliminated. That 529 // means the stack pointer cannot be used to access the emergency spill slot 530 // when !hasReservedCallFrame(). 531 #ifndef NDEBUG 532 if (RS && FrameReg == ARM::SP && RS->isScavengingFrameIndex(FrameIndex)){ 533 assert(STI.getFrameLowering()->hasReservedCallFrame(MF) && 534 "Cannot use SP to access the emergency spill slot in " 535 "functions without a reserved call frame"); 536 assert(!MF.getFrameInfo().hasVarSizedObjects() && 537 "Cannot use SP to access the emergency spill slot in " 538 "functions with variable sized frame objects"); 539 } 540 #endif // NDEBUG 541 542 // Special handling of dbg_value instructions. 543 if (MI.isDebugValue()) { 544 MI.getOperand(FIOperandNum). ChangeToRegister(FrameReg, false /*isDef*/); 545 MI.getOperand(FIOperandNum+1).ChangeToImmediate(Offset); 546 return; 547 } 548 549 // Modify MI as necessary to handle as much of 'Offset' as possible 550 assert(MF.getInfo<ARMFunctionInfo>()->isThumbFunction() && 551 "This eliminateFrameIndex only supports Thumb1!"); 552 if (rewriteFrameIndex(MI, FIOperandNum, FrameReg, Offset, TII)) 553 return; 554 555 // If we get here, the immediate doesn't fit into the instruction. We folded 556 // as much as possible above, handle the rest, providing a register that is 557 // SP+LargeImm. 558 assert(Offset && "This code isn't needed if offset already handled!"); 559 560 unsigned Opcode = MI.getOpcode(); 561 562 // Remove predicate first. 563 int PIdx = MI.findFirstPredOperandIdx(); 564 if (PIdx != -1) 565 removeOperands(MI, PIdx); 566 567 if (MI.mayLoad()) { 568 // Use the destination register to materialize sp + offset. 569 unsigned TmpReg = MI.getOperand(0).getReg(); 570 bool UseRR = false; 571 if (Opcode == ARM::tLDRspi) { 572 if (FrameReg == ARM::SP || STI.genExecuteOnly()) 573 emitThumbRegPlusImmInReg(MBB, II, dl, TmpReg, FrameReg, 574 Offset, false, TII, *this); 575 else { 576 emitLoadConstPool(MBB, II, dl, TmpReg, 0, Offset); 577 UseRR = true; 578 } 579 } else { 580 emitThumbRegPlusImmediate(MBB, II, dl, TmpReg, FrameReg, Offset, TII, 581 *this); 582 } 583 584 MI.setDesc(TII.get(UseRR ? ARM::tLDRr : ARM::tLDRi)); 585 MI.getOperand(FIOperandNum).ChangeToRegister(TmpReg, false, false, true); 586 if (UseRR) 587 // Use [reg, reg] addrmode. Replace the immediate operand w/ the frame 588 // register. The offset is already handled in the vreg value. 589 MI.getOperand(FIOperandNum+1).ChangeToRegister(FrameReg, false, false, 590 false); 591 } else if (MI.mayStore()) { 592 VReg = MF.getRegInfo().createVirtualRegister(&ARM::tGPRRegClass); 593 bool UseRR = false; 594 595 if (Opcode == ARM::tSTRspi) { 596 if (FrameReg == ARM::SP || STI.genExecuteOnly()) 597 emitThumbRegPlusImmInReg(MBB, II, dl, VReg, FrameReg, 598 Offset, false, TII, *this); 599 else { 600 emitLoadConstPool(MBB, II, dl, VReg, 0, Offset); 601 UseRR = true; 602 } 603 } else 604 emitThumbRegPlusImmediate(MBB, II, dl, VReg, FrameReg, Offset, TII, 605 *this); 606 MI.setDesc(TII.get(UseRR ? ARM::tSTRr : ARM::tSTRi)); 607 MI.getOperand(FIOperandNum).ChangeToRegister(VReg, false, false, true); 608 if (UseRR) 609 // Use [reg, reg] addrmode. Replace the immediate operand w/ the frame 610 // register. The offset is already handled in the vreg value. 611 MI.getOperand(FIOperandNum+1).ChangeToRegister(FrameReg, false, false, 612 false); 613 } else { 614 llvm_unreachable("Unexpected opcode!"); 615 } 616 617 // Add predicate back if it's needed. 618 if (MI.isPredicable()) 619 MIB.add(predOps(ARMCC::AL)); 620 } 621