2 //=== HexagonMCCompound.cpp - Hexagon Compound checker -------===//
4 // The LLVM Compiler Infrastructure
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
11 // This file is looks at a packet and tries to form compound insns
13 //===----------------------------------------------------------------------===//
15 #include "MCTargetDesc/HexagonBaseInfo.h"
16 #include "MCTargetDesc/HexagonMCShuffler.h"
17 #include "llvm/ADT/StringExtras.h"
18 #include "llvm/MC/MCAssembler.h"
19 #include "llvm/MC/MCContext.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/MC/MCSectionELF.h"
22 #include "llvm/MC/MCStreamer.h"
23 #include "llvm/MC/MCSymbol.h"
24 #include "llvm/Support/Debug.h"
25 #include "llvm/Support/raw_ostream.h"
28 using namespace Hexagon;
30 #define DEBUG_TYPE "hexagon-mccompound"
43 static const unsigned tstBitOpcode[8] = {
44 J4_tstbit0_fp0_jump_nt, J4_tstbit0_fp0_jump_t, J4_tstbit0_fp1_jump_nt,
45 J4_tstbit0_fp1_jump_t, J4_tstbit0_tp0_jump_nt, J4_tstbit0_tp0_jump_t,
46 J4_tstbit0_tp1_jump_nt, J4_tstbit0_tp1_jump_t};
47 static const unsigned cmpeqBitOpcode[8] = {
48 J4_cmpeq_fp0_jump_nt, J4_cmpeq_fp0_jump_t, J4_cmpeq_fp1_jump_nt,
49 J4_cmpeq_fp1_jump_t, J4_cmpeq_tp0_jump_nt, J4_cmpeq_tp0_jump_t,
50 J4_cmpeq_tp1_jump_nt, J4_cmpeq_tp1_jump_t};
51 static const unsigned cmpgtBitOpcode[8] = {
52 J4_cmpgt_fp0_jump_nt, J4_cmpgt_fp0_jump_t, J4_cmpgt_fp1_jump_nt,
53 J4_cmpgt_fp1_jump_t, J4_cmpgt_tp0_jump_nt, J4_cmpgt_tp0_jump_t,
54 J4_cmpgt_tp1_jump_nt, J4_cmpgt_tp1_jump_t};
55 static const unsigned cmpgtuBitOpcode[8] = {
56 J4_cmpgtu_fp0_jump_nt, J4_cmpgtu_fp0_jump_t, J4_cmpgtu_fp1_jump_nt,
57 J4_cmpgtu_fp1_jump_t, J4_cmpgtu_tp0_jump_nt, J4_cmpgtu_tp0_jump_t,
58 J4_cmpgtu_tp1_jump_nt, J4_cmpgtu_tp1_jump_t};
59 static const unsigned cmpeqiBitOpcode[8] = {
60 J4_cmpeqi_fp0_jump_nt, J4_cmpeqi_fp0_jump_t, J4_cmpeqi_fp1_jump_nt,
61 J4_cmpeqi_fp1_jump_t, J4_cmpeqi_tp0_jump_nt, J4_cmpeqi_tp0_jump_t,
62 J4_cmpeqi_tp1_jump_nt, J4_cmpeqi_tp1_jump_t};
63 static const unsigned cmpgtiBitOpcode[8] = {
64 J4_cmpgti_fp0_jump_nt, J4_cmpgti_fp0_jump_t, J4_cmpgti_fp1_jump_nt,
65 J4_cmpgti_fp1_jump_t, J4_cmpgti_tp0_jump_nt, J4_cmpgti_tp0_jump_t,
66 J4_cmpgti_tp1_jump_nt, J4_cmpgti_tp1_jump_t};
67 static const unsigned cmpgtuiBitOpcode[8] = {
68 J4_cmpgtui_fp0_jump_nt, J4_cmpgtui_fp0_jump_t, J4_cmpgtui_fp1_jump_nt,
69 J4_cmpgtui_fp1_jump_t, J4_cmpgtui_tp0_jump_nt, J4_cmpgtui_tp0_jump_t,
70 J4_cmpgtui_tp1_jump_nt, J4_cmpgtui_tp1_jump_t};
71 static const unsigned cmpeqn1BitOpcode[8] = {
72 J4_cmpeqn1_fp0_jump_nt, J4_cmpeqn1_fp0_jump_t, J4_cmpeqn1_fp1_jump_nt,
73 J4_cmpeqn1_fp1_jump_t, J4_cmpeqn1_tp0_jump_nt, J4_cmpeqn1_tp0_jump_t,
74 J4_cmpeqn1_tp1_jump_nt, J4_cmpeqn1_tp1_jump_t};
75 static const unsigned cmpgtn1BitOpcode[8] = {
76 J4_cmpgtn1_fp0_jump_nt, J4_cmpgtn1_fp0_jump_t, J4_cmpgtn1_fp1_jump_nt,
77 J4_cmpgtn1_fp1_jump_t, J4_cmpgtn1_tp0_jump_nt, J4_cmpgtn1_tp0_jump_t,
78 J4_cmpgtn1_tp1_jump_nt, J4_cmpgtn1_tp1_jump_t,
81 // enum HexagonII::CompoundGroup
83 unsigned getCompoundCandidateGroup(MCInst const &MI, bool IsExtended) {
84 unsigned DstReg, SrcReg, Src1Reg, Src2Reg;
86 switch (MI.getOpcode()) {
88 return HexagonII::HCG_None;
91 // "p0=cmp.eq(Rs16,Rt16); if (p0.new) jump:nt #r9:2"
92 // "Rd16=#U6 ; jump #r9:2"
93 // "Rd16=Rs16 ; jump #r9:2"
95 case Hexagon::C2_cmpeq:
96 case Hexagon::C2_cmpgt:
97 case Hexagon::C2_cmpgtu:
100 DstReg = MI.getOperand(0).getReg();
101 Src1Reg = MI.getOperand(1).getReg();
102 Src2Reg = MI.getOperand(2).getReg();
103 if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
104 HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
105 HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg))
106 return HexagonII::HCG_A;
108 case Hexagon::C2_cmpeqi:
109 case Hexagon::C2_cmpgti:
110 case Hexagon::C2_cmpgtui:
113 // P0 = cmp.eq(Rs,#u2)
114 DstReg = MI.getOperand(0).getReg();
115 SrcReg = MI.getOperand(1).getReg();
116 if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
117 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
118 MI.getOperand(2).isImm() && ((isUInt<5>(MI.getOperand(2).getImm())) ||
119 (MI.getOperand(2).getImm() == -1)))
120 return HexagonII::HCG_A;
122 case Hexagon::A2_tfr:
126 DstReg = MI.getOperand(0).getReg();
127 SrcReg = MI.getOperand(1).getReg();
128 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
129 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg))
130 return HexagonII::HCG_A;
132 case Hexagon::A2_tfrsi:
136 DstReg = MI.getOperand(0).getReg();
137 if (MI.getOperand(1).isImm() && MI.getOperand(1).getImm() <= 63 &&
138 MI.getOperand(1).getImm() >= 0 &&
139 HexagonMCInstrInfo::isIntRegForSubInst(DstReg))
140 return HexagonII::HCG_A;
142 case Hexagon::S2_tstbit_i:
145 DstReg = MI.getOperand(0).getReg();
146 Src1Reg = MI.getOperand(1).getReg();
147 if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
148 MI.getOperand(2).isImm() &&
149 HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
150 (MI.getOperand(2).getImm() == 0))
151 return HexagonII::HCG_A;
153 // The fact that .new form is used pretty much guarantees
154 // that predicate register will match. Nevertheless,
155 // there could be some false positives without additional
157 case Hexagon::J2_jumptnew:
158 case Hexagon::J2_jumpfnew:
159 case Hexagon::J2_jumptnewpt:
160 case Hexagon::J2_jumpfnewpt:
161 Src1Reg = MI.getOperand(0).getReg();
162 if (Hexagon::P0 == Src1Reg || Hexagon::P1 == Src1Reg)
163 return HexagonII::HCG_B;
165 // Transfer and jump:
166 // Rd=#U6 ; jump #r9:2
167 // Rd=Rs ; jump #r9:2
168 // Do not test for jump range here.
169 case Hexagon::J2_jump:
170 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
171 return HexagonII::HCG_C;
175 return HexagonII::HCG_None;
179 /// getCompoundOp - Return the index from 0-7 into the above opcode lists.
181 unsigned getCompoundOp(MCInst const &HMCI) {
182 const MCOperand &Predicate = HMCI.getOperand(0);
183 unsigned PredReg = Predicate.getReg();
185 assert((PredReg == Hexagon::P0) || (PredReg == Hexagon::P1) ||
186 (PredReg == Hexagon::P2) || (PredReg == Hexagon::P3));
188 switch (HMCI.getOpcode()) {
190 llvm_unreachable("Expected match not found.\n");
192 case Hexagon::J2_jumpfnew:
193 return (PredReg == Hexagon::P0) ? fp0_jump_nt : fp1_jump_nt;
194 case Hexagon::J2_jumpfnewpt:
195 return (PredReg == Hexagon::P0) ? fp0_jump_t : fp1_jump_t;
196 case Hexagon::J2_jumptnew:
197 return (PredReg == Hexagon::P0) ? tp0_jump_nt : tp1_jump_nt;
198 case Hexagon::J2_jumptnewpt:
199 return (PredReg == Hexagon::P0) ? tp0_jump_t : tp1_jump_t;
205 MCInst *getCompoundInsn(MCContext &Context, MCInst const &L, MCInst const &R) {
206 MCInst *CompoundInsn = 0;
207 unsigned compoundOpcode;
210 switch (L.getOpcode()) {
212 DEBUG(dbgs() << "Possible compound ignored\n");
215 case Hexagon::A2_tfrsi:
216 Rt = L.getOperand(0);
217 compoundOpcode = J4_jumpseti;
218 CompoundInsn = new (Context) MCInst;
219 CompoundInsn->setOpcode(compoundOpcode);
221 CompoundInsn->addOperand(Rt);
222 CompoundInsn->addOperand(L.getOperand(1)); // Immediate
223 CompoundInsn->addOperand(R.getOperand(0)); // Jump target
226 case Hexagon::A2_tfr:
227 Rt = L.getOperand(0);
228 Rs = L.getOperand(1);
230 compoundOpcode = J4_jumpsetr;
231 CompoundInsn = new (Context) MCInst;
232 CompoundInsn->setOpcode(compoundOpcode);
233 CompoundInsn->addOperand(Rt);
234 CompoundInsn->addOperand(Rs);
235 CompoundInsn->addOperand(R.getOperand(0)); // Jump target.
239 case Hexagon::C2_cmpeq:
240 DEBUG(dbgs() << "CX: C2_cmpeq\n");
241 Rs = L.getOperand(1);
242 Rt = L.getOperand(2);
244 compoundOpcode = cmpeqBitOpcode[getCompoundOp(R)];
245 CompoundInsn = new (Context) MCInst;
246 CompoundInsn->setOpcode(compoundOpcode);
247 CompoundInsn->addOperand(Rs);
248 CompoundInsn->addOperand(Rt);
249 CompoundInsn->addOperand(R.getOperand(1));
252 case Hexagon::C2_cmpgt:
253 DEBUG(dbgs() << "CX: C2_cmpgt\n");
254 Rs = L.getOperand(1);
255 Rt = L.getOperand(2);
257 compoundOpcode = cmpgtBitOpcode[getCompoundOp(R)];
258 CompoundInsn = new (Context) MCInst;
259 CompoundInsn->setOpcode(compoundOpcode);
260 CompoundInsn->addOperand(Rs);
261 CompoundInsn->addOperand(Rt);
262 CompoundInsn->addOperand(R.getOperand(1));
265 case Hexagon::C2_cmpgtu:
266 DEBUG(dbgs() << "CX: C2_cmpgtu\n");
267 Rs = L.getOperand(1);
268 Rt = L.getOperand(2);
270 compoundOpcode = cmpgtuBitOpcode[getCompoundOp(R)];
271 CompoundInsn = new (Context) MCInst;
272 CompoundInsn->setOpcode(compoundOpcode);
273 CompoundInsn->addOperand(Rs);
274 CompoundInsn->addOperand(Rt);
275 CompoundInsn->addOperand(R.getOperand(1));
278 case Hexagon::C2_cmpeqi:
279 DEBUG(dbgs() << "CX: C2_cmpeqi\n");
280 if (L.getOperand(2).getImm() == -1)
281 compoundOpcode = cmpeqn1BitOpcode[getCompoundOp(R)];
283 compoundOpcode = cmpeqiBitOpcode[getCompoundOp(R)];
285 Rs = L.getOperand(1);
286 CompoundInsn = new (Context) MCInst;
287 CompoundInsn->setOpcode(compoundOpcode);
288 CompoundInsn->addOperand(Rs);
289 if (L.getOperand(2).getImm() != -1)
290 CompoundInsn->addOperand(L.getOperand(2));
291 CompoundInsn->addOperand(R.getOperand(1));
294 case Hexagon::C2_cmpgti:
295 DEBUG(dbgs() << "CX: C2_cmpgti\n");
296 if (L.getOperand(2).getImm() == -1)
297 compoundOpcode = cmpgtn1BitOpcode[getCompoundOp(R)];
299 compoundOpcode = cmpgtiBitOpcode[getCompoundOp(R)];
301 Rs = L.getOperand(1);
302 CompoundInsn = new (Context) MCInst;
303 CompoundInsn->setOpcode(compoundOpcode);
304 CompoundInsn->addOperand(Rs);
305 if (L.getOperand(2).getImm() != -1)
306 CompoundInsn->addOperand(L.getOperand(2));
307 CompoundInsn->addOperand(R.getOperand(1));
310 case Hexagon::C2_cmpgtui:
311 DEBUG(dbgs() << "CX: C2_cmpgtui\n");
312 Rs = L.getOperand(1);
313 compoundOpcode = cmpgtuiBitOpcode[getCompoundOp(R)];
314 CompoundInsn = new (Context) MCInst;
315 CompoundInsn->setOpcode(compoundOpcode);
316 CompoundInsn->addOperand(Rs);
317 CompoundInsn->addOperand(L.getOperand(2));
318 CompoundInsn->addOperand(R.getOperand(1));
321 case Hexagon::S2_tstbit_i:
322 DEBUG(dbgs() << "CX: S2_tstbit_i\n");
323 Rs = L.getOperand(1);
324 compoundOpcode = tstBitOpcode[getCompoundOp(R)];
325 CompoundInsn = new (Context) MCInst;
326 CompoundInsn->setOpcode(compoundOpcode);
327 CompoundInsn->addOperand(Rs);
328 CompoundInsn->addOperand(R.getOperand(1));
336 /// Non-Symmetrical. See if these two instructions are fit for compound pair.
338 bool isOrderedCompoundPair(MCInst const &MIa, bool IsExtendedA,
339 MCInst const &MIb, bool IsExtendedB) {
340 unsigned MIaG = getCompoundCandidateGroup(MIa, IsExtendedA);
341 unsigned MIbG = getCompoundCandidateGroup(MIb, IsExtendedB);
342 // We have two candidates - check that this is the same register
343 // we are talking about.
344 unsigned Opca = MIa.getOpcode();
345 if (MIaG == HexagonII::HCG_A && MIbG == HexagonII::HCG_C &&
346 (Opca == Hexagon::A2_tfr || Opca == Hexagon::A2_tfrsi))
348 return ((MIaG == HexagonII::HCG_A && MIbG == HexagonII::HCG_B) &&
349 (MIa.getOperand(0).getReg() == MIb.getOperand(0).getReg()));
354 bool lookForCompound(MCInstrInfo const &MCII, MCContext &Context, MCInst &MCI) {
355 assert(HexagonMCInstrInfo::isBundle(MCI));
356 bool JExtended = false;
357 for (MCInst::iterator J =
358 MCI.begin() + HexagonMCInstrInfo::bundleInstructionsOffset;
359 J != MCI.end(); ++J) {
360 MCInst const *JumpInst = J->getInst();
361 if (HexagonMCInstrInfo::isImmext(*JumpInst)) {
365 if (llvm::HexagonMCInstrInfo::getType(MCII, *JumpInst) ==
367 // Try to pair with another insn (B)undled with jump.
368 bool BExtended = false;
369 for (MCInst::iterator B =
370 MCI.begin() + HexagonMCInstrInfo::bundleInstructionsOffset;
371 B != MCI.end(); ++B) {
372 MCInst const *Inst = B->getInst();
373 if (JumpInst == Inst)
375 if (HexagonMCInstrInfo::isImmext(*Inst)) {
379 DEBUG(dbgs() << "J,B: " << JumpInst->getOpcode() << ","
380 << Inst->getOpcode() << "\n");
381 if (isOrderedCompoundPair(*Inst, BExtended, *JumpInst, JExtended)) {
382 MCInst *CompoundInsn = getCompoundInsn(Context, *Inst, *JumpInst);
384 DEBUG(dbgs() << "B: " << Inst->getOpcode() << ","
385 << JumpInst->getOpcode() << " Compounds to "
386 << CompoundInsn->getOpcode() << "\n");
387 J->setInst(CompoundInsn);
401 /// tryCompound - Given a bundle check for compound insns when one
402 /// is found update the contents fo the bundle with the compound insn.
403 /// If a compound instruction is found then the bundle will have one
405 void HexagonMCInstrInfo::tryCompound(MCInstrInfo const &MCII,
406 MCContext &Context, MCInst &MCI) {
407 assert(MCI.getOpcode() == Hexagon::BUNDLE &&
408 "Non-Bundle where Bundle expected");
410 // By definition a compound must have 2 insn.
414 // Look for compounds until none are found, only update the bundle when
415 // a compound is found.
416 while (lookForCompound(MCII, Context, MCI))