1//===-- Thumb2InstrInfo.cpp - Thumb-2 Instruction Information -------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains the Thumb-2 implementation of the TargetInstrInfo class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "Thumb2InstrInfo.h"
15#include "ARM.h"
16#include "ARMConstantPoolValue.h"
17#include "ARMMachineFunctionInfo.h"
18#include "MCTargetDesc/ARMAddressingModes.h"
19#include "llvm/CodeGen/MachineFrameInfo.h"
20#include "llvm/CodeGen/MachineInstrBuilder.h"
21#include "llvm/CodeGen/MachineMemOperand.h"
22#include "llvm/MC/MCInst.h"
23#include "llvm/Support/CommandLine.h"
24
25using namespace llvm;
26
27static cl::opt<bool>
28OldT2IfCvt("old-thumb2-ifcvt", cl::Hidden,
29           cl::desc("Use old-style Thumb2 if-conversion heuristics"),
30           cl::init(false));
31
32Thumb2InstrInfo::Thumb2InstrInfo(const ARMSubtarget &STI)
33  : ARMBaseInstrInfo(STI), RI(*this, STI) {
34}
35
36/// getNoopForMachoTarget - Return the noop instruction to use for a noop.
37void Thumb2InstrInfo::getNoopForMachoTarget(MCInst &NopInst) const {
38  NopInst.setOpcode(ARM::tNOP);
39  NopInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
40  NopInst.addOperand(MCOperand::CreateReg(0));
41}
42
43unsigned Thumb2InstrInfo::getUnindexedOpcode(unsigned Opc) const {
44  // FIXME
45  return 0;
46}
47
48void
49Thumb2InstrInfo::ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail,
50                                         MachineBasicBlock *NewDest) const {
51  MachineBasicBlock *MBB = Tail->getParent();
52  ARMFunctionInfo *AFI = MBB->getParent()->getInfo<ARMFunctionInfo>();
53  if (!AFI->hasITBlocks()) {
54    TargetInstrInfo::ReplaceTailWithBranchTo(Tail, NewDest);
55    return;
56  }
57
58  // If the first instruction of Tail is predicated, we may have to update
59  // the IT instruction.
60  unsigned PredReg = 0;
61  ARMCC::CondCodes CC = getInstrPredicate(Tail, PredReg);
62  MachineBasicBlock::iterator MBBI = Tail;
63  if (CC != ARMCC::AL)
64    // Expecting at least the t2IT instruction before it.
65    --MBBI;
66
67  // Actually replace the tail.
68  TargetInstrInfo::ReplaceTailWithBranchTo(Tail, NewDest);
69
70  // Fix up IT.
71  if (CC != ARMCC::AL) {
72    MachineBasicBlock::iterator E = MBB->begin();
73    unsigned Count = 4; // At most 4 instructions in an IT block.
74    while (Count && MBBI != E) {
75      if (MBBI->isDebugValue()) {
76        --MBBI;
77        continue;
78      }
79      if (MBBI->getOpcode() == ARM::t2IT) {
80        unsigned Mask = MBBI->getOperand(1).getImm();
81        if (Count == 4)
82          MBBI->eraseFromParent();
83        else {
84          unsigned MaskOn = 1 << Count;
85          unsigned MaskOff = ~(MaskOn - 1);
86          MBBI->getOperand(1).setImm((Mask & MaskOff) | MaskOn);
87        }
88        return;
89      }
90      --MBBI;
91      --Count;
92    }
93
94    // Ctrl flow can reach here if branch folding is run before IT block
95    // formation pass.
96  }
97}
98
99bool
100Thumb2InstrInfo::isLegalToSplitMBBAt(MachineBasicBlock &MBB,
101                                     MachineBasicBlock::iterator MBBI) const {
102  while (MBBI->isDebugValue()) {
103    ++MBBI;
104    if (MBBI == MBB.end())
105      return false;
106  }
107
108  unsigned PredReg = 0;
109  return getITInstrPredicate(MBBI, PredReg) == ARMCC::AL;
110}
111
112void Thumb2InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
113                                  MachineBasicBlock::iterator I, DebugLoc DL,
114                                  unsigned DestReg, unsigned SrcReg,
115                                  bool KillSrc) const {
116  // Handle SPR, DPR, and QPR copies.
117  if (!ARM::GPRRegClass.contains(DestReg, SrcReg))
118    return ARMBaseInstrInfo::copyPhysReg(MBB, I, DL, DestReg, SrcReg, KillSrc);
119
120  AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::tMOVr), DestReg)
121    .addReg(SrcReg, getKillRegState(KillSrc)));
122}
123
124void Thumb2InstrInfo::
125storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
126                    unsigned SrcReg, bool isKill, int FI,
127                    const TargetRegisterClass *RC,
128                    const TargetRegisterInfo *TRI) const {
129  if (RC == &ARM::GPRRegClass   || RC == &ARM::tGPRRegClass ||
130      RC == &ARM::tcGPRRegClass || RC == &ARM::rGPRRegClass ||
131      RC == &ARM::GPRnopcRegClass) {
132    DebugLoc DL;
133    if (I != MBB.end()) DL = I->getDebugLoc();
134
135    MachineFunction &MF = *MBB.getParent();
136    MachineFrameInfo &MFI = *MF.getFrameInfo();
137    MachineMemOperand *MMO =
138      MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FI),
139                              MachineMemOperand::MOStore,
140                              MFI.getObjectSize(FI),
141                              MFI.getObjectAlignment(FI));
142    AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::t2STRi12))
143                   .addReg(SrcReg, getKillRegState(isKill))
144                   .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
145    return;
146  }
147
148  ARMBaseInstrInfo::storeRegToStackSlot(MBB, I, SrcReg, isKill, FI, RC, TRI);
149}
150
151void Thumb2InstrInfo::
152loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
153                     unsigned DestReg, int FI,
154                     const TargetRegisterClass *RC,
155                     const TargetRegisterInfo *TRI) const {
156  if (RC == &ARM::GPRRegClass   || RC == &ARM::tGPRRegClass ||
157      RC == &ARM::tcGPRRegClass || RC == &ARM::rGPRRegClass ||
158      RC == &ARM::GPRnopcRegClass) {
159    DebugLoc DL;
160    if (I != MBB.end()) DL = I->getDebugLoc();
161
162    MachineFunction &MF = *MBB.getParent();
163    MachineFrameInfo &MFI = *MF.getFrameInfo();
164    MachineMemOperand *MMO =
165      MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FI),
166                              MachineMemOperand::MOLoad,
167                              MFI.getObjectSize(FI),
168                              MFI.getObjectAlignment(FI));
169    AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::t2LDRi12), DestReg)
170                   .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
171    return;
172  }
173
174  ARMBaseInstrInfo::loadRegFromStackSlot(MBB, I, DestReg, FI, RC, TRI);
175}
176
177void llvm::emitT2RegPlusImmediate(MachineBasicBlock &MBB,
178                               MachineBasicBlock::iterator &MBBI, DebugLoc dl,
179                               unsigned DestReg, unsigned BaseReg, int NumBytes,
180                               ARMCC::CondCodes Pred, unsigned PredReg,
181                               const ARMBaseInstrInfo &TII, unsigned MIFlags) {
182  bool isSub = NumBytes < 0;
183  if (isSub) NumBytes = -NumBytes;
184
185  // If profitable, use a movw or movt to materialize the offset.
186  // FIXME: Use the scavenger to grab a scratch register.
187  if (DestReg != ARM::SP && DestReg != BaseReg &&
188      NumBytes >= 4096 &&
189      ARM_AM::getT2SOImmVal(NumBytes) == -1) {
190    bool Fits = false;
191    if (NumBytes < 65536) {
192      // Use a movw to materialize the 16-bit constant.
193      BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi16), DestReg)
194        .addImm(NumBytes)
195        .addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags);
196      Fits = true;
197    } else if ((NumBytes & 0xffff) == 0) {
198      // Use a movt to materialize the 32-bit constant.
199      BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVTi16), DestReg)
200        .addReg(DestReg)
201        .addImm(NumBytes >> 16)
202        .addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags);
203      Fits = true;
204    }
205
206    if (Fits) {
207      if (isSub) {
208        BuildMI(MBB, MBBI, dl, TII.get(ARM::t2SUBrr), DestReg)
209          .addReg(BaseReg, RegState::Kill)
210          .addReg(DestReg, RegState::Kill)
211          .addImm((unsigned)Pred).addReg(PredReg).addReg(0)
212          .setMIFlags(MIFlags);
213      } else {
214        BuildMI(MBB, MBBI, dl, TII.get(ARM::t2ADDrr), DestReg)
215          .addReg(DestReg, RegState::Kill)
216          .addReg(BaseReg, RegState::Kill)
217          .addImm((unsigned)Pred).addReg(PredReg).addReg(0)
218          .setMIFlags(MIFlags);
219      }
220      return;
221    }
222  }
223
224  while (NumBytes) {
225    unsigned ThisVal = NumBytes;
226    unsigned Opc = 0;
227    if (DestReg == ARM::SP && BaseReg != ARM::SP) {
228      // mov sp, rn. Note t2MOVr cannot be used.
229      AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr),DestReg)
230        .addReg(BaseReg).setMIFlags(MIFlags));
231      BaseReg = ARM::SP;
232      continue;
233    }
234
235    bool HasCCOut = true;
236    if (BaseReg == ARM::SP) {
237      // sub sp, sp, #imm7
238      if (DestReg == ARM::SP && (ThisVal < ((1 << 7)-1) * 4)) {
239        assert((ThisVal & 3) == 0 && "Stack update is not multiple of 4?");
240        Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
241        AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
242          .addReg(BaseReg).addImm(ThisVal/4).setMIFlags(MIFlags));
243        NumBytes = 0;
244        continue;
245      }
246
247      // sub rd, sp, so_imm
248      Opc = isSub ? ARM::t2SUBri : ARM::t2ADDri;
249      if (ARM_AM::getT2SOImmVal(NumBytes) != -1) {
250        NumBytes = 0;
251      } else {
252        // FIXME: Move this to ARMAddressingModes.h?
253        unsigned RotAmt = CountLeadingZeros_32(ThisVal);
254        ThisVal = ThisVal & ARM_AM::rotr32(0xff000000U, RotAmt);
255        NumBytes &= ~ThisVal;
256        assert(ARM_AM::getT2SOImmVal(ThisVal) != -1 &&
257               "Bit extraction didn't work?");
258      }
259    } else {
260      assert(DestReg != ARM::SP && BaseReg != ARM::SP);
261      Opc = isSub ? ARM::t2SUBri : ARM::t2ADDri;
262      if (ARM_AM::getT2SOImmVal(NumBytes) != -1) {
263        NumBytes = 0;
264      } else if (ThisVal < 4096) {
265        Opc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12;
266        HasCCOut = false;
267        NumBytes = 0;
268      } else {
269        // FIXME: Move this to ARMAddressingModes.h?
270        unsigned RotAmt = CountLeadingZeros_32(ThisVal);
271        ThisVal = ThisVal & ARM_AM::rotr32(0xff000000U, RotAmt);
272        NumBytes &= ~ThisVal;
273        assert(ARM_AM::getT2SOImmVal(ThisVal) != -1 &&
274               "Bit extraction didn't work?");
275      }
276    }
277
278    // Build the new ADD / SUB.
279    MachineInstrBuilder MIB =
280      AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
281                     .addReg(BaseReg, RegState::Kill)
282                     .addImm(ThisVal)).setMIFlags(MIFlags);
283    if (HasCCOut)
284      AddDefaultCC(MIB);
285
286    BaseReg = DestReg;
287  }
288}
289
290static unsigned
291negativeOffsetOpcode(unsigned opcode)
292{
293  switch (opcode) {
294  case ARM::t2LDRi12:   return ARM::t2LDRi8;
295  case ARM::t2LDRHi12:  return ARM::t2LDRHi8;
296  case ARM::t2LDRBi12:  return ARM::t2LDRBi8;
297  case ARM::t2LDRSHi12: return ARM::t2LDRSHi8;
298  case ARM::t2LDRSBi12: return ARM::t2LDRSBi8;
299  case ARM::t2STRi12:   return ARM::t2STRi8;
300  case ARM::t2STRBi12:  return ARM::t2STRBi8;
301  case ARM::t2STRHi12:  return ARM::t2STRHi8;
302
303  case ARM::t2LDRi8:
304  case ARM::t2LDRHi8:
305  case ARM::t2LDRBi8:
306  case ARM::t2LDRSHi8:
307  case ARM::t2LDRSBi8:
308  case ARM::t2STRi8:
309  case ARM::t2STRBi8:
310  case ARM::t2STRHi8:
311    return opcode;
312
313  default:
314    break;
315  }
316
317  return 0;
318}
319
320static unsigned
321positiveOffsetOpcode(unsigned opcode)
322{
323  switch (opcode) {
324  case ARM::t2LDRi8:   return ARM::t2LDRi12;
325  case ARM::t2LDRHi8:  return ARM::t2LDRHi12;
326  case ARM::t2LDRBi8:  return ARM::t2LDRBi12;
327  case ARM::t2LDRSHi8: return ARM::t2LDRSHi12;
328  case ARM::t2LDRSBi8: return ARM::t2LDRSBi12;
329  case ARM::t2STRi8:   return ARM::t2STRi12;
330  case ARM::t2STRBi8:  return ARM::t2STRBi12;
331  case ARM::t2STRHi8:  return ARM::t2STRHi12;
332
333  case ARM::t2LDRi12:
334  case ARM::t2LDRHi12:
335  case ARM::t2LDRBi12:
336  case ARM::t2LDRSHi12:
337  case ARM::t2LDRSBi12:
338  case ARM::t2STRi12:
339  case ARM::t2STRBi12:
340  case ARM::t2STRHi12:
341    return opcode;
342
343  default:
344    break;
345  }
346
347  return 0;
348}
349
350static unsigned
351immediateOffsetOpcode(unsigned opcode)
352{
353  switch (opcode) {
354  case ARM::t2LDRs:   return ARM::t2LDRi12;
355  case ARM::t2LDRHs:  return ARM::t2LDRHi12;
356  case ARM::t2LDRBs:  return ARM::t2LDRBi12;
357  case ARM::t2LDRSHs: return ARM::t2LDRSHi12;
358  case ARM::t2LDRSBs: return ARM::t2LDRSBi12;
359  case ARM::t2STRs:   return ARM::t2STRi12;
360  case ARM::t2STRBs:  return ARM::t2STRBi12;
361  case ARM::t2STRHs:  return ARM::t2STRHi12;
362
363  case ARM::t2LDRi12:
364  case ARM::t2LDRHi12:
365  case ARM::t2LDRBi12:
366  case ARM::t2LDRSHi12:
367  case ARM::t2LDRSBi12:
368  case ARM::t2STRi12:
369  case ARM::t2STRBi12:
370  case ARM::t2STRHi12:
371  case ARM::t2LDRi8:
372  case ARM::t2LDRHi8:
373  case ARM::t2LDRBi8:
374  case ARM::t2LDRSHi8:
375  case ARM::t2LDRSBi8:
376  case ARM::t2STRi8:
377  case ARM::t2STRBi8:
378  case ARM::t2STRHi8:
379    return opcode;
380
381  default:
382    break;
383  }
384
385  return 0;
386}
387
388bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
389                               unsigned FrameReg, int &Offset,
390                               const ARMBaseInstrInfo &TII) {
391  unsigned Opcode = MI.getOpcode();
392  const MCInstrDesc &Desc = MI.getDesc();
393  unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
394  bool isSub = false;
395
396  // Memory operands in inline assembly always use AddrModeT2_i12.
397  if (Opcode == ARM::INLINEASM)
398    AddrMode = ARMII::AddrModeT2_i12; // FIXME. mode for thumb2?
399
400  if (Opcode == ARM::t2ADDri || Opcode == ARM::t2ADDri12) {
401    Offset += MI.getOperand(FrameRegIdx+1).getImm();
402
403    unsigned PredReg;
404    if (Offset == 0 && getInstrPredicate(&MI, PredReg) == ARMCC::AL) {
405      // Turn it into a move.
406      MI.setDesc(TII.get(ARM::tMOVr));
407      MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
408      // Remove offset and remaining explicit predicate operands.
409      do MI.RemoveOperand(FrameRegIdx+1);
410      while (MI.getNumOperands() > FrameRegIdx+1);
411      MachineInstrBuilder MIB(*MI.getParent()->getParent(), &MI);
412      AddDefaultPred(MIB);
413      return true;
414    }
415
416    bool HasCCOut = Opcode != ARM::t2ADDri12;
417
418    if (Offset < 0) {
419      Offset = -Offset;
420      isSub = true;
421      MI.setDesc(TII.get(ARM::t2SUBri));
422    } else {
423      MI.setDesc(TII.get(ARM::t2ADDri));
424    }
425
426    // Common case: small offset, fits into instruction.
427    if (ARM_AM::getT2SOImmVal(Offset) != -1) {
428      MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
429      MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
430      // Add cc_out operand if the original instruction did not have one.
431      if (!HasCCOut)
432        MI.addOperand(MachineOperand::CreateReg(0, false));
433      Offset = 0;
434      return true;
435    }
436    // Another common case: imm12.
437    if (Offset < 4096 &&
438        (!HasCCOut || MI.getOperand(MI.getNumOperands()-1).getReg() == 0)) {
439      unsigned NewOpc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12;
440      MI.setDesc(TII.get(NewOpc));
441      MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
442      MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
443      // Remove the cc_out operand.
444      if (HasCCOut)
445        MI.RemoveOperand(MI.getNumOperands()-1);
446      Offset = 0;
447      return true;
448    }
449
450    // Otherwise, extract 8 adjacent bits from the immediate into this
451    // t2ADDri/t2SUBri.
452    unsigned RotAmt = CountLeadingZeros_32(Offset);
453    unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xff000000U, RotAmt);
454
455    // We will handle these bits from offset, clear them.
456    Offset &= ~ThisImmVal;
457
458    assert(ARM_AM::getT2SOImmVal(ThisImmVal) != -1 &&
459           "Bit extraction didn't work?");
460    MI.getOperand(FrameRegIdx+1).ChangeToImmediate(ThisImmVal);
461    // Add cc_out operand if the original instruction did not have one.
462    if (!HasCCOut)
463      MI.addOperand(MachineOperand::CreateReg(0, false));
464
465  } else {
466
467    // AddrMode4 and AddrMode6 cannot handle any offset.
468    if (AddrMode == ARMII::AddrMode4 || AddrMode == ARMII::AddrMode6)
469      return false;
470
471    // AddrModeT2_so cannot handle any offset. If there is no offset
472    // register then we change to an immediate version.
473    unsigned NewOpc = Opcode;
474    if (AddrMode == ARMII::AddrModeT2_so) {
475      unsigned OffsetReg = MI.getOperand(FrameRegIdx+1).getReg();
476      if (OffsetReg != 0) {
477        MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
478        return Offset == 0;
479      }
480
481      MI.RemoveOperand(FrameRegIdx+1);
482      MI.getOperand(FrameRegIdx+1).ChangeToImmediate(0);
483      NewOpc = immediateOffsetOpcode(Opcode);
484      AddrMode = ARMII::AddrModeT2_i12;
485    }
486
487    unsigned NumBits = 0;
488    unsigned Scale = 1;
489    if (AddrMode == ARMII::AddrModeT2_i8 || AddrMode == ARMII::AddrModeT2_i12) {
490      // i8 supports only negative, and i12 supports only positive, so
491      // based on Offset sign convert Opcode to the appropriate
492      // instruction
493      Offset += MI.getOperand(FrameRegIdx+1).getImm();
494      if (Offset < 0) {
495        NewOpc = negativeOffsetOpcode(Opcode);
496        NumBits = 8;
497        isSub = true;
498        Offset = -Offset;
499      } else {
500        NewOpc = positiveOffsetOpcode(Opcode);
501        NumBits = 12;
502      }
503    } else if (AddrMode == ARMII::AddrMode5) {
504      // VFP address mode.
505      const MachineOperand &OffOp = MI.getOperand(FrameRegIdx+1);
506      int InstrOffs = ARM_AM::getAM5Offset(OffOp.getImm());
507      if (ARM_AM::getAM5Op(OffOp.getImm()) == ARM_AM::sub)
508        InstrOffs *= -1;
509      NumBits = 8;
510      Scale = 4;
511      Offset += InstrOffs * 4;
512      assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
513      if (Offset < 0) {
514        Offset = -Offset;
515        isSub = true;
516      }
517    } else {
518      llvm_unreachable("Unsupported addressing mode!");
519    }
520
521    if (NewOpc != Opcode)
522      MI.setDesc(TII.get(NewOpc));
523
524    MachineOperand &ImmOp = MI.getOperand(FrameRegIdx+1);
525
526    // Attempt to fold address computation
527    // Common case: small offset, fits into instruction.
528    int ImmedOffset = Offset / Scale;
529    unsigned Mask = (1 << NumBits) - 1;
530    if ((unsigned)Offset <= Mask * Scale) {
531      // Replace the FrameIndex with fp/sp
532      MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
533      if (isSub) {
534        if (AddrMode == ARMII::AddrMode5)
535          // FIXME: Not consistent.
536          ImmedOffset |= 1 << NumBits;
537        else
538          ImmedOffset = -ImmedOffset;
539      }
540      ImmOp.ChangeToImmediate(ImmedOffset);
541      Offset = 0;
542      return true;
543    }
544
545    // Otherwise, offset doesn't fit. Pull in what we can to simplify
546    ImmedOffset = ImmedOffset & Mask;
547    if (isSub) {
548      if (AddrMode == ARMII::AddrMode5)
549        // FIXME: Not consistent.
550        ImmedOffset |= 1 << NumBits;
551      else {
552        ImmedOffset = -ImmedOffset;
553        if (ImmedOffset == 0)
554          // Change the opcode back if the encoded offset is zero.
555          MI.setDesc(TII.get(positiveOffsetOpcode(NewOpc)));
556      }
557    }
558    ImmOp.ChangeToImmediate(ImmedOffset);
559    Offset &= ~(Mask*Scale);
560  }
561
562  Offset = (isSub) ? -Offset : Offset;
563  return Offset == 0;
564}
565
566ARMCC::CondCodes
567llvm::getITInstrPredicate(const MachineInstr *MI, unsigned &PredReg) {
568  unsigned Opc = MI->getOpcode();
569  if (Opc == ARM::tBcc || Opc == ARM::t2Bcc)
570    return ARMCC::AL;
571  return getInstrPredicate(MI, PredReg);
572}
573