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() = default; 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, Align(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, Align(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, Register DestReg, unsigned SubIdx, int Val, 106 ARMCC::CondCodes Pred, Register PredReg, unsigned MIFlags) const { 107 MachineFunction &MF = *MBB.getParent(); 108 const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>(); 109 if (STI.isThumb1Only()) { 110 assert((isARMLowRegister(DestReg) || DestReg.isVirtual()) && 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 a 120 /// destreg = basereg + immediate in Thumb code. Materialize the immediate in a 121 /// register using mov / mvn (armv6-M >) sequences, movs / lsls / adds / lsls / 122 /// adds / lsls / adds sequences (armv6-M) or load the immediate from a 123 /// constpool entry. 124 static void emitThumbRegPlusImmInReg( 125 MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, 126 const DebugLoc &dl, Register DestReg, Register BaseReg, int NumBytes, 127 bool CanChangeCC, const TargetInstrInfo &TII, 128 const ARMBaseRegisterInfo &MRI, unsigned MIFlags = MachineInstr::NoFlags) { 129 MachineFunction &MF = *MBB.getParent(); 130 const ARMSubtarget &ST = MF.getSubtarget<ARMSubtarget>(); 131 bool isHigh = !isARMLowRegister(DestReg) || 132 (BaseReg != 0 && !isARMLowRegister(BaseReg)); 133 bool isSub = false; 134 // Subtract doesn't have high register version. Load the negative value 135 // if either base or dest register is a high register. Also, if do not 136 // issue sub as part of the sequence if condition register is to be 137 // preserved. 138 if (NumBytes < 0 && !isHigh && CanChangeCC) { 139 isSub = true; 140 NumBytes = -NumBytes; 141 } 142 Register LdReg = DestReg; 143 if (DestReg == ARM::SP) 144 assert(BaseReg == ARM::SP && "Unexpected!"); 145 if (!isARMLowRegister(DestReg) && !DestReg.isVirtual()) 146 LdReg = MF.getRegInfo().createVirtualRegister(&ARM::tGPRRegClass); 147 148 if (NumBytes <= 255 && NumBytes >= 0 && CanChangeCC) { 149 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg) 150 .add(t1CondCodeOp()) 151 .addImm(NumBytes) 152 .setMIFlags(MIFlags); 153 } else if (NumBytes < 0 && NumBytes >= -255 && CanChangeCC) { 154 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg) 155 .add(t1CondCodeOp()) 156 .addImm(NumBytes) 157 .setMIFlags(MIFlags); 158 BuildMI(MBB, MBBI, dl, TII.get(ARM::tRSB), LdReg) 159 .add(t1CondCodeOp()) 160 .addReg(LdReg, RegState::Kill) 161 .setMIFlags(MIFlags); 162 } else if (ST.genExecuteOnly()) { 163 unsigned XOInstr = ST.useMovt() ? ARM::t2MOVi32imm : ARM::tMOVi32imm; 164 BuildMI(MBB, MBBI, dl, TII.get(XOInstr), LdReg) 165 .addImm(NumBytes).setMIFlags(MIFlags); 166 } else 167 MRI.emitLoadConstPool(MBB, MBBI, dl, LdReg, 0, NumBytes, ARMCC::AL, 0, 168 MIFlags); 169 170 // Emit add / sub. 171 int Opc = (isSub) ? ARM::tSUBrr 172 : ((isHigh || !CanChangeCC) ? ARM::tADDhirr : ARM::tADDrr); 173 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg); 174 if (Opc != ARM::tADDhirr) 175 MIB = MIB.add(t1CondCodeOp()); 176 if (DestReg == ARM::SP || isSub) 177 MIB.addReg(BaseReg).addReg(LdReg, RegState::Kill); 178 else 179 MIB.addReg(LdReg).addReg(BaseReg, RegState::Kill); 180 MIB.add(predOps(ARMCC::AL)); 181 } 182 183 /// emitThumbRegPlusImmediate - Emits a series of instructions to materialize 184 /// a destreg = basereg + immediate in Thumb code. Tries a series of ADDs or 185 /// SUBs first, and uses a constant pool value if the instruction sequence would 186 /// be too long. This is allowed to modify the condition flags. 187 void llvm::emitThumbRegPlusImmediate(MachineBasicBlock &MBB, 188 MachineBasicBlock::iterator &MBBI, 189 const DebugLoc &dl, Register DestReg, 190 Register BaseReg, int NumBytes, 191 const TargetInstrInfo &TII, 192 const ARMBaseRegisterInfo &MRI, 193 unsigned MIFlags) { 194 bool isSub = NumBytes < 0; 195 unsigned Bytes = (unsigned)NumBytes; 196 if (isSub) Bytes = -NumBytes; 197 198 int CopyOpc = 0; 199 unsigned CopyBits = 0; 200 unsigned CopyScale = 1; 201 bool CopyNeedsCC = false; 202 int ExtraOpc = 0; 203 unsigned ExtraBits = 0; 204 unsigned ExtraScale = 1; 205 bool ExtraNeedsCC = false; 206 207 // Strategy: 208 // We need to select two types of instruction, maximizing the available 209 // immediate range of each. The instructions we use will depend on whether 210 // DestReg and BaseReg are low, high or the stack pointer. 211 // * CopyOpc - DestReg = BaseReg + imm 212 // This will be emitted once if DestReg != BaseReg, and never if 213 // DestReg == BaseReg. 214 // * ExtraOpc - DestReg = DestReg + imm 215 // This will be emitted as many times as necessary to add the 216 // full immediate. 217 // If the immediate ranges of these instructions are not large enough to cover 218 // NumBytes with a reasonable number of instructions, we fall back to using a 219 // value loaded from a constant pool. 220 if (DestReg == ARM::SP) { 221 if (BaseReg == ARM::SP) { 222 // sp -> sp 223 // Already in right reg, no copy needed 224 } else { 225 // low -> sp or high -> sp 226 CopyOpc = ARM::tMOVr; 227 CopyBits = 0; 228 } 229 ExtraOpc = isSub ? ARM::tSUBspi : ARM::tADDspi; 230 ExtraBits = 7; 231 ExtraScale = 4; 232 } else if (isARMLowRegister(DestReg)) { 233 if (BaseReg == ARM::SP) { 234 // sp -> low 235 assert(!isSub && "Thumb1 does not have tSUBrSPi"); 236 CopyOpc = ARM::tADDrSPi; 237 CopyBits = 8; 238 CopyScale = 4; 239 } else if (DestReg == BaseReg) { 240 // low -> same low 241 // Already in right reg, no copy needed 242 } else if (isARMLowRegister(BaseReg)) { 243 // low -> different low 244 CopyOpc = isSub ? ARM::tSUBi3 : ARM::tADDi3; 245 CopyBits = 3; 246 CopyNeedsCC = true; 247 } else { 248 // high -> low 249 CopyOpc = ARM::tMOVr; 250 CopyBits = 0; 251 } 252 ExtraOpc = isSub ? ARM::tSUBi8 : ARM::tADDi8; 253 ExtraBits = 8; 254 ExtraNeedsCC = true; 255 } else /* DestReg is high */ { 256 if (DestReg == BaseReg) { 257 // high -> same high 258 // Already in right reg, no copy needed 259 } else { 260 // {low,high,sp} -> high 261 CopyOpc = ARM::tMOVr; 262 CopyBits = 0; 263 } 264 ExtraOpc = 0; 265 } 266 267 // We could handle an unaligned immediate with an unaligned copy instruction 268 // and an aligned extra instruction, but this case is not currently needed. 269 assert(((Bytes & 3) == 0 || ExtraScale == 1) && 270 "Unaligned offset, but all instructions require alignment"); 271 272 unsigned CopyRange = ((1 << CopyBits) - 1) * CopyScale; 273 // If we would emit the copy with an immediate of 0, just use tMOVr. 274 if (CopyOpc && Bytes < CopyScale) { 275 CopyOpc = ARM::tMOVr; 276 CopyScale = 1; 277 CopyNeedsCC = false; 278 CopyRange = 0; 279 } 280 unsigned ExtraRange = ((1 << ExtraBits) - 1) * ExtraScale; // per instruction 281 unsigned RequiredCopyInstrs = CopyOpc ? 1 : 0; 282 unsigned RangeAfterCopy = (CopyRange > Bytes) ? 0 : (Bytes - CopyRange); 283 284 // We could handle this case when the copy instruction does not require an 285 // aligned immediate, but we do not currently do this. 286 assert(RangeAfterCopy % ExtraScale == 0 && 287 "Extra instruction requires immediate to be aligned"); 288 289 unsigned RequiredExtraInstrs; 290 if (ExtraRange) 291 RequiredExtraInstrs = alignTo(RangeAfterCopy, ExtraRange) / ExtraRange; 292 else if (RangeAfterCopy > 0) 293 // We need an extra instruction but none is available 294 RequiredExtraInstrs = 1000000; 295 else 296 RequiredExtraInstrs = 0; 297 unsigned RequiredInstrs = RequiredCopyInstrs + RequiredExtraInstrs; 298 unsigned Threshold = (DestReg == ARM::SP) ? 3 : 2; 299 300 // Use a constant pool, if the sequence of ADDs/SUBs is too expensive. 301 if (RequiredInstrs > Threshold) { 302 emitThumbRegPlusImmInReg(MBB, MBBI, dl, 303 DestReg, BaseReg, NumBytes, true, 304 TII, MRI, MIFlags); 305 return; 306 } 307 308 // Emit zero or one copy instructions 309 if (CopyOpc) { 310 unsigned CopyImm = std::min(Bytes, CopyRange) / CopyScale; 311 Bytes -= CopyImm * CopyScale; 312 313 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(CopyOpc), DestReg); 314 if (CopyNeedsCC) 315 MIB = MIB.add(t1CondCodeOp()); 316 MIB.addReg(BaseReg, RegState::Kill); 317 if (CopyOpc != ARM::tMOVr) { 318 MIB.addImm(CopyImm); 319 } 320 MIB.setMIFlags(MIFlags).add(predOps(ARMCC::AL)); 321 322 BaseReg = DestReg; 323 } 324 325 // Emit zero or more in-place add/sub instructions 326 while (Bytes) { 327 unsigned ExtraImm = std::min(Bytes, ExtraRange) / ExtraScale; 328 Bytes -= ExtraImm * ExtraScale; 329 330 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(ExtraOpc), DestReg); 331 if (ExtraNeedsCC) 332 MIB = MIB.add(t1CondCodeOp()); 333 MIB.addReg(BaseReg) 334 .addImm(ExtraImm) 335 .add(predOps(ARMCC::AL)) 336 .setMIFlags(MIFlags); 337 } 338 } 339 340 static void removeOperands(MachineInstr &MI, unsigned i) { 341 unsigned Op = i; 342 for (unsigned e = MI.getNumOperands(); i != e; ++i) 343 MI.removeOperand(Op); 344 } 345 346 /// convertToNonSPOpcode - Change the opcode to the non-SP version, because 347 /// we're replacing the frame index with a non-SP register. 348 static unsigned convertToNonSPOpcode(unsigned Opcode) { 349 switch (Opcode) { 350 case ARM::tLDRspi: 351 return ARM::tLDRi; 352 353 case ARM::tSTRspi: 354 return ARM::tSTRi; 355 } 356 357 return Opcode; 358 } 359 360 bool ThumbRegisterInfo::rewriteFrameIndex(MachineBasicBlock::iterator II, 361 unsigned FrameRegIdx, 362 Register FrameReg, int &Offset, 363 const ARMBaseInstrInfo &TII) const { 364 MachineInstr &MI = *II; 365 MachineBasicBlock &MBB = *MI.getParent(); 366 MachineFunction &MF = *MBB.getParent(); 367 assert(MBB.getParent()->getSubtarget<ARMSubtarget>().isThumb1Only() && 368 "This isn't needed for thumb2!"); 369 DebugLoc dl = MI.getDebugLoc(); 370 MachineInstrBuilder MIB(*MBB.getParent(), &MI); 371 unsigned Opcode = MI.getOpcode(); 372 const MCInstrDesc &Desc = MI.getDesc(); 373 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); 374 375 if (Opcode == ARM::tADDframe) { 376 Offset += MI.getOperand(FrameRegIdx+1).getImm(); 377 Register DestReg = MI.getOperand(0).getReg(); 378 379 emitThumbRegPlusImmediate(MBB, II, dl, DestReg, FrameReg, Offset, TII, 380 *this); 381 MBB.erase(II); 382 return true; 383 } else { 384 if (AddrMode != ARMII::AddrModeT1_s) 385 llvm_unreachable("Unsupported addressing mode!"); 386 387 unsigned ImmIdx = FrameRegIdx + 1; 388 int InstrOffs = MI.getOperand(ImmIdx).getImm(); 389 unsigned NumBits = (FrameReg == ARM::SP) ? 8 : 5; 390 unsigned Scale = 4; 391 392 Offset += InstrOffs * Scale; 393 assert((Offset & (Scale - 1)) == 0 && "Can't encode this offset!"); 394 395 // Common case: small offset, fits into instruction. 396 MachineOperand &ImmOp = MI.getOperand(ImmIdx); 397 int ImmedOffset = Offset / Scale; 398 unsigned Mask = (1 << NumBits) - 1; 399 400 if ((unsigned)Offset <= Mask * Scale) { 401 // Replace the FrameIndex with the frame register (e.g., sp). 402 Register DestReg = FrameReg; 403 404 // In case FrameReg is a high register, move it to a low reg to ensure it 405 // can be used as an operand. 406 if (ARM::hGPRRegClass.contains(FrameReg) && FrameReg != ARM::SP) { 407 DestReg = MF.getRegInfo().createVirtualRegister(&ARM::tGPRRegClass); 408 BuildMI(MBB, II, dl, TII.get(ARM::tMOVr), DestReg) 409 .addReg(FrameReg) 410 .add(predOps(ARMCC::AL)); 411 } 412 413 MI.getOperand(FrameRegIdx).ChangeToRegister(DestReg, false); 414 ImmOp.ChangeToImmediate(ImmedOffset); 415 416 // If we're using a register where sp was stored, convert the instruction 417 // to the non-SP version. 418 unsigned NewOpc = convertToNonSPOpcode(Opcode); 419 if (NewOpc != Opcode && FrameReg != ARM::SP) 420 MI.setDesc(TII.get(NewOpc)); 421 422 return true; 423 } 424 425 NumBits = 5; 426 Mask = (1 << NumBits) - 1; 427 428 // If this is a thumb spill / restore, we will be using a constpool load to 429 // materialize the offset. 430 if (Opcode == ARM::tLDRspi || Opcode == ARM::tSTRspi) { 431 ImmOp.ChangeToImmediate(0); 432 } else { 433 // Otherwise, it didn't fit. Pull in what we can to simplify the immed. 434 ImmedOffset = ImmedOffset & Mask; 435 ImmOp.ChangeToImmediate(ImmedOffset); 436 Offset &= ~(Mask * Scale); 437 } 438 } 439 440 return Offset == 0; 441 } 442 443 void ThumbRegisterInfo::resolveFrameIndex(MachineInstr &MI, Register BaseReg, 444 int64_t Offset) const { 445 const MachineFunction &MF = *MI.getParent()->getParent(); 446 const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>(); 447 if (!STI.isThumb1Only()) 448 return ARMBaseRegisterInfo::resolveFrameIndex(MI, BaseReg, Offset); 449 450 const ARMBaseInstrInfo &TII = *STI.getInstrInfo(); 451 int Off = Offset; // ARM doesn't need the general 64-bit offsets 452 unsigned i = 0; 453 454 while (!MI.getOperand(i).isFI()) { 455 ++i; 456 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 457 } 458 bool Done = rewriteFrameIndex(MI, i, BaseReg, Off, TII); 459 assert (Done && "Unable to resolve frame index!"); 460 (void)Done; 461 } 462 463 bool ThumbRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 464 int SPAdj, unsigned FIOperandNum, 465 RegScavenger *RS) const { 466 MachineInstr &MI = *II; 467 MachineBasicBlock &MBB = *MI.getParent(); 468 MachineFunction &MF = *MBB.getParent(); 469 const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>(); 470 if (!STI.isThumb1Only()) 471 return ARMBaseRegisterInfo::eliminateFrameIndex(II, SPAdj, FIOperandNum, 472 RS); 473 474 Register VReg; 475 const ARMBaseInstrInfo &TII = *STI.getInstrInfo(); 476 DebugLoc dl = MI.getDebugLoc(); 477 MachineInstrBuilder MIB(*MBB.getParent(), &MI); 478 479 Register FrameReg; 480 int FrameIndex = MI.getOperand(FIOperandNum).getIndex(); 481 const ARMFrameLowering *TFI = getFrameLowering(MF); 482 int Offset = TFI->ResolveFrameIndexReference(MF, FrameIndex, FrameReg, SPAdj); 483 484 // PEI::scavengeFrameVirtualRegs() cannot accurately track SPAdj because the 485 // call frame setup/destroy instructions have already been eliminated. That 486 // means the stack pointer cannot be used to access the emergency spill slot 487 // when !hasReservedCallFrame(). 488 #ifndef NDEBUG 489 if (RS && FrameReg == ARM::SP && RS->isScavengingFrameIndex(FrameIndex)){ 490 assert(STI.getFrameLowering()->hasReservedCallFrame(MF) && 491 "Cannot use SP to access the emergency spill slot in " 492 "functions without a reserved call frame"); 493 assert(!MF.getFrameInfo().hasVarSizedObjects() && 494 "Cannot use SP to access the emergency spill slot in " 495 "functions with variable sized frame objects"); 496 } 497 #endif // NDEBUG 498 499 // Special handling of dbg_value instructions. 500 if (MI.isDebugValue()) { 501 MI.getOperand(FIOperandNum). ChangeToRegister(FrameReg, false /*isDef*/); 502 MI.getOperand(FIOperandNum+1).ChangeToImmediate(Offset); 503 return false; 504 } 505 506 // Modify MI as necessary to handle as much of 'Offset' as possible 507 assert(MF.getInfo<ARMFunctionInfo>()->isThumbFunction() && 508 "This eliminateFrameIndex only supports Thumb1!"); 509 if (rewriteFrameIndex(MI, FIOperandNum, FrameReg, Offset, TII)) 510 return true; 511 512 // If we get here, the immediate doesn't fit into the instruction. We folded 513 // as much as possible above, handle the rest, providing a register that is 514 // SP+LargeImm. 515 assert(Offset && "This code isn't needed if offset already handled!"); 516 517 unsigned Opcode = MI.getOpcode(); 518 519 // Remove predicate first. 520 int PIdx = MI.findFirstPredOperandIdx(); 521 if (PIdx != -1) 522 removeOperands(MI, PIdx); 523 524 if (MI.mayLoad()) { 525 // Use the destination register to materialize sp + offset. 526 Register TmpReg = MI.getOperand(0).getReg(); 527 bool UseRR = false; 528 if (Opcode == ARM::tLDRspi) { 529 if (FrameReg == ARM::SP || STI.genExecuteOnly()) 530 emitThumbRegPlusImmInReg(MBB, II, dl, TmpReg, FrameReg, 531 Offset, false, TII, *this); 532 else { 533 emitLoadConstPool(MBB, II, dl, TmpReg, 0, Offset); 534 if (!ARM::hGPRRegClass.contains(FrameReg)) { 535 UseRR = true; 536 } else { 537 // If FrameReg is a high register, add the reg values in a separate 538 // instruction as the load won't be able to access it. 539 BuildMI(MBB, II, dl, TII.get(ARM::tADDhirr), TmpReg) 540 .addReg(TmpReg) 541 .addReg(FrameReg) 542 .add(predOps(ARMCC::AL)); 543 } 544 } 545 } else { 546 emitThumbRegPlusImmediate(MBB, II, dl, TmpReg, FrameReg, Offset, TII, 547 *this); 548 } 549 550 MI.setDesc(TII.get(UseRR ? ARM::tLDRr : ARM::tLDRi)); 551 MI.getOperand(FIOperandNum).ChangeToRegister(TmpReg, false, false, true); 552 if (UseRR) { 553 assert(!ARM::hGPRRegClass.contains(FrameReg) && 554 "Thumb1 loads can't use high register"); 555 // Use [reg, reg] addrmode. Replace the immediate operand w/ the frame 556 // register. The offset is already handled in the vreg value. 557 MI.getOperand(FIOperandNum+1).ChangeToRegister(FrameReg, false, false, 558 false); 559 } 560 } else if (MI.mayStore()) { 561 VReg = MF.getRegInfo().createVirtualRegister(&ARM::tGPRRegClass); 562 bool UseRR = false; 563 564 if (Opcode == ARM::tSTRspi) { 565 if (FrameReg == ARM::SP || STI.genExecuteOnly()) 566 emitThumbRegPlusImmInReg(MBB, II, dl, VReg, FrameReg, 567 Offset, false, TII, *this); 568 else { 569 emitLoadConstPool(MBB, II, dl, VReg, 0, Offset); 570 if (!ARM::hGPRRegClass.contains(FrameReg)) { 571 UseRR = true; 572 } else { 573 // If FrameReg is a high register, add the reg values in a separate 574 // instruction as the load won't be able to access it. 575 BuildMI(MBB, II, dl, TII.get(ARM::tADDhirr), VReg) 576 .addReg(VReg) 577 .addReg(FrameReg) 578 .add(predOps(ARMCC::AL)); 579 } 580 } 581 } else 582 emitThumbRegPlusImmediate(MBB, II, dl, VReg, FrameReg, Offset, TII, 583 *this); 584 MI.setDesc(TII.get(UseRR ? ARM::tSTRr : ARM::tSTRi)); 585 MI.getOperand(FIOperandNum).ChangeToRegister(VReg, false, false, true); 586 if (UseRR) { 587 assert(!ARM::hGPRRegClass.contains(FrameReg) && 588 "Thumb1 stores can't use high register"); 589 // Use [reg, reg] addrmode. Replace the immediate operand w/ the frame 590 // register. The offset is already handled in the vreg value. 591 MI.getOperand(FIOperandNum+1).ChangeToRegister(FrameReg, false, false, 592 false); 593 } 594 } else { 595 llvm_unreachable("Unexpected opcode!"); 596 } 597 598 // Add predicate back if it's needed. 599 if (MI.isPredicable()) 600 MIB.add(predOps(ARMCC::AL)); 601 return false; 602 } 603 604 bool 605 ThumbRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const { 606 if (MF.getSubtarget<ARMSubtarget>().isThumb1Only()) { 607 // For Thumb1, the emergency spill slot must be some small positive 608 // offset from the base/stack pointer. 609 return false; 610 } 611 // For Thumb2, put the emergency spill slot next to FP. 612 return true; 613 } 614