1 //=== HexagonMCCompound.cpp - Hexagon Compound checker -------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file is looks at a packet and tries to form compound insns
11 //===----------------------------------------------------------------------===//
13 #include "MCTargetDesc/HexagonBaseInfo.h"
14 #include "MCTargetDesc/HexagonMCInstrInfo.h"
15 #include "MCTargetDesc/HexagonMCShuffler.h"
16 #include "llvm/MC/MCContext.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/Support/Debug.h"
20 #include "llvm/Support/ErrorHandling.h"
21 #include "llvm/Support/raw_ostream.h"
26 using namespace Hexagon
;
28 #define DEBUG_TYPE "hexagon-mccompound"
41 static const unsigned tstBitOpcode
[8] = {
42 J4_tstbit0_fp0_jump_nt
, J4_tstbit0_fp0_jump_t
, J4_tstbit0_fp1_jump_nt
,
43 J4_tstbit0_fp1_jump_t
, J4_tstbit0_tp0_jump_nt
, J4_tstbit0_tp0_jump_t
,
44 J4_tstbit0_tp1_jump_nt
, J4_tstbit0_tp1_jump_t
};
45 static const unsigned cmpeqBitOpcode
[8] = {
46 J4_cmpeq_fp0_jump_nt
, J4_cmpeq_fp0_jump_t
, J4_cmpeq_fp1_jump_nt
,
47 J4_cmpeq_fp1_jump_t
, J4_cmpeq_tp0_jump_nt
, J4_cmpeq_tp0_jump_t
,
48 J4_cmpeq_tp1_jump_nt
, J4_cmpeq_tp1_jump_t
};
49 static const unsigned cmpgtBitOpcode
[8] = {
50 J4_cmpgt_fp0_jump_nt
, J4_cmpgt_fp0_jump_t
, J4_cmpgt_fp1_jump_nt
,
51 J4_cmpgt_fp1_jump_t
, J4_cmpgt_tp0_jump_nt
, J4_cmpgt_tp0_jump_t
,
52 J4_cmpgt_tp1_jump_nt
, J4_cmpgt_tp1_jump_t
};
53 static const unsigned cmpgtuBitOpcode
[8] = {
54 J4_cmpgtu_fp0_jump_nt
, J4_cmpgtu_fp0_jump_t
, J4_cmpgtu_fp1_jump_nt
,
55 J4_cmpgtu_fp1_jump_t
, J4_cmpgtu_tp0_jump_nt
, J4_cmpgtu_tp0_jump_t
,
56 J4_cmpgtu_tp1_jump_nt
, J4_cmpgtu_tp1_jump_t
};
57 static const unsigned cmpeqiBitOpcode
[8] = {
58 J4_cmpeqi_fp0_jump_nt
, J4_cmpeqi_fp0_jump_t
, J4_cmpeqi_fp1_jump_nt
,
59 J4_cmpeqi_fp1_jump_t
, J4_cmpeqi_tp0_jump_nt
, J4_cmpeqi_tp0_jump_t
,
60 J4_cmpeqi_tp1_jump_nt
, J4_cmpeqi_tp1_jump_t
};
61 static const unsigned cmpgtiBitOpcode
[8] = {
62 J4_cmpgti_fp0_jump_nt
, J4_cmpgti_fp0_jump_t
, J4_cmpgti_fp1_jump_nt
,
63 J4_cmpgti_fp1_jump_t
, J4_cmpgti_tp0_jump_nt
, J4_cmpgti_tp0_jump_t
,
64 J4_cmpgti_tp1_jump_nt
, J4_cmpgti_tp1_jump_t
};
65 static const unsigned cmpgtuiBitOpcode
[8] = {
66 J4_cmpgtui_fp0_jump_nt
, J4_cmpgtui_fp0_jump_t
, J4_cmpgtui_fp1_jump_nt
,
67 J4_cmpgtui_fp1_jump_t
, J4_cmpgtui_tp0_jump_nt
, J4_cmpgtui_tp0_jump_t
,
68 J4_cmpgtui_tp1_jump_nt
, J4_cmpgtui_tp1_jump_t
};
69 static const unsigned cmpeqn1BitOpcode
[8] = {
70 J4_cmpeqn1_fp0_jump_nt
, J4_cmpeqn1_fp0_jump_t
, J4_cmpeqn1_fp1_jump_nt
,
71 J4_cmpeqn1_fp1_jump_t
, J4_cmpeqn1_tp0_jump_nt
, J4_cmpeqn1_tp0_jump_t
,
72 J4_cmpeqn1_tp1_jump_nt
, J4_cmpeqn1_tp1_jump_t
};
73 static const unsigned cmpgtn1BitOpcode
[8] = {
74 J4_cmpgtn1_fp0_jump_nt
, J4_cmpgtn1_fp0_jump_t
, J4_cmpgtn1_fp1_jump_nt
,
75 J4_cmpgtn1_fp1_jump_t
, J4_cmpgtn1_tp0_jump_nt
, J4_cmpgtn1_tp0_jump_t
,
76 J4_cmpgtn1_tp1_jump_nt
, J4_cmpgtn1_tp1_jump_t
,
79 // enum HexagonII::CompoundGroup
80 static unsigned getCompoundCandidateGroup(MCInst
const &MI
, bool IsExtended
) {
81 unsigned DstReg
, SrcReg
, Src1Reg
, Src2Reg
;
83 switch (MI
.getOpcode()) {
85 return HexagonII::HCG_None
;
88 // "p0=cmp.eq(Rs16,Rt16); if (p0.new) jump:nt #r9:2"
89 // "Rd16=#U6 ; jump #r9:2"
90 // "Rd16=Rs16 ; jump #r9:2"
92 case Hexagon::C2_cmpeq
:
93 case Hexagon::C2_cmpgt
:
94 case Hexagon::C2_cmpgtu
:
96 return HexagonII::HCG_None
;
97 DstReg
= MI
.getOperand(0).getReg();
98 Src1Reg
= MI
.getOperand(1).getReg();
99 Src2Reg
= MI
.getOperand(2).getReg();
100 if ((Hexagon::P0
== DstReg
|| Hexagon::P1
== DstReg
) &&
101 HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg
) &&
102 HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg
))
103 return HexagonII::HCG_A
;
105 case Hexagon::C2_cmpeqi
:
106 case Hexagon::C2_cmpgti
:
107 case Hexagon::C2_cmpgtui
:
109 return HexagonII::HCG_None
;
110 // P0 = cmp.eq(Rs,#u2)
111 DstReg
= MI
.getOperand(0).getReg();
112 SrcReg
= MI
.getOperand(1).getReg();
113 if ((Hexagon::P0
== DstReg
|| Hexagon::P1
== DstReg
) &&
114 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg
) &&
115 (HexagonMCInstrInfo::inRange
<5>(MI
, 2) ||
116 HexagonMCInstrInfo::minConstant(MI
, 2) == -1))
117 return HexagonII::HCG_A
;
119 case Hexagon::A2_tfr
:
121 return HexagonII::HCG_None
;
123 DstReg
= MI
.getOperand(0).getReg();
124 SrcReg
= MI
.getOperand(1).getReg();
125 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg
) &&
126 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg
))
127 return HexagonII::HCG_A
;
129 case Hexagon::A2_tfrsi
:
131 return HexagonII::HCG_None
;
133 DstReg
= MI
.getOperand(0).getReg();
134 if (HexagonMCInstrInfo::minConstant(MI
, 1) <= 63 &&
135 HexagonMCInstrInfo::minConstant(MI
, 1) >= 0 &&
136 HexagonMCInstrInfo::isIntRegForSubInst(DstReg
))
137 return HexagonII::HCG_A
;
139 case Hexagon::S2_tstbit_i
:
141 return HexagonII::HCG_None
;
142 DstReg
= MI
.getOperand(0).getReg();
143 Src1Reg
= MI
.getOperand(1).getReg();
144 if ((Hexagon::P0
== DstReg
|| Hexagon::P1
== DstReg
) &&
145 HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg
) &&
146 HexagonMCInstrInfo::minConstant(MI
, 2) == 0)
147 return HexagonII::HCG_A
;
149 // The fact that .new form is used pretty much guarantees
150 // that predicate register will match. Nevertheless,
151 // there could be some false positives without additional
153 case Hexagon::J2_jumptnew
:
154 case Hexagon::J2_jumpfnew
:
155 case Hexagon::J2_jumptnewpt
:
156 case Hexagon::J2_jumpfnewpt
:
157 Src1Reg
= MI
.getOperand(0).getReg();
158 if (Hexagon::P0
== Src1Reg
|| Hexagon::P1
== Src1Reg
)
159 return HexagonII::HCG_B
;
161 // Transfer and jump:
162 // Rd=#U6 ; jump #r9:2
163 // Rd=Rs ; jump #r9:2
164 // Do not test for jump range here.
165 case Hexagon::J2_jump
:
166 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4
:
167 return HexagonII::HCG_C
;
171 return HexagonII::HCG_None
;
174 /// getCompoundOp - Return the index from 0-7 into the above opcode lists.
175 static unsigned getCompoundOp(MCInst
const &HMCI
) {
176 const MCOperand
&Predicate
= HMCI
.getOperand(0);
177 unsigned PredReg
= Predicate
.getReg();
179 assert((PredReg
== Hexagon::P0
) || (PredReg
== Hexagon::P1
) ||
180 (PredReg
== Hexagon::P2
) || (PredReg
== Hexagon::P3
));
182 switch (HMCI
.getOpcode()) {
184 llvm_unreachable("Expected match not found.\n");
186 case Hexagon::J2_jumpfnew
:
187 return (PredReg
== Hexagon::P0
) ? fp0_jump_nt
: fp1_jump_nt
;
188 case Hexagon::J2_jumpfnewpt
:
189 return (PredReg
== Hexagon::P0
) ? fp0_jump_t
: fp1_jump_t
;
190 case Hexagon::J2_jumptnew
:
191 return (PredReg
== Hexagon::P0
) ? tp0_jump_nt
: tp1_jump_nt
;
192 case Hexagon::J2_jumptnewpt
:
193 return (PredReg
== Hexagon::P0
) ? tp0_jump_t
: tp1_jump_t
;
197 static MCInst
*getCompoundInsn(MCContext
&Context
, MCInst
const &L
,
199 MCInst
*CompoundInsn
= nullptr;
200 unsigned compoundOpcode
;
205 switch (L
.getOpcode()) {
207 LLVM_DEBUG(dbgs() << "Possible compound ignored\n");
210 case Hexagon::A2_tfrsi
:
211 Rt
= L
.getOperand(0);
212 compoundOpcode
= J4_jumpseti
;
213 CompoundInsn
= Context
.createMCInst();
214 CompoundInsn
->setOpcode(compoundOpcode
);
216 CompoundInsn
->addOperand(Rt
);
217 CompoundInsn
->addOperand(L
.getOperand(1)); // Immediate
218 CompoundInsn
->addOperand(R
.getOperand(0)); // Jump target
221 case Hexagon::A2_tfr
:
222 Rt
= L
.getOperand(0);
223 Rs
= L
.getOperand(1);
225 compoundOpcode
= J4_jumpsetr
;
226 CompoundInsn
= Context
.createMCInst();
227 CompoundInsn
->setOpcode(compoundOpcode
);
228 CompoundInsn
->addOperand(Rt
);
229 CompoundInsn
->addOperand(Rs
);
230 CompoundInsn
->addOperand(R
.getOperand(0)); // Jump target.
234 case Hexagon::C2_cmpeq
:
235 LLVM_DEBUG(dbgs() << "CX: C2_cmpeq\n");
236 Rs
= L
.getOperand(1);
237 Rt
= L
.getOperand(2);
239 compoundOpcode
= cmpeqBitOpcode
[getCompoundOp(R
)];
240 CompoundInsn
= Context
.createMCInst();
241 CompoundInsn
->setOpcode(compoundOpcode
);
242 CompoundInsn
->addOperand(Rs
);
243 CompoundInsn
->addOperand(Rt
);
244 CompoundInsn
->addOperand(R
.getOperand(1));
247 case Hexagon::C2_cmpgt
:
248 LLVM_DEBUG(dbgs() << "CX: C2_cmpgt\n");
249 Rs
= L
.getOperand(1);
250 Rt
= L
.getOperand(2);
252 compoundOpcode
= cmpgtBitOpcode
[getCompoundOp(R
)];
253 CompoundInsn
= Context
.createMCInst();
254 CompoundInsn
->setOpcode(compoundOpcode
);
255 CompoundInsn
->addOperand(Rs
);
256 CompoundInsn
->addOperand(Rt
);
257 CompoundInsn
->addOperand(R
.getOperand(1));
260 case Hexagon::C2_cmpgtu
:
261 LLVM_DEBUG(dbgs() << "CX: C2_cmpgtu\n");
262 Rs
= L
.getOperand(1);
263 Rt
= L
.getOperand(2);
265 compoundOpcode
= cmpgtuBitOpcode
[getCompoundOp(R
)];
266 CompoundInsn
= Context
.createMCInst();
267 CompoundInsn
->setOpcode(compoundOpcode
);
268 CompoundInsn
->addOperand(Rs
);
269 CompoundInsn
->addOperand(Rt
);
270 CompoundInsn
->addOperand(R
.getOperand(1));
273 case Hexagon::C2_cmpeqi
:
274 LLVM_DEBUG(dbgs() << "CX: C2_cmpeqi\n");
275 Success
= L
.getOperand(2).getExpr()->evaluateAsAbsolute(Value
);
279 compoundOpcode
= cmpeqn1BitOpcode
[getCompoundOp(R
)];
281 compoundOpcode
= cmpeqiBitOpcode
[getCompoundOp(R
)];
283 Rs
= L
.getOperand(1);
284 CompoundInsn
= Context
.createMCInst();
285 CompoundInsn
->setOpcode(compoundOpcode
);
286 CompoundInsn
->addOperand(Rs
);
287 CompoundInsn
->addOperand(L
.getOperand(2));
288 CompoundInsn
->addOperand(R
.getOperand(1));
291 case Hexagon::C2_cmpgti
:
292 LLVM_DEBUG(dbgs() << "CX: C2_cmpgti\n");
293 Success
= L
.getOperand(2).getExpr()->evaluateAsAbsolute(Value
);
297 compoundOpcode
= cmpgtn1BitOpcode
[getCompoundOp(R
)];
299 compoundOpcode
= cmpgtiBitOpcode
[getCompoundOp(R
)];
301 Rs
= L
.getOperand(1);
302 CompoundInsn
= Context
.createMCInst();
303 CompoundInsn
->setOpcode(compoundOpcode
);
304 CompoundInsn
->addOperand(Rs
);
305 CompoundInsn
->addOperand(L
.getOperand(2));
306 CompoundInsn
->addOperand(R
.getOperand(1));
309 case Hexagon::C2_cmpgtui
:
310 LLVM_DEBUG(dbgs() << "CX: C2_cmpgtui\n");
311 Rs
= L
.getOperand(1);
312 compoundOpcode
= cmpgtuiBitOpcode
[getCompoundOp(R
)];
313 CompoundInsn
= Context
.createMCInst();
314 CompoundInsn
->setOpcode(compoundOpcode
);
315 CompoundInsn
->addOperand(Rs
);
316 CompoundInsn
->addOperand(L
.getOperand(2));
317 CompoundInsn
->addOperand(R
.getOperand(1));
320 case Hexagon::S2_tstbit_i
:
321 LLVM_DEBUG(dbgs() << "CX: S2_tstbit_i\n");
322 Rs
= L
.getOperand(1);
323 compoundOpcode
= tstBitOpcode
[getCompoundOp(R
)];
324 CompoundInsn
= Context
.createMCInst();
325 CompoundInsn
->setOpcode(compoundOpcode
);
326 CompoundInsn
->addOperand(Rs
);
327 CompoundInsn
->addOperand(R
.getOperand(1));
334 /// Non-Symmetrical. See if these two instructions are fit for compound pair.
335 static bool isOrderedCompoundPair(MCInst
const &MIa
, bool IsExtendedA
,
336 MCInst
const &MIb
, bool IsExtendedB
) {
337 unsigned MIaG
= getCompoundCandidateGroup(MIa
, IsExtendedA
);
338 unsigned MIbG
= getCompoundCandidateGroup(MIb
, IsExtendedB
);
339 // We have two candidates - check that this is the same register
340 // we are talking about.
341 unsigned Opca
= MIa
.getOpcode();
342 if (MIaG
== HexagonII::HCG_A
&& MIbG
== HexagonII::HCG_C
&&
343 (Opca
== Hexagon::A2_tfr
|| Opca
== Hexagon::A2_tfrsi
))
345 return ((MIaG
== HexagonII::HCG_A
&& MIbG
== HexagonII::HCG_B
) &&
346 (MIa
.getOperand(0).getReg() == MIb
.getOperand(0).getReg()));
349 static bool lookForCompound(MCInstrInfo
const &MCII
, MCContext
&Context
,
351 assert(HexagonMCInstrInfo::isBundle(MCI
));
352 bool JExtended
= false;
353 for (MCInst::iterator J
=
354 MCI
.begin() + HexagonMCInstrInfo::bundleInstructionsOffset
;
355 J
!= MCI
.end(); ++J
) {
356 MCInst
const *JumpInst
= J
->getInst();
357 if (HexagonMCInstrInfo::isImmext(*JumpInst
)) {
361 if (HexagonMCInstrInfo::getType(MCII
, *JumpInst
) == HexagonII::TypeJ
) {
362 // Try to pair with another insn (B)undled with jump.
363 bool BExtended
= false;
364 for (MCInst::iterator B
=
365 MCI
.begin() + HexagonMCInstrInfo::bundleInstructionsOffset
;
366 B
!= MCI
.end(); ++B
) {
367 MCInst
const *Inst
= B
->getInst();
368 if (JumpInst
== Inst
)
370 if (HexagonMCInstrInfo::isImmext(*Inst
)) {
374 LLVM_DEBUG(dbgs() << "J,B: " << JumpInst
->getOpcode() << ","
375 << Inst
->getOpcode() << "\n");
376 if (isOrderedCompoundPair(*Inst
, BExtended
, *JumpInst
, JExtended
)) {
377 MCInst
*CompoundInsn
= getCompoundInsn(Context
, *Inst
, *JumpInst
);
379 LLVM_DEBUG(dbgs() << "B: " << Inst
->getOpcode() << ","
380 << JumpInst
->getOpcode() << " Compounds to "
381 << CompoundInsn
->getOpcode() << "\n");
382 J
->setInst(CompoundInsn
);
395 /// tryCompound - Given a bundle check for compound insns when one
396 /// is found update the contents fo the bundle with the compound insn.
397 /// If a compound instruction is found then the bundle will have one
399 void HexagonMCInstrInfo::tryCompound(MCInstrInfo
const &MCII
, MCSubtargetInfo
const &STI
,
400 MCContext
&Context
, MCInst
&MCI
) {
401 assert(HexagonMCInstrInfo::isBundle(MCI
) &&
402 "Non-Bundle where Bundle expected");
404 // By definition a compound must have 2 insn.
408 bool StartedValid
= llvm::HexagonMCShuffle(Context
, false, MCII
, STI
, MCI
);
410 // Create a vector, needed to keep the order of jump instructions.
411 MCInst
CheckList(MCI
);
413 // Look for compounds until none are found, only update the bundle when
414 // a compound is found.
415 while (lookForCompound(MCII
, Context
, CheckList
)) {
416 // Keep the original bundle around in case the shuffle fails.
417 MCInst
OriginalBundle(MCI
);
419 // Need to update the bundle.
423 !llvm::HexagonMCShuffle(Context
, false, MCII
, STI
, MCI
)) {
424 LLVM_DEBUG(dbgs() << "Found ERROR\n");
425 MCI
= OriginalBundle
;