1 
2 //=== HexagonMCCompound.cpp - Hexagon Compound checker  -------===//
3 //
4 //                     The LLVM Compiler Infrastructure
5 //
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10 //
11 // This file is looks at a packet and tries to form compound insns
12 //
13 //===----------------------------------------------------------------------===//
14 #include "Hexagon.h"
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"
26 
27 using namespace llvm;
28 using namespace Hexagon;
29 
30 #define DEBUG_TYPE "hexagon-mccompound"
31 
32 enum OpcodeIndex {
33   fp0_jump_nt = 0,
34   fp0_jump_t,
35   fp1_jump_nt,
36   fp1_jump_t,
37   tp0_jump_nt,
38   tp0_jump_t,
39   tp1_jump_nt,
40   tp1_jump_t
41 };
42 
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,
79 };
80 
81 // enum HexagonII::CompoundGroup
82 namespace {
83 unsigned getCompoundCandidateGroup(MCInst const &MI, bool IsExtended) {
84   unsigned DstReg, SrcReg, Src1Reg, Src2Reg;
85 
86   switch (MI.getOpcode()) {
87   default:
88     return HexagonII::HCG_None;
89   //
90   // Compound pairs.
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"
94   //
95   case Hexagon::C2_cmpeq:
96   case Hexagon::C2_cmpgt:
97   case Hexagon::C2_cmpgtu:
98     if (IsExtended)
99       return false;
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;
107     break;
108   case Hexagon::C2_cmpeqi:
109   case Hexagon::C2_cmpgti:
110   case Hexagon::C2_cmpgtui:
111     if (IsExtended)
112       return false;
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         (HexagonMCInstrInfo::inRange<5>(MI, 2) ||
119          HexagonMCInstrInfo::minConstant(MI, 2) == -1))
120       return HexagonII::HCG_A;
121     break;
122   case Hexagon::A2_tfr:
123     if (IsExtended)
124       return false;
125     // Rd = Rs
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;
131     break;
132   case Hexagon::A2_tfrsi:
133     if (IsExtended)
134       return false;
135     // Rd = #u6
136     DstReg = MI.getOperand(0).getReg();
137     if (HexagonMCInstrInfo::minConstant(MI, 1) <= 63 &&
138         HexagonMCInstrInfo::minConstant(MI, 1) >= 0 &&
139         HexagonMCInstrInfo::isIntRegForSubInst(DstReg))
140       return HexagonII::HCG_A;
141     break;
142   case Hexagon::S2_tstbit_i:
143     if (IsExtended)
144       return false;
145     DstReg = MI.getOperand(0).getReg();
146     Src1Reg = MI.getOperand(1).getReg();
147     if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
148         HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
149         HexagonMCInstrInfo::minConstant(MI, 2) == 0)
150       return HexagonII::HCG_A;
151     break;
152   // The fact that .new form is used pretty much guarantees
153   // that predicate register will match. Nevertheless,
154   // there could be some false positives without additional
155   // checking.
156   case Hexagon::J2_jumptnew:
157   case Hexagon::J2_jumpfnew:
158   case Hexagon::J2_jumptnewpt:
159   case Hexagon::J2_jumpfnewpt:
160     Src1Reg = MI.getOperand(0).getReg();
161     if (Hexagon::P0 == Src1Reg || Hexagon::P1 == Src1Reg)
162       return HexagonII::HCG_B;
163     break;
164   // Transfer and jump:
165   // Rd=#U6 ; jump #r9:2
166   // Rd=Rs ; jump #r9:2
167   // Do not test for jump range here.
168   case Hexagon::J2_jump:
169   case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
170     return HexagonII::HCG_C;
171     break;
172   }
173 
174   return HexagonII::HCG_None;
175 }
176 }
177 
178 /// getCompoundOp - Return the index from 0-7 into the above opcode lists.
179 namespace {
180 unsigned getCompoundOp(MCInst const &HMCI) {
181   const MCOperand &Predicate = HMCI.getOperand(0);
182   unsigned PredReg = Predicate.getReg();
183 
184   assert((PredReg == Hexagon::P0) || (PredReg == Hexagon::P1) ||
185          (PredReg == Hexagon::P2) || (PredReg == Hexagon::P3));
186 
187   switch (HMCI.getOpcode()) {
188   default:
189     llvm_unreachable("Expected match not found.\n");
190     break;
191   case Hexagon::J2_jumpfnew:
192     return (PredReg == Hexagon::P0) ? fp0_jump_nt : fp1_jump_nt;
193   case Hexagon::J2_jumpfnewpt:
194     return (PredReg == Hexagon::P0) ? fp0_jump_t : fp1_jump_t;
195   case Hexagon::J2_jumptnew:
196     return (PredReg == Hexagon::P0) ? tp0_jump_nt : tp1_jump_nt;
197   case Hexagon::J2_jumptnewpt:
198     return (PredReg == Hexagon::P0) ? tp0_jump_t : tp1_jump_t;
199   }
200 }
201 }
202 
203 namespace {
204 MCInst *getCompoundInsn(MCContext &Context, MCInst const &L, MCInst const &R) {
205   MCInst *CompoundInsn = 0;
206   unsigned compoundOpcode;
207   MCOperand Rs, Rt;
208   int64_t Value;
209   bool Success;
210 
211   switch (L.getOpcode()) {
212   default:
213     DEBUG(dbgs() << "Possible compound ignored\n");
214     return CompoundInsn;
215 
216   case Hexagon::A2_tfrsi:
217     Rt = L.getOperand(0);
218     compoundOpcode = J4_jumpseti;
219     CompoundInsn = new (Context) MCInst;
220     CompoundInsn->setOpcode(compoundOpcode);
221 
222     CompoundInsn->addOperand(Rt);
223     CompoundInsn->addOperand(L.getOperand(1)); // Immediate
224     CompoundInsn->addOperand(R.getOperand(0)); // Jump target
225     break;
226 
227   case Hexagon::A2_tfr:
228     Rt = L.getOperand(0);
229     Rs = L.getOperand(1);
230 
231     compoundOpcode = J4_jumpsetr;
232     CompoundInsn = new (Context) MCInst;
233     CompoundInsn->setOpcode(compoundOpcode);
234     CompoundInsn->addOperand(Rt);
235     CompoundInsn->addOperand(Rs);
236     CompoundInsn->addOperand(R.getOperand(0)); // Jump target.
237 
238     break;
239 
240   case Hexagon::C2_cmpeq:
241     DEBUG(dbgs() << "CX: C2_cmpeq\n");
242     Rs = L.getOperand(1);
243     Rt = L.getOperand(2);
244 
245     compoundOpcode = cmpeqBitOpcode[getCompoundOp(R)];
246     CompoundInsn = new (Context) MCInst;
247     CompoundInsn->setOpcode(compoundOpcode);
248     CompoundInsn->addOperand(Rs);
249     CompoundInsn->addOperand(Rt);
250     CompoundInsn->addOperand(R.getOperand(1));
251     break;
252 
253   case Hexagon::C2_cmpgt:
254     DEBUG(dbgs() << "CX: C2_cmpgt\n");
255     Rs = L.getOperand(1);
256     Rt = L.getOperand(2);
257 
258     compoundOpcode = cmpgtBitOpcode[getCompoundOp(R)];
259     CompoundInsn = new (Context) MCInst;
260     CompoundInsn->setOpcode(compoundOpcode);
261     CompoundInsn->addOperand(Rs);
262     CompoundInsn->addOperand(Rt);
263     CompoundInsn->addOperand(R.getOperand(1));
264     break;
265 
266   case Hexagon::C2_cmpgtu:
267     DEBUG(dbgs() << "CX: C2_cmpgtu\n");
268     Rs = L.getOperand(1);
269     Rt = L.getOperand(2);
270 
271     compoundOpcode = cmpgtuBitOpcode[getCompoundOp(R)];
272     CompoundInsn = new (Context) MCInst;
273     CompoundInsn->setOpcode(compoundOpcode);
274     CompoundInsn->addOperand(Rs);
275     CompoundInsn->addOperand(Rt);
276     CompoundInsn->addOperand(R.getOperand(1));
277     break;
278 
279   case Hexagon::C2_cmpeqi:
280     DEBUG(dbgs() << "CX: C2_cmpeqi\n");
281     Success = L.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
282     (void)Success;
283     assert(Success);
284     if (Value == -1)
285       compoundOpcode = cmpeqn1BitOpcode[getCompoundOp(R)];
286     else
287       compoundOpcode = cmpeqiBitOpcode[getCompoundOp(R)];
288 
289     Rs = L.getOperand(1);
290     CompoundInsn = new (Context) MCInst;
291     CompoundInsn->setOpcode(compoundOpcode);
292     CompoundInsn->addOperand(Rs);
293     CompoundInsn->addOperand(L.getOperand(2));
294     CompoundInsn->addOperand(R.getOperand(1));
295     break;
296 
297   case Hexagon::C2_cmpgti:
298     DEBUG(dbgs() << "CX: C2_cmpgti\n");
299     Success = L.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
300     (void)Success;
301     assert(Success);
302     if (Value == -1)
303       compoundOpcode = cmpgtn1BitOpcode[getCompoundOp(R)];
304     else
305       compoundOpcode = cmpgtiBitOpcode[getCompoundOp(R)];
306 
307     Rs = L.getOperand(1);
308     CompoundInsn = new (Context) MCInst;
309     CompoundInsn->setOpcode(compoundOpcode);
310     CompoundInsn->addOperand(Rs);
311     CompoundInsn->addOperand(L.getOperand(2));
312     CompoundInsn->addOperand(R.getOperand(1));
313     break;
314 
315   case Hexagon::C2_cmpgtui:
316     DEBUG(dbgs() << "CX: C2_cmpgtui\n");
317     Rs = L.getOperand(1);
318     compoundOpcode = cmpgtuiBitOpcode[getCompoundOp(R)];
319     CompoundInsn = new (Context) MCInst;
320     CompoundInsn->setOpcode(compoundOpcode);
321     CompoundInsn->addOperand(Rs);
322     CompoundInsn->addOperand(L.getOperand(2));
323     CompoundInsn->addOperand(R.getOperand(1));
324     break;
325 
326   case Hexagon::S2_tstbit_i:
327     DEBUG(dbgs() << "CX: S2_tstbit_i\n");
328     Rs = L.getOperand(1);
329     compoundOpcode = tstBitOpcode[getCompoundOp(R)];
330     CompoundInsn = new (Context) MCInst;
331     CompoundInsn->setOpcode(compoundOpcode);
332     CompoundInsn->addOperand(Rs);
333     CompoundInsn->addOperand(R.getOperand(1));
334     break;
335   }
336 
337   return CompoundInsn;
338 }
339 }
340 
341 /// Non-Symmetrical. See if these two instructions are fit for compound pair.
342 namespace {
343 bool isOrderedCompoundPair(MCInst const &MIa, bool IsExtendedA,
344                            MCInst const &MIb, bool IsExtendedB) {
345   unsigned MIaG = getCompoundCandidateGroup(MIa, IsExtendedA);
346   unsigned MIbG = getCompoundCandidateGroup(MIb, IsExtendedB);
347   // We have two candidates - check that this is the same register
348   // we are talking about.
349   unsigned Opca = MIa.getOpcode();
350   if (MIaG == HexagonII::HCG_A && MIbG == HexagonII::HCG_C &&
351       (Opca == Hexagon::A2_tfr || Opca == Hexagon::A2_tfrsi))
352     return true;
353   return ((MIaG == HexagonII::HCG_A && MIbG == HexagonII::HCG_B) &&
354           (MIa.getOperand(0).getReg() == MIb.getOperand(0).getReg()));
355 }
356 }
357 
358 namespace {
359 bool lookForCompound(MCInstrInfo const &MCII, MCContext &Context, MCInst &MCI) {
360   assert(HexagonMCInstrInfo::isBundle(MCI));
361   bool JExtended = false;
362   for (MCInst::iterator J =
363            MCI.begin() + HexagonMCInstrInfo::bundleInstructionsOffset;
364        J != MCI.end(); ++J) {
365     MCInst const *JumpInst = J->getInst();
366     if (HexagonMCInstrInfo::isImmext(*JumpInst)) {
367       JExtended = true;
368       continue;
369     }
370     if (llvm::HexagonMCInstrInfo::getType(MCII, *JumpInst) ==
371         HexagonII::TypeJ) {
372       // Try to pair with another insn (B)undled with jump.
373       bool BExtended = false;
374       for (MCInst::iterator B =
375                MCI.begin() + HexagonMCInstrInfo::bundleInstructionsOffset;
376            B != MCI.end(); ++B) {
377         MCInst const *Inst = B->getInst();
378         if (JumpInst == Inst)
379           continue;
380         if (HexagonMCInstrInfo::isImmext(*Inst)) {
381           BExtended = true;
382           continue;
383         }
384         DEBUG(dbgs() << "J,B: " << JumpInst->getOpcode() << ","
385                      << Inst->getOpcode() << "\n");
386         if (isOrderedCompoundPair(*Inst, BExtended, *JumpInst, JExtended)) {
387           MCInst *CompoundInsn = getCompoundInsn(Context, *Inst, *JumpInst);
388           if (CompoundInsn) {
389             DEBUG(dbgs() << "B: " << Inst->getOpcode() << ","
390                          << JumpInst->getOpcode() << " Compounds to "
391                          << CompoundInsn->getOpcode() << "\n");
392             J->setInst(CompoundInsn);
393             MCI.erase(B);
394             return true;
395           }
396         }
397         BExtended = false;
398       }
399     }
400     JExtended = false;
401   }
402   return false;
403 }
404 }
405 
406 /// tryCompound - Given a bundle check for compound insns when one
407 /// is found update the contents fo the bundle with the compound insn.
408 /// If a compound instruction is found then the bundle will have one
409 /// additional slot.
410 void HexagonMCInstrInfo::tryCompound(MCInstrInfo const &MCII,
411                                      MCContext &Context, MCInst &MCI) {
412   assert(HexagonMCInstrInfo::isBundle(MCI) &&
413          "Non-Bundle where Bundle expected");
414 
415   // By definition a compound must have 2 insn.
416   if (MCI.size() < 2)
417     return;
418 
419   // Look for compounds until none are found, only update the bundle when
420   // a compound is found.
421   while (lookForCompound(MCII, Context, MCI))
422     ;
423 
424   return;
425 }
426