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