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/MCInst.h"
18 #include "llvm/Support/Debug.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include "llvm/Support/raw_ostream.h"
25 using namespace Hexagon
;
27 #define DEBUG_TYPE "hexagon-mccompound"
40 static const unsigned tstBitOpcode
[8] = {
41 J4_tstbit0_fp0_jump_nt
, J4_tstbit0_fp0_jump_t
, J4_tstbit0_fp1_jump_nt
,
42 J4_tstbit0_fp1_jump_t
, J4_tstbit0_tp0_jump_nt
, J4_tstbit0_tp0_jump_t
,
43 J4_tstbit0_tp1_jump_nt
, J4_tstbit0_tp1_jump_t
};
44 static const unsigned cmpeqBitOpcode
[8] = {
45 J4_cmpeq_fp0_jump_nt
, J4_cmpeq_fp0_jump_t
, J4_cmpeq_fp1_jump_nt
,
46 J4_cmpeq_fp1_jump_t
, J4_cmpeq_tp0_jump_nt
, J4_cmpeq_tp0_jump_t
,
47 J4_cmpeq_tp1_jump_nt
, J4_cmpeq_tp1_jump_t
};
48 static const unsigned cmpgtBitOpcode
[8] = {
49 J4_cmpgt_fp0_jump_nt
, J4_cmpgt_fp0_jump_t
, J4_cmpgt_fp1_jump_nt
,
50 J4_cmpgt_fp1_jump_t
, J4_cmpgt_tp0_jump_nt
, J4_cmpgt_tp0_jump_t
,
51 J4_cmpgt_tp1_jump_nt
, J4_cmpgt_tp1_jump_t
};
52 static const unsigned cmpgtuBitOpcode
[8] = {
53 J4_cmpgtu_fp0_jump_nt
, J4_cmpgtu_fp0_jump_t
, J4_cmpgtu_fp1_jump_nt
,
54 J4_cmpgtu_fp1_jump_t
, J4_cmpgtu_tp0_jump_nt
, J4_cmpgtu_tp0_jump_t
,
55 J4_cmpgtu_tp1_jump_nt
, J4_cmpgtu_tp1_jump_t
};
56 static const unsigned cmpeqiBitOpcode
[8] = {
57 J4_cmpeqi_fp0_jump_nt
, J4_cmpeqi_fp0_jump_t
, J4_cmpeqi_fp1_jump_nt
,
58 J4_cmpeqi_fp1_jump_t
, J4_cmpeqi_tp0_jump_nt
, J4_cmpeqi_tp0_jump_t
,
59 J4_cmpeqi_tp1_jump_nt
, J4_cmpeqi_tp1_jump_t
};
60 static const unsigned cmpgtiBitOpcode
[8] = {
61 J4_cmpgti_fp0_jump_nt
, J4_cmpgti_fp0_jump_t
, J4_cmpgti_fp1_jump_nt
,
62 J4_cmpgti_fp1_jump_t
, J4_cmpgti_tp0_jump_nt
, J4_cmpgti_tp0_jump_t
,
63 J4_cmpgti_tp1_jump_nt
, J4_cmpgti_tp1_jump_t
};
64 static const unsigned cmpgtuiBitOpcode
[8] = {
65 J4_cmpgtui_fp0_jump_nt
, J4_cmpgtui_fp0_jump_t
, J4_cmpgtui_fp1_jump_nt
,
66 J4_cmpgtui_fp1_jump_t
, J4_cmpgtui_tp0_jump_nt
, J4_cmpgtui_tp0_jump_t
,
67 J4_cmpgtui_tp1_jump_nt
, J4_cmpgtui_tp1_jump_t
};
68 static const unsigned cmpeqn1BitOpcode
[8] = {
69 J4_cmpeqn1_fp0_jump_nt
, J4_cmpeqn1_fp0_jump_t
, J4_cmpeqn1_fp1_jump_nt
,
70 J4_cmpeqn1_fp1_jump_t
, J4_cmpeqn1_tp0_jump_nt
, J4_cmpeqn1_tp0_jump_t
,
71 J4_cmpeqn1_tp1_jump_nt
, J4_cmpeqn1_tp1_jump_t
};
72 static const unsigned cmpgtn1BitOpcode
[8] = {
73 J4_cmpgtn1_fp0_jump_nt
, J4_cmpgtn1_fp0_jump_t
, J4_cmpgtn1_fp1_jump_nt
,
74 J4_cmpgtn1_fp1_jump_t
, J4_cmpgtn1_tp0_jump_nt
, J4_cmpgtn1_tp0_jump_t
,
75 J4_cmpgtn1_tp1_jump_nt
, J4_cmpgtn1_tp1_jump_t
,
78 // enum HexagonII::CompoundGroup
79 static unsigned getCompoundCandidateGroup(MCInst
const &MI
, bool IsExtended
) {
80 unsigned DstReg
, SrcReg
, Src1Reg
, Src2Reg
;
82 switch (MI
.getOpcode()) {
84 return HexagonII::HCG_None
;
87 // "p0=cmp.eq(Rs16,Rt16); if (p0.new) jump:nt #r9:2"
88 // "Rd16=#U6 ; jump #r9:2"
89 // "Rd16=Rs16 ; jump #r9:2"
91 case Hexagon::C2_cmpeq
:
92 case Hexagon::C2_cmpgt
:
93 case Hexagon::C2_cmpgtu
:
96 DstReg
= MI
.getOperand(0).getReg();
97 Src1Reg
= MI
.getOperand(1).getReg();
98 Src2Reg
= MI
.getOperand(2).getReg();
99 if ((Hexagon::P0
== DstReg
|| Hexagon::P1
== DstReg
) &&
100 HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg
) &&
101 HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg
))
102 return HexagonII::HCG_A
;
104 case Hexagon::C2_cmpeqi
:
105 case Hexagon::C2_cmpgti
:
106 case Hexagon::C2_cmpgtui
:
109 // P0 = cmp.eq(Rs,#u2)
110 DstReg
= MI
.getOperand(0).getReg();
111 SrcReg
= MI
.getOperand(1).getReg();
112 if ((Hexagon::P0
== DstReg
|| Hexagon::P1
== DstReg
) &&
113 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg
) &&
114 (HexagonMCInstrInfo::inRange
<5>(MI
, 2) ||
115 HexagonMCInstrInfo::minConstant(MI
, 2) == -1))
116 return HexagonII::HCG_A
;
118 case Hexagon::A2_tfr
:
122 DstReg
= MI
.getOperand(0).getReg();
123 SrcReg
= MI
.getOperand(1).getReg();
124 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg
) &&
125 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg
))
126 return HexagonII::HCG_A
;
128 case Hexagon::A2_tfrsi
:
132 DstReg
= MI
.getOperand(0).getReg();
133 if (HexagonMCInstrInfo::minConstant(MI
, 1) <= 63 &&
134 HexagonMCInstrInfo::minConstant(MI
, 1) >= 0 &&
135 HexagonMCInstrInfo::isIntRegForSubInst(DstReg
))
136 return HexagonII::HCG_A
;
138 case Hexagon::S2_tstbit_i
:
141 DstReg
= MI
.getOperand(0).getReg();
142 Src1Reg
= MI
.getOperand(1).getReg();
143 if ((Hexagon::P0
== DstReg
|| Hexagon::P1
== DstReg
) &&
144 HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg
) &&
145 HexagonMCInstrInfo::minConstant(MI
, 2) == 0)
146 return HexagonII::HCG_A
;
148 // The fact that .new form is used pretty much guarantees
149 // that predicate register will match. Nevertheless,
150 // there could be some false positives without additional
152 case Hexagon::J2_jumptnew
:
153 case Hexagon::J2_jumpfnew
:
154 case Hexagon::J2_jumptnewpt
:
155 case Hexagon::J2_jumpfnewpt
:
156 Src1Reg
= MI
.getOperand(0).getReg();
157 if (Hexagon::P0
== Src1Reg
|| Hexagon::P1
== Src1Reg
)
158 return HexagonII::HCG_B
;
160 // Transfer and jump:
161 // Rd=#U6 ; jump #r9:2
162 // Rd=Rs ; jump #r9:2
163 // Do not test for jump range here.
164 case Hexagon::J2_jump
:
165 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4
:
166 return HexagonII::HCG_C
;
170 return HexagonII::HCG_None
;
173 /// getCompoundOp - Return the index from 0-7 into the above opcode lists.
174 static unsigned getCompoundOp(MCInst
const &HMCI
) {
175 const MCOperand
&Predicate
= HMCI
.getOperand(0);
176 unsigned PredReg
= Predicate
.getReg();
178 assert((PredReg
== Hexagon::P0
) || (PredReg
== Hexagon::P1
) ||
179 (PredReg
== Hexagon::P2
) || (PredReg
== Hexagon::P3
));
181 switch (HMCI
.getOpcode()) {
183 llvm_unreachable("Expected match not found.\n");
185 case Hexagon::J2_jumpfnew
:
186 return (PredReg
== Hexagon::P0
) ? fp0_jump_nt
: fp1_jump_nt
;
187 case Hexagon::J2_jumpfnewpt
:
188 return (PredReg
== Hexagon::P0
) ? fp0_jump_t
: fp1_jump_t
;
189 case Hexagon::J2_jumptnew
:
190 return (PredReg
== Hexagon::P0
) ? tp0_jump_nt
: tp1_jump_nt
;
191 case Hexagon::J2_jumptnewpt
:
192 return (PredReg
== Hexagon::P0
) ? tp0_jump_t
: tp1_jump_t
;
196 static MCInst
*getCompoundInsn(MCContext
&Context
, MCInst
const &L
,
198 MCInst
*CompoundInsn
= nullptr;
199 unsigned compoundOpcode
;
204 switch (L
.getOpcode()) {
206 LLVM_DEBUG(dbgs() << "Possible compound ignored\n");
209 case Hexagon::A2_tfrsi
:
210 Rt
= L
.getOperand(0);
211 compoundOpcode
= J4_jumpseti
;
212 CompoundInsn
= new (Context
) MCInst
;
213 CompoundInsn
->setOpcode(compoundOpcode
);
215 CompoundInsn
->addOperand(Rt
);
216 CompoundInsn
->addOperand(L
.getOperand(1)); // Immediate
217 CompoundInsn
->addOperand(R
.getOperand(0)); // Jump target
220 case Hexagon::A2_tfr
:
221 Rt
= L
.getOperand(0);
222 Rs
= L
.getOperand(1);
224 compoundOpcode
= J4_jumpsetr
;
225 CompoundInsn
= new (Context
) MCInst
;
226 CompoundInsn
->setOpcode(compoundOpcode
);
227 CompoundInsn
->addOperand(Rt
);
228 CompoundInsn
->addOperand(Rs
);
229 CompoundInsn
->addOperand(R
.getOperand(0)); // Jump target.
233 case Hexagon::C2_cmpeq
:
234 LLVM_DEBUG(dbgs() << "CX: C2_cmpeq\n");
235 Rs
= L
.getOperand(1);
236 Rt
= L
.getOperand(2);
238 compoundOpcode
= cmpeqBitOpcode
[getCompoundOp(R
)];
239 CompoundInsn
= new (Context
) MCInst
;
240 CompoundInsn
->setOpcode(compoundOpcode
);
241 CompoundInsn
->addOperand(Rs
);
242 CompoundInsn
->addOperand(Rt
);
243 CompoundInsn
->addOperand(R
.getOperand(1));
246 case Hexagon::C2_cmpgt
:
247 LLVM_DEBUG(dbgs() << "CX: C2_cmpgt\n");
248 Rs
= L
.getOperand(1);
249 Rt
= L
.getOperand(2);
251 compoundOpcode
= cmpgtBitOpcode
[getCompoundOp(R
)];
252 CompoundInsn
= new (Context
) MCInst
;
253 CompoundInsn
->setOpcode(compoundOpcode
);
254 CompoundInsn
->addOperand(Rs
);
255 CompoundInsn
->addOperand(Rt
);
256 CompoundInsn
->addOperand(R
.getOperand(1));
259 case Hexagon::C2_cmpgtu
:
260 LLVM_DEBUG(dbgs() << "CX: C2_cmpgtu\n");
261 Rs
= L
.getOperand(1);
262 Rt
= L
.getOperand(2);
264 compoundOpcode
= cmpgtuBitOpcode
[getCompoundOp(R
)];
265 CompoundInsn
= new (Context
) MCInst
;
266 CompoundInsn
->setOpcode(compoundOpcode
);
267 CompoundInsn
->addOperand(Rs
);
268 CompoundInsn
->addOperand(Rt
);
269 CompoundInsn
->addOperand(R
.getOperand(1));
272 case Hexagon::C2_cmpeqi
:
273 LLVM_DEBUG(dbgs() << "CX: C2_cmpeqi\n");
274 Success
= L
.getOperand(2).getExpr()->evaluateAsAbsolute(Value
);
278 compoundOpcode
= cmpeqn1BitOpcode
[getCompoundOp(R
)];
280 compoundOpcode
= cmpeqiBitOpcode
[getCompoundOp(R
)];
282 Rs
= L
.getOperand(1);
283 CompoundInsn
= new (Context
) MCInst
;
284 CompoundInsn
->setOpcode(compoundOpcode
);
285 CompoundInsn
->addOperand(Rs
);
286 CompoundInsn
->addOperand(L
.getOperand(2));
287 CompoundInsn
->addOperand(R
.getOperand(1));
290 case Hexagon::C2_cmpgti
:
291 LLVM_DEBUG(dbgs() << "CX: C2_cmpgti\n");
292 Success
= L
.getOperand(2).getExpr()->evaluateAsAbsolute(Value
);
296 compoundOpcode
= cmpgtn1BitOpcode
[getCompoundOp(R
)];
298 compoundOpcode
= cmpgtiBitOpcode
[getCompoundOp(R
)];
300 Rs
= L
.getOperand(1);
301 CompoundInsn
= new (Context
) MCInst
;
302 CompoundInsn
->setOpcode(compoundOpcode
);
303 CompoundInsn
->addOperand(Rs
);
304 CompoundInsn
->addOperand(L
.getOperand(2));
305 CompoundInsn
->addOperand(R
.getOperand(1));
308 case Hexagon::C2_cmpgtui
:
309 LLVM_DEBUG(dbgs() << "CX: C2_cmpgtui\n");
310 Rs
= L
.getOperand(1);
311 compoundOpcode
= cmpgtuiBitOpcode
[getCompoundOp(R
)];
312 CompoundInsn
= new (Context
) MCInst
;
313 CompoundInsn
->setOpcode(compoundOpcode
);
314 CompoundInsn
->addOperand(Rs
);
315 CompoundInsn
->addOperand(L
.getOperand(2));
316 CompoundInsn
->addOperand(R
.getOperand(1));
319 case Hexagon::S2_tstbit_i
:
320 LLVM_DEBUG(dbgs() << "CX: S2_tstbit_i\n");
321 Rs
= L
.getOperand(1);
322 compoundOpcode
= tstBitOpcode
[getCompoundOp(R
)];
323 CompoundInsn
= new (Context
) MCInst
;
324 CompoundInsn
->setOpcode(compoundOpcode
);
325 CompoundInsn
->addOperand(Rs
);
326 CompoundInsn
->addOperand(R
.getOperand(1));
333 /// Non-Symmetrical. See if these two instructions are fit for compound pair.
334 static bool isOrderedCompoundPair(MCInst
const &MIa
, bool IsExtendedA
,
335 MCInst
const &MIb
, bool IsExtendedB
) {
336 unsigned MIaG
= getCompoundCandidateGroup(MIa
, IsExtendedA
);
337 unsigned MIbG
= getCompoundCandidateGroup(MIb
, IsExtendedB
);
338 // We have two candidates - check that this is the same register
339 // we are talking about.
340 unsigned Opca
= MIa
.getOpcode();
341 if (MIaG
== HexagonII::HCG_A
&& MIbG
== HexagonII::HCG_C
&&
342 (Opca
== Hexagon::A2_tfr
|| Opca
== Hexagon::A2_tfrsi
))
344 return ((MIaG
== HexagonII::HCG_A
&& MIbG
== HexagonII::HCG_B
) &&
345 (MIa
.getOperand(0).getReg() == MIb
.getOperand(0).getReg()));
348 static bool lookForCompound(MCInstrInfo
const &MCII
, MCContext
&Context
,
350 assert(HexagonMCInstrInfo::isBundle(MCI
));
351 bool JExtended
= false;
352 for (MCInst::iterator J
=
353 MCI
.begin() + HexagonMCInstrInfo::bundleInstructionsOffset
;
354 J
!= MCI
.end(); ++J
) {
355 MCInst
const *JumpInst
= J
->getInst();
356 if (HexagonMCInstrInfo::isImmext(*JumpInst
)) {
360 if (HexagonMCInstrInfo::getType(MCII
, *JumpInst
) == HexagonII::TypeJ
) {
361 // Try to pair with another insn (B)undled with jump.
362 bool BExtended
= false;
363 for (MCInst::iterator B
=
364 MCI
.begin() + HexagonMCInstrInfo::bundleInstructionsOffset
;
365 B
!= MCI
.end(); ++B
) {
366 MCInst
const *Inst
= B
->getInst();
367 if (JumpInst
== Inst
)
369 if (HexagonMCInstrInfo::isImmext(*Inst
)) {
373 LLVM_DEBUG(dbgs() << "J,B: " << JumpInst
->getOpcode() << ","
374 << Inst
->getOpcode() << "\n");
375 if (isOrderedCompoundPair(*Inst
, BExtended
, *JumpInst
, JExtended
)) {
376 MCInst
*CompoundInsn
= getCompoundInsn(Context
, *Inst
, *JumpInst
);
378 LLVM_DEBUG(dbgs() << "B: " << Inst
->getOpcode() << ","
379 << JumpInst
->getOpcode() << " Compounds to "
380 << CompoundInsn
->getOpcode() << "\n");
381 J
->setInst(CompoundInsn
);
394 /// tryCompound - Given a bundle check for compound insns when one
395 /// is found update the contents fo the bundle with the compound insn.
396 /// If a compound instruction is found then the bundle will have one
398 void HexagonMCInstrInfo::tryCompound(MCInstrInfo
const &MCII
, MCSubtargetInfo
const &STI
,
399 MCContext
&Context
, MCInst
&MCI
) {
400 assert(HexagonMCInstrInfo::isBundle(MCI
) &&
401 "Non-Bundle where Bundle expected");
403 // By definition a compound must have 2 insn.
407 bool StartedValid
= llvm::HexagonMCShuffle(Context
, false, MCII
, STI
, MCI
);
409 // Create a vector, needed to keep the order of jump instructions.
410 MCInst
CheckList(MCI
);
412 // Look for compounds until none are found, only update the bundle when
413 // a compound is found.
414 while (lookForCompound(MCII
, Context
, CheckList
)) {
415 // Keep the original bundle around in case the shuffle fails.
416 MCInst
OriginalBundle(MCI
);
418 // Need to update the bundle.
422 !llvm::HexagonMCShuffle(Context
, false, MCII
, STI
, MCI
)) {
423 LLVM_DEBUG(dbgs() << "Found ERROR\n");
424 MCI
= OriginalBundle
;