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