1 //===- HexagonMCDuplexInfo.cpp - Instruction bundle checking --------------===//
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 implements duplexing of instructions to reduce code size
11 //===----------------------------------------------------------------------===//
13 #include "HexagonMCExpr.h"
14 #include "MCTargetDesc/HexagonBaseInfo.h"
15 #include "MCTargetDesc/HexagonMCInstrInfo.h"
16 #include "MCTargetDesc/HexagonMCTargetDesc.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/MC/MCSubtargetInfo.h"
19 #include "llvm/Support/Debug.h"
20 #include "llvm/Support/ErrorHandling.h"
21 #include "llvm/Support/MathExtras.h"
22 #include "llvm/Support/raw_ostream.h"
30 using namespace Hexagon
;
32 #define DEBUG_TYPE "hexagon-mcduplex-info"
34 // pair table of subInstructions with opcodes
35 static const std::pair
<unsigned, unsigned> opcodeData
[] = {
36 std::make_pair((unsigned)SA1_addi
, 0),
37 std::make_pair((unsigned)SA1_addrx
, 6144),
38 std::make_pair((unsigned)SA1_addsp
, 3072),
39 std::make_pair((unsigned)SA1_and1
, 4608),
40 std::make_pair((unsigned)SA1_clrf
, 6768),
41 std::make_pair((unsigned)SA1_clrfnew
, 6736),
42 std::make_pair((unsigned)SA1_clrt
, 6752),
43 std::make_pair((unsigned)SA1_clrtnew
, 6720),
44 std::make_pair((unsigned)SA1_cmpeqi
, 6400),
45 std::make_pair((unsigned)SA1_combine0i
, 7168),
46 std::make_pair((unsigned)SA1_combine1i
, 7176),
47 std::make_pair((unsigned)SA1_combine2i
, 7184),
48 std::make_pair((unsigned)SA1_combine3i
, 7192),
49 std::make_pair((unsigned)SA1_combinerz
, 7432),
50 std::make_pair((unsigned)SA1_combinezr
, 7424),
51 std::make_pair((unsigned)SA1_dec
, 4864),
52 std::make_pair((unsigned)SA1_inc
, 4352),
53 std::make_pair((unsigned)SA1_seti
, 2048),
54 std::make_pair((unsigned)SA1_setin1
, 6656),
55 std::make_pair((unsigned)SA1_sxtb
, 5376),
56 std::make_pair((unsigned)SA1_sxth
, 5120),
57 std::make_pair((unsigned)SA1_tfr
, 4096),
58 std::make_pair((unsigned)SA1_zxtb
, 5888),
59 std::make_pair((unsigned)SA1_zxth
, 5632),
60 std::make_pair((unsigned)SL1_loadri_io
, 0),
61 std::make_pair((unsigned)SL1_loadrub_io
, 4096),
62 std::make_pair((unsigned)SL2_deallocframe
, 7936),
63 std::make_pair((unsigned)SL2_jumpr31
, 8128),
64 std::make_pair((unsigned)SL2_jumpr31_f
, 8133),
65 std::make_pair((unsigned)SL2_jumpr31_fnew
, 8135),
66 std::make_pair((unsigned)SL2_jumpr31_t
, 8132),
67 std::make_pair((unsigned)SL2_jumpr31_tnew
, 8134),
68 std::make_pair((unsigned)SL2_loadrb_io
, 4096),
69 std::make_pair((unsigned)SL2_loadrd_sp
, 7680),
70 std::make_pair((unsigned)SL2_loadrh_io
, 0),
71 std::make_pair((unsigned)SL2_loadri_sp
, 7168),
72 std::make_pair((unsigned)SL2_loadruh_io
, 2048),
73 std::make_pair((unsigned)SL2_return
, 8000),
74 std::make_pair((unsigned)SL2_return_f
, 8005),
75 std::make_pair((unsigned)SL2_return_fnew
, 8007),
76 std::make_pair((unsigned)SL2_return_t
, 8004),
77 std::make_pair((unsigned)SL2_return_tnew
, 8006),
78 std::make_pair((unsigned)SS1_storeb_io
, 4096),
79 std::make_pair((unsigned)SS1_storew_io
, 0),
80 std::make_pair((unsigned)SS2_allocframe
, 7168),
81 std::make_pair((unsigned)SS2_storebi0
, 4608),
82 std::make_pair((unsigned)SS2_storebi1
, 4864),
83 std::make_pair((unsigned)SS2_stored_sp
, 2560),
84 std::make_pair((unsigned)SS2_storeh_io
, 0),
85 std::make_pair((unsigned)SS2_storew_sp
, 2048),
86 std::make_pair((unsigned)SS2_storewi0
, 4096),
87 std::make_pair((unsigned)SS2_storewi1
, 4352)};
89 bool HexagonMCInstrInfo::isDuplexPairMatch(unsigned Ga
, unsigned Gb
) {
91 case HexagonII::HSIG_None
:
94 case HexagonII::HSIG_L1
:
95 return (Gb
== HexagonII::HSIG_L1
|| Gb
== HexagonII::HSIG_A
);
96 case HexagonII::HSIG_L2
:
97 return (Gb
== HexagonII::HSIG_L1
|| Gb
== HexagonII::HSIG_L2
||
98 Gb
== HexagonII::HSIG_A
);
99 case HexagonII::HSIG_S1
:
100 return (Gb
== HexagonII::HSIG_L1
|| Gb
== HexagonII::HSIG_L2
||
101 Gb
== HexagonII::HSIG_S1
|| Gb
== HexagonII::HSIG_A
);
102 case HexagonII::HSIG_S2
:
103 return (Gb
== HexagonII::HSIG_L1
|| Gb
== HexagonII::HSIG_L2
||
104 Gb
== HexagonII::HSIG_S1
|| Gb
== HexagonII::HSIG_S2
||
105 Gb
== HexagonII::HSIG_A
);
106 case HexagonII::HSIG_A
:
107 return (Gb
== HexagonII::HSIG_A
);
108 case HexagonII::HSIG_Compound
:
109 return (Gb
== HexagonII::HSIG_Compound
);
114 unsigned HexagonMCInstrInfo::iClassOfDuplexPair(unsigned Ga
, unsigned Gb
) {
116 case HexagonII::HSIG_None
:
119 case HexagonII::HSIG_L1
:
123 case HexagonII::HSIG_L1
:
125 case HexagonII::HSIG_A
:
129 case HexagonII::HSIG_L2
:
133 case HexagonII::HSIG_L1
:
135 case HexagonII::HSIG_L2
:
137 case HexagonII::HSIG_A
:
141 case HexagonII::HSIG_S1
:
145 case HexagonII::HSIG_L1
:
147 case HexagonII::HSIG_L2
:
149 case HexagonII::HSIG_S1
:
151 case HexagonII::HSIG_A
:
155 case HexagonII::HSIG_S2
:
159 case HexagonII::HSIG_L1
:
161 case HexagonII::HSIG_L2
:
163 case HexagonII::HSIG_S1
:
165 case HexagonII::HSIG_S2
:
167 case HexagonII::HSIG_A
:
171 case HexagonII::HSIG_A
:
175 case HexagonII::HSIG_A
:
179 case HexagonII::HSIG_Compound
:
181 case HexagonII::HSIG_Compound
:
189 unsigned HexagonMCInstrInfo::getDuplexCandidateGroup(MCInst
const &MCI
) {
190 unsigned DstReg
, PredReg
, SrcReg
, Src1Reg
, Src2Reg
;
192 switch (MCI
.getOpcode()) {
194 return HexagonII::HSIG_None
;
198 // Rd = memw(Rs+#u4:2)
199 // Rd = memub(Rs+#u4:0)
200 case Hexagon::L2_loadri_io
:
201 DstReg
= MCI
.getOperand(0).getReg();
202 SrcReg
= MCI
.getOperand(1).getReg();
203 // Special case this one from Group L2.
204 // Rd = memw(r29+#u5:2)
205 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg
)) {
206 if (HexagonMCInstrInfo::isIntReg(SrcReg
) &&
207 Hexagon::R29
== SrcReg
&& inRange
<5, 2>(MCI
, 2)) {
208 return HexagonII::HSIG_L2
;
210 // Rd = memw(Rs+#u4:2)
211 if (HexagonMCInstrInfo::isIntRegForSubInst(SrcReg
) &&
212 inRange
<4, 2>(MCI
, 2)) {
213 return HexagonII::HSIG_L1
;
217 case Hexagon::L2_loadrub_io
:
218 // Rd = memub(Rs+#u4:0)
219 DstReg
= MCI
.getOperand(0).getReg();
220 SrcReg
= MCI
.getOperand(1).getReg();
221 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg
) &&
222 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg
) &&
223 inRange
<4>(MCI
, 2)) {
224 return HexagonII::HSIG_L1
;
230 // Rd = memh/memuh(Rs+#u3:1)
231 // Rd = memb(Rs+#u3:0)
232 // Rd = memw(r29+#u5:2) - Handled above.
233 // Rdd = memd(r29+#u5:3)
235 // [if ([!]p0[.new])] dealloc_return
236 // [if ([!]p0[.new])] jumpr r31
237 case Hexagon::L2_loadrh_io
:
238 case Hexagon::L2_loadruh_io
:
239 // Rd = memh/memuh(Rs+#u3:1)
240 DstReg
= MCI
.getOperand(0).getReg();
241 SrcReg
= MCI
.getOperand(1).getReg();
242 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg
) &&
243 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg
) &&
244 inRange
<3, 1>(MCI
, 2)) {
245 return HexagonII::HSIG_L2
;
248 case Hexagon::L2_loadrb_io
:
249 // Rd = memb(Rs+#u3:0)
250 DstReg
= MCI
.getOperand(0).getReg();
251 SrcReg
= MCI
.getOperand(1).getReg();
252 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg
) &&
253 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg
) &&
254 inRange
<3>(MCI
, 2)) {
255 return HexagonII::HSIG_L2
;
258 case Hexagon::L2_loadrd_io
:
259 // Rdd = memd(r29+#u5:3)
260 DstReg
= MCI
.getOperand(0).getReg();
261 SrcReg
= MCI
.getOperand(1).getReg();
262 if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg
) &&
263 HexagonMCInstrInfo::isIntReg(SrcReg
) && Hexagon::R29
== SrcReg
&&
264 inRange
<5, 3>(MCI
, 2)) {
265 return HexagonII::HSIG_L2
;
269 case Hexagon::L4_return
:
270 case Hexagon::L2_deallocframe
:
271 return HexagonII::HSIG_L2
;
273 case Hexagon::EH_RETURN_JMPR
:
274 case Hexagon::J2_jumpr
:
275 case Hexagon::PS_jmpret
:
277 // Actual form JMPR implicit-def %pc, implicit %r31, implicit internal %r0.
278 DstReg
= MCI
.getOperand(0).getReg();
279 if (Hexagon::R31
== DstReg
)
280 return HexagonII::HSIG_L2
;
283 case Hexagon::J2_jumprt
:
284 case Hexagon::J2_jumprf
:
285 case Hexagon::J2_jumprtnew
:
286 case Hexagon::J2_jumprfnew
:
287 case Hexagon::J2_jumprtnewpt
:
288 case Hexagon::J2_jumprfnewpt
:
289 case Hexagon::PS_jmprett
:
290 case Hexagon::PS_jmpretf
:
291 case Hexagon::PS_jmprettnew
:
292 case Hexagon::PS_jmpretfnew
:
293 case Hexagon::PS_jmprettnewpt
:
294 case Hexagon::PS_jmpretfnewpt
:
295 DstReg
= MCI
.getOperand(1).getReg();
296 SrcReg
= MCI
.getOperand(0).getReg();
297 // [if ([!]p0[.new])] jumpr r31
298 if ((Hexagon::P0
== SrcReg
) && (Hexagon::R31
== DstReg
)) {
299 return HexagonII::HSIG_L2
;
302 case Hexagon::L4_return_t
:
303 case Hexagon::L4_return_f
:
304 case Hexagon::L4_return_tnew_pnt
:
305 case Hexagon::L4_return_fnew_pnt
:
306 case Hexagon::L4_return_tnew_pt
:
307 case Hexagon::L4_return_fnew_pt
:
308 // [if ([!]p0[.new])] dealloc_return
309 SrcReg
= MCI
.getOperand(1).getReg();
310 if (Hexagon::P0
== SrcReg
) {
311 return HexagonII::HSIG_L2
;
317 // memw(Rs+#u4:2) = Rt
318 // memb(Rs+#u4:0) = Rt
319 case Hexagon::S2_storeri_io
:
320 // Special case this one from Group S2.
321 // memw(r29+#u5:2) = Rt
322 Src1Reg
= MCI
.getOperand(0).getReg();
323 Src2Reg
= MCI
.getOperand(2).getReg();
324 if (HexagonMCInstrInfo::isIntReg(Src1Reg
) &&
325 HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg
) &&
326 Hexagon::R29
== Src1Reg
&& inRange
<5, 2>(MCI
, 1)) {
327 return HexagonII::HSIG_S2
;
329 // memw(Rs+#u4:2) = Rt
330 if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg
) &&
331 HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg
) &&
332 inRange
<4, 2>(MCI
, 1)) {
333 return HexagonII::HSIG_S1
;
336 case Hexagon::S2_storerb_io
:
337 // memb(Rs+#u4:0) = Rt
338 Src1Reg
= MCI
.getOperand(0).getReg();
339 Src2Reg
= MCI
.getOperand(2).getReg();
340 if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg
) &&
341 HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg
) &&
342 inRange
<4>(MCI
, 1)) {
343 return HexagonII::HSIG_S1
;
349 // memh(Rs+#u3:1) = Rt
350 // memw(r29+#u5:2) = Rt
351 // memd(r29+#s6:3) = Rtt
352 // memw(Rs+#u4:2) = #U1
353 // memb(Rs+#u4) = #U1
355 case Hexagon::S2_storerh_io
:
356 // memh(Rs+#u3:1) = Rt
357 Src1Reg
= MCI
.getOperand(0).getReg();
358 Src2Reg
= MCI
.getOperand(2).getReg();
359 if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg
) &&
360 HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg
) &&
361 inRange
<3, 1>(MCI
, 1)) {
362 return HexagonII::HSIG_S2
;
365 case Hexagon::S2_storerd_io
:
366 // memd(r29+#s6:3) = Rtt
367 Src1Reg
= MCI
.getOperand(0).getReg();
368 Src2Reg
= MCI
.getOperand(2).getReg();
369 if (HexagonMCInstrInfo::isDblRegForSubInst(Src2Reg
) &&
370 HexagonMCInstrInfo::isIntReg(Src1Reg
) && Hexagon::R29
== Src1Reg
&&
371 inSRange
<6, 3>(MCI
, 1)) {
372 return HexagonII::HSIG_S2
;
375 case Hexagon::S4_storeiri_io
:
376 // memw(Rs+#u4:2) = #U1
377 Src1Reg
= MCI
.getOperand(0).getReg();
378 if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg
) &&
379 inRange
<4, 2>(MCI
, 1) && inRange
<1>(MCI
, 2)) {
380 return HexagonII::HSIG_S2
;
383 case Hexagon::S4_storeirb_io
:
384 // memb(Rs+#u4) = #U1
385 Src1Reg
= MCI
.getOperand(0).getReg();
386 if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg
) &&
387 inRange
<4>(MCI
, 1) && inRange
<1>(MCI
, 2)) {
388 return HexagonII::HSIG_S2
;
391 case Hexagon::S2_allocframe
:
392 if (inRange
<5, 3>(MCI
, 2))
393 return HexagonII::HSIG_S2
;
402 // if ([!]P0[.new]) Rd = #0
403 // Rd = add(r29,#u6:2)
405 // P0 = cmp.eq(Rs,#u2)
406 // Rdd = combine(#0,Rs)
407 // Rdd = combine(Rs,#0)
408 // Rdd = combine(#u2,#U2)
411 // Rd = sxth/sxtb/zxtb/zxth(Rs)
413 case Hexagon::A2_addi
:
414 DstReg
= MCI
.getOperand(0).getReg();
415 SrcReg
= MCI
.getOperand(1).getReg();
416 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg
)) {
417 // Rd = add(r29,#u6:2)
418 if (HexagonMCInstrInfo::isIntReg(SrcReg
) && Hexagon::R29
== SrcReg
&&
419 inRange
<6, 2>(MCI
, 2)) {
420 return HexagonII::HSIG_A
;
423 if (DstReg
== SrcReg
) {
424 return HexagonII::HSIG_A
;
428 if (HexagonMCInstrInfo::isIntRegForSubInst(SrcReg
) &&
429 (minConstant(MCI
, 2) == 1 || minConstant(MCI
, 2) == -1)) {
430 return HexagonII::HSIG_A
;
434 case Hexagon::A2_add
:
436 DstReg
= MCI
.getOperand(0).getReg();
437 Src1Reg
= MCI
.getOperand(1).getReg();
438 Src2Reg
= MCI
.getOperand(2).getReg();
439 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg
) && (DstReg
== Src1Reg
) &&
440 HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg
)) {
441 return HexagonII::HSIG_A
;
444 case Hexagon::A2_andir
:
445 DstReg
= MCI
.getOperand(0).getReg();
446 SrcReg
= MCI
.getOperand(1).getReg();
447 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg
) &&
448 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg
) &&
449 (minConstant(MCI
, 2) == 1 || minConstant(MCI
, 2) == 255)) {
450 return HexagonII::HSIG_A
;
453 case Hexagon::A2_tfr
:
455 DstReg
= MCI
.getOperand(0).getReg();
456 SrcReg
= MCI
.getOperand(1).getReg();
457 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg
) &&
458 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg
)) {
459 return HexagonII::HSIG_A
;
462 case Hexagon::A2_tfrsi
:
463 DstReg
= MCI
.getOperand(0).getReg();
465 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg
)) {
466 return HexagonII::HSIG_A
;
469 case Hexagon::C2_cmoveit
:
470 case Hexagon::C2_cmovenewit
:
471 case Hexagon::C2_cmoveif
:
472 case Hexagon::C2_cmovenewif
:
473 // if ([!]P0[.new]) Rd = #0
475 // %r16 = C2_cmovenewit internal %p0, 0, implicit undef %r16;
476 DstReg
= MCI
.getOperand(0).getReg(); // Rd
477 PredReg
= MCI
.getOperand(1).getReg(); // P0
478 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg
) &&
479 Hexagon::P0
== PredReg
&& minConstant(MCI
, 2) == 0) {
480 return HexagonII::HSIG_A
;
483 case Hexagon::C2_cmpeqi
:
484 // P0 = cmp.eq(Rs,#u2)
485 DstReg
= MCI
.getOperand(0).getReg();
486 SrcReg
= MCI
.getOperand(1).getReg();
487 if (Hexagon::P0
== DstReg
&&
488 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg
) &&
489 inRange
<2>(MCI
, 2)) {
490 return HexagonII::HSIG_A
;
493 case Hexagon::A2_combineii
:
494 case Hexagon::A4_combineii
:
495 // Rdd = combine(#u2,#U2)
496 DstReg
= MCI
.getOperand(0).getReg();
497 if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg
) &&
498 inRange
<2>(MCI
, 1) && inRange
<2>(MCI
, 2)) {
499 return HexagonII::HSIG_A
;
502 case Hexagon::A4_combineri
:
503 // Rdd = combine(Rs,#0)
504 DstReg
= MCI
.getOperand(0).getReg();
505 SrcReg
= MCI
.getOperand(1).getReg();
506 if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg
) &&
507 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg
) &&
508 minConstant(MCI
, 2) == 0) {
509 return HexagonII::HSIG_A
;
512 case Hexagon::A4_combineir
:
513 // Rdd = combine(#0,Rs)
514 DstReg
= MCI
.getOperand(0).getReg();
515 SrcReg
= MCI
.getOperand(2).getReg();
516 if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg
) &&
517 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg
) &&
518 minConstant(MCI
, 1) == 0) {
519 return HexagonII::HSIG_A
;
522 case Hexagon::A2_sxtb
:
523 case Hexagon::A2_sxth
:
524 case Hexagon::A2_zxtb
:
525 case Hexagon::A2_zxth
:
526 // Rd = sxth/sxtb/zxtb/zxth(Rs)
527 DstReg
= MCI
.getOperand(0).getReg();
528 SrcReg
= MCI
.getOperand(1).getReg();
529 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg
) &&
530 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg
)) {
531 return HexagonII::HSIG_A
;
536 return HexagonII::HSIG_None
;
539 bool HexagonMCInstrInfo::subInstWouldBeExtended(MCInst
const &potentialDuplex
) {
540 unsigned DstReg
, SrcReg
;
541 switch (potentialDuplex
.getOpcode()) {
542 case Hexagon::A2_addi
:
543 // testing for case of: Rx = add(Rx,#s7)
544 DstReg
= potentialDuplex
.getOperand(0).getReg();
545 SrcReg
= potentialDuplex
.getOperand(1).getReg();
546 if (DstReg
== SrcReg
&& HexagonMCInstrInfo::isIntRegForSubInst(DstReg
)) {
548 if (!potentialDuplex
.getOperand(2).getExpr()->evaluateAsAbsolute(Value
))
550 if (!isShiftedInt
<7, 0>(Value
))
554 case Hexagon::A2_tfrsi
:
555 DstReg
= potentialDuplex
.getOperand(0).getReg();
557 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg
)) {
559 if (!potentialDuplex
.getOperand(1).getExpr()->evaluateAsAbsolute(Value
))
561 // Check for case of Rd = #-1.
564 // Check for case of Rd = #u6.
565 if (!isShiftedUInt
<6, 0>(Value
))
575 /// non-Symmetrical. See if these two instructions are fit for duplex pair.
576 bool HexagonMCInstrInfo::isOrderedDuplexPair(MCInstrInfo
const &MCII
,
577 MCInst
const &MIa
, bool ExtendedA
,
578 MCInst
const &MIb
, bool ExtendedB
,
580 MCSubtargetInfo
const &STI
) {
581 // Slot 1 cannot be extended in duplexes PRM 10.5
584 // Only A2_addi and A2_tfrsi can be extended in duplex form PRM 10.5
586 unsigned Opcode
= MIb
.getOpcode();
587 if ((Opcode
!= Hexagon::A2_addi
) && (Opcode
!= Hexagon::A2_tfrsi
))
590 unsigned MIaG
= HexagonMCInstrInfo::getDuplexCandidateGroup(MIa
),
591 MIbG
= HexagonMCInstrInfo::getDuplexCandidateGroup(MIb
);
593 static std::map
<unsigned, unsigned> subinstOpcodeMap(std::begin(opcodeData
),
594 std::end(opcodeData
));
596 // If a duplex contains 2 insns in the same group, the insns must be
597 // ordered such that the numerically smaller opcode is in slot 1.
598 if ((MIaG
!= HexagonII::HSIG_None
) && (MIaG
== MIbG
) && bisReversable
) {
599 MCInst SubInst0
= HexagonMCInstrInfo::deriveSubInst(MIa
);
600 MCInst SubInst1
= HexagonMCInstrInfo::deriveSubInst(MIb
);
602 unsigned zeroedSubInstS0
=
603 subinstOpcodeMap
.find(SubInst0
.getOpcode())->second
;
604 unsigned zeroedSubInstS1
=
605 subinstOpcodeMap
.find(SubInst1
.getOpcode())->second
;
607 if (zeroedSubInstS0
< zeroedSubInstS1
)
608 // subinstS0 (maps to slot 0) must be greater than
609 // subinstS1 (maps to slot 1)
613 // allocframe must always be in slot 0
614 if (MIb
.getOpcode() == Hexagon::S2_allocframe
)
617 if ((MIaG
!= HexagonII::HSIG_None
) && (MIbG
!= HexagonII::HSIG_None
)) {
618 // Prevent 2 instructions with extenders from duplexing
619 // Note that MIb (slot1) can be extended and MIa (slot0)
620 // can never be extended
621 if (subInstWouldBeExtended(MIa
))
624 // If duplexing produces an extender, but the original did not
625 // have an extender, do not duplex.
626 if (subInstWouldBeExtended(MIb
) && !ExtendedB
)
630 // If jumpr r31 appears, it must be in slot 0, and never slot 1 (MIb).
631 if (MIbG
== HexagonII::HSIG_L2
) {
632 if ((MIb
.getNumOperands() > 1) && MIb
.getOperand(1).isReg() &&
633 (MIb
.getOperand(1).getReg() == Hexagon::R31
))
635 if ((MIb
.getNumOperands() > 0) && MIb
.getOperand(0).isReg() &&
636 (MIb
.getOperand(0).getReg() == Hexagon::R31
))
640 if (STI
.getCPU().equals_insensitive("hexagonv5") ||
641 STI
.getCPU().equals_insensitive("hexagonv55") ||
642 STI
.getCPU().equals_insensitive("hexagonv60")) {
643 // If a store appears, it must be in slot 0 (MIa) 1st, and then slot 1 (MIb);
644 // therefore, not duplexable if slot 1 is a store, and slot 0 is not.
645 if ((MIbG
== HexagonII::HSIG_S1
) || (MIbG
== HexagonII::HSIG_S2
)) {
646 if ((MIaG
!= HexagonII::HSIG_S1
) && (MIaG
!= HexagonII::HSIG_S2
))
651 return (isDuplexPairMatch(MIaG
, MIbG
));
654 /// Symmetrical. See if these two instructions are fit for duplex pair.
655 bool HexagonMCInstrInfo::isDuplexPair(MCInst
const &MIa
, MCInst
const &MIb
) {
656 unsigned MIaG
= getDuplexCandidateGroup(MIa
),
657 MIbG
= getDuplexCandidateGroup(MIb
);
658 return (isDuplexPairMatch(MIaG
, MIbG
) || isDuplexPairMatch(MIbG
, MIaG
));
661 inline static void addOps(MCInst
&subInstPtr
, MCInst
const &Inst
,
663 if (Inst
.getOperand(opNum
).isReg()) {
664 switch (Inst
.getOperand(opNum
).getReg()) {
666 llvm_unreachable("Not Duplexable Register");
693 subInstPtr
.addOperand(Inst
.getOperand(opNum
));
697 subInstPtr
.addOperand(Inst
.getOperand(opNum
));
700 MCInst
HexagonMCInstrInfo::deriveSubInst(MCInst
const &Inst
) {
704 switch (Inst
.getOpcode()) {
706 // dbgs() << "opcode: "<< Inst->getOpcode() << "\n";
707 llvm_unreachable("Unimplemented subinstruction \n");
709 case Hexagon::A2_addi
:
710 Absolute
= Inst
.getOperand(2).getExpr()->evaluateAsAbsolute(Value
);
713 Result
.setOpcode(Hexagon::SA1_inc
);
714 addOps(Result
, Inst
, 0);
715 addOps(Result
, Inst
, 1);
717 } // 1,2 SUBInst $Rd = add($Rs, #1)
719 Result
.setOpcode(Hexagon::SA1_dec
);
720 addOps(Result
, Inst
, 0);
721 addOps(Result
, Inst
, 1);
722 addOps(Result
, Inst
, 2);
724 } // 1,2 SUBInst $Rd = add($Rs,#-1)
725 if (Inst
.getOperand(1).getReg() == Hexagon::R29
) {
726 Result
.setOpcode(Hexagon::SA1_addsp
);
727 addOps(Result
, Inst
, 0);
728 addOps(Result
, Inst
, 2);
730 } // 1,3 SUBInst $Rd = add(r29, #$u6_2)
732 Result
.setOpcode(Hexagon::SA1_addi
);
733 addOps(Result
, Inst
, 0);
734 addOps(Result
, Inst
, 1);
735 addOps(Result
, Inst
, 2);
736 break; // 1,2,3 SUBInst $Rx = add($Rx, #$s7)
737 case Hexagon::A2_add
:
738 Result
.setOpcode(Hexagon::SA1_addrx
);
739 addOps(Result
, Inst
, 0);
740 addOps(Result
, Inst
, 1);
741 addOps(Result
, Inst
, 2);
742 break; // 1,2,3 SUBInst $Rx = add($_src_, $Rs)
743 case Hexagon::S2_allocframe
:
744 Result
.setOpcode(Hexagon::SS2_allocframe
);
745 addOps(Result
, Inst
, 2);
746 break; // 1 SUBInst allocframe(#$u5_3)
747 case Hexagon::A2_andir
:
748 if (minConstant(Inst
, 2) == 255) {
749 Result
.setOpcode(Hexagon::SA1_zxtb
);
750 addOps(Result
, Inst
, 0);
751 addOps(Result
, Inst
, 1);
752 break; // 1,2 $Rd = and($Rs, #255)
754 Result
.setOpcode(Hexagon::SA1_and1
);
755 addOps(Result
, Inst
, 0);
756 addOps(Result
, Inst
, 1);
757 break; // 1,2 SUBInst $Rd = and($Rs, #1)
759 case Hexagon::C2_cmpeqi
:
760 Result
.setOpcode(Hexagon::SA1_cmpeqi
);
761 addOps(Result
, Inst
, 1);
762 addOps(Result
, Inst
, 2);
763 break; // 2,3 SUBInst p0 = cmp.eq($Rs, #$u2)
764 case Hexagon::A4_combineii
:
765 case Hexagon::A2_combineii
:
766 Absolute
= Inst
.getOperand(1).getExpr()->evaluateAsAbsolute(Value
);
767 assert(Absolute
);(void)Absolute
;
769 Result
.setOpcode(Hexagon::SA1_combine1i
);
770 addOps(Result
, Inst
, 0);
771 addOps(Result
, Inst
, 2);
772 break; // 1,3 SUBInst $Rdd = combine(#1, #$u2)
775 Result
.setOpcode(Hexagon::SA1_combine3i
);
776 addOps(Result
, Inst
, 0);
777 addOps(Result
, Inst
, 2);
778 break; // 1,3 SUBInst $Rdd = combine(#3, #$u2)
781 Result
.setOpcode(Hexagon::SA1_combine0i
);
782 addOps(Result
, Inst
, 0);
783 addOps(Result
, Inst
, 2);
784 break; // 1,3 SUBInst $Rdd = combine(#0, #$u2)
787 Result
.setOpcode(Hexagon::SA1_combine2i
);
788 addOps(Result
, Inst
, 0);
789 addOps(Result
, Inst
, 2);
790 break; // 1,3 SUBInst $Rdd = combine(#2, #$u2)
793 case Hexagon::A4_combineir
:
794 Result
.setOpcode(Hexagon::SA1_combinezr
);
795 addOps(Result
, Inst
, 0);
796 addOps(Result
, Inst
, 2);
797 break; // 1,3 SUBInst $Rdd = combine(#0, $Rs)
798 case Hexagon::A4_combineri
:
799 Result
.setOpcode(Hexagon::SA1_combinerz
);
800 addOps(Result
, Inst
, 0);
801 addOps(Result
, Inst
, 1);
802 break; // 1,2 SUBInst $Rdd = combine($Rs, #0)
803 case Hexagon::L4_return_tnew_pnt
:
804 case Hexagon::L4_return_tnew_pt
:
805 Result
.setOpcode(Hexagon::SL2_return_tnew
);
806 break; // none SUBInst if (p0.new) dealloc_return:nt
807 case Hexagon::L4_return_fnew_pnt
:
808 case Hexagon::L4_return_fnew_pt
:
809 Result
.setOpcode(Hexagon::SL2_return_fnew
);
810 break; // none SUBInst if (!p0.new) dealloc_return:nt
811 case Hexagon::L4_return_f
:
812 Result
.setOpcode(Hexagon::SL2_return_f
);
813 break; // none SUBInst if (!p0) dealloc_return
814 case Hexagon::L4_return_t
:
815 Result
.setOpcode(Hexagon::SL2_return_t
);
816 break; // none SUBInst if (p0) dealloc_return
817 case Hexagon::L4_return
:
818 Result
.setOpcode(Hexagon::SL2_return
);
819 break; // none SUBInst dealloc_return
820 case Hexagon::L2_deallocframe
:
821 Result
.setOpcode(Hexagon::SL2_deallocframe
);
822 break; // none SUBInst deallocframe
823 case Hexagon::EH_RETURN_JMPR
:
824 case Hexagon::J2_jumpr
:
825 case Hexagon::PS_jmpret
:
826 Result
.setOpcode(Hexagon::SL2_jumpr31
);
827 break; // none SUBInst jumpr r31
828 case Hexagon::J2_jumprf
:
829 case Hexagon::PS_jmpretf
:
830 Result
.setOpcode(Hexagon::SL2_jumpr31_f
);
831 break; // none SUBInst if (!p0) jumpr r31
832 case Hexagon::J2_jumprfnew
:
833 case Hexagon::J2_jumprfnewpt
:
834 case Hexagon::PS_jmpretfnewpt
:
835 case Hexagon::PS_jmpretfnew
:
836 Result
.setOpcode(Hexagon::SL2_jumpr31_fnew
);
837 break; // none SUBInst if (!p0.new) jumpr:nt r31
838 case Hexagon::J2_jumprt
:
839 case Hexagon::PS_jmprett
:
840 Result
.setOpcode(Hexagon::SL2_jumpr31_t
);
841 break; // none SUBInst if (p0) jumpr r31
842 case Hexagon::J2_jumprtnew
:
843 case Hexagon::J2_jumprtnewpt
:
844 case Hexagon::PS_jmprettnewpt
:
845 case Hexagon::PS_jmprettnew
:
846 Result
.setOpcode(Hexagon::SL2_jumpr31_tnew
);
847 break; // none SUBInst if (p0.new) jumpr:nt r31
848 case Hexagon::L2_loadrb_io
:
849 Result
.setOpcode(Hexagon::SL2_loadrb_io
);
850 addOps(Result
, Inst
, 0);
851 addOps(Result
, Inst
, 1);
852 addOps(Result
, Inst
, 2);
853 break; // 1,2,3 SUBInst $Rd = memb($Rs + #$u3_0)
854 case Hexagon::L2_loadrd_io
:
855 Result
.setOpcode(Hexagon::SL2_loadrd_sp
);
856 addOps(Result
, Inst
, 0);
857 addOps(Result
, Inst
, 2);
858 break; // 1,3 SUBInst $Rdd = memd(r29 + #$u5_3)
859 case Hexagon::L2_loadrh_io
:
860 Result
.setOpcode(Hexagon::SL2_loadrh_io
);
861 addOps(Result
, Inst
, 0);
862 addOps(Result
, Inst
, 1);
863 addOps(Result
, Inst
, 2);
864 break; // 1,2,3 SUBInst $Rd = memh($Rs + #$u3_1)
865 case Hexagon::L2_loadrub_io
:
866 Result
.setOpcode(Hexagon::SL1_loadrub_io
);
867 addOps(Result
, Inst
, 0);
868 addOps(Result
, Inst
, 1);
869 addOps(Result
, Inst
, 2);
870 break; // 1,2,3 SUBInst $Rd = memub($Rs + #$u4_0)
871 case Hexagon::L2_loadruh_io
:
872 Result
.setOpcode(Hexagon::SL2_loadruh_io
);
873 addOps(Result
, Inst
, 0);
874 addOps(Result
, Inst
, 1);
875 addOps(Result
, Inst
, 2);
876 break; // 1,2,3 SUBInst $Rd = memuh($Rs + #$u3_1)
877 case Hexagon::L2_loadri_io
:
878 if (Inst
.getOperand(1).getReg() == Hexagon::R29
) {
879 Result
.setOpcode(Hexagon::SL2_loadri_sp
);
880 addOps(Result
, Inst
, 0);
881 addOps(Result
, Inst
, 2);
882 break; // 2 1,3 SUBInst $Rd = memw(r29 + #$u5_2)
884 Result
.setOpcode(Hexagon::SL1_loadri_io
);
885 addOps(Result
, Inst
, 0);
886 addOps(Result
, Inst
, 1);
887 addOps(Result
, Inst
, 2);
888 break; // 1,2,3 SUBInst $Rd = memw($Rs + #$u4_2)
890 case Hexagon::S4_storeirb_io
:
891 Absolute
= Inst
.getOperand(2).getExpr()->evaluateAsAbsolute(Value
);
892 assert(Absolute
);(void)Absolute
;
894 Result
.setOpcode(Hexagon::SS2_storebi0
);
895 addOps(Result
, Inst
, 0);
896 addOps(Result
, Inst
, 1);
897 break; // 1,2 SUBInst memb($Rs + #$u4_0)=#0
898 } else if (Value
== 1) {
899 Result
.setOpcode(Hexagon::SS2_storebi1
);
900 addOps(Result
, Inst
, 0);
901 addOps(Result
, Inst
, 1);
902 break; // 2 1,2 SUBInst memb($Rs + #$u4_0)=#1
905 case Hexagon::S2_storerb_io
:
906 Result
.setOpcode(Hexagon::SS1_storeb_io
);
907 addOps(Result
, Inst
, 0);
908 addOps(Result
, Inst
, 1);
909 addOps(Result
, Inst
, 2);
910 break; // 1,2,3 SUBInst memb($Rs + #$u4_0) = $Rt
911 case Hexagon::S2_storerd_io
:
912 Result
.setOpcode(Hexagon::SS2_stored_sp
);
913 addOps(Result
, Inst
, 1);
914 addOps(Result
, Inst
, 2);
915 break; // 2,3 SUBInst memd(r29 + #$s6_3) = $Rtt
916 case Hexagon::S2_storerh_io
:
917 Result
.setOpcode(Hexagon::SS2_storeh_io
);
918 addOps(Result
, Inst
, 0);
919 addOps(Result
, Inst
, 1);
920 addOps(Result
, Inst
, 2);
921 break; // 1,2,3 SUBInst memb($Rs + #$u4_0) = $Rt
922 case Hexagon::S4_storeiri_io
:
923 Absolute
= Inst
.getOperand(2).getExpr()->evaluateAsAbsolute(Value
);
924 assert(Absolute
);(void)Absolute
;
926 Result
.setOpcode(Hexagon::SS2_storewi0
);
927 addOps(Result
, Inst
, 0);
928 addOps(Result
, Inst
, 1);
929 break; // 3 1,2 SUBInst memw($Rs + #$u4_2)=#0
930 } else if (Value
== 1) {
931 Result
.setOpcode(Hexagon::SS2_storewi1
);
932 addOps(Result
, Inst
, 0);
933 addOps(Result
, Inst
, 1);
934 break; // 3 1,2 SUBInst memw($Rs + #$u4_2)=#1
935 } else if (Inst
.getOperand(0).getReg() == Hexagon::R29
) {
936 Result
.setOpcode(Hexagon::SS2_storew_sp
);
937 addOps(Result
, Inst
, 1);
938 addOps(Result
, Inst
, 2);
939 break; // 1 2,3 SUBInst memw(r29 + #$u5_2) = $Rt
942 case Hexagon::S2_storeri_io
:
943 if (Inst
.getOperand(0).getReg() == Hexagon::R29
) {
944 Result
.setOpcode(Hexagon::SS2_storew_sp
);
945 addOps(Result
, Inst
, 1);
946 addOps(Result
, Inst
, 2); // 1,2,3 SUBInst memw(sp + #$u5_2) = $Rt
948 Result
.setOpcode(Hexagon::SS1_storew_io
);
949 addOps(Result
, Inst
, 0);
950 addOps(Result
, Inst
, 1);
951 addOps(Result
, Inst
, 2); // 1,2,3 SUBInst memw($Rs + #$u4_2) = $Rt
954 case Hexagon::A2_sxtb
:
955 Result
.setOpcode(Hexagon::SA1_sxtb
);
956 addOps(Result
, Inst
, 0);
957 addOps(Result
, Inst
, 1);
958 break; // 1,2 SUBInst $Rd = sxtb($Rs)
959 case Hexagon::A2_sxth
:
960 Result
.setOpcode(Hexagon::SA1_sxth
);
961 addOps(Result
, Inst
, 0);
962 addOps(Result
, Inst
, 1);
963 break; // 1,2 SUBInst $Rd = sxth($Rs)
964 case Hexagon::A2_tfr
:
965 Result
.setOpcode(Hexagon::SA1_tfr
);
966 addOps(Result
, Inst
, 0);
967 addOps(Result
, Inst
, 1);
968 break; // 1,2 SUBInst $Rd = $Rs
969 case Hexagon::C2_cmovenewif
:
970 Result
.setOpcode(Hexagon::SA1_clrfnew
);
971 addOps(Result
, Inst
, 0);
972 addOps(Result
, Inst
, 1);
973 break; // 2 SUBInst if (!p0.new) $Rd = #0
974 case Hexagon::C2_cmovenewit
:
975 Result
.setOpcode(Hexagon::SA1_clrtnew
);
976 addOps(Result
, Inst
, 0);
977 addOps(Result
, Inst
, 1);
978 break; // 2 SUBInst if (p0.new) $Rd = #0
979 case Hexagon::C2_cmoveif
:
980 Result
.setOpcode(Hexagon::SA1_clrf
);
981 addOps(Result
, Inst
, 0);
982 addOps(Result
, Inst
, 1);
983 break; // 2 SUBInst if (!p0) $Rd = #0
984 case Hexagon::C2_cmoveit
:
985 Result
.setOpcode(Hexagon::SA1_clrt
);
986 addOps(Result
, Inst
, 0);
987 addOps(Result
, Inst
, 1);
988 break; // 2 SUBInst if (p0) $Rd = #0
989 case Hexagon::A2_tfrsi
:
990 Absolute
= Inst
.getOperand(1).getExpr()->evaluateAsAbsolute(Value
);
991 if (Absolute
&& Value
== -1) {
992 Result
.setOpcode(Hexagon::SA1_setin1
);
993 addOps(Result
, Inst
, 0);
994 addOps(Result
, Inst
, 1);
995 break; // 2 1 SUBInst $Rd = #-1
997 Result
.setOpcode(Hexagon::SA1_seti
);
998 addOps(Result
, Inst
, 0);
999 addOps(Result
, Inst
, 1);
1000 break; // 1,2 SUBInst $Rd = #$u6
1002 case Hexagon::A2_zxtb
:
1003 Result
.setOpcode(Hexagon::SA1_zxtb
);
1004 addOps(Result
, Inst
, 0);
1005 addOps(Result
, Inst
, 1);
1006 break; // 1,2 $Rd = and($Rs, #255)
1008 case Hexagon::A2_zxth
:
1009 Result
.setOpcode(Hexagon::SA1_zxth
);
1010 addOps(Result
, Inst
, 0);
1011 addOps(Result
, Inst
, 1);
1012 break; // 1,2 SUBInst $Rd = zxth($Rs)
1017 static bool isStoreInst(unsigned opCode
) {
1019 case Hexagon::S2_storeri_io
:
1020 case Hexagon::S2_storerb_io
:
1021 case Hexagon::S2_storerh_io
:
1022 case Hexagon::S2_storerd_io
:
1023 case Hexagon::S4_storeiri_io
:
1024 case Hexagon::S4_storeirb_io
:
1025 case Hexagon::S2_allocframe
:
1032 SmallVector
<DuplexCandidate
, 8>
1033 HexagonMCInstrInfo::getDuplexPossibilties(MCInstrInfo
const &MCII
,
1034 MCSubtargetInfo
const &STI
,
1035 MCInst
const &MCB
) {
1036 assert(isBundle(MCB
));
1037 SmallVector
<DuplexCandidate
, 8> duplexToTry
;
1038 // Use an "order matters" version of isDuplexPair.
1039 unsigned numInstrInPacket
= MCB
.getNumOperands();
1041 for (unsigned distance
= 1; distance
< numInstrInPacket
; ++distance
) {
1042 for (unsigned j
= HexagonMCInstrInfo::bundleInstructionsOffset
,
1044 (j
< numInstrInPacket
) && (k
< numInstrInPacket
); ++j
, ++k
) {
1046 // Check if reversible.
1047 bool bisReversable
= true;
1048 if (isStoreInst(MCB
.getOperand(j
).getInst()->getOpcode()) &&
1049 isStoreInst(MCB
.getOperand(k
).getInst()->getOpcode())) {
1050 LLVM_DEBUG(dbgs() << "skip out of order write pair: " << k
<< "," << j
1052 bisReversable
= false;
1054 if (HexagonMCInstrInfo::isMemReorderDisabled(MCB
)) // }:mem_noshuf
1055 bisReversable
= false;
1058 if (isOrderedDuplexPair(
1059 MCII
, *MCB
.getOperand(k
).getInst(),
1060 HexagonMCInstrInfo::hasExtenderForIndex(MCB
, k
- 1),
1061 *MCB
.getOperand(j
).getInst(),
1062 HexagonMCInstrInfo::hasExtenderForIndex(MCB
, j
- 1),
1063 bisReversable
, STI
)) {
1065 unsigned iClass
= iClassOfDuplexPair(
1066 getDuplexCandidateGroup(*MCB
.getOperand(k
).getInst()),
1067 getDuplexCandidateGroup(*MCB
.getOperand(j
).getInst()));
1069 // Save off pairs for duplex checking.
1070 duplexToTry
.push_back(DuplexCandidate(j
, k
, iClass
));
1071 LLVM_DEBUG(dbgs() << "adding pair: " << j
<< "," << k
<< ":"
1072 << MCB
.getOperand(j
).getInst()->getOpcode() << ","
1073 << MCB
.getOperand(k
).getInst()->getOpcode() << "\n");
1076 LLVM_DEBUG(dbgs() << "skipping pair: " << j
<< "," << k
<< ":"
1077 << MCB
.getOperand(j
).getInst()->getOpcode() << ","
1078 << MCB
.getOperand(k
).getInst()->getOpcode() << "\n");
1082 if (bisReversable
) {
1083 if (isOrderedDuplexPair(
1084 MCII
, *MCB
.getOperand(j
).getInst(),
1085 HexagonMCInstrInfo::hasExtenderForIndex(MCB
, j
- 1),
1086 *MCB
.getOperand(k
).getInst(),
1087 HexagonMCInstrInfo::hasExtenderForIndex(MCB
, k
- 1),
1088 bisReversable
, STI
)) {
1090 unsigned iClass
= iClassOfDuplexPair(
1091 getDuplexCandidateGroup(*MCB
.getOperand(j
).getInst()),
1092 getDuplexCandidateGroup(*MCB
.getOperand(k
).getInst()));
1094 // Save off pairs for duplex checking.
1095 duplexToTry
.push_back(DuplexCandidate(k
, j
, iClass
));
1097 << "adding pair:" << k
<< "," << j
<< ":"
1098 << MCB
.getOperand(j
).getInst()->getOpcode() << ","
1099 << MCB
.getOperand(k
).getInst()->getOpcode() << "\n");
1102 << "skipping pair: " << k
<< "," << j
<< ":"
1103 << MCB
.getOperand(j
).getInst()->getOpcode() << ","
1104 << MCB
.getOperand(k
).getInst()->getOpcode() << "\n");