1 //===----- HexagonMCDuplexInfo.cpp - Instruction bundle checking ----------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This implements duplexing of instructions to reduce code size
12 //===----------------------------------------------------------------------===//
14 #include "HexagonBaseInfo.h"
15 #include "MCTargetDesc/HexagonMCInstrInfo.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/Support/Debug.h"
19 #include "llvm/Support/raw_ostream.h"
24 using namespace Hexagon;
26 #define DEBUG_TYPE "hexagon-mcduplex-info"
28 // pair table of subInstructions with opcodes
29 static const std::pair<unsigned, unsigned> opcodeData[] = {
30 std::make_pair((unsigned)V4_SA1_addi, 0),
31 std::make_pair((unsigned)V4_SA1_addrx, 6144),
32 std::make_pair((unsigned)V4_SA1_addsp, 3072),
33 std::make_pair((unsigned)V4_SA1_and1, 4608),
34 std::make_pair((unsigned)V4_SA1_clrf, 6768),
35 std::make_pair((unsigned)V4_SA1_clrfnew, 6736),
36 std::make_pair((unsigned)V4_SA1_clrt, 6752),
37 std::make_pair((unsigned)V4_SA1_clrtnew, 6720),
38 std::make_pair((unsigned)V4_SA1_cmpeqi, 6400),
39 std::make_pair((unsigned)V4_SA1_combine0i, 7168),
40 std::make_pair((unsigned)V4_SA1_combine1i, 7176),
41 std::make_pair((unsigned)V4_SA1_combine2i, 7184),
42 std::make_pair((unsigned)V4_SA1_combine3i, 7192),
43 std::make_pair((unsigned)V4_SA1_combinerz, 7432),
44 std::make_pair((unsigned)V4_SA1_combinezr, 7424),
45 std::make_pair((unsigned)V4_SA1_dec, 4864),
46 std::make_pair((unsigned)V4_SA1_inc, 4352),
47 std::make_pair((unsigned)V4_SA1_seti, 2048),
48 std::make_pair((unsigned)V4_SA1_setin1, 6656),
49 std::make_pair((unsigned)V4_SA1_sxtb, 5376),
50 std::make_pair((unsigned)V4_SA1_sxth, 5120),
51 std::make_pair((unsigned)V4_SA1_tfr, 4096),
52 std::make_pair((unsigned)V4_SA1_zxtb, 5888),
53 std::make_pair((unsigned)V4_SA1_zxth, 5632),
54 std::make_pair((unsigned)V4_SL1_loadri_io, 0),
55 std::make_pair((unsigned)V4_SL1_loadrub_io, 4096),
56 std::make_pair((unsigned)V4_SL2_deallocframe, 7936),
57 std::make_pair((unsigned)V4_SL2_jumpr31, 8128),
58 std::make_pair((unsigned)V4_SL2_jumpr31_f, 8133),
59 std::make_pair((unsigned)V4_SL2_jumpr31_fnew, 8135),
60 std::make_pair((unsigned)V4_SL2_jumpr31_t, 8132),
61 std::make_pair((unsigned)V4_SL2_jumpr31_tnew, 8134),
62 std::make_pair((unsigned)V4_SL2_loadrb_io, 4096),
63 std::make_pair((unsigned)V4_SL2_loadrd_sp, 7680),
64 std::make_pair((unsigned)V4_SL2_loadrh_io, 0),
65 std::make_pair((unsigned)V4_SL2_loadri_sp, 7168),
66 std::make_pair((unsigned)V4_SL2_loadruh_io, 2048),
67 std::make_pair((unsigned)V4_SL2_return, 8000),
68 std::make_pair((unsigned)V4_SL2_return_f, 8005),
69 std::make_pair((unsigned)V4_SL2_return_fnew, 8007),
70 std::make_pair((unsigned)V4_SL2_return_t, 8004),
71 std::make_pair((unsigned)V4_SL2_return_tnew, 8006),
72 std::make_pair((unsigned)V4_SS1_storeb_io, 4096),
73 std::make_pair((unsigned)V4_SS1_storew_io, 0),
74 std::make_pair((unsigned)V4_SS2_allocframe, 7168),
75 std::make_pair((unsigned)V4_SS2_storebi0, 4608),
76 std::make_pair((unsigned)V4_SS2_storebi1, 4864),
77 std::make_pair((unsigned)V4_SS2_stored_sp, 2560),
78 std::make_pair((unsigned)V4_SS2_storeh_io, 0),
79 std::make_pair((unsigned)V4_SS2_storew_sp, 2048),
80 std::make_pair((unsigned)V4_SS2_storewi0, 4096),
81 std::make_pair((unsigned)V4_SS2_storewi1, 4352)};
83 static std::map<unsigned, unsigned>
84 subinstOpcodeMap(opcodeData,
85 opcodeData + sizeof(opcodeData) / sizeof(opcodeData[0]));
87 bool HexagonMCInstrInfo::isDuplexPairMatch(unsigned Ga, unsigned Gb) {
89 case HexagonII::HSIG_None:
92 case HexagonII::HSIG_L1:
93 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_A);
94 case HexagonII::HSIG_L2:
95 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
96 Gb == HexagonII::HSIG_A);
97 case HexagonII::HSIG_S1:
98 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
99 Gb == HexagonII::HSIG_S1 || Gb == HexagonII::HSIG_A);
100 case HexagonII::HSIG_S2:
101 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
102 Gb == HexagonII::HSIG_S1 || Gb == HexagonII::HSIG_S2 ||
103 Gb == HexagonII::HSIG_A);
104 case HexagonII::HSIG_A:
105 return (Gb == HexagonII::HSIG_A);
106 case HexagonII::HSIG_Compound:
107 return (Gb == HexagonII::HSIG_Compound);
112 unsigned HexagonMCInstrInfo::iClassOfDuplexPair(unsigned Ga, unsigned Gb) {
114 case HexagonII::HSIG_None:
117 case HexagonII::HSIG_L1:
121 case HexagonII::HSIG_L1:
123 case HexagonII::HSIG_A:
126 case HexagonII::HSIG_L2:
130 case HexagonII::HSIG_L1:
132 case HexagonII::HSIG_L2:
134 case HexagonII::HSIG_A:
137 case HexagonII::HSIG_S1:
141 case HexagonII::HSIG_L1:
143 case HexagonII::HSIG_L2:
145 case HexagonII::HSIG_S1:
147 case HexagonII::HSIG_A:
150 case HexagonII::HSIG_S2:
154 case HexagonII::HSIG_L1:
156 case HexagonII::HSIG_L2:
158 case HexagonII::HSIG_S1:
160 case HexagonII::HSIG_S2:
162 case HexagonII::HSIG_A:
165 case HexagonII::HSIG_A:
169 case HexagonII::HSIG_A:
172 case HexagonII::HSIG_Compound:
174 case HexagonII::HSIG_Compound:
181 unsigned HexagonMCInstrInfo::getDuplexCandidateGroup(MCInst const &MCI) {
182 unsigned DstReg, PredReg, SrcReg, Src1Reg, Src2Reg;
184 switch (MCI.getOpcode()) {
186 return HexagonII::HSIG_None;
190 // Rd = memw(Rs+#u4:2)
191 // Rd = memub(Rs+#u4:0)
192 case Hexagon::L2_loadri_io:
193 DstReg = MCI.getOperand(0).getReg();
194 SrcReg = MCI.getOperand(1).getReg();
195 // Special case this one from Group L2.
196 // Rd = memw(r29+#u5:2)
197 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
198 if (HexagonMCInstrInfo::isIntReg(SrcReg) &&
199 Hexagon::R29 == SrcReg && inRange<5, 2>(MCI, 2)) {
200 return HexagonII::HSIG_L2;
202 // Rd = memw(Rs+#u4:2)
203 if (HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
204 inRange<4, 2>(MCI, 2)) {
205 return HexagonII::HSIG_L1;
209 case Hexagon::L2_loadrub_io:
210 // Rd = memub(Rs+#u4:0)
211 DstReg = MCI.getOperand(0).getReg();
212 SrcReg = MCI.getOperand(1).getReg();
213 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
214 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
215 inRange<4>(MCI, 2)) {
216 return HexagonII::HSIG_L1;
222 // Rd = memh/memuh(Rs+#u3:1)
223 // Rd = memb(Rs+#u3:0)
224 // Rd = memw(r29+#u5:2) - Handled above.
225 // Rdd = memd(r29+#u5:3)
227 // [if ([!]p0[.new])] dealloc_return
228 // [if ([!]p0[.new])] jumpr r31
229 case Hexagon::L2_loadrh_io:
230 case Hexagon::L2_loadruh_io:
231 // Rd = memh/memuh(Rs+#u3:1)
232 DstReg = MCI.getOperand(0).getReg();
233 SrcReg = MCI.getOperand(1).getReg();
234 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
235 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
236 inRange<3, 1>(MCI, 2)) {
237 return HexagonII::HSIG_L2;
240 case Hexagon::L2_loadrb_io:
241 // Rd = memb(Rs+#u3:0)
242 DstReg = MCI.getOperand(0).getReg();
243 SrcReg = MCI.getOperand(1).getReg();
244 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
245 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
246 inRange<3>(MCI, 2)) {
247 return HexagonII::HSIG_L2;
250 case Hexagon::L2_loadrd_io:
251 // Rdd = memd(r29+#u5:3)
252 DstReg = MCI.getOperand(0).getReg();
253 SrcReg = MCI.getOperand(1).getReg();
254 if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
255 HexagonMCInstrInfo::isIntReg(SrcReg) && Hexagon::R29 == SrcReg &&
256 inRange<5, 3>(MCI, 2)) {
257 return HexagonII::HSIG_L2;
261 case Hexagon::L4_return:
263 case Hexagon::L2_deallocframe:
265 return HexagonII::HSIG_L2;
266 case Hexagon::EH_RETURN_JMPR:
268 case Hexagon::J2_jumpr:
269 case Hexagon::JMPret:
271 // Actual form JMPR %PC<imp-def>, %R31<imp-use>, %R0<imp-use,internal>.
272 DstReg = MCI.getOperand(0).getReg();
273 if (Hexagon::R31 == DstReg) {
274 return HexagonII::HSIG_L2;
278 case Hexagon::J2_jumprt:
279 case Hexagon::J2_jumprf:
280 case Hexagon::J2_jumprtnew:
281 case Hexagon::J2_jumprfnew:
282 case Hexagon::JMPrett:
283 case Hexagon::JMPretf:
284 case Hexagon::JMPrettnew:
285 case Hexagon::JMPretfnew:
286 case Hexagon::JMPrettnewpt:
287 case Hexagon::JMPretfnewpt:
288 DstReg = MCI.getOperand(1).getReg();
289 SrcReg = MCI.getOperand(0).getReg();
290 // [if ([!]p0[.new])] jumpr r31
291 if ((HexagonMCInstrInfo::isPredReg(SrcReg) && (Hexagon::P0 == SrcReg)) &&
292 (Hexagon::R31 == DstReg)) {
293 return HexagonII::HSIG_L2;
296 case Hexagon::L4_return_t:
298 case Hexagon::L4_return_f:
300 case Hexagon::L4_return_tnew_pnt:
302 case Hexagon::L4_return_fnew_pnt:
304 case Hexagon::L4_return_tnew_pt:
306 case Hexagon::L4_return_fnew_pt:
307 // [if ([!]p0[.new])] dealloc_return
308 SrcReg = MCI.getOperand(0).getReg();
309 if (Hexagon::P0 == SrcReg) {
310 return HexagonII::HSIG_L2;
316 // memw(Rs+#u4:2) = Rt
317 // memb(Rs+#u4:0) = Rt
318 case Hexagon::S2_storeri_io:
319 // Special case this one from Group S2.
320 // memw(r29+#u5:2) = Rt
321 Src1Reg = MCI.getOperand(0).getReg();
322 Src2Reg = MCI.getOperand(2).getReg();
323 if (HexagonMCInstrInfo::isIntReg(Src1Reg) &&
324 HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
325 Hexagon::R29 == Src1Reg && inRange<5, 2>(MCI, 1)) {
326 return HexagonII::HSIG_S2;
328 // memw(Rs+#u4:2) = Rt
329 if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
330 HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
331 inRange<4, 2>(MCI, 1)) {
332 return HexagonII::HSIG_S1;
335 case Hexagon::S2_storerb_io:
336 // memb(Rs+#u4:0) = Rt
337 Src1Reg = MCI.getOperand(0).getReg();
338 Src2Reg = MCI.getOperand(2).getReg();
339 if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
340 HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
341 inRange<4>(MCI, 1)) {
342 return HexagonII::HSIG_S1;
348 // memh(Rs+#u3:1) = Rt
349 // memw(r29+#u5:2) = Rt
350 // memd(r29+#s6:3) = Rtt
351 // memw(Rs+#u4:2) = #U1
352 // memb(Rs+#u4) = #U1
354 case Hexagon::S2_storerh_io:
355 // memh(Rs+#u3:1) = Rt
356 Src1Reg = MCI.getOperand(0).getReg();
357 Src2Reg = MCI.getOperand(2).getReg();
358 if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
359 HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
360 inRange<3, 1>(MCI, 1)) {
361 return HexagonII::HSIG_S2;
364 case Hexagon::S2_storerd_io:
365 // memd(r29+#s6:3) = Rtt
366 Src1Reg = MCI.getOperand(0).getReg();
367 Src2Reg = MCI.getOperand(2).getReg();
368 if (HexagonMCInstrInfo::isDblRegForSubInst(Src2Reg) &&
369 HexagonMCInstrInfo::isIntReg(Src1Reg) && Hexagon::R29 == Src1Reg &&
370 inSRange<6, 3>(MCI, 1)) {
371 return HexagonII::HSIG_S2;
374 case Hexagon::S4_storeiri_io:
375 // memw(Rs+#u4:2) = #U1
376 Src1Reg = MCI.getOperand(0).getReg();
377 if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
378 inRange<4, 2>(MCI, 1) && inRange<1>(MCI, 2)) {
379 return HexagonII::HSIG_S2;
382 case Hexagon::S4_storeirb_io:
383 // memb(Rs+#u4) = #U1
384 Src1Reg = MCI.getOperand(0).getReg();
385 if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
386 inRange<4>(MCI, 1) && inRange<1>(MCI, 2)) {
387 return HexagonII::HSIG_S2;
390 case Hexagon::S2_allocframe:
391 if (inRange<5, 3>(MCI, 0))
392 return HexagonII::HSIG_S2;
401 // if ([!]P0[.new]) Rd = #0
402 // Rd = add(r29,#u6:2)
404 // P0 = cmp.eq(Rs,#u2)
405 // Rdd = combine(#0,Rs)
406 // Rdd = combine(Rs,#0)
407 // Rdd = combine(#u2,#U2)
410 // Rd = sxth/sxtb/zxtb/zxth(Rs)
412 case Hexagon::A2_addi:
413 DstReg = MCI.getOperand(0).getReg();
414 SrcReg = MCI.getOperand(1).getReg();
415 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
416 // Rd = add(r29,#u6:2)
417 if (HexagonMCInstrInfo::isIntReg(SrcReg) && Hexagon::R29 == SrcReg &&
418 inRange<6, 2>(MCI, 2)) {
419 return HexagonII::HSIG_A;
422 if (DstReg == SrcReg) {
423 return HexagonII::HSIG_A;
427 if (HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
428 (minConstant(MCI, 2) == 1 || minConstant(MCI, 2) == -1)) {
429 return HexagonII::HSIG_A;
433 case Hexagon::A2_add:
435 DstReg = MCI.getOperand(0).getReg();
436 Src1Reg = MCI.getOperand(1).getReg();
437 Src2Reg = MCI.getOperand(2).getReg();
438 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) && (DstReg == Src1Reg) &&
439 HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg)) {
440 return HexagonII::HSIG_A;
443 case Hexagon::A2_andir:
444 DstReg = MCI.getOperand(0).getReg();
445 SrcReg = MCI.getOperand(1).getReg();
446 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
447 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
448 (minConstant(MCI, 2) == 1 || minConstant(MCI, 2) == 255)) {
449 return HexagonII::HSIG_A;
452 case Hexagon::A2_tfr:
454 DstReg = MCI.getOperand(0).getReg();
455 SrcReg = MCI.getOperand(1).getReg();
456 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
457 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg)) {
458 return HexagonII::HSIG_A;
461 case Hexagon::A2_tfrsi:
462 DstReg = MCI.getOperand(0).getReg();
464 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
465 return HexagonII::HSIG_A;
468 case Hexagon::C2_cmoveit:
469 case Hexagon::C2_cmovenewit:
470 case Hexagon::C2_cmoveif:
471 case Hexagon::C2_cmovenewif:
472 // if ([!]P0[.new]) Rd = #0
474 // %R16<def> = C2_cmovenewit %P0<internal>, 0, %R16<imp-use,undef>;
475 DstReg = MCI.getOperand(0).getReg(); // Rd
476 PredReg = MCI.getOperand(1).getReg(); // P0
477 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
478 Hexagon::P0 == PredReg && minConstant(MCI, 2) == 0) {
479 return HexagonII::HSIG_A;
482 case Hexagon::C2_cmpeqi:
483 // P0 = cmp.eq(Rs,#u2)
484 DstReg = MCI.getOperand(0).getReg();
485 SrcReg = MCI.getOperand(1).getReg();
486 if (Hexagon::P0 == DstReg &&
487 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
488 inRange<2>(MCI, 2)) {
489 return HexagonII::HSIG_A;
492 case Hexagon::A2_combineii:
493 case Hexagon::A4_combineii:
494 // Rdd = combine(#u2,#U2)
495 DstReg = MCI.getOperand(0).getReg();
496 if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
497 inRange<2>(MCI, 1) && inRange<2>(MCI, 2)) {
498 return HexagonII::HSIG_A;
501 case Hexagon::A4_combineri:
502 // Rdd = combine(Rs,#0)
503 DstReg = MCI.getOperand(0).getReg();
504 SrcReg = MCI.getOperand(1).getReg();
505 if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
506 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
507 minConstant(MCI, 2) == 0) {
508 return HexagonII::HSIG_A;
511 case Hexagon::A4_combineir:
512 // Rdd = combine(#0,Rs)
513 DstReg = MCI.getOperand(0).getReg();
514 SrcReg = MCI.getOperand(2).getReg();
515 if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
516 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
517 minConstant(MCI, 1) == 0) {
518 return HexagonII::HSIG_A;
521 case Hexagon::A2_sxtb:
522 case Hexagon::A2_sxth:
523 case Hexagon::A2_zxtb:
524 case Hexagon::A2_zxth:
525 // Rd = sxth/sxtb/zxtb/zxth(Rs)
526 DstReg = MCI.getOperand(0).getReg();
527 SrcReg = MCI.getOperand(1).getReg();
528 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
529 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg)) {
530 return HexagonII::HSIG_A;
535 return HexagonII::HSIG_None;
538 bool HexagonMCInstrInfo::subInstWouldBeExtended(MCInst const &potentialDuplex) {
539 unsigned DstReg, SrcReg;
540 switch (potentialDuplex.getOpcode()) {
541 case Hexagon::A2_addi:
542 // testing for case of: Rx = add(Rx,#s7)
543 DstReg = potentialDuplex.getOperand(0).getReg();
544 SrcReg = potentialDuplex.getOperand(1).getReg();
545 if (DstReg == SrcReg && HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
547 if (!potentialDuplex.getOperand(2).getExpr()->evaluateAsAbsolute(Value))
549 if (!isShiftedInt<7, 0>(Value))
553 case Hexagon::A2_tfrsi:
554 DstReg = potentialDuplex.getOperand(0).getReg();
556 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
558 if (!potentialDuplex.getOperand(1).getExpr()->evaluateAsAbsolute(Value))
560 // Check for case of Rd = #-1.
563 // Check for case of Rd = #u6.
564 if (!isShiftedUInt<6, 0>(Value))
574 /// non-Symmetrical. See if these two instructions are fit for duplex pair.
575 bool HexagonMCInstrInfo::isOrderedDuplexPair(MCInstrInfo const &MCII,
576 MCInst const &MIa, bool ExtendedA,
577 MCInst const &MIb, bool ExtendedB,
578 bool bisReversable) {
579 // Slot 1 cannot be extended in duplexes PRM 10.5
582 // Only A2_addi and A2_tfrsi can be extended in duplex form PRM 10.5
584 unsigned Opcode = MIb.getOpcode();
585 if ((Opcode != Hexagon::A2_addi) && (Opcode != Hexagon::A2_tfrsi))
588 unsigned MIaG = HexagonMCInstrInfo::getDuplexCandidateGroup(MIa),
589 MIbG = HexagonMCInstrInfo::getDuplexCandidateGroup(MIb);
591 // If a duplex contains 2 insns in the same group, the insns must be
592 // ordered such that the numerically smaller opcode is in slot 1.
593 if ((MIaG != HexagonII::HSIG_None) && (MIaG == MIbG) && bisReversable) {
594 MCInst SubInst0 = HexagonMCInstrInfo::deriveSubInst(MIa);
595 MCInst SubInst1 = HexagonMCInstrInfo::deriveSubInst(MIb);
597 unsigned zeroedSubInstS0 =
598 subinstOpcodeMap.find(SubInst0.getOpcode())->second;
599 unsigned zeroedSubInstS1 =
600 subinstOpcodeMap.find(SubInst1.getOpcode())->second;
602 if (zeroedSubInstS0 < zeroedSubInstS1)
603 // subinstS0 (maps to slot 0) must be greater than
604 // subinstS1 (maps to slot 1)
608 // allocframe must always be in slot 0
609 if (MIb.getOpcode() == Hexagon::S2_allocframe)
612 if ((MIaG != HexagonII::HSIG_None) && (MIbG != HexagonII::HSIG_None)) {
613 // Prevent 2 instructions with extenders from duplexing
614 // Note that MIb (slot1) can be extended and MIa (slot0)
615 // can never be extended
616 if (subInstWouldBeExtended(MIa))
619 // If duplexing produces an extender, but the original did not
620 // have an extender, do not duplex.
621 if (subInstWouldBeExtended(MIb) && !ExtendedB)
625 // If jumpr r31 appears, it must be in slot 0, and never slot 1 (MIb).
626 if (MIbG == HexagonII::HSIG_L2) {
627 if ((MIb.getNumOperands() > 1) && MIb.getOperand(1).isReg() &&
628 (MIb.getOperand(1).getReg() == Hexagon::R31))
630 if ((MIb.getNumOperands() > 0) && MIb.getOperand(0).isReg() &&
631 (MIb.getOperand(0).getReg() == Hexagon::R31))
635 // If a store appears, it must be in slot 0 (MIa) 1st, and then slot 1 (MIb);
636 // therefore, not duplexable if slot 1 is a store, and slot 0 is not.
637 if ((MIbG == HexagonII::HSIG_S1) || (MIbG == HexagonII::HSIG_S2)) {
638 if ((MIaG != HexagonII::HSIG_S1) && (MIaG != HexagonII::HSIG_S2))
642 return (isDuplexPairMatch(MIaG, MIbG));
645 /// Symmetrical. See if these two instructions are fit for duplex pair.
646 bool HexagonMCInstrInfo::isDuplexPair(MCInst const &MIa, MCInst const &MIb) {
647 unsigned MIaG = getDuplexCandidateGroup(MIa),
648 MIbG = getDuplexCandidateGroup(MIb);
649 return (isDuplexPairMatch(MIaG, MIbG) || isDuplexPairMatch(MIbG, MIaG));
652 inline static void addOps(MCInst &subInstPtr, MCInst const &Inst,
654 if (Inst.getOperand(opNum).isReg()) {
655 switch (Inst.getOperand(opNum).getReg()) {
657 llvm_unreachable("Not Duplexable Register");
683 subInstPtr.addOperand(Inst.getOperand(opNum));
687 subInstPtr.addOperand(Inst.getOperand(opNum));
690 MCInst HexagonMCInstrInfo::deriveSubInst(MCInst const &Inst) {
694 switch (Inst.getOpcode()) {
696 // dbgs() << "opcode: "<< Inst->getOpcode() << "\n";
697 llvm_unreachable("Unimplemented subinstruction \n");
699 case Hexagon::A2_addi:
700 Absolute = Inst.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
701 assert(Absolute);(void)Absolute;
703 Result.setOpcode(Hexagon::V4_SA1_inc);
704 addOps(Result, Inst, 0);
705 addOps(Result, Inst, 1);
707 } // 1,2 SUBInst $Rd = add($Rs, #1)
708 else if (Value == -1) {
709 Result.setOpcode(Hexagon::V4_SA1_dec);
710 addOps(Result, Inst, 0);
711 addOps(Result, Inst, 1);
713 } // 1,2 SUBInst $Rd = add($Rs,#-1)
714 else if (Inst.getOperand(1).getReg() == Hexagon::R29) {
715 Result.setOpcode(Hexagon::V4_SA1_addsp);
716 addOps(Result, Inst, 0);
717 addOps(Result, Inst, 2);
719 } // 1,3 SUBInst $Rd = add(r29, #$u6_2)
721 Result.setOpcode(Hexagon::V4_SA1_addi);
722 addOps(Result, Inst, 0);
723 addOps(Result, Inst, 1);
724 addOps(Result, Inst, 2);
726 } // 1,2,3 SUBInst $Rx = add($Rx, #$s7)
727 case Hexagon::A2_add:
728 Result.setOpcode(Hexagon::V4_SA1_addrx);
729 addOps(Result, Inst, 0);
730 addOps(Result, Inst, 1);
731 addOps(Result, Inst, 2);
732 break; // 1,2,3 SUBInst $Rx = add($_src_, $Rs)
733 case Hexagon::S2_allocframe:
734 Result.setOpcode(Hexagon::V4_SS2_allocframe);
735 addOps(Result, Inst, 0);
736 break; // 1 SUBInst allocframe(#$u5_3)
737 case Hexagon::A2_andir:
738 if (minConstant(Inst, 2) == 255) {
739 Result.setOpcode(Hexagon::V4_SA1_zxtb);
740 addOps(Result, Inst, 0);
741 addOps(Result, Inst, 1);
742 break; // 1,2 $Rd = and($Rs, #255)
744 Result.setOpcode(Hexagon::V4_SA1_and1);
745 addOps(Result, Inst, 0);
746 addOps(Result, Inst, 1);
747 break; // 1,2 SUBInst $Rd = and($Rs, #1)
749 case Hexagon::C2_cmpeqi:
750 Result.setOpcode(Hexagon::V4_SA1_cmpeqi);
751 addOps(Result, Inst, 1);
752 addOps(Result, Inst, 2);
753 break; // 2,3 SUBInst p0 = cmp.eq($Rs, #$u2)
754 case Hexagon::A4_combineii:
755 case Hexagon::A2_combineii:
756 Absolute = Inst.getOperand(1).getExpr()->evaluateAsAbsolute(Value);
757 assert(Absolute);(void)Absolute;
759 Result.setOpcode(Hexagon::V4_SA1_combine1i);
760 addOps(Result, Inst, 0);
761 addOps(Result, Inst, 2);
762 break; // 1,3 SUBInst $Rdd = combine(#1, #$u2)
765 Result.setOpcode(Hexagon::V4_SA1_combine3i);
766 addOps(Result, Inst, 0);
767 addOps(Result, Inst, 2);
768 break; // 1,3 SUBInst $Rdd = combine(#3, #$u2)
771 Result.setOpcode(Hexagon::V4_SA1_combine0i);
772 addOps(Result, Inst, 0);
773 addOps(Result, Inst, 2);
774 break; // 1,3 SUBInst $Rdd = combine(#0, #$u2)
777 Result.setOpcode(Hexagon::V4_SA1_combine2i);
778 addOps(Result, Inst, 0);
779 addOps(Result, Inst, 2);
780 break; // 1,3 SUBInst $Rdd = combine(#2, #$u2)
782 case Hexagon::A4_combineir:
783 Result.setOpcode(Hexagon::V4_SA1_combinezr);
784 addOps(Result, Inst, 0);
785 addOps(Result, Inst, 2);
786 break; // 1,3 SUBInst $Rdd = combine(#0, $Rs)
788 case Hexagon::A4_combineri:
789 Result.setOpcode(Hexagon::V4_SA1_combinerz);
790 addOps(Result, Inst, 0);
791 addOps(Result, Inst, 1);
792 break; // 1,2 SUBInst $Rdd = combine($Rs, #0)
793 case Hexagon::L4_return_tnew_pnt:
794 case Hexagon::L4_return_tnew_pt:
795 Result.setOpcode(Hexagon::V4_SL2_return_tnew);
796 break; // none SUBInst if (p0.new) dealloc_return:nt
797 case Hexagon::L4_return_fnew_pnt:
798 case Hexagon::L4_return_fnew_pt:
799 Result.setOpcode(Hexagon::V4_SL2_return_fnew);
800 break; // none SUBInst if (!p0.new) dealloc_return:nt
801 case Hexagon::L4_return_f:
802 Result.setOpcode(Hexagon::V4_SL2_return_f);
803 break; // none SUBInst if (!p0) dealloc_return
804 case Hexagon::L4_return_t:
805 Result.setOpcode(Hexagon::V4_SL2_return_t);
806 break; // none SUBInst if (p0) dealloc_return
807 case Hexagon::L4_return:
808 Result.setOpcode(Hexagon::V4_SL2_return);
809 break; // none SUBInst dealloc_return
810 case Hexagon::L2_deallocframe:
811 Result.setOpcode(Hexagon::V4_SL2_deallocframe);
812 break; // none SUBInst deallocframe
813 case Hexagon::EH_RETURN_JMPR:
814 case Hexagon::J2_jumpr:
815 case Hexagon::JMPret:
816 Result.setOpcode(Hexagon::V4_SL2_jumpr31);
817 break; // none SUBInst jumpr r31
818 case Hexagon::J2_jumprf:
819 case Hexagon::JMPretf:
820 Result.setOpcode(Hexagon::V4_SL2_jumpr31_f);
821 break; // none SUBInst if (!p0) jumpr r31
822 case Hexagon::J2_jumprfnew:
823 case Hexagon::JMPretfnewpt:
824 case Hexagon::JMPretfnew:
825 Result.setOpcode(Hexagon::V4_SL2_jumpr31_fnew);
826 break; // none SUBInst if (!p0.new) jumpr:nt r31
827 case Hexagon::J2_jumprt:
828 case Hexagon::JMPrett:
829 Result.setOpcode(Hexagon::V4_SL2_jumpr31_t);
830 break; // none SUBInst if (p0) jumpr r31
831 case Hexagon::J2_jumprtnew:
832 case Hexagon::JMPrettnewpt:
833 case Hexagon::JMPrettnew:
834 Result.setOpcode(Hexagon::V4_SL2_jumpr31_tnew);
835 break; // none SUBInst if (p0.new) jumpr:nt r31
836 case Hexagon::L2_loadrb_io:
837 Result.setOpcode(Hexagon::V4_SL2_loadrb_io);
838 addOps(Result, Inst, 0);
839 addOps(Result, Inst, 1);
840 addOps(Result, Inst, 2);
841 break; // 1,2,3 SUBInst $Rd = memb($Rs + #$u3_0)
842 case Hexagon::L2_loadrd_io:
843 Result.setOpcode(Hexagon::V4_SL2_loadrd_sp);
844 addOps(Result, Inst, 0);
845 addOps(Result, Inst, 2);
846 break; // 1,3 SUBInst $Rdd = memd(r29 + #$u5_3)
847 case Hexagon::L2_loadrh_io:
848 Result.setOpcode(Hexagon::V4_SL2_loadrh_io);
849 addOps(Result, Inst, 0);
850 addOps(Result, Inst, 1);
851 addOps(Result, Inst, 2);
852 break; // 1,2,3 SUBInst $Rd = memh($Rs + #$u3_1)
853 case Hexagon::L2_loadrub_io:
854 Result.setOpcode(Hexagon::V4_SL1_loadrub_io);
855 addOps(Result, Inst, 0);
856 addOps(Result, Inst, 1);
857 addOps(Result, Inst, 2);
858 break; // 1,2,3 SUBInst $Rd = memub($Rs + #$u4_0)
859 case Hexagon::L2_loadruh_io:
860 Result.setOpcode(Hexagon::V4_SL2_loadruh_io);
861 addOps(Result, Inst, 0);
862 addOps(Result, Inst, 1);
863 addOps(Result, Inst, 2);
864 break; // 1,2,3 SUBInst $Rd = memuh($Rs + #$u3_1)
865 case Hexagon::L2_loadri_io:
866 if (Inst.getOperand(1).getReg() == Hexagon::R29) {
867 Result.setOpcode(Hexagon::V4_SL2_loadri_sp);
868 addOps(Result, Inst, 0);
869 addOps(Result, Inst, 2);
870 break; // 2 1,3 SUBInst $Rd = memw(r29 + #$u5_2)
872 Result.setOpcode(Hexagon::V4_SL1_loadri_io);
873 addOps(Result, Inst, 0);
874 addOps(Result, Inst, 1);
875 addOps(Result, Inst, 2);
876 break; // 1,2,3 SUBInst $Rd = memw($Rs + #$u4_2)
878 case Hexagon::S4_storeirb_io:
879 Absolute = Inst.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
880 assert(Absolute);(void)Absolute;
882 Result.setOpcode(Hexagon::V4_SS2_storebi0);
883 addOps(Result, Inst, 0);
884 addOps(Result, Inst, 1);
885 break; // 1,2 SUBInst memb($Rs + #$u4_0)=#0
886 } else if (Value == 1) {
887 Result.setOpcode(Hexagon::V4_SS2_storebi1);
888 addOps(Result, Inst, 0);
889 addOps(Result, Inst, 1);
890 break; // 2 1,2 SUBInst memb($Rs + #$u4_0)=#1
892 case Hexagon::S2_storerb_io:
893 Result.setOpcode(Hexagon::V4_SS1_storeb_io);
894 addOps(Result, Inst, 0);
895 addOps(Result, Inst, 1);
896 addOps(Result, Inst, 2);
897 break; // 1,2,3 SUBInst memb($Rs + #$u4_0) = $Rt
898 case Hexagon::S2_storerd_io:
899 Result.setOpcode(Hexagon::V4_SS2_stored_sp);
900 addOps(Result, Inst, 1);
901 addOps(Result, Inst, 2);
902 break; // 2,3 SUBInst memd(r29 + #$s6_3) = $Rtt
903 case Hexagon::S2_storerh_io:
904 Result.setOpcode(Hexagon::V4_SS2_storeh_io);
905 addOps(Result, Inst, 0);
906 addOps(Result, Inst, 1);
907 addOps(Result, Inst, 2);
908 break; // 1,2,3 SUBInst memb($Rs + #$u4_0) = $Rt
909 case Hexagon::S4_storeiri_io:
910 Absolute = Inst.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
911 assert(Absolute);(void)Absolute;
913 Result.setOpcode(Hexagon::V4_SS2_storewi0);
914 addOps(Result, Inst, 0);
915 addOps(Result, Inst, 1);
916 break; // 3 1,2 SUBInst memw($Rs + #$u4_2)=#0
917 } else if (Value == 1) {
918 Result.setOpcode(Hexagon::V4_SS2_storewi1);
919 addOps(Result, Inst, 0);
920 addOps(Result, Inst, 1);
921 break; // 3 1,2 SUBInst memw($Rs + #$u4_2)=#1
922 } else if (Inst.getOperand(0).getReg() == Hexagon::R29) {
923 Result.setOpcode(Hexagon::V4_SS2_storew_sp);
924 addOps(Result, Inst, 1);
925 addOps(Result, Inst, 2);
926 break; // 1 2,3 SUBInst memw(r29 + #$u5_2) = $Rt
928 case Hexagon::S2_storeri_io:
929 if (Inst.getOperand(0).getReg() == Hexagon::R29) {
930 Result.setOpcode(Hexagon::V4_SS2_storew_sp);
931 addOps(Result, Inst, 1);
932 addOps(Result, Inst, 2); // 1,2,3 SUBInst memw(sp + #$u5_2) = $Rt
934 Result.setOpcode(Hexagon::V4_SS1_storew_io);
935 addOps(Result, Inst, 0);
936 addOps(Result, Inst, 1);
937 addOps(Result, Inst, 2); // 1,2,3 SUBInst memw($Rs + #$u4_2) = $Rt
940 case Hexagon::A2_sxtb:
941 Result.setOpcode(Hexagon::V4_SA1_sxtb);
942 addOps(Result, Inst, 0);
943 addOps(Result, Inst, 1);
944 break; // 1,2 SUBInst $Rd = sxtb($Rs)
945 case Hexagon::A2_sxth:
946 Result.setOpcode(Hexagon::V4_SA1_sxth);
947 addOps(Result, Inst, 0);
948 addOps(Result, Inst, 1);
949 break; // 1,2 SUBInst $Rd = sxth($Rs)
950 case Hexagon::A2_tfr:
951 Result.setOpcode(Hexagon::V4_SA1_tfr);
952 addOps(Result, Inst, 0);
953 addOps(Result, Inst, 1);
954 break; // 1,2 SUBInst $Rd = $Rs
955 case Hexagon::C2_cmovenewif:
956 Result.setOpcode(Hexagon::V4_SA1_clrfnew);
957 addOps(Result, Inst, 0);
958 break; // 2 SUBInst if (!p0.new) $Rd = #0
959 case Hexagon::C2_cmovenewit:
960 Result.setOpcode(Hexagon::V4_SA1_clrtnew);
961 addOps(Result, Inst, 0);
962 break; // 2 SUBInst if (p0.new) $Rd = #0
963 case Hexagon::C2_cmoveif:
964 Result.setOpcode(Hexagon::V4_SA1_clrf);
965 addOps(Result, Inst, 0);
966 break; // 2 SUBInst if (!p0) $Rd = #0
967 case Hexagon::C2_cmoveit:
968 Result.setOpcode(Hexagon::V4_SA1_clrt);
969 addOps(Result, Inst, 0);
970 break; // 2 SUBInst if (p0) $Rd = #0
971 case Hexagon::A2_tfrsi:
972 Absolute = Inst.getOperand(1).getExpr()->evaluateAsAbsolute(Value);
973 if (Absolute && Value == -1) {
974 Result.setOpcode(Hexagon::V4_SA1_setin1);
975 addOps(Result, Inst, 0);
976 break; // 2 1 SUBInst $Rd = #-1
978 Result.setOpcode(Hexagon::V4_SA1_seti);
979 addOps(Result, Inst, 0);
980 addOps(Result, Inst, 1);
981 break; // 1,2 SUBInst $Rd = #$u6
983 case Hexagon::A2_zxtb:
984 Result.setOpcode(Hexagon::V4_SA1_zxtb);
985 addOps(Result, Inst, 0);
986 addOps(Result, Inst, 1);
987 break; // 1,2 $Rd = and($Rs, #255)
989 case Hexagon::A2_zxth:
990 Result.setOpcode(Hexagon::V4_SA1_zxth);
991 addOps(Result, Inst, 0);
992 addOps(Result, Inst, 1);
993 break; // 1,2 SUBInst $Rd = zxth($Rs)
998 static bool isStoreInst(unsigned opCode) {
1000 case Hexagon::S2_storeri_io:
1001 case Hexagon::S2_storerb_io:
1002 case Hexagon::S2_storerh_io:
1003 case Hexagon::S2_storerd_io:
1004 case Hexagon::S4_storeiri_io:
1005 case Hexagon::S4_storeirb_io:
1006 case Hexagon::S2_allocframe:
1013 SmallVector<DuplexCandidate, 8>
1014 HexagonMCInstrInfo::getDuplexPossibilties(MCInstrInfo const &MCII,
1015 MCInst const &MCB) {
1016 assert(isBundle(MCB));
1017 SmallVector<DuplexCandidate, 8> duplexToTry;
1018 // Use an "order matters" version of isDuplexPair.
1019 unsigned numInstrInPacket = MCB.getNumOperands();
1021 for (unsigned distance = 1; distance < numInstrInPacket; ++distance) {
1022 for (unsigned j = HexagonMCInstrInfo::bundleInstructionsOffset,
1024 (j < numInstrInPacket) && (k < numInstrInPacket); ++j, ++k) {
1026 // Check if reversable.
1027 bool bisReversable = true;
1028 if (isStoreInst(MCB.getOperand(j).getInst()->getOpcode()) &&
1029 isStoreInst(MCB.getOperand(k).getInst()->getOpcode())) {
1030 DEBUG(dbgs() << "skip out of order write pair: " << k << "," << j
1032 bisReversable = false;
1034 if (HexagonMCInstrInfo::isMemReorderDisabled(MCB)) // }:mem_noshuf
1035 bisReversable = false;
1038 if (isOrderedDuplexPair(
1039 MCII, *MCB.getOperand(k).getInst(),
1040 HexagonMCInstrInfo::hasExtenderForIndex(MCB, k - 1),
1041 *MCB.getOperand(j).getInst(),
1042 HexagonMCInstrInfo::hasExtenderForIndex(MCB, j - 1),
1045 unsigned iClass = iClassOfDuplexPair(
1046 getDuplexCandidateGroup(*MCB.getOperand(k).getInst()),
1047 getDuplexCandidateGroup(*MCB.getOperand(j).getInst()));
1049 // Save off pairs for duplex checking.
1050 duplexToTry.push_back(DuplexCandidate(j, k, iClass));
1051 DEBUG(dbgs() << "adding pair: " << j << "," << k << ":"
1052 << MCB.getOperand(j).getInst()->getOpcode() << ","
1053 << MCB.getOperand(k).getInst()->getOpcode() << "\n");
1056 DEBUG(dbgs() << "skipping pair: " << j << "," << k << ":"
1057 << MCB.getOperand(j).getInst()->getOpcode() << ","
1058 << MCB.getOperand(k).getInst()->getOpcode() << "\n");
1062 if (bisReversable) {
1063 if (isOrderedDuplexPair(
1064 MCII, *MCB.getOperand(j).getInst(),
1065 HexagonMCInstrInfo::hasExtenderForIndex(MCB, j - 1),
1066 *MCB.getOperand(k).getInst(),
1067 HexagonMCInstrInfo::hasExtenderForIndex(MCB, k - 1),
1070 unsigned iClass = iClassOfDuplexPair(
1071 getDuplexCandidateGroup(*MCB.getOperand(j).getInst()),
1072 getDuplexCandidateGroup(*MCB.getOperand(k).getInst()));
1074 // Save off pairs for duplex checking.
1075 duplexToTry.push_back(DuplexCandidate(k, j, iClass));
1076 DEBUG(dbgs() << "adding pair:" << k << "," << j << ":"
1077 << MCB.getOperand(j).getInst()->getOpcode() << ","
1078 << MCB.getOperand(k).getInst()->getOpcode() << "\n");
1080 DEBUG(dbgs() << "skipping pair: " << k << "," << j << ":"
1081 << MCB.getOperand(j).getInst()->getOpcode() << ","
1082 << MCB.getOperand(k).getInst()->getOpcode() << "\n");