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