LLVM  10.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);
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).
162  if (Register::isVirtualRegister(SrcReg)) {
164  MRI->constrainRegClass(SrcReg, &ARM::GPRPairnospRegClass);
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).
203  if (Register::isVirtualRegister(DestReg)) {
205  MRI->constrainRegClass(DestReg, &ARM::GPRPairnospRegClass);
206  }
207 
208  MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::t2LDRDi8));
209  AddDReg(MIB, DestReg, ARM::gsub_0, RegState::DefineNoRead, TRI);
210  AddDReg(MIB, DestReg, ARM::gsub_1, RegState::DefineNoRead, TRI);
212 
213  if (Register::isPhysicalRegister(DestReg))
214  MIB.addReg(DestReg, RegState::ImplicitDefine);
215  return;
216  }
217 
218  ARMBaseInstrInfo::loadRegFromStackSlot(MBB, I, DestReg, FI, RC, TRI);
219 }
220 
221 void Thumb2InstrInfo::expandLoadStackGuard(
223  MachineFunction &MF = *MI->getParent()->getParent();
224  if (MF.getTarget().isPositionIndependent())
225  expandLoadStackGuardBase(MI, ARM::t2MOV_ga_pcrel, ARM::t2LDRi12);
226  else
227  expandLoadStackGuardBase(MI, ARM::t2MOVi32imm, ARM::t2LDRi12);
228 }
229 
232  const DebugLoc &dl, unsigned DestReg,
233  unsigned BaseReg, int NumBytes,
234  ARMCC::CondCodes Pred, unsigned PredReg,
235  const ARMBaseInstrInfo &TII,
236  unsigned MIFlags) {
237  if (NumBytes == 0 && DestReg != BaseReg) {
238  BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
239  .addReg(BaseReg, RegState::Kill)
240  .addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags);
241  return;
242  }
243 
244  bool isSub = NumBytes < 0;
245  if (isSub) NumBytes = -NumBytes;
246 
247  // If profitable, use a movw or movt to materialize the offset.
248  // FIXME: Use the scavenger to grab a scratch register.
249  if (DestReg != ARM::SP && DestReg != BaseReg &&
250  NumBytes >= 4096 &&
251  ARM_AM::getT2SOImmVal(NumBytes) == -1) {
252  bool Fits = false;
253  if (NumBytes < 65536) {
254  // Use a movw to materialize the 16-bit constant.
255  BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi16), DestReg)
256  .addImm(NumBytes)
257  .addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags);
258  Fits = true;
259  } else if ((NumBytes & 0xffff) == 0) {
260  // Use a movt to materialize the 32-bit constant.
261  BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVTi16), DestReg)
262  .addReg(DestReg)
263  .addImm(NumBytes >> 16)
264  .addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags);
265  Fits = true;
266  }
267 
268  if (Fits) {
269  if (isSub) {
270  BuildMI(MBB, MBBI, dl, TII.get(ARM::t2SUBrr), DestReg)
271  .addReg(BaseReg)
272  .addReg(DestReg, RegState::Kill)
273  .add(predOps(Pred, PredReg))
274  .add(condCodeOp())
275  .setMIFlags(MIFlags);
276  } else {
277  // Here we know that DestReg is not SP but we do not
278  // know anything about BaseReg. t2ADDrr is an invalid
279  // instruction is SP is used as the second argument, but
280  // is fine if SP is the first argument. To be sure we
281  // do not generate invalid encoding, put BaseReg first.
282  BuildMI(MBB, MBBI, dl, TII.get(ARM::t2ADDrr), DestReg)
283  .addReg(BaseReg)
284  .addReg(DestReg, RegState::Kill)
285  .add(predOps(Pred, PredReg))
286  .add(condCodeOp())
287  .setMIFlags(MIFlags);
288  }
289  return;
290  }
291  }
292 
293  while (NumBytes) {
294  unsigned ThisVal = NumBytes;
295  unsigned Opc = 0;
296  if (DestReg == ARM::SP && BaseReg != ARM::SP) {
297  // mov sp, rn. Note t2MOVr cannot be used.
298  BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
299  .addReg(BaseReg)
300  .setMIFlags(MIFlags)
301  .add(predOps(ARMCC::AL));
302  BaseReg = ARM::SP;
303  continue;
304  }
305 
306  bool HasCCOut = true;
307  if (BaseReg == ARM::SP) {
308  // sub sp, sp, #imm7
309  if (DestReg == ARM::SP && (ThisVal < ((1 << 7)-1) * 4)) {
310  assert((ThisVal & 3) == 0 && "Stack update is not multiple of 4?");
311  Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
312  BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
313  .addReg(BaseReg)
314  .addImm(ThisVal / 4)
315  .setMIFlags(MIFlags)
316  .add(predOps(ARMCC::AL));
317  NumBytes = 0;
318  continue;
319  }
320 
321  // sub rd, sp, so_imm
322  Opc = isSub ? ARM::t2SUBri : ARM::t2ADDri;
323  if (ARM_AM::getT2SOImmVal(NumBytes) != -1) {
324  NumBytes = 0;
325  } else {
326  // FIXME: Move this to ARMAddressingModes.h?
327  unsigned RotAmt = countLeadingZeros(ThisVal);
328  ThisVal = ThisVal & ARM_AM::rotr32(0xff000000U, RotAmt);
329  NumBytes &= ~ThisVal;
330  assert(ARM_AM::getT2SOImmVal(ThisVal) != -1 &&
331  "Bit extraction didn't work?");
332  }
333  } else {
334  assert(DestReg != ARM::SP && BaseReg != ARM::SP);
335  Opc = isSub ? ARM::t2SUBri : ARM::t2ADDri;
336  if (ARM_AM::getT2SOImmVal(NumBytes) != -1) {
337  NumBytes = 0;
338  } else if (ThisVal < 4096) {
339  Opc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12;
340  HasCCOut = false;
341  NumBytes = 0;
342  } else {
343  // FIXME: Move this to ARMAddressingModes.h?
344  unsigned RotAmt = countLeadingZeros(ThisVal);
345  ThisVal = ThisVal & ARM_AM::rotr32(0xff000000U, RotAmt);
346  NumBytes &= ~ThisVal;
347  assert(ARM_AM::getT2SOImmVal(ThisVal) != -1 &&
348  "Bit extraction didn't work?");
349  }
350  }
351 
352  // Build the new ADD / SUB.
353  MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
354  .addReg(BaseReg, RegState::Kill)
355  .addImm(ThisVal)
357  .setMIFlags(MIFlags);
358  if (HasCCOut)
359  MIB.add(condCodeOp());
360 
361  BaseReg = DestReg;
362  }
363 }
364 
365 static unsigned
366 negativeOffsetOpcode(unsigned opcode)
367 {
368  switch (opcode) {
369  case ARM::t2LDRi12: return ARM::t2LDRi8;
370  case ARM::t2LDRHi12: return ARM::t2LDRHi8;
371  case ARM::t2LDRBi12: return ARM::t2LDRBi8;
372  case ARM::t2LDRSHi12: return ARM::t2LDRSHi8;
373  case ARM::t2LDRSBi12: return ARM::t2LDRSBi8;
374  case ARM::t2STRi12: return ARM::t2STRi8;
375  case ARM::t2STRBi12: return ARM::t2STRBi8;
376  case ARM::t2STRHi12: return ARM::t2STRHi8;
377  case ARM::t2PLDi12: return ARM::t2PLDi8;
378 
379  case ARM::t2LDRi8:
380  case ARM::t2LDRHi8:
381  case ARM::t2LDRBi8:
382  case ARM::t2LDRSHi8:
383  case ARM::t2LDRSBi8:
384  case ARM::t2STRi8:
385  case ARM::t2STRBi8:
386  case ARM::t2STRHi8:
387  case ARM::t2PLDi8:
388  return opcode;
389 
390  default:
391  break;
392  }
393 
394  return 0;
395 }
396 
397 static unsigned
398 positiveOffsetOpcode(unsigned opcode)
399 {
400  switch (opcode) {
401  case ARM::t2LDRi8: return ARM::t2LDRi12;
402  case ARM::t2LDRHi8: return ARM::t2LDRHi12;
403  case ARM::t2LDRBi8: return ARM::t2LDRBi12;
404  case ARM::t2LDRSHi8: return ARM::t2LDRSHi12;
405  case ARM::t2LDRSBi8: return ARM::t2LDRSBi12;
406  case ARM::t2STRi8: return ARM::t2STRi12;
407  case ARM::t2STRBi8: return ARM::t2STRBi12;
408  case ARM::t2STRHi8: return ARM::t2STRHi12;
409  case ARM::t2PLDi8: 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  return opcode;
421 
422  default:
423  break;
424  }
425 
426  return 0;
427 }
428 
429 static unsigned
430 immediateOffsetOpcode(unsigned opcode)
431 {
432  switch (opcode) {
433  case ARM::t2LDRs: return ARM::t2LDRi12;
434  case ARM::t2LDRHs: return ARM::t2LDRHi12;
435  case ARM::t2LDRBs: return ARM::t2LDRBi12;
436  case ARM::t2LDRSHs: return ARM::t2LDRSHi12;
437  case ARM::t2LDRSBs: return ARM::t2LDRSBi12;
438  case ARM::t2STRs: return ARM::t2STRi12;
439  case ARM::t2STRBs: return ARM::t2STRBi12;
440  case ARM::t2STRHs: return ARM::t2STRHi12;
441  case ARM::t2PLDs: return ARM::t2PLDi12;
442 
443  case ARM::t2LDRi12:
444  case ARM::t2LDRHi12:
445  case ARM::t2LDRBi12:
446  case ARM::t2LDRSHi12:
447  case ARM::t2LDRSBi12:
448  case ARM::t2STRi12:
449  case ARM::t2STRBi12:
450  case ARM::t2STRHi12:
451  case ARM::t2PLDi12:
452  case ARM::t2LDRi8:
453  case ARM::t2LDRHi8:
454  case ARM::t2LDRBi8:
455  case ARM::t2LDRSHi8:
456  case ARM::t2LDRSBi8:
457  case ARM::t2STRi8:
458  case ARM::t2STRBi8:
459  case ARM::t2STRHi8:
460  case ARM::t2PLDi8:
461  return opcode;
462 
463  default:
464  break;
465  }
466 
467  return 0;
468 }
469 
470 bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
471  unsigned FrameReg, int &Offset,
472  const ARMBaseInstrInfo &TII,
473  const TargetRegisterInfo *TRI) {
474  unsigned Opcode = MI.getOpcode();
475  const MCInstrDesc &Desc = MI.getDesc();
476  unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
477  bool isSub = false;
478 
479  MachineFunction &MF = *MI.getParent()->getParent();
480  const TargetRegisterClass *RegClass =
481  TII.getRegClass(Desc, FrameRegIdx, TRI, MF);
482 
483  // Memory operands in inline assembly always use AddrModeT2_i12.
484  if (Opcode == ARM::INLINEASM || Opcode == ARM::INLINEASM_BR)
485  AddrMode = ARMII::AddrModeT2_i12; // FIXME. mode for thumb2?
486 
487  if (Opcode == ARM::t2ADDri || Opcode == ARM::t2ADDri12) {
488  Offset += MI.getOperand(FrameRegIdx+1).getImm();
489 
490  unsigned PredReg;
491  if (Offset == 0 && getInstrPredicate(MI, PredReg) == ARMCC::AL &&
492  !MI.definesRegister(ARM::CPSR)) {
493  // Turn it into a move.
494  MI.setDesc(TII.get(ARM::tMOVr));
495  MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
496  // Remove offset and remaining explicit predicate operands.
497  do MI.RemoveOperand(FrameRegIdx+1);
498  while (MI.getNumOperands() > FrameRegIdx+1);
499  MachineInstrBuilder MIB(*MI.getParent()->getParent(), &MI);
500  MIB.add(predOps(ARMCC::AL));
501  return true;
502  }
503 
504  bool HasCCOut = Opcode != ARM::t2ADDri12;
505 
506  if (Offset < 0) {
507  Offset = -Offset;
508  isSub = true;
509  MI.setDesc(TII.get(ARM::t2SUBri));
510  } else {
511  MI.setDesc(TII.get(ARM::t2ADDri));
512  }
513 
514  // Common case: small offset, fits into instruction.
515  if (ARM_AM::getT2SOImmVal(Offset) != -1) {
516  MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
517  MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
518  // Add cc_out operand if the original instruction did not have one.
519  if (!HasCCOut)
521  Offset = 0;
522  return true;
523  }
524  // Another common case: imm12.
525  if (Offset < 4096 &&
526  (!HasCCOut || MI.getOperand(MI.getNumOperands()-1).getReg() == 0)) {
527  unsigned NewOpc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12;
528  MI.setDesc(TII.get(NewOpc));
529  MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
530  MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
531  // Remove the cc_out operand.
532  if (HasCCOut)
533  MI.RemoveOperand(MI.getNumOperands()-1);
534  Offset = 0;
535  return true;
536  }
537 
538  // Otherwise, extract 8 adjacent bits from the immediate into this
539  // t2ADDri/t2SUBri.
540  unsigned RotAmt = countLeadingZeros<unsigned>(Offset);
541  unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xff000000U, RotAmt);
542 
543  // We will handle these bits from offset, clear them.
544  Offset &= ~ThisImmVal;
545 
546  assert(ARM_AM::getT2SOImmVal(ThisImmVal) != -1 &&
547  "Bit extraction didn't work?");
548  MI.getOperand(FrameRegIdx+1).ChangeToImmediate(ThisImmVal);
549  // Add cc_out operand if the original instruction did not have one.
550  if (!HasCCOut)
552  } else {
553  // AddrMode4 and AddrMode6 cannot handle any offset.
554  if (AddrMode == ARMII::AddrMode4 || AddrMode == ARMII::AddrMode6)
555  return false;
556 
557  // AddrModeT2_so cannot handle any offset. If there is no offset
558  // register then we change to an immediate version.
559  unsigned NewOpc = Opcode;
560  if (AddrMode == ARMII::AddrModeT2_so) {
561  Register OffsetReg = MI.getOperand(FrameRegIdx + 1).getReg();
562  if (OffsetReg != 0) {
563  MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
564  return Offset == 0;
565  }
566 
567  MI.RemoveOperand(FrameRegIdx+1);
568  MI.getOperand(FrameRegIdx+1).ChangeToImmediate(0);
569  NewOpc = immediateOffsetOpcode(Opcode);
570  AddrMode = ARMII::AddrModeT2_i12;
571  }
572 
573  unsigned NumBits = 0;
574  unsigned Scale = 1;
575  if (AddrMode == ARMII::AddrModeT2_i8 || AddrMode == ARMII::AddrModeT2_i12) {
576  // i8 supports only negative, and i12 supports only positive, so
577  // based on Offset sign convert Opcode to the appropriate
578  // instruction
579  Offset += MI.getOperand(FrameRegIdx+1).getImm();
580  if (Offset < 0) {
581  NewOpc = negativeOffsetOpcode(Opcode);
582  NumBits = 8;
583  isSub = true;
584  Offset = -Offset;
585  } else {
586  NewOpc = positiveOffsetOpcode(Opcode);
587  NumBits = 12;
588  }
589  } else if (AddrMode == ARMII::AddrMode5) {
590  // VFP address mode.
591  const MachineOperand &OffOp = MI.getOperand(FrameRegIdx+1);
592  int InstrOffs = ARM_AM::getAM5Offset(OffOp.getImm());
593  if (ARM_AM::getAM5Op(OffOp.getImm()) == ARM_AM::sub)
594  InstrOffs *= -1;
595  NumBits = 8;
596  Scale = 4;
597  Offset += InstrOffs * 4;
598  assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
599  if (Offset < 0) {
600  Offset = -Offset;
601  isSub = true;
602  }
603  } else if (AddrMode == ARMII::AddrMode5FP16) {
604  // VFP address mode.
605  const MachineOperand &OffOp = MI.getOperand(FrameRegIdx+1);
606  int InstrOffs = ARM_AM::getAM5FP16Offset(OffOp.getImm());
607  if (ARM_AM::getAM5FP16Op(OffOp.getImm()) == ARM_AM::sub)
608  InstrOffs *= -1;
609  NumBits = 8;
610  Scale = 2;
611  Offset += InstrOffs * 2;
612  assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
613  if (Offset < 0) {
614  Offset = -Offset;
615  isSub = true;
616  }
617  } else if (AddrMode == ARMII::AddrModeT2_i7s4 ||
618  AddrMode == ARMII::AddrModeT2_i7s2 ||
619  AddrMode == ARMII::AddrModeT2_i7) {
620  Offset += MI.getOperand(FrameRegIdx + 1).getImm();
621  unsigned OffsetMask;
622  switch (AddrMode) {
623  case ARMII::AddrModeT2_i7s4: NumBits = 9; OffsetMask = 0x3; break;
624  case ARMII::AddrModeT2_i7s2: NumBits = 8; OffsetMask = 0x1; break;
625  default: NumBits = 7; OffsetMask = 0x0; break;
626  }
627  // MCInst operand expects already scaled value.
628  Scale = 1;
629  assert((Offset & OffsetMask) == 0 && "Can't encode this offset!");
630  (void)OffsetMask; // squash unused-variable warning at -NDEBUG
631  } else if (AddrMode == ARMII::AddrModeT2_i8s4) {
632  Offset += MI.getOperand(FrameRegIdx + 1).getImm() * 4;
633  NumBits = 8 + 2;
634  // MCInst operand expects already scaled value.
635  Scale = 1;
636  assert((Offset & 3) == 0 && "Can't encode this offset!");
637  } else if (AddrMode == ARMII::AddrModeT2_ldrex) {
638  Offset += MI.getOperand(FrameRegIdx + 1).getImm() * 4;
639  NumBits = 8; // 8 bits scaled by 4
640  Scale = 4;
641  assert((Offset & 3) == 0 && "Can't encode this offset!");
642  } else {
643  llvm_unreachable("Unsupported addressing mode!");
644  }
645 
646  if (NewOpc != Opcode)
647  MI.setDesc(TII.get(NewOpc));
648 
649  MachineOperand &ImmOp = MI.getOperand(FrameRegIdx+1);
650 
651  // Attempt to fold address computation
652  // Common case: small offset, fits into instruction. We need to make sure
653  // the register class is correct too, for instructions like the MVE
654  // VLDRH.32, which only accepts low tGPR registers.
655  int ImmedOffset = Offset / Scale;
656  unsigned Mask = (1 << NumBits) - 1;
657  if ((unsigned)Offset <= Mask * Scale &&
658  (Register::isVirtualRegister(FrameReg) ||
659  RegClass->contains(FrameReg))) {
660  if (Register::isVirtualRegister(FrameReg)) {
661  // Make sure the register class for the virtual register is correct
663  if (!MRI->constrainRegClass(FrameReg, RegClass))
664  llvm_unreachable("Unable to constrain virtual register class.");
665  }
666 
667  // Replace the FrameIndex with fp/sp
668  MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
669  if (isSub) {
670  if (AddrMode == ARMII::AddrMode5 || AddrMode == ARMII::AddrMode5FP16)
671  // FIXME: Not consistent.
672  ImmedOffset |= 1 << NumBits;
673  else
674  ImmedOffset = -ImmedOffset;
675  }
676  ImmOp.ChangeToImmediate(ImmedOffset);
677  Offset = 0;
678  return true;
679  }
680 
681  // Otherwise, offset doesn't fit. Pull in what we can to simplify
682  ImmedOffset = ImmedOffset & Mask;
683  if (isSub) {
684  if (AddrMode == ARMII::AddrMode5 || AddrMode == ARMII::AddrMode5FP16)
685  // FIXME: Not consistent.
686  ImmedOffset |= 1 << NumBits;
687  else {
688  ImmedOffset = -ImmedOffset;
689  if (ImmedOffset == 0)
690  // Change the opcode back if the encoded offset is zero.
691  MI.setDesc(TII.get(positiveOffsetOpcode(NewOpc)));
692  }
693  }
694  ImmOp.ChangeToImmediate(ImmedOffset);
695  Offset &= ~(Mask*Scale);
696  }
697 
698  Offset = (isSub) ? -Offset : Offset;
699  return Offset == 0 && (Register::isVirtualRegister(FrameReg) ||
700  RegClass->contains(FrameReg));
701 }
702 
704  unsigned &PredReg) {
705  unsigned Opc = MI.getOpcode();
706  if (Opc == ARM::tBcc || Opc == ARM::t2Bcc)
707  return ARMCC::AL;
708  return getInstrPredicate(MI, PredReg);
709 }
710 
712  const MCInstrDesc &MCID = MI.getDesc();
713 
714  if (!MCID.OpInfo)
715  return -1;
716 
717  for (unsigned i = 0, e = MCID.getNumOperands(); i != e; ++i)
718  if (ARM::isVpred(MCID.OpInfo[i].OperandType))
719  return i;
720 
721  return -1;
722 }
723 
725  unsigned &PredReg) {
726  int PIdx = findFirstVPTPredOperandIdx(MI);
727  if (PIdx == -1) {
728  PredReg = 0;
729  return ARMVCC::None;
730  }
731 
732  PredReg = MI.getOperand(PIdx+1).getReg();
733  return (ARMVCC::VPTCodes)MI.getOperand(PIdx).getImm();
734 }
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
bool contains(unsigned Reg) const
Return true if the specified register is included in this register class.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
Definition: Register.h:63
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:179
static unsigned negativeOffsetOpcode(unsigned opcode)
unsigned const TargetRegisterInfo * TRI
A debug info location.
Definition: DebugLoc.h:33
return AArch64::GPR64RegClass contains(Reg)
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:226
const HexagonInstrInfo * TII
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:414
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:411
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.
INLINEASM - Represents an inline asm block.
Definition: ISDOpcodes.h:696
uint8_t OperandType
Information about the type of the operand.
Definition: MCInstrDesc.h:82
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
Definition: MachineInstr.h:408
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.
bool definesRegister(Register Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr fully defines the specified register.
constexpr double e
Definition: MathExtras.h:57
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...
Thumb2InstrInfo(const ARMSubtarget &STI)
const MachineInstrBuilder & addFrameIndex(int Idx) const
static MachineOperand CreateReg(Register 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)
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:225
#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...
bool rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, unsigned FrameReg, int &Offset, const ARMBaseInstrInfo &TII, const TargetRegisterInfo *TRI)
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:256
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:64
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
Tail - This calling convention attemps to make calls as fast as possible while guaranteeing that tail...
Definition: CallingConv.h:81
void ChangeToRegister(Register 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...
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:699
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
Definition: Register.h:69
const MCOperandInfo * OpInfo
Definition: MCInstrDesc.h:190
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)
Register getReg() const
getReg - Returns the register number.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:416
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:122
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Wrapper class representing virtual and physical registers.
Definition: Register.h:19