LLVM  4.0.0
Thumb2InstrInfo.cpp
Go to the documentation of this file.
1 //===-- Thumb2InstrInfo.cpp - Thumb-2 Instruction 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-2 implementation of the TargetInstrInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "Thumb2InstrInfo.h"
15 #include "ARMConstantPoolValue.h"
16 #include "ARMMachineFunctionInfo.h"
22 #include "llvm/MC/MCInst.h"
24 
25 using namespace llvm;
26 
27 static cl::opt<bool>
28 OldT2IfCvt("old-thumb2-ifcvt", cl::Hidden,
29  cl::desc("Use old-style Thumb2 if-conversion heuristics"),
30  cl::init(false));
31 
33  : ARMBaseInstrInfo(STI), RI() {}
34 
35 /// getNoopForMachoTarget - Return the noop instruction to use for a noop.
37  NopInst.setOpcode(ARM::tHINT);
38  NopInst.addOperand(MCOperand::createImm(0));
40  NopInst.addOperand(MCOperand::createReg(0));
41 }
42 
43 unsigned Thumb2InstrInfo::getUnindexedOpcode(unsigned Opc) const {
44  // FIXME
45  return 0;
46 }
47 
48 void
50  MachineBasicBlock *NewDest) const {
51  MachineBasicBlock *MBB = Tail->getParent();
53  if (!AFI->hasITBlocks() || Tail->isBranch()) {
55  return;
56  }
57 
58  // If the first instruction of Tail is predicated, we may have to update
59  // the IT instruction.
60  unsigned PredReg = 0;
61  ARMCC::CondCodes CC = getInstrPredicate(*Tail, PredReg);
62  MachineBasicBlock::iterator MBBI = Tail;
63  if (CC != ARMCC::AL)
64  // Expecting at least the t2IT instruction before it.
65  --MBBI;
66 
67  // Actually replace the tail.
69 
70  // Fix up IT.
71  if (CC != ARMCC::AL) {
73  unsigned Count = 4; // At most 4 instructions in an IT block.
74  while (Count && MBBI != E) {
75  if (MBBI->isDebugValue()) {
76  --MBBI;
77  continue;
78  }
79  if (MBBI->getOpcode() == ARM::t2IT) {
80  unsigned Mask = MBBI->getOperand(1).getImm();
81  if (Count == 4)
82  MBBI->eraseFromParent();
83  else {
84  unsigned MaskOn = 1 << Count;
85  unsigned MaskOff = ~(MaskOn - 1);
86  MBBI->getOperand(1).setImm((Mask & MaskOff) | MaskOn);
87  }
88  return;
89  }
90  --MBBI;
91  --Count;
92  }
93 
94  // Ctrl flow can reach here if branch folding is run before IT block
95  // formation pass.
96  }
97 }
98 
99 bool
101  MachineBasicBlock::iterator MBBI) const {
102  while (MBBI->isDebugValue()) {
103  ++MBBI;
104  if (MBBI == MBB.end())
105  return false;
106  }
107 
108  unsigned PredReg = 0;
109  return getITInstrPredicate(*MBBI, PredReg) == ARMCC::AL;
110 }
111 
114  const DebugLoc &DL, unsigned DestReg,
115  unsigned SrcReg, bool KillSrc) const {
116  // Handle SPR, DPR, and QPR copies.
117  if (!ARM::GPRRegClass.contains(DestReg, SrcReg))
118  return ARMBaseInstrInfo::copyPhysReg(MBB, I, DL, DestReg, SrcReg, KillSrc);
119 
120  AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::tMOVr), DestReg)
121  .addReg(SrcReg, getKillRegState(KillSrc)));
122 }
123 
126  unsigned SrcReg, bool isKill, int FI,
127  const TargetRegisterClass *RC,
128  const TargetRegisterInfo *TRI) const {
129  DebugLoc DL;
130  if (I != MBB.end()) DL = I->getDebugLoc();
131 
132  MachineFunction &MF = *MBB.getParent();
133  MachineFrameInfo &MFI = MF.getFrameInfo();
136  MFI.getObjectSize(FI), MFI.getObjectAlignment(FI));
137 
138  if (RC == &ARM::GPRRegClass || RC == &ARM::tGPRRegClass ||
139  RC == &ARM::tcGPRRegClass || RC == &ARM::rGPRRegClass ||
140  RC == &ARM::GPRnopcRegClass) {
141  AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::t2STRi12))
142  .addReg(SrcReg, getKillRegState(isKill))
143  .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
144  return;
145  }
146 
147  if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
148  // Thumb2 STRD expects its dest-registers to be in rGPR. Not a problem for
149  // gsub_0, but needs an extra constraint for gsub_1 (which could be sp
150  // otherwise).
153  MRI->constrainRegClass(SrcReg, &ARM::GPRPair_with_gsub_1_in_rGPRRegClass);
154  }
155 
156  MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::t2STRDi8));
157  AddDReg(MIB, SrcReg, ARM::gsub_0, getKillRegState(isKill), TRI);
158  AddDReg(MIB, SrcReg, ARM::gsub_1, 0, TRI);
159  MIB.addFrameIndex(FI).addImm(0).addMemOperand(MMO);
160  AddDefaultPred(MIB);
161  return;
162  }
163 
164  ARMBaseInstrInfo::storeRegToStackSlot(MBB, I, SrcReg, isKill, FI, RC, TRI);
165 }
166 
169  unsigned DestReg, int FI,
170  const TargetRegisterClass *RC,
171  const TargetRegisterInfo *TRI) const {
172  MachineFunction &MF = *MBB.getParent();
173  MachineFrameInfo &MFI = MF.getFrameInfo();
176  MFI.getObjectSize(FI), MFI.getObjectAlignment(FI));
177  DebugLoc DL;
178  if (I != MBB.end()) DL = I->getDebugLoc();
179 
180  if (RC == &ARM::GPRRegClass || RC == &ARM::tGPRRegClass ||
181  RC == &ARM::tcGPRRegClass || RC == &ARM::rGPRRegClass ||
182  RC == &ARM::GPRnopcRegClass) {
183  AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::t2LDRi12), DestReg)
184  .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
185  return;
186  }
187 
188  if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
189  // Thumb2 LDRD expects its dest-registers to be in rGPR. Not a problem for
190  // gsub_0, but needs an extra constraint for gsub_1 (which could be sp
191  // otherwise).
194  MRI->constrainRegClass(DestReg,
195  &ARM::GPRPair_with_gsub_1_in_rGPRRegClass);
196  }
197 
198  MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::t2LDRDi8));
199  AddDReg(MIB, DestReg, ARM::gsub_0, RegState::DefineNoRead, TRI);
200  AddDReg(MIB, DestReg, ARM::gsub_1, RegState::DefineNoRead, TRI);
201  MIB.addFrameIndex(FI).addImm(0).addMemOperand(MMO);
202  AddDefaultPred(MIB);
203 
205  MIB.addReg(DestReg, RegState::ImplicitDefine);
206  return;
207  }
208 
209  ARMBaseInstrInfo::loadRegFromStackSlot(MBB, I, DestReg, FI, RC, TRI);
210 }
211 
212 void Thumb2InstrInfo::expandLoadStackGuard(
214  MachineFunction &MF = *MI->getParent()->getParent();
215  if (MF.getTarget().isPositionIndependent())
216  expandLoadStackGuardBase(MI, ARM::t2MOV_ga_pcrel, ARM::t2LDRi12);
217  else
218  expandLoadStackGuardBase(MI, ARM::t2MOVi32imm, ARM::t2LDRi12);
219 }
220 
223  const DebugLoc &dl, unsigned DestReg,
224  unsigned BaseReg, int NumBytes,
225  ARMCC::CondCodes Pred, unsigned PredReg,
226  const ARMBaseInstrInfo &TII,
227  unsigned MIFlags) {
228  if (NumBytes == 0 && DestReg != BaseReg) {
229  BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
230  .addReg(BaseReg, RegState::Kill)
231  .addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags);
232  return;
233  }
234 
235  bool isSub = NumBytes < 0;
236  if (isSub) NumBytes = -NumBytes;
237 
238  // If profitable, use a movw or movt to materialize the offset.
239  // FIXME: Use the scavenger to grab a scratch register.
240  if (DestReg != ARM::SP && DestReg != BaseReg &&
241  NumBytes >= 4096 &&
242  ARM_AM::getT2SOImmVal(NumBytes) == -1) {
243  bool Fits = false;
244  if (NumBytes < 65536) {
245  // Use a movw to materialize the 16-bit constant.
246  BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi16), DestReg)
247  .addImm(NumBytes)
248  .addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags);
249  Fits = true;
250  } else if ((NumBytes & 0xffff) == 0) {
251  // Use a movt to materialize the 32-bit constant.
252  BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVTi16), DestReg)
253  .addReg(DestReg)
254  .addImm(NumBytes >> 16)
255  .addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags);
256  Fits = true;
257  }
258 
259  if (Fits) {
260  if (isSub) {
261  BuildMI(MBB, MBBI, dl, TII.get(ARM::t2SUBrr), DestReg)
262  .addReg(BaseReg)
263  .addReg(DestReg, RegState::Kill)
264  .addImm((unsigned)Pred).addReg(PredReg).addReg(0)
265  .setMIFlags(MIFlags);
266  } else {
267  // Here we know that DestReg is not SP but we do not
268  // know anything about BaseReg. t2ADDrr is an invalid
269  // instruction is SP is used as the second argument, but
270  // is fine if SP is the first argument. To be sure we
271  // do not generate invalid encoding, put BaseReg first.
272  BuildMI(MBB, MBBI, dl, TII.get(ARM::t2ADDrr), DestReg)
273  .addReg(BaseReg)
274  .addReg(DestReg, RegState::Kill)
275  .addImm((unsigned)Pred).addReg(PredReg).addReg(0)
276  .setMIFlags(MIFlags);
277  }
278  return;
279  }
280  }
281 
282  while (NumBytes) {
283  unsigned ThisVal = NumBytes;
284  unsigned Opc = 0;
285  if (DestReg == ARM::SP && BaseReg != ARM::SP) {
286  // mov sp, rn. Note t2MOVr cannot be used.
287  AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr),DestReg)
288  .addReg(BaseReg).setMIFlags(MIFlags));
289  BaseReg = ARM::SP;
290  continue;
291  }
292 
293  bool HasCCOut = true;
294  if (BaseReg == ARM::SP) {
295  // sub sp, sp, #imm7
296  if (DestReg == ARM::SP && (ThisVal < ((1 << 7)-1) * 4)) {
297  assert((ThisVal & 3) == 0 && "Stack update is not multiple of 4?");
298  Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
299  AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
300  .addReg(BaseReg).addImm(ThisVal/4).setMIFlags(MIFlags));
301  NumBytes = 0;
302  continue;
303  }
304 
305  // sub rd, sp, so_imm
306  Opc = isSub ? ARM::t2SUBri : ARM::t2ADDri;
307  if (ARM_AM::getT2SOImmVal(NumBytes) != -1) {
308  NumBytes = 0;
309  } else {
310  // FIXME: Move this to ARMAddressingModes.h?
311  unsigned RotAmt = countLeadingZeros(ThisVal);
312  ThisVal = ThisVal & ARM_AM::rotr32(0xff000000U, RotAmt);
313  NumBytes &= ~ThisVal;
314  assert(ARM_AM::getT2SOImmVal(ThisVal) != -1 &&
315  "Bit extraction didn't work?");
316  }
317  } else {
318  assert(DestReg != ARM::SP && BaseReg != ARM::SP);
319  Opc = isSub ? ARM::t2SUBri : ARM::t2ADDri;
320  if (ARM_AM::getT2SOImmVal(NumBytes) != -1) {
321  NumBytes = 0;
322  } else if (ThisVal < 4096) {
323  Opc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12;
324  HasCCOut = false;
325  NumBytes = 0;
326  } else {
327  // FIXME: Move this to ARMAddressingModes.h?
328  unsigned RotAmt = countLeadingZeros(ThisVal);
329  ThisVal = ThisVal & ARM_AM::rotr32(0xff000000U, RotAmt);
330  NumBytes &= ~ThisVal;
331  assert(ARM_AM::getT2SOImmVal(ThisVal) != -1 &&
332  "Bit extraction didn't work?");
333  }
334  }
335 
336  // Build the new ADD / SUB.
337  MachineInstrBuilder MIB =
338  AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
339  .addReg(BaseReg, RegState::Kill)
340  .addImm(ThisVal)).setMIFlags(MIFlags);
341  if (HasCCOut)
342  AddDefaultCC(MIB);
343 
344  BaseReg = DestReg;
345  }
346 }
347 
348 static unsigned
349 negativeOffsetOpcode(unsigned opcode)
350 {
351  switch (opcode) {
352  case ARM::t2LDRi12: return ARM::t2LDRi8;
353  case ARM::t2LDRHi12: return ARM::t2LDRHi8;
354  case ARM::t2LDRBi12: return ARM::t2LDRBi8;
355  case ARM::t2LDRSHi12: return ARM::t2LDRSHi8;
356  case ARM::t2LDRSBi12: return ARM::t2LDRSBi8;
357  case ARM::t2STRi12: return ARM::t2STRi8;
358  case ARM::t2STRBi12: return ARM::t2STRBi8;
359  case ARM::t2STRHi12: return ARM::t2STRHi8;
360  case ARM::t2PLDi12: return ARM::t2PLDi8;
361 
362  case ARM::t2LDRi8:
363  case ARM::t2LDRHi8:
364  case ARM::t2LDRBi8:
365  case ARM::t2LDRSHi8:
366  case ARM::t2LDRSBi8:
367  case ARM::t2STRi8:
368  case ARM::t2STRBi8:
369  case ARM::t2STRHi8:
370  case ARM::t2PLDi8:
371  return opcode;
372 
373  default:
374  break;
375  }
376 
377  return 0;
378 }
379 
380 static unsigned
381 positiveOffsetOpcode(unsigned opcode)
382 {
383  switch (opcode) {
384  case ARM::t2LDRi8: return ARM::t2LDRi12;
385  case ARM::t2LDRHi8: return ARM::t2LDRHi12;
386  case ARM::t2LDRBi8: return ARM::t2LDRBi12;
387  case ARM::t2LDRSHi8: return ARM::t2LDRSHi12;
388  case ARM::t2LDRSBi8: return ARM::t2LDRSBi12;
389  case ARM::t2STRi8: return ARM::t2STRi12;
390  case ARM::t2STRBi8: return ARM::t2STRBi12;
391  case ARM::t2STRHi8: return ARM::t2STRHi12;
392  case ARM::t2PLDi8: return ARM::t2PLDi12;
393 
394  case ARM::t2LDRi12:
395  case ARM::t2LDRHi12:
396  case ARM::t2LDRBi12:
397  case ARM::t2LDRSHi12:
398  case ARM::t2LDRSBi12:
399  case ARM::t2STRi12:
400  case ARM::t2STRBi12:
401  case ARM::t2STRHi12:
402  case ARM::t2PLDi12:
403  return opcode;
404 
405  default:
406  break;
407  }
408 
409  return 0;
410 }
411 
412 static unsigned
413 immediateOffsetOpcode(unsigned opcode)
414 {
415  switch (opcode) {
416  case ARM::t2LDRs: return ARM::t2LDRi12;
417  case ARM::t2LDRHs: return ARM::t2LDRHi12;
418  case ARM::t2LDRBs: return ARM::t2LDRBi12;
419  case ARM::t2LDRSHs: return ARM::t2LDRSHi12;
420  case ARM::t2LDRSBs: return ARM::t2LDRSBi12;
421  case ARM::t2STRs: return ARM::t2STRi12;
422  case ARM::t2STRBs: return ARM::t2STRBi12;
423  case ARM::t2STRHs: return ARM::t2STRHi12;
424  case ARM::t2PLDs: return ARM::t2PLDi12;
425 
426  case ARM::t2LDRi12:
427  case ARM::t2LDRHi12:
428  case ARM::t2LDRBi12:
429  case ARM::t2LDRSHi12:
430  case ARM::t2LDRSBi12:
431  case ARM::t2STRi12:
432  case ARM::t2STRBi12:
433  case ARM::t2STRHi12:
434  case ARM::t2PLDi12:
435  case ARM::t2LDRi8:
436  case ARM::t2LDRHi8:
437  case ARM::t2LDRBi8:
438  case ARM::t2LDRSHi8:
439  case ARM::t2LDRSBi8:
440  case ARM::t2STRi8:
441  case ARM::t2STRBi8:
442  case ARM::t2STRHi8:
443  case ARM::t2PLDi8:
444  return opcode;
445 
446  default:
447  break;
448  }
449 
450  return 0;
451 }
452 
453 bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
454  unsigned FrameReg, int &Offset,
455  const ARMBaseInstrInfo &TII) {
456  unsigned Opcode = MI.getOpcode();
457  const MCInstrDesc &Desc = MI.getDesc();
458  unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
459  bool isSub = false;
460 
461  // Memory operands in inline assembly always use AddrModeT2_i12.
462  if (Opcode == ARM::INLINEASM)
463  AddrMode = ARMII::AddrModeT2_i12; // FIXME. mode for thumb2?
464 
465  if (Opcode == ARM::t2ADDri || Opcode == ARM::t2ADDri12) {
466  Offset += MI.getOperand(FrameRegIdx+1).getImm();
467 
468  unsigned PredReg;
469  if (Offset == 0 && getInstrPredicate(MI, PredReg) == ARMCC::AL) {
470  // Turn it into a move.
471  MI.setDesc(TII.get(ARM::tMOVr));
472  MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
473  // Remove offset and remaining explicit predicate operands.
474  do MI.RemoveOperand(FrameRegIdx+1);
475  while (MI.getNumOperands() > FrameRegIdx+1);
476  MachineInstrBuilder MIB(*MI.getParent()->getParent(), &MI);
477  AddDefaultPred(MIB);
478  return true;
479  }
480 
481  bool HasCCOut = Opcode != ARM::t2ADDri12;
482 
483  if (Offset < 0) {
484  Offset = -Offset;
485  isSub = true;
486  MI.setDesc(TII.get(ARM::t2SUBri));
487  } else {
488  MI.setDesc(TII.get(ARM::t2ADDri));
489  }
490 
491  // Common case: small offset, fits into instruction.
492  if (ARM_AM::getT2SOImmVal(Offset) != -1) {
493  MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
494  MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
495  // Add cc_out operand if the original instruction did not have one.
496  if (!HasCCOut)
498  Offset = 0;
499  return true;
500  }
501  // Another common case: imm12.
502  if (Offset < 4096 &&
503  (!HasCCOut || MI.getOperand(MI.getNumOperands()-1).getReg() == 0)) {
504  unsigned NewOpc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12;
505  MI.setDesc(TII.get(NewOpc));
506  MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
507  MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
508  // Remove the cc_out operand.
509  if (HasCCOut)
510  MI.RemoveOperand(MI.getNumOperands()-1);
511  Offset = 0;
512  return true;
513  }
514 
515  // Otherwise, extract 8 adjacent bits from the immediate into this
516  // t2ADDri/t2SUBri.
517  unsigned RotAmt = countLeadingZeros<unsigned>(Offset);
518  unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xff000000U, RotAmt);
519 
520  // We will handle these bits from offset, clear them.
521  Offset &= ~ThisImmVal;
522 
523  assert(ARM_AM::getT2SOImmVal(ThisImmVal) != -1 &&
524  "Bit extraction didn't work?");
525  MI.getOperand(FrameRegIdx+1).ChangeToImmediate(ThisImmVal);
526  // Add cc_out operand if the original instruction did not have one.
527  if (!HasCCOut)
529 
530  } else {
531 
532  // AddrMode4 and AddrMode6 cannot handle any offset.
533  if (AddrMode == ARMII::AddrMode4 || AddrMode == ARMII::AddrMode6)
534  return false;
535 
536  // AddrModeT2_so cannot handle any offset. If there is no offset
537  // register then we change to an immediate version.
538  unsigned NewOpc = Opcode;
539  if (AddrMode == ARMII::AddrModeT2_so) {
540  unsigned OffsetReg = MI.getOperand(FrameRegIdx+1).getReg();
541  if (OffsetReg != 0) {
542  MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
543  return Offset == 0;
544  }
545 
546  MI.RemoveOperand(FrameRegIdx+1);
547  MI.getOperand(FrameRegIdx+1).ChangeToImmediate(0);
548  NewOpc = immediateOffsetOpcode(Opcode);
549  AddrMode = ARMII::AddrModeT2_i12;
550  }
551 
552  unsigned NumBits = 0;
553  unsigned Scale = 1;
554  if (AddrMode == ARMII::AddrModeT2_i8 || AddrMode == ARMII::AddrModeT2_i12) {
555  // i8 supports only negative, and i12 supports only positive, so
556  // based on Offset sign convert Opcode to the appropriate
557  // instruction
558  Offset += MI.getOperand(FrameRegIdx+1).getImm();
559  if (Offset < 0) {
560  NewOpc = negativeOffsetOpcode(Opcode);
561  NumBits = 8;
562  isSub = true;
563  Offset = -Offset;
564  } else {
565  NewOpc = positiveOffsetOpcode(Opcode);
566  NumBits = 12;
567  }
568  } else if (AddrMode == ARMII::AddrMode5) {
569  // VFP address mode.
570  const MachineOperand &OffOp = MI.getOperand(FrameRegIdx+1);
571  int InstrOffs = ARM_AM::getAM5Offset(OffOp.getImm());
572  if (ARM_AM::getAM5Op(OffOp.getImm()) == ARM_AM::sub)
573  InstrOffs *= -1;
574  NumBits = 8;
575  Scale = 4;
576  Offset += InstrOffs * 4;
577  assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
578  if (Offset < 0) {
579  Offset = -Offset;
580  isSub = true;
581  }
582  } else if (AddrMode == ARMII::AddrModeT2_i8s4) {
583  Offset += MI.getOperand(FrameRegIdx + 1).getImm() * 4;
584  NumBits = 10; // 8 bits scaled by 4
585  // MCInst operand expects already scaled value.
586  Scale = 1;
587  assert((Offset & 3) == 0 && "Can't encode this offset!");
588  } else {
589  llvm_unreachable("Unsupported addressing mode!");
590  }
591 
592  if (NewOpc != Opcode)
593  MI.setDesc(TII.get(NewOpc));
594 
595  MachineOperand &ImmOp = MI.getOperand(FrameRegIdx+1);
596 
597  // Attempt to fold address computation
598  // Common case: small offset, fits into instruction.
599  int ImmedOffset = Offset / Scale;
600  unsigned Mask = (1 << NumBits) - 1;
601  if ((unsigned)Offset <= Mask * Scale) {
602  // Replace the FrameIndex with fp/sp
603  MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
604  if (isSub) {
605  if (AddrMode == ARMII::AddrMode5)
606  // FIXME: Not consistent.
607  ImmedOffset |= 1 << NumBits;
608  else
609  ImmedOffset = -ImmedOffset;
610  }
611  ImmOp.ChangeToImmediate(ImmedOffset);
612  Offset = 0;
613  return true;
614  }
615 
616  // Otherwise, offset doesn't fit. Pull in what we can to simplify
617  ImmedOffset = ImmedOffset & Mask;
618  if (isSub) {
619  if (AddrMode == ARMII::AddrMode5)
620  // FIXME: Not consistent.
621  ImmedOffset |= 1 << NumBits;
622  else {
623  ImmedOffset = -ImmedOffset;
624  if (ImmedOffset == 0)
625  // Change the opcode back if the encoded offset is zero.
626  MI.setDesc(TII.get(positiveOffsetOpcode(NewOpc)));
627  }
628  }
629  ImmOp.ChangeToImmediate(ImmedOffset);
630  Offset &= ~(Mask*Scale);
631  }
632 
633  Offset = (isSub) ? -Offset : Offset;
634  return Offset == 0;
635 }
636 
638  unsigned &PredReg) {
639  unsigned Opc = MI.getOpcode();
640  if (Opc == ARM::tBcc || Opc == ARM::t2Bcc)
641  return ARMCC::AL;
642  return getInstrPredicate(MI, PredReg);
643 }
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
void ChangeToRegister(unsigned Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isDebug=false)
ChangeToRegister - Replace this operand with a new register operand of the specified value...
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:163
MachineInstrBuilder MachineInstrBuilder &DefMI const MCInstrDesc & Desc
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
static unsigned negativeOffsetOpcode(unsigned opcode)
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
Definition: MachineInstr.h:270
A debug info location.
Definition: DebugLoc.h:34
void expandLoadStackGuardBase(MachineBasicBlock::iterator MI, unsigned LoadImmOpc, unsigned LoadOpc) const
std::size_t countLeadingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the most significant bit to the least stopping at the first 1...
Definition: MathExtras.h:180
return AArch64::GPR64RegClass contains(Reg)
void getNoopForMachoTarget(MCInst &NopInst) const override
getNoopForMachoTarget - Return the noop instruction to use for a noop.
static unsigned rotr32(unsigned Val, unsigned Amt)
rotr32 - Rotate a 32-bit unsigned value right by a specified # bits.
static cl::opt< bool > OldT2IfCvt("old-thumb2-ifcvt", cl::Hidden, cl::desc("Use old-style Thumb2 if-conversion heuristics"), cl::init(false))
bool isLegalToSplitMBBAt(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) const override
A description of a memory reference used in the backend.
static const MachineInstrBuilder & AddDefaultPred(const MachineInstrBuilder &MIB)
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:111
const HexagonInstrInfo * TII
static MachineOperand CreateReg(unsigned Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false)
void emitT2RegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &dl, unsigned DestReg, unsigned BaseReg, int NumBytes, ARMCC::CondCodes Pred, unsigned PredReg, const ARMBaseInstrInfo &TII, unsigned MIFlags=0)
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
bool rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, unsigned FrameReg, int &Offset, const ARMBaseInstrInfo &TII)
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
INLINEASM - Represents an inline asm block.
Definition: ISDOpcodes.h:589
unsigned getNumOperands() const
Access to explicit operands of the instruction.
Definition: MachineInstr.h:277
void RemoveOperand(unsigned i)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
MachineBasicBlock * MBB
static int getT2SOImmVal(unsigned Arg)
getT2SOImmVal - Given a 32-bit immediate, if it is something that can fit into a Thumb-2 shifter_oper...
int64_t getImm() const
const TargetRegisterClass * constrainRegClass(unsigned Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
constrainRegClass - Constrain the register class of the specified virtual register to be a common sub...
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:150
unsigned getKillRegState(bool B)
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const override
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:273
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
void ChangeToImmediate(int64_t ImmVal)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value...
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:131
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned getUnindexedOpcode(unsigned Opc) const override
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:395
unsigned const MachineRegisterInfo * MRI
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
static unsigned char getAM5Offset(unsigned AM5Opc)
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:279
uint32_t Offset
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
bool isPositionIndependent() const
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Thumb2InstrInfo(const ARMSubtarget &STI)
static unsigned immediateOffsetOpcode(unsigned opcode)
ARMCC::CondCodes getInstrPredicate(const MachineInstr &MI, unsigned &PredReg)
getInstrPredicate - If instruction is predicated, returns its predicate condition, otherwise returns AL.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
The memory access writes data.
static const MachineInstrBuilder & AddDefaultCC(const MachineInstrBuilder &MIB)
void setOpcode(unsigned Op)
Definition: MCInst.h:158
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
ARMCC::CondCodes getITInstrPredicate(const MachineInstr &MI, unsigned &PredReg)
getITInstrPredicate - Valid only in Thumb2 mode.
MachineOperand class - Representation of each machine instruction operand.
unsigned getObjectAlignment(int ObjectIdx) const
Return the alignment of the specified stack object.
void ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail, MachineBasicBlock *NewDest) const override
const MachineInstrBuilder & addFrameIndex(int Idx) const
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, unsigned base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SynchronizationScope SynchScope=CrossThread, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
AddrMode
ARM Addressing Modes.
Definition: ARMBaseInfo.h:235
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
The memory access reads data.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
Representation of each machine instruction.
Definition: MachineInstr.h:52
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
static unsigned positiveOffsetOpcode(unsigned opcode)
ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
#define I(x, y, z)
Definition: MD5.cpp:54
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
static AddrOpc getAM5Op(unsigned AM5Opc)
unsigned getReg() const
getReg - Returns the register number.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Definition: BitmaskEnum.h:81
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const override
IRTranslator LLVM IR MI
void addOperand(const MCOperand &Op)
Definition: MCInst.h:168
virtual void ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail, MachineBasicBlock *NewDest) const
Delete the instruction OldInst and everything after it, replacing it with an unconditional branch to ...
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:117
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
const MachineInstrBuilder & AddDReg(MachineInstrBuilder &MIB, unsigned Reg, unsigned SubIdx, unsigned State, const TargetRegisterInfo *TRI) const