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 static std::map<unsigned, unsigned>
     84     subinstOpcodeMap(std::begin(opcodeData), std::end(opcodeData));
     85 
     86 bool HexagonMCInstrInfo::isDuplexPairMatch(unsigned Ga, unsigned Gb) {
     87   switch (Ga) {
     88   case HexagonII::HSIG_None:
     89   default:
     90     return false;
     91   case HexagonII::HSIG_L1:
     92     return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_A);
     93   case HexagonII::HSIG_L2:
     94     return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
     95             Gb == HexagonII::HSIG_A);
     96   case HexagonII::HSIG_S1:
     97     return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
     98             Gb == HexagonII::HSIG_S1 || Gb == HexagonII::HSIG_A);
     99   case HexagonII::HSIG_S2:
    100     return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
    101             Gb == HexagonII::HSIG_S1 || Gb == HexagonII::HSIG_S2 ||
    102             Gb == HexagonII::HSIG_A);
    103   case HexagonII::HSIG_A:
    104     return (Gb == HexagonII::HSIG_A);
    105   case HexagonII::HSIG_Compound:
    106     return (Gb == HexagonII::HSIG_Compound);
    107   }
    108   return false;
    109 }
    110 
    111 unsigned HexagonMCInstrInfo::iClassOfDuplexPair(unsigned Ga, unsigned Gb) {
    112   switch (Ga) {
    113   case HexagonII::HSIG_None:
    114   default:
    115     break;
    116   case HexagonII::HSIG_L1:
    117     switch (Gb) {
    118     default:
    119       break;
    120     case HexagonII::HSIG_L1:
    121       return 0;
    122     case HexagonII::HSIG_A:
    123       return 0x4;
    124     }
    125   case HexagonII::HSIG_L2:
    126     switch (Gb) {
    127     default:
    128       break;
    129     case HexagonII::HSIG_L1:
    130       return 0x1;
    131     case HexagonII::HSIG_L2:
    132       return 0x2;
    133     case HexagonII::HSIG_A:
    134       return 0x5;
    135     }
    136   case HexagonII::HSIG_S1:
    137     switch (Gb) {
    138     default:
    139       break;
    140     case HexagonII::HSIG_L1:
    141       return 0x8;
    142     case HexagonII::HSIG_L2:
    143       return 0x9;
    144     case HexagonII::HSIG_S1:
    145       return 0xA;
    146     case HexagonII::HSIG_A:
    147       return 0x6;
    148     }
    149   case HexagonII::HSIG_S2:
    150     switch (Gb) {
    151     default:
    152       break;
    153     case HexagonII::HSIG_L1:
    154       return 0xC;
    155     case HexagonII::HSIG_L2:
    156       return 0xD;
    157     case HexagonII::HSIG_S1:
    158       return 0xB;
    159     case HexagonII::HSIG_S2:
    160       return 0xE;
    161     case HexagonII::HSIG_A:
    162       return 0x7;
    163     }
    164   case HexagonII::HSIG_A:
    165     switch (Gb) {
    166     default:
    167       break;
    168     case HexagonII::HSIG_A:
    169       return 0x3;
    170     }
    171   case HexagonII::HSIG_Compound:
    172     switch (Gb) {
    173     case HexagonII::HSIG_Compound:
    174       return 0xFFFFFFFF;
    175     }
    176   }
    177   return 0xFFFFFFFF;
    178 }
    179 
    180 unsigned HexagonMCInstrInfo::getDuplexCandidateGroup(MCInst const &MCI) {
    181   unsigned DstReg, PredReg, SrcReg, Src1Reg, Src2Reg;
    182 
    183   switch (MCI.getOpcode()) {
    184   default:
    185     return HexagonII::HSIG_None;
    186   //
    187   // Group L1:
    188   //
    189   // Rd = memw(Rs+#u4:2)
    190   // Rd = memub(Rs+#u4:0)
    191   case Hexagon::L2_loadri_io:
    192     DstReg = MCI.getOperand(0).getReg();
    193     SrcReg = MCI.getOperand(1).getReg();
    194     // Special case this one from Group L2.
    195     // Rd = memw(r29+#u5:2)
    196     if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
    197       if (HexagonMCInstrInfo::isIntReg(SrcReg) &&
    198           Hexagon::R29 == SrcReg && inRange<5, 2>(MCI, 2)) {
    199         return HexagonII::HSIG_L2;
    200       }
    201       // Rd = memw(Rs+#u4:2)
    202       if (HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
    203           inRange<4, 2>(MCI, 2)) {
    204         return HexagonII::HSIG_L1;
    205       }
    206     }
    207     break;
    208   case Hexagon::L2_loadrub_io:
    209     // Rd = memub(Rs+#u4:0)
    210     DstReg = MCI.getOperand(0).getReg();
    211     SrcReg = MCI.getOperand(1).getReg();
    212     if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
    213         HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
    214         inRange<4>(MCI, 2)) {
    215       return HexagonII::HSIG_L1;
    216     }
    217     break;
    218   //
    219   // Group L2:
    220   //
    221   // Rd = memh/memuh(Rs+#u3:1)
    222   // Rd = memb(Rs+#u3:0)
    223   // Rd = memw(r29+#u5:2) - Handled above.
    224   // Rdd = memd(r29+#u5:3)
    225   // deallocframe
    226   // [if ([!]p0[.new])] dealloc_return
    227   // [if ([!]p0[.new])] jumpr r31
    228   case Hexagon::L2_loadrh_io:
    229   case Hexagon::L2_loadruh_io:
    230     // Rd = memh/memuh(Rs+#u3:1)
    231     DstReg = MCI.getOperand(0).getReg();
    232     SrcReg = MCI.getOperand(1).getReg();
    233     if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
    234         HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
    235         inRange<3, 1>(MCI, 2)) {
    236       return HexagonII::HSIG_L2;
    237     }
    238     break;
    239   case Hexagon::L2_loadrb_io:
    240     // Rd = memb(Rs+#u3:0)
    241     DstReg = MCI.getOperand(0).getReg();
    242     SrcReg = MCI.getOperand(1).getReg();
    243     if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
    244         HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
    245         inRange<3>(MCI, 2)) {
    246       return HexagonII::HSIG_L2;
    247     }
    248     break;
    249   case Hexagon::L2_loadrd_io:
    250     // Rdd = memd(r29+#u5:3)
    251     DstReg = MCI.getOperand(0).getReg();
    252     SrcReg = MCI.getOperand(1).getReg();
    253     if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
    254         HexagonMCInstrInfo::isIntReg(SrcReg) && Hexagon::R29 == SrcReg &&
    255         inRange<5, 3>(MCI, 2)) {
    256       return HexagonII::HSIG_L2;
    257     }
    258     break;
    259 
    260   case Hexagon::L4_return:
    261 
    262   case Hexagon::L2_deallocframe:
    263 
    264     return HexagonII::HSIG_L2;
    265   case Hexagon::EH_RETURN_JMPR:
    266 
    267   case Hexagon::J2_jumpr:
    268   case Hexagon::JMPret:
    269     // jumpr r31
    270     // Actual form JMPR %PC<imp-def>, %R31<imp-use>, %R0<imp-use,internal>.
    271     DstReg = MCI.getOperand(0).getReg();
    272     if (Hexagon::R31 == DstReg) {
    273       return HexagonII::HSIG_L2;
    274     }
    275     break;
    276 
    277   case Hexagon::J2_jumprt:
    278   case Hexagon::J2_jumprf:
    279   case Hexagon::J2_jumprtnew:
    280   case Hexagon::J2_jumprfnew:
    281   case Hexagon::JMPrett:
    282   case Hexagon::JMPretf:
    283   case Hexagon::JMPrettnew:
    284   case Hexagon::JMPretfnew:
    285   case Hexagon::JMPrettnewpt:
    286   case Hexagon::JMPretfnewpt:
    287     DstReg = MCI.getOperand(1).getReg();
    288     SrcReg = MCI.getOperand(0).getReg();
    289     // [if ([!]p0[.new])] jumpr r31
    290     if ((HexagonMCInstrInfo::isPredReg(SrcReg) && (Hexagon::P0 == SrcReg)) &&
    291         (Hexagon::R31 == DstReg)) {
    292       return HexagonII::HSIG_L2;
    293     }
    294     break;
    295   case Hexagon::L4_return_t:
    296 
    297   case Hexagon::L4_return_f:
    298 
    299   case Hexagon::L4_return_tnew_pnt:
    300 
    301   case Hexagon::L4_return_fnew_pnt:
    302 
    303   case Hexagon::L4_return_tnew_pt:
    304 
    305   case Hexagon::L4_return_fnew_pt:
    306     // [if ([!]p0[.new])] dealloc_return
    307     SrcReg = MCI.getOperand(0).getReg();
    308     if (Hexagon::P0 == SrcReg) {
    309       return HexagonII::HSIG_L2;
    310     }
    311     break;
    312   //
    313   // Group S1:
    314   //
    315   // memw(Rs+#u4:2) = Rt
    316   // memb(Rs+#u4:0) = Rt
    317   case Hexagon::S2_storeri_io:
    318     // Special case this one from Group S2.
    319     // memw(r29+#u5:2) = Rt
    320     Src1Reg = MCI.getOperand(0).getReg();
    321     Src2Reg = MCI.getOperand(2).getReg();
    322     if (HexagonMCInstrInfo::isIntReg(Src1Reg) &&
    323         HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
    324         Hexagon::R29 == Src1Reg && inRange<5, 2>(MCI, 1)) {
    325       return HexagonII::HSIG_S2;
    326     }
    327     // memw(Rs+#u4:2) = Rt
    328     if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
    329         HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
    330         inRange<4, 2>(MCI, 1)) {
    331       return HexagonII::HSIG_S1;
    332     }
    333     break;
    334   case Hexagon::S2_storerb_io:
    335     // memb(Rs+#u4:0) = Rt
    336     Src1Reg = MCI.getOperand(0).getReg();
    337     Src2Reg = MCI.getOperand(2).getReg();
    338     if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
    339         HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
    340         inRange<4>(MCI, 1)) {
    341       return HexagonII::HSIG_S1;
    342     }
    343     break;
    344   //
    345   // Group S2:
    346   //
    347   // memh(Rs+#u3:1) = Rt
    348   // memw(r29+#u5:2) = Rt
    349   // memd(r29+#s6:3) = Rtt
    350   // memw(Rs+#u4:2) = #U1
    351   // memb(Rs+#u4) = #U1
    352   // allocframe(#u5:3)
    353   case Hexagon::S2_storerh_io:
    354     // memh(Rs+#u3:1) = Rt
    355     Src1Reg = MCI.getOperand(0).getReg();
    356     Src2Reg = MCI.getOperand(2).getReg();
    357     if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
    358         HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
    359         inRange<3, 1>(MCI, 1)) {
    360       return HexagonII::HSIG_S2;
    361     }
    362     break;
    363   case Hexagon::S2_storerd_io:
    364     // memd(r29+#s6:3) = Rtt
    365     Src1Reg = MCI.getOperand(0).getReg();
    366     Src2Reg = MCI.getOperand(2).getReg();
    367     if (HexagonMCInstrInfo::isDblRegForSubInst(Src2Reg) &&
    368         HexagonMCInstrInfo::isIntReg(Src1Reg) && Hexagon::R29 == Src1Reg &&
    369         inSRange<6, 3>(MCI, 1)) {
    370       return HexagonII::HSIG_S2;
    371     }
    372     break;
    373   case Hexagon::S4_storeiri_io:
    374     // memw(Rs+#u4:2) = #U1
    375     Src1Reg = MCI.getOperand(0).getReg();
    376     if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
    377         inRange<4, 2>(MCI, 1) && inRange<1>(MCI, 2)) {
    378       return HexagonII::HSIG_S2;
    379     }
    380     break;
    381   case Hexagon::S4_storeirb_io:
    382     // memb(Rs+#u4) = #U1
    383     Src1Reg = MCI.getOperand(0).getReg();
    384     if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
    385         inRange<4>(MCI, 1) && inRange<1>(MCI, 2)) {
    386       return HexagonII::HSIG_S2;
    387     }
    388     break;
    389   case Hexagon::S2_allocframe:
    390     if (inRange<5, 3>(MCI, 0))
    391       return HexagonII::HSIG_S2;
    392     break;
    393   //
    394   // Group A:
    395   //
    396   // Rx = add(Rx,#s7)
    397   // Rd = Rs
    398   // Rd = #u6
    399   // Rd = #-1
    400   // if ([!]P0[.new]) Rd = #0
    401   // Rd = add(r29,#u6:2)
    402   // Rx = add(Rx,Rs)
    403   // P0 = cmp.eq(Rs,#u2)
    404   // Rdd = combine(#0,Rs)
    405   // Rdd = combine(Rs,#0)
    406   // Rdd = combine(#u2,#U2)
    407   // Rd = add(Rs,#1)
    408   // Rd = add(Rs,#-1)
    409   // Rd = sxth/sxtb/zxtb/zxth(Rs)
    410   // Rd = and(Rs,#1)
    411   case Hexagon::A2_addi:
    412     DstReg = MCI.getOperand(0).getReg();
    413     SrcReg = MCI.getOperand(1).getReg();
    414     if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
    415       // Rd = add(r29,#u6:2)
    416       if (HexagonMCInstrInfo::isIntReg(SrcReg) && Hexagon::R29 == SrcReg &&
    417           inRange<6, 2>(MCI, 2)) {
    418         return HexagonII::HSIG_A;
    419       }
    420       // Rx = add(Rx,#s7)
    421       if (DstReg == SrcReg) {
    422         return HexagonII::HSIG_A;
    423       }
    424       // Rd = add(Rs,#1)
    425       // Rd = add(Rs,#-1)
    426       if (HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
    427           (minConstant(MCI, 2) == 1 || minConstant(MCI, 2) == -1)) {
    428         return HexagonII::HSIG_A;
    429       }
    430     }
    431     break;
    432   case Hexagon::A2_add:
    433     // Rx = add(Rx,Rs)
    434     DstReg = MCI.getOperand(0).getReg();
    435     Src1Reg = MCI.getOperand(1).getReg();
    436     Src2Reg = MCI.getOperand(2).getReg();
    437     if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) && (DstReg == Src1Reg) &&
    438         HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg)) {
    439       return HexagonII::HSIG_A;
    440     }
    441     break;
    442   case Hexagon::A2_andir:
    443     DstReg = MCI.getOperand(0).getReg();
    444     SrcReg = MCI.getOperand(1).getReg();
    445     if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
    446         HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
    447         (minConstant(MCI, 2) == 1 || minConstant(MCI, 2) == 255)) {
    448       return HexagonII::HSIG_A;
    449     }
    450     break;
    451   case Hexagon::A2_tfr:
    452     // Rd = Rs
    453     DstReg = MCI.getOperand(0).getReg();
    454     SrcReg = MCI.getOperand(1).getReg();
    455     if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
    456         HexagonMCInstrInfo::isIntRegForSubInst(SrcReg)) {
    457       return HexagonII::HSIG_A;
    458     }
    459     break;
    460   case Hexagon::A2_tfrsi:
    461     DstReg = MCI.getOperand(0).getReg();
    462 
    463     if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
    464       return HexagonII::HSIG_A;
    465     }
    466     break;
    467   case Hexagon::C2_cmoveit:
    468   case Hexagon::C2_cmovenewit:
    469   case Hexagon::C2_cmoveif:
    470   case Hexagon::C2_cmovenewif:
    471     // if ([!]P0[.new]) Rd = #0
    472     // Actual form:
    473     // %R16<def> = C2_cmovenewit %P0<internal>, 0, %R16<imp-use,undef>;
    474     DstReg = MCI.getOperand(0).getReg();  // Rd
    475     PredReg = MCI.getOperand(1).getReg(); // P0
    476     if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
    477         Hexagon::P0 == PredReg && minConstant(MCI, 2) == 0) {
    478       return HexagonII::HSIG_A;
    479     }
    480     break;
    481   case Hexagon::C2_cmpeqi:
    482     // P0 = cmp.eq(Rs,#u2)
    483     DstReg = MCI.getOperand(0).getReg();
    484     SrcReg = MCI.getOperand(1).getReg();
    485     if (Hexagon::P0 == DstReg &&
    486         HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
    487         inRange<2>(MCI, 2)) {
    488       return HexagonII::HSIG_A;
    489     }
    490     break;
    491   case Hexagon::A2_combineii:
    492   case Hexagon::A4_combineii:
    493     // Rdd = combine(#u2,#U2)
    494     DstReg = MCI.getOperand(0).getReg();
    495     if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
    496         inRange<2>(MCI, 1) && inRange<2>(MCI, 2)) {
    497       return HexagonII::HSIG_A;
    498     }
    499     break;
    500   case Hexagon::A4_combineri:
    501     // Rdd = combine(Rs,#0)
    502     DstReg = MCI.getOperand(0).getReg();
    503     SrcReg = MCI.getOperand(1).getReg();
    504     if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
    505         HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
    506         minConstant(MCI, 2) == 0) {
    507       return HexagonII::HSIG_A;
    508     }
    509     break;
    510   case Hexagon::A4_combineir:
    511     // Rdd = combine(#0,Rs)
    512     DstReg = MCI.getOperand(0).getReg();
    513     SrcReg = MCI.getOperand(2).getReg();
    514     if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
    515         HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
    516         minConstant(MCI, 1) == 0) {
    517       return HexagonII::HSIG_A;
    518     }
    519     break;
    520   case Hexagon::A2_sxtb:
    521   case Hexagon::A2_sxth:
    522   case Hexagon::A2_zxtb:
    523   case Hexagon::A2_zxth:
    524     // Rd = sxth/sxtb/zxtb/zxth(Rs)
    525     DstReg = MCI.getOperand(0).getReg();
    526     SrcReg = MCI.getOperand(1).getReg();
    527     if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
    528         HexagonMCInstrInfo::isIntRegForSubInst(SrcReg)) {
    529       return HexagonII::HSIG_A;
    530     }
    531     break;
    532   }
    533 
    534   return HexagonII::HSIG_None;
    535 }
    536 
    537 bool HexagonMCInstrInfo::subInstWouldBeExtended(MCInst const &potentialDuplex) {
    538   unsigned DstReg, SrcReg;
    539   switch (potentialDuplex.getOpcode()) {
    540   case Hexagon::A2_addi:
    541     // testing for case of: Rx = add(Rx,#s7)
    542     DstReg = potentialDuplex.getOperand(0).getReg();
    543     SrcReg = potentialDuplex.getOperand(1).getReg();
    544     if (DstReg == SrcReg && HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
    545       int64_t Value;
    546       if (!potentialDuplex.getOperand(2).getExpr()->evaluateAsAbsolute(Value))
    547         return true;
    548       if (!isShiftedInt<7, 0>(Value))
    549         return true;
    550     }
    551     break;
    552   case Hexagon::A2_tfrsi:
    553     DstReg = potentialDuplex.getOperand(0).getReg();
    554 
    555     if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
    556       int64_t Value;
    557       if (!potentialDuplex.getOperand(1).getExpr()->evaluateAsAbsolute(Value))
    558         return true;
    559       // Check for case of Rd = #-1.
    560       if (Value == -1)
    561         return false;
    562       // Check for case of Rd = #u6.
    563       if (!isShiftedUInt<6, 0>(Value))
    564         return true;
    565     }
    566     break;
    567   default:
    568     break;
    569   }
    570   return false;
    571 }
    572 
    573 /// non-Symmetrical. See if these two instructions are fit for duplex pair.
    574 bool HexagonMCInstrInfo::isOrderedDuplexPair(MCInstrInfo const &MCII,
    575                                              MCInst const &MIa, bool ExtendedA,
    576                                              MCInst const &MIb, bool ExtendedB,
    577                                              bool bisReversable) {
    578   // Slot 1 cannot be extended in duplexes PRM 10.5
    579   if (ExtendedA)
    580     return false;
    581   // Only A2_addi and A2_tfrsi can be extended in duplex form PRM 10.5
    582   if (ExtendedB) {
    583     unsigned Opcode = MIb.getOpcode();
    584     if ((Opcode != Hexagon::A2_addi) && (Opcode != Hexagon::A2_tfrsi))
    585       return false;
    586   }
    587   unsigned MIaG = HexagonMCInstrInfo::getDuplexCandidateGroup(MIa),
    588            MIbG = HexagonMCInstrInfo::getDuplexCandidateGroup(MIb);
    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