Home | History | Annotate | Download | only in MCTargetDesc
      1 //===----- HexagonMCDuplexInfo.cpp - Instruction bundle checking ----------===//
      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 implements duplexing of instructions to reduce code size
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "HexagonBaseInfo.h"
     15 #include "MCTargetDesc/HexagonMCInstrInfo.h"
     16 
     17 #include "llvm/ADT/SmallVector.h"
     18 #include "llvm/Support/Debug.h"
     19 #include "llvm/Support/raw_ostream.h"
     20 
     21 #include <map>
     22 
     23 using namespace llvm;
     24 using namespace Hexagon;
     25 
     26 #define DEBUG_TYPE "hexagon-mcduplex-info"
     27 
     28 // pair table of subInstructions with opcodes
     29 static const std::pair<unsigned, unsigned> opcodeData[] = {
     30     std::make_pair((unsigned)V4_SA1_addi, 0),
     31     std::make_pair((unsigned)V4_SA1_addrx, 6144),
     32     std::make_pair((unsigned)V4_SA1_addsp, 3072),
     33     std::make_pair((unsigned)V4_SA1_and1, 4608),
     34     std::make_pair((unsigned)V4_SA1_clrf, 6768),
     35     std::make_pair((unsigned)V4_SA1_clrfnew, 6736),
     36     std::make_pair((unsigned)V4_SA1_clrt, 6752),
     37     std::make_pair((unsigned)V4_SA1_clrtnew, 6720),
     38     std::make_pair((unsigned)V4_SA1_cmpeqi, 6400),
     39     std::make_pair((unsigned)V4_SA1_combine0i, 7168),
     40     std::make_pair((unsigned)V4_SA1_combine1i, 7176),
     41     std::make_pair((unsigned)V4_SA1_combine2i, 7184),
     42     std::make_pair((unsigned)V4_SA1_combine3i, 7192),
     43     std::make_pair((unsigned)V4_SA1_combinerz, 7432),
     44     std::make_pair((unsigned)V4_SA1_combinezr, 7424),
     45     std::make_pair((unsigned)V4_SA1_dec, 4864),
     46     std::make_pair((unsigned)V4_SA1_inc, 4352),
     47     std::make_pair((unsigned)V4_SA1_seti, 2048),
     48     std::make_pair((unsigned)V4_SA1_setin1, 6656),
     49     std::make_pair((unsigned)V4_SA1_sxtb, 5376),
     50     std::make_pair((unsigned)V4_SA1_sxth, 5120),
     51     std::make_pair((unsigned)V4_SA1_tfr, 4096),
     52     std::make_pair((unsigned)V4_SA1_zxtb, 5888),
     53     std::make_pair((unsigned)V4_SA1_zxth, 5632),
     54     std::make_pair((unsigned)V4_SL1_loadri_io, 0),
     55     std::make_pair((unsigned)V4_SL1_loadrub_io, 4096),
     56     std::make_pair((unsigned)V4_SL2_deallocframe, 7936),
     57     std::make_pair((unsigned)V4_SL2_jumpr31, 8128),
     58     std::make_pair((unsigned)V4_SL2_jumpr31_f, 8133),
     59     std::make_pair((unsigned)V4_SL2_jumpr31_fnew, 8135),
     60     std::make_pair((unsigned)V4_SL2_jumpr31_t, 8132),
     61     std::make_pair((unsigned)V4_SL2_jumpr31_tnew, 8134),
     62     std::make_pair((unsigned)V4_SL2_loadrb_io, 4096),
     63     std::make_pair((unsigned)V4_SL2_loadrd_sp, 7680),
     64     std::make_pair((unsigned)V4_SL2_loadrh_io, 0),
     65     std::make_pair((unsigned)V4_SL2_loadri_sp, 7168),
     66     std::make_pair((unsigned)V4_SL2_loadruh_io, 2048),
     67     std::make_pair((unsigned)V4_SL2_return, 8000),
     68     std::make_pair((unsigned)V4_SL2_return_f, 8005),
     69     std::make_pair((unsigned)V4_SL2_return_fnew, 8007),
     70     std::make_pair((unsigned)V4_SL2_return_t, 8004),
     71     std::make_pair((unsigned)V4_SL2_return_tnew, 8006),
     72     std::make_pair((unsigned)V4_SS1_storeb_io, 4096),
     73     std::make_pair((unsigned)V4_SS1_storew_io, 0),
     74     std::make_pair((unsigned)V4_SS2_allocframe, 7168),
     75     std::make_pair((unsigned)V4_SS2_storebi0, 4608),
     76     std::make_pair((unsigned)V4_SS2_storebi1, 4864),
     77     std::make_pair((unsigned)V4_SS2_stored_sp, 2560),
     78     std::make_pair((unsigned)V4_SS2_storeh_io, 0),
     79     std::make_pair((unsigned)V4_SS2_storew_sp, 2048),
     80     std::make_pair((unsigned)V4_SS2_storewi0, 4096),
     81     std::make_pair((unsigned)V4_SS2_storewi1, 4352)};
     82 
     83 bool HexagonMCInstrInfo::isDuplexPairMatch(unsigned Ga, unsigned Gb) {
     84   switch (Ga) {
     85   case HexagonII::HSIG_None:
     86   default:
     87     return false;
     88   case HexagonII::HSIG_L1:
     89     return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_A);
     90   case HexagonII::HSIG_L2:
     91     return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
     92             Gb == HexagonII::HSIG_A);
     93   case HexagonII::HSIG_S1:
     94     return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
     95             Gb == HexagonII::HSIG_S1 || Gb == HexagonII::HSIG_A);
     96   case HexagonII::HSIG_S2:
     97     return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
     98             Gb == HexagonII::HSIG_S1 || Gb == HexagonII::HSIG_S2 ||
     99             Gb == HexagonII::HSIG_A);
    100   case HexagonII::HSIG_A:
    101     return (Gb == HexagonII::HSIG_A);
    102   case HexagonII::HSIG_Compound:
    103     return (Gb == HexagonII::HSIG_Compound);
    104   }
    105   return false;
    106 }
    107 
    108 unsigned HexagonMCInstrInfo::iClassOfDuplexPair(unsigned Ga, unsigned Gb) {
    109   switch (Ga) {
    110   case HexagonII::HSIG_None:
    111   default:
    112     break;
    113   case HexagonII::HSIG_L1:
    114     switch (Gb) {
    115     default:
    116       break;
    117     case HexagonII::HSIG_L1:
    118       return 0;
    119     case HexagonII::HSIG_A:
    120       return 0x4;
    121     }
    122   case HexagonII::HSIG_L2:
    123     switch (Gb) {
    124     default:
    125       break;
    126     case HexagonII::HSIG_L1:
    127       return 0x1;
    128     case HexagonII::HSIG_L2:
    129       return 0x2;
    130     case HexagonII::HSIG_A:
    131       return 0x5;
    132     }
    133   case HexagonII::HSIG_S1:
    134     switch (Gb) {
    135     default:
    136       break;
    137     case HexagonII::HSIG_L1:
    138       return 0x8;
    139     case HexagonII::HSIG_L2:
    140       return 0x9;
    141     case HexagonII::HSIG_S1:
    142       return 0xA;
    143     case HexagonII::HSIG_A:
    144       return 0x6;
    145     }
    146   case HexagonII::HSIG_S2:
    147     switch (Gb) {
    148     default:
    149       break;
    150     case HexagonII::HSIG_L1:
    151       return 0xC;
    152     case HexagonII::HSIG_L2:
    153       return 0xD;
    154     case HexagonII::HSIG_S1:
    155       return 0xB;
    156     case HexagonII::HSIG_S2:
    157       return 0xE;
    158     case HexagonII::HSIG_A:
    159       return 0x7;
    160     }
    161   case HexagonII::HSIG_A:
    162     switch (Gb) {
    163     default:
    164       break;
    165     case HexagonII::HSIG_A:
    166       return 0x3;
    167     }
    168   case HexagonII::HSIG_Compound:
    169     switch (Gb) {
    170     case HexagonII::HSIG_Compound:
    171       return 0xFFFFFFFF;
    172     }
    173   }
    174   return 0xFFFFFFFF;
    175 }
    176 
    177 unsigned HexagonMCInstrInfo::getDuplexCandidateGroup(MCInst const &MCI) {
    178   unsigned DstReg, PredReg, SrcReg, Src1Reg, Src2Reg;
    179 
    180   switch (MCI.getOpcode()) {
    181   default:
    182     return HexagonII::HSIG_None;
    183   //
    184   // Group L1:
    185   //
    186   // Rd = memw(Rs+#u4:2)
    187   // Rd = memub(Rs+#u4:0)
    188   case Hexagon::L2_loadri_io:
    189     DstReg = MCI.getOperand(0).getReg();
    190     SrcReg = MCI.getOperand(1).getReg();
    191     // Special case this one from Group L2.
    192     // Rd = memw(r29+#u5:2)
    193     if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
    194       if (HexagonMCInstrInfo::isIntReg(SrcReg) &&
    195           Hexagon::R29 == SrcReg && inRange<5, 2>(MCI, 2)) {
    196         return HexagonII::HSIG_L2;
    197       }
    198       // Rd = memw(Rs+#u4:2)
    199       if (HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
    200           inRange<4, 2>(MCI, 2)) {
    201         return HexagonII::HSIG_L1;
    202       }
    203     }
    204     break;
    205   case Hexagon::L2_loadrub_io:
    206     // Rd = memub(Rs+#u4:0)
    207     DstReg = MCI.getOperand(0).getReg();
    208     SrcReg = MCI.getOperand(1).getReg();
    209     if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
    210         HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
    211         inRange<4>(MCI, 2)) {
    212       return HexagonII::HSIG_L1;
    213     }
    214     break;
    215   //
    216   // Group L2:
    217   //
    218   // Rd = memh/memuh(Rs+#u3:1)
    219   // Rd = memb(Rs+#u3:0)
    220   // Rd = memw(r29+#u5:2) - Handled above.
    221   // Rdd = memd(r29+#u5:3)
    222   // deallocframe
    223   // [if ([!]p0[.new])] dealloc_return
    224   // [if ([!]p0[.new])] jumpr r31
    225   case Hexagon::L2_loadrh_io:
    226   case Hexagon::L2_loadruh_io:
    227     // Rd = memh/memuh(Rs+#u3:1)
    228     DstReg = MCI.getOperand(0).getReg();
    229     SrcReg = MCI.getOperand(1).getReg();
    230     if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
    231         HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
    232         inRange<3, 1>(MCI, 2)) {
    233       return HexagonII::HSIG_L2;
    234     }
    235     break;
    236   case Hexagon::L2_loadrb_io:
    237     // Rd = memb(Rs+#u3:0)
    238     DstReg = MCI.getOperand(0).getReg();
    239     SrcReg = MCI.getOperand(1).getReg();
    240     if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
    241         HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
    242         inRange<3>(MCI, 2)) {
    243       return HexagonII::HSIG_L2;
    244     }
    245     break;
    246   case Hexagon::L2_loadrd_io:
    247     // Rdd = memd(r29+#u5:3)
    248     DstReg = MCI.getOperand(0).getReg();
    249     SrcReg = MCI.getOperand(1).getReg();
    250     if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
    251         HexagonMCInstrInfo::isIntReg(SrcReg) && Hexagon::R29 == SrcReg &&
    252         inRange<5, 3>(MCI, 2)) {
    253       return HexagonII::HSIG_L2;
    254     }
    255     break;
    256 
    257   case Hexagon::L4_return:
    258 
    259   case Hexagon::L2_deallocframe:
    260 
    261     return HexagonII::HSIG_L2;
    262   case Hexagon::EH_RETURN_JMPR:
    263 
    264   case Hexagon::J2_jumpr:
    265   case Hexagon::JMPret:
    266     // jumpr r31
    267     // Actual form JMPR %PC<imp-def>, %R31<imp-use>, %R0<imp-use,internal>.
    268     DstReg = MCI.getOperand(0).getReg();
    269     if (Hexagon::R31 == DstReg) {
    270       return HexagonII::HSIG_L2;
    271     }
    272     break;
    273 
    274   case Hexagon::J2_jumprt:
    275   case Hexagon::J2_jumprf:
    276   case Hexagon::J2_jumprtnew:
    277   case Hexagon::J2_jumprfnew:
    278   case Hexagon::JMPrett:
    279   case Hexagon::JMPretf:
    280   case Hexagon::JMPrettnew:
    281   case Hexagon::JMPretfnew:
    282   case Hexagon::JMPrettnewpt:
    283   case Hexagon::JMPretfnewpt:
    284     DstReg = MCI.getOperand(1).getReg();
    285     SrcReg = MCI.getOperand(0).getReg();
    286     // [if ([!]p0[.new])] jumpr r31
    287     if ((HexagonMCInstrInfo::isPredReg(SrcReg) && (Hexagon::P0 == SrcReg)) &&
    288         (Hexagon::R31 == DstReg)) {
    289       return HexagonII::HSIG_L2;
    290     }
    291     break;
    292   case Hexagon::L4_return_t:
    293 
    294   case Hexagon::L4_return_f:
    295 
    296   case Hexagon::L4_return_tnew_pnt:
    297 
    298   case Hexagon::L4_return_fnew_pnt:
    299 
    300   case Hexagon::L4_return_tnew_pt:
    301 
    302   case Hexagon::L4_return_fnew_pt:
    303     // [if ([!]p0[.new])] dealloc_return
    304     SrcReg = MCI.getOperand(0).getReg();
    305     if (Hexagon::P0 == SrcReg) {
    306       return HexagonII::HSIG_L2;
    307     }
    308     break;
    309   //
    310   // Group S1:
    311   //
    312   // memw(Rs+#u4:2) = Rt
    313   // memb(Rs+#u4:0) = Rt
    314   case Hexagon::S2_storeri_io:
    315     // Special case this one from Group S2.
    316     // memw(r29+#u5:2) = Rt
    317     Src1Reg = MCI.getOperand(0).getReg();
    318     Src2Reg = MCI.getOperand(2).getReg();
    319     if (HexagonMCInstrInfo::isIntReg(Src1Reg) &&
    320         HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
    321         Hexagon::R29 == Src1Reg && inRange<5, 2>(MCI, 1)) {
    322       return HexagonII::HSIG_S2;
    323     }
    324     // memw(Rs+#u4:2) = Rt
    325     if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
    326         HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
    327         inRange<4, 2>(MCI, 1)) {
    328       return HexagonII::HSIG_S1;
    329     }
    330     break;
    331   case Hexagon::S2_storerb_io:
    332     // memb(Rs+#u4:0) = Rt
    333     Src1Reg = MCI.getOperand(0).getReg();
    334     Src2Reg = MCI.getOperand(2).getReg();
    335     if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
    336         HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
    337         inRange<4>(MCI, 1)) {
    338       return HexagonII::HSIG_S1;
    339     }
    340     break;
    341   //
    342   // Group S2:
    343   //
    344   // memh(Rs+#u3:1) = Rt
    345   // memw(r29+#u5:2) = Rt
    346   // memd(r29+#s6:3) = Rtt
    347   // memw(Rs+#u4:2) = #U1
    348   // memb(Rs+#u4) = #U1
    349   // allocframe(#u5:3)
    350   case Hexagon::S2_storerh_io:
    351     // memh(Rs+#u3:1) = Rt
    352     Src1Reg = MCI.getOperand(0).getReg();
    353     Src2Reg = MCI.getOperand(2).getReg();
    354     if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
    355         HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
    356         inRange<3, 1>(MCI, 1)) {
    357       return HexagonII::HSIG_S2;
    358     }
    359     break;
    360   case Hexagon::S2_storerd_io:
    361     // memd(r29+#s6:3) = Rtt
    362     Src1Reg = MCI.getOperand(0).getReg();
    363     Src2Reg = MCI.getOperand(2).getReg();
    364     if (HexagonMCInstrInfo::isDblRegForSubInst(Src2Reg) &&
    365         HexagonMCInstrInfo::isIntReg(Src1Reg) && Hexagon::R29 == Src1Reg &&
    366         inSRange<6, 3>(MCI, 1)) {
    367       return HexagonII::HSIG_S2;
    368     }
    369     break;
    370   case Hexagon::S4_storeiri_io:
    371     // memw(Rs+#u4:2) = #U1
    372     Src1Reg = MCI.getOperand(0).getReg();
    373     if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
    374         inRange<4, 2>(MCI, 1) && inRange<1>(MCI, 2)) {
    375       return HexagonII::HSIG_S2;
    376     }
    377     break;
    378   case Hexagon::S4_storeirb_io:
    379     // memb(Rs+#u4) = #U1
    380     Src1Reg = MCI.getOperand(0).getReg();
    381     if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
    382         inRange<4>(MCI, 1) && inRange<1>(MCI, 2)) {
    383       return HexagonII::HSIG_S2;
    384     }
    385     break;
    386   case Hexagon::S2_allocframe:
    387     if (inRange<5, 3>(MCI, 0))
    388       return HexagonII::HSIG_S2;
    389     break;
    390   //
    391   // Group A:
    392   //
    393   // Rx = add(Rx,#s7)
    394   // Rd = Rs
    395   // Rd = #u6
    396   // Rd = #-1
    397   // if ([!]P0[.new]) Rd = #0
    398   // Rd = add(r29,#u6:2)
    399   // Rx = add(Rx,Rs)
    400   // P0 = cmp.eq(Rs,#u2)
    401   // Rdd = combine(#0,Rs)
    402   // Rdd = combine(Rs,#0)
    403   // Rdd = combine(#u2,#U2)
    404   // Rd = add(Rs,#1)
    405   // Rd = add(Rs,#-1)
    406   // Rd = sxth/sxtb/zxtb/zxth(Rs)
    407   // Rd = and(Rs,#1)
    408   case Hexagon::A2_addi:
    409     DstReg = MCI.getOperand(0).getReg();
    410     SrcReg = MCI.getOperand(1).getReg();
    411     if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
    412       // Rd = add(r29,#u6:2)
    413       if (HexagonMCInstrInfo::isIntReg(SrcReg) && Hexagon::R29 == SrcReg &&
    414           inRange<6, 2>(MCI, 2)) {
    415         return HexagonII::HSIG_A;
    416       }
    417       // Rx = add(Rx,#s7)
    418       if (DstReg == SrcReg) {
    419         return HexagonII::HSIG_A;
    420       }
    421       // Rd = add(Rs,#1)
    422       // Rd = add(Rs,#-1)
    423       if (HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
    424           (minConstant(MCI, 2) == 1 || minConstant(MCI, 2) == -1)) {
    425         return HexagonII::HSIG_A;
    426       }
    427     }
    428     break;
    429   case Hexagon::A2_add:
    430     // Rx = add(Rx,Rs)
    431     DstReg = MCI.getOperand(0).getReg();
    432     Src1Reg = MCI.getOperand(1).getReg();
    433     Src2Reg = MCI.getOperand(2).getReg();
    434     if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) && (DstReg == Src1Reg) &&
    435         HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg)) {
    436       return HexagonII::HSIG_A;
    437     }
    438     break;
    439   case Hexagon::A2_andir:
    440     DstReg = MCI.getOperand(0).getReg();
    441     SrcReg = MCI.getOperand(1).getReg();
    442     if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
    443         HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
    444         (minConstant(MCI, 2) == 1 || minConstant(MCI, 2) == 255)) {
    445       return HexagonII::HSIG_A;
    446     }
    447     break;
    448   case Hexagon::A2_tfr:
    449     // Rd = Rs
    450     DstReg = MCI.getOperand(0).getReg();
    451     SrcReg = MCI.getOperand(1).getReg();
    452     if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
    453         HexagonMCInstrInfo::isIntRegForSubInst(SrcReg)) {
    454       return HexagonII::HSIG_A;
    455     }
    456     break;
    457   case Hexagon::A2_tfrsi:
    458     DstReg = MCI.getOperand(0).getReg();
    459 
    460     if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
    461       return HexagonII::HSIG_A;
    462     }
    463     break;
    464   case Hexagon::C2_cmoveit:
    465   case Hexagon::C2_cmovenewit:
    466   case Hexagon::C2_cmoveif:
    467   case Hexagon::C2_cmovenewif:
    468     // if ([!]P0[.new]) Rd = #0
    469     // Actual form:
    470     // %R16<def> = C2_cmovenewit %P0<internal>, 0, %R16<imp-use,undef>;
    471     DstReg = MCI.getOperand(0).getReg();  // Rd
    472     PredReg = MCI.getOperand(1).getReg(); // P0
    473     if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
    474         Hexagon::P0 == PredReg && minConstant(MCI, 2) == 0) {
    475       return HexagonII::HSIG_A;
    476     }
    477     break;
    478   case Hexagon::C2_cmpeqi:
    479     // P0 = cmp.eq(Rs,#u2)
    480     DstReg = MCI.getOperand(0).getReg();
    481     SrcReg = MCI.getOperand(1).getReg();
    482     if (Hexagon::P0 == DstReg &&
    483         HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
    484         inRange<2>(MCI, 2)) {
    485       return HexagonII::HSIG_A;
    486     }
    487     break;
    488   case Hexagon::A2_combineii:
    489   case Hexagon::A4_combineii:
    490     // Rdd = combine(#u2,#U2)
    491     DstReg = MCI.getOperand(0).getReg();
    492     if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
    493         inRange<2>(MCI, 1) && inRange<2>(MCI, 2)) {
    494       return HexagonII::HSIG_A;
    495     }
    496     break;
    497   case Hexagon::A4_combineri:
    498     // Rdd = combine(Rs,#0)
    499     DstReg = MCI.getOperand(0).getReg();
    500     SrcReg = MCI.getOperand(1).getReg();
    501     if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
    502         HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
    503         minConstant(MCI, 2) == 0) {
    504       return HexagonII::HSIG_A;
    505     }
    506     break;
    507   case Hexagon::A4_combineir:
    508     // Rdd = combine(#0,Rs)
    509     DstReg = MCI.getOperand(0).getReg();
    510     SrcReg = MCI.getOperand(2).getReg();
    511     if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
    512         HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
    513         minConstant(MCI, 1) == 0) {
    514       return HexagonII::HSIG_A;
    515     }
    516     break;
    517   case Hexagon::A2_sxtb:
    518   case Hexagon::A2_sxth:
    519   case Hexagon::A2_zxtb:
    520   case Hexagon::A2_zxth:
    521     // Rd = sxth/sxtb/zxtb/zxth(Rs)
    522     DstReg = MCI.getOperand(0).getReg();
    523     SrcReg = MCI.getOperand(1).getReg();
    524     if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
    525         HexagonMCInstrInfo::isIntRegForSubInst(SrcReg)) {
    526       return HexagonII::HSIG_A;
    527     }
    528     break;
    529   }
    530 
    531   return HexagonII::HSIG_None;
    532 }
    533 
    534 bool HexagonMCInstrInfo::subInstWouldBeExtended(MCInst const &potentialDuplex) {
    535   unsigned DstReg, SrcReg;
    536   switch (potentialDuplex.getOpcode()) {
    537   case Hexagon::A2_addi:
    538     // testing for case of: Rx = add(Rx,#s7)
    539     DstReg = potentialDuplex.getOperand(0).getReg();
    540     SrcReg = potentialDuplex.getOperand(1).getReg();
    541     if (DstReg == SrcReg && HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
    542       int64_t Value;
    543       if (!potentialDuplex.getOperand(2).getExpr()->evaluateAsAbsolute(Value))
    544         return true;
    545       if (!isShiftedInt<7, 0>(Value))
    546         return true;
    547     }
    548     break;
    549   case Hexagon::A2_tfrsi:
    550     DstReg = potentialDuplex.getOperand(0).getReg();
    551 
    552     if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
    553       int64_t Value;
    554       if (!potentialDuplex.getOperand(1).getExpr()->evaluateAsAbsolute(Value))
    555         return true;
    556       // Check for case of Rd = #-1.
    557       if (Value == -1)
    558         return false;
    559       // Check for case of Rd = #u6.
    560       if (!isShiftedUInt<6, 0>(Value))
    561         return true;
    562     }
    563     break;
    564   default:
    565     break;
    566   }
    567   return false;
    568 }
    569 
    570 /// non-Symmetrical. See if these two instructions are fit for duplex pair.
    571 bool HexagonMCInstrInfo::isOrderedDuplexPair(MCInstrInfo const &MCII,
    572                                              MCInst const &MIa, bool ExtendedA,
    573                                              MCInst const &MIb, bool ExtendedB,
    574                                              bool bisReversable) {
    575   // Slot 1 cannot be extended in duplexes PRM 10.5
    576   if (ExtendedA)
    577     return false;
    578   // Only A2_addi and A2_tfrsi can be extended in duplex form PRM 10.5
    579   if (ExtendedB) {
    580     unsigned Opcode = MIb.getOpcode();
    581     if ((Opcode != Hexagon::A2_addi) && (Opcode != Hexagon::A2_tfrsi))
    582       return false;
    583   }
    584   unsigned MIaG = HexagonMCInstrInfo::getDuplexCandidateGroup(MIa),
    585            MIbG = HexagonMCInstrInfo::getDuplexCandidateGroup(MIb);
    586 
    587   static std::map<unsigned, unsigned> subinstOpcodeMap(std::begin(opcodeData),
    588                                                        std::end(opcodeData));
    589 
    590   // If a duplex contains 2 insns in the same group, the insns must be
    591   // ordered such that the numerically smaller opcode is in slot 1.
    592   if ((MIaG != HexagonII::HSIG_None) && (MIaG == MIbG) && bisReversable) {
    593     MCInst SubInst0 = HexagonMCInstrInfo::deriveSubInst(MIa);
    594     MCInst SubInst1 = HexagonMCInstrInfo::deriveSubInst(MIb);
    595 
    596     unsigned zeroedSubInstS0 =
    597         subinstOpcodeMap.find(SubInst0.getOpcode())->second;
    598     unsigned zeroedSubInstS1 =
    599         subinstOpcodeMap.find(SubInst1.getOpcode())->second;
    600 
    601     if (zeroedSubInstS0 < zeroedSubInstS1)
    602       // subinstS0 (maps to slot 0) must be greater than
    603       // subinstS1 (maps to slot 1)
    604       return false;
    605   }
    606 
    607   // allocframe must always be in slot 0
    608   if (MIb.getOpcode() == Hexagon::S2_allocframe)
    609     return false;
    610 
    611   if ((MIaG != HexagonII::HSIG_None) && (MIbG != HexagonII::HSIG_None)) {
    612     // Prevent 2 instructions with extenders from duplexing
    613     // Note that MIb (slot1) can be extended and MIa (slot0)
    614     //   can never be extended
    615     if (subInstWouldBeExtended(MIa))
    616       return false;
    617 
    618     // If duplexing produces an extender, but the original did not
    619     //   have an extender, do not duplex.
    620     if (subInstWouldBeExtended(MIb) && !ExtendedB)
    621       return false;
    622   }
    623 
    624   // If jumpr r31 appears, it must be in slot 0, and never slot 1 (MIb).
    625   if (MIbG == HexagonII::HSIG_L2) {
    626     if ((MIb.getNumOperands() > 1) && MIb.getOperand(1).isReg() &&
    627         (MIb.getOperand(1).getReg() == Hexagon::R31))
    628       return false;
    629     if ((MIb.getNumOperands() > 0) && MIb.getOperand(0).isReg() &&
    630         (MIb.getOperand(0).getReg() == Hexagon::R31))
    631       return false;
    632   }
    633 
    634   // If a store appears, it must be in slot 0 (MIa) 1st, and then slot 1 (MIb);
    635   //   therefore, not duplexable if slot 1 is a store, and slot 0 is not.
    636   if ((MIbG == HexagonII::HSIG_S1) || (MIbG == HexagonII::HSIG_S2)) {
    637     if ((MIaG != HexagonII::HSIG_S1) && (MIaG != HexagonII::HSIG_S2))
    638       return false;
    639   }
    640 
    641   return (isDuplexPairMatch(MIaG, MIbG));
    642 }
    643 
    644 /// Symmetrical. See if these two instructions are fit for duplex pair.
    645 bool HexagonMCInstrInfo::isDuplexPair(MCInst const &MIa, MCInst const &MIb) {
    646   unsigned MIaG = getDuplexCandidateGroup(MIa),
    647            MIbG = getDuplexCandidateGroup(MIb);
    648   return (isDuplexPairMatch(MIaG, MIbG) || isDuplexPairMatch(MIbG, MIaG));
    649 }
    650 
    651 inline static void addOps(MCInst &subInstPtr, MCInst const &Inst,
    652                           unsigned opNum) {
    653   if (Inst.getOperand(opNum).isReg()) {
    654     switch (Inst.getOperand(opNum).getReg()) {
    655     default:
    656       llvm_unreachable("Not Duplexable Register");
    657       break;
    658     case Hexagon::R0:
    659     case Hexagon::R1:
    660     case Hexagon::R2:
    661     case Hexagon::R3:
    662     case Hexagon::R4:
    663     case Hexagon::R5:
    664     case Hexagon::R6:
    665     case Hexagon::R7:
    666     case Hexagon::D0:
    667     case Hexagon::D1:
    668     case Hexagon::D2:
    669     case Hexagon::D3:
    670     case Hexagon::R16:
    671     case Hexagon::R17:
    672     case Hexagon::R18:
    673     case Hexagon::R19:
    674     case Hexagon::R20:
    675     case Hexagon::R21:
    676     case Hexagon::R22:
    677     case Hexagon::R23:
    678     case Hexagon::D8:
    679     case Hexagon::D9:
    680     case Hexagon::D10:
    681     case Hexagon::D11:
    682       subInstPtr.addOperand(Inst.getOperand(opNum));
    683       break;
    684     }
    685   } else
    686     subInstPtr.addOperand(Inst.getOperand(opNum));
    687 }
    688 
    689 MCInst HexagonMCInstrInfo::deriveSubInst(MCInst const &Inst) {
    690   MCInst Result;
    691   bool Absolute;
    692   int64_t Value;
    693   switch (Inst.getOpcode()) {
    694   default:
    695     // dbgs() << "opcode: "<< Inst->getOpcode() << "\n";
    696     llvm_unreachable("Unimplemented subinstruction \n");
    697     break;
    698   case Hexagon::A2_addi:
    699     Absolute = Inst.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
    700     assert(Absolute);(void)Absolute;
    701     if (Value == 1) {
    702       Result.setOpcode(Hexagon::V4_SA1_inc);
    703       addOps(Result, Inst, 0);
    704       addOps(Result, Inst, 1);
    705       break;
    706     } //  1,2 SUBInst $Rd = add($Rs, #1)
    707     else if (Value == -1) {
    708       Result.setOpcode(Hexagon::V4_SA1_dec);
    709       addOps(Result, Inst, 0);
    710       addOps(Result, Inst, 1);
    711       break;
    712     } //  1,2 SUBInst $Rd = add($Rs,#-1)
    713     else if (Inst.getOperand(1).getReg() == Hexagon::R29) {
    714       Result.setOpcode(Hexagon::V4_SA1_addsp);
    715       addOps(Result, Inst, 0);
    716       addOps(Result, Inst, 2);
    717       break;
    718     } //  1,3 SUBInst $Rd = add(r29, #$u6_2)
    719     else {
    720       Result.setOpcode(Hexagon::V4_SA1_addi);
    721       addOps(Result, Inst, 0);
    722       addOps(Result, Inst, 1);
    723       addOps(Result, Inst, 2);
    724       break;
    725     } //    1,2,3 SUBInst $Rx = add($Rx, #$s7)
    726   case Hexagon::A2_add:
    727     Result.setOpcode(Hexagon::V4_SA1_addrx);
    728     addOps(Result, Inst, 0);
    729     addOps(Result, Inst, 1);
    730     addOps(Result, Inst, 2);
    731     break; //    1,2,3 SUBInst $Rx = add($_src_, $Rs)
    732   case Hexagon::S2_allocframe:
    733     Result.setOpcode(Hexagon::V4_SS2_allocframe);
    734     addOps(Result, Inst, 0);
    735     break; //    1 SUBInst allocframe(#$u5_3)
    736   case Hexagon::A2_andir:
    737     if (minConstant(Inst, 2) == 255) {
    738       Result.setOpcode(Hexagon::V4_SA1_zxtb);
    739       addOps(Result, Inst, 0);
    740       addOps(Result, Inst, 1);
    741       break; //    1,2    $Rd = and($Rs, #255)
    742     } else {
    743       Result.setOpcode(Hexagon::V4_SA1_and1);
    744       addOps(Result, Inst, 0);
    745       addOps(Result, Inst, 1);
    746       break; //    1,2 SUBInst $Rd = and($Rs, #1)
    747     }
    748   case Hexagon::C2_cmpeqi:
    749     Result.setOpcode(Hexagon::V4_SA1_cmpeqi);
    750     addOps(Result, Inst, 1);
    751     addOps(Result, Inst, 2);
    752     break; //    2,3 SUBInst p0 = cmp.eq($Rs, #$u2)
    753   case Hexagon::A4_combineii:
    754   case Hexagon::A2_combineii:
    755     Absolute = Inst.getOperand(1).getExpr()->evaluateAsAbsolute(Value);
    756     assert(Absolute);(void)Absolute;
    757     if (Value == 1) {
    758       Result.setOpcode(Hexagon::V4_SA1_combine1i);
    759       addOps(Result, Inst, 0);
    760       addOps(Result, Inst, 2);
    761       break; //  1,3 SUBInst $Rdd = combine(#1, #$u2)
    762     }
    763     if (Value == 3) {
    764       Result.setOpcode(Hexagon::V4_SA1_combine3i);
    765       addOps(Result, Inst, 0);
    766       addOps(Result, Inst, 2);
    767       break; //  1,3 SUBInst $Rdd = combine(#3, #$u2)
    768     }
    769     if (Value == 0) {
    770       Result.setOpcode(Hexagon::V4_SA1_combine0i);
    771       addOps(Result, Inst, 0);
    772       addOps(Result, Inst, 2);
    773       break; //  1,3 SUBInst $Rdd = combine(#0, #$u2)
    774     }
    775     if (Value == 2) {
    776       Result.setOpcode(Hexagon::V4_SA1_combine2i);
    777       addOps(Result, Inst, 0);
    778       addOps(Result, Inst, 2);
    779       break; //  1,3 SUBInst $Rdd = combine(#2, #$u2)
    780     }
    781   case Hexagon::A4_combineir:
    782     Result.setOpcode(Hexagon::V4_SA1_combinezr);
    783     addOps(Result, Inst, 0);
    784     addOps(Result, Inst, 2);
    785     break; //    1,3 SUBInst $Rdd = combine(#0, $Rs)
    786 
    787   case Hexagon::A4_combineri:
    788     Result.setOpcode(Hexagon::V4_SA1_combinerz);
    789     addOps(Result, Inst, 0);
    790     addOps(Result, Inst, 1);
    791     break; //    1,2 SUBInst $Rdd = combine($Rs, #0)
    792   case Hexagon::L4_return_tnew_pnt:
    793   case Hexagon::L4_return_tnew_pt:
    794     Result.setOpcode(Hexagon::V4_SL2_return_tnew);
    795     break; //    none  SUBInst if (p0.new) dealloc_return:nt
    796   case Hexagon::L4_return_fnew_pnt:
    797   case Hexagon::L4_return_fnew_pt:
    798     Result.setOpcode(Hexagon::V4_SL2_return_fnew);
    799     break; //    none  SUBInst if (!p0.new) dealloc_return:nt
    800   case Hexagon::L4_return_f:
    801     Result.setOpcode(Hexagon::V4_SL2_return_f);
    802     break; //    none  SUBInst if (!p0) dealloc_return
    803   case Hexagon::L4_return_t:
    804     Result.setOpcode(Hexagon::V4_SL2_return_t);
    805     break; //    none  SUBInst if (p0) dealloc_return
    806   case Hexagon::L4_return:
    807     Result.setOpcode(Hexagon::V4_SL2_return);
    808     break; //    none  SUBInst dealloc_return
    809   case Hexagon::L2_deallocframe:
    810     Result.setOpcode(Hexagon::V4_SL2_deallocframe);
    811     break; //    none  SUBInst deallocframe
    812   case Hexagon::EH_RETURN_JMPR:
    813   case Hexagon::J2_jumpr:
    814   case Hexagon::JMPret:
    815     Result.setOpcode(Hexagon::V4_SL2_jumpr31);
    816     break; //    none  SUBInst jumpr r31
    817   case Hexagon::J2_jumprf:
    818   case Hexagon::JMPretf:
    819     Result.setOpcode(Hexagon::V4_SL2_jumpr31_f);
    820     break; //    none  SUBInst if (!p0) jumpr r31
    821   case Hexagon::J2_jumprfnew:
    822   case Hexagon::JMPretfnewpt:
    823   case Hexagon::JMPretfnew:
    824     Result.setOpcode(Hexagon::V4_SL2_jumpr31_fnew);
    825     break; //    none  SUBInst if (!p0.new) jumpr:nt r31
    826   case Hexagon::J2_jumprt:
    827   case Hexagon::JMPrett:
    828     Result.setOpcode(Hexagon::V4_SL2_jumpr31_t);
    829     break; //    none  SUBInst if (p0) jumpr r31
    830   case Hexagon::J2_jumprtnew:
    831   case Hexagon::JMPrettnewpt:
    832   case Hexagon::JMPrettnew:
    833     Result.setOpcode(Hexagon::V4_SL2_jumpr31_tnew);
    834     break; //    none  SUBInst if (p0.new) jumpr:nt r31
    835   case Hexagon::L2_loadrb_io:
    836     Result.setOpcode(Hexagon::V4_SL2_loadrb_io);
    837     addOps(Result, Inst, 0);
    838     addOps(Result, Inst, 1);
    839     addOps(Result, Inst, 2);
    840     break; //    1,2,3 SUBInst $Rd = memb($Rs + #$u3_0)
    841   case Hexagon::L2_loadrd_io:
    842     Result.setOpcode(Hexagon::V4_SL2_loadrd_sp);
    843     addOps(Result, Inst, 0);
    844     addOps(Result, Inst, 2);
    845     break; //    1,3 SUBInst $Rdd = memd(r29 + #$u5_3)
    846   case Hexagon::L2_loadrh_io:
    847     Result.setOpcode(Hexagon::V4_SL2_loadrh_io);
    848     addOps(Result, Inst, 0);
    849     addOps(Result, Inst, 1);
    850     addOps(Result, Inst, 2);
    851     break; //    1,2,3 SUBInst $Rd = memh($Rs + #$u3_1)
    852   case Hexagon::L2_loadrub_io:
    853     Result.setOpcode(Hexagon::V4_SL1_loadrub_io);
    854     addOps(Result, Inst, 0);
    855     addOps(Result, Inst, 1);
    856     addOps(Result, Inst, 2);
    857     break; //    1,2,3 SUBInst $Rd = memub($Rs + #$u4_0)
    858   case Hexagon::L2_loadruh_io:
    859     Result.setOpcode(Hexagon::V4_SL2_loadruh_io);
    860     addOps(Result, Inst, 0);
    861     addOps(Result, Inst, 1);
    862     addOps(Result, Inst, 2);
    863     break; //    1,2,3 SUBInst $Rd = memuh($Rs + #$u3_1)
    864   case Hexagon::L2_loadri_io:
    865     if (Inst.getOperand(1).getReg() == Hexagon::R29) {
    866       Result.setOpcode(Hexagon::V4_SL2_loadri_sp);
    867       addOps(Result, Inst, 0);
    868       addOps(Result, Inst, 2);
    869       break; //  2 1,3 SUBInst $Rd = memw(r29 + #$u5_2)
    870     } else {
    871       Result.setOpcode(Hexagon::V4_SL1_loadri_io);
    872       addOps(Result, Inst, 0);
    873       addOps(Result, Inst, 1);
    874       addOps(Result, Inst, 2);
    875       break; //    1,2,3 SUBInst $Rd = memw($Rs + #$u4_2)
    876     }
    877   case Hexagon::S4_storeirb_io:
    878     Absolute = Inst.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
    879     assert(Absolute);(void)Absolute;
    880     if (Value == 0) {
    881       Result.setOpcode(Hexagon::V4_SS2_storebi0);
    882       addOps(Result, Inst, 0);
    883       addOps(Result, Inst, 1);
    884       break; //    1,2 SUBInst memb($Rs + #$u4_0)=#0
    885     } else if (Value == 1) {
    886       Result.setOpcode(Hexagon::V4_SS2_storebi1);
    887       addOps(Result, Inst, 0);
    888       addOps(Result, Inst, 1);
    889       break; //  2 1,2 SUBInst memb($Rs + #$u4_0)=#1
    890     }
    891   case Hexagon::S2_storerb_io:
    892     Result.setOpcode(Hexagon::V4_SS1_storeb_io);
    893     addOps(Result, Inst, 0);
    894     addOps(Result, Inst, 1);
    895     addOps(Result, Inst, 2);
    896     break; //    1,2,3 SUBInst memb($Rs + #$u4_0) = $Rt
    897   case Hexagon::S2_storerd_io:
    898     Result.setOpcode(Hexagon::V4_SS2_stored_sp);
    899     addOps(Result, Inst, 1);
    900     addOps(Result, Inst, 2);
    901     break; //    2,3 SUBInst memd(r29 + #$s6_3) = $Rtt
    902   case Hexagon::S2_storerh_io:
    903     Result.setOpcode(Hexagon::V4_SS2_storeh_io);
    904     addOps(Result, Inst, 0);
    905     addOps(Result, Inst, 1);
    906     addOps(Result, Inst, 2);
    907     break; //    1,2,3 SUBInst memb($Rs + #$u4_0) = $Rt
    908   case Hexagon::S4_storeiri_io:
    909     Absolute = Inst.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
    910     assert(Absolute);(void)Absolute;
    911     if (Value == 0) {
    912       Result.setOpcode(Hexagon::V4_SS2_storewi0);
    913       addOps(Result, Inst, 0);
    914       addOps(Result, Inst, 1);
    915       break; //  3 1,2 SUBInst memw($Rs + #$u4_2)=#0
    916     } else if (Value == 1) {
    917       Result.setOpcode(Hexagon::V4_SS2_storewi1);
    918       addOps(Result, Inst, 0);
    919       addOps(Result, Inst, 1);
    920       break; //  3 1,2 SUBInst memw($Rs + #$u4_2)=#1
    921     } else if (Inst.getOperand(0).getReg() == Hexagon::R29) {
    922       Result.setOpcode(Hexagon::V4_SS2_storew_sp);
    923       addOps(Result, Inst, 1);
    924       addOps(Result, Inst, 2);
    925       break; //  1 2,3 SUBInst memw(r29 + #$u5_2) = $Rt
    926     }
    927   case Hexagon::S2_storeri_io:
    928     if (Inst.getOperand(0).getReg() == Hexagon::R29) {
    929       Result.setOpcode(Hexagon::V4_SS2_storew_sp);
    930       addOps(Result, Inst, 1);
    931       addOps(Result, Inst, 2); //  1,2,3 SUBInst memw(sp + #$u5_2) = $Rt
    932     } else {
    933       Result.setOpcode(Hexagon::V4_SS1_storew_io);
    934       addOps(Result, Inst, 0);
    935       addOps(Result, Inst, 1);
    936       addOps(Result, Inst, 2); //  1,2,3 SUBInst memw($Rs + #$u4_2) = $Rt
    937     }
    938     break;
    939   case Hexagon::A2_sxtb:
    940     Result.setOpcode(Hexagon::V4_SA1_sxtb);
    941     addOps(Result, Inst, 0);
    942     addOps(Result, Inst, 1);
    943     break; //  1,2 SUBInst $Rd = sxtb($Rs)
    944   case Hexagon::A2_sxth:
    945     Result.setOpcode(Hexagon::V4_SA1_sxth);
    946     addOps(Result, Inst, 0);
    947     addOps(Result, Inst, 1);
    948     break; //  1,2 SUBInst $Rd = sxth($Rs)
    949   case Hexagon::A2_tfr:
    950     Result.setOpcode(Hexagon::V4_SA1_tfr);
    951     addOps(Result, Inst, 0);
    952     addOps(Result, Inst, 1);
    953     break; //  1,2 SUBInst $Rd = $Rs
    954   case Hexagon::C2_cmovenewif:
    955     Result.setOpcode(Hexagon::V4_SA1_clrfnew);
    956     addOps(Result, Inst, 0);
    957     break; //  2 SUBInst if (!p0.new) $Rd = #0
    958   case Hexagon::C2_cmovenewit:
    959     Result.setOpcode(Hexagon::V4_SA1_clrtnew);
    960     addOps(Result, Inst, 0);
    961     break; //  2 SUBInst if (p0.new) $Rd = #0
    962   case Hexagon::C2_cmoveif:
    963     Result.setOpcode(Hexagon::V4_SA1_clrf);
    964     addOps(Result, Inst, 0);
    965     break; //  2 SUBInst if (!p0) $Rd = #0
    966   case Hexagon::C2_cmoveit:
    967     Result.setOpcode(Hexagon::V4_SA1_clrt);
    968     addOps(Result, Inst, 0);
    969     break; //  2 SUBInst if (p0) $Rd = #0
    970   case Hexagon::A2_tfrsi:
    971     Absolute = Inst.getOperand(1).getExpr()->evaluateAsAbsolute(Value);
    972     if (Absolute && Value == -1) {
    973       Result.setOpcode(Hexagon::V4_SA1_setin1);
    974       addOps(Result, Inst, 0);
    975       break; //  2 1 SUBInst $Rd = #-1
    976     } else {
    977       Result.setOpcode(Hexagon::V4_SA1_seti);
    978       addOps(Result, Inst, 0);
    979       addOps(Result, Inst, 1);
    980       break; //    1,2 SUBInst $Rd = #$u6
    981     }
    982   case Hexagon::A2_zxtb:
    983     Result.setOpcode(Hexagon::V4_SA1_zxtb);
    984     addOps(Result, Inst, 0);
    985     addOps(Result, Inst, 1);
    986     break; //    1,2    $Rd = and($Rs, #255)
    987 
    988   case Hexagon::A2_zxth:
    989     Result.setOpcode(Hexagon::V4_SA1_zxth);
    990     addOps(Result, Inst, 0);
    991     addOps(Result, Inst, 1);
    992     break; //    1,2 SUBInst $Rd = zxth($Rs)
    993   }
    994   return Result;
    995 }
    996 
    997 static bool isStoreInst(unsigned opCode) {
    998   switch (opCode) {
    999   case Hexagon::S2_storeri_io:
   1000   case Hexagon::S2_storerb_io:
   1001   case Hexagon::S2_storerh_io:
   1002   case Hexagon::S2_storerd_io:
   1003   case Hexagon::S4_storeiri_io:
   1004   case Hexagon::S4_storeirb_io:
   1005   case Hexagon::S2_allocframe:
   1006     return true;
   1007   default:
   1008     return false;
   1009   }
   1010 }
   1011 
   1012 SmallVector<DuplexCandidate, 8>
   1013 HexagonMCInstrInfo::getDuplexPossibilties(MCInstrInfo const &MCII,
   1014                                           MCInst const &MCB) {
   1015   assert(isBundle(MCB));
   1016   SmallVector<DuplexCandidate, 8> duplexToTry;
   1017   // Use an "order matters" version of isDuplexPair.
   1018   unsigned numInstrInPacket = MCB.getNumOperands();
   1019 
   1020   for (unsigned distance = 1; distance < numInstrInPacket; ++distance) {
   1021     for (unsigned j = HexagonMCInstrInfo::bundleInstructionsOffset,
   1022                   k = j + distance;
   1023          (j < numInstrInPacket) && (k < numInstrInPacket); ++j, ++k) {
   1024 
   1025       // Check if reversable.
   1026       bool bisReversable = true;
   1027       if (isStoreInst(MCB.getOperand(j).getInst()->getOpcode()) &&
   1028           isStoreInst(MCB.getOperand(k).getInst()->getOpcode())) {
   1029         DEBUG(dbgs() << "skip out of order write pair: " << k << "," << j
   1030                      << "\n");
   1031         bisReversable = false;
   1032       }
   1033       if (HexagonMCInstrInfo::isMemReorderDisabled(MCB)) // }:mem_noshuf
   1034         bisReversable = false;
   1035 
   1036       // Try in order.
   1037       if (isOrderedDuplexPair(
   1038               MCII, *MCB.getOperand(k).getInst(),
   1039               HexagonMCInstrInfo::hasExtenderForIndex(MCB, k - 1),
   1040               *MCB.getOperand(j).getInst(),
   1041               HexagonMCInstrInfo::hasExtenderForIndex(MCB, j - 1),
   1042               bisReversable)) {
   1043         // Get iClass.
   1044         unsigned iClass = iClassOfDuplexPair(
   1045             getDuplexCandidateGroup(*MCB.getOperand(k).getInst()),
   1046             getDuplexCandidateGroup(*MCB.getOperand(j).getInst()));
   1047 
   1048         // Save off pairs for duplex checking.
   1049         duplexToTry.push_back(DuplexCandidate(j, k, iClass));
   1050         DEBUG(dbgs() << "adding pair: " << j << "," << k << ":"
   1051                      << MCB.getOperand(j).getInst()->getOpcode() << ","
   1052                      << MCB.getOperand(k).getInst()->getOpcode() << "\n");
   1053         continue;
   1054       } else {
   1055         DEBUG(dbgs() << "skipping pair: " << j << "," << k << ":"
   1056                      << MCB.getOperand(j).getInst()->getOpcode() << ","
   1057                      << MCB.getOperand(k).getInst()->getOpcode() << "\n");
   1058       }
   1059 
   1060       // Try reverse.
   1061       if (bisReversable) {
   1062         if (isOrderedDuplexPair(
   1063                 MCII, *MCB.getOperand(j).getInst(),
   1064                 HexagonMCInstrInfo::hasExtenderForIndex(MCB, j - 1),
   1065                 *MCB.getOperand(k).getInst(),
   1066                 HexagonMCInstrInfo::hasExtenderForIndex(MCB, k - 1),
   1067                 bisReversable)) {
   1068           // Get iClass.
   1069           unsigned iClass = iClassOfDuplexPair(
   1070               getDuplexCandidateGroup(*MCB.getOperand(j).getInst()),
   1071               getDuplexCandidateGroup(*MCB.getOperand(k).getInst()));
   1072 
   1073           // Save off pairs for duplex checking.
   1074           duplexToTry.push_back(DuplexCandidate(k, j, iClass));
   1075           DEBUG(dbgs() << "adding pair:" << k << "," << j << ":"
   1076                        << MCB.getOperand(j).getInst()->getOpcode() << ","
   1077                        << MCB.getOperand(k).getInst()->getOpcode() << "\n");
   1078         } else {
   1079           DEBUG(dbgs() << "skipping pair: " << k << "," << j << ":"
   1080                        << MCB.getOperand(j).getInst()->getOpcode() << ","
   1081                        << MCB.getOperand(k).getInst()->getOpcode() << "\n");
   1082         }
   1083       }
   1084     }
   1085   }
   1086   return duplexToTry;
   1087 }
   1088