• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
getCompoundCandidateGroup(MCInst const & MI,bool IsExtended)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 {
getCompoundOp(MCInst const & HMCI)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 {
getCompoundInsn(MCContext & Context,MCInst const & L,MCInst const & R)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     if (Value != -1)
294       CompoundInsn->addOperand(L.getOperand(2));
295     CompoundInsn->addOperand(R.getOperand(1));
296     break;
297 
298   case Hexagon::C2_cmpgti:
299     DEBUG(dbgs() << "CX: C2_cmpgti\n");
300     Success = L.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
301     (void)Success;
302     assert(Success);
303     if (Value == -1)
304       compoundOpcode = cmpgtn1BitOpcode[getCompoundOp(R)];
305     else
306       compoundOpcode = cmpgtiBitOpcode[getCompoundOp(R)];
307 
308     Rs = L.getOperand(1);
309     CompoundInsn = new (Context) MCInst;
310     CompoundInsn->setOpcode(compoundOpcode);
311     CompoundInsn->addOperand(Rs);
312     if (Value != -1)
313       CompoundInsn->addOperand(L.getOperand(2));
314     CompoundInsn->addOperand(R.getOperand(1));
315     break;
316 
317   case Hexagon::C2_cmpgtui:
318     DEBUG(dbgs() << "CX: C2_cmpgtui\n");
319     Rs = L.getOperand(1);
320     compoundOpcode = cmpgtuiBitOpcode[getCompoundOp(R)];
321     CompoundInsn = new (Context) MCInst;
322     CompoundInsn->setOpcode(compoundOpcode);
323     CompoundInsn->addOperand(Rs);
324     CompoundInsn->addOperand(L.getOperand(2));
325     CompoundInsn->addOperand(R.getOperand(1));
326     break;
327 
328   case Hexagon::S2_tstbit_i:
329     DEBUG(dbgs() << "CX: S2_tstbit_i\n");
330     Rs = L.getOperand(1);
331     compoundOpcode = tstBitOpcode[getCompoundOp(R)];
332     CompoundInsn = new (Context) MCInst;
333     CompoundInsn->setOpcode(compoundOpcode);
334     CompoundInsn->addOperand(Rs);
335     CompoundInsn->addOperand(R.getOperand(1));
336     break;
337   }
338 
339   return CompoundInsn;
340 }
341 }
342 
343 /// Non-Symmetrical. See if these two instructions are fit for compound pair.
344 namespace {
isOrderedCompoundPair(MCInst const & MIa,bool IsExtendedA,MCInst const & MIb,bool IsExtendedB)345 bool isOrderedCompoundPair(MCInst const &MIa, bool IsExtendedA,
346                            MCInst const &MIb, bool IsExtendedB) {
347   unsigned MIaG = getCompoundCandidateGroup(MIa, IsExtendedA);
348   unsigned MIbG = getCompoundCandidateGroup(MIb, IsExtendedB);
349   // We have two candidates - check that this is the same register
350   // we are talking about.
351   unsigned Opca = MIa.getOpcode();
352   if (MIaG == HexagonII::HCG_A && MIbG == HexagonII::HCG_C &&
353       (Opca == Hexagon::A2_tfr || Opca == Hexagon::A2_tfrsi))
354     return true;
355   return ((MIaG == HexagonII::HCG_A && MIbG == HexagonII::HCG_B) &&
356           (MIa.getOperand(0).getReg() == MIb.getOperand(0).getReg()));
357 }
358 }
359 
360 namespace {
lookForCompound(MCInstrInfo const & MCII,MCContext & Context,MCInst & MCI)361 bool lookForCompound(MCInstrInfo const &MCII, MCContext &Context, MCInst &MCI) {
362   assert(HexagonMCInstrInfo::isBundle(MCI));
363   bool JExtended = false;
364   for (MCInst::iterator J =
365            MCI.begin() + HexagonMCInstrInfo::bundleInstructionsOffset;
366        J != MCI.end(); ++J) {
367     MCInst const *JumpInst = J->getInst();
368     if (HexagonMCInstrInfo::isImmext(*JumpInst)) {
369       JExtended = true;
370       continue;
371     }
372     if (llvm::HexagonMCInstrInfo::getType(MCII, *JumpInst) ==
373         HexagonII::TypeJ) {
374       // Try to pair with another insn (B)undled with jump.
375       bool BExtended = false;
376       for (MCInst::iterator B =
377                MCI.begin() + HexagonMCInstrInfo::bundleInstructionsOffset;
378            B != MCI.end(); ++B) {
379         MCInst const *Inst = B->getInst();
380         if (JumpInst == Inst)
381           continue;
382         if (HexagonMCInstrInfo::isImmext(*Inst)) {
383           BExtended = true;
384           continue;
385         }
386         DEBUG(dbgs() << "J,B: " << JumpInst->getOpcode() << ","
387                      << Inst->getOpcode() << "\n");
388         if (isOrderedCompoundPair(*Inst, BExtended, *JumpInst, JExtended)) {
389           MCInst *CompoundInsn = getCompoundInsn(Context, *Inst, *JumpInst);
390           if (CompoundInsn) {
391             DEBUG(dbgs() << "B: " << Inst->getOpcode() << ","
392                          << JumpInst->getOpcode() << " Compounds to "
393                          << CompoundInsn->getOpcode() << "\n");
394             J->setInst(CompoundInsn);
395             MCI.erase(B);
396             return true;
397           }
398         }
399         BExtended = false;
400       }
401     }
402     JExtended = false;
403   }
404   return false;
405 }
406 }
407 
408 /// tryCompound - Given a bundle check for compound insns when one
409 /// is found update the contents fo the bundle with the compound insn.
410 /// If a compound instruction is found then the bundle will have one
411 /// additional slot.
tryCompound(MCInstrInfo const & MCII,MCContext & Context,MCInst & MCI)412 void HexagonMCInstrInfo::tryCompound(MCInstrInfo const &MCII,
413                                      MCContext &Context, MCInst &MCI) {
414   assert(HexagonMCInstrInfo::isBundle(MCI) &&
415          "Non-Bundle where Bundle expected");
416 
417   // By definition a compound must have 2 insn.
418   if (MCI.size() < 2)
419     return;
420 
421   // Look for compounds until none are found, only update the bundle when
422   // a compound is found.
423   while (lookForCompound(MCII, Context, MCI))
424     ;
425 
426   return;
427 }
428