Thumb1RegisterInfo.cpp revision d0c38176690e9602a93a20a43f1bd084564a8116
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::tLDRcp)) 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 354bool Thumb1RegisterInfo:: 355rewriteFrameIndex(MachineBasicBlock::iterator II, unsigned FrameRegIdx, 356 unsigned FrameReg, int &Offset, 357 const ARMBaseInstrInfo &TII) const { 358 MachineInstr &MI = *II; 359 MachineBasicBlock &MBB = *MI.getParent(); 360 DebugLoc dl = MI.getDebugLoc(); 361 unsigned Opcode = MI.getOpcode(); 362 const TargetInstrDesc &Desc = MI.getDesc(); 363 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); 364 365 if (Opcode == ARM::tADDrSPi) { 366 Offset += MI.getOperand(FrameRegIdx+1).getImm(); 367 368 // Can't use tADDrSPi if it's based off the frame pointer. 369 unsigned NumBits = 0; 370 unsigned Scale = 1; 371 if (FrameReg != ARM::SP) { 372 Opcode = ARM::tADDi3; 373 MI.setDesc(TII.get(Opcode)); 374 NumBits = 3; 375 } else { 376 NumBits = 8; 377 Scale = 4; 378 assert((Offset & 3) == 0 && 379 "Thumb add/sub sp, #imm immediate must be multiple of 4!"); 380 } 381 382 unsigned PredReg; 383 if (Offset == 0 && getInstrPredicate(&MI, PredReg) == ARMCC::AL) { 384 // Turn it into a move. 385 MI.setDesc(TII.get(ARM::tMOVgpr2tgpr)); 386 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 387 // Remove offset and remaining explicit predicate operands. 388 do MI.RemoveOperand(FrameRegIdx+1); 389 while (MI.getNumOperands() > FrameRegIdx+1 && 390 (!MI.getOperand(FrameRegIdx+1).isReg() || 391 !MI.getOperand(FrameRegIdx+1).isImm())); 392 return true; 393 } 394 395 // Common case: small offset, fits into instruction. 396 unsigned Mask = (1 << NumBits) - 1; 397 if (((Offset / Scale) & ~Mask) == 0) { 398 // Replace the FrameIndex with sp / fp 399 if (Opcode == ARM::tADDi3) { 400 removeOperands(MI, FrameRegIdx); 401 MachineInstrBuilder MIB(&MI); 402 AddDefaultPred(AddDefaultT1CC(MIB).addReg(FrameReg) 403 .addImm(Offset / Scale)); 404 } else { 405 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 406 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset / Scale); 407 } 408 return true; 409 } 410 411 unsigned DestReg = MI.getOperand(0).getReg(); 412 unsigned Bytes = (Offset > 0) ? Offset : -Offset; 413 unsigned NumMIs = calcNumMI(Opcode, 0, Bytes, NumBits, Scale); 414 // MI would expand into a large number of instructions. Don't try to 415 // simplify the immediate. 416 if (NumMIs > 2) { 417 emitThumbRegPlusImmediate(MBB, II, DestReg, FrameReg, Offset, TII, 418 *this, dl); 419 MBB.erase(II); 420 return true; 421 } 422 423 if (Offset > 0) { 424 // Translate r0 = add sp, imm to 425 // r0 = add sp, 255*4 426 // r0 = add r0, (imm - 255*4) 427 if (Opcode == ARM::tADDi3) { 428 removeOperands(MI, FrameRegIdx); 429 MachineInstrBuilder MIB(&MI); 430 AddDefaultPred(AddDefaultT1CC(MIB).addReg(FrameReg).addImm(Mask)); 431 } else { 432 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 433 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Mask); 434 } 435 Offset = (Offset - Mask * Scale); 436 MachineBasicBlock::iterator NII = llvm::next(II); 437 emitThumbRegPlusImmediate(MBB, NII, DestReg, DestReg, Offset, TII, 438 *this, dl); 439 } else { 440 // Translate r0 = add sp, -imm to 441 // r0 = -imm (this is then translated into a series of instructons) 442 // r0 = add r0, sp 443 emitThumbConstant(MBB, II, DestReg, Offset, TII, *this, dl); 444 445 MI.setDesc(TII.get(ARM::tADDhirr)); 446 MI.getOperand(FrameRegIdx).ChangeToRegister(DestReg, false, false, true); 447 MI.getOperand(FrameRegIdx+1).ChangeToRegister(FrameReg, false); 448 if (Opcode == ARM::tADDi3) { 449 MachineInstrBuilder MIB(&MI); 450 AddDefaultPred(MIB); 451 } 452 } 453 return true; 454 } else { 455 unsigned ImmIdx = 0; 456 int InstrOffs = 0; 457 unsigned NumBits = 0; 458 unsigned Scale = 1; 459 switch (AddrMode) { 460 case ARMII::AddrModeT1_s: { 461 ImmIdx = FrameRegIdx+1; 462 InstrOffs = MI.getOperand(ImmIdx).getImm(); 463 NumBits = (FrameReg == ARM::SP) ? 8 : 5; 464 Scale = 4; 465 break; 466 } 467 default: 468 llvm_unreachable("Unsupported addressing mode!"); 469 break; 470 } 471 472 Offset += InstrOffs * Scale; 473 assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!"); 474 475 // Common case: small offset, fits into instruction. 476 MachineOperand &ImmOp = MI.getOperand(ImmIdx); 477 int ImmedOffset = Offset / Scale; 478 unsigned Mask = (1 << NumBits) - 1; 479 if ((unsigned)Offset <= Mask * Scale) { 480 // Replace the FrameIndex with sp 481 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 482 ImmOp.ChangeToImmediate(ImmedOffset); 483 return true; 484 } 485 486 bool isThumSpillRestore = Opcode == ARM::tRestore || Opcode == ARM::tSpill; 487 if (AddrMode == ARMII::AddrModeT1_s) { 488 // Thumb tLDRspi, tSTRspi. These will change to instructions that use 489 // a different base register. 490 NumBits = 5; 491 Mask = (1 << NumBits) - 1; 492 } 493 // If this is a thumb spill / restore, we will be using a constpool load to 494 // materialize the offset. 495 if (AddrMode == ARMII::AddrModeT1_s && isThumSpillRestore) 496 ImmOp.ChangeToImmediate(0); 497 else { 498 // Otherwise, it didn't fit. Pull in what we can to simplify the immed. 499 ImmedOffset = ImmedOffset & Mask; 500 ImmOp.ChangeToImmediate(ImmedOffset); 501 Offset &= ~(Mask*Scale); 502 } 503 } 504 return Offset == 0; 505} 506 507void 508Thumb1RegisterInfo::resolveFrameIndex(MachineBasicBlock::iterator I, 509 unsigned BaseReg, int64_t Offset) const { 510 MachineInstr &MI = *I; 511 int Off = Offset; // ARM doesn't need the general 64-bit offsets 512 unsigned i = 0; 513 514 while (!MI.getOperand(i).isFI()) { 515 ++i; 516 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 517 } 518 bool Done = false; 519 Done = rewriteFrameIndex(MI, i, BaseReg, Off, TII); 520 assert (Done && "Unable to resolve frame index!"); 521} 522 523/// saveScavengerRegister - Spill the register so it can be used by the 524/// register scavenger. Return true. 525bool 526Thumb1RegisterInfo::saveScavengerRegister(MachineBasicBlock &MBB, 527 MachineBasicBlock::iterator I, 528 MachineBasicBlock::iterator &UseMI, 529 const TargetRegisterClass *RC, 530 unsigned Reg) const { 531 // Thumb1 can't use the emergency spill slot on the stack because 532 // ldr/str immediate offsets must be positive, and if we're referencing 533 // off the frame pointer (if, for example, there are alloca() calls in 534 // the function, the offset will be negative. Use R12 instead since that's 535 // a call clobbered register that we know won't be used in Thumb1 mode. 536 DebugLoc DL; 537 BuildMI(MBB, I, DL, TII.get(ARM::tMOVtgpr2gpr)). 538 addReg(ARM::R12, RegState::Define).addReg(Reg, RegState::Kill); 539 540 // The UseMI is where we would like to restore the register. If there's 541 // interference with R12 before then, however, we'll need to restore it 542 // before that instead and adjust the UseMI. 543 bool done = false; 544 for (MachineBasicBlock::iterator II = I; !done && II != UseMI ; ++II) { 545 if (II->isDebugValue()) 546 continue; 547 // If this instruction affects R12, adjust our restore point. 548 for (unsigned i = 0, e = II->getNumOperands(); i != e; ++i) { 549 const MachineOperand &MO = II->getOperand(i); 550 if (!MO.isReg() || MO.isUndef() || !MO.getReg() || 551 TargetRegisterInfo::isVirtualRegister(MO.getReg())) 552 continue; 553 if (MO.getReg() == ARM::R12) { 554 UseMI = II; 555 done = true; 556 break; 557 } 558 } 559 } 560 // Restore the register from R12 561 BuildMI(MBB, UseMI, DL, TII.get(ARM::tMOVgpr2tgpr)). 562 addReg(Reg, RegState::Define).addReg(ARM::R12, RegState::Kill); 563 564 return true; 565} 566 567void 568Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 569 int SPAdj, RegScavenger *RS) const { 570 unsigned VReg = 0; 571 unsigned i = 0; 572 MachineInstr &MI = *II; 573 MachineBasicBlock &MBB = *MI.getParent(); 574 MachineFunction &MF = *MBB.getParent(); 575 const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo(); 576 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 577 DebugLoc dl = MI.getDebugLoc(); 578 579 while (!MI.getOperand(i).isFI()) { 580 ++i; 581 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 582 } 583 584 unsigned FrameReg = ARM::SP; 585 int FrameIndex = MI.getOperand(i).getIndex(); 586 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) + 587 MF.getFrameInfo()->getStackSize() + SPAdj; 588 589 if (AFI->isGPRCalleeSavedArea1Frame(FrameIndex)) 590 Offset -= AFI->getGPRCalleeSavedArea1Offset(); 591 else if (AFI->isGPRCalleeSavedArea2Frame(FrameIndex)) 592 Offset -= AFI->getGPRCalleeSavedArea2Offset(); 593 else if (MF.getFrameInfo()->hasVarSizedObjects()) { 594 assert(SPAdj == 0 && TFI->hasFP(MF) && "Unexpected"); 595 // There are alloca()'s in this function, must reference off the frame 596 // pointer or base pointer instead. 597 if (!hasBasePointer(MF)) { 598 FrameReg = getFrameRegister(MF); 599 Offset -= AFI->getFramePtrSpillOffset(); 600 } else 601 FrameReg = BasePtr; 602 } 603 604 // Special handling of dbg_value instructions. 605 if (MI.isDebugValue()) { 606 MI.getOperand(i). ChangeToRegister(FrameReg, false /*isDef*/); 607 MI.getOperand(i+1).ChangeToImmediate(Offset); 608 return; 609 } 610 611 // Modify MI as necessary to handle as much of 'Offset' as possible 612 assert(AFI->isThumbFunction() && 613 "This eliminateFrameIndex only supports Thumb1!"); 614 if (rewriteFrameIndex(MI, i, FrameReg, Offset, TII)) 615 return; 616 617 // If we get here, the immediate doesn't fit into the instruction. We folded 618 // as much as possible above, handle the rest, providing a register that is 619 // SP+LargeImm. 620 assert(Offset && "This code isn't needed if offset already handled!"); 621 622 unsigned Opcode = MI.getOpcode(); 623 const TargetInstrDesc &Desc = MI.getDesc(); 624 625 // Remove predicate first. 626 int PIdx = MI.findFirstPredOperandIdx(); 627 if (PIdx != -1) 628 removeOperands(MI, PIdx); 629 630 if (Desc.mayLoad()) { 631 // Use the destination register to materialize sp + offset. 632 unsigned TmpReg = MI.getOperand(0).getReg(); 633 bool UseRR = false; 634 if (Opcode == ARM::tRestore) { 635 if (FrameReg == ARM::SP) 636 emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg, 637 Offset, false, TII, *this, dl); 638 else { 639 emitLoadConstPool(MBB, II, dl, TmpReg, 0, Offset); 640 UseRR = true; 641 } 642 } else { 643 emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII, 644 *this, dl); 645 } 646 647 MI.setDesc(TII.get(ARM::tLDR)); 648 MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true); 649 if (UseRR) 650 // Use [reg, reg] addrmode. 651 MI.addOperand(MachineOperand::CreateReg(FrameReg, false)); 652 else // tLDR has an extra register operand. 653 MI.addOperand(MachineOperand::CreateReg(0, false)); 654 } else if (Desc.mayStore()) { 655 VReg = MF.getRegInfo().createVirtualRegister(ARM::tGPRRegisterClass); 656 bool UseRR = false; 657 658 if (Opcode == ARM::tSpill) { 659 if (FrameReg == ARM::SP) 660 emitThumbRegPlusImmInReg(MBB, II, VReg, FrameReg, 661 Offset, false, TII, *this, dl); 662 else { 663 emitLoadConstPool(MBB, II, dl, VReg, 0, Offset); 664 UseRR = true; 665 } 666 } else 667 emitThumbRegPlusImmediate(MBB, II, VReg, FrameReg, Offset, TII, 668 *this, dl); 669 MI.setDesc(TII.get(ARM::tSTR)); 670 MI.getOperand(i).ChangeToRegister(VReg, false, false, true); 671 if (UseRR) // Use [reg, reg] addrmode. 672 MI.addOperand(MachineOperand::CreateReg(FrameReg, false)); 673 else // tSTR has an extra register operand. 674 MI.addOperand(MachineOperand::CreateReg(0, false)); 675 } else 676 assert(false && "Unexpected opcode!"); 677 678 // Add predicate back if it's needed. 679 if (MI.getDesc().isPredicable()) { 680 MachineInstrBuilder MIB(&MI); 681 AddDefaultPred(MIB); 682 } 683} 684