blob: d194bea3d8dc93afdb06ff74836425ec90e13e11 [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) &&
Colin LeMahieu13cc3ab2015-11-10 00:51:56 +0000118 (HexagonMCInstrInfo::inRange<5>(MI, 2) ||
119 HexagonMCInstrInfo::minConstant(MI, 2) == -1))
Colin LeMahieu6aca6f02015-06-08 16:34:47 +0000120 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();
Colin LeMahieu13cc3ab2015-11-10 00:51:56 +0000137 if (HexagonMCInstrInfo::minConstant(MI, 1) <= 63 &&
138 HexagonMCInstrInfo::minConstant(MI, 1) >= 0 &&
Colin LeMahieu6aca6f02015-06-08 16:34:47 +0000139 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) &&
Colin LeMahieu6aca6f02015-06-08 16:34:47 +0000148 HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
Colin LeMahieu13cc3ab2015-11-10 00:51:56 +0000149 HexagonMCInstrInfo::minConstant(MI, 2) == 0)
Colin LeMahieu6aca6f02015-06-08 16:34:47 +0000150 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}
Alexander Kornienkof00654e2015-06-23 09:49:53 +0000176}
Colin LeMahieu6aca6f02015-06-08 16:34:47 +0000177
178/// getCompoundOp - Return the index from 0-7 into the above opcode lists.
179namespace {
180unsigned 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}
Alexander Kornienkof00654e2015-06-23 09:49:53 +0000201}
Colin LeMahieu6aca6f02015-06-08 16:34:47 +0000202
203namespace {
204MCInst *getCompoundInsn(MCContext &Context, MCInst const &L, MCInst const &R) {
205 MCInst *CompoundInsn = 0;
206 unsigned compoundOpcode;
207 MCOperand Rs, Rt;
Colin LeMahieu13cc3ab2015-11-10 00:51:56 +0000208 int64_t Value;
209 bool Success;
Colin LeMahieu6aca6f02015-06-08 16:34:47 +0000210
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");
Colin LeMahieu13cc3ab2015-11-10 00:51:56 +0000281 Success = L.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
282 (void)Success;
283 assert(Success);
284 if (Value == -1)
Colin LeMahieu6aca6f02015-06-08 16:34:47 +0000285 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);
Colin LeMahieu13cc3ab2015-11-10 00:51:56 +0000293 if (Value != -1)
Colin LeMahieu6aca6f02015-06-08 16:34:47 +0000294 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");
Colin LeMahieu13cc3ab2015-11-10 00:51:56 +0000300 Success = L.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
301 (void)Success;
302 assert(Success);
303 if (Value == -1)
Colin LeMahieu6aca6f02015-06-08 16:34:47 +0000304 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);
Colin LeMahieu13cc3ab2015-11-10 00:51:56 +0000312 if (Value != -1)
Colin LeMahieu6aca6f02015-06-08 16:34:47 +0000313 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}
Alexander Kornienkof00654e2015-06-23 09:49:53 +0000341}
Colin LeMahieu6aca6f02015-06-08 16:34:47 +0000342
343/// Non-Symmetrical. See if these two instructions are fit for compound pair.
344namespace {
345bool 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}
Alexander Kornienkof00654e2015-06-23 09:49:53 +0000358}
Colin LeMahieu6aca6f02015-06-08 16:34:47 +0000359
360namespace {
361bool 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}
Alexander Kornienkof00654e2015-06-23 09:49:53 +0000406}
Colin LeMahieu6aca6f02015-06-08 16:34:47 +0000407
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.
412void HexagonMCInstrInfo::tryCompound(MCInstrInfo const &MCII,
413 MCContext &Context, MCInst &MCI) {
Colin LeMahieuf0af6e52015-11-13 17:42:46 +0000414 assert(HexagonMCInstrInfo::isBundle(MCI) &&
Colin LeMahieu6aca6f02015-06-08 16:34:47 +0000415 "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}