Home | History | Annotate | Download | only in MCTargetDesc
      1 
      2 //=== HexagonMCCompound.cpp - Hexagon Compound checker  -------===//
      3 //
      4 //                     The LLVM Compiler Infrastructure
      5 //
      6 // This file is distributed under the University of Illinois Open Source
      7 // License. See LICENSE.TXT for details.
      8 //
      9 //===----------------------------------------------------------------------===//
     10 //
     11 // This file is looks at a packet and tries to form compound insns
     12 //
     13 //===----------------------------------------------------------------------===//
     14 #include "Hexagon.h"
     15 #include "MCTargetDesc/HexagonBaseInfo.h"
     16 #include "MCTargetDesc/HexagonMCShuffler.h"
     17 #include "llvm/ADT/StringExtras.h"
     18 #include "llvm/MC/MCAssembler.h"
     19 #include "llvm/MC/MCContext.h"
     20 #include "llvm/MC/MCInst.h"
     21 #include "llvm/MC/MCSectionELF.h"
     22 #include "llvm/MC/MCStreamer.h"
     23 #include "llvm/MC/MCSymbol.h"
     24 #include "llvm/Support/Debug.h"
     25 #include "llvm/Support/raw_ostream.h"
     26 
     27 using namespace llvm;
     28 using namespace Hexagon;
     29 
     30 #define DEBUG_TYPE "hexagon-mccompound"
     31 
     32 enum OpcodeIndex {
     33   fp0_jump_nt = 0,
     34   fp0_jump_t,
     35   fp1_jump_nt,
     36   fp1_jump_t,
     37   tp0_jump_nt,
     38   tp0_jump_t,
     39   tp1_jump_nt,
     40   tp1_jump_t
     41 };
     42 
     43 static const unsigned tstBitOpcode[8] = {
     44     J4_tstbit0_fp0_jump_nt, J4_tstbit0_fp0_jump_t,  J4_tstbit0_fp1_jump_nt,
     45     J4_tstbit0_fp1_jump_t,  J4_tstbit0_tp0_jump_nt, J4_tstbit0_tp0_jump_t,
     46     J4_tstbit0_tp1_jump_nt, J4_tstbit0_tp1_jump_t};
     47 static const unsigned cmpeqBitOpcode[8] = {
     48     J4_cmpeq_fp0_jump_nt, J4_cmpeq_fp0_jump_t,  J4_cmpeq_fp1_jump_nt,
     49     J4_cmpeq_fp1_jump_t,  J4_cmpeq_tp0_jump_nt, J4_cmpeq_tp0_jump_t,
     50     J4_cmpeq_tp1_jump_nt, J4_cmpeq_tp1_jump_t};
     51 static const unsigned cmpgtBitOpcode[8] = {
     52     J4_cmpgt_fp0_jump_nt, J4_cmpgt_fp0_jump_t,  J4_cmpgt_fp1_jump_nt,
     53     J4_cmpgt_fp1_jump_t,  J4_cmpgt_tp0_jump_nt, J4_cmpgt_tp0_jump_t,
     54     J4_cmpgt_tp1_jump_nt, J4_cmpgt_tp1_jump_t};
     55 static const unsigned cmpgtuBitOpcode[8] = {
     56     J4_cmpgtu_fp0_jump_nt, J4_cmpgtu_fp0_jump_t,  J4_cmpgtu_fp1_jump_nt,
     57     J4_cmpgtu_fp1_jump_t,  J4_cmpgtu_tp0_jump_nt, J4_cmpgtu_tp0_jump_t,
     58     J4_cmpgtu_tp1_jump_nt, J4_cmpgtu_tp1_jump_t};
     59 static const unsigned cmpeqiBitOpcode[8] = {
     60     J4_cmpeqi_fp0_jump_nt, J4_cmpeqi_fp0_jump_t,  J4_cmpeqi_fp1_jump_nt,
     61     J4_cmpeqi_fp1_jump_t,  J4_cmpeqi_tp0_jump_nt, J4_cmpeqi_tp0_jump_t,
     62     J4_cmpeqi_tp1_jump_nt, J4_cmpeqi_tp1_jump_t};
     63 static const unsigned cmpgtiBitOpcode[8] = {
     64     J4_cmpgti_fp0_jump_nt, J4_cmpgti_fp0_jump_t,  J4_cmpgti_fp1_jump_nt,
     65     J4_cmpgti_fp1_jump_t,  J4_cmpgti_tp0_jump_nt, J4_cmpgti_tp0_jump_t,
     66     J4_cmpgti_tp1_jump_nt, J4_cmpgti_tp1_jump_t};
     67 static const unsigned cmpgtuiBitOpcode[8] = {
     68     J4_cmpgtui_fp0_jump_nt, J4_cmpgtui_fp0_jump_t,  J4_cmpgtui_fp1_jump_nt,
     69     J4_cmpgtui_fp1_jump_t,  J4_cmpgtui_tp0_jump_nt, J4_cmpgtui_tp0_jump_t,
     70     J4_cmpgtui_tp1_jump_nt, J4_cmpgtui_tp1_jump_t};
     71 static const unsigned cmpeqn1BitOpcode[8] = {
     72     J4_cmpeqn1_fp0_jump_nt, J4_cmpeqn1_fp0_jump_t,  J4_cmpeqn1_fp1_jump_nt,
     73     J4_cmpeqn1_fp1_jump_t,  J4_cmpeqn1_tp0_jump_nt, J4_cmpeqn1_tp0_jump_t,
     74     J4_cmpeqn1_tp1_jump_nt, J4_cmpeqn1_tp1_jump_t};
     75 static const unsigned cmpgtn1BitOpcode[8] = {
     76     J4_cmpgtn1_fp0_jump_nt, J4_cmpgtn1_fp0_jump_t,  J4_cmpgtn1_fp1_jump_nt,
     77     J4_cmpgtn1_fp1_jump_t,  J4_cmpgtn1_tp0_jump_nt, J4_cmpgtn1_tp0_jump_t,
     78     J4_cmpgtn1_tp1_jump_nt, J4_cmpgtn1_tp1_jump_t,
     79 };
     80 
     81 // enum HexagonII::CompoundGroup
     82 namespace {
     83 unsigned getCompoundCandidateGroup(MCInst const &MI, bool IsExtended) {
     84   unsigned DstReg, SrcReg, Src1Reg, Src2Reg;
     85 
     86   switch (MI.getOpcode()) {
     87   default:
     88     return HexagonII::HCG_None;
     89   //
     90   // Compound pairs.
     91   // "p0=cmp.eq(Rs16,Rt16); if (p0.new) jump:nt #r9:2"
     92   // "Rd16=#U6 ; jump #r9:2"
     93   // "Rd16=Rs16 ; jump #r9:2"
     94   //
     95   case Hexagon::C2_cmpeq:
     96   case Hexagon::C2_cmpgt:
     97   case Hexagon::C2_cmpgtu:
     98     if (IsExtended)
     99       return false;
    100     DstReg = MI.getOperand(0).getReg();
    101     Src1Reg = MI.getOperand(1).getReg();
    102     Src2Reg = MI.getOperand(2).getReg();
    103     if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
    104         HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
    105         HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg))
    106       return HexagonII::HCG_A;
    107     break;
    108   case Hexagon::C2_cmpeqi:
    109   case Hexagon::C2_cmpgti:
    110   case Hexagon::C2_cmpgtui:
    111     if (IsExtended)
    112       return false;
    113     // P0 = cmp.eq(Rs,#u2)
    114     DstReg = MI.getOperand(0).getReg();
    115     SrcReg = MI.getOperand(1).getReg();
    116     if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
    117         HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
    118         (HexagonMCInstrInfo::inRange<5>(MI, 2) ||
    119          HexagonMCInstrInfo::minConstant(MI, 2) == -1))
    120       return HexagonII::HCG_A;
    121     break;
    122   case Hexagon::A2_tfr:
    123     if (IsExtended)
    124       return false;
    125     // Rd = Rs
    126     DstReg = MI.getOperand(0).getReg();
    127     SrcReg = MI.getOperand(1).getReg();
    128     if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
    129         HexagonMCInstrInfo::isIntRegForSubInst(SrcReg))
    130       return HexagonII::HCG_A;
    131     break;
    132   case Hexagon::A2_tfrsi:
    133     if (IsExtended)
    134       return false;
    135     // Rd = #u6
    136     DstReg = MI.getOperand(0).getReg();
    137     if (HexagonMCInstrInfo::minConstant(MI, 1) <= 63 &&
    138         HexagonMCInstrInfo::minConstant(MI, 1) >= 0 &&
    139         HexagonMCInstrInfo::isIntRegForSubInst(DstReg))
    140       return HexagonII::HCG_A;
    141     break;
    142   case Hexagon::S2_tstbit_i:
    143     if (IsExtended)
    144       return false;
    145     DstReg = MI.getOperand(0).getReg();
    146     Src1Reg = MI.getOperand(1).getReg();
    147     if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
    148         HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
    149         HexagonMCInstrInfo::minConstant(MI, 2) == 0)
    150       return HexagonII::HCG_A;
    151     break;
    152   // The fact that .new form is used pretty much guarantees
    153   // that predicate register will match. Nevertheless,
    154   // there could be some false positives without additional
    155   // checking.
    156   case Hexagon::J2_jumptnew:
    157   case Hexagon::J2_jumpfnew:
    158   case Hexagon::J2_jumptnewpt:
    159   case Hexagon::J2_jumpfnewpt:
    160     Src1Reg = MI.getOperand(0).getReg();
    161     if (Hexagon::P0 == Src1Reg || Hexagon::P1 == Src1Reg)
    162       return HexagonII::HCG_B;
    163     break;
    164   // Transfer and jump:
    165   // Rd=#U6 ; jump #r9:2
    166   // Rd=Rs ; jump #r9:2
    167   // Do not test for jump range here.
    168   case Hexagon::J2_jump:
    169   case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
    170     return HexagonII::HCG_C;
    171     break;
    172   }
    173 
    174   return HexagonII::HCG_None;
    175 }
    176 }
    177 
    178 /// getCompoundOp - Return the index from 0-7 into the above opcode lists.
    179 namespace {
    180 unsigned getCompoundOp(MCInst const &HMCI) {
    181   const MCOperand &Predicate = HMCI.getOperand(0);
    182   unsigned PredReg = Predicate.getReg();
    183 
    184   assert((PredReg == Hexagon::P0) || (PredReg == Hexagon::P1) ||
    185          (PredReg == Hexagon::P2) || (PredReg == Hexagon::P3));
    186 
    187   switch (HMCI.getOpcode()) {
    188   default:
    189     llvm_unreachable("Expected match not found.\n");
    190     break;
    191   case Hexagon::J2_jumpfnew:
    192     return (PredReg == Hexagon::P0) ? fp0_jump_nt : fp1_jump_nt;
    193   case Hexagon::J2_jumpfnewpt:
    194     return (PredReg == Hexagon::P0) ? fp0_jump_t : fp1_jump_t;
    195   case Hexagon::J2_jumptnew:
    196     return (PredReg == Hexagon::P0) ? tp0_jump_nt : tp1_jump_nt;
    197   case Hexagon::J2_jumptnewpt:
    198     return (PredReg == Hexagon::P0) ? tp0_jump_t : tp1_jump_t;
    199   }
    200 }
    201 }
    202 
    203 namespace {
    204 MCInst *getCompoundInsn(MCContext &Context, MCInst const &L, MCInst const &R) {
    205   MCInst *CompoundInsn = 0;
    206   unsigned compoundOpcode;
    207   MCOperand Rs, Rt;
    208   int64_t Value;
    209   bool Success;
    210 
    211   switch (L.getOpcode()) {
    212   default:
    213     DEBUG(dbgs() << "Possible compound ignored\n");
    214     return CompoundInsn;
    215 
    216   case Hexagon::A2_tfrsi:
    217     Rt = L.getOperand(0);
    218     compoundOpcode = J4_jumpseti;
    219     CompoundInsn = new (Context) MCInst;
    220     CompoundInsn->setOpcode(compoundOpcode);
    221 
    222     CompoundInsn->addOperand(Rt);
    223     CompoundInsn->addOperand(L.getOperand(1)); // Immediate
    224     CompoundInsn->addOperand(R.getOperand(0)); // Jump target
    225     break;
    226 
    227   case Hexagon::A2_tfr:
    228     Rt = L.getOperand(0);
    229     Rs = L.getOperand(1);
    230 
    231     compoundOpcode = J4_jumpsetr;
    232     CompoundInsn = new (Context) MCInst;
    233     CompoundInsn->setOpcode(compoundOpcode);
    234     CompoundInsn->addOperand(Rt);
    235     CompoundInsn->addOperand(Rs);
    236     CompoundInsn->addOperand(R.getOperand(0)); // Jump target.
    237 
    238     break;
    239 
    240   case Hexagon::C2_cmpeq:
    241     DEBUG(dbgs() << "CX: C2_cmpeq\n");
    242     Rs = L.getOperand(1);
    243     Rt = L.getOperand(2);
    244 
    245     compoundOpcode = cmpeqBitOpcode[getCompoundOp(R)];
    246     CompoundInsn = new (Context) MCInst;
    247     CompoundInsn->setOpcode(compoundOpcode);
    248     CompoundInsn->addOperand(Rs);
    249     CompoundInsn->addOperand(Rt);
    250     CompoundInsn->addOperand(R.getOperand(1));
    251     break;
    252 
    253   case Hexagon::C2_cmpgt:
    254     DEBUG(dbgs() << "CX: C2_cmpgt\n");
    255     Rs = L.getOperand(1);
    256     Rt = L.getOperand(2);
    257 
    258     compoundOpcode = cmpgtBitOpcode[getCompoundOp(R)];
    259     CompoundInsn = new (Context) MCInst;
    260     CompoundInsn->setOpcode(compoundOpcode);
    261     CompoundInsn->addOperand(Rs);
    262     CompoundInsn->addOperand(Rt);
    263     CompoundInsn->addOperand(R.getOperand(1));
    264     break;
    265 
    266   case Hexagon::C2_cmpgtu:
    267     DEBUG(dbgs() << "CX: C2_cmpgtu\n");
    268     Rs = L.getOperand(1);
    269     Rt = L.getOperand(2);
    270 
    271     compoundOpcode = cmpgtuBitOpcode[getCompoundOp(R)];
    272     CompoundInsn = new (Context) MCInst;
    273     CompoundInsn->setOpcode(compoundOpcode);
    274     CompoundInsn->addOperand(Rs);
    275     CompoundInsn->addOperand(Rt);
    276     CompoundInsn->addOperand(R.getOperand(1));
    277     break;
    278 
    279   case Hexagon::C2_cmpeqi:
    280     DEBUG(dbgs() << "CX: C2_cmpeqi\n");
    281     Success = L.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
    282     (void)Success;
    283     assert(Success);
    284     if (Value == -1)
    285       compoundOpcode = cmpeqn1BitOpcode[getCompoundOp(R)];
    286     else
    287       compoundOpcode = cmpeqiBitOpcode[getCompoundOp(R)];
    288 
    289     Rs = L.getOperand(1);
    290     CompoundInsn = new (Context) MCInst;
    291     CompoundInsn->setOpcode(compoundOpcode);
    292     CompoundInsn->addOperand(Rs);
    293     if (Value != -1)
    294       CompoundInsn->addOperand(L.getOperand(2));
    295     CompoundInsn->addOperand(R.getOperand(1));
    296     break;
    297 
    298   case Hexagon::C2_cmpgti:
    299     DEBUG(dbgs() << "CX: C2_cmpgti\n");
    300     Success = L.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
    301     (void)Success;
    302     assert(Success);
    303     if (Value == -1)
    304       compoundOpcode = cmpgtn1BitOpcode[getCompoundOp(R)];
    305     else
    306       compoundOpcode = cmpgtiBitOpcode[getCompoundOp(R)];
    307 
    308     Rs = L.getOperand(1);
    309     CompoundInsn = new (Context) MCInst;
    310     CompoundInsn->setOpcode(compoundOpcode);
    311     CompoundInsn->addOperand(Rs);
    312     if (Value != -1)
    313       CompoundInsn->addOperand(L.getOperand(2));
    314     CompoundInsn->addOperand(R.getOperand(1));
    315     break;
    316 
    317   case Hexagon::C2_cmpgtui:
    318     DEBUG(dbgs() << "CX: C2_cmpgtui\n");
    319     Rs = L.getOperand(1);
    320     compoundOpcode = cmpgtuiBitOpcode[getCompoundOp(R)];
    321     CompoundInsn = new (Context) MCInst;
    322     CompoundInsn->setOpcode(compoundOpcode);
    323     CompoundInsn->addOperand(Rs);
    324     CompoundInsn->addOperand(L.getOperand(2));
    325     CompoundInsn->addOperand(R.getOperand(1));
    326     break;
    327 
    328   case Hexagon::S2_tstbit_i:
    329     DEBUG(dbgs() << "CX: S2_tstbit_i\n");
    330     Rs = L.getOperand(1);
    331     compoundOpcode = tstBitOpcode[getCompoundOp(R)];
    332     CompoundInsn = new (Context) MCInst;
    333     CompoundInsn->setOpcode(compoundOpcode);
    334     CompoundInsn->addOperand(Rs);
    335     CompoundInsn->addOperand(R.getOperand(1));
    336     break;
    337   }
    338 
    339   return CompoundInsn;
    340 }
    341 }
    342 
    343 /// Non-Symmetrical. See if these two instructions are fit for compound pair.
    344 namespace {
    345 bool isOrderedCompoundPair(MCInst const &MIa, bool IsExtendedA,
    346                            MCInst const &MIb, bool IsExtendedB) {
    347   unsigned MIaG = getCompoundCandidateGroup(MIa, IsExtendedA);
    348   unsigned MIbG = getCompoundCandidateGroup(MIb, IsExtendedB);
    349   // We have two candidates - check that this is the same register
    350   // we are talking about.
    351   unsigned Opca = MIa.getOpcode();
    352   if (MIaG == HexagonII::HCG_A && MIbG == HexagonII::HCG_C &&
    353       (Opca == Hexagon::A2_tfr || Opca == Hexagon::A2_tfrsi))
    354     return true;
    355   return ((MIaG == HexagonII::HCG_A && MIbG == HexagonII::HCG_B) &&
    356           (MIa.getOperand(0).getReg() == MIb.getOperand(0).getReg()));
    357 }
    358 }
    359 
    360 namespace {
    361 bool lookForCompound(MCInstrInfo const &MCII, MCContext &Context, MCInst &MCI) {
    362   assert(HexagonMCInstrInfo::isBundle(MCI));
    363   bool JExtended = false;
    364   for (MCInst::iterator J =
    365            MCI.begin() + HexagonMCInstrInfo::bundleInstructionsOffset;
    366        J != MCI.end(); ++J) {
    367     MCInst const *JumpInst = J->getInst();
    368     if (HexagonMCInstrInfo::isImmext(*JumpInst)) {
    369       JExtended = true;
    370       continue;
    371     }
    372     if (llvm::HexagonMCInstrInfo::getType(MCII, *JumpInst) ==
    373         HexagonII::TypeJ) {
    374       // Try to pair with another insn (B)undled with jump.
    375       bool BExtended = false;
    376       for (MCInst::iterator B =
    377                MCI.begin() + HexagonMCInstrInfo::bundleInstructionsOffset;
    378            B != MCI.end(); ++B) {
    379         MCInst const *Inst = B->getInst();
    380         if (JumpInst == Inst)
    381           continue;
    382         if (HexagonMCInstrInfo::isImmext(*Inst)) {
    383           BExtended = true;
    384           continue;
    385         }
    386         DEBUG(dbgs() << "J,B: " << JumpInst->getOpcode() << ","
    387                      << Inst->getOpcode() << "\n");
    388         if (isOrderedCompoundPair(*Inst, BExtended, *JumpInst, JExtended)) {
    389           MCInst *CompoundInsn = getCompoundInsn(Context, *Inst, *JumpInst);
    390           if (CompoundInsn) {
    391             DEBUG(dbgs() << "B: " << Inst->getOpcode() << ","
    392                          << JumpInst->getOpcode() << " Compounds to "
    393                          << CompoundInsn->getOpcode() << "\n");
    394             J->setInst(CompoundInsn);
    395             MCI.erase(B);
    396             return true;
    397           }
    398         }
    399         BExtended = false;
    400       }
    401     }
    402     JExtended = false;
    403   }
    404   return false;
    405 }
    406 }
    407 
    408 /// tryCompound - Given a bundle check for compound insns when one
    409 /// is found update the contents fo the bundle with the compound insn.
    410 /// If a compound instruction is found then the bundle will have one
    411 /// additional slot.
    412 void HexagonMCInstrInfo::tryCompound(MCInstrInfo const &MCII,
    413                                      MCContext &Context, MCInst &MCI) {
    414   assert(HexagonMCInstrInfo::isBundle(MCI) &&
    415          "Non-Bundle where Bundle expected");
    416 
    417   // By definition a compound must have 2 insn.
    418   if (MCI.size() < 2)
    419     return;
    420 
    421   // Look for compounds until none are found, only update the bundle when
    422   // a compound is found.
    423   while (lookForCompound(MCII, Context, MCI))
    424     ;
    425 
    426   return;
    427 }
    428