1 //=== HexagonMCCompound.cpp - Hexagon Compound checker -------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file is looks at a packet and tries to form compound insns
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "Hexagon.h"
15 #include "MCTargetDesc/HexagonBaseInfo.h"
16 #include "MCTargetDesc/HexagonMCInstrInfo.h"
17 #include "MCTargetDesc/HexagonMCShuffler.h"
18 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/Support/Debug.h"
21 #include "llvm/Support/ErrorHandling.h"
22 #include "llvm/Support/raw_ostream.h"
23 #include <cassert>
24 #include <cstdint>
25
26 using namespace llvm;
27 using namespace Hexagon;
28
29 #define DEBUG_TYPE "hexagon-mccompound"
30
31 enum OpcodeIndex {
32 fp0_jump_nt = 0,
33 fp0_jump_t,
34 fp1_jump_nt,
35 fp1_jump_t,
36 tp0_jump_nt,
37 tp0_jump_t,
38 tp1_jump_nt,
39 tp1_jump_t
40 };
41
42 static const unsigned tstBitOpcode[8] = {
43 J4_tstbit0_fp0_jump_nt, J4_tstbit0_fp0_jump_t, J4_tstbit0_fp1_jump_nt,
44 J4_tstbit0_fp1_jump_t, J4_tstbit0_tp0_jump_nt, J4_tstbit0_tp0_jump_t,
45 J4_tstbit0_tp1_jump_nt, J4_tstbit0_tp1_jump_t};
46 static const unsigned cmpeqBitOpcode[8] = {
47 J4_cmpeq_fp0_jump_nt, J4_cmpeq_fp0_jump_t, J4_cmpeq_fp1_jump_nt,
48 J4_cmpeq_fp1_jump_t, J4_cmpeq_tp0_jump_nt, J4_cmpeq_tp0_jump_t,
49 J4_cmpeq_tp1_jump_nt, J4_cmpeq_tp1_jump_t};
50 static const unsigned cmpgtBitOpcode[8] = {
51 J4_cmpgt_fp0_jump_nt, J4_cmpgt_fp0_jump_t, J4_cmpgt_fp1_jump_nt,
52 J4_cmpgt_fp1_jump_t, J4_cmpgt_tp0_jump_nt, J4_cmpgt_tp0_jump_t,
53 J4_cmpgt_tp1_jump_nt, J4_cmpgt_tp1_jump_t};
54 static const unsigned cmpgtuBitOpcode[8] = {
55 J4_cmpgtu_fp0_jump_nt, J4_cmpgtu_fp0_jump_t, J4_cmpgtu_fp1_jump_nt,
56 J4_cmpgtu_fp1_jump_t, J4_cmpgtu_tp0_jump_nt, J4_cmpgtu_tp0_jump_t,
57 J4_cmpgtu_tp1_jump_nt, J4_cmpgtu_tp1_jump_t};
58 static const unsigned cmpeqiBitOpcode[8] = {
59 J4_cmpeqi_fp0_jump_nt, J4_cmpeqi_fp0_jump_t, J4_cmpeqi_fp1_jump_nt,
60 J4_cmpeqi_fp1_jump_t, J4_cmpeqi_tp0_jump_nt, J4_cmpeqi_tp0_jump_t,
61 J4_cmpeqi_tp1_jump_nt, J4_cmpeqi_tp1_jump_t};
62 static const unsigned cmpgtiBitOpcode[8] = {
63 J4_cmpgti_fp0_jump_nt, J4_cmpgti_fp0_jump_t, J4_cmpgti_fp1_jump_nt,
64 J4_cmpgti_fp1_jump_t, J4_cmpgti_tp0_jump_nt, J4_cmpgti_tp0_jump_t,
65 J4_cmpgti_tp1_jump_nt, J4_cmpgti_tp1_jump_t};
66 static const unsigned cmpgtuiBitOpcode[8] = {
67 J4_cmpgtui_fp0_jump_nt, J4_cmpgtui_fp0_jump_t, J4_cmpgtui_fp1_jump_nt,
68 J4_cmpgtui_fp1_jump_t, J4_cmpgtui_tp0_jump_nt, J4_cmpgtui_tp0_jump_t,
69 J4_cmpgtui_tp1_jump_nt, J4_cmpgtui_tp1_jump_t};
70 static const unsigned cmpeqn1BitOpcode[8] = {
71 J4_cmpeqn1_fp0_jump_nt, J4_cmpeqn1_fp0_jump_t, J4_cmpeqn1_fp1_jump_nt,
72 J4_cmpeqn1_fp1_jump_t, J4_cmpeqn1_tp0_jump_nt, J4_cmpeqn1_tp0_jump_t,
73 J4_cmpeqn1_tp1_jump_nt, J4_cmpeqn1_tp1_jump_t};
74 static const unsigned cmpgtn1BitOpcode[8] = {
75 J4_cmpgtn1_fp0_jump_nt, J4_cmpgtn1_fp0_jump_t, J4_cmpgtn1_fp1_jump_nt,
76 J4_cmpgtn1_fp1_jump_t, J4_cmpgtn1_tp0_jump_nt, J4_cmpgtn1_tp0_jump_t,
77 J4_cmpgtn1_tp1_jump_nt, J4_cmpgtn1_tp1_jump_t,
78 };
79
80 // enum HexagonII::CompoundGroup
getCompoundCandidateGroup(MCInst const & MI,bool IsExtended)81 static unsigned getCompoundCandidateGroup(MCInst const &MI, bool IsExtended) {
82 unsigned DstReg, SrcReg, Src1Reg, Src2Reg;
83
84 switch (MI.getOpcode()) {
85 default:
86 return HexagonII::HCG_None;
87 //
88 // Compound pairs.
89 // "p0=cmp.eq(Rs16,Rt16); if (p0.new) jump:nt #r9:2"
90 // "Rd16=#U6 ; jump #r9:2"
91 // "Rd16=Rs16 ; jump #r9:2"
92 //
93 case Hexagon::C2_cmpeq:
94 case Hexagon::C2_cmpgt:
95 case Hexagon::C2_cmpgtu:
96 if (IsExtended)
97 return false;
98 DstReg = MI.getOperand(0).getReg();
99 Src1Reg = MI.getOperand(1).getReg();
100 Src2Reg = MI.getOperand(2).getReg();
101 if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
102 HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
103 HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg))
104 return HexagonII::HCG_A;
105 break;
106 case Hexagon::C2_cmpeqi:
107 case Hexagon::C2_cmpgti:
108 case Hexagon::C2_cmpgtui:
109 if (IsExtended)
110 return false;
111 // P0 = cmp.eq(Rs,#u2)
112 DstReg = MI.getOperand(0).getReg();
113 SrcReg = MI.getOperand(1).getReg();
114 if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
115 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
116 (HexagonMCInstrInfo::inRange<5>(MI, 2) ||
117 HexagonMCInstrInfo::minConstant(MI, 2) == -1))
118 return HexagonII::HCG_A;
119 break;
120 case Hexagon::A2_tfr:
121 if (IsExtended)
122 return false;
123 // Rd = Rs
124 DstReg = MI.getOperand(0).getReg();
125 SrcReg = MI.getOperand(1).getReg();
126 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
127 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg))
128 return HexagonII::HCG_A;
129 break;
130 case Hexagon::A2_tfrsi:
131 if (IsExtended)
132 return false;
133 // Rd = #u6
134 DstReg = MI.getOperand(0).getReg();
135 if (HexagonMCInstrInfo::minConstant(MI, 1) <= 63 &&
136 HexagonMCInstrInfo::minConstant(MI, 1) >= 0 &&
137 HexagonMCInstrInfo::isIntRegForSubInst(DstReg))
138 return HexagonII::HCG_A;
139 break;
140 case Hexagon::S2_tstbit_i:
141 if (IsExtended)
142 return false;
143 DstReg = MI.getOperand(0).getReg();
144 Src1Reg = MI.getOperand(1).getReg();
145 if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
146 HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
147 HexagonMCInstrInfo::minConstant(MI, 2) == 0)
148 return HexagonII::HCG_A;
149 break;
150 // The fact that .new form is used pretty much guarantees
151 // that predicate register will match. Nevertheless,
152 // there could be some false positives without additional
153 // checking.
154 case Hexagon::J2_jumptnew:
155 case Hexagon::J2_jumpfnew:
156 case Hexagon::J2_jumptnewpt:
157 case Hexagon::J2_jumpfnewpt:
158 Src1Reg = MI.getOperand(0).getReg();
159 if (Hexagon::P0 == Src1Reg || Hexagon::P1 == Src1Reg)
160 return HexagonII::HCG_B;
161 break;
162 // Transfer and jump:
163 // Rd=#U6 ; jump #r9:2
164 // Rd=Rs ; jump #r9:2
165 // Do not test for jump range here.
166 case Hexagon::J2_jump:
167 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
168 return HexagonII::HCG_C;
169 break;
170 }
171
172 return HexagonII::HCG_None;
173 }
174
175 /// getCompoundOp - Return the index from 0-7 into the above opcode lists.
getCompoundOp(MCInst const & HMCI)176 static unsigned getCompoundOp(MCInst const &HMCI) {
177 const MCOperand &Predicate = HMCI.getOperand(0);
178 unsigned PredReg = Predicate.getReg();
179
180 assert((PredReg == Hexagon::P0) || (PredReg == Hexagon::P1) ||
181 (PredReg == Hexagon::P2) || (PredReg == Hexagon::P3));
182
183 switch (HMCI.getOpcode()) {
184 default:
185 llvm_unreachable("Expected match not found.\n");
186 break;
187 case Hexagon::J2_jumpfnew:
188 return (PredReg == Hexagon::P0) ? fp0_jump_nt : fp1_jump_nt;
189 case Hexagon::J2_jumpfnewpt:
190 return (PredReg == Hexagon::P0) ? fp0_jump_t : fp1_jump_t;
191 case Hexagon::J2_jumptnew:
192 return (PredReg == Hexagon::P0) ? tp0_jump_nt : tp1_jump_nt;
193 case Hexagon::J2_jumptnewpt:
194 return (PredReg == Hexagon::P0) ? tp0_jump_t : tp1_jump_t;
195 }
196 }
197
getCompoundInsn(MCContext & Context,MCInst const & L,MCInst const & R)198 static MCInst *getCompoundInsn(MCContext &Context, MCInst const &L,
199 MCInst const &R) {
200 MCInst *CompoundInsn = nullptr;
201 unsigned compoundOpcode;
202 MCOperand Rs, Rt;
203 int64_t Value;
204 bool Success;
205
206 switch (L.getOpcode()) {
207 default:
208 LLVM_DEBUG(dbgs() << "Possible compound ignored\n");
209 return CompoundInsn;
210
211 case Hexagon::A2_tfrsi:
212 Rt = L.getOperand(0);
213 compoundOpcode = J4_jumpseti;
214 CompoundInsn = new (Context) MCInst;
215 CompoundInsn->setOpcode(compoundOpcode);
216
217 CompoundInsn->addOperand(Rt);
218 CompoundInsn->addOperand(L.getOperand(1)); // Immediate
219 CompoundInsn->addOperand(R.getOperand(0)); // Jump target
220 break;
221
222 case Hexagon::A2_tfr:
223 Rt = L.getOperand(0);
224 Rs = L.getOperand(1);
225
226 compoundOpcode = J4_jumpsetr;
227 CompoundInsn = new (Context) MCInst;
228 CompoundInsn->setOpcode(compoundOpcode);
229 CompoundInsn->addOperand(Rt);
230 CompoundInsn->addOperand(Rs);
231 CompoundInsn->addOperand(R.getOperand(0)); // Jump target.
232
233 break;
234
235 case Hexagon::C2_cmpeq:
236 LLVM_DEBUG(dbgs() << "CX: C2_cmpeq\n");
237 Rs = L.getOperand(1);
238 Rt = L.getOperand(2);
239
240 compoundOpcode = cmpeqBitOpcode[getCompoundOp(R)];
241 CompoundInsn = new (Context) MCInst;
242 CompoundInsn->setOpcode(compoundOpcode);
243 CompoundInsn->addOperand(Rs);
244 CompoundInsn->addOperand(Rt);
245 CompoundInsn->addOperand(R.getOperand(1));
246 break;
247
248 case Hexagon::C2_cmpgt:
249 LLVM_DEBUG(dbgs() << "CX: C2_cmpgt\n");
250 Rs = L.getOperand(1);
251 Rt = L.getOperand(2);
252
253 compoundOpcode = cmpgtBitOpcode[getCompoundOp(R)];
254 CompoundInsn = new (Context) MCInst;
255 CompoundInsn->setOpcode(compoundOpcode);
256 CompoundInsn->addOperand(Rs);
257 CompoundInsn->addOperand(Rt);
258 CompoundInsn->addOperand(R.getOperand(1));
259 break;
260
261 case Hexagon::C2_cmpgtu:
262 LLVM_DEBUG(dbgs() << "CX: C2_cmpgtu\n");
263 Rs = L.getOperand(1);
264 Rt = L.getOperand(2);
265
266 compoundOpcode = cmpgtuBitOpcode[getCompoundOp(R)];
267 CompoundInsn = new (Context) MCInst;
268 CompoundInsn->setOpcode(compoundOpcode);
269 CompoundInsn->addOperand(Rs);
270 CompoundInsn->addOperand(Rt);
271 CompoundInsn->addOperand(R.getOperand(1));
272 break;
273
274 case Hexagon::C2_cmpeqi:
275 LLVM_DEBUG(dbgs() << "CX: C2_cmpeqi\n");
276 Success = L.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
277 (void)Success;
278 assert(Success);
279 if (Value == -1)
280 compoundOpcode = cmpeqn1BitOpcode[getCompoundOp(R)];
281 else
282 compoundOpcode = cmpeqiBitOpcode[getCompoundOp(R)];
283
284 Rs = L.getOperand(1);
285 CompoundInsn = new (Context) MCInst;
286 CompoundInsn->setOpcode(compoundOpcode);
287 CompoundInsn->addOperand(Rs);
288 CompoundInsn->addOperand(L.getOperand(2));
289 CompoundInsn->addOperand(R.getOperand(1));
290 break;
291
292 case Hexagon::C2_cmpgti:
293 LLVM_DEBUG(dbgs() << "CX: C2_cmpgti\n");
294 Success = L.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
295 (void)Success;
296 assert(Success);
297 if (Value == -1)
298 compoundOpcode = cmpgtn1BitOpcode[getCompoundOp(R)];
299 else
300 compoundOpcode = cmpgtiBitOpcode[getCompoundOp(R)];
301
302 Rs = L.getOperand(1);
303 CompoundInsn = new (Context) MCInst;
304 CompoundInsn->setOpcode(compoundOpcode);
305 CompoundInsn->addOperand(Rs);
306 CompoundInsn->addOperand(L.getOperand(2));
307 CompoundInsn->addOperand(R.getOperand(1));
308 break;
309
310 case Hexagon::C2_cmpgtui:
311 LLVM_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 LLVM_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
335 /// Non-Symmetrical. See if these two instructions are fit for compound pair.
isOrderedCompoundPair(MCInst const & MIa,bool IsExtendedA,MCInst const & MIb,bool IsExtendedB)336 static bool isOrderedCompoundPair(MCInst const &MIa, bool IsExtendedA,
337 MCInst const &MIb, bool IsExtendedB) {
338 unsigned MIaG = getCompoundCandidateGroup(MIa, IsExtendedA);
339 unsigned MIbG = getCompoundCandidateGroup(MIb, IsExtendedB);
340 // We have two candidates - check that this is the same register
341 // we are talking about.
342 unsigned Opca = MIa.getOpcode();
343 if (MIaG == HexagonII::HCG_A && MIbG == HexagonII::HCG_C &&
344 (Opca == Hexagon::A2_tfr || Opca == Hexagon::A2_tfrsi))
345 return true;
346 return ((MIaG == HexagonII::HCG_A && MIbG == HexagonII::HCG_B) &&
347 (MIa.getOperand(0).getReg() == MIb.getOperand(0).getReg()));
348 }
349
lookForCompound(MCInstrInfo const & MCII,MCContext & Context,MCInst & MCI)350 static bool lookForCompound(MCInstrInfo const &MCII, MCContext &Context,
351 MCInst &MCI) {
352 assert(HexagonMCInstrInfo::isBundle(MCI));
353 bool JExtended = false;
354 for (MCInst::iterator J =
355 MCI.begin() + HexagonMCInstrInfo::bundleInstructionsOffset;
356 J != MCI.end(); ++J) {
357 MCInst const *JumpInst = J->getInst();
358 if (HexagonMCInstrInfo::isImmext(*JumpInst)) {
359 JExtended = true;
360 continue;
361 }
362 if (HexagonMCInstrInfo::getType(MCII, *JumpInst) == HexagonII::TypeJ) {
363 // Try to pair with another insn (B)undled with jump.
364 bool BExtended = false;
365 for (MCInst::iterator B =
366 MCI.begin() + HexagonMCInstrInfo::bundleInstructionsOffset;
367 B != MCI.end(); ++B) {
368 MCInst const *Inst = B->getInst();
369 if (JumpInst == Inst)
370 continue;
371 if (HexagonMCInstrInfo::isImmext(*Inst)) {
372 BExtended = true;
373 continue;
374 }
375 LLVM_DEBUG(dbgs() << "J,B: " << JumpInst->getOpcode() << ","
376 << Inst->getOpcode() << "\n");
377 if (isOrderedCompoundPair(*Inst, BExtended, *JumpInst, JExtended)) {
378 MCInst *CompoundInsn = getCompoundInsn(Context, *Inst, *JumpInst);
379 if (CompoundInsn) {
380 LLVM_DEBUG(dbgs() << "B: " << Inst->getOpcode() << ","
381 << JumpInst->getOpcode() << " Compounds to "
382 << CompoundInsn->getOpcode() << "\n");
383 J->setInst(CompoundInsn);
384 MCI.erase(B);
385 return true;
386 }
387 }
388 BExtended = false;
389 }
390 }
391 JExtended = false;
392 }
393 return false;
394 }
395
396 /// tryCompound - Given a bundle check for compound insns when one
397 /// is found update the contents fo the bundle with the compound insn.
398 /// If a compound instruction is found then the bundle will have one
399 /// additional slot.
tryCompound(MCInstrInfo const & MCII,MCSubtargetInfo const & STI,MCContext & Context,MCInst & MCI)400 void HexagonMCInstrInfo::tryCompound(MCInstrInfo const &MCII, MCSubtargetInfo const &STI,
401 MCContext &Context, MCInst &MCI) {
402 assert(HexagonMCInstrInfo::isBundle(MCI) &&
403 "Non-Bundle where Bundle expected");
404
405 // By definition a compound must have 2 insn.
406 if (MCI.size() < 2)
407 return;
408
409 bool StartedValid = llvm::HexagonMCShuffle(Context, false, MCII, STI, MCI);
410
411 // Create a vector, needed to keep the order of jump instructions.
412 MCInst CheckList(MCI);
413
414 // Look for compounds until none are found, only update the bundle when
415 // a compound is found.
416 while (lookForCompound(MCII, Context, CheckList)) {
417 // Keep the original bundle around in case the shuffle fails.
418 MCInst OriginalBundle(MCI);
419
420 // Need to update the bundle.
421 MCI = CheckList;
422
423 if (StartedValid &&
424 !llvm::HexagonMCShuffle(Context, false, MCII, STI, MCI)) {
425 LLVM_DEBUG(dbgs() << "Found ERROR\n");
426 MCI = OriginalBundle;
427 }
428 }
429 }
430