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