LLVM API Documentation
00001 //===-- Thumb1RegisterInfo.cpp - Thumb-1 Register Information -------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains the Thumb-1 implementation of the TargetRegisterInfo 00011 // class. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "Thumb1RegisterInfo.h" 00016 #include "ARM.h" 00017 #include "ARMBaseInstrInfo.h" 00018 #include "ARMMachineFunctionInfo.h" 00019 #include "ARMSubtarget.h" 00020 #include "MCTargetDesc/ARMAddressingModes.h" 00021 #include "llvm/CodeGen/MachineConstantPool.h" 00022 #include "llvm/CodeGen/MachineFrameInfo.h" 00023 #include "llvm/CodeGen/MachineFunction.h" 00024 #include "llvm/CodeGen/MachineInstrBuilder.h" 00025 #include "llvm/CodeGen/MachineRegisterInfo.h" 00026 #include "llvm/CodeGen/RegisterScavenging.h" 00027 #include "llvm/IR/Constants.h" 00028 #include "llvm/IR/DerivedTypes.h" 00029 #include "llvm/IR/Function.h" 00030 #include "llvm/IR/LLVMContext.h" 00031 #include "llvm/Support/CommandLine.h" 00032 #include "llvm/Support/ErrorHandling.h" 00033 #include "llvm/Support/raw_ostream.h" 00034 #include "llvm/Target/TargetFrameLowering.h" 00035 #include "llvm/Target/TargetMachine.h" 00036 00037 namespace llvm { 00038 extern cl::opt<bool> ReuseFrameIndexVals; 00039 } 00040 00041 using namespace llvm; 00042 00043 Thumb1RegisterInfo::Thumb1RegisterInfo(const ARMBaseInstrInfo &tii, 00044 const ARMSubtarget &sti) 00045 : ARMBaseRegisterInfo(tii, sti) { 00046 } 00047 00048 const TargetRegisterClass* 00049 Thumb1RegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC) 00050 const { 00051 if (ARM::tGPRRegClass.hasSubClassEq(RC)) 00052 return &ARM::tGPRRegClass; 00053 return ARMBaseRegisterInfo::getLargestLegalSuperClass(RC); 00054 } 00055 00056 const TargetRegisterClass * 00057 Thumb1RegisterInfo::getPointerRegClass(const MachineFunction &MF, unsigned Kind) 00058 const { 00059 return &ARM::tGPRRegClass; 00060 } 00061 00062 /// emitLoadConstPool - Emits a load from constpool to materialize the 00063 /// specified immediate. 00064 void 00065 Thumb1RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB, 00066 MachineBasicBlock::iterator &MBBI, 00067 DebugLoc dl, 00068 unsigned DestReg, unsigned SubIdx, 00069 int Val, 00070 ARMCC::CondCodes Pred, unsigned PredReg, 00071 unsigned MIFlags) const { 00072 MachineFunction &MF = *MBB.getParent(); 00073 MachineConstantPool *ConstantPool = MF.getConstantPool(); 00074 const Constant *C = ConstantInt::get( 00075 Type::getInt32Ty(MBB.getParent()->getFunction()->getContext()), Val); 00076 unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4); 00077 00078 BuildMI(MBB, MBBI, dl, TII.get(ARM::tLDRpci)) 00079 .addReg(DestReg, getDefRegState(true), SubIdx) 00080 .addConstantPoolIndex(Idx).addImm(Pred).addReg(PredReg) 00081 .setMIFlags(MIFlags); 00082 } 00083 00084 00085 /// emitThumbRegPlusImmInReg - Emits a series of instructions to materialize 00086 /// a destreg = basereg + immediate in Thumb code. Materialize the immediate 00087 /// in a register using mov / mvn sequences or load the immediate from a 00088 /// constpool entry. 00089 static 00090 void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB, 00091 MachineBasicBlock::iterator &MBBI, 00092 DebugLoc dl, 00093 unsigned DestReg, unsigned BaseReg, 00094 int NumBytes, bool CanChangeCC, 00095 const TargetInstrInfo &TII, 00096 const ARMBaseRegisterInfo& MRI, 00097 unsigned MIFlags = MachineInstr::NoFlags) { 00098 MachineFunction &MF = *MBB.getParent(); 00099 bool isHigh = !isARMLowRegister(DestReg) || 00100 (BaseReg != 0 && !isARMLowRegister(BaseReg)); 00101 bool isSub = false; 00102 // Subtract doesn't have high register version. Load the negative value 00103 // if either base or dest register is a high register. Also, if do not 00104 // issue sub as part of the sequence if condition register is to be 00105 // preserved. 00106 if (NumBytes < 0 && !isHigh && CanChangeCC) { 00107 isSub = true; 00108 NumBytes = -NumBytes; 00109 } 00110 unsigned LdReg = DestReg; 00111 if (DestReg == ARM::SP) { 00112 assert(BaseReg == ARM::SP && "Unexpected!"); 00113 LdReg = MF.getRegInfo().createVirtualRegister(&ARM::tGPRRegClass); 00114 } 00115 00116 if (NumBytes <= 255 && NumBytes >= 0) 00117 AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg)) 00118 .addImm(NumBytes).setMIFlags(MIFlags); 00119 else if (NumBytes < 0 && NumBytes >= -255) { 00120 AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg)) 00121 .addImm(NumBytes).setMIFlags(MIFlags); 00122 AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tRSB), LdReg)) 00123 .addReg(LdReg, RegState::Kill).setMIFlags(MIFlags); 00124 } else 00125 MRI.emitLoadConstPool(MBB, MBBI, dl, LdReg, 0, NumBytes, 00126 ARMCC::AL, 0, MIFlags); 00127 00128 // Emit add / sub. 00129 int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr); 00130 MachineInstrBuilder MIB = 00131 BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg); 00132 if (Opc != ARM::tADDhirr) 00133 MIB = AddDefaultT1CC(MIB); 00134 if (DestReg == ARM::SP || isSub) 00135 MIB.addReg(BaseReg).addReg(LdReg, RegState::Kill); 00136 else 00137 MIB.addReg(LdReg).addReg(BaseReg, RegState::Kill); 00138 AddDefaultPred(MIB); 00139 } 00140 00141 /// calcNumMI - Returns the number of instructions required to materialize 00142 /// the specific add / sub r, c instruction. 00143 static unsigned calcNumMI(int Opc, int ExtraOpc, unsigned Bytes, 00144 unsigned NumBits, unsigned Scale) { 00145 unsigned NumMIs = 0; 00146 unsigned Chunk = ((1 << NumBits) - 1) * Scale; 00147 00148 if (Opc == ARM::tADDrSPi) { 00149 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes; 00150 Bytes -= ThisVal; 00151 NumMIs++; 00152 NumBits = 8; 00153 Scale = 1; // Followed by a number of tADDi8. 00154 Chunk = ((1 << NumBits) - 1) * Scale; 00155 } 00156 00157 NumMIs += Bytes / Chunk; 00158 if ((Bytes % Chunk) != 0) 00159 NumMIs++; 00160 if (ExtraOpc) 00161 NumMIs++; 00162 return NumMIs; 00163 } 00164 00165 /// emitThumbRegPlusImmediate - Emits a series of instructions to materialize 00166 /// a destreg = basereg + immediate in Thumb code. 00167 void llvm::emitThumbRegPlusImmediate(MachineBasicBlock &MBB, 00168 MachineBasicBlock::iterator &MBBI, 00169 DebugLoc dl, 00170 unsigned DestReg, unsigned BaseReg, 00171 int NumBytes, const TargetInstrInfo &TII, 00172 const ARMBaseRegisterInfo& MRI, 00173 unsigned MIFlags) { 00174 bool isSub = NumBytes < 0; 00175 unsigned Bytes = (unsigned)NumBytes; 00176 if (isSub) Bytes = -NumBytes; 00177 bool isMul4 = (Bytes & 3) == 0; 00178 bool isTwoAddr = false; 00179 bool DstNotEqBase = false; 00180 unsigned NumBits = 1; 00181 unsigned Scale = 1; 00182 int Opc = 0; 00183 int ExtraOpc = 0; 00184 bool NeedCC = false; 00185 00186 if (DestReg == BaseReg && BaseReg == ARM::SP) { 00187 assert(isMul4 && "Thumb sp inc / dec size must be multiple of 4!"); 00188 NumBits = 7; 00189 Scale = 4; 00190 Opc = isSub ? ARM::tSUBspi : ARM::tADDspi; 00191 isTwoAddr = true; 00192 } else if (!isSub && BaseReg == ARM::SP) { 00193 // r1 = add sp, 403 00194 // => 00195 // r1 = add sp, 100 * 4 00196 // r1 = add r1, 3 00197 if (!isMul4) { 00198 Bytes &= ~3; 00199 ExtraOpc = ARM::tADDi3; 00200 } 00201 NumBits = 8; 00202 Scale = 4; 00203 Opc = ARM::tADDrSPi; 00204 } else { 00205 // sp = sub sp, c 00206 // r1 = sub sp, c 00207 // r8 = sub sp, c 00208 if (DestReg != BaseReg) 00209 DstNotEqBase = true; 00210 NumBits = 8; 00211 if (DestReg == ARM::SP) { 00212 Opc = isSub ? ARM::tSUBspi : ARM::tADDspi; 00213 assert(isMul4 && "Thumb sp inc / dec size must be multiple of 4!"); 00214 NumBits = 7; 00215 Scale = 4; 00216 } else { 00217 Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8; 00218 NumBits = 8; 00219 NeedCC = true; 00220 } 00221 isTwoAddr = true; 00222 } 00223 00224 unsigned NumMIs = calcNumMI(Opc, ExtraOpc, Bytes, NumBits, Scale); 00225 unsigned Threshold = (DestReg == ARM::SP) ? 3 : 2; 00226 if (NumMIs > Threshold) { 00227 // This will expand into too many instructions. Load the immediate from a 00228 // constpool entry. 00229 emitThumbRegPlusImmInReg(MBB, MBBI, dl, 00230 DestReg, BaseReg, NumBytes, true, 00231 TII, MRI, MIFlags); 00232 return; 00233 } 00234 00235 if (DstNotEqBase) { 00236 if (isARMLowRegister(DestReg) && isARMLowRegister(BaseReg)) { 00237 // If both are low registers, emit DestReg = add BaseReg, max(Imm, 7) 00238 unsigned Chunk = (1 << 3) - 1; 00239 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes; 00240 Bytes -= ThisVal; 00241 const MCInstrDesc &MCID = TII.get(isSub ? ARM::tSUBi3 : ARM::tADDi3); 00242 const MachineInstrBuilder MIB = 00243 AddDefaultT1CC(BuildMI(MBB, MBBI, dl, MCID, DestReg) 00244 .setMIFlags(MIFlags)); 00245 AddDefaultPred(MIB.addReg(BaseReg, RegState::Kill).addImm(ThisVal)); 00246 } else { 00247 AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg) 00248 .addReg(BaseReg, RegState::Kill)) 00249 .setMIFlags(MIFlags); 00250 } 00251 BaseReg = DestReg; 00252 } 00253 00254 unsigned Chunk = ((1 << NumBits) - 1) * Scale; 00255 while (Bytes) { 00256 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes; 00257 Bytes -= ThisVal; 00258 ThisVal /= Scale; 00259 // Build the new tADD / tSUB. 00260 if (isTwoAddr) { 00261 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg); 00262 if (NeedCC) 00263 MIB = AddDefaultT1CC(MIB); 00264 MIB.addReg(DestReg).addImm(ThisVal); 00265 MIB = AddDefaultPred(MIB); 00266 MIB.setMIFlags(MIFlags); 00267 } else { 00268 bool isKill = BaseReg != ARM::SP; 00269 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg); 00270 if (NeedCC) 00271 MIB = AddDefaultT1CC(MIB); 00272 MIB.addReg(BaseReg, getKillRegState(isKill)).addImm(ThisVal); 00273 MIB = AddDefaultPred(MIB); 00274 MIB.setMIFlags(MIFlags); 00275 00276 BaseReg = DestReg; 00277 if (Opc == ARM::tADDrSPi) { 00278 // r4 = add sp, imm 00279 // r4 = add r4, imm 00280 // ... 00281 NumBits = 8; 00282 Scale = 1; 00283 Chunk = ((1 << NumBits) - 1) * Scale; 00284 Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8; 00285 NeedCC = isTwoAddr = true; 00286 } 00287 } 00288 } 00289 00290 if (ExtraOpc) { 00291 const MCInstrDesc &MCID = TII.get(ExtraOpc); 00292 AddDefaultPred(AddDefaultT1CC(BuildMI(MBB, MBBI, dl, MCID, DestReg)) 00293 .addReg(DestReg, RegState::Kill) 00294 .addImm(((unsigned)NumBytes) & 3) 00295 .setMIFlags(MIFlags)); 00296 } 00297 } 00298 00299 /// emitThumbConstant - Emit a series of instructions to materialize a 00300 /// constant. 00301 static void emitThumbConstant(MachineBasicBlock &MBB, 00302 MachineBasicBlock::iterator &MBBI, 00303 unsigned DestReg, int Imm, 00304 const TargetInstrInfo &TII, 00305 const Thumb1RegisterInfo& MRI, 00306 DebugLoc dl) { 00307 bool isSub = Imm < 0; 00308 if (isSub) Imm = -Imm; 00309 00310 int Chunk = (1 << 8) - 1; 00311 int ThisVal = (Imm > Chunk) ? Chunk : Imm; 00312 Imm -= ThisVal; 00313 AddDefaultPred(AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), 00314 DestReg)) 00315 .addImm(ThisVal)); 00316 if (Imm > 0) 00317 emitThumbRegPlusImmediate(MBB, MBBI, dl, DestReg, DestReg, Imm, TII, MRI); 00318 if (isSub) { 00319 const MCInstrDesc &MCID = TII.get(ARM::tRSB); 00320 AddDefaultPred(AddDefaultT1CC(BuildMI(MBB, MBBI, dl, MCID, DestReg)) 00321 .addReg(DestReg, RegState::Kill)); 00322 } 00323 } 00324 00325 static void removeOperands(MachineInstr &MI, unsigned i) { 00326 unsigned Op = i; 00327 for (unsigned e = MI.getNumOperands(); i != e; ++i) 00328 MI.RemoveOperand(Op); 00329 } 00330 00331 /// convertToNonSPOpcode - Change the opcode to the non-SP version, because 00332 /// we're replacing the frame index with a non-SP register. 00333 static unsigned convertToNonSPOpcode(unsigned Opcode) { 00334 switch (Opcode) { 00335 case ARM::tLDRspi: 00336 return ARM::tLDRi; 00337 00338 case ARM::tSTRspi: 00339 return ARM::tSTRi; 00340 } 00341 00342 return Opcode; 00343 } 00344 00345 bool Thumb1RegisterInfo:: 00346 rewriteFrameIndex(MachineBasicBlock::iterator II, unsigned FrameRegIdx, 00347 unsigned FrameReg, int &Offset, 00348 const ARMBaseInstrInfo &TII) const { 00349 MachineInstr &MI = *II; 00350 MachineBasicBlock &MBB = *MI.getParent(); 00351 DebugLoc dl = MI.getDebugLoc(); 00352 MachineInstrBuilder MIB(*MBB.getParent(), &MI); 00353 unsigned Opcode = MI.getOpcode(); 00354 const MCInstrDesc &Desc = MI.getDesc(); 00355 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); 00356 00357 if (Opcode == ARM::tADDrSPi) { 00358 Offset += MI.getOperand(FrameRegIdx+1).getImm(); 00359 00360 // Can't use tADDrSPi if it's based off the frame pointer. 00361 unsigned NumBits = 0; 00362 unsigned Scale = 1; 00363 if (FrameReg != ARM::SP) { 00364 Opcode = ARM::tADDi3; 00365 NumBits = 3; 00366 } else { 00367 NumBits = 8; 00368 Scale = 4; 00369 assert((Offset & 3) == 0 && 00370 "Thumb add/sub sp, #imm immediate must be multiple of 4!"); 00371 } 00372 00373 unsigned PredReg; 00374 if (Offset == 0 && getInstrPredicate(&MI, PredReg) == ARMCC::AL) { 00375 // Turn it into a move. 00376 MI.setDesc(TII.get(ARM::tMOVr)); 00377 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 00378 // Remove offset 00379 MI.RemoveOperand(FrameRegIdx+1); 00380 return true; 00381 } 00382 00383 // Common case: small offset, fits into instruction. 00384 unsigned Mask = (1 << NumBits) - 1; 00385 if (((Offset / Scale) & ~Mask) == 0) { 00386 // Replace the FrameIndex with sp / fp 00387 if (Opcode == ARM::tADDi3) { 00388 MI.setDesc(TII.get(Opcode)); 00389 removeOperands(MI, FrameRegIdx); 00390 AddDefaultPred(AddDefaultT1CC(MIB).addReg(FrameReg) 00391 .addImm(Offset / Scale)); 00392 } else { 00393 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 00394 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset / Scale); 00395 } 00396 return true; 00397 } 00398 00399 unsigned DestReg = MI.getOperand(0).getReg(); 00400 unsigned Bytes = (Offset > 0) ? Offset : -Offset; 00401 unsigned NumMIs = calcNumMI(Opcode, 0, Bytes, NumBits, Scale); 00402 // MI would expand into a large number of instructions. Don't try to 00403 // simplify the immediate. 00404 if (NumMIs > 2) { 00405 emitThumbRegPlusImmediate(MBB, II, dl, DestReg, FrameReg, Offset, TII, 00406 *this); 00407 MBB.erase(II); 00408 return true; 00409 } 00410 00411 if (Offset > 0) { 00412 // Translate r0 = add sp, imm to 00413 // r0 = add sp, 255*4 00414 // r0 = add r0, (imm - 255*4) 00415 if (Opcode == ARM::tADDi3) { 00416 MI.setDesc(TII.get(Opcode)); 00417 removeOperands(MI, FrameRegIdx); 00418 AddDefaultPred(AddDefaultT1CC(MIB).addReg(FrameReg).addImm(Mask)); 00419 } else { 00420 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 00421 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Mask); 00422 } 00423 Offset = (Offset - Mask * Scale); 00424 MachineBasicBlock::iterator NII = llvm::next(II); 00425 emitThumbRegPlusImmediate(MBB, NII, dl, DestReg, DestReg, Offset, TII, 00426 *this); 00427 } else { 00428 // Translate r0 = add sp, -imm to 00429 // r0 = -imm (this is then translated into a series of instructons) 00430 // r0 = add r0, sp 00431 emitThumbConstant(MBB, II, DestReg, Offset, TII, *this, dl); 00432 00433 MI.setDesc(TII.get(ARM::tADDhirr)); 00434 MI.getOperand(FrameRegIdx).ChangeToRegister(DestReg, false, false, true); 00435 MI.getOperand(FrameRegIdx+1).ChangeToRegister(FrameReg, false); 00436 } 00437 return true; 00438 } else { 00439 if (AddrMode != ARMII::AddrModeT1_s) 00440 llvm_unreachable("Unsupported addressing mode!"); 00441 00442 unsigned ImmIdx = FrameRegIdx + 1; 00443 int InstrOffs = MI.getOperand(ImmIdx).getImm(); 00444 unsigned NumBits = (FrameReg == ARM::SP) ? 8 : 5; 00445 unsigned Scale = 4; 00446 00447 Offset += InstrOffs * Scale; 00448 assert((Offset & (Scale - 1)) == 0 && "Can't encode this offset!"); 00449 00450 // Common case: small offset, fits into instruction. 00451 MachineOperand &ImmOp = MI.getOperand(ImmIdx); 00452 int ImmedOffset = Offset / Scale; 00453 unsigned Mask = (1 << NumBits) - 1; 00454 00455 if ((unsigned)Offset <= Mask * Scale) { 00456 // Replace the FrameIndex with the frame register (e.g., sp). 00457 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 00458 ImmOp.ChangeToImmediate(ImmedOffset); 00459 00460 // If we're using a register where sp was stored, convert the instruction 00461 // to the non-SP version. 00462 unsigned NewOpc = convertToNonSPOpcode(Opcode); 00463 if (NewOpc != Opcode && FrameReg != ARM::SP) 00464 MI.setDesc(TII.get(NewOpc)); 00465 00466 return true; 00467 } 00468 00469 NumBits = 5; 00470 Mask = (1 << NumBits) - 1; 00471 00472 // If this is a thumb spill / restore, we will be using a constpool load to 00473 // materialize the offset. 00474 if (Opcode == ARM::tLDRspi || Opcode == ARM::tSTRspi) { 00475 ImmOp.ChangeToImmediate(0); 00476 } else { 00477 // Otherwise, it didn't fit. Pull in what we can to simplify the immed. 00478 ImmedOffset = ImmedOffset & Mask; 00479 ImmOp.ChangeToImmediate(ImmedOffset); 00480 Offset &= ~(Mask * Scale); 00481 } 00482 } 00483 00484 return Offset == 0; 00485 } 00486 00487 void 00488 Thumb1RegisterInfo::resolveFrameIndex(MachineBasicBlock::iterator I, 00489 unsigned BaseReg, int64_t Offset) const { 00490 MachineInstr &MI = *I; 00491 int Off = Offset; // ARM doesn't need the general 64-bit offsets 00492 unsigned i = 0; 00493 00494 while (!MI.getOperand(i).isFI()) { 00495 ++i; 00496 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 00497 } 00498 bool Done = rewriteFrameIndex(MI, i, BaseReg, Off, TII); 00499 assert (Done && "Unable to resolve frame index!"); 00500 (void)Done; 00501 } 00502 00503 /// saveScavengerRegister - Spill the register so it can be used by the 00504 /// register scavenger. Return true. 00505 bool 00506 Thumb1RegisterInfo::saveScavengerRegister(MachineBasicBlock &MBB, 00507 MachineBasicBlock::iterator I, 00508 MachineBasicBlock::iterator &UseMI, 00509 const TargetRegisterClass *RC, 00510 unsigned Reg) const { 00511 // Thumb1 can't use the emergency spill slot on the stack because 00512 // ldr/str immediate offsets must be positive, and if we're referencing 00513 // off the frame pointer (if, for example, there are alloca() calls in 00514 // the function, the offset will be negative. Use R12 instead since that's 00515 // a call clobbered register that we know won't be used in Thumb1 mode. 00516 DebugLoc DL; 00517 AddDefaultPred(BuildMI(MBB, I, DL, TII.get(ARM::tMOVr)) 00518 .addReg(ARM::R12, RegState::Define) 00519 .addReg(Reg, RegState::Kill)); 00520 00521 // The UseMI is where we would like to restore the register. If there's 00522 // interference with R12 before then, however, we'll need to restore it 00523 // before that instead and adjust the UseMI. 00524 bool done = false; 00525 for (MachineBasicBlock::iterator II = I; !done && II != UseMI ; ++II) { 00526 if (II->isDebugValue()) 00527 continue; 00528 // If this instruction affects R12, adjust our restore point. 00529 for (unsigned i = 0, e = II->getNumOperands(); i != e; ++i) { 00530 const MachineOperand &MO = II->getOperand(i); 00531 if (MO.isRegMask() && MO.clobbersPhysReg(ARM::R12)) { 00532 UseMI = II; 00533 done = true; 00534 break; 00535 } 00536 if (!MO.isReg() || MO.isUndef() || !MO.getReg() || 00537 TargetRegisterInfo::isVirtualRegister(MO.getReg())) 00538 continue; 00539 if (MO.getReg() == ARM::R12) { 00540 UseMI = II; 00541 done = true; 00542 break; 00543 } 00544 } 00545 } 00546 // Restore the register from R12 00547 AddDefaultPred(BuildMI(MBB, UseMI, DL, TII.get(ARM::tMOVr)). 00548 addReg(Reg, RegState::Define).addReg(ARM::R12, RegState::Kill)); 00549 00550 return true; 00551 } 00552 00553 void 00554 Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 00555 int SPAdj, unsigned FIOperandNum, 00556 RegScavenger *RS) const { 00557 unsigned VReg = 0; 00558 MachineInstr &MI = *II; 00559 MachineBasicBlock &MBB = *MI.getParent(); 00560 MachineFunction &MF = *MBB.getParent(); 00561 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 00562 DebugLoc dl = MI.getDebugLoc(); 00563 MachineInstrBuilder MIB(*MBB.getParent(), &MI); 00564 00565 unsigned FrameReg = ARM::SP; 00566 int FrameIndex = MI.getOperand(FIOperandNum).getIndex(); 00567 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) + 00568 MF.getFrameInfo()->getStackSize() + SPAdj; 00569 00570 if (AFI->isGPRCalleeSavedArea1Frame(FrameIndex)) 00571 Offset -= AFI->getGPRCalleeSavedArea1Offset(); 00572 else if (AFI->isGPRCalleeSavedArea2Frame(FrameIndex)) 00573 Offset -= AFI->getGPRCalleeSavedArea2Offset(); 00574 else if (MF.getFrameInfo()->hasVarSizedObjects()) { 00575 assert(SPAdj == 0 && MF.getTarget().getFrameLowering()->hasFP(MF) && 00576 "Unexpected"); 00577 // There are alloca()'s in this function, must reference off the frame 00578 // pointer or base pointer instead. 00579 if (!hasBasePointer(MF)) { 00580 FrameReg = getFrameRegister(MF); 00581 Offset -= AFI->getFramePtrSpillOffset(); 00582 } else 00583 FrameReg = BasePtr; 00584 } 00585 00586 // PEI::scavengeFrameVirtualRegs() cannot accurately track SPAdj because the 00587 // call frame setup/destroy instructions have already been eliminated. That 00588 // means the stack pointer cannot be used to access the emergency spill slot 00589 // when !hasReservedCallFrame(). 00590 #ifndef NDEBUG 00591 if (RS && FrameReg == ARM::SP && RS->isScavengingFrameIndex(FrameIndex)){ 00592 assert(MF.getTarget().getFrameLowering()->hasReservedCallFrame(MF) && 00593 "Cannot use SP to access the emergency spill slot in " 00594 "functions without a reserved call frame"); 00595 assert(!MF.getFrameInfo()->hasVarSizedObjects() && 00596 "Cannot use SP to access the emergency spill slot in " 00597 "functions with variable sized frame objects"); 00598 } 00599 #endif // NDEBUG 00600 00601 // Special handling of dbg_value instructions. 00602 if (MI.isDebugValue()) { 00603 MI.getOperand(FIOperandNum). ChangeToRegister(FrameReg, false /*isDef*/); 00604 MI.getOperand(FIOperandNum+1).ChangeToImmediate(Offset); 00605 return; 00606 } 00607 00608 // Modify MI as necessary to handle as much of 'Offset' as possible 00609 assert(AFI->isThumbFunction() && 00610 "This eliminateFrameIndex only supports Thumb1!"); 00611 if (rewriteFrameIndex(MI, FIOperandNum, FrameReg, Offset, TII)) 00612 return; 00613 00614 // If we get here, the immediate doesn't fit into the instruction. We folded 00615 // as much as possible above, handle the rest, providing a register that is 00616 // SP+LargeImm. 00617 assert(Offset && "This code isn't needed if offset already handled!"); 00618 00619 unsigned Opcode = MI.getOpcode(); 00620 00621 // Remove predicate first. 00622 int PIdx = MI.findFirstPredOperandIdx(); 00623 if (PIdx != -1) 00624 removeOperands(MI, PIdx); 00625 00626 if (MI.mayLoad()) { 00627 // Use the destination register to materialize sp + offset. 00628 unsigned TmpReg = MI.getOperand(0).getReg(); 00629 bool UseRR = false; 00630 if (Opcode == ARM::tLDRspi) { 00631 if (FrameReg == ARM::SP) 00632 emitThumbRegPlusImmInReg(MBB, II, dl, TmpReg, FrameReg, 00633 Offset, false, TII, *this); 00634 else { 00635 emitLoadConstPool(MBB, II, dl, TmpReg, 0, Offset); 00636 UseRR = true; 00637 } 00638 } else { 00639 emitThumbRegPlusImmediate(MBB, II, dl, TmpReg, FrameReg, Offset, TII, 00640 *this); 00641 } 00642 00643 MI.setDesc(TII.get(UseRR ? ARM::tLDRr : ARM::tLDRi)); 00644 MI.getOperand(FIOperandNum).ChangeToRegister(TmpReg, false, false, true); 00645 if (UseRR) 00646 // Use [reg, reg] addrmode. Replace the immediate operand w/ the frame 00647 // register. The offset is already handled in the vreg value. 00648 MI.getOperand(FIOperandNum+1).ChangeToRegister(FrameReg, false, false, 00649 false); 00650 } else if (MI.mayStore()) { 00651 VReg = MF.getRegInfo().createVirtualRegister(&ARM::tGPRRegClass); 00652 bool UseRR = false; 00653 00654 if (Opcode == ARM::tSTRspi) { 00655 if (FrameReg == ARM::SP) 00656 emitThumbRegPlusImmInReg(MBB, II, dl, VReg, FrameReg, 00657 Offset, false, TII, *this); 00658 else { 00659 emitLoadConstPool(MBB, II, dl, VReg, 0, Offset); 00660 UseRR = true; 00661 } 00662 } else 00663 emitThumbRegPlusImmediate(MBB, II, dl, VReg, FrameReg, Offset, TII, 00664 *this); 00665 MI.setDesc(TII.get(UseRR ? ARM::tSTRr : ARM::tSTRi)); 00666 MI.getOperand(FIOperandNum).ChangeToRegister(VReg, false, false, true); 00667 if (UseRR) 00668 // Use [reg, reg] addrmode. Replace the immediate operand w/ the frame 00669 // register. The offset is already handled in the vreg value. 00670 MI.getOperand(FIOperandNum+1).ChangeToRegister(FrameReg, false, false, 00671 false); 00672 } else { 00673 llvm_unreachable("Unexpected opcode!"); 00674 } 00675 00676 // Add predicate back if it's needed. 00677 if (MI.isPredicable()) 00678 AddDefaultPred(MIB); 00679 }