HexagonInstrInfo.cpp revision 27baab62e7d6267d9b18e4665c6bb1b75dae10d4
1//=- HexagonInstrInfo.cpp - Hexagon Instruction Information -------*- C++ -*-=//
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 Hexagon implementation of the TargetInstrInfo class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "HexagonRegisterInfo.h"
15#include "HexagonInstrInfo.h"
16#include "HexagonSubtarget.h"
17#include "Hexagon.h"
18#include "llvm/Support/MathExtras.h"
19#include "llvm/ADT/STLExtras.h"
20#include "llvm/ADT/SmallVector.h"
21#include "llvm/CodeGen/MachineInstrBuilder.h"
22#include "llvm/CodeGen/MachineRegisterInfo.h"
23#include "llvm/CodeGen/MachineFrameInfo.h"
24#include "llvm/CodeGen/MachineMemOperand.h"
25#include "llvm/CodeGen/PseudoSourceValue.h"
26#define GET_INSTRINFO_CTOR
27#include "HexagonGenInstrInfo.inc"
28
29#include <iostream>
30
31
32using namespace llvm;
33
34///
35/// Constants for Hexagon instructions.
36///
37const int Hexagon_MEMW_OFFSET_MAX = 4095;
38const int Hexagon_MEMW_OFFSET_MIN = 4096;
39const int Hexagon_MEMD_OFFSET_MAX = 8191;
40const int Hexagon_MEMD_OFFSET_MIN = 8192;
41const int Hexagon_MEMH_OFFSET_MAX = 2047;
42const int Hexagon_MEMH_OFFSET_MIN = 2048;
43const int Hexagon_MEMB_OFFSET_MAX = 1023;
44const int Hexagon_MEMB_OFFSET_MIN = 1024;
45const int Hexagon_ADDI_OFFSET_MAX = 32767;
46const int Hexagon_ADDI_OFFSET_MIN = 32768;
47const int Hexagon_MEMD_AUTOINC_MAX = 56;
48const int Hexagon_MEMD_AUTOINC_MIN = 64;
49const int Hexagon_MEMW_AUTOINC_MAX = 28;
50const int Hexagon_MEMW_AUTOINC_MIN = 32;
51const int Hexagon_MEMH_AUTOINC_MAX = 14;
52const int Hexagon_MEMH_AUTOINC_MIN = 16;
53const int Hexagon_MEMB_AUTOINC_MAX = 7;
54const int Hexagon_MEMB_AUTOINC_MIN = 8;
55
56
57
58HexagonInstrInfo::HexagonInstrInfo(HexagonSubtarget &ST)
59  : HexagonGenInstrInfo(Hexagon::ADJCALLSTACKDOWN, Hexagon::ADJCALLSTACKUP),
60    RI(ST, *this), Subtarget(ST) {
61}
62
63
64/// isLoadFromStackSlot - If the specified machine instruction is a direct
65/// load from a stack slot, return the virtual or physical register number of
66/// the destination along with the FrameIndex of the loaded stack slot.  If
67/// not, return 0.  This predicate must return 0 if the instruction has
68/// any side effects other than loading from the stack slot.
69unsigned HexagonInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
70                                             int &FrameIndex) const {
71
72
73  switch (MI->getOpcode()) {
74  case Hexagon::LDriw:
75  case Hexagon::LDrid:
76  case Hexagon::LDrih:
77  case Hexagon::LDrib:
78  case Hexagon::LDriub:
79    if (MI->getOperand(2).isFI() &&
80        MI->getOperand(1).isImm() && (MI->getOperand(1).getImm() == 0)) {
81      FrameIndex = MI->getOperand(2).getIndex();
82      return MI->getOperand(0).getReg();
83    }
84    break;
85
86  default:
87    break;
88  }
89
90  return 0;
91}
92
93
94/// isStoreToStackSlot - If the specified machine instruction is a direct
95/// store to a stack slot, return the virtual or physical register number of
96/// the source reg along with the FrameIndex of the loaded stack slot.  If
97/// not, return 0.  This predicate must return 0 if the instruction has
98/// any side effects other than storing to the stack slot.
99unsigned HexagonInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
100                                            int &FrameIndex) const {
101  switch (MI->getOpcode()) {
102  case Hexagon::STriw:
103  case Hexagon::STrid:
104  case Hexagon::STrih:
105  case Hexagon::STrib:
106    if (MI->getOperand(2).isFI() &&
107        MI->getOperand(1).isImm() && (MI->getOperand(1).getImm() == 0)) {
108      FrameIndex = MI->getOperand(2).getIndex();
109      return MI->getOperand(0).getReg();
110    }
111    break;
112
113  default:
114    break;
115  }
116
117  return 0;
118}
119
120
121unsigned
122HexagonInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB,
123                             MachineBasicBlock *FBB,
124                             const SmallVectorImpl<MachineOperand> &Cond,
125                             DebugLoc DL) const{
126
127    int BOpc   = Hexagon::JMP;
128    int BccOpc = Hexagon::JMP_Pred;
129
130    assert(TBB && "InsertBranch must not be told to insert a fallthrough");
131
132    int regPos = 0;
133    // Check if ReverseBranchCondition has asked to reverse this branch
134    // If we want to reverse the branch an odd number of times, we want
135    // JMP_PredNot.
136    if (!Cond.empty() && Cond[0].isImm() && Cond[0].getImm() == 0) {
137      BccOpc = Hexagon::JMP_PredNot;
138      regPos = 1;
139    }
140
141    if (FBB == 0) {
142      if (Cond.empty()) {
143        // Due to a bug in TailMerging/CFG Optimization, we need to add a
144        // special case handling of a predicated jump followed by an
145        // unconditional jump. If not, Tail Merging and CFG Optimization go
146        // into an infinite loop.
147        MachineBasicBlock *NewTBB, *NewFBB;
148        SmallVector<MachineOperand, 4> Cond;
149        MachineInstr *Term = MBB.getFirstTerminator();
150        if (isPredicated(Term) && !AnalyzeBranch(MBB, NewTBB, NewFBB, Cond,
151                                                 false)) {
152          MachineBasicBlock *NextBB =
153            llvm::next(MachineFunction::iterator(&MBB));
154          if (NewTBB == NextBB) {
155            ReverseBranchCondition(Cond);
156            RemoveBranch(MBB);
157            return InsertBranch(MBB, TBB, 0, Cond, DL);
158          }
159        }
160        BuildMI(&MBB, DL, get(BOpc)).addMBB(TBB);
161      } else {
162        BuildMI(&MBB, DL,
163                get(BccOpc)).addReg(Cond[regPos].getReg()).addMBB(TBB);
164      }
165      return 1;
166    }
167
168    BuildMI(&MBB, DL, get(BccOpc)).addReg(Cond[regPos].getReg()).addMBB(TBB);
169    BuildMI(&MBB, DL, get(BOpc)).addMBB(FBB);
170
171    return 2;
172}
173
174
175bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
176                                     MachineBasicBlock *&TBB,
177                                 MachineBasicBlock *&FBB,
178                                 SmallVectorImpl<MachineOperand> &Cond,
179                                 bool AllowModify) const {
180  FBB = NULL;
181
182  // If the block has no terminators, it just falls into the block after it.
183  MachineBasicBlock::iterator I = MBB.end();
184  if (I == MBB.begin())
185    return false;
186
187  // A basic block may looks like this:
188  //
189  //  [   insn
190  //     EH_LABEL
191  //      insn
192  //      insn
193  //      insn
194  //     EH_LABEL
195  //      insn     ]
196  //
197  // It has two succs but does not have a terminator
198  // Don't know how to handle it.
199  do {
200    --I;
201    if (I->isEHLabel())
202      return true;
203  } while (I != MBB.begin());
204
205  I = MBB.end();
206  --I;
207
208  while (I->isDebugValue()) {
209    if (I == MBB.begin())
210      return false;
211    --I;
212  }
213  if (!isUnpredicatedTerminator(I))
214    return false;
215
216  // Get the last instruction in the block.
217  MachineInstr *LastInst = I;
218
219  // If there is only one terminator instruction, process it.
220  if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
221    if (LastInst->getOpcode() == Hexagon::JMP) {
222      TBB = LastInst->getOperand(0).getMBB();
223      return false;
224    }
225    if (LastInst->getOpcode() == Hexagon::JMP_Pred) {
226      // Block ends with fall-through true condbranch.
227      TBB = LastInst->getOperand(1).getMBB();
228      Cond.push_back(LastInst->getOperand(0));
229      return false;
230    }
231    if (LastInst->getOpcode() == Hexagon::JMP_PredNot) {
232      // Block ends with fall-through false condbranch.
233      TBB = LastInst->getOperand(1).getMBB();
234      Cond.push_back(MachineOperand::CreateImm(0));
235      Cond.push_back(LastInst->getOperand(0));
236      return false;
237    }
238    // Otherwise, don't know what this is.
239    return true;
240  }
241
242  // Get the instruction before it if it's a terminator.
243  MachineInstr *SecondLastInst = I;
244
245  // If there are three terminators, we don't know what sort of block this is.
246  if (SecondLastInst && I != MBB.begin() &&
247      isUnpredicatedTerminator(--I))
248    return true;
249
250  // If the block ends with Hexagon::BRCOND and Hexagon:JMP, handle it.
251  if (((SecondLastInst->getOpcode() == Hexagon::BRCOND) ||
252      (SecondLastInst->getOpcode() == Hexagon::JMP_Pred)) &&
253      LastInst->getOpcode() == Hexagon::JMP) {
254    TBB =  SecondLastInst->getOperand(1).getMBB();
255    Cond.push_back(SecondLastInst->getOperand(0));
256    FBB = LastInst->getOperand(0).getMBB();
257    return false;
258  }
259
260  // If the block ends with Hexagon::JMP_PredNot and Hexagon:JMP, handle it.
261  if ((SecondLastInst->getOpcode() == Hexagon::JMP_PredNot) &&
262      LastInst->getOpcode() == Hexagon::JMP) {
263    TBB =  SecondLastInst->getOperand(1).getMBB();
264    Cond.push_back(MachineOperand::CreateImm(0));
265    Cond.push_back(SecondLastInst->getOperand(0));
266    FBB = LastInst->getOperand(0).getMBB();
267    return false;
268  }
269
270  // If the block ends with two Hexagon:JMPs, handle it.  The second one is not
271  // executed, so remove it.
272  if (SecondLastInst->getOpcode() == Hexagon::JMP &&
273      LastInst->getOpcode() == Hexagon::JMP) {
274    TBB = SecondLastInst->getOperand(0).getMBB();
275    I = LastInst;
276    if (AllowModify)
277      I->eraseFromParent();
278    return false;
279  }
280
281  // Otherwise, can't handle this.
282  return true;
283}
284
285
286unsigned HexagonInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
287  int BOpc   = Hexagon::JMP;
288  int BccOpc = Hexagon::JMP_Pred;
289  int BccOpcNot = Hexagon::JMP_PredNot;
290
291  MachineBasicBlock::iterator I = MBB.end();
292  if (I == MBB.begin()) return 0;
293  --I;
294  if (I->getOpcode() != BOpc && I->getOpcode() != BccOpc &&
295      I->getOpcode() != BccOpcNot)
296    return 0;
297
298  // Remove the branch.
299  I->eraseFromParent();
300
301  I = MBB.end();
302
303  if (I == MBB.begin()) return 1;
304  --I;
305  if (I->getOpcode() != BccOpc && I->getOpcode() != BccOpcNot)
306    return 1;
307
308  // Remove the branch.
309  I->eraseFromParent();
310  return 2;
311}
312
313
314void HexagonInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
315                                 MachineBasicBlock::iterator I, DebugLoc DL,
316                                 unsigned DestReg, unsigned SrcReg,
317                                 bool KillSrc) const {
318  if (Hexagon::IntRegsRegClass.contains(SrcReg, DestReg)) {
319    BuildMI(MBB, I, DL, get(Hexagon::TFR), DestReg).addReg(SrcReg);
320    return;
321  }
322  if (Hexagon::DoubleRegsRegClass.contains(SrcReg, DestReg)) {
323    BuildMI(MBB, I, DL, get(Hexagon::TFR_64), DestReg).addReg(SrcReg);
324    return;
325  }
326  if (Hexagon::PredRegsRegClass.contains(SrcReg, DestReg)) {
327    // Map Pd = Ps to Pd = or(Ps, Ps).
328    BuildMI(MBB, I, DL, get(Hexagon::OR_pp),
329            DestReg).addReg(SrcReg).addReg(SrcReg);
330    return;
331  }
332  if (Hexagon::DoubleRegsRegClass.contains(DestReg, SrcReg)) {
333    // We can have an overlap between single and double reg: r1:0 = r0.
334    if(SrcReg == RI.getSubReg(DestReg, Hexagon::subreg_loreg)) {
335        // r1:0 = r0
336        BuildMI(MBB, I, DL, get(Hexagon::TFRI), (RI.getSubReg(DestReg,
337                Hexagon::subreg_hireg))).addImm(0);
338    } else {
339        // r1:0 = r1 or no overlap.
340        BuildMI(MBB, I, DL, get(Hexagon::TFR), (RI.getSubReg(DestReg,
341                Hexagon::subreg_loreg))).addReg(SrcReg);
342        BuildMI(MBB, I, DL, get(Hexagon::TFRI), (RI.getSubReg(DestReg,
343                Hexagon::subreg_hireg))).addImm(0);
344    }
345    return;
346  }
347  if (Hexagon::CRRegsRegClass.contains(DestReg, SrcReg)) {
348    BuildMI(MBB, I, DL, get(Hexagon::TFCR), DestReg).addReg(SrcReg);
349    return;
350  }
351
352  assert (0 && "Unimplemented");
353}
354
355
356void HexagonInstrInfo::
357storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
358                    unsigned SrcReg, bool isKill, int FI,
359                    const TargetRegisterClass *RC,
360                    const TargetRegisterInfo *TRI) const {
361
362  DebugLoc DL = MBB.findDebugLoc(I);
363  MachineFunction &MF = *MBB.getParent();
364  MachineFrameInfo &MFI = *MF.getFrameInfo();
365  unsigned Align = MFI.getObjectAlignment(FI);
366
367  MachineMemOperand *MMO =
368      MF.getMachineMemOperand(
369                      MachinePointerInfo(PseudoSourceValue::getFixedStack(FI)),
370                      MachineMemOperand::MOStore,
371                      MFI.getObjectSize(FI),
372                      Align);
373
374  if (Hexagon::IntRegsRegisterClass->hasSubClassEq(RC)) {
375    BuildMI(MBB, I, DL, get(Hexagon::STriw))
376          .addFrameIndex(FI).addImm(0)
377          .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
378  } else if (Hexagon::DoubleRegsRegisterClass->hasSubClassEq(RC)) {
379    BuildMI(MBB, I, DL, get(Hexagon::STrid))
380          .addFrameIndex(FI).addImm(0)
381          .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
382  } else if (Hexagon::PredRegsRegisterClass->hasSubClassEq(RC)) {
383    BuildMI(MBB, I, DL, get(Hexagon::STriw_pred))
384          .addFrameIndex(FI).addImm(0)
385          .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
386  } else {
387    assert(0 && "Unimplemented");
388  }
389}
390
391
392void HexagonInstrInfo::storeRegToAddr(
393                                 MachineFunction &MF, unsigned SrcReg,
394                                 bool isKill,
395                                 SmallVectorImpl<MachineOperand> &Addr,
396                                 const TargetRegisterClass *RC,
397                                 SmallVectorImpl<MachineInstr*> &NewMIs) const
398{
399  assert(0 && "Unimplemented");
400  return;
401}
402
403
404void HexagonInstrInfo::
405loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
406                     unsigned DestReg, int FI,
407                     const TargetRegisterClass *RC,
408                     const TargetRegisterInfo *TRI) const {
409  DebugLoc DL = MBB.findDebugLoc(I);
410  MachineFunction &MF = *MBB.getParent();
411  MachineFrameInfo &MFI = *MF.getFrameInfo();
412  unsigned Align = MFI.getObjectAlignment(FI);
413
414  MachineMemOperand *MMO =
415      MF.getMachineMemOperand(
416                      MachinePointerInfo(PseudoSourceValue::getFixedStack(FI)),
417                      MachineMemOperand::MOLoad,
418                      MFI.getObjectSize(FI),
419                      Align);
420
421  if (RC == Hexagon::IntRegsRegisterClass) {
422    BuildMI(MBB, I, DL, get(Hexagon::LDriw), DestReg)
423          .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
424  } else if (RC == Hexagon::DoubleRegsRegisterClass) {
425    BuildMI(MBB, I, DL, get(Hexagon::LDrid), DestReg)
426          .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
427  } else if (RC == Hexagon::PredRegsRegisterClass) {
428    BuildMI(MBB, I, DL, get(Hexagon::LDriw_pred), DestReg)
429          .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
430  } else {
431    assert(0 && "Can't store this register to stack slot");
432  }
433}
434
435
436void HexagonInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
437                                        SmallVectorImpl<MachineOperand> &Addr,
438                                        const TargetRegisterClass *RC,
439                                 SmallVectorImpl<MachineInstr*> &NewMIs) const {
440  assert(0 && "Unimplemented");
441}
442
443
444MachineInstr *HexagonInstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
445                                                    MachineInstr* MI,
446                                          const SmallVectorImpl<unsigned> &Ops,
447                                                    int FI) const {
448  // Hexagon_TODO: Implement.
449  return(0);
450}
451
452
453unsigned HexagonInstrInfo::createVR(MachineFunction* MF, MVT VT) const {
454
455  MachineRegisterInfo &RegInfo = MF->getRegInfo();
456  const TargetRegisterClass *TRC;
457  if (VT == MVT::i1) {
458    TRC =  Hexagon::PredRegsRegisterClass;
459  } else if (VT == MVT::i32) {
460    TRC =  Hexagon::IntRegsRegisterClass;
461  } else if (VT == MVT::i64) {
462    TRC =  Hexagon::DoubleRegsRegisterClass;
463  } else {
464    llvm_unreachable("Cannot handle this register class");
465  }
466
467  unsigned NewReg = RegInfo.createVirtualRegister(TRC);
468  return NewReg;
469}
470
471
472bool HexagonInstrInfo::isPredicable(MachineInstr *MI) const {
473  bool isPred = MI->getDesc().isPredicable();
474
475  if (!isPred)
476    return false;
477
478  const int Opc = MI->getOpcode();
479
480  switch(Opc) {
481  case Hexagon::TFRI:
482    return isInt<12>(MI->getOperand(1).getImm());
483
484  case Hexagon::STrid:
485  case Hexagon::STrid_indexed:
486    return isShiftedUInt<6,3>(MI->getOperand(1).getImm());
487
488  case Hexagon::STriw:
489  case Hexagon::STriw_indexed:
490  case Hexagon::STriw_nv_V4:
491    return isShiftedUInt<6,2>(MI->getOperand(1).getImm());
492
493  case Hexagon::STrih:
494  case Hexagon::STrih_indexed:
495  case Hexagon::STrih_nv_V4:
496    return isShiftedUInt<6,1>(MI->getOperand(1).getImm());
497
498  case Hexagon::STrib:
499  case Hexagon::STrib_indexed:
500  case Hexagon::STrib_nv_V4:
501    return isUInt<6>(MI->getOperand(1).getImm());
502
503  case Hexagon::LDrid:
504  case Hexagon::LDrid_indexed:
505    return isShiftedUInt<6,3>(MI->getOperand(2).getImm());
506
507  case Hexagon::LDriw:
508  case Hexagon::LDriw_indexed:
509    return isShiftedUInt<6,2>(MI->getOperand(2).getImm());
510
511  case Hexagon::LDrih:
512  case Hexagon::LDriuh:
513  case Hexagon::LDrih_indexed:
514  case Hexagon::LDriuh_indexed:
515    return isShiftedUInt<6,1>(MI->getOperand(2).getImm());
516
517  case Hexagon::LDrib:
518  case Hexagon::LDriub:
519  case Hexagon::LDrib_indexed:
520  case Hexagon::LDriub_indexed:
521    return isUInt<6>(MI->getOperand(2).getImm());
522
523  case Hexagon::POST_LDrid:
524    return isShiftedInt<4,3>(MI->getOperand(3).getImm());
525
526  case Hexagon::POST_LDriw:
527    return isShiftedInt<4,2>(MI->getOperand(3).getImm());
528
529  case Hexagon::POST_LDrih:
530  case Hexagon::POST_LDriuh:
531    return isShiftedInt<4,1>(MI->getOperand(3).getImm());
532
533  case Hexagon::POST_LDrib:
534  case Hexagon::POST_LDriub:
535    return isInt<4>(MI->getOperand(3).getImm());
536
537  case Hexagon::STrib_imm_V4:
538  case Hexagon::STrih_imm_V4:
539  case Hexagon::STriw_imm_V4:
540    return (isUInt<6>(MI->getOperand(1).getImm()) &&
541            isInt<6>(MI->getOperand(2).getImm()));
542
543  case Hexagon::ADD_ri:
544    return isInt<8>(MI->getOperand(2).getImm());
545
546  case Hexagon::ASLH:
547  case Hexagon::ASRH:
548  case Hexagon::SXTB:
549  case Hexagon::SXTH:
550  case Hexagon::ZXTB:
551  case Hexagon::ZXTH:
552    return Subtarget.getHexagonArchVersion() == HexagonSubtarget::V4;
553
554  case Hexagon::JMPR:
555    return false;
556  }
557
558  return true;
559}
560
561
562int HexagonInstrInfo::
563getMatchingCondBranchOpcode(int Opc, bool invertPredicate) const {
564  switch(Opc) {
565  case Hexagon::TFR:
566    return !invertPredicate ? Hexagon::TFR_cPt :
567                              Hexagon::TFR_cNotPt;
568  case Hexagon::TFRI:
569    return !invertPredicate ? Hexagon::TFRI_cPt :
570                              Hexagon::TFRI_cNotPt;
571  case Hexagon::JMP:
572    return !invertPredicate ? Hexagon::JMP_Pred :
573                              Hexagon::JMP_PredNot;
574  case Hexagon::ADD_ri:
575    return !invertPredicate ? Hexagon::ADD_ri_cPt :
576                              Hexagon::ADD_ri_cNotPt;
577  case Hexagon::ADD_rr:
578    return !invertPredicate ? Hexagon::ADD_rr_cPt :
579                              Hexagon::ADD_rr_cNotPt;
580  case Hexagon::XOR_rr:
581    return !invertPredicate ? Hexagon::XOR_rr_cPt :
582                              Hexagon::XOR_rr_cNotPt;
583  case Hexagon::AND_rr:
584    return !invertPredicate ? Hexagon::AND_rr_cPt :
585                              Hexagon::AND_rr_cNotPt;
586  case Hexagon::OR_rr:
587    return !invertPredicate ? Hexagon::OR_rr_cPt :
588                              Hexagon::OR_rr_cNotPt;
589  case Hexagon::SUB_rr:
590    return !invertPredicate ? Hexagon::SUB_rr_cPt :
591                              Hexagon::SUB_rr_cNotPt;
592  case Hexagon::COMBINE_rr:
593    return !invertPredicate ? Hexagon::COMBINE_rr_cPt :
594                              Hexagon::COMBINE_rr_cNotPt;
595  case Hexagon::ASLH:
596    return !invertPredicate ? Hexagon::ASLH_cPt_V4 :
597                              Hexagon::ASLH_cNotPt_V4;
598  case Hexagon::ASRH:
599    return !invertPredicate ? Hexagon::ASRH_cPt_V4 :
600                              Hexagon::ASRH_cNotPt_V4;
601  case Hexagon::SXTB:
602    return !invertPredicate ? Hexagon::SXTB_cPt_V4 :
603                              Hexagon::SXTB_cNotPt_V4;
604  case Hexagon::SXTH:
605    return !invertPredicate ? Hexagon::SXTH_cPt_V4 :
606                              Hexagon::SXTH_cNotPt_V4;
607  case Hexagon::ZXTB:
608    return !invertPredicate ? Hexagon::ZXTB_cPt_V4 :
609                              Hexagon::ZXTB_cNotPt_V4;
610  case Hexagon::ZXTH:
611    return !invertPredicate ? Hexagon::ZXTH_cPt_V4 :
612                              Hexagon::ZXTH_cNotPt_V4;
613
614  case Hexagon::JMPR:
615    return !invertPredicate ? Hexagon::JMPR_cPt :
616                              Hexagon::JMPR_cNotPt;
617
618  // V4 indexed+scaled load.
619  case Hexagon::LDrid_indexed_V4:
620    return !invertPredicate ? Hexagon::LDrid_indexed_cPt_V4 :
621                              Hexagon::LDrid_indexed_cNotPt_V4;
622  case Hexagon::LDrid_indexed_shl_V4:
623    return !invertPredicate ? Hexagon::LDrid_indexed_shl_cPt_V4 :
624                              Hexagon::LDrid_indexed_shl_cNotPt_V4;
625  case Hexagon::LDrib_indexed_V4:
626    return !invertPredicate ? Hexagon::LDrib_indexed_cPt_V4 :
627                              Hexagon::LDrib_indexed_cNotPt_V4;
628  case Hexagon::LDriub_indexed_V4:
629    return !invertPredicate ? Hexagon::LDriub_indexed_cPt_V4 :
630                              Hexagon::LDriub_indexed_cNotPt_V4;
631  case Hexagon::LDriub_ae_indexed_V4:
632    return !invertPredicate ? Hexagon::LDriub_indexed_cPt_V4 :
633                              Hexagon::LDriub_indexed_cNotPt_V4;
634  case Hexagon::LDrib_indexed_shl_V4:
635    return !invertPredicate ? Hexagon::LDrib_indexed_shl_cPt_V4 :
636                              Hexagon::LDrib_indexed_shl_cNotPt_V4;
637  case Hexagon::LDriub_indexed_shl_V4:
638    return !invertPredicate ? Hexagon::LDriub_indexed_shl_cPt_V4 :
639                              Hexagon::LDriub_indexed_shl_cNotPt_V4;
640  case Hexagon::LDriub_ae_indexed_shl_V4:
641    return !invertPredicate ? Hexagon::LDriub_indexed_shl_cPt_V4 :
642                              Hexagon::LDriub_indexed_shl_cNotPt_V4;
643  case Hexagon::LDrih_indexed_V4:
644    return !invertPredicate ? Hexagon::LDrih_indexed_cPt_V4 :
645                              Hexagon::LDrih_indexed_cNotPt_V4;
646  case Hexagon::LDriuh_indexed_V4:
647    return !invertPredicate ? Hexagon::LDriuh_indexed_cPt_V4 :
648                              Hexagon::LDriuh_indexed_cNotPt_V4;
649  case Hexagon::LDriuh_ae_indexed_V4:
650    return !invertPredicate ? Hexagon::LDriuh_indexed_cPt_V4 :
651                              Hexagon::LDriuh_indexed_cNotPt_V4;
652  case Hexagon::LDrih_indexed_shl_V4:
653    return !invertPredicate ? Hexagon::LDrih_indexed_shl_cPt_V4 :
654                              Hexagon::LDrih_indexed_shl_cNotPt_V4;
655  case Hexagon::LDriuh_indexed_shl_V4:
656    return !invertPredicate ? Hexagon::LDriuh_indexed_shl_cPt_V4 :
657                              Hexagon::LDriuh_indexed_shl_cNotPt_V4;
658  case Hexagon::LDriuh_ae_indexed_shl_V4:
659    return !invertPredicate ? Hexagon::LDriuh_indexed_shl_cPt_V4 :
660                              Hexagon::LDriuh_indexed_shl_cNotPt_V4;
661  case Hexagon::LDriw_indexed_V4:
662    return !invertPredicate ? Hexagon::LDriw_indexed_cPt_V4 :
663                              Hexagon::LDriw_indexed_cNotPt_V4;
664  case Hexagon::LDriw_indexed_shl_V4:
665    return !invertPredicate ? Hexagon::LDriw_indexed_shl_cPt_V4 :
666                              Hexagon::LDriw_indexed_shl_cNotPt_V4;
667    // Byte.
668  case Hexagon::POST_STbri:
669    return !invertPredicate ? Hexagon::POST_STbri_cPt :
670                              Hexagon::POST_STbri_cNotPt;
671  case Hexagon::STrib:
672    return !invertPredicate ? Hexagon::STrib_cPt :
673                              Hexagon::STrib_cNotPt;
674  case Hexagon::STrib_indexed:
675    return !invertPredicate ? Hexagon::STrib_indexed_cPt :
676                              Hexagon::STrib_indexed_cNotPt;
677  case Hexagon::STrib_imm_V4:
678    return !invertPredicate ? Hexagon::STrib_imm_cPt_V4 :
679                              Hexagon::STrib_imm_cNotPt_V4;
680  case Hexagon::STrib_indexed_shl_V4:
681    return !invertPredicate ? Hexagon::STrib_indexed_shl_cPt_V4 :
682                              Hexagon::STrib_indexed_shl_cNotPt_V4;
683  // Halfword.
684  case Hexagon::POST_SThri:
685    return !invertPredicate ? Hexagon::POST_SThri_cPt :
686                              Hexagon::POST_SThri_cNotPt;
687  case Hexagon::STrih:
688    return !invertPredicate ? Hexagon::STrih_cPt :
689                              Hexagon::STrih_cNotPt;
690  case Hexagon::STrih_indexed:
691    return !invertPredicate ? Hexagon::STrih_indexed_cPt :
692                              Hexagon::STrih_indexed_cNotPt;
693  case Hexagon::STrih_imm_V4:
694    return !invertPredicate ? Hexagon::STrih_imm_cPt_V4 :
695                              Hexagon::STrih_imm_cNotPt_V4;
696  case Hexagon::STrih_indexed_shl_V4:
697    return !invertPredicate ? Hexagon::STrih_indexed_shl_cPt_V4 :
698                              Hexagon::STrih_indexed_shl_cNotPt_V4;
699  // Word.
700  case Hexagon::POST_STwri:
701    return !invertPredicate ? Hexagon::POST_STwri_cPt :
702                              Hexagon::POST_STwri_cNotPt;
703  case Hexagon::STriw:
704    return !invertPredicate ? Hexagon::STriw_cPt :
705                              Hexagon::STriw_cNotPt;
706  case Hexagon::STriw_indexed:
707    return !invertPredicate ? Hexagon::STriw_indexed_cPt :
708                              Hexagon::STriw_indexed_cNotPt;
709  case Hexagon::STriw_indexed_shl_V4:
710    return !invertPredicate ? Hexagon::STriw_indexed_shl_cPt_V4 :
711                              Hexagon::STriw_indexed_shl_cNotPt_V4;
712  case Hexagon::STriw_imm_V4:
713    return !invertPredicate ? Hexagon::STriw_imm_cPt_V4 :
714                              Hexagon::STriw_imm_cNotPt_V4;
715  // Double word.
716  case Hexagon::POST_STdri:
717    return !invertPredicate ? Hexagon::POST_STdri_cPt :
718                              Hexagon::POST_STdri_cNotPt;
719  case Hexagon::STrid:
720    return !invertPredicate ? Hexagon::STrid_cPt :
721                              Hexagon::STrid_cNotPt;
722  case Hexagon::STrid_indexed:
723    return !invertPredicate ? Hexagon::STrid_indexed_cPt :
724                              Hexagon::STrid_indexed_cNotPt;
725  case Hexagon::STrid_indexed_shl_V4:
726    return !invertPredicate ? Hexagon::STrid_indexed_shl_cPt_V4 :
727                              Hexagon::STrid_indexed_shl_cNotPt_V4;
728  // Load.
729  case Hexagon::LDrid:
730    return !invertPredicate ? Hexagon::LDrid_cPt :
731                              Hexagon::LDrid_cNotPt;
732  case Hexagon::LDriw:
733    return !invertPredicate ? Hexagon::LDriw_cPt :
734                              Hexagon::LDriw_cNotPt;
735  case Hexagon::LDrih:
736    return !invertPredicate ? Hexagon::LDrih_cPt :
737                              Hexagon::LDrih_cNotPt;
738  case Hexagon::LDriuh:
739    return !invertPredicate ? Hexagon::LDriuh_cPt :
740                              Hexagon::LDriuh_cNotPt;
741  case Hexagon::LDrib:
742    return !invertPredicate ? Hexagon::LDrib_cPt :
743                              Hexagon::LDrib_cNotPt;
744  case Hexagon::LDriub:
745    return !invertPredicate ? Hexagon::LDriub_cPt :
746                              Hexagon::LDriub_cNotPt;
747  case Hexagon::LDriubit:
748    return !invertPredicate ? Hexagon::LDriub_cPt :
749                              Hexagon::LDriub_cNotPt;
750 // Load Indexed.
751  case Hexagon::LDrid_indexed:
752    return !invertPredicate ? Hexagon::LDrid_indexed_cPt :
753                              Hexagon::LDrid_indexed_cNotPt;
754  case Hexagon::LDriw_indexed:
755    return !invertPredicate ? Hexagon::LDriw_indexed_cPt :
756                              Hexagon::LDriw_indexed_cNotPt;
757  case Hexagon::LDrih_indexed:
758    return !invertPredicate ? Hexagon::LDrih_indexed_cPt :
759                              Hexagon::LDrih_indexed_cNotPt;
760  case Hexagon::LDriuh_indexed:
761    return !invertPredicate ? Hexagon::LDriuh_indexed_cPt :
762                              Hexagon::LDriuh_indexed_cNotPt;
763  case Hexagon::LDrib_indexed:
764    return !invertPredicate ? Hexagon::LDrib_indexed_cPt :
765                              Hexagon::LDrib_indexed_cNotPt;
766  case Hexagon::LDriub_indexed:
767    return !invertPredicate ? Hexagon::LDriub_indexed_cPt :
768                              Hexagon::LDriub_indexed_cNotPt;
769  // Post Increment Load.
770  case Hexagon::POST_LDrid:
771    return !invertPredicate ? Hexagon::POST_LDrid_cPt :
772                              Hexagon::POST_LDrid_cNotPt;
773  case Hexagon::POST_LDriw:
774    return !invertPredicate ? Hexagon::POST_LDriw_cPt :
775                              Hexagon::POST_LDriw_cNotPt;
776  case Hexagon::POST_LDrih:
777    return !invertPredicate ? Hexagon::POST_LDrih_cPt :
778                              Hexagon::POST_LDrih_cNotPt;
779  case Hexagon::POST_LDriuh:
780    return !invertPredicate ? Hexagon::POST_LDriuh_cPt :
781                              Hexagon::POST_LDriuh_cNotPt;
782  case Hexagon::POST_LDrib:
783    return !invertPredicate ? Hexagon::POST_LDrib_cPt :
784                              Hexagon::POST_LDrib_cNotPt;
785  case Hexagon::POST_LDriub:
786    return !invertPredicate ? Hexagon::POST_LDriub_cPt :
787                              Hexagon::POST_LDriub_cNotPt;
788  // DEALLOC_RETURN.
789  case Hexagon::DEALLOC_RET_V4:
790    return !invertPredicate ? Hexagon::DEALLOC_RET_cPt_V4 :
791                              Hexagon::DEALLOC_RET_cNotPt_V4;
792  }
793  llvm_unreachable("Unexpected predicable instruction");
794}
795
796
797bool HexagonInstrInfo::
798PredicateInstruction(MachineInstr *MI,
799                     const SmallVectorImpl<MachineOperand> &Cond) const {
800  int Opc = MI->getOpcode();
801  assert (isPredicable(MI) && "Expected predicable instruction");
802  bool invertJump = (!Cond.empty() && Cond[0].isImm() &&
803                     (Cond[0].getImm() == 0));
804  MI->setDesc(get(getMatchingCondBranchOpcode(Opc, invertJump)));
805  //
806  // This assumes that the predicate is always the first operand
807  // in the set of inputs.
808  //
809  MI->addOperand(MI->getOperand(MI->getNumOperands()-1));
810  int oper;
811  for (oper = MI->getNumOperands() - 3; oper >= 0; --oper) {
812    MachineOperand MO = MI->getOperand(oper);
813    if ((MO.isReg() && !MO.isUse() && !MO.isImplicit())) {
814      break;
815    }
816
817    if (MO.isReg()) {
818      MI->getOperand(oper+1).ChangeToRegister(MO.getReg(), MO.isDef(),
819                                              MO.isImplicit(), MO.isKill(),
820                                              MO.isDead(), MO.isUndef(),
821                                              MO.isDebug());
822    } else if (MO.isImm()) {
823      MI->getOperand(oper+1).ChangeToImmediate(MO.getImm());
824    } else {
825      assert(false && "Unexpected operand type");
826    }
827  }
828
829  int regPos = invertJump ? 1 : 0;
830  MachineOperand PredMO = Cond[regPos];
831  MI->getOperand(oper+1).ChangeToRegister(PredMO.getReg(), PredMO.isDef(),
832                                          PredMO.isImplicit(), PredMO.isKill(),
833                                          PredMO.isDead(), PredMO.isUndef(),
834                                          PredMO.isDebug());
835
836  return true;
837}
838
839
840bool
841HexagonInstrInfo::
842isProfitableToIfCvt(MachineBasicBlock &MBB,
843                    unsigned NumCyles,
844                    unsigned ExtraPredCycles,
845                    const BranchProbability &Probability) const {
846  return true;
847}
848
849
850bool
851HexagonInstrInfo::
852isProfitableToIfCvt(MachineBasicBlock &TMBB,
853                    unsigned NumTCycles,
854                    unsigned ExtraTCycles,
855                    MachineBasicBlock &FMBB,
856                    unsigned NumFCycles,
857                    unsigned ExtraFCycles,
858                    const BranchProbability &Probability) const {
859  return true;
860}
861
862
863bool HexagonInstrInfo::isPredicated(const MachineInstr *MI) const {
864  switch (MI->getOpcode()) {
865  case Hexagon::TFR_cPt:
866  case Hexagon::TFR_cNotPt:
867  case Hexagon::TFRI_cPt:
868  case Hexagon::TFRI_cNotPt:
869  case Hexagon::TFR_cdnPt:
870  case Hexagon::TFR_cdnNotPt:
871  case Hexagon::TFRI_cdnPt:
872  case Hexagon::TFRI_cdnNotPt:
873    return true;
874
875  case Hexagon::JMP_Pred:
876  case Hexagon::JMP_PredNot:
877  case Hexagon::BRCOND:
878  case Hexagon::JMP_PredPt:
879  case Hexagon::JMP_PredNotPt:
880  case Hexagon::JMP_PredPnt:
881  case Hexagon::JMP_PredNotPnt:
882    return true;
883
884  case Hexagon::LDrid_indexed_cPt_V4 :
885  case Hexagon::LDrid_indexed_cdnPt_V4 :
886  case Hexagon::LDrid_indexed_cNotPt_V4 :
887  case Hexagon::LDrid_indexed_cdnNotPt_V4 :
888  case Hexagon::LDrid_indexed_shl_cPt_V4 :
889  case Hexagon::LDrid_indexed_shl_cdnPt_V4 :
890  case Hexagon::LDrid_indexed_shl_cNotPt_V4 :
891  case Hexagon::LDrid_indexed_shl_cdnNotPt_V4 :
892  case Hexagon::LDrib_indexed_cPt_V4 :
893  case Hexagon::LDrib_indexed_cdnPt_V4 :
894  case Hexagon::LDrib_indexed_cNotPt_V4 :
895  case Hexagon::LDrib_indexed_cdnNotPt_V4 :
896  case Hexagon::LDrib_indexed_shl_cPt_V4 :
897  case Hexagon::LDrib_indexed_shl_cdnPt_V4 :
898  case Hexagon::LDrib_indexed_shl_cNotPt_V4 :
899  case Hexagon::LDrib_indexed_shl_cdnNotPt_V4 :
900  case Hexagon::LDriub_indexed_cPt_V4 :
901  case Hexagon::LDriub_indexed_cdnPt_V4 :
902  case Hexagon::LDriub_indexed_cNotPt_V4 :
903  case Hexagon::LDriub_indexed_cdnNotPt_V4 :
904  case Hexagon::LDriub_indexed_shl_cPt_V4 :
905  case Hexagon::LDriub_indexed_shl_cdnPt_V4 :
906  case Hexagon::LDriub_indexed_shl_cNotPt_V4 :
907  case Hexagon::LDriub_indexed_shl_cdnNotPt_V4 :
908  case Hexagon::LDrih_indexed_cPt_V4 :
909  case Hexagon::LDrih_indexed_cdnPt_V4 :
910  case Hexagon::LDrih_indexed_cNotPt_V4 :
911  case Hexagon::LDrih_indexed_cdnNotPt_V4 :
912  case Hexagon::LDrih_indexed_shl_cPt_V4 :
913  case Hexagon::LDrih_indexed_shl_cdnPt_V4 :
914  case Hexagon::LDrih_indexed_shl_cNotPt_V4 :
915  case Hexagon::LDrih_indexed_shl_cdnNotPt_V4 :
916  case Hexagon::LDriuh_indexed_cPt_V4 :
917  case Hexagon::LDriuh_indexed_cdnPt_V4 :
918  case Hexagon::LDriuh_indexed_cNotPt_V4 :
919  case Hexagon::LDriuh_indexed_cdnNotPt_V4 :
920  case Hexagon::LDriuh_indexed_shl_cPt_V4 :
921  case Hexagon::LDriuh_indexed_shl_cdnPt_V4 :
922  case Hexagon::LDriuh_indexed_shl_cNotPt_V4 :
923  case Hexagon::LDriuh_indexed_shl_cdnNotPt_V4 :
924  case Hexagon::LDriw_indexed_cPt_V4 :
925  case Hexagon::LDriw_indexed_cdnPt_V4 :
926  case Hexagon::LDriw_indexed_cNotPt_V4 :
927  case Hexagon::LDriw_indexed_cdnNotPt_V4 :
928  case Hexagon::LDriw_indexed_shl_cPt_V4 :
929  case Hexagon::LDriw_indexed_shl_cdnPt_V4 :
930  case Hexagon::LDriw_indexed_shl_cNotPt_V4 :
931  case Hexagon::LDriw_indexed_shl_cdnNotPt_V4 :
932    return true;
933
934  case Hexagon::LDrid_cPt :
935  case Hexagon::LDrid_cNotPt :
936  case Hexagon::LDrid_indexed_cPt :
937  case Hexagon::LDrid_indexed_cNotPt :
938  case Hexagon::POST_LDrid_cPt :
939  case Hexagon::POST_LDrid_cNotPt :
940  case Hexagon::LDriw_cPt :
941  case Hexagon::LDriw_cNotPt :
942  case Hexagon::LDriw_indexed_cPt :
943  case Hexagon::LDriw_indexed_cNotPt :
944  case Hexagon::POST_LDriw_cPt :
945  case Hexagon::POST_LDriw_cNotPt :
946  case Hexagon::LDrih_cPt :
947  case Hexagon::LDrih_cNotPt :
948  case Hexagon::LDrih_indexed_cPt :
949  case Hexagon::LDrih_indexed_cNotPt :
950  case Hexagon::POST_LDrih_cPt :
951  case Hexagon::POST_LDrih_cNotPt :
952  case Hexagon::LDrib_cPt :
953  case Hexagon::LDrib_cNotPt :
954  case Hexagon::LDrib_indexed_cPt :
955  case Hexagon::LDrib_indexed_cNotPt :
956  case Hexagon::POST_LDrib_cPt :
957  case Hexagon::POST_LDrib_cNotPt :
958  case Hexagon::LDriuh_cPt :
959  case Hexagon::LDriuh_cNotPt :
960  case Hexagon::LDriuh_indexed_cPt :
961  case Hexagon::LDriuh_indexed_cNotPt :
962  case Hexagon::POST_LDriuh_cPt :
963  case Hexagon::POST_LDriuh_cNotPt :
964  case Hexagon::LDriub_cPt :
965  case Hexagon::LDriub_cNotPt :
966  case Hexagon::LDriub_indexed_cPt :
967  case Hexagon::LDriub_indexed_cNotPt :
968  case Hexagon::POST_LDriub_cPt :
969  case Hexagon::POST_LDriub_cNotPt :
970    return true;
971
972  case Hexagon::LDrid_cdnPt :
973  case Hexagon::LDrid_cdnNotPt :
974  case Hexagon::LDrid_indexed_cdnPt :
975  case Hexagon::LDrid_indexed_cdnNotPt :
976  case Hexagon::POST_LDrid_cdnPt_V4 :
977  case Hexagon::POST_LDrid_cdnNotPt_V4 :
978  case Hexagon::LDriw_cdnPt :
979  case Hexagon::LDriw_cdnNotPt :
980  case Hexagon::LDriw_indexed_cdnPt :
981  case Hexagon::LDriw_indexed_cdnNotPt :
982  case Hexagon::POST_LDriw_cdnPt_V4 :
983  case Hexagon::POST_LDriw_cdnNotPt_V4 :
984  case Hexagon::LDrih_cdnPt :
985  case Hexagon::LDrih_cdnNotPt :
986  case Hexagon::LDrih_indexed_cdnPt :
987  case Hexagon::LDrih_indexed_cdnNotPt :
988  case Hexagon::POST_LDrih_cdnPt_V4 :
989  case Hexagon::POST_LDrih_cdnNotPt_V4 :
990  case Hexagon::LDrib_cdnPt :
991  case Hexagon::LDrib_cdnNotPt :
992  case Hexagon::LDrib_indexed_cdnPt :
993  case Hexagon::LDrib_indexed_cdnNotPt :
994  case Hexagon::POST_LDrib_cdnPt_V4 :
995  case Hexagon::POST_LDrib_cdnNotPt_V4 :
996  case Hexagon::LDriuh_cdnPt :
997  case Hexagon::LDriuh_cdnNotPt :
998  case Hexagon::LDriuh_indexed_cdnPt :
999  case Hexagon::LDriuh_indexed_cdnNotPt :
1000  case Hexagon::POST_LDriuh_cdnPt_V4 :
1001  case Hexagon::POST_LDriuh_cdnNotPt_V4 :
1002  case Hexagon::LDriub_cdnPt :
1003  case Hexagon::LDriub_cdnNotPt :
1004  case Hexagon::LDriub_indexed_cdnPt :
1005  case Hexagon::LDriub_indexed_cdnNotPt :
1006  case Hexagon::POST_LDriub_cdnPt_V4 :
1007  case Hexagon::POST_LDriub_cdnNotPt_V4 :
1008    return true;
1009
1010  case Hexagon::ADD_ri_cPt:
1011  case Hexagon::ADD_ri_cNotPt:
1012  case Hexagon::ADD_ri_cdnPt:
1013  case Hexagon::ADD_ri_cdnNotPt:
1014  case Hexagon::ADD_rr_cPt:
1015  case Hexagon::ADD_rr_cNotPt:
1016  case Hexagon::ADD_rr_cdnPt:
1017  case Hexagon::ADD_rr_cdnNotPt:
1018  case Hexagon::XOR_rr_cPt:
1019  case Hexagon::XOR_rr_cNotPt:
1020  case Hexagon::XOR_rr_cdnPt:
1021  case Hexagon::XOR_rr_cdnNotPt:
1022  case Hexagon::AND_rr_cPt:
1023  case Hexagon::AND_rr_cNotPt:
1024  case Hexagon::AND_rr_cdnPt:
1025  case Hexagon::AND_rr_cdnNotPt:
1026  case Hexagon::OR_rr_cPt:
1027  case Hexagon::OR_rr_cNotPt:
1028  case Hexagon::OR_rr_cdnPt:
1029  case Hexagon::OR_rr_cdnNotPt:
1030  case Hexagon::SUB_rr_cPt:
1031  case Hexagon::SUB_rr_cNotPt:
1032  case Hexagon::SUB_rr_cdnPt:
1033  case Hexagon::SUB_rr_cdnNotPt:
1034  case Hexagon::COMBINE_rr_cPt:
1035  case Hexagon::COMBINE_rr_cNotPt:
1036  case Hexagon::COMBINE_rr_cdnPt:
1037  case Hexagon::COMBINE_rr_cdnNotPt:
1038    return true;
1039
1040  case Hexagon::ASLH_cPt_V4:
1041  case Hexagon::ASLH_cNotPt_V4:
1042  case Hexagon::ASRH_cPt_V4:
1043  case Hexagon::ASRH_cNotPt_V4:
1044  case Hexagon::SXTB_cPt_V4:
1045  case Hexagon::SXTB_cNotPt_V4:
1046  case Hexagon::SXTH_cPt_V4:
1047  case Hexagon::SXTH_cNotPt_V4:
1048  case Hexagon::ZXTB_cPt_V4:
1049  case Hexagon::ZXTB_cNotPt_V4:
1050  case Hexagon::ZXTH_cPt_V4:
1051  case Hexagon::ZXTH_cNotPt_V4:
1052    return true;
1053
1054  case Hexagon::ASLH_cdnPt_V4:
1055  case Hexagon::ASLH_cdnNotPt_V4:
1056  case Hexagon::ASRH_cdnPt_V4:
1057  case Hexagon::ASRH_cdnNotPt_V4:
1058  case Hexagon::SXTB_cdnPt_V4:
1059  case Hexagon::SXTB_cdnNotPt_V4:
1060  case Hexagon::SXTH_cdnPt_V4:
1061  case Hexagon::SXTH_cdnNotPt_V4:
1062  case Hexagon::ZXTB_cdnPt_V4:
1063  case Hexagon::ZXTB_cdnNotPt_V4:
1064  case Hexagon::ZXTH_cdnPt_V4:
1065  case Hexagon::ZXTH_cdnNotPt_V4:
1066    return true;
1067
1068  default:
1069    return false;
1070  }
1071}
1072
1073
1074bool
1075HexagonInstrInfo::DefinesPredicate(MachineInstr *MI,
1076                                   std::vector<MachineOperand> &Pred) const {
1077  for (unsigned oper = 0; oper < MI->getNumOperands(); ++oper) {
1078    MachineOperand MO = MI->getOperand(oper);
1079    if (MO.isReg() && MO.isDef()) {
1080      const TargetRegisterClass* RC = RI.getMinimalPhysRegClass(MO.getReg());
1081      if (RC == Hexagon::PredRegsRegisterClass) {
1082        Pred.push_back(MO);
1083        return true;
1084      }
1085    }
1086  }
1087  return false;
1088}
1089
1090
1091bool
1092HexagonInstrInfo::
1093SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
1094                  const SmallVectorImpl<MachineOperand> &Pred2) const {
1095  // TODO: Fix this
1096  return false;
1097}
1098
1099
1100//
1101// We indicate that we want to reverse the branch by
1102// inserting a 0 at the beginning of the Cond vector.
1103//
1104bool HexagonInstrInfo::
1105ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
1106  if (!Cond.empty() && Cond[0].isImm() && Cond[0].getImm() == 0) {
1107    Cond.erase(Cond.begin());
1108  } else {
1109    Cond.insert(Cond.begin(), MachineOperand::CreateImm(0));
1110  }
1111  return false;
1112}
1113
1114
1115bool HexagonInstrInfo::
1116isProfitableToDupForIfCvt(MachineBasicBlock &MBB,unsigned NumInstrs,
1117                          const BranchProbability &Probability) const {
1118  return (NumInstrs <= 4);
1119}
1120
1121bool HexagonInstrInfo::isDeallocRet(const MachineInstr *MI) const {
1122  switch (MI->getOpcode()) {
1123  case Hexagon::DEALLOC_RET_V4 :
1124  case Hexagon::DEALLOC_RET_cPt_V4 :
1125  case Hexagon::DEALLOC_RET_cNotPt_V4 :
1126  case Hexagon::DEALLOC_RET_cdnPnt_V4 :
1127  case Hexagon::DEALLOC_RET_cNotdnPnt_V4 :
1128  case Hexagon::DEALLOC_RET_cdnPt_V4 :
1129  case Hexagon::DEALLOC_RET_cNotdnPt_V4 :
1130   return true;
1131  }
1132  return false;
1133}
1134
1135
1136bool HexagonInstrInfo::
1137isValidOffset(const int Opcode, const int Offset) const {
1138  // This function is to check whether the "Offset" is in the correct range of
1139  // the given "Opcode". If "Offset" is not in the correct range, "ADD_ri" is
1140  // inserted to calculate the final address. Due to this reason, the function
1141  // assumes that the "Offset" has correct alignment.
1142
1143  switch(Opcode) {
1144
1145  case Hexagon::LDriw:
1146  case Hexagon::STriw:
1147  case Hexagon::STriwt:
1148    assert((Offset % 4 == 0) && "Offset has incorrect alignment");
1149    return (Offset >= Hexagon_MEMW_OFFSET_MIN) &&
1150      (Offset <= Hexagon_MEMW_OFFSET_MAX);
1151
1152  case Hexagon::LDrid:
1153  case Hexagon::STrid:
1154    assert((Offset % 8 == 0) && "Offset has incorrect alignment");
1155    return (Offset >= Hexagon_MEMD_OFFSET_MIN) &&
1156      (Offset <= Hexagon_MEMD_OFFSET_MAX);
1157
1158  case Hexagon::LDrih:
1159  case Hexagon::LDriuh:
1160  case Hexagon::STrih:
1161  case Hexagon::LDrih_ae:
1162    assert((Offset % 2 == 0) && "Offset has incorrect alignment");
1163    return (Offset >= Hexagon_MEMH_OFFSET_MIN) &&
1164      (Offset <= Hexagon_MEMH_OFFSET_MAX);
1165
1166  case Hexagon::LDrib:
1167  case Hexagon::STrib:
1168  case Hexagon::LDriub:
1169  case Hexagon::LDriubit:
1170  case Hexagon::LDrib_ae:
1171  case Hexagon::LDriub_ae:
1172    return (Offset >= Hexagon_MEMB_OFFSET_MIN) &&
1173      (Offset <= Hexagon_MEMB_OFFSET_MAX);
1174
1175  case Hexagon::ADD_ri:
1176  case Hexagon::TFR_FI:
1177    return (Offset >= Hexagon_ADDI_OFFSET_MIN) &&
1178      (Offset <= Hexagon_ADDI_OFFSET_MAX);
1179
1180  case Hexagon::MEMw_ADDSUBi_indexed_MEM_V4 :
1181  case Hexagon::MEMw_ADDi_indexed_MEM_V4 :
1182  case Hexagon::MEMw_SUBi_indexed_MEM_V4 :
1183  case Hexagon::MEMw_ADDr_indexed_MEM_V4 :
1184  case Hexagon::MEMw_SUBr_indexed_MEM_V4 :
1185  case Hexagon::MEMw_ANDr_indexed_MEM_V4 :
1186  case Hexagon::MEMw_ORr_indexed_MEM_V4 :
1187  case Hexagon::MEMw_ADDSUBi_MEM_V4 :
1188  case Hexagon::MEMw_ADDi_MEM_V4 :
1189  case Hexagon::MEMw_SUBi_MEM_V4 :
1190  case Hexagon::MEMw_ADDr_MEM_V4 :
1191  case Hexagon::MEMw_SUBr_MEM_V4 :
1192  case Hexagon::MEMw_ANDr_MEM_V4 :
1193  case Hexagon::MEMw_ORr_MEM_V4 :
1194    assert ((Offset % 4) == 0 && "MEMOPw offset is not aligned correctly." );
1195    return (0 <= Offset && Offset <= 255);
1196
1197  case Hexagon::MEMh_ADDSUBi_indexed_MEM_V4 :
1198  case Hexagon::MEMh_ADDi_indexed_MEM_V4 :
1199  case Hexagon::MEMh_SUBi_indexed_MEM_V4 :
1200  case Hexagon::MEMh_ADDr_indexed_MEM_V4 :
1201  case Hexagon::MEMh_SUBr_indexed_MEM_V4 :
1202  case Hexagon::MEMh_ANDr_indexed_MEM_V4 :
1203  case Hexagon::MEMh_ORr_indexed_MEM_V4 :
1204  case Hexagon::MEMh_ADDSUBi_MEM_V4 :
1205  case Hexagon::MEMh_ADDi_MEM_V4 :
1206  case Hexagon::MEMh_SUBi_MEM_V4 :
1207  case Hexagon::MEMh_ADDr_MEM_V4 :
1208  case Hexagon::MEMh_SUBr_MEM_V4 :
1209  case Hexagon::MEMh_ANDr_MEM_V4 :
1210  case Hexagon::MEMh_ORr_MEM_V4 :
1211    assert ((Offset % 2) == 0 && "MEMOPh offset is not aligned correctly." );
1212    return (0 <= Offset && Offset <= 127);
1213
1214  case Hexagon::MEMb_ADDSUBi_indexed_MEM_V4 :
1215  case Hexagon::MEMb_ADDi_indexed_MEM_V4 :
1216  case Hexagon::MEMb_SUBi_indexed_MEM_V4 :
1217  case Hexagon::MEMb_ADDr_indexed_MEM_V4 :
1218  case Hexagon::MEMb_SUBr_indexed_MEM_V4 :
1219  case Hexagon::MEMb_ANDr_indexed_MEM_V4 :
1220  case Hexagon::MEMb_ORr_indexed_MEM_V4 :
1221  case Hexagon::MEMb_ADDSUBi_MEM_V4 :
1222  case Hexagon::MEMb_ADDi_MEM_V4 :
1223  case Hexagon::MEMb_SUBi_MEM_V4 :
1224  case Hexagon::MEMb_ADDr_MEM_V4 :
1225  case Hexagon::MEMb_SUBr_MEM_V4 :
1226  case Hexagon::MEMb_ANDr_MEM_V4 :
1227  case Hexagon::MEMb_ORr_MEM_V4 :
1228    return (0 <= Offset && Offset <= 63);
1229
1230  // LDri_pred and STriw_pred are pseudo operations, so it has to take offset of
1231  // any size. Later pass knows how to handle it.
1232  case Hexagon::STriw_pred:
1233  case Hexagon::LDriw_pred:
1234    return true;
1235
1236  // INLINEASM is very special.
1237  case Hexagon::INLINEASM:
1238    return true;
1239  }
1240
1241  llvm_unreachable("No offset range is defined for this opcode. "
1242                   "Please define it in the above switch statement!");
1243}
1244
1245
1246//
1247// Check if the Offset is a valid auto-inc imm by Load/Store Type.
1248//
1249bool HexagonInstrInfo::
1250isValidAutoIncImm(const EVT VT, const int Offset) const {
1251
1252  if (VT == MVT::i64) {
1253      return (Offset >= Hexagon_MEMD_AUTOINC_MIN &&
1254              Offset <= Hexagon_MEMD_AUTOINC_MAX &&
1255              (Offset & 0x7) == 0);
1256  }
1257  if (VT == MVT::i32) {
1258      return (Offset >= Hexagon_MEMW_AUTOINC_MIN &&
1259              Offset <= Hexagon_MEMW_AUTOINC_MAX &&
1260              (Offset & 0x3) == 0);
1261  }
1262  if (VT == MVT::i16) {
1263      return (Offset >= Hexagon_MEMH_AUTOINC_MIN &&
1264              Offset <= Hexagon_MEMH_AUTOINC_MAX &&
1265              (Offset & 0x1) == 0);
1266  }
1267  if (VT == MVT::i8) {
1268      return (Offset >= Hexagon_MEMB_AUTOINC_MIN &&
1269              Offset <= Hexagon_MEMB_AUTOINC_MAX);
1270  }
1271
1272  assert(0 && "Not an auto-inc opc!");
1273
1274  return false;
1275}
1276
1277
1278bool HexagonInstrInfo::
1279isMemOp(const MachineInstr *MI) const {
1280  switch (MI->getOpcode())
1281  {
1282    case Hexagon::MEMw_ADDSUBi_indexed_MEM_V4 :
1283    case Hexagon::MEMw_ADDi_indexed_MEM_V4 :
1284    case Hexagon::MEMw_SUBi_indexed_MEM_V4 :
1285    case Hexagon::MEMw_ADDr_indexed_MEM_V4 :
1286    case Hexagon::MEMw_SUBr_indexed_MEM_V4 :
1287    case Hexagon::MEMw_ANDr_indexed_MEM_V4 :
1288    case Hexagon::MEMw_ORr_indexed_MEM_V4 :
1289    case Hexagon::MEMw_ADDSUBi_MEM_V4 :
1290    case Hexagon::MEMw_ADDi_MEM_V4 :
1291    case Hexagon::MEMw_SUBi_MEM_V4 :
1292    case Hexagon::MEMw_ADDr_MEM_V4 :
1293    case Hexagon::MEMw_SUBr_MEM_V4 :
1294    case Hexagon::MEMw_ANDr_MEM_V4 :
1295    case Hexagon::MEMw_ORr_MEM_V4 :
1296    case Hexagon::MEMh_ADDSUBi_indexed_MEM_V4 :
1297    case Hexagon::MEMh_ADDi_indexed_MEM_V4 :
1298    case Hexagon::MEMh_SUBi_indexed_MEM_V4 :
1299    case Hexagon::MEMh_ADDr_indexed_MEM_V4 :
1300    case Hexagon::MEMh_SUBr_indexed_MEM_V4 :
1301    case Hexagon::MEMh_ANDr_indexed_MEM_V4 :
1302    case Hexagon::MEMh_ORr_indexed_MEM_V4 :
1303    case Hexagon::MEMh_ADDSUBi_MEM_V4 :
1304    case Hexagon::MEMh_ADDi_MEM_V4 :
1305    case Hexagon::MEMh_SUBi_MEM_V4 :
1306    case Hexagon::MEMh_ADDr_MEM_V4 :
1307    case Hexagon::MEMh_SUBr_MEM_V4 :
1308    case Hexagon::MEMh_ANDr_MEM_V4 :
1309    case Hexagon::MEMh_ORr_MEM_V4 :
1310    case Hexagon::MEMb_ADDSUBi_indexed_MEM_V4 :
1311    case Hexagon::MEMb_ADDi_indexed_MEM_V4 :
1312    case Hexagon::MEMb_SUBi_indexed_MEM_V4 :
1313    case Hexagon::MEMb_ADDr_indexed_MEM_V4 :
1314    case Hexagon::MEMb_SUBr_indexed_MEM_V4 :
1315    case Hexagon::MEMb_ANDr_indexed_MEM_V4 :
1316    case Hexagon::MEMb_ORr_indexed_MEM_V4 :
1317    case Hexagon::MEMb_ADDSUBi_MEM_V4 :
1318    case Hexagon::MEMb_ADDi_MEM_V4 :
1319    case Hexagon::MEMb_SUBi_MEM_V4 :
1320    case Hexagon::MEMb_ADDr_MEM_V4 :
1321    case Hexagon::MEMb_SUBr_MEM_V4 :
1322    case Hexagon::MEMb_ANDr_MEM_V4 :
1323    case Hexagon::MEMb_ORr_MEM_V4 :
1324    return true;
1325  }
1326  return false;
1327}
1328
1329
1330bool HexagonInstrInfo::
1331isSpillPredRegOp(const MachineInstr *MI) const {
1332  switch (MI->getOpcode())
1333  {
1334    case Hexagon::STriw_pred :
1335    case Hexagon::LDriw_pred :
1336    return true;
1337  }
1338  return false;
1339}
1340
1341
1342bool HexagonInstrInfo::isConditionalALU32 (const MachineInstr* MI) const {
1343  const HexagonRegisterInfo& QRI = getRegisterInfo();
1344  switch (MI->getOpcode())
1345  {
1346    case Hexagon::ADD_ri_cPt:
1347    case Hexagon::ADD_ri_cNotPt:
1348    case Hexagon::ADD_rr_cPt:
1349    case Hexagon::ADD_rr_cNotPt:
1350    case Hexagon::XOR_rr_cPt:
1351    case Hexagon::XOR_rr_cNotPt:
1352    case Hexagon::AND_rr_cPt:
1353    case Hexagon::AND_rr_cNotPt:
1354    case Hexagon::OR_rr_cPt:
1355    case Hexagon::OR_rr_cNotPt:
1356    case Hexagon::SUB_rr_cPt:
1357    case Hexagon::SUB_rr_cNotPt:
1358    case Hexagon::COMBINE_rr_cPt:
1359    case Hexagon::COMBINE_rr_cNotPt:
1360      return true;
1361    case Hexagon::ASLH_cPt_V4:
1362    case Hexagon::ASLH_cNotPt_V4:
1363    case Hexagon::ASRH_cPt_V4:
1364    case Hexagon::ASRH_cNotPt_V4:
1365    case Hexagon::SXTB_cPt_V4:
1366    case Hexagon::SXTB_cNotPt_V4:
1367    case Hexagon::SXTH_cPt_V4:
1368    case Hexagon::SXTH_cNotPt_V4:
1369    case Hexagon::ZXTB_cPt_V4:
1370    case Hexagon::ZXTB_cNotPt_V4:
1371    case Hexagon::ZXTH_cPt_V4:
1372    case Hexagon::ZXTH_cNotPt_V4:
1373      return QRI.Subtarget.getHexagonArchVersion() == HexagonSubtarget::V4;
1374
1375    default:
1376      return false;
1377  }
1378  return false;
1379}
1380
1381
1382bool HexagonInstrInfo::
1383isConditionalLoad (const MachineInstr* MI) const {
1384  const HexagonRegisterInfo& QRI = getRegisterInfo();
1385  switch (MI->getOpcode())
1386  {
1387    case Hexagon::LDrid_cPt :
1388    case Hexagon::LDrid_cNotPt :
1389    case Hexagon::LDrid_indexed_cPt :
1390    case Hexagon::LDrid_indexed_cNotPt :
1391    case Hexagon::LDriw_cPt :
1392    case Hexagon::LDriw_cNotPt :
1393    case Hexagon::LDriw_indexed_cPt :
1394    case Hexagon::LDriw_indexed_cNotPt :
1395    case Hexagon::LDrih_cPt :
1396    case Hexagon::LDrih_cNotPt :
1397    case Hexagon::LDrih_indexed_cPt :
1398    case Hexagon::LDrih_indexed_cNotPt :
1399    case Hexagon::LDrib_cPt :
1400    case Hexagon::LDrib_cNotPt :
1401    case Hexagon::LDrib_indexed_cPt :
1402    case Hexagon::LDrib_indexed_cNotPt :
1403    case Hexagon::LDriuh_cPt :
1404    case Hexagon::LDriuh_cNotPt :
1405    case Hexagon::LDriuh_indexed_cPt :
1406    case Hexagon::LDriuh_indexed_cNotPt :
1407    case Hexagon::LDriub_cPt :
1408    case Hexagon::LDriub_cNotPt :
1409    case Hexagon::LDriub_indexed_cPt :
1410    case Hexagon::LDriub_indexed_cNotPt :
1411      return true;
1412    case Hexagon::POST_LDrid_cPt :
1413    case Hexagon::POST_LDrid_cNotPt :
1414    case Hexagon::POST_LDriw_cPt :
1415    case Hexagon::POST_LDriw_cNotPt :
1416    case Hexagon::POST_LDrih_cPt :
1417    case Hexagon::POST_LDrih_cNotPt :
1418    case Hexagon::POST_LDrib_cPt :
1419    case Hexagon::POST_LDrib_cNotPt :
1420    case Hexagon::POST_LDriuh_cPt :
1421    case Hexagon::POST_LDriuh_cNotPt :
1422    case Hexagon::POST_LDriub_cPt :
1423    case Hexagon::POST_LDriub_cNotPt :
1424      return QRI.Subtarget.getHexagonArchVersion() == HexagonSubtarget::V4;
1425    case Hexagon::LDrid_indexed_cPt_V4 :
1426    case Hexagon::LDrid_indexed_cNotPt_V4 :
1427    case Hexagon::LDrid_indexed_shl_cPt_V4 :
1428    case Hexagon::LDrid_indexed_shl_cNotPt_V4 :
1429    case Hexagon::LDrib_indexed_cPt_V4 :
1430    case Hexagon::LDrib_indexed_cNotPt_V4 :
1431    case Hexagon::LDrib_indexed_shl_cPt_V4 :
1432    case Hexagon::LDrib_indexed_shl_cNotPt_V4 :
1433    case Hexagon::LDriub_indexed_cPt_V4 :
1434    case Hexagon::LDriub_indexed_cNotPt_V4 :
1435    case Hexagon::LDriub_indexed_shl_cPt_V4 :
1436    case Hexagon::LDriub_indexed_shl_cNotPt_V4 :
1437    case Hexagon::LDrih_indexed_cPt_V4 :
1438    case Hexagon::LDrih_indexed_cNotPt_V4 :
1439    case Hexagon::LDrih_indexed_shl_cPt_V4 :
1440    case Hexagon::LDrih_indexed_shl_cNotPt_V4 :
1441    case Hexagon::LDriuh_indexed_cPt_V4 :
1442    case Hexagon::LDriuh_indexed_cNotPt_V4 :
1443    case Hexagon::LDriuh_indexed_shl_cPt_V4 :
1444    case Hexagon::LDriuh_indexed_shl_cNotPt_V4 :
1445    case Hexagon::LDriw_indexed_cPt_V4 :
1446    case Hexagon::LDriw_indexed_cNotPt_V4 :
1447    case Hexagon::LDriw_indexed_shl_cPt_V4 :
1448    case Hexagon::LDriw_indexed_shl_cNotPt_V4 :
1449      return QRI.Subtarget.getHexagonArchVersion() == HexagonSubtarget::V4;
1450    default:
1451      return false;
1452  }
1453  return false;
1454}
1455