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