Fixed/added namespace ending comments using clang-tidy. NFC
[oota-llvm.git] / lib / Target / Hexagon / MCTargetDesc / HexagonMCCompound.cpp
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         MI.getOperand(2).isImm() && ((isUInt<5>(MI.getOperand(2).getImm())) ||
119                                      (MI.getOperand(2).getImm() == -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 (MI.getOperand(1).isImm() && MI.getOperand(1).getImm() <= 63 &&
138         MI.getOperand(1).getImm() >= 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         MI.getOperand(2).isImm() &&
149         HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
150         (MI.getOperand(2).getImm() == 0))
151       return HexagonII::HCG_A;
152     break;
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
156   // checking.
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;
164     break;
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;
172     break;
173   }
174
175   return HexagonII::HCG_None;
176 }
177 } // namespace
178
179 /// getCompoundOp - Return the index from 0-7 into the above opcode lists.
180 namespace {
181 unsigned getCompoundOp(MCInst const &HMCI) {
182   const MCOperand &Predicate = HMCI.getOperand(0);
183   unsigned PredReg = Predicate.getReg();
184
185   assert((PredReg == Hexagon::P0) || (PredReg == Hexagon::P1) ||
186          (PredReg == Hexagon::P2) || (PredReg == Hexagon::P3));
187
188   switch (HMCI.getOpcode()) {
189   default:
190     llvm_unreachable("Expected match not found.\n");
191     break;
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;
200   }
201 }
202 } // namespace
203
204 namespace {
205 MCInst *getCompoundInsn(MCContext &Context, MCInst const &L, MCInst const &R) {
206   MCInst *CompoundInsn = 0;
207   unsigned compoundOpcode;
208   MCOperand Rs, Rt;
209
210   switch (L.getOpcode()) {
211   default:
212     DEBUG(dbgs() << "Possible compound ignored\n");
213     return CompoundInsn;
214
215   case Hexagon::A2_tfrsi:
216     Rt = L.getOperand(0);
217     compoundOpcode = J4_jumpseti;
218     CompoundInsn = new (Context) MCInst;
219     CompoundInsn->setOpcode(compoundOpcode);
220
221     CompoundInsn->addOperand(Rt);
222     CompoundInsn->addOperand(L.getOperand(1)); // Immediate
223     CompoundInsn->addOperand(R.getOperand(0)); // Jump target
224     break;
225
226   case Hexagon::A2_tfr:
227     Rt = L.getOperand(0);
228     Rs = L.getOperand(1);
229
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.
236
237     break;
238
239   case Hexagon::C2_cmpeq:
240     DEBUG(dbgs() << "CX: C2_cmpeq\n");
241     Rs = L.getOperand(1);
242     Rt = L.getOperand(2);
243
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));
250     break;
251
252   case Hexagon::C2_cmpgt:
253     DEBUG(dbgs() << "CX: C2_cmpgt\n");
254     Rs = L.getOperand(1);
255     Rt = L.getOperand(2);
256
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));
263     break;
264
265   case Hexagon::C2_cmpgtu:
266     DEBUG(dbgs() << "CX: C2_cmpgtu\n");
267     Rs = L.getOperand(1);
268     Rt = L.getOperand(2);
269
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));
276     break;
277
278   case Hexagon::C2_cmpeqi:
279     DEBUG(dbgs() << "CX: C2_cmpeqi\n");
280     if (L.getOperand(2).getImm() == -1)
281       compoundOpcode = cmpeqn1BitOpcode[getCompoundOp(R)];
282     else
283       compoundOpcode = cmpeqiBitOpcode[getCompoundOp(R)];
284
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));
292     break;
293
294   case Hexagon::C2_cmpgti:
295     DEBUG(dbgs() << "CX: C2_cmpgti\n");
296     if (L.getOperand(2).getImm() == -1)
297       compoundOpcode = cmpgtn1BitOpcode[getCompoundOp(R)];
298     else
299       compoundOpcode = cmpgtiBitOpcode[getCompoundOp(R)];
300
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));
308     break;
309
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));
319     break;
320
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));
329     break;
330   }
331
332   return CompoundInsn;
333 }
334 } // namespace
335
336 /// Non-Symmetrical. See if these two instructions are fit for compound pair.
337 namespace {
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))
347     return true;
348   return ((MIaG == HexagonII::HCG_A && MIbG == HexagonII::HCG_B) &&
349           (MIa.getOperand(0).getReg() == MIb.getOperand(0).getReg()));
350 }
351 } // namespace
352
353 namespace {
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)) {
362       JExtended = true;
363       continue;
364     }
365     if (llvm::HexagonMCInstrInfo::getType(MCII, *JumpInst) ==
366         HexagonII::TypeJ) {
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)
374           continue;
375         if (HexagonMCInstrInfo::isImmext(*Inst)) {
376           BExtended = true;
377           continue;
378         }
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);
383           if (CompoundInsn) {
384             DEBUG(dbgs() << "B: " << Inst->getOpcode() << ","
385                          << JumpInst->getOpcode() << " Compounds to "
386                          << CompoundInsn->getOpcode() << "\n");
387             J->setInst(CompoundInsn);
388             MCI.erase(B);
389             return true;
390           }
391         }
392         BExtended = false;
393       }
394     }
395     JExtended = false;
396   }
397   return false;
398 }
399 } // namespace
400
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
404 /// additional slot.
405 void HexagonMCInstrInfo::tryCompound(MCInstrInfo const &MCII,
406                                      MCContext &Context, MCInst &MCI) {
407   assert(MCI.getOpcode() == Hexagon::BUNDLE &&
408          "Non-Bundle where Bundle expected");
409
410   // By definition a compound must have 2 insn.
411   if (MCI.size() < 2)
412     return;
413
414   // Look for compounds until none are found, only update the bundle when
415   // a compound is found.
416   while (lookForCompound(MCII, Context, MCI))
417     ;
418
419   return;
420 }