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