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