xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCompound.cpp (revision 04eeddc0aa8e0a417a16eaf9d7d095207f4a8623)
10b57cec5SDimitry Andric //=== HexagonMCCompound.cpp - Hexagon Compound checker  -------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file is looks at a packet and tries to form compound insns
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "MCTargetDesc/HexagonBaseInfo.h"
140b57cec5SDimitry Andric #include "MCTargetDesc/HexagonMCInstrInfo.h"
150b57cec5SDimitry Andric #include "MCTargetDesc/HexagonMCShuffler.h"
160b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
17e8d8bef9SDimitry Andric #include "llvm/MC/MCExpr.h"
180b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
190b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
200b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
210b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
220b57cec5SDimitry Andric #include <cassert>
230b57cec5SDimitry Andric #include <cstdint>
240b57cec5SDimitry Andric 
250b57cec5SDimitry Andric using namespace llvm;
260b57cec5SDimitry Andric using namespace Hexagon;
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric #define DEBUG_TYPE "hexagon-mccompound"
290b57cec5SDimitry Andric 
300b57cec5SDimitry Andric enum OpcodeIndex {
310b57cec5SDimitry Andric   fp0_jump_nt = 0,
320b57cec5SDimitry Andric   fp0_jump_t,
330b57cec5SDimitry Andric   fp1_jump_nt,
340b57cec5SDimitry Andric   fp1_jump_t,
350b57cec5SDimitry Andric   tp0_jump_nt,
360b57cec5SDimitry Andric   tp0_jump_t,
370b57cec5SDimitry Andric   tp1_jump_nt,
380b57cec5SDimitry Andric   tp1_jump_t
390b57cec5SDimitry Andric };
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric static const unsigned tstBitOpcode[8] = {
420b57cec5SDimitry Andric     J4_tstbit0_fp0_jump_nt, J4_tstbit0_fp0_jump_t,  J4_tstbit0_fp1_jump_nt,
430b57cec5SDimitry Andric     J4_tstbit0_fp1_jump_t,  J4_tstbit0_tp0_jump_nt, J4_tstbit0_tp0_jump_t,
440b57cec5SDimitry Andric     J4_tstbit0_tp1_jump_nt, J4_tstbit0_tp1_jump_t};
450b57cec5SDimitry Andric static const unsigned cmpeqBitOpcode[8] = {
460b57cec5SDimitry Andric     J4_cmpeq_fp0_jump_nt, J4_cmpeq_fp0_jump_t,  J4_cmpeq_fp1_jump_nt,
470b57cec5SDimitry Andric     J4_cmpeq_fp1_jump_t,  J4_cmpeq_tp0_jump_nt, J4_cmpeq_tp0_jump_t,
480b57cec5SDimitry Andric     J4_cmpeq_tp1_jump_nt, J4_cmpeq_tp1_jump_t};
490b57cec5SDimitry Andric static const unsigned cmpgtBitOpcode[8] = {
500b57cec5SDimitry Andric     J4_cmpgt_fp0_jump_nt, J4_cmpgt_fp0_jump_t,  J4_cmpgt_fp1_jump_nt,
510b57cec5SDimitry Andric     J4_cmpgt_fp1_jump_t,  J4_cmpgt_tp0_jump_nt, J4_cmpgt_tp0_jump_t,
520b57cec5SDimitry Andric     J4_cmpgt_tp1_jump_nt, J4_cmpgt_tp1_jump_t};
530b57cec5SDimitry Andric static const unsigned cmpgtuBitOpcode[8] = {
540b57cec5SDimitry Andric     J4_cmpgtu_fp0_jump_nt, J4_cmpgtu_fp0_jump_t,  J4_cmpgtu_fp1_jump_nt,
550b57cec5SDimitry Andric     J4_cmpgtu_fp1_jump_t,  J4_cmpgtu_tp0_jump_nt, J4_cmpgtu_tp0_jump_t,
560b57cec5SDimitry Andric     J4_cmpgtu_tp1_jump_nt, J4_cmpgtu_tp1_jump_t};
570b57cec5SDimitry Andric static const unsigned cmpeqiBitOpcode[8] = {
580b57cec5SDimitry Andric     J4_cmpeqi_fp0_jump_nt, J4_cmpeqi_fp0_jump_t,  J4_cmpeqi_fp1_jump_nt,
590b57cec5SDimitry Andric     J4_cmpeqi_fp1_jump_t,  J4_cmpeqi_tp0_jump_nt, J4_cmpeqi_tp0_jump_t,
600b57cec5SDimitry Andric     J4_cmpeqi_tp1_jump_nt, J4_cmpeqi_tp1_jump_t};
610b57cec5SDimitry Andric static const unsigned cmpgtiBitOpcode[8] = {
620b57cec5SDimitry Andric     J4_cmpgti_fp0_jump_nt, J4_cmpgti_fp0_jump_t,  J4_cmpgti_fp1_jump_nt,
630b57cec5SDimitry Andric     J4_cmpgti_fp1_jump_t,  J4_cmpgti_tp0_jump_nt, J4_cmpgti_tp0_jump_t,
640b57cec5SDimitry Andric     J4_cmpgti_tp1_jump_nt, J4_cmpgti_tp1_jump_t};
650b57cec5SDimitry Andric static const unsigned cmpgtuiBitOpcode[8] = {
660b57cec5SDimitry Andric     J4_cmpgtui_fp0_jump_nt, J4_cmpgtui_fp0_jump_t,  J4_cmpgtui_fp1_jump_nt,
670b57cec5SDimitry Andric     J4_cmpgtui_fp1_jump_t,  J4_cmpgtui_tp0_jump_nt, J4_cmpgtui_tp0_jump_t,
680b57cec5SDimitry Andric     J4_cmpgtui_tp1_jump_nt, J4_cmpgtui_tp1_jump_t};
690b57cec5SDimitry Andric static const unsigned cmpeqn1BitOpcode[8] = {
700b57cec5SDimitry Andric     J4_cmpeqn1_fp0_jump_nt, J4_cmpeqn1_fp0_jump_t,  J4_cmpeqn1_fp1_jump_nt,
710b57cec5SDimitry Andric     J4_cmpeqn1_fp1_jump_t,  J4_cmpeqn1_tp0_jump_nt, J4_cmpeqn1_tp0_jump_t,
720b57cec5SDimitry Andric     J4_cmpeqn1_tp1_jump_nt, J4_cmpeqn1_tp1_jump_t};
730b57cec5SDimitry Andric static const unsigned cmpgtn1BitOpcode[8] = {
740b57cec5SDimitry Andric     J4_cmpgtn1_fp0_jump_nt, J4_cmpgtn1_fp0_jump_t,  J4_cmpgtn1_fp1_jump_nt,
750b57cec5SDimitry Andric     J4_cmpgtn1_fp1_jump_t,  J4_cmpgtn1_tp0_jump_nt, J4_cmpgtn1_tp0_jump_t,
760b57cec5SDimitry Andric     J4_cmpgtn1_tp1_jump_nt, J4_cmpgtn1_tp1_jump_t,
770b57cec5SDimitry Andric };
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric // enum HexagonII::CompoundGroup
getCompoundCandidateGroup(MCInst const & MI,bool IsExtended)800b57cec5SDimitry Andric static unsigned getCompoundCandidateGroup(MCInst const &MI, bool IsExtended) {
810b57cec5SDimitry Andric   unsigned DstReg, SrcReg, Src1Reg, Src2Reg;
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric   switch (MI.getOpcode()) {
840b57cec5SDimitry Andric   default:
850b57cec5SDimitry Andric     return HexagonII::HCG_None;
860b57cec5SDimitry Andric   //
870b57cec5SDimitry Andric   // Compound pairs.
880b57cec5SDimitry Andric   // "p0=cmp.eq(Rs16,Rt16); if (p0.new) jump:nt #r9:2"
890b57cec5SDimitry Andric   // "Rd16=#U6 ; jump #r9:2"
900b57cec5SDimitry Andric   // "Rd16=Rs16 ; jump #r9:2"
910b57cec5SDimitry Andric   //
920b57cec5SDimitry Andric   case Hexagon::C2_cmpeq:
930b57cec5SDimitry Andric   case Hexagon::C2_cmpgt:
940b57cec5SDimitry Andric   case Hexagon::C2_cmpgtu:
950b57cec5SDimitry Andric     if (IsExtended)
96480093f4SDimitry Andric       return HexagonII::HCG_None;
970b57cec5SDimitry Andric     DstReg = MI.getOperand(0).getReg();
980b57cec5SDimitry Andric     Src1Reg = MI.getOperand(1).getReg();
990b57cec5SDimitry Andric     Src2Reg = MI.getOperand(2).getReg();
1000b57cec5SDimitry Andric     if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
1010b57cec5SDimitry Andric         HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
1020b57cec5SDimitry Andric         HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg))
1030b57cec5SDimitry Andric       return HexagonII::HCG_A;
1040b57cec5SDimitry Andric     break;
1050b57cec5SDimitry Andric   case Hexagon::C2_cmpeqi:
1060b57cec5SDimitry Andric   case Hexagon::C2_cmpgti:
1070b57cec5SDimitry Andric   case Hexagon::C2_cmpgtui:
1080b57cec5SDimitry Andric     if (IsExtended)
109480093f4SDimitry Andric       return HexagonII::HCG_None;
1100b57cec5SDimitry Andric     // P0 = cmp.eq(Rs,#u2)
1110b57cec5SDimitry Andric     DstReg = MI.getOperand(0).getReg();
1120b57cec5SDimitry Andric     SrcReg = MI.getOperand(1).getReg();
1130b57cec5SDimitry Andric     if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
1140b57cec5SDimitry Andric         HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
1150b57cec5SDimitry Andric         (HexagonMCInstrInfo::inRange<5>(MI, 2) ||
1160b57cec5SDimitry Andric          HexagonMCInstrInfo::minConstant(MI, 2) == -1))
1170b57cec5SDimitry Andric       return HexagonII::HCG_A;
1180b57cec5SDimitry Andric     break;
1190b57cec5SDimitry Andric   case Hexagon::A2_tfr:
1200b57cec5SDimitry Andric     if (IsExtended)
121480093f4SDimitry Andric       return HexagonII::HCG_None;
1220b57cec5SDimitry Andric     // Rd = Rs
1230b57cec5SDimitry Andric     DstReg = MI.getOperand(0).getReg();
1240b57cec5SDimitry Andric     SrcReg = MI.getOperand(1).getReg();
1250b57cec5SDimitry Andric     if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
1260b57cec5SDimitry Andric         HexagonMCInstrInfo::isIntRegForSubInst(SrcReg))
1270b57cec5SDimitry Andric       return HexagonII::HCG_A;
1280b57cec5SDimitry Andric     break;
1290b57cec5SDimitry Andric   case Hexagon::A2_tfrsi:
1300b57cec5SDimitry Andric     if (IsExtended)
131480093f4SDimitry Andric       return HexagonII::HCG_None;
1320b57cec5SDimitry Andric     // Rd = #u6
1330b57cec5SDimitry Andric     DstReg = MI.getOperand(0).getReg();
1340b57cec5SDimitry Andric     if (HexagonMCInstrInfo::minConstant(MI, 1) <= 63 &&
1350b57cec5SDimitry Andric         HexagonMCInstrInfo::minConstant(MI, 1) >= 0 &&
1360b57cec5SDimitry Andric         HexagonMCInstrInfo::isIntRegForSubInst(DstReg))
1370b57cec5SDimitry Andric       return HexagonII::HCG_A;
1380b57cec5SDimitry Andric     break;
1390b57cec5SDimitry Andric   case Hexagon::S2_tstbit_i:
1400b57cec5SDimitry Andric     if (IsExtended)
141480093f4SDimitry Andric       return HexagonII::HCG_None;
1420b57cec5SDimitry Andric     DstReg = MI.getOperand(0).getReg();
1430b57cec5SDimitry Andric     Src1Reg = MI.getOperand(1).getReg();
1440b57cec5SDimitry Andric     if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
1450b57cec5SDimitry Andric         HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
1460b57cec5SDimitry Andric         HexagonMCInstrInfo::minConstant(MI, 2) == 0)
1470b57cec5SDimitry Andric       return HexagonII::HCG_A;
1480b57cec5SDimitry Andric     break;
1490b57cec5SDimitry Andric   // The fact that .new form is used pretty much guarantees
1500b57cec5SDimitry Andric   // that predicate register will match. Nevertheless,
1510b57cec5SDimitry Andric   // there could be some false positives without additional
1520b57cec5SDimitry Andric   // checking.
1530b57cec5SDimitry Andric   case Hexagon::J2_jumptnew:
1540b57cec5SDimitry Andric   case Hexagon::J2_jumpfnew:
1550b57cec5SDimitry Andric   case Hexagon::J2_jumptnewpt:
1560b57cec5SDimitry Andric   case Hexagon::J2_jumpfnewpt:
1570b57cec5SDimitry Andric     Src1Reg = MI.getOperand(0).getReg();
1580b57cec5SDimitry Andric     if (Hexagon::P0 == Src1Reg || Hexagon::P1 == Src1Reg)
1590b57cec5SDimitry Andric       return HexagonII::HCG_B;
1600b57cec5SDimitry Andric     break;
1610b57cec5SDimitry Andric   // Transfer and jump:
1620b57cec5SDimitry Andric   // Rd=#U6 ; jump #r9:2
1630b57cec5SDimitry Andric   // Rd=Rs ; jump #r9:2
1640b57cec5SDimitry Andric   // Do not test for jump range here.
1650b57cec5SDimitry Andric   case Hexagon::J2_jump:
1660b57cec5SDimitry Andric   case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
1670b57cec5SDimitry Andric     return HexagonII::HCG_C;
1680b57cec5SDimitry Andric     break;
1690b57cec5SDimitry Andric   }
1700b57cec5SDimitry Andric 
1710b57cec5SDimitry Andric   return HexagonII::HCG_None;
1720b57cec5SDimitry Andric }
1730b57cec5SDimitry Andric 
1740b57cec5SDimitry Andric /// getCompoundOp - Return the index from 0-7 into the above opcode lists.
getCompoundOp(MCInst const & HMCI)1750b57cec5SDimitry Andric static unsigned getCompoundOp(MCInst const &HMCI) {
1760b57cec5SDimitry Andric   const MCOperand &Predicate = HMCI.getOperand(0);
1770b57cec5SDimitry Andric   unsigned PredReg = Predicate.getReg();
1780b57cec5SDimitry Andric 
1790b57cec5SDimitry Andric   assert((PredReg == Hexagon::P0) || (PredReg == Hexagon::P1) ||
1800b57cec5SDimitry Andric          (PredReg == Hexagon::P2) || (PredReg == Hexagon::P3));
1810b57cec5SDimitry Andric 
1820b57cec5SDimitry Andric   switch (HMCI.getOpcode()) {
1830b57cec5SDimitry Andric   default:
1840b57cec5SDimitry Andric     llvm_unreachable("Expected match not found.\n");
1850b57cec5SDimitry Andric     break;
1860b57cec5SDimitry Andric   case Hexagon::J2_jumpfnew:
1870b57cec5SDimitry Andric     return (PredReg == Hexagon::P0) ? fp0_jump_nt : fp1_jump_nt;
1880b57cec5SDimitry Andric   case Hexagon::J2_jumpfnewpt:
1890b57cec5SDimitry Andric     return (PredReg == Hexagon::P0) ? fp0_jump_t : fp1_jump_t;
1900b57cec5SDimitry Andric   case Hexagon::J2_jumptnew:
1910b57cec5SDimitry Andric     return (PredReg == Hexagon::P0) ? tp0_jump_nt : tp1_jump_nt;
1920b57cec5SDimitry Andric   case Hexagon::J2_jumptnewpt:
1930b57cec5SDimitry Andric     return (PredReg == Hexagon::P0) ? tp0_jump_t : tp1_jump_t;
1940b57cec5SDimitry Andric   }
1950b57cec5SDimitry Andric }
1960b57cec5SDimitry Andric 
getCompoundInsn(MCContext & Context,MCInst const & L,MCInst const & R)1970b57cec5SDimitry Andric static MCInst *getCompoundInsn(MCContext &Context, MCInst const &L,
1980b57cec5SDimitry Andric                                MCInst const &R) {
1990b57cec5SDimitry Andric   MCInst *CompoundInsn = nullptr;
2000b57cec5SDimitry Andric   unsigned compoundOpcode;
2010b57cec5SDimitry Andric   MCOperand Rs, Rt;
2020b57cec5SDimitry Andric   int64_t Value;
2030b57cec5SDimitry Andric   bool Success;
2040b57cec5SDimitry Andric 
2050b57cec5SDimitry Andric   switch (L.getOpcode()) {
2060b57cec5SDimitry Andric   default:
2070b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Possible compound ignored\n");
2080b57cec5SDimitry Andric     return CompoundInsn;
2090b57cec5SDimitry Andric 
2100b57cec5SDimitry Andric   case Hexagon::A2_tfrsi:
2110b57cec5SDimitry Andric     Rt = L.getOperand(0);
2120b57cec5SDimitry Andric     compoundOpcode = J4_jumpseti;
213e8d8bef9SDimitry Andric     CompoundInsn = Context.createMCInst();
2140b57cec5SDimitry Andric     CompoundInsn->setOpcode(compoundOpcode);
2150b57cec5SDimitry Andric 
2160b57cec5SDimitry Andric     CompoundInsn->addOperand(Rt);
2170b57cec5SDimitry Andric     CompoundInsn->addOperand(L.getOperand(1)); // Immediate
2180b57cec5SDimitry Andric     CompoundInsn->addOperand(R.getOperand(0)); // Jump target
2190b57cec5SDimitry Andric     break;
2200b57cec5SDimitry Andric 
2210b57cec5SDimitry Andric   case Hexagon::A2_tfr:
2220b57cec5SDimitry Andric     Rt = L.getOperand(0);
2230b57cec5SDimitry Andric     Rs = L.getOperand(1);
2240b57cec5SDimitry Andric 
2250b57cec5SDimitry Andric     compoundOpcode = J4_jumpsetr;
226e8d8bef9SDimitry Andric     CompoundInsn = Context.createMCInst();
2270b57cec5SDimitry Andric     CompoundInsn->setOpcode(compoundOpcode);
2280b57cec5SDimitry Andric     CompoundInsn->addOperand(Rt);
2290b57cec5SDimitry Andric     CompoundInsn->addOperand(Rs);
2300b57cec5SDimitry Andric     CompoundInsn->addOperand(R.getOperand(0)); // Jump target.
2310b57cec5SDimitry Andric 
2320b57cec5SDimitry Andric     break;
2330b57cec5SDimitry Andric 
2340b57cec5SDimitry Andric   case Hexagon::C2_cmpeq:
2350b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "CX: C2_cmpeq\n");
2360b57cec5SDimitry Andric     Rs = L.getOperand(1);
2370b57cec5SDimitry Andric     Rt = L.getOperand(2);
2380b57cec5SDimitry Andric 
2390b57cec5SDimitry Andric     compoundOpcode = cmpeqBitOpcode[getCompoundOp(R)];
240e8d8bef9SDimitry Andric     CompoundInsn = Context.createMCInst();
2410b57cec5SDimitry Andric     CompoundInsn->setOpcode(compoundOpcode);
2420b57cec5SDimitry Andric     CompoundInsn->addOperand(Rs);
2430b57cec5SDimitry Andric     CompoundInsn->addOperand(Rt);
2440b57cec5SDimitry Andric     CompoundInsn->addOperand(R.getOperand(1));
2450b57cec5SDimitry Andric     break;
2460b57cec5SDimitry Andric 
2470b57cec5SDimitry Andric   case Hexagon::C2_cmpgt:
2480b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "CX: C2_cmpgt\n");
2490b57cec5SDimitry Andric     Rs = L.getOperand(1);
2500b57cec5SDimitry Andric     Rt = L.getOperand(2);
2510b57cec5SDimitry Andric 
2520b57cec5SDimitry Andric     compoundOpcode = cmpgtBitOpcode[getCompoundOp(R)];
253e8d8bef9SDimitry Andric     CompoundInsn = Context.createMCInst();
2540b57cec5SDimitry Andric     CompoundInsn->setOpcode(compoundOpcode);
2550b57cec5SDimitry Andric     CompoundInsn->addOperand(Rs);
2560b57cec5SDimitry Andric     CompoundInsn->addOperand(Rt);
2570b57cec5SDimitry Andric     CompoundInsn->addOperand(R.getOperand(1));
2580b57cec5SDimitry Andric     break;
2590b57cec5SDimitry Andric 
2600b57cec5SDimitry Andric   case Hexagon::C2_cmpgtu:
2610b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "CX: C2_cmpgtu\n");
2620b57cec5SDimitry Andric     Rs = L.getOperand(1);
2630b57cec5SDimitry Andric     Rt = L.getOperand(2);
2640b57cec5SDimitry Andric 
2650b57cec5SDimitry Andric     compoundOpcode = cmpgtuBitOpcode[getCompoundOp(R)];
266e8d8bef9SDimitry Andric     CompoundInsn = Context.createMCInst();
2670b57cec5SDimitry Andric     CompoundInsn->setOpcode(compoundOpcode);
2680b57cec5SDimitry Andric     CompoundInsn->addOperand(Rs);
2690b57cec5SDimitry Andric     CompoundInsn->addOperand(Rt);
2700b57cec5SDimitry Andric     CompoundInsn->addOperand(R.getOperand(1));
2710b57cec5SDimitry Andric     break;
2720b57cec5SDimitry Andric 
2730b57cec5SDimitry Andric   case Hexagon::C2_cmpeqi:
2740b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "CX: C2_cmpeqi\n");
2750b57cec5SDimitry Andric     Success = L.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
2760b57cec5SDimitry Andric     (void)Success;
2770b57cec5SDimitry Andric     assert(Success);
2780b57cec5SDimitry Andric     if (Value == -1)
2790b57cec5SDimitry Andric       compoundOpcode = cmpeqn1BitOpcode[getCompoundOp(R)];
2800b57cec5SDimitry Andric     else
2810b57cec5SDimitry Andric       compoundOpcode = cmpeqiBitOpcode[getCompoundOp(R)];
2820b57cec5SDimitry Andric 
2830b57cec5SDimitry Andric     Rs = L.getOperand(1);
284e8d8bef9SDimitry Andric     CompoundInsn = Context.createMCInst();
2850b57cec5SDimitry Andric     CompoundInsn->setOpcode(compoundOpcode);
2860b57cec5SDimitry Andric     CompoundInsn->addOperand(Rs);
2870b57cec5SDimitry Andric     CompoundInsn->addOperand(L.getOperand(2));
2880b57cec5SDimitry Andric     CompoundInsn->addOperand(R.getOperand(1));
2890b57cec5SDimitry Andric     break;
2900b57cec5SDimitry Andric 
2910b57cec5SDimitry Andric   case Hexagon::C2_cmpgti:
2920b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "CX: C2_cmpgti\n");
2930b57cec5SDimitry Andric     Success = L.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
2940b57cec5SDimitry Andric     (void)Success;
2950b57cec5SDimitry Andric     assert(Success);
2960b57cec5SDimitry Andric     if (Value == -1)
2970b57cec5SDimitry Andric       compoundOpcode = cmpgtn1BitOpcode[getCompoundOp(R)];
2980b57cec5SDimitry Andric     else
2990b57cec5SDimitry Andric       compoundOpcode = cmpgtiBitOpcode[getCompoundOp(R)];
3000b57cec5SDimitry Andric 
3010b57cec5SDimitry Andric     Rs = L.getOperand(1);
302e8d8bef9SDimitry Andric     CompoundInsn = Context.createMCInst();
3030b57cec5SDimitry Andric     CompoundInsn->setOpcode(compoundOpcode);
3040b57cec5SDimitry Andric     CompoundInsn->addOperand(Rs);
3050b57cec5SDimitry Andric     CompoundInsn->addOperand(L.getOperand(2));
3060b57cec5SDimitry Andric     CompoundInsn->addOperand(R.getOperand(1));
3070b57cec5SDimitry Andric     break;
3080b57cec5SDimitry Andric 
3090b57cec5SDimitry Andric   case Hexagon::C2_cmpgtui:
3100b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "CX: C2_cmpgtui\n");
3110b57cec5SDimitry Andric     Rs = L.getOperand(1);
3120b57cec5SDimitry Andric     compoundOpcode = cmpgtuiBitOpcode[getCompoundOp(R)];
313e8d8bef9SDimitry Andric     CompoundInsn = Context.createMCInst();
3140b57cec5SDimitry Andric     CompoundInsn->setOpcode(compoundOpcode);
3150b57cec5SDimitry Andric     CompoundInsn->addOperand(Rs);
3160b57cec5SDimitry Andric     CompoundInsn->addOperand(L.getOperand(2));
3170b57cec5SDimitry Andric     CompoundInsn->addOperand(R.getOperand(1));
3180b57cec5SDimitry Andric     break;
3190b57cec5SDimitry Andric 
3200b57cec5SDimitry Andric   case Hexagon::S2_tstbit_i:
3210b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "CX: S2_tstbit_i\n");
3220b57cec5SDimitry Andric     Rs = L.getOperand(1);
3230b57cec5SDimitry Andric     compoundOpcode = tstBitOpcode[getCompoundOp(R)];
324e8d8bef9SDimitry Andric     CompoundInsn = Context.createMCInst();
3250b57cec5SDimitry Andric     CompoundInsn->setOpcode(compoundOpcode);
3260b57cec5SDimitry Andric     CompoundInsn->addOperand(Rs);
3270b57cec5SDimitry Andric     CompoundInsn->addOperand(R.getOperand(1));
3280b57cec5SDimitry Andric     break;
3290b57cec5SDimitry Andric   }
3300b57cec5SDimitry Andric 
3310b57cec5SDimitry Andric   return CompoundInsn;
3320b57cec5SDimitry Andric }
3330b57cec5SDimitry Andric 
3340b57cec5SDimitry Andric /// Non-Symmetrical. See if these two instructions are fit for compound pair.
isOrderedCompoundPair(MCInst const & MIa,bool IsExtendedA,MCInst const & MIb,bool IsExtendedB)3350b57cec5SDimitry Andric static bool isOrderedCompoundPair(MCInst const &MIa, bool IsExtendedA,
3360b57cec5SDimitry Andric                                   MCInst const &MIb, bool IsExtendedB) {
3370b57cec5SDimitry Andric   unsigned MIaG = getCompoundCandidateGroup(MIa, IsExtendedA);
3380b57cec5SDimitry Andric   unsigned MIbG = getCompoundCandidateGroup(MIb, IsExtendedB);
3390b57cec5SDimitry Andric   // We have two candidates - check that this is the same register
3400b57cec5SDimitry Andric   // we are talking about.
3410b57cec5SDimitry Andric   unsigned Opca = MIa.getOpcode();
3420b57cec5SDimitry Andric   if (MIaG == HexagonII::HCG_A && MIbG == HexagonII::HCG_C &&
3430b57cec5SDimitry Andric       (Opca == Hexagon::A2_tfr || Opca == Hexagon::A2_tfrsi))
3440b57cec5SDimitry Andric     return true;
3450b57cec5SDimitry Andric   return ((MIaG == HexagonII::HCG_A && MIbG == HexagonII::HCG_B) &&
3460b57cec5SDimitry Andric           (MIa.getOperand(0).getReg() == MIb.getOperand(0).getReg()));
3470b57cec5SDimitry Andric }
3480b57cec5SDimitry Andric 
lookForCompound(MCInstrInfo const & MCII,MCContext & Context,MCInst & MCI)3490b57cec5SDimitry Andric static bool lookForCompound(MCInstrInfo const &MCII, MCContext &Context,
3500b57cec5SDimitry Andric                             MCInst &MCI) {
3510b57cec5SDimitry Andric   assert(HexagonMCInstrInfo::isBundle(MCI));
3520b57cec5SDimitry Andric   bool JExtended = false;
3530b57cec5SDimitry Andric   for (MCInst::iterator J =
3540b57cec5SDimitry Andric            MCI.begin() + HexagonMCInstrInfo::bundleInstructionsOffset;
3550b57cec5SDimitry Andric        J != MCI.end(); ++J) {
3560b57cec5SDimitry Andric     MCInst const *JumpInst = J->getInst();
3570b57cec5SDimitry Andric     if (HexagonMCInstrInfo::isImmext(*JumpInst)) {
3580b57cec5SDimitry Andric       JExtended = true;
3590b57cec5SDimitry Andric       continue;
3600b57cec5SDimitry Andric     }
3610b57cec5SDimitry Andric     if (HexagonMCInstrInfo::getType(MCII, *JumpInst) == HexagonII::TypeJ) {
3620b57cec5SDimitry Andric       // Try to pair with another insn (B)undled with jump.
3630b57cec5SDimitry Andric       bool BExtended = false;
3640b57cec5SDimitry Andric       for (MCInst::iterator B =
3650b57cec5SDimitry Andric                MCI.begin() + HexagonMCInstrInfo::bundleInstructionsOffset;
3660b57cec5SDimitry Andric            B != MCI.end(); ++B) {
3670b57cec5SDimitry Andric         MCInst const *Inst = B->getInst();
368*04eeddc0SDimitry Andric         if (JumpInst == Inst) {
369*04eeddc0SDimitry Andric           BExtended = false;
3700b57cec5SDimitry Andric           continue;
371*04eeddc0SDimitry Andric         }
3720b57cec5SDimitry Andric         if (HexagonMCInstrInfo::isImmext(*Inst)) {
3730b57cec5SDimitry Andric           BExtended = true;
3740b57cec5SDimitry Andric           continue;
3750b57cec5SDimitry Andric         }
3760b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << "J,B: " << JumpInst->getOpcode() << ","
3770b57cec5SDimitry Andric                           << Inst->getOpcode() << "\n");
3780b57cec5SDimitry Andric         if (isOrderedCompoundPair(*Inst, BExtended, *JumpInst, JExtended)) {
3790b57cec5SDimitry Andric           MCInst *CompoundInsn = getCompoundInsn(Context, *Inst, *JumpInst);
3800b57cec5SDimitry Andric           if (CompoundInsn) {
3810b57cec5SDimitry Andric             LLVM_DEBUG(dbgs() << "B: " << Inst->getOpcode() << ","
3820b57cec5SDimitry Andric                               << JumpInst->getOpcode() << " Compounds to "
3830b57cec5SDimitry Andric                               << CompoundInsn->getOpcode() << "\n");
3840b57cec5SDimitry Andric             J->setInst(CompoundInsn);
3850b57cec5SDimitry Andric             MCI.erase(B);
3860b57cec5SDimitry Andric             return true;
3870b57cec5SDimitry Andric           }
3880b57cec5SDimitry Andric         }
3890b57cec5SDimitry Andric         BExtended = false;
3900b57cec5SDimitry Andric       }
3910b57cec5SDimitry Andric     }
3920b57cec5SDimitry Andric     JExtended = false;
3930b57cec5SDimitry Andric   }
3940b57cec5SDimitry Andric   return false;
3950b57cec5SDimitry Andric }
3960b57cec5SDimitry Andric 
3970b57cec5SDimitry Andric /// tryCompound - Given a bundle check for compound insns when one
3980b57cec5SDimitry Andric /// is found update the contents fo the bundle with the compound insn.
3990b57cec5SDimitry Andric /// If a compound instruction is found then the bundle will have one
4000b57cec5SDimitry Andric /// additional slot.
tryCompound(MCInstrInfo const & MCII,MCSubtargetInfo const & STI,MCContext & Context,MCInst & MCI)4010b57cec5SDimitry Andric void HexagonMCInstrInfo::tryCompound(MCInstrInfo const &MCII, MCSubtargetInfo const &STI,
4020b57cec5SDimitry Andric                                      MCContext &Context, MCInst &MCI) {
4030b57cec5SDimitry Andric   assert(HexagonMCInstrInfo::isBundle(MCI) &&
4040b57cec5SDimitry Andric          "Non-Bundle where Bundle expected");
4050b57cec5SDimitry Andric 
4060b57cec5SDimitry Andric   // By definition a compound must have 2 insn.
4070b57cec5SDimitry Andric   if (MCI.size() < 2)
4080b57cec5SDimitry Andric     return;
4090b57cec5SDimitry Andric 
4100b57cec5SDimitry Andric   // Create a vector, needed to keep the order of jump instructions.
4110b57cec5SDimitry Andric   MCInst CheckList(MCI);
4120b57cec5SDimitry Andric 
413*04eeddc0SDimitry Andric   // Keep the last known good bundle around in case the shuffle fails.
414*04eeddc0SDimitry Andric   MCInst LastValidBundle(MCI);
415*04eeddc0SDimitry Andric 
416*04eeddc0SDimitry Andric   bool PreviouslyValid = llvm::HexagonMCShuffle(Context, false, MCII, STI, MCI);
417*04eeddc0SDimitry Andric 
4180b57cec5SDimitry Andric   // Look for compounds until none are found, only update the bundle when
4190b57cec5SDimitry Andric   // a compound is found.
4200b57cec5SDimitry Andric   while (lookForCompound(MCII, Context, CheckList)) {
4210b57cec5SDimitry Andric     // Need to update the bundle.
4220b57cec5SDimitry Andric     MCI = CheckList;
4230b57cec5SDimitry Andric 
424*04eeddc0SDimitry Andric     const bool IsValid = llvm::HexagonMCShuffle(Context, false, MCII, STI, MCI);
425*04eeddc0SDimitry Andric     if (PreviouslyValid && !IsValid) {
4260b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "Found ERROR\n");
427*04eeddc0SDimitry Andric       MCI = LastValidBundle;
428*04eeddc0SDimitry Andric     } else if (IsValid) {
429*04eeddc0SDimitry Andric       LastValidBundle = MCI;
430*04eeddc0SDimitry Andric       PreviouslyValid = true;
4310b57cec5SDimitry Andric     }
4320b57cec5SDimitry Andric   }
4330b57cec5SDimitry Andric }
434