LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 "ARM.h"
16 #include "ARMConstantPoolValue.h"
17 #include "ARMMachineFunctionInfo.h"
23 #include "llvm/MC/MCInst.h"
25 
26 using namespace llvm;
27 
28 static cl::opt<bool>
29 OldT2IfCvt("old-thumb2-ifcvt", cl::Hidden,
30  cl::desc("Use old-style Thumb2 if-conversion heuristics"),
31  cl::init(false));
32 
34  : ARMBaseInstrInfo(STI), RI(STI) {
35 }
36 
37 /// getNoopForMachoTarget - Return the noop instruction to use for a noop.
39  NopInst.setOpcode(ARM::tHINT);
40  NopInst.addOperand(MCOperand::CreateImm(0));
42  NopInst.addOperand(MCOperand::CreateReg(0));
43 }
44 
45 unsigned Thumb2InstrInfo::getUnindexedOpcode(unsigned Opc) const {
46  // FIXME
47  return 0;
48 }
49 
50 void
52  MachineBasicBlock *NewDest) const {
53  MachineBasicBlock *MBB = Tail->getParent();
55  if (!AFI->hasITBlocks()) {
57  return;
58  }
59 
60  // If the first instruction of Tail is predicated, we may have to update
61  // the IT instruction.
62  unsigned PredReg = 0;
63  ARMCC::CondCodes CC = getInstrPredicate(Tail, PredReg);
64  MachineBasicBlock::iterator MBBI = Tail;
65  if (CC != ARMCC::AL)
66  // Expecting at least the t2IT instruction before it.
67  --MBBI;
68 
69  // Actually replace the tail.
71 
72  // Fix up IT.
73  if (CC != ARMCC::AL) {
75  unsigned Count = 4; // At most 4 instructions in an IT block.
76  while (Count && MBBI != E) {
77  if (MBBI->isDebugValue()) {
78  --MBBI;
79  continue;
80  }
81  if (MBBI->getOpcode() == ARM::t2IT) {
82  unsigned Mask = MBBI->getOperand(1).getImm();
83  if (Count == 4)
84  MBBI->eraseFromParent();
85  else {
86  unsigned MaskOn = 1 << Count;
87  unsigned MaskOff = ~(MaskOn - 1);
88  MBBI->getOperand(1).setImm((Mask & MaskOff) | MaskOn);
89  }
90  return;
91  }
92  --MBBI;
93  --Count;
94  }
95 
96  // Ctrl flow can reach here if branch folding is run before IT block
97  // formation pass.
98  }
99 }
100 
101 bool
103  MachineBasicBlock::iterator MBBI) const {
104  while (MBBI->isDebugValue()) {
105  ++MBBI;
106  if (MBBI == MBB.end())
107  return false;
108  }
109 
110  unsigned PredReg = 0;
111  return getITInstrPredicate(MBBI, PredReg) == ARMCC::AL;
112 }
113 
116  unsigned DestReg, unsigned SrcReg,
117  bool KillSrc) const {
118  // Handle SPR, DPR, and QPR copies.
119  if (!ARM::GPRRegClass.contains(DestReg, SrcReg))
120  return ARMBaseInstrInfo::copyPhysReg(MBB, I, DL, DestReg, SrcReg, KillSrc);
121 
122  AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::tMOVr), DestReg)
123  .addReg(SrcReg, getKillRegState(KillSrc)));
124 }
125 
128  unsigned SrcReg, bool isKill, int FI,
129  const TargetRegisterClass *RC,
130  const TargetRegisterInfo *TRI) const {
131  DebugLoc DL;
132  if (I != MBB.end()) DL = I->getDebugLoc();
133 
134  MachineFunction &MF = *MBB.getParent();
135  MachineFrameInfo &MFI = *MF.getFrameInfo();
136  MachineMemOperand *MMO =
139  MFI.getObjectSize(FI),
140  MFI.getObjectAlignment(FI));
141 
142  if (RC == &ARM::GPRRegClass || RC == &ARM::tGPRRegClass ||
143  RC == &ARM::tcGPRRegClass || RC == &ARM::rGPRRegClass ||
144  RC == &ARM::GPRnopcRegClass) {
145  AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::t2STRi12))
146  .addReg(SrcReg, getKillRegState(isKill))
147  .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
148  return;
149  }
150 
151  if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
152  // Thumb2 STRD expects its dest-registers to be in rGPR. Not a problem for
153  // gsub_0, but needs an extra constraint for gsub_1 (which could be sp
154  // otherwise).
156  MRI->constrainRegClass(SrcReg, &ARM::GPRPair_with_gsub_1_in_rGPRRegClass);
157 
158  MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::t2STRDi8));
159  AddDReg(MIB, SrcReg, ARM::gsub_0, getKillRegState(isKill), TRI);
160  AddDReg(MIB, SrcReg, ARM::gsub_1, 0, TRI);
161  MIB.addFrameIndex(FI).addImm(0).addMemOperand(MMO);
162  AddDefaultPred(MIB);
163  return;
164  }
165 
166  ARMBaseInstrInfo::storeRegToStackSlot(MBB, I, SrcReg, isKill, FI, RC, TRI);
167 }
168 
171  unsigned DestReg, int FI,
172  const TargetRegisterClass *RC,
173  const TargetRegisterInfo *TRI) const {
174  MachineFunction &MF = *MBB.getParent();
175  MachineFrameInfo &MFI = *MF.getFrameInfo();
176  MachineMemOperand *MMO =
179  MFI.getObjectSize(FI),
180  MFI.getObjectAlignment(FI));
181  DebugLoc DL;
182  if (I != MBB.end()) DL = I->getDebugLoc();
183 
184  if (RC == &ARM::GPRRegClass || RC == &ARM::tGPRRegClass ||
185  RC == &ARM::tcGPRRegClass || RC == &ARM::rGPRRegClass ||
186  RC == &ARM::GPRnopcRegClass) {
187  AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::t2LDRi12), DestReg)
188  .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
189  return;
190  }
191 
192  if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
193  // Thumb2 LDRD expects its dest-registers to be in rGPR. Not a problem for
194  // gsub_0, but needs an extra constraint for gsub_1 (which could be sp
195  // otherwise).
197  MRI->constrainRegClass(DestReg, &ARM::GPRPair_with_gsub_1_in_rGPRRegClass);
198 
199  MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::t2LDRDi8));
200  AddDReg(MIB, DestReg, ARM::gsub_0, RegState::DefineNoRead, TRI);
201  AddDReg(MIB, DestReg, ARM::gsub_1, RegState::DefineNoRead, TRI);
202  MIB.addFrameIndex(FI).addImm(0).addMemOperand(MMO);
203  AddDefaultPred(MIB);
204 
206  MIB.addReg(DestReg, RegState::ImplicitDefine);
207  return;
208  }
209 
210  ARMBaseInstrInfo::loadRegFromStackSlot(MBB, I, DestReg, FI, RC, TRI);
211 }
212 
215  unsigned DestReg, unsigned BaseReg, int NumBytes,
216  ARMCC::CondCodes Pred, unsigned PredReg,
217  const ARMBaseInstrInfo &TII, unsigned MIFlags) {
218  if (NumBytes == 0 && DestReg != BaseReg) {
219  BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
220  .addReg(BaseReg, RegState::Kill)
221  .addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags);
222  return;
223  }
224 
225  bool isSub = NumBytes < 0;
226  if (isSub) NumBytes = -NumBytes;
227 
228  // If profitable, use a movw or movt to materialize the offset.
229  // FIXME: Use the scavenger to grab a scratch register.
230  if (DestReg != ARM::SP && DestReg != BaseReg &&
231  NumBytes >= 4096 &&
232  ARM_AM::getT2SOImmVal(NumBytes) == -1) {
233  bool Fits = false;
234  if (NumBytes < 65536) {
235  // Use a movw to materialize the 16-bit constant.
236  BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi16), DestReg)
237  .addImm(NumBytes)
238  .addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags);
239  Fits = true;
240  } else if ((NumBytes & 0xffff) == 0) {
241  // Use a movt to materialize the 32-bit constant.
242  BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVTi16), DestReg)
243  .addReg(DestReg)
244  .addImm(NumBytes >> 16)
245  .addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags);
246  Fits = true;
247  }
248 
249  if (Fits) {
250  if (isSub) {
251  BuildMI(MBB, MBBI, dl, TII.get(ARM::t2SUBrr), DestReg)
252  .addReg(BaseReg, RegState::Kill)
253  .addReg(DestReg, RegState::Kill)
254  .addImm((unsigned)Pred).addReg(PredReg).addReg(0)
255  .setMIFlags(MIFlags);
256  } else {
257  BuildMI(MBB, MBBI, dl, TII.get(ARM::t2ADDrr), DestReg)
258  .addReg(DestReg, RegState::Kill)
259  .addReg(BaseReg, RegState::Kill)
260  .addImm((unsigned)Pred).addReg(PredReg).addReg(0)
261  .setMIFlags(MIFlags);
262  }
263  return;
264  }
265  }
266 
267  while (NumBytes) {
268  unsigned ThisVal = NumBytes;
269  unsigned Opc = 0;
270  if (DestReg == ARM::SP && BaseReg != ARM::SP) {
271  // mov sp, rn. Note t2MOVr cannot be used.
272  AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr),DestReg)
273  .addReg(BaseReg).setMIFlags(MIFlags));
274  BaseReg = ARM::SP;
275  continue;
276  }
277 
278  bool HasCCOut = true;
279  if (BaseReg == ARM::SP) {
280  // sub sp, sp, #imm7
281  if (DestReg == ARM::SP && (ThisVal < ((1 << 7)-1) * 4)) {
282  assert((ThisVal & 3) == 0 && "Stack update is not multiple of 4?");
283  Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
284  AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
285  .addReg(BaseReg).addImm(ThisVal/4).setMIFlags(MIFlags));
286  NumBytes = 0;
287  continue;
288  }
289 
290  // sub rd, sp, so_imm
291  Opc = isSub ? ARM::t2SUBri : ARM::t2ADDri;
292  if (ARM_AM::getT2SOImmVal(NumBytes) != -1) {
293  NumBytes = 0;
294  } else {
295  // FIXME: Move this to ARMAddressingModes.h?
296  unsigned RotAmt = countLeadingZeros(ThisVal);
297  ThisVal = ThisVal & ARM_AM::rotr32(0xff000000U, RotAmt);
298  NumBytes &= ~ThisVal;
299  assert(ARM_AM::getT2SOImmVal(ThisVal) != -1 &&
300  "Bit extraction didn't work?");
301  }
302  } else {
303  assert(DestReg != ARM::SP && BaseReg != ARM::SP);
304  Opc = isSub ? ARM::t2SUBri : ARM::t2ADDri;
305  if (ARM_AM::getT2SOImmVal(NumBytes) != -1) {
306  NumBytes = 0;
307  } else if (ThisVal < 4096) {
308  Opc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12;
309  HasCCOut = false;
310  NumBytes = 0;
311  } else {
312  // FIXME: Move this to ARMAddressingModes.h?
313  unsigned RotAmt = countLeadingZeros(ThisVal);
314  ThisVal = ThisVal & ARM_AM::rotr32(0xff000000U, RotAmt);
315  NumBytes &= ~ThisVal;
316  assert(ARM_AM::getT2SOImmVal(ThisVal) != -1 &&
317  "Bit extraction didn't work?");
318  }
319  }
320 
321  // Build the new ADD / SUB.
322  MachineInstrBuilder MIB =
323  AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
324  .addReg(BaseReg, RegState::Kill)
325  .addImm(ThisVal)).setMIFlags(MIFlags);
326  if (HasCCOut)
327  AddDefaultCC(MIB);
328 
329  BaseReg = DestReg;
330  }
331 }
332 
333 static unsigned
334 negativeOffsetOpcode(unsigned opcode)
335 {
336  switch (opcode) {
337  case ARM::t2LDRi12: return ARM::t2LDRi8;
338  case ARM::t2LDRHi12: return ARM::t2LDRHi8;
339  case ARM::t2LDRBi12: return ARM::t2LDRBi8;
340  case ARM::t2LDRSHi12: return ARM::t2LDRSHi8;
341  case ARM::t2LDRSBi12: return ARM::t2LDRSBi8;
342  case ARM::t2STRi12: return ARM::t2STRi8;
343  case ARM::t2STRBi12: return ARM::t2STRBi8;
344  case ARM::t2STRHi12: return ARM::t2STRHi8;
345  case ARM::t2PLDi12: return ARM::t2PLDi8;
346 
347  case ARM::t2LDRi8:
348  case ARM::t2LDRHi8:
349  case ARM::t2LDRBi8:
350  case ARM::t2LDRSHi8:
351  case ARM::t2LDRSBi8:
352  case ARM::t2STRi8:
353  case ARM::t2STRBi8:
354  case ARM::t2STRHi8:
355  case ARM::t2PLDi8:
356  return opcode;
357 
358  default:
359  break;
360  }
361 
362  return 0;
363 }
364 
365 static unsigned
366 positiveOffsetOpcode(unsigned opcode)
367 {
368  switch (opcode) {
369  case ARM::t2LDRi8: return ARM::t2LDRi12;
370  case ARM::t2LDRHi8: return ARM::t2LDRHi12;
371  case ARM::t2LDRBi8: return ARM::t2LDRBi12;
372  case ARM::t2LDRSHi8: return ARM::t2LDRSHi12;
373  case ARM::t2LDRSBi8: return ARM::t2LDRSBi12;
374  case ARM::t2STRi8: return ARM::t2STRi12;
375  case ARM::t2STRBi8: return ARM::t2STRBi12;
376  case ARM::t2STRHi8: return ARM::t2STRHi12;
377  case ARM::t2PLDi8: return ARM::t2PLDi12;
378 
379  case ARM::t2LDRi12:
380  case ARM::t2LDRHi12:
381  case ARM::t2LDRBi12:
382  case ARM::t2LDRSHi12:
383  case ARM::t2LDRSBi12:
384  case ARM::t2STRi12:
385  case ARM::t2STRBi12:
386  case ARM::t2STRHi12:
387  case ARM::t2PLDi12:
388  return opcode;
389 
390  default:
391  break;
392  }
393 
394  return 0;
395 }
396 
397 static unsigned
398 immediateOffsetOpcode(unsigned opcode)
399 {
400  switch (opcode) {
401  case ARM::t2LDRs: return ARM::t2LDRi12;
402  case ARM::t2LDRHs: return ARM::t2LDRHi12;
403  case ARM::t2LDRBs: return ARM::t2LDRBi12;
404  case ARM::t2LDRSHs: return ARM::t2LDRSHi12;
405  case ARM::t2LDRSBs: return ARM::t2LDRSBi12;
406  case ARM::t2STRs: return ARM::t2STRi12;
407  case ARM::t2STRBs: return ARM::t2STRBi12;
408  case ARM::t2STRHs: return ARM::t2STRHi12;
409  case ARM::t2PLDs: return ARM::t2PLDi12;
410 
411  case ARM::t2LDRi12:
412  case ARM::t2LDRHi12:
413  case ARM::t2LDRBi12:
414  case ARM::t2LDRSHi12:
415  case ARM::t2LDRSBi12:
416  case ARM::t2STRi12:
417  case ARM::t2STRBi12:
418  case ARM::t2STRHi12:
419  case ARM::t2PLDi12:
420  case ARM::t2LDRi8:
421  case ARM::t2LDRHi8:
422  case ARM::t2LDRBi8:
423  case ARM::t2LDRSHi8:
424  case ARM::t2LDRSBi8:
425  case ARM::t2STRi8:
426  case ARM::t2STRBi8:
427  case ARM::t2STRHi8:
428  case ARM::t2PLDi8:
429  return opcode;
430 
431  default:
432  break;
433  }
434 
435  return 0;
436 }
437 
438 bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
439  unsigned FrameReg, int &Offset,
440  const ARMBaseInstrInfo &TII) {
441  unsigned Opcode = MI.getOpcode();
442  const MCInstrDesc &Desc = MI.getDesc();
443  unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
444  bool isSub = false;
445 
446  // Memory operands in inline assembly always use AddrModeT2_i12.
447  if (Opcode == ARM::INLINEASM)
448  AddrMode = ARMII::AddrModeT2_i12; // FIXME. mode for thumb2?
449 
450  if (Opcode == ARM::t2ADDri || Opcode == ARM::t2ADDri12) {
451  Offset += MI.getOperand(FrameRegIdx+1).getImm();
452 
453  unsigned PredReg;
454  if (Offset == 0 && getInstrPredicate(&MI, PredReg) == ARMCC::AL) {
455  // Turn it into a move.
456  MI.setDesc(TII.get(ARM::tMOVr));
457  MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
458  // Remove offset and remaining explicit predicate operands.
459  do MI.RemoveOperand(FrameRegIdx+1);
460  while (MI.getNumOperands() > FrameRegIdx+1);
461  MachineInstrBuilder MIB(*MI.getParent()->getParent(), &MI);
462  AddDefaultPred(MIB);
463  return true;
464  }
465 
466  bool HasCCOut = Opcode != ARM::t2ADDri12;
467 
468  if (Offset < 0) {
469  Offset = -Offset;
470  isSub = true;
471  MI.setDesc(TII.get(ARM::t2SUBri));
472  } else {
473  MI.setDesc(TII.get(ARM::t2ADDri));
474  }
475 
476  // Common case: small offset, fits into instruction.
477  if (ARM_AM::getT2SOImmVal(Offset) != -1) {
478  MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
479  MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
480  // Add cc_out operand if the original instruction did not have one.
481  if (!HasCCOut)
483  Offset = 0;
484  return true;
485  }
486  // Another common case: imm12.
487  if (Offset < 4096 &&
488  (!HasCCOut || MI.getOperand(MI.getNumOperands()-1).getReg() == 0)) {
489  unsigned NewOpc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12;
490  MI.setDesc(TII.get(NewOpc));
491  MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
492  MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
493  // Remove the cc_out operand.
494  if (HasCCOut)
495  MI.RemoveOperand(MI.getNumOperands()-1);
496  Offset = 0;
497  return true;
498  }
499 
500  // Otherwise, extract 8 adjacent bits from the immediate into this
501  // t2ADDri/t2SUBri.
502  unsigned RotAmt = countLeadingZeros<unsigned>(Offset);
503  unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xff000000U, RotAmt);
504 
505  // We will handle these bits from offset, clear them.
506  Offset &= ~ThisImmVal;
507 
508  assert(ARM_AM::getT2SOImmVal(ThisImmVal) != -1 &&
509  "Bit extraction didn't work?");
510  MI.getOperand(FrameRegIdx+1).ChangeToImmediate(ThisImmVal);
511  // Add cc_out operand if the original instruction did not have one.
512  if (!HasCCOut)
514 
515  } else {
516 
517  // AddrMode4 and AddrMode6 cannot handle any offset.
518  if (AddrMode == ARMII::AddrMode4 || AddrMode == ARMII::AddrMode6)
519  return false;
520 
521  // AddrModeT2_so cannot handle any offset. If there is no offset
522  // register then we change to an immediate version.
523  unsigned NewOpc = Opcode;
524  if (AddrMode == ARMII::AddrModeT2_so) {
525  unsigned OffsetReg = MI.getOperand(FrameRegIdx+1).getReg();
526  if (OffsetReg != 0) {
527  MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
528  return Offset == 0;
529  }
530 
531  MI.RemoveOperand(FrameRegIdx+1);
532  MI.getOperand(FrameRegIdx+1).ChangeToImmediate(0);
533  NewOpc = immediateOffsetOpcode(Opcode);
534  AddrMode = ARMII::AddrModeT2_i12;
535  }
536 
537  unsigned NumBits = 0;
538  unsigned Scale = 1;
539  if (AddrMode == ARMII::AddrModeT2_i8 || AddrMode == ARMII::AddrModeT2_i12) {
540  // i8 supports only negative, and i12 supports only positive, so
541  // based on Offset sign convert Opcode to the appropriate
542  // instruction
543  Offset += MI.getOperand(FrameRegIdx+1).getImm();
544  if (Offset < 0) {
545  NewOpc = negativeOffsetOpcode(Opcode);
546  NumBits = 8;
547  isSub = true;
548  Offset = -Offset;
549  } else {
550  NewOpc = positiveOffsetOpcode(Opcode);
551  NumBits = 12;
552  }
553  } else if (AddrMode == ARMII::AddrMode5) {
554  // VFP address mode.
555  const MachineOperand &OffOp = MI.getOperand(FrameRegIdx+1);
556  int InstrOffs = ARM_AM::getAM5Offset(OffOp.getImm());
557  if (ARM_AM::getAM5Op(OffOp.getImm()) == ARM_AM::sub)
558  InstrOffs *= -1;
559  NumBits = 8;
560  Scale = 4;
561  Offset += InstrOffs * 4;
562  assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
563  if (Offset < 0) {
564  Offset = -Offset;
565  isSub = true;
566  }
567  } else if (AddrMode == ARMII::AddrModeT2_i8s4) {
568  Offset += MI.getOperand(FrameRegIdx + 1).getImm() * 4;
569  NumBits = 8;
570  // MCInst operand has already scaled value.
571  Scale = 1;
572  if (Offset < 0) {
573  isSub = true;
574  Offset = -Offset;
575  }
576  } else {
577  llvm_unreachable("Unsupported addressing mode!");
578  }
579 
580  if (NewOpc != Opcode)
581  MI.setDesc(TII.get(NewOpc));
582 
583  MachineOperand &ImmOp = MI.getOperand(FrameRegIdx+1);
584 
585  // Attempt to fold address computation
586  // Common case: small offset, fits into instruction.
587  int ImmedOffset = Offset / Scale;
588  unsigned Mask = (1 << NumBits) - 1;
589  if ((unsigned)Offset <= Mask * Scale) {
590  // Replace the FrameIndex with fp/sp
591  MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
592  if (isSub) {
593  if (AddrMode == ARMII::AddrMode5)
594  // FIXME: Not consistent.
595  ImmedOffset |= 1 << NumBits;
596  else
597  ImmedOffset = -ImmedOffset;
598  }
599  ImmOp.ChangeToImmediate(ImmedOffset);
600  Offset = 0;
601  return true;
602  }
603 
604  // Otherwise, offset doesn't fit. Pull in what we can to simplify
605  ImmedOffset = ImmedOffset & Mask;
606  if (isSub) {
607  if (AddrMode == ARMII::AddrMode5)
608  // FIXME: Not consistent.
609  ImmedOffset |= 1 << NumBits;
610  else {
611  ImmedOffset = -ImmedOffset;
612  if (ImmedOffset == 0)
613  // Change the opcode back if the encoded offset is zero.
614  MI.setDesc(TII.get(positiveOffsetOpcode(NewOpc)));
615  }
616  }
617  ImmOp.ChangeToImmediate(ImmedOffset);
618  Offset &= ~(Mask*Scale);
619  }
620 
621  Offset = (isSub) ? -Offset : Offset;
622  return Offset == 0;
623 }
624 
626 llvm::getITInstrPredicate(const MachineInstr *MI, unsigned &PredReg) {
627  unsigned Opc = MI->getOpcode();
628  if (Opc == ARM::tBcc || Opc == ARM::t2Bcc)
629  return ARMCC::AL;
630  return getInstrPredicate(MI, PredReg);
631 }
virtual void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const
The memory access reads data.
const MachineFunction * getParent() const
The memory access writes data.
static MCOperand CreateReg(unsigned Reg)
Definition: MCInst.h:111
void ChangeToRegister(unsigned Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isDebug=false)
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, unsigned f, uint64_t s, unsigned base_alignment, const MDNode *TBAAInfo=0, const MDNode *Ranges=0)
void emitT2RegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, DebugLoc dl, unsigned DestReg, unsigned BaseReg, int NumBytes, ARMCC::CondCodes Pred, unsigned PredReg, const ARMBaseInstrInfo &TII, unsigned MIFlags=0)
static unsigned negativeOffsetOpcode(unsigned opcode)
const MCInstrDesc & getDesc() const
Definition: MachineInstr.h:257
void ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail, MachineBasicBlock *NewDest) const
ARMCC::CondCodes getITInstrPredicate(const MachineInstr *MI, unsigned &PredReg)
static MachinePointerInfo getFixedStack(int FI, int64_t offset=0)
static unsigned rotr32(unsigned Val, unsigned Amt)
virtual void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, DebugLoc DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const
static cl::opt< bool > OldT2IfCvt("old-thumb2-ifcvt", cl::Hidden, cl::desc("Use old-style Thumb2 if-conversion heuristics"), cl::init(false))
static const MachineInstrBuilder & AddDefaultPred(const MachineInstrBuilder &MIB)
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)
#define llvm_unreachable(msg)
bool isLegalToSplitMBBAt(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) const
Abstract Stack Frame Information.
enable_if_c< std::numeric_limits< T >::is_integer &&!std::numeric_limits< T >::is_signed, std::size_t >::type 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:120
bool rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, unsigned FrameReg, int &Offset, const ARMBaseInstrInfo &TII)
const MachineInstrBuilder & addImm(int64_t Val) const
unsigned getNumOperands() const
Definition: MachineInstr.h:265
void RemoveOperand(unsigned i)
int getOpcode() const
Definition: MachineInstr.h:261
static int getT2SOImmVal(unsigned Arg)
int64_t getImm() const
const TargetRegisterClass * constrainRegClass(unsigned Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
unsigned getKillRegState(bool B)
void ChangeToImmediate(int64_t ImmVal)
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:119
bundle_iterator< MachineInstr, instr_iterator > iterator
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:314
ARMCC::CondCodes getInstrPredicate(const MachineInstr *MI, unsigned &PredReg)
static unsigned char getAM5Offset(unsigned AM5Opc)
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:267
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
Thumb2InstrInfo(const ARMSubtarget &STI)
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
static unsigned immediateOffsetOpcode(unsigned opcode)
static const MachineInstrBuilder & AddDefaultCC(const MachineInstrBuilder &MIB)
void setOpcode(unsigned Op)
Definition: MCInst.h:157
void setDesc(const MCInstrDesc &tid)
Definition: MachineInstr.h:984
void addOperand(MachineFunction &MF, const MachineOperand &Op)
virtual void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const
unsigned getObjectAlignment(int ObjectIdx) const
getObjectAlignment - Return the alignment of the specified stack object.
MachineFrameInfo * getFrameInfo()
const MachineInstrBuilder & addFrameIndex(int Idx) const
AddrMode
ARM Addressing Modes.
Definition: ARMBaseInfo.h:234
static bool isPhysicalRegister(unsigned Reg)
MachineRegisterInfo & getRegInfo()
static unsigned positiveOffsetOpcode(unsigned opcode)
static MCOperand CreateImm(int64_t Val)
Definition: MCInst.h:117
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, DebugLoc DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
#define I(x, y, z)
Definition: MD5.cpp:54
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
static AddrOpc getAM5Op(unsigned AM5Opc)
void getNoopForMachoTarget(MCInst &NopInst) const
getNoopForMachoTarget - Return the noop instruction to use for a noop.
unsigned getReg() const
getReg - Returns the register number.
void addOperand(const MCOperand &Op)
Definition: MCInst.h:167
const MCRegisterInfo & MRI
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const
virtual void ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail, MachineBasicBlock *NewDest) const
unsigned getUnindexedOpcode(unsigned Opc) const
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
int64_t getObjectSize(int ObjectIdx) const
const MachineInstrBuilder & AddDReg(MachineInstrBuilder &MIB, unsigned Reg, unsigned SubIdx, unsigned State, const TargetRegisterInfo *TRI) const