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);
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).
162  if (Register::isVirtualRegister(SrcReg)) {
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).
203  if (Register::isVirtualRegister(DestReg)) {
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 
214  if (Register::isPhysicalRegister(DestReg))
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  const TargetRegisterInfo *TRI) {
475  unsigned Opcode = MI.getOpcode();
476  const MCInstrDesc &Desc = MI.getDesc();
477  unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
478  bool isSub = false;
479 
480  MachineFunction &MF = *MI.getParent()->getParent();
481  const TargetRegisterClass *RegClass =
482  TII.getRegClass(Desc, FrameRegIdx, TRI, MF);
483 
484  // Memory operands in inline assembly always use AddrModeT2_i12.
485  if (Opcode == ARM::INLINEASM || Opcode == ARM::INLINEASM_BR)
486  AddrMode = ARMII::AddrModeT2_i12; // FIXME. mode for thumb2?
487 
488  if (Opcode == ARM::t2ADDri || Opcode == ARM::t2ADDri12) {
489  Offset += MI.getOperand(FrameRegIdx+1).getImm();
490 
491  unsigned PredReg;
492  if (Offset == 0 && getInstrPredicate(MI, PredReg) == ARMCC::AL &&
493  !MI.definesRegister(ARM::CPSR)) {
494  // Turn it into a move.
495  MI.setDesc(TII.get(ARM::tMOVr));
496  MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
497  // Remove offset and remaining explicit predicate operands.
498  do MI.RemoveOperand(FrameRegIdx+1);
499  while (MI.getNumOperands() > FrameRegIdx+1);
500  MachineInstrBuilder MIB(*MI.getParent()->getParent(), &MI);
501  MIB.add(predOps(ARMCC::AL));
502  return true;
503  }
504 
505  bool HasCCOut = Opcode != ARM::t2ADDri12;
506 
507  if (Offset < 0) {
508  Offset = -Offset;
509  isSub = true;
510  MI.setDesc(TII.get(ARM::t2SUBri));
511  } else {
512  MI.setDesc(TII.get(ARM::t2ADDri));
513  }
514 
515  // Common case: small offset, fits into instruction.
516  if (ARM_AM::getT2SOImmVal(Offset) != -1) {
517  MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
518  MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
519  // Add cc_out operand if the original instruction did not have one.
520  if (!HasCCOut)
522  Offset = 0;
523  return true;
524  }
525  // Another common case: imm12.
526  if (Offset < 4096 &&
527  (!HasCCOut || MI.getOperand(MI.getNumOperands()-1).getReg() == 0)) {
528  unsigned NewOpc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12;
529  MI.setDesc(TII.get(NewOpc));
530  MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
531  MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
532  // Remove the cc_out operand.
533  if (HasCCOut)
534  MI.RemoveOperand(MI.getNumOperands()-1);
535  Offset = 0;
536  return true;
537  }
538 
539  // Otherwise, extract 8 adjacent bits from the immediate into this
540  // t2ADDri/t2SUBri.
541  unsigned RotAmt = countLeadingZeros<unsigned>(Offset);
542  unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xff000000U, RotAmt);
543 
544  // We will handle these bits from offset, clear them.
545  Offset &= ~ThisImmVal;
546 
547  assert(ARM_AM::getT2SOImmVal(ThisImmVal) != -1 &&
548  "Bit extraction didn't work?");
549  MI.getOperand(FrameRegIdx+1).ChangeToImmediate(ThisImmVal);
550  // Add cc_out operand if the original instruction did not have one.
551  if (!HasCCOut)
553  } else {
554  // AddrMode4 and AddrMode6 cannot handle any offset.
555  if (AddrMode == ARMII::AddrMode4 || AddrMode == ARMII::AddrMode6)
556  return false;
557 
558  // AddrModeT2_so cannot handle any offset. If there is no offset
559  // register then we change to an immediate version.
560  unsigned NewOpc = Opcode;
561  if (AddrMode == ARMII::AddrModeT2_so) {
562  Register OffsetReg = MI.getOperand(FrameRegIdx + 1).getReg();
563  if (OffsetReg != 0) {
564  MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
565  return Offset == 0;
566  }
567 
568  MI.RemoveOperand(FrameRegIdx+1);
569  MI.getOperand(FrameRegIdx+1).ChangeToImmediate(0);
570  NewOpc = immediateOffsetOpcode(Opcode);
571  AddrMode = ARMII::AddrModeT2_i12;
572  }
573 
574  unsigned NumBits = 0;
575  unsigned Scale = 1;
576  if (AddrMode == ARMII::AddrModeT2_i8 || AddrMode == ARMII::AddrModeT2_i12) {
577  // i8 supports only negative, and i12 supports only positive, so
578  // based on Offset sign convert Opcode to the appropriate
579  // instruction
580  Offset += MI.getOperand(FrameRegIdx+1).getImm();
581  if (Offset < 0) {
582  NewOpc = negativeOffsetOpcode(Opcode);
583  NumBits = 8;
584  isSub = true;
585  Offset = -Offset;
586  } else {
587  NewOpc = positiveOffsetOpcode(Opcode);
588  NumBits = 12;
589  }
590  } else if (AddrMode == ARMII::AddrMode5) {
591  // VFP address mode.
592  const MachineOperand &OffOp = MI.getOperand(FrameRegIdx+1);
593  int InstrOffs = ARM_AM::getAM5Offset(OffOp.getImm());
594  if (ARM_AM::getAM5Op(OffOp.getImm()) == ARM_AM::sub)
595  InstrOffs *= -1;
596  NumBits = 8;
597  Scale = 4;
598  Offset += InstrOffs * 4;
599  assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
600  if (Offset < 0) {
601  Offset = -Offset;
602  isSub = true;
603  }
604  } else if (AddrMode == ARMII::AddrMode5FP16) {
605  // VFP address mode.
606  const MachineOperand &OffOp = MI.getOperand(FrameRegIdx+1);
607  int InstrOffs = ARM_AM::getAM5FP16Offset(OffOp.getImm());
608  if (ARM_AM::getAM5FP16Op(OffOp.getImm()) == ARM_AM::sub)
609  InstrOffs *= -1;
610  NumBits = 8;
611  Scale = 2;
612  Offset += InstrOffs * 2;
613  assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
614  if (Offset < 0) {
615  Offset = -Offset;
616  isSub = true;
617  }
618  } else if (AddrMode == ARMII::AddrModeT2_i7s4 ||
619  AddrMode == ARMII::AddrModeT2_i7s2 ||
620  AddrMode == ARMII::AddrModeT2_i7) {
621  Offset += MI.getOperand(FrameRegIdx + 1).getImm();
622  unsigned OffsetMask;
623  switch (AddrMode) {
624  case ARMII::AddrModeT2_i7s4: NumBits = 9; OffsetMask = 0x3; break;
625  case ARMII::AddrModeT2_i7s2: NumBits = 8; OffsetMask = 0x1; break;
626  default: NumBits = 7; OffsetMask = 0x0; break;
627  }
628  // MCInst operand expects already scaled value.
629  Scale = 1;
630  assert((Offset & OffsetMask) == 0 && "Can't encode this offset!");
631  (void)OffsetMask; // squash unused-variable warning at -NDEBUG
632  } else if (AddrMode == ARMII::AddrModeT2_i8s4) {
633  Offset += MI.getOperand(FrameRegIdx + 1).getImm() * 4;
634  NumBits = 8 + 2;
635  // MCInst operand expects already scaled value.
636  Scale = 1;
637  assert((Offset & 3) == 0 && "Can't encode this offset!");
638  } else if (AddrMode == ARMII::AddrModeT2_ldrex) {
639  Offset += MI.getOperand(FrameRegIdx + 1).getImm() * 4;
640  NumBits = 8; // 8 bits scaled by 4
641  Scale = 4;
642  assert((Offset & 3) == 0 && "Can't encode this offset!");
643  } else {
644  llvm_unreachable("Unsupported addressing mode!");
645  }
646 
647  if (NewOpc != Opcode)
648  MI.setDesc(TII.get(NewOpc));
649 
650  MachineOperand &ImmOp = MI.getOperand(FrameRegIdx+1);
651 
652  // Attempt to fold address computation
653  // Common case: small offset, fits into instruction. We need to make sure
654  // the register class is correct too, for instructions like the MVE
655  // VLDRH.32, which only accepts low tGPR registers.
656  int ImmedOffset = Offset / Scale;
657  unsigned Mask = (1 << NumBits) - 1;
658  if ((unsigned)Offset <= Mask * Scale &&
659  (Register::isVirtualRegister(FrameReg) ||
660  RegClass->contains(FrameReg))) {
661  if (Register::isVirtualRegister(FrameReg)) {
662  // Make sure the register class for the virtual register is correct
664  if (!MRI->constrainRegClass(FrameReg, RegClass))
665  llvm_unreachable("Unable to constrain virtual register class.");
666  }
667 
668  // Replace the FrameIndex with fp/sp
669  MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
670  if (isSub) {
671  if (AddrMode == ARMII::AddrMode5 || AddrMode == ARMII::AddrMode5FP16)
672  // FIXME: Not consistent.
673  ImmedOffset |= 1 << NumBits;
674  else
675  ImmedOffset = -ImmedOffset;
676  }
677  ImmOp.ChangeToImmediate(ImmedOffset);
678  Offset = 0;
679  return true;
680  }
681 
682  // Otherwise, offset doesn't fit. Pull in what we can to simplify
683  ImmedOffset = ImmedOffset & Mask;
684  if (isSub) {
685  if (AddrMode == ARMII::AddrMode5 || AddrMode == ARMII::AddrMode5FP16)
686  // FIXME: Not consistent.
687  ImmedOffset |= 1 << NumBits;
688  else {
689  ImmedOffset = -ImmedOffset;
690  if (ImmedOffset == 0)
691  // Change the opcode back if the encoded offset is zero.
692  MI.setDesc(TII.get(positiveOffsetOpcode(NewOpc)));
693  }
694  }
695  ImmOp.ChangeToImmediate(ImmedOffset);
696  Offset &= ~(Mask*Scale);
697  }
698 
699  Offset = (isSub) ? -Offset : Offset;
700  return Offset == 0 && (Register::isVirtualRegister(FrameReg) ||
701  RegClass->contains(FrameReg));
702 }
703 
705  unsigned &PredReg) {
706  unsigned Opc = MI.getOpcode();
707  if (Opc == ARM::tBcc || Opc == ARM::t2Bcc)
708  return ARMCC::AL;
709  return getInstrPredicate(MI, PredReg);
710 }
711 
713  const MCInstrDesc &MCID = MI.getDesc();
714 
715  if (!MCID.OpInfo)
716  return -1;
717 
718  for (unsigned i = 0, e = MCID.getNumOperands(); i != e; ++i)
719  if (ARM::isVpred(MCID.OpInfo[i].OperandType))
720  return i;
721 
722  return -1;
723 }
724 
726  unsigned &PredReg) {
727  int PIdx = findFirstVPTPredOperandIdx(MI);
728  if (PIdx == -1) {
729  PredReg = 0;
730  return ARMVCC::None;
731  }
732 
733  PredReg = MI.getOperand(PIdx+1).getReg();
734  return (ARMVCC::VPTCodes)MI.getOperand(PIdx).getImm();
735 }
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:178
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:225
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:695
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.
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: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...
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
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:698
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:189
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