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