blob: 886f8db3bc63853782a209eccdbb0913d2ad4c43 [file] [log] [blame]
Colin LeMahieu6aca6f02015-06-08 16:34:47 +00001
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
27using namespace llvm;
28using namespace Hexagon;
29
30#define DEBUG_TYPE "hexagon-mccompound"
31
32enum 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
Benjamin Kramerfeacdd32015-06-10 14:43:59 +000043static 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};
47static 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};
51static 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};
55static 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};
59static 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};
63static 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};
67static 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};
71static 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};
75static const unsigned cmpgtn1BitOpcode[8] = {
Colin LeMahieu6aca6f02015-06-08 16:34:47 +000076 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
82namespace {
83unsigned 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}
Alexander Kornienkof00654e2015-06-23 09:49:53 +0000177}
Colin LeMahieu6aca6f02015-06-08 16:34:47 +0000178
179/// getCompoundOp - Return the index from 0-7 into the above opcode lists.
180namespace {
181unsigned 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}
Alexander Kornienkof00654e2015-06-23 09:49:53 +0000202}
Colin LeMahieu6aca6f02015-06-08 16:34:47 +0000203
204namespace {
205MCInst *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}
Alexander Kornienkof00654e2015-06-23 09:49:53 +0000334}
Colin LeMahieu6aca6f02015-06-08 16:34:47 +0000335
336/// Non-Symmetrical. See if these two instructions are fit for compound pair.
337namespace {
338bool 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}
Alexander Kornienkof00654e2015-06-23 09:49:53 +0000351}
Colin LeMahieu6aca6f02015-06-08 16:34:47 +0000352
353namespace {
354bool 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}
Alexander Kornienkof00654e2015-06-23 09:49:53 +0000399}
Colin LeMahieu6aca6f02015-06-08 16:34:47 +0000400
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.
405void 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}