1 //===- Thumb1RegisterInfo.cpp - Thumb-1 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-1 implementation of the TargetRegisterInfo 11 // class. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "ARM.h" 16 #include "ARMAddressingModes.h" 17 #include "ARMBaseInstrInfo.h" 18 #include "ARMMachineFunctionInfo.h" 19 #include "ARMSubtarget.h" 20 #include "Thumb1InstrInfo.h" 21 #include "Thumb1RegisterInfo.h" 22 #include "llvm/Constants.h" 23 #include "llvm/DerivedTypes.h" 24 #include "llvm/Function.h" 25 #include "llvm/LLVMContext.h" 26 #include "llvm/CodeGen/MachineConstantPool.h" 27 #include "llvm/CodeGen/MachineFrameInfo.h" 28 #include "llvm/CodeGen/MachineFunction.h" 29 #include "llvm/CodeGen/MachineInstrBuilder.h" 30 #include "llvm/CodeGen/MachineRegisterInfo.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 bool NeedPred = false; 185 186 if (DestReg == BaseReg && BaseReg == ARM::SP) { 187 assert(isMul4 && "Thumb sp inc / dec size must be multiple of 4!"); 188 NumBits = 7; 189 Scale = 4; 190 Opc = isSub ? ARM::tSUBspi : ARM::tADDspi; 191 isTwoAddr = true; 192 } else if (!isSub && BaseReg == ARM::SP) { 193 // r1 = add sp, 403 194 // => 195 // r1 = add sp, 100 * 4 196 // r1 = add r1, 3 197 if (!isMul4) { 198 Bytes &= ~3; 199 ExtraOpc = ARM::tADDi3; 200 } 201 NumBits = 8; 202 Scale = 4; 203 Opc = ARM::tADDrSPi; 204 } else { 205 // sp = sub sp, c 206 // r1 = sub sp, c 207 // r8 = sub sp, c 208 if (DestReg != BaseReg) 209 DstNotEqBase = true; 210 NumBits = 8; 211 if (DestReg == ARM::SP) { 212 Opc = isSub ? ARM::tSUBspi : ARM::tADDspi; 213 assert(isMul4 && "Thumb sp inc / dec size must be multiple of 4!"); 214 NumBits = 7; 215 Scale = 4; 216 } else { 217 Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8; 218 NumBits = 8; 219 NeedPred = NeedCC = true; 220 } 221 isTwoAddr = true; 222 } 223 224 unsigned NumMIs = calcNumMI(Opc, ExtraOpc, Bytes, NumBits, Scale); 225 unsigned Threshold = (DestReg == ARM::SP) ? 3 : 2; 226 if (NumMIs > Threshold) { 227 // This will expand into too many instructions. Load the immediate from a 228 // constpool entry. 229 emitThumbRegPlusImmInReg(MBB, MBBI, dl, 230 DestReg, BaseReg, NumBytes, true, 231 TII, MRI, MIFlags); 232 return; 233 } 234 235 if (DstNotEqBase) { 236 if (isARMLowRegister(DestReg) && isARMLowRegister(BaseReg)) { 237 // If both are low registers, emit DestReg = add BaseReg, max(Imm, 7) 238 unsigned Chunk = (1 << 3) - 1; 239 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes; 240 Bytes -= ThisVal; 241 const MCInstrDesc &MCID = TII.get(isSub ? ARM::tSUBi3 : ARM::tADDi3); 242 const MachineInstrBuilder MIB = 243 AddDefaultT1CC(BuildMI(MBB, MBBI, dl, MCID, DestReg).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 if (NeedPred) 265 MIB = AddDefaultPred(MIB); 266 MIB.setMIFlags(MIFlags); 267 } 268 else { 269 bool isKill = BaseReg != ARM::SP; 270 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg); 271 if (NeedCC) 272 MIB = AddDefaultT1CC(MIB); 273 MIB.addReg(BaseReg, getKillRegState(isKill)).addImm(ThisVal); 274 if (NeedPred) 275 MIB = AddDefaultPred(MIB); 276 MIB.setMIFlags(MIFlags); 277 278 BaseReg = DestReg; 279 if (Opc == ARM::tADDrSPi) { 280 // r4 = add sp, imm 281 // r4 = add r4, imm 282 // ... 283 NumBits = 8; 284 Scale = 1; 285 Chunk = ((1 << NumBits) - 1) * Scale; 286 Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8; 287 NeedPred = NeedCC = isTwoAddr = true; 288 } 289 } 290 } 291 292 if (ExtraOpc) { 293 const MCInstrDesc &MCID = TII.get(ExtraOpc); 294 AddDefaultPred(AddDefaultT1CC(BuildMI(MBB, MBBI, dl, MCID, DestReg)) 295 .addReg(DestReg, RegState::Kill) 296 .addImm(((unsigned)NumBytes) & 3) 297 .setMIFlags(MIFlags)); 298 } 299 } 300 301 static void emitSPUpdate(MachineBasicBlock &MBB, 302 MachineBasicBlock::iterator &MBBI, 303 const TargetInstrInfo &TII, DebugLoc dl, 304 const Thumb1RegisterInfo &MRI, 305 int NumBytes) { 306 emitThumbRegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes, TII, 307 MRI); 308 } 309 310 void Thumb1RegisterInfo:: 311 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 312 MachineBasicBlock::iterator I) const { 313 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 314 315 if (!TFI->hasReservedCallFrame(MF)) { 316 // If we have alloca, convert as follows: 317 // ADJCALLSTACKDOWN -> sub, sp, sp, amount 318 // ADJCALLSTACKUP -> add, sp, sp, amount 319 MachineInstr *Old = I; 320 DebugLoc dl = Old->getDebugLoc(); 321 unsigned Amount = Old->getOperand(0).getImm(); 322 if (Amount != 0) { 323 // We need to keep the stack aligned properly. To do this, we round the 324 // amount of space needed for the outgoing arguments up to the next 325 // alignment boundary. 326 unsigned Align = TFI->getStackAlignment(); 327 Amount = (Amount+Align-1)/Align*Align; 328 329 // Replace the pseudo instruction with a new instruction... 330 unsigned Opc = Old->getOpcode(); 331 if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) { 332 emitSPUpdate(MBB, I, TII, dl, *this, -Amount); 333 } else { 334 assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP); 335 emitSPUpdate(MBB, I, TII, dl, *this, Amount); 336 } 337 } 338 } 339 MBB.erase(I); 340 } 341 342 /// emitThumbConstant - Emit a series of instructions to materialize a 343 /// constant. 344 static void emitThumbConstant(MachineBasicBlock &MBB, 345 MachineBasicBlock::iterator &MBBI, 346 unsigned DestReg, int Imm, 347 const TargetInstrInfo &TII, 348 const Thumb1RegisterInfo& MRI, 349 DebugLoc dl) { 350 bool isSub = Imm < 0; 351 if (isSub) Imm = -Imm; 352 353 int Chunk = (1 << 8) - 1; 354 int ThisVal = (Imm > Chunk) ? Chunk : Imm; 355 Imm -= ThisVal; 356 AddDefaultPred(AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), 357 DestReg)) 358 .addImm(ThisVal)); 359 if (Imm > 0) 360 emitThumbRegPlusImmediate(MBB, MBBI, dl, DestReg, DestReg, Imm, TII, MRI); 361 if (isSub) { 362 const MCInstrDesc &MCID = TII.get(ARM::tRSB); 363 AddDefaultPred(AddDefaultT1CC(BuildMI(MBB, MBBI, dl, MCID, DestReg)) 364 .addReg(DestReg, RegState::Kill)); 365 } 366 } 367 368 static void removeOperands(MachineInstr &MI, unsigned i) { 369 unsigned Op = i; 370 for (unsigned e = MI.getNumOperands(); i != e; ++i) 371 MI.RemoveOperand(Op); 372 } 373 374 /// convertToNonSPOpcode - Change the opcode to the non-SP version, because 375 /// we're replacing the frame index with a non-SP register. 376 static unsigned convertToNonSPOpcode(unsigned Opcode) { 377 switch (Opcode) { 378 case ARM::tLDRspi: 379 return ARM::tLDRi; 380 381 case ARM::tSTRspi: 382 return ARM::tSTRi; 383 } 384 385 return Opcode; 386 } 387 388 bool Thumb1RegisterInfo:: 389 rewriteFrameIndex(MachineBasicBlock::iterator II, unsigned FrameRegIdx, 390 unsigned FrameReg, int &Offset, 391 const ARMBaseInstrInfo &TII) const { 392 MachineInstr &MI = *II; 393 MachineBasicBlock &MBB = *MI.getParent(); 394 DebugLoc dl = MI.getDebugLoc(); 395 unsigned Opcode = MI.getOpcode(); 396 const MCInstrDesc &Desc = MI.getDesc(); 397 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); 398 399 if (Opcode == ARM::tADDrSPi) { 400 Offset += MI.getOperand(FrameRegIdx+1).getImm(); 401 402 // Can't use tADDrSPi if it's based off the frame pointer. 403 unsigned NumBits = 0; 404 unsigned Scale = 1; 405 if (FrameReg != ARM::SP) { 406 Opcode = ARM::tADDi3; 407 MI.setDesc(TII.get(Opcode)); 408 NumBits = 3; 409 } else { 410 NumBits = 8; 411 Scale = 4; 412 assert((Offset & 3) == 0 && 413 "Thumb add/sub sp, #imm immediate must be multiple of 4!"); 414 } 415 416 unsigned PredReg; 417 if (Offset == 0 && getInstrPredicate(&MI, PredReg) == ARMCC::AL) { 418 // Turn it into a move. 419 MI.setDesc(TII.get(ARM::tMOVr)); 420 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 421 // Remove offset and add predicate operands. 422 MI.RemoveOperand(FrameRegIdx+1); 423 MachineInstrBuilder MIB(&MI); 424 AddDefaultPred(MIB); 425 return true; 426 } 427 428 // Common case: small offset, fits into instruction. 429 unsigned Mask = (1 << NumBits) - 1; 430 if (((Offset / Scale) & ~Mask) == 0) { 431 // Replace the FrameIndex with sp / fp 432 if (Opcode == ARM::tADDi3) { 433 removeOperands(MI, FrameRegIdx); 434 MachineInstrBuilder MIB(&MI); 435 AddDefaultPred(AddDefaultT1CC(MIB).addReg(FrameReg) 436 .addImm(Offset / Scale)); 437 } else { 438 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 439 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset / Scale); 440 } 441 return true; 442 } 443 444 unsigned DestReg = MI.getOperand(0).getReg(); 445 unsigned Bytes = (Offset > 0) ? Offset : -Offset; 446 unsigned NumMIs = calcNumMI(Opcode, 0, Bytes, NumBits, Scale); 447 // MI would expand into a large number of instructions. Don't try to 448 // simplify the immediate. 449 if (NumMIs > 2) { 450 emitThumbRegPlusImmediate(MBB, II, dl, DestReg, FrameReg, Offset, TII, 451 *this); 452 MBB.erase(II); 453 return true; 454 } 455 456 if (Offset > 0) { 457 // Translate r0 = add sp, imm to 458 // r0 = add sp, 255*4 459 // r0 = add r0, (imm - 255*4) 460 if (Opcode == ARM::tADDi3) { 461 removeOperands(MI, FrameRegIdx); 462 MachineInstrBuilder MIB(&MI); 463 AddDefaultPred(AddDefaultT1CC(MIB).addReg(FrameReg).addImm(Mask)); 464 } else { 465 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 466 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Mask); 467 } 468 Offset = (Offset - Mask * Scale); 469 MachineBasicBlock::iterator NII = llvm::next(II); 470 emitThumbRegPlusImmediate(MBB, NII, dl, DestReg, DestReg, Offset, TII, 471 *this); 472 } else { 473 // Translate r0 = add sp, -imm to 474 // r0 = -imm (this is then translated into a series of instructons) 475 // r0 = add r0, sp 476 emitThumbConstant(MBB, II, DestReg, Offset, TII, *this, dl); 477 478 MI.setDesc(TII.get(ARM::tADDhirr)); 479 MI.getOperand(FrameRegIdx).ChangeToRegister(DestReg, false, false, true); 480 MI.getOperand(FrameRegIdx+1).ChangeToRegister(FrameReg, false); 481 if (Opcode == ARM::tADDi3) { 482 MachineInstrBuilder MIB(&MI); 483 AddDefaultPred(MIB); 484 } 485 } 486 return true; 487 } else { 488 if (AddrMode != ARMII::AddrModeT1_s) 489 llvm_unreachable("Unsupported addressing mode!"); 490 491 unsigned ImmIdx = FrameRegIdx + 1; 492 int InstrOffs = MI.getOperand(ImmIdx).getImm(); 493 unsigned NumBits = (FrameReg == ARM::SP) ? 8 : 5; 494 unsigned Scale = 4; 495 496 Offset += InstrOffs * Scale; 497 assert((Offset & (Scale - 1)) == 0 && "Can't encode this offset!"); 498 499 // Common case: small offset, fits into instruction. 500 MachineOperand &ImmOp = MI.getOperand(ImmIdx); 501 int ImmedOffset = Offset / Scale; 502 unsigned Mask = (1 << NumBits) - 1; 503 504 if ((unsigned)Offset <= Mask * Scale) { 505 // Replace the FrameIndex with the frame register (e.g., sp). 506 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 507 ImmOp.ChangeToImmediate(ImmedOffset); 508 509 // If we're using a register where sp was stored, convert the instruction 510 // to the non-SP version. 511 unsigned NewOpc = convertToNonSPOpcode(Opcode); 512 if (NewOpc != Opcode && FrameReg != ARM::SP) 513 MI.setDesc(TII.get(NewOpc)); 514 515 return true; 516 } 517 518 NumBits = 5; 519 Mask = (1 << NumBits) - 1; 520 521 // If this is a thumb spill / restore, we will be using a constpool load to 522 // materialize the offset. 523 if (Opcode == ARM::tLDRspi || Opcode == ARM::tSTRspi) { 524 ImmOp.ChangeToImmediate(0); 525 } else { 526 // Otherwise, it didn't fit. Pull in what we can to simplify the immed. 527 ImmedOffset = ImmedOffset & Mask; 528 ImmOp.ChangeToImmediate(ImmedOffset); 529 Offset &= ~(Mask * Scale); 530 } 531 } 532 533 return Offset == 0; 534 } 535 536 void 537 Thumb1RegisterInfo::resolveFrameIndex(MachineBasicBlock::iterator I, 538 unsigned BaseReg, int64_t Offset) const { 539 MachineInstr &MI = *I; 540 int Off = Offset; // ARM doesn't need the general 64-bit offsets 541 unsigned i = 0; 542 543 while (!MI.getOperand(i).isFI()) { 544 ++i; 545 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 546 } 547 bool Done = false; 548 Done = rewriteFrameIndex(MI, i, BaseReg, Off, TII); 549 assert (Done && "Unable to resolve frame index!"); 550 } 551 552 /// saveScavengerRegister - Spill the register so it can be used by the 553 /// register scavenger. Return true. 554 bool 555 Thumb1RegisterInfo::saveScavengerRegister(MachineBasicBlock &MBB, 556 MachineBasicBlock::iterator I, 557 MachineBasicBlock::iterator &UseMI, 558 const TargetRegisterClass *RC, 559 unsigned Reg) const { 560 // Thumb1 can't use the emergency spill slot on the stack because 561 // ldr/str immediate offsets must be positive, and if we're referencing 562 // off the frame pointer (if, for example, there are alloca() calls in 563 // the function, the offset will be negative. Use R12 instead since that's 564 // a call clobbered register that we know won't be used in Thumb1 mode. 565 DebugLoc DL; 566 AddDefaultPred(BuildMI(MBB, I, DL, TII.get(ARM::tMOVr)) 567 .addReg(ARM::R12, RegState::Define) 568 .addReg(Reg, RegState::Kill)); 569 570 // The UseMI is where we would like to restore the register. If there's 571 // interference with R12 before then, however, we'll need to restore it 572 // before that instead and adjust the UseMI. 573 bool done = false; 574 for (MachineBasicBlock::iterator II = I; !done && II != UseMI ; ++II) { 575 if (II->isDebugValue()) 576 continue; 577 // If this instruction affects R12, adjust our restore point. 578 for (unsigned i = 0, e = II->getNumOperands(); i != e; ++i) { 579 const MachineOperand &MO = II->getOperand(i); 580 if (!MO.isReg() || MO.isUndef() || !MO.getReg() || 581 TargetRegisterInfo::isVirtualRegister(MO.getReg())) 582 continue; 583 if (MO.getReg() == ARM::R12) { 584 UseMI = II; 585 done = true; 586 break; 587 } 588 } 589 } 590 // Restore the register from R12 591 AddDefaultPred(BuildMI(MBB, UseMI, DL, TII.get(ARM::tMOVr)). 592 addReg(Reg, RegState::Define).addReg(ARM::R12, RegState::Kill)); 593 594 return true; 595 } 596 597 void 598 Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 599 int SPAdj, RegScavenger *RS) const { 600 unsigned VReg = 0; 601 unsigned i = 0; 602 MachineInstr &MI = *II; 603 MachineBasicBlock &MBB = *MI.getParent(); 604 MachineFunction &MF = *MBB.getParent(); 605 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 606 DebugLoc dl = MI.getDebugLoc(); 607 608 while (!MI.getOperand(i).isFI()) { 609 ++i; 610 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 611 } 612 613 unsigned FrameReg = ARM::SP; 614 int FrameIndex = MI.getOperand(i).getIndex(); 615 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) + 616 MF.getFrameInfo()->getStackSize() + SPAdj; 617 618 if (AFI->isGPRCalleeSavedArea1Frame(FrameIndex)) 619 Offset -= AFI->getGPRCalleeSavedArea1Offset(); 620 else if (AFI->isGPRCalleeSavedArea2Frame(FrameIndex)) 621 Offset -= AFI->getGPRCalleeSavedArea2Offset(); 622 else if (MF.getFrameInfo()->hasVarSizedObjects()) { 623 assert(SPAdj == 0 && MF.getTarget().getFrameLowering()->hasFP(MF) && 624 "Unexpected"); 625 // There are alloca()'s in this function, must reference off the frame 626 // pointer or base pointer instead. 627 if (!hasBasePointer(MF)) { 628 FrameReg = getFrameRegister(MF); 629 Offset -= AFI->getFramePtrSpillOffset(); 630 } else 631 FrameReg = BasePtr; 632 } 633 634 // Special handling of dbg_value instructions. 635 if (MI.isDebugValue()) { 636 MI.getOperand(i). ChangeToRegister(FrameReg, false /*isDef*/); 637 MI.getOperand(i+1).ChangeToImmediate(Offset); 638 return; 639 } 640 641 // Modify MI as necessary to handle as much of 'Offset' as possible 642 assert(AFI->isThumbFunction() && 643 "This eliminateFrameIndex only supports Thumb1!"); 644 if (rewriteFrameIndex(MI, i, FrameReg, Offset, TII)) 645 return; 646 647 // If we get here, the immediate doesn't fit into the instruction. We folded 648 // as much as possible above, handle the rest, providing a register that is 649 // SP+LargeImm. 650 assert(Offset && "This code isn't needed if offset already handled!"); 651 652 unsigned Opcode = MI.getOpcode(); 653 const MCInstrDesc &Desc = MI.getDesc(); 654 655 // Remove predicate first. 656 int PIdx = MI.findFirstPredOperandIdx(); 657 if (PIdx != -1) 658 removeOperands(MI, PIdx); 659 660 if (Desc.mayLoad()) { 661 // Use the destination register to materialize sp + offset. 662 unsigned TmpReg = MI.getOperand(0).getReg(); 663 bool UseRR = false; 664 if (Opcode == ARM::tLDRspi) { 665 if (FrameReg == ARM::SP) 666 emitThumbRegPlusImmInReg(MBB, II, dl, TmpReg, FrameReg, 667 Offset, false, TII, *this); 668 else { 669 emitLoadConstPool(MBB, II, dl, TmpReg, 0, Offset); 670 UseRR = true; 671 } 672 } else { 673 emitThumbRegPlusImmediate(MBB, II, dl, TmpReg, FrameReg, Offset, TII, 674 *this); 675 } 676 677 MI.setDesc(TII.get(UseRR ? ARM::tLDRr : ARM::tLDRi)); 678 MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true); 679 if (UseRR) 680 // Use [reg, reg] addrmode. Replace the immediate operand w/ the frame 681 // register. The offset is already handled in the vreg value. 682 MI.getOperand(i+1).ChangeToRegister(FrameReg, false, false, false); 683 } else if (Desc.mayStore()) { 684 VReg = MF.getRegInfo().createVirtualRegister(ARM::tGPRRegisterClass); 685 bool UseRR = false; 686 687 if (Opcode == ARM::tSTRspi) { 688 if (FrameReg == ARM::SP) 689 emitThumbRegPlusImmInReg(MBB, II, dl, VReg, FrameReg, 690 Offset, false, TII, *this); 691 else { 692 emitLoadConstPool(MBB, II, dl, VReg, 0, Offset); 693 UseRR = true; 694 } 695 } else 696 emitThumbRegPlusImmediate(MBB, II, dl, VReg, FrameReg, Offset, TII, 697 *this); 698 MI.setDesc(TII.get(UseRR ? ARM::tSTRr : ARM::tSTRi)); 699 MI.getOperand(i).ChangeToRegister(VReg, false, false, true); 700 if (UseRR) 701 // Use [reg, reg] addrmode. Replace the immediate operand w/ the frame 702 // register. The offset is already handled in the vreg value. 703 MI.getOperand(i+1).ChangeToRegister(FrameReg, false, false, false); 704 } else { 705 assert(false && "Unexpected opcode!"); 706 } 707 708 // Add predicate back if it's needed. 709 if (MI.getDesc().isPredicable()) { 710 MachineInstrBuilder MIB(&MI); 711 AddDefaultPred(MIB); 712 } 713 } 714