LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Thumb1RegisterInfo.cpp
Go to the documentation of this file.
1 //===-- Thumb1RegisterInfo.cpp - Thumb-1 Register Information -------------===//
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 "Thumb1RegisterInfo.h"
16 #include "ARM.h"
17 #include "ARMBaseInstrInfo.h"
18 #include "ARMMachineFunctionInfo.h"
19 #include "ARMSubtarget.h"
27 #include "llvm/IR/Constants.h"
28 #include "llvm/IR/DerivedTypes.h"
29 #include "llvm/IR/Function.h"
30 #include "llvm/IR/LLVMContext.h"
36 
37 namespace llvm {
39 }
40 
41 using namespace llvm;
42 
44  : ARMBaseRegisterInfo(sti) {
45 }
46 
49  const {
50  if (ARM::tGPRRegClass.hasSubClassEq(RC))
51  return &ARM::tGPRRegClass;
53 }
54 
55 const TargetRegisterClass *
57  const {
58  return &ARM::tGPRRegClass;
59 }
60 
61 /// emitLoadConstPool - Emits a load from constpool to materialize the
62 /// specified immediate.
63 void
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  const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
74  const Constant *C = ConstantInt::get(
76  unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
77 
78  BuildMI(MBB, MBBI, dl, TII.get(ARM::tLDRpci))
79  .addReg(DestReg, getDefRegState(true), SubIdx)
80  .addConstantPoolIndex(Idx).addImm(Pred).addReg(PredReg)
81  .setMIFlags(MIFlags);
82 }
83 
84 
85 /// emitThumbRegPlusImmInReg - Emits a series of instructions to materialize
86 /// a destreg = basereg + immediate in Thumb code. Materialize the immediate
87 /// in a register using mov / mvn sequences or load the immediate from a
88 /// constpool entry.
89 static
92  DebugLoc dl,
93  unsigned DestReg, unsigned BaseReg,
94  int NumBytes, bool CanChangeCC,
95  const TargetInstrInfo &TII,
96  const ARMBaseRegisterInfo& MRI,
97  unsigned MIFlags = MachineInstr::NoFlags) {
98  MachineFunction &MF = *MBB.getParent();
99  bool isHigh = !isARMLowRegister(DestReg) ||
100  (BaseReg != 0 && !isARMLowRegister(BaseReg));
101  bool isSub = false;
102  // Subtract doesn't have high register version. Load the negative value
103  // if either base or dest register is a high register. Also, if do not
104  // issue sub as part of the sequence if condition register is to be
105  // preserved.
106  if (NumBytes < 0 && !isHigh && CanChangeCC) {
107  isSub = true;
108  NumBytes = -NumBytes;
109  }
110  unsigned LdReg = DestReg;
111  if (DestReg == ARM::SP) {
112  assert(BaseReg == ARM::SP && "Unexpected!");
113  LdReg = MF.getRegInfo().createVirtualRegister(&ARM::tGPRRegClass);
114  }
115 
116  if (NumBytes <= 255 && NumBytes >= 0)
117  AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg))
118  .addImm(NumBytes).setMIFlags(MIFlags);
119  else if (NumBytes < 0 && NumBytes >= -255) {
120  AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg))
121  .addImm(NumBytes).setMIFlags(MIFlags);
122  AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tRSB), LdReg))
123  .addReg(LdReg, RegState::Kill).setMIFlags(MIFlags);
124  } else
125  MRI.emitLoadConstPool(MBB, MBBI, dl, LdReg, 0, NumBytes,
126  ARMCC::AL, 0, MIFlags);
127 
128  // Emit add / sub.
129  int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr);
130  MachineInstrBuilder MIB =
131  BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg);
132  if (Opc != ARM::tADDhirr)
133  MIB = AddDefaultT1CC(MIB);
134  if (DestReg == ARM::SP || isSub)
135  MIB.addReg(BaseReg).addReg(LdReg, RegState::Kill);
136  else
137  MIB.addReg(LdReg).addReg(BaseReg, RegState::Kill);
138  AddDefaultPred(MIB);
139 }
140 
141 /// calcNumMI - Returns the number of instructions required to materialize
142 /// the specific add / sub r, c instruction.
143 static unsigned calcNumMI(int Opc, int ExtraOpc, unsigned Bytes,
144  unsigned NumBits, unsigned Scale) {
145  unsigned NumMIs = 0;
146  unsigned Chunk = ((1 << NumBits) - 1) * Scale;
147 
148  if (Opc == ARM::tADDrSPi) {
149  unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
150  Bytes -= ThisVal;
151  NumMIs++;
152  NumBits = 8;
153  Scale = 1; // Followed by a number of tADDi8.
154  Chunk = ((1 << NumBits) - 1) * Scale;
155  }
156 
157  NumMIs += Bytes / Chunk;
158  if ((Bytes % Chunk) != 0)
159  NumMIs++;
160  if (ExtraOpc)
161  NumMIs++;
162  return NumMIs;
163 }
164 
165 /// emitThumbRegPlusImmediate - Emits a series of instructions to materialize
166 /// a destreg = basereg + immediate in Thumb code.
169  DebugLoc dl,
170  unsigned DestReg, unsigned BaseReg,
171  int NumBytes, const TargetInstrInfo &TII,
172  const ARMBaseRegisterInfo& MRI,
173  unsigned MIFlags) {
174  bool isSub = NumBytes < 0;
175  unsigned Bytes = (unsigned)NumBytes;
176  if (isSub) Bytes = -NumBytes;
177  bool isMul4 = (Bytes & 3) == 0;
178  bool isTwoAddr = false;
179  bool DstNotEqBase = false;
180  unsigned NumBits = 1;
181  unsigned Scale = 1;
182  int Opc = 0;
183  int ExtraOpc = 0;
184  bool NeedCC = 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  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)
244  .setMIFlags(MIFlags));
245  AddDefaultPred(MIB.addReg(BaseReg, RegState::Kill).addImm(ThisVal));
246  } else {
247  AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
248  .addReg(BaseReg, RegState::Kill))
249  .setMIFlags(MIFlags);
250  }
251  BaseReg = DestReg;
252  }
253 
254  unsigned Chunk = ((1 << NumBits) - 1) * Scale;
255  while (Bytes) {
256  unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
257  Bytes -= ThisVal;
258  ThisVal /= Scale;
259  // Build the new tADD / tSUB.
260  if (isTwoAddr) {
261  MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg);
262  if (NeedCC)
263  MIB = AddDefaultT1CC(MIB);
264  MIB.addReg(DestReg).addImm(ThisVal);
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  MIB = AddDefaultPred(MIB);
274  MIB.setMIFlags(MIFlags);
275 
276  BaseReg = DestReg;
277  if (Opc == ARM::tADDrSPi) {
278  // r4 = add sp, imm
279  // r4 = add r4, imm
280  // ...
281  NumBits = 8;
282  Scale = 1;
283  Chunk = ((1 << NumBits) - 1) * Scale;
284  Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
285  NeedCC = isTwoAddr = true;
286  }
287  }
288  }
289 
290  if (ExtraOpc) {
291  const MCInstrDesc &MCID = TII.get(ExtraOpc);
292  AddDefaultPred(AddDefaultT1CC(BuildMI(MBB, MBBI, dl, MCID, DestReg))
293  .addReg(DestReg, RegState::Kill)
294  .addImm(((unsigned)NumBytes) & 3)
295  .setMIFlags(MIFlags));
296  }
297 }
298 
299 /// emitThumbConstant - Emit a series of instructions to materialize a
300 /// constant.
303  unsigned DestReg, int Imm,
304  const TargetInstrInfo &TII,
305  const Thumb1RegisterInfo& MRI,
306  DebugLoc dl) {
307  bool isSub = Imm < 0;
308  if (isSub) Imm = -Imm;
309 
310  int Chunk = (1 << 8) - 1;
311  int ThisVal = (Imm > Chunk) ? Chunk : Imm;
312  Imm -= ThisVal;
313  AddDefaultPred(AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8),
314  DestReg))
315  .addImm(ThisVal));
316  if (Imm > 0)
317  emitThumbRegPlusImmediate(MBB, MBBI, dl, DestReg, DestReg, Imm, TII, MRI);
318  if (isSub) {
319  const MCInstrDesc &MCID = TII.get(ARM::tRSB);
320  AddDefaultPred(AddDefaultT1CC(BuildMI(MBB, MBBI, dl, MCID, DestReg))
321  .addReg(DestReg, RegState::Kill));
322  }
323 }
324 
325 static void removeOperands(MachineInstr &MI, unsigned i) {
326  unsigned Op = i;
327  for (unsigned e = MI.getNumOperands(); i != e; ++i)
328  MI.RemoveOperand(Op);
329 }
330 
331 /// convertToNonSPOpcode - Change the opcode to the non-SP version, because
332 /// we're replacing the frame index with a non-SP register.
333 static unsigned convertToNonSPOpcode(unsigned Opcode) {
334  switch (Opcode) {
335  case ARM::tLDRspi:
336  return ARM::tLDRi;
337 
338  case ARM::tSTRspi:
339  return ARM::tSTRi;
340  }
341 
342  return Opcode;
343 }
344 
347  unsigned FrameReg, int &Offset,
348  const ARMBaseInstrInfo &TII) const {
349  MachineInstr &MI = *II;
350  MachineBasicBlock &MBB = *MI.getParent();
351  DebugLoc dl = MI.getDebugLoc();
352  MachineInstrBuilder MIB(*MBB.getParent(), &MI);
353  unsigned Opcode = MI.getOpcode();
354  const MCInstrDesc &Desc = MI.getDesc();
355  unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
356 
357  if (Opcode == ARM::tADDrSPi) {
358  Offset += MI.getOperand(FrameRegIdx+1).getImm();
359 
360  // Can't use tADDrSPi if it's based off the frame pointer.
361  unsigned NumBits = 0;
362  unsigned Scale = 1;
363  if (FrameReg != ARM::SP) {
364  Opcode = ARM::tADDi3;
365  NumBits = 3;
366  } else {
367  NumBits = 8;
368  Scale = 4;
369  assert((Offset & 3) == 0 &&
370  "Thumb add/sub sp, #imm immediate must be multiple of 4!");
371  }
372 
373  unsigned PredReg;
374  if (Offset == 0 && getInstrPredicate(&MI, PredReg) == ARMCC::AL) {
375  // Turn it into a move.
376  MI.setDesc(TII.get(ARM::tMOVr));
377  MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
378  // Remove offset
379  MI.RemoveOperand(FrameRegIdx+1);
380  return true;
381  }
382 
383  // Common case: small offset, fits into instruction.
384  unsigned Mask = (1 << NumBits) - 1;
385  if (((Offset / Scale) & ~Mask) == 0) {
386  // Replace the FrameIndex with sp / fp
387  if (Opcode == ARM::tADDi3) {
388  MI.setDesc(TII.get(Opcode));
389  removeOperands(MI, FrameRegIdx);
390  AddDefaultPred(AddDefaultT1CC(MIB).addReg(FrameReg)
391  .addImm(Offset / Scale));
392  } else {
393  MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
394  MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset / Scale);
395  }
396  return true;
397  }
398 
399  unsigned DestReg = MI.getOperand(0).getReg();
400  unsigned Bytes = (Offset > 0) ? Offset : -Offset;
401  unsigned NumMIs = calcNumMI(Opcode, 0, Bytes, NumBits, Scale);
402  // MI would expand into a large number of instructions. Don't try to
403  // simplify the immediate.
404  if (NumMIs > 2) {
405  emitThumbRegPlusImmediate(MBB, II, dl, DestReg, FrameReg, Offset, TII,
406  *this);
407  MBB.erase(II);
408  return true;
409  }
410 
411  if (Offset > 0) {
412  // Translate r0 = add sp, imm to
413  // r0 = add sp, 255*4
414  // r0 = add r0, (imm - 255*4)
415  if (Opcode == ARM::tADDi3) {
416  MI.setDesc(TII.get(Opcode));
417  removeOperands(MI, FrameRegIdx);
418  AddDefaultPred(AddDefaultT1CC(MIB).addReg(FrameReg).addImm(Mask));
419  } else {
420  MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
421  MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Mask);
422  }
423  Offset = (Offset - Mask * Scale);
425  emitThumbRegPlusImmediate(MBB, NII, dl, DestReg, DestReg, Offset, TII,
426  *this);
427  } else {
428  // Translate r0 = add sp, -imm to
429  // r0 = -imm (this is then translated into a series of instructions)
430  // r0 = add r0, sp
431  emitThumbConstant(MBB, II, DestReg, Offset, TII, *this, dl);
432 
433  MI.setDesc(TII.get(ARM::tADDhirr));
434  MI.getOperand(FrameRegIdx).ChangeToRegister(DestReg, false, false, true);
435  MI.getOperand(FrameRegIdx+1).ChangeToRegister(FrameReg, false);
436  }
437  return true;
438  } else {
439  if (AddrMode != ARMII::AddrModeT1_s)
440  llvm_unreachable("Unsupported addressing mode!");
441 
442  unsigned ImmIdx = FrameRegIdx + 1;
443  int InstrOffs = MI.getOperand(ImmIdx).getImm();
444  unsigned NumBits = (FrameReg == ARM::SP) ? 8 : 5;
445  unsigned Scale = 4;
446 
447  Offset += InstrOffs * Scale;
448  assert((Offset & (Scale - 1)) == 0 && "Can't encode this offset!");
449 
450  // Common case: small offset, fits into instruction.
451  MachineOperand &ImmOp = MI.getOperand(ImmIdx);
452  int ImmedOffset = Offset / Scale;
453  unsigned Mask = (1 << NumBits) - 1;
454 
455  if ((unsigned)Offset <= Mask * Scale) {
456  // Replace the FrameIndex with the frame register (e.g., sp).
457  MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
458  ImmOp.ChangeToImmediate(ImmedOffset);
459 
460  // If we're using a register where sp was stored, convert the instruction
461  // to the non-SP version.
462  unsigned NewOpc = convertToNonSPOpcode(Opcode);
463  if (NewOpc != Opcode && FrameReg != ARM::SP)
464  MI.setDesc(TII.get(NewOpc));
465 
466  return true;
467  }
468 
469  NumBits = 5;
470  Mask = (1 << NumBits) - 1;
471 
472  // If this is a thumb spill / restore, we will be using a constpool load to
473  // materialize the offset.
474  if (Opcode == ARM::tLDRspi || Opcode == ARM::tSTRspi) {
475  ImmOp.ChangeToImmediate(0);
476  } else {
477  // Otherwise, it didn't fit. Pull in what we can to simplify the immed.
478  ImmedOffset = ImmedOffset & Mask;
479  ImmOp.ChangeToImmediate(ImmedOffset);
480  Offset &= ~(Mask * Scale);
481  }
482  }
483 
484  return Offset == 0;
485 }
486 
487 void
489  unsigned BaseReg, int64_t Offset) const {
490  MachineInstr &MI = *I;
491  const ARMBaseInstrInfo &TII =
492  *static_cast<const ARMBaseInstrInfo*>(
494  int Off = Offset; // ARM doesn't need the general 64-bit offsets
495  unsigned i = 0;
496 
497  while (!MI.getOperand(i).isFI()) {
498  ++i;
499  assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
500  }
501  bool Done = rewriteFrameIndex(MI, i, BaseReg, Off, TII);
502  assert (Done && "Unable to resolve frame index!");
503  (void)Done;
504 }
505 
506 /// saveScavengerRegister - Spill the register so it can be used by the
507 /// register scavenger. Return true.
508 bool
512  const TargetRegisterClass *RC,
513  unsigned Reg) const {
514  // Thumb1 can't use the emergency spill slot on the stack because
515  // ldr/str immediate offsets must be positive, and if we're referencing
516  // off the frame pointer (if, for example, there are alloca() calls in
517  // the function, the offset will be negative. Use R12 instead since that's
518  // a call clobbered register that we know won't be used in Thumb1 mode.
519  const TargetInstrInfo &TII = *MBB.getParent()->getTarget().getInstrInfo();
520  DebugLoc DL;
521  AddDefaultPred(BuildMI(MBB, I, DL, TII.get(ARM::tMOVr))
522  .addReg(ARM::R12, RegState::Define)
523  .addReg(Reg, RegState::Kill));
524 
525  // The UseMI is where we would like to restore the register. If there's
526  // interference with R12 before then, however, we'll need to restore it
527  // before that instead and adjust the UseMI.
528  bool done = false;
529  for (MachineBasicBlock::iterator II = I; !done && II != UseMI ; ++II) {
530  if (II->isDebugValue())
531  continue;
532  // If this instruction affects R12, adjust our restore point.
533  for (unsigned i = 0, e = II->getNumOperands(); i != e; ++i) {
534  const MachineOperand &MO = II->getOperand(i);
535  if (MO.isRegMask() && MO.clobbersPhysReg(ARM::R12)) {
536  UseMI = II;
537  done = true;
538  break;
539  }
540  if (!MO.isReg() || MO.isUndef() || !MO.getReg() ||
542  continue;
543  if (MO.getReg() == ARM::R12) {
544  UseMI = II;
545  done = true;
546  break;
547  }
548  }
549  }
550  // Restore the register from R12
551  AddDefaultPred(BuildMI(MBB, UseMI, DL, TII.get(ARM::tMOVr)).
552  addReg(Reg, RegState::Define).addReg(ARM::R12, RegState::Kill));
553 
554  return true;
555 }
556 
557 void
559  int SPAdj, unsigned FIOperandNum,
560  RegScavenger *RS) const {
561  unsigned VReg = 0;
562  MachineInstr &MI = *II;
563  MachineBasicBlock &MBB = *MI.getParent();
564  MachineFunction &MF = *MBB.getParent();
565  const ARMBaseInstrInfo &TII =
566  *static_cast<const ARMBaseInstrInfo*>(MF.getTarget().getInstrInfo());
568  DebugLoc dl = MI.getDebugLoc();
569  MachineInstrBuilder MIB(*MBB.getParent(), &MI);
570 
571  unsigned FrameReg = ARM::SP;
572  int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
573  int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
574  MF.getFrameInfo()->getStackSize() + SPAdj;
575 
576  if (MF.getFrameInfo()->hasVarSizedObjects()) {
577  assert(SPAdj == 0 && MF.getTarget().getFrameLowering()->hasFP(MF) &&
578  "Unexpected");
579  // There are alloca()'s in this function, must reference off the frame
580  // pointer or base pointer instead.
581  if (!hasBasePointer(MF)) {
582  FrameReg = getFrameRegister(MF);
583  Offset -= AFI->getFramePtrSpillOffset();
584  } else
585  FrameReg = BasePtr;
586  }
587 
588  // PEI::scavengeFrameVirtualRegs() cannot accurately track SPAdj because the
589  // call frame setup/destroy instructions have already been eliminated. That
590  // means the stack pointer cannot be used to access the emergency spill slot
591  // when !hasReservedCallFrame().
592 #ifndef NDEBUG
593  if (RS && FrameReg == ARM::SP && RS->isScavengingFrameIndex(FrameIndex)){
594  assert(MF.getTarget().getFrameLowering()->hasReservedCallFrame(MF) &&
595  "Cannot use SP to access the emergency spill slot in "
596  "functions without a reserved call frame");
597  assert(!MF.getFrameInfo()->hasVarSizedObjects() &&
598  "Cannot use SP to access the emergency spill slot in "
599  "functions with variable sized frame objects");
600  }
601 #endif // NDEBUG
602 
603  // Special handling of dbg_value instructions.
604  if (MI.isDebugValue()) {
605  MI.getOperand(FIOperandNum). ChangeToRegister(FrameReg, false /*isDef*/);
606  MI.getOperand(FIOperandNum+1).ChangeToImmediate(Offset);
607  return;
608  }
609 
610  // Modify MI as necessary to handle as much of 'Offset' as possible
611  assert(AFI->isThumbFunction() &&
612  "This eliminateFrameIndex only supports Thumb1!");
613  if (rewriteFrameIndex(MI, FIOperandNum, FrameReg, Offset, TII))
614  return;
615 
616  // If we get here, the immediate doesn't fit into the instruction. We folded
617  // as much as possible above, handle the rest, providing a register that is
618  // SP+LargeImm.
619  assert(Offset && "This code isn't needed if offset already handled!");
620 
621  unsigned Opcode = MI.getOpcode();
622 
623  // Remove predicate first.
624  int PIdx = MI.findFirstPredOperandIdx();
625  if (PIdx != -1)
626  removeOperands(MI, PIdx);
627 
628  if (MI.mayLoad()) {
629  // Use the destination register to materialize sp + offset.
630  unsigned TmpReg = MI.getOperand(0).getReg();
631  bool UseRR = false;
632  if (Opcode == ARM::tLDRspi) {
633  if (FrameReg == ARM::SP)
634  emitThumbRegPlusImmInReg(MBB, II, dl, TmpReg, FrameReg,
635  Offset, false, TII, *this);
636  else {
637  emitLoadConstPool(MBB, II, dl, TmpReg, 0, Offset);
638  UseRR = true;
639  }
640  } else {
641  emitThumbRegPlusImmediate(MBB, II, dl, TmpReg, FrameReg, Offset, TII,
642  *this);
643  }
644 
645  MI.setDesc(TII.get(UseRR ? ARM::tLDRr : ARM::tLDRi));
646  MI.getOperand(FIOperandNum).ChangeToRegister(TmpReg, false, false, true);
647  if (UseRR)
648  // Use [reg, reg] addrmode. Replace the immediate operand w/ the frame
649  // register. The offset is already handled in the vreg value.
650  MI.getOperand(FIOperandNum+1).ChangeToRegister(FrameReg, false, false,
651  false);
652  } else if (MI.mayStore()) {
653  VReg = MF.getRegInfo().createVirtualRegister(&ARM::tGPRRegClass);
654  bool UseRR = false;
655 
656  if (Opcode == ARM::tSTRspi) {
657  if (FrameReg == ARM::SP)
658  emitThumbRegPlusImmInReg(MBB, II, dl, VReg, FrameReg,
659  Offset, false, TII, *this);
660  else {
661  emitLoadConstPool(MBB, II, dl, VReg, 0, Offset);
662  UseRR = true;
663  }
664  } else
665  emitThumbRegPlusImmediate(MBB, II, dl, VReg, FrameReg, Offset, TII,
666  *this);
667  MI.setDesc(TII.get(UseRR ? ARM::tSTRr : ARM::tSTRi));
668  MI.getOperand(FIOperandNum).ChangeToRegister(VReg, false, false, true);
669  if (UseRR)
670  // Use [reg, reg] addrmode. Replace the immediate operand w/ the frame
671  // register. The offset is already handled in the vreg value.
672  MI.getOperand(FIOperandNum+1).ChangeToRegister(FrameReg, false, false,
673  false);
674  } else {
675  llvm_unreachable("Unexpected opcode!");
676  }
677 
678  // Add predicate back if it's needed.
679  if (MI.isPredicable())
680  AddDefaultPred(MIB);
681 }
unsigned getFrameRegister(const MachineFunction &MF) const
const MachineFunction * getParent() const
The machine constant pool.
instr_iterator erase(instr_iterator I)
LLVMContext & getContext() const
Definition: Function.cpp:167
void ChangeToRegister(unsigned Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isDebug=false)
void resolveFrameIndex(MachineBasicBlock::iterator I, unsigned BaseReg, int64_t Offset) const
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
static unsigned calcNumMI(int Opc, int ExtraOpc, unsigned Bytes, unsigned NumBits, unsigned Scale)
bool mayStore(QueryType Type=AnyInBundle) const
Definition: MachineInstr.h:479
static bool isVirtualRegister(unsigned Reg)
bool isPredicable(QueryType Type=AllInBundle) const
Definition: MachineInstr.h:404
const MCInstrDesc & getDesc() const
Definition: MachineInstr.h:257
static void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, DebugLoc dl, unsigned DestReg, unsigned BaseReg, int NumBytes, bool CanChangeCC, const TargetInstrInfo &TII, const ARMBaseRegisterInfo &MRI, unsigned MIFlags=MachineInstr::NoFlags)
const Function * getFunction() const
bool saveScavengerRegister(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, MachineBasicBlock::iterator &UseMI, const TargetRegisterClass *RC, unsigned Reg) const
uint64_t getStackSize() const
static const MachineInstrBuilder & AddDefaultPred(const MachineInstrBuilder &MIB)
const TargetRegisterClass * getLargestLegalSuperClass(const TargetRegisterClass *RC) const
const HexagonInstrInfo * TII
virtual bool hasFP(const MachineFunction &MF) const =0
#define llvm_unreachable(msg)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool mayLoad(QueryType Type=AnyInBundle) const
Definition: MachineInstr.h:465
bool isUndef() const
const MachineInstrBuilder & addImm(int64_t Val) const
unsigned getNumOperands() const
Definition: MachineInstr.h:265
void RemoveOperand(unsigned i)
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
int getOpcode() const
Definition: MachineInstr.h:261
void eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=NULL) const
int64_t getImm() const
unsigned getKillRegState(bool B)
void ChangeToImmediate(int64_t ImmVal)
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:119
bool isDebugValue() const
Definition: MachineInstr.h:639
unsigned getDefRegState(bool B)
bundle_iterator< MachineInstr, instr_iterator > iterator
static void emitThumbConstant(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, unsigned DestReg, int Imm, const TargetInstrInfo &TII, const Thumb1RegisterInfo &MRI, DebugLoc dl)
bool rewriteFrameIndex(MachineBasicBlock::iterator II, unsigned FrameRegIdx, unsigned FrameReg, int &Offset, const ARMBaseInstrInfo &TII) const
ARMCC::CondCodes getInstrPredicate(const MachineInstr *MI, unsigned &PredReg)
LLVM Constant Representation.
Definition: Constant.h:41
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:267
unsigned getFramePtrSpillOffset() const
ItTy next(ItTy it, Dist n)
Definition: STLExtras.h:154
void emitThumbRegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, DebugLoc dl, unsigned DestReg, unsigned BaseReg, int NumBytes, const TargetInstrInfo &TII, const ARMBaseRegisterInfo &MRI, unsigned MIFlags=0)
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
MachineConstantPool * getConstantPool()
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
virtual const TargetFrameLowering * getFrameLowering() const
Thumb1RegisterInfo(const ARMSubtarget &STI)
const MCInstrDesc & get(unsigned Opcode) const
Definition: MCInstrInfo.h:48
virtual bool hasReservedCallFrame(const MachineFunction &MF) const
int64_t getObjectOffset(int ObjectIdx) const
bool isRegMask() const
isRegMask - Tests if this is a MO_RegisterMask operand.
bool isScavengingFrameIndex(int FI) const
Query whether a frame index is a scavenging frame index.
virtual const TargetInstrInfo * getInstrInfo() const
void setDesc(const MCInstrDesc &tid)
Definition: MachineInstr.h:984
const TargetRegisterClass * getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
Definition: Constants.cpp:492
MachineFrameInfo * getFrameInfo()
static bool clobbersPhysReg(const uint32_t *RegMask, unsigned PhysReg)
bool hasBasePointer(const MachineFunction &MF) const
AddrMode
ARM Addressing Modes.
Definition: ARMBaseInfo.h:234
int findFirstPredOperandIdx() const
static void removeOperands(MachineInstr &MI, unsigned i)
cl::opt< bool > ReuseFrameIndexVals
static bool isARMLowRegister(unsigned Reg)
Definition: ARMBaseInfo.h:209
MachineRegisterInfo & getRegInfo()
static IntegerType * getInt32Ty(LLVMContext &C)
Definition: Type.cpp:241
static unsigned convertToNonSPOpcode(unsigned Opcode)
#define I(x, y, z)
Definition: MD5.cpp:54
const TargetMachine & getTarget() const
bool hasVarSizedObjects() const
virtual void emitLoadConstPool(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, DebugLoc dl, unsigned DestReg, unsigned SubIdx, int Val, ARMCC::CondCodes Pred=ARMCC::AL, unsigned PredReg=0, unsigned MIFlags=MachineInstr::NoFlags) const
static int const Threshold
unsigned getReg() const
getReg - Returns the register number.
const TargetRegisterClass * getLargestLegalSuperClass(const TargetRegisterClass *RC) const
const MCRegisterInfo & MRI
void emitLoadConstPool(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, DebugLoc dl, unsigned DestReg, unsigned SubIdx, int Val, ARMCC::CondCodes Pred=ARMCC::AL, unsigned PredReg=0, unsigned MIFlags=MachineInstr::NoFlags) const
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
unsigned getConstantPoolIndex(const Constant *C, unsigned Alignment)
DebugLoc getDebugLoc() const
Definition: MachineInstr.h:244
static const MachineInstrBuilder & AddDefaultT1CC(const MachineInstrBuilder &MIB, bool isDead=false)