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 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) && Hexagon::R29 == SrcReg &&
199 MCI.getOperand(2).isImm() &&
200 isShiftedUInt<5, 2>(MCI.getOperand(2).getImm())) {
201 return HexagonII::HSIG_L2;
203 // Rd = memw(Rs+#u4:2)
204 if (HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
205 (MCI.getOperand(2).isImm() &&
206 isShiftedUInt<4, 2>(MCI.getOperand(2).getImm()))) {
207 return HexagonII::HSIG_L1;
211 case Hexagon::L2_loadrub_io:
212 // Rd = memub(Rs+#u4:0)
213 DstReg = MCI.getOperand(0).getReg();
214 SrcReg = MCI.getOperand(1).getReg();
215 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
216 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
217 MCI.getOperand(2).isImm() && isUInt<4>(MCI.getOperand(2).getImm())) {
218 return HexagonII::HSIG_L1;
224 // Rd = memh/memuh(Rs+#u3:1)
225 // Rd = memb(Rs+#u3:0)
226 // Rd = memw(r29+#u5:2) - Handled above.
227 // Rdd = memd(r29+#u5:3)
229 // [if ([!]p0[.new])] dealloc_return
230 // [if ([!]p0[.new])] jumpr r31
231 case Hexagon::L2_loadrh_io:
232 case Hexagon::L2_loadruh_io:
233 // Rd = memh/memuh(Rs+#u3:1)
234 DstReg = MCI.getOperand(0).getReg();
235 SrcReg = MCI.getOperand(1).getReg();
236 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
237 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
238 MCI.getOperand(2).isImm() &&
239 isShiftedUInt<3, 1>(MCI.getOperand(2).getImm())) {
240 return HexagonII::HSIG_L2;
243 case Hexagon::L2_loadrb_io:
244 // Rd = memb(Rs+#u3:0)
245 DstReg = MCI.getOperand(0).getReg();
246 SrcReg = MCI.getOperand(1).getReg();
247 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
248 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
249 MCI.getOperand(2).isImm() && isUInt<3>(MCI.getOperand(2).getImm())) {
250 return HexagonII::HSIG_L2;
253 case Hexagon::L2_loadrd_io:
254 // Rdd = memd(r29+#u5:3)
255 DstReg = MCI.getOperand(0).getReg();
256 SrcReg = MCI.getOperand(1).getReg();
257 if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
258 HexagonMCInstrInfo::isIntReg(SrcReg) && Hexagon::R29 == SrcReg &&
259 MCI.getOperand(2).isImm() &&
260 isShiftedUInt<5, 3>(MCI.getOperand(2).getImm())) {
261 return HexagonII::HSIG_L2;
265 case Hexagon::L4_return:
267 case Hexagon::L2_deallocframe:
269 return HexagonII::HSIG_L2;
270 case Hexagon::EH_RETURN_JMPR:
272 case Hexagon::J2_jumpr:
273 case Hexagon::JMPret:
275 // Actual form JMPR %PC<imp-def>, %R31<imp-use>, %R0<imp-use,internal>.
276 DstReg = MCI.getOperand(0).getReg();
277 if (Hexagon::R31 == DstReg) {
278 return HexagonII::HSIG_L2;
282 case Hexagon::J2_jumprt:
283 case Hexagon::J2_jumprf:
284 case Hexagon::J2_jumprtnew:
285 case Hexagon::J2_jumprfnew:
286 case Hexagon::JMPrett:
287 case Hexagon::JMPretf:
288 case Hexagon::JMPrettnew:
289 case Hexagon::JMPretfnew:
290 case Hexagon::JMPrettnewpt:
291 case Hexagon::JMPretfnewpt:
292 DstReg = MCI.getOperand(1).getReg();
293 SrcReg = MCI.getOperand(0).getReg();
294 // [if ([!]p0[.new])] jumpr r31
295 if ((HexagonMCInstrInfo::isPredReg(SrcReg) && (Hexagon::P0 == SrcReg)) &&
296 (Hexagon::R31 == DstReg)) {
297 return HexagonII::HSIG_L2;
300 case Hexagon::L4_return_t:
302 case Hexagon::L4_return_f:
304 case Hexagon::L4_return_tnew_pnt:
306 case Hexagon::L4_return_fnew_pnt:
308 case Hexagon::L4_return_tnew_pt:
310 case Hexagon::L4_return_fnew_pt:
311 // [if ([!]p0[.new])] dealloc_return
312 SrcReg = MCI.getOperand(0).getReg();
313 if (Hexagon::P0 == SrcReg) {
314 return HexagonII::HSIG_L2;
320 // memw(Rs+#u4:2) = Rt
321 // memb(Rs+#u4:0) = Rt
322 case Hexagon::S2_storeri_io:
323 // Special case this one from Group S2.
324 // memw(r29+#u5:2) = Rt
325 Src1Reg = MCI.getOperand(0).getReg();
326 Src2Reg = MCI.getOperand(2).getReg();
327 if (HexagonMCInstrInfo::isIntReg(Src1Reg) &&
328 HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
329 Hexagon::R29 == Src1Reg && MCI.getOperand(1).isImm() &&
330 isShiftedUInt<5, 2>(MCI.getOperand(1).getImm())) {
331 return HexagonII::HSIG_S2;
333 // memw(Rs+#u4:2) = Rt
334 if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
335 HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
336 MCI.getOperand(1).isImm() &&
337 isShiftedUInt<4, 2>(MCI.getOperand(1).getImm())) {
338 return HexagonII::HSIG_S1;
341 case Hexagon::S2_storerb_io:
342 // memb(Rs+#u4:0) = Rt
343 Src1Reg = MCI.getOperand(0).getReg();
344 Src2Reg = MCI.getOperand(2).getReg();
345 if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
346 HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
347 MCI.getOperand(1).isImm() && isUInt<4>(MCI.getOperand(1).getImm())) {
348 return HexagonII::HSIG_S1;
354 // memh(Rs+#u3:1) = Rt
355 // memw(r29+#u5:2) = Rt
356 // memd(r29+#s6:3) = Rtt
357 // memw(Rs+#u4:2) = #U1
358 // memb(Rs+#u4) = #U1
360 case Hexagon::S2_storerh_io:
361 // memh(Rs+#u3:1) = Rt
362 Src1Reg = MCI.getOperand(0).getReg();
363 Src2Reg = MCI.getOperand(2).getReg();
364 if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
365 HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
366 MCI.getOperand(1).isImm() &&
367 isShiftedUInt<3, 1>(MCI.getOperand(1).getImm())) {
368 return HexagonII::HSIG_S2;
371 case Hexagon::S2_storerd_io:
372 // memd(r29+#s6:3) = Rtt
373 Src1Reg = MCI.getOperand(0).getReg();
374 Src2Reg = MCI.getOperand(2).getReg();
375 if (HexagonMCInstrInfo::isDblRegForSubInst(Src2Reg) &&
376 HexagonMCInstrInfo::isIntReg(Src1Reg) && Hexagon::R29 == Src1Reg &&
377 MCI.getOperand(1).isImm() &&
378 isShiftedInt<6, 3>(MCI.getOperand(1).getImm())) {
379 return HexagonII::HSIG_S2;
382 case Hexagon::S4_storeiri_io:
383 // memw(Rs+#u4:2) = #U1
384 Src1Reg = MCI.getOperand(0).getReg();
385 if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
386 MCI.getOperand(1).isImm() &&
387 isShiftedUInt<4, 2>(MCI.getOperand(1).getImm()) &&
388 MCI.getOperand(2).isImm() && isUInt<1>(MCI.getOperand(2).getImm())) {
389 return HexagonII::HSIG_S2;
392 case Hexagon::S4_storeirb_io:
393 // memb(Rs+#u4) = #U1
394 Src1Reg = MCI.getOperand(0).getReg();
395 if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
396 MCI.getOperand(1).isImm() && isUInt<4>(MCI.getOperand(1).getImm()) &&
397 MCI.getOperand(2).isImm() && MCI.getOperand(2).isImm() &&
398 isUInt<1>(MCI.getOperand(2).getImm())) {
399 return HexagonII::HSIG_S2;
402 case Hexagon::S2_allocframe:
403 if (MCI.getOperand(0).isImm() &&
404 isShiftedUInt<5, 3>(MCI.getOperand(0).getImm())) {
405 return HexagonII::HSIG_S2;
415 // if ([!]P0[.new]) Rd = #0
416 // Rd = add(r29,#u6:2)
418 // P0 = cmp.eq(Rs,#u2)
419 // Rdd = combine(#0,Rs)
420 // Rdd = combine(Rs,#0)
421 // Rdd = combine(#u2,#U2)
424 // Rd = sxth/sxtb/zxtb/zxth(Rs)
426 case Hexagon::A2_addi:
427 DstReg = MCI.getOperand(0).getReg();
428 SrcReg = MCI.getOperand(1).getReg();
429 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
430 // Rd = add(r29,#u6:2)
431 if (HexagonMCInstrInfo::isIntReg(SrcReg) && Hexagon::R29 == SrcReg &&
432 MCI.getOperand(2).isImm() &&
433 isShiftedUInt<6, 2>(MCI.getOperand(2).getImm())) {
434 return HexagonII::HSIG_A;
437 if (DstReg == SrcReg) {
438 return HexagonII::HSIG_A;
442 if (HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
443 MCI.getOperand(2).isImm() && ((MCI.getOperand(2).getImm() == 1) ||
444 (MCI.getOperand(2).getImm() == -1))) {
445 return HexagonII::HSIG_A;
449 case Hexagon::A2_add:
451 DstReg = MCI.getOperand(0).getReg();
452 Src1Reg = MCI.getOperand(1).getReg();
453 Src2Reg = MCI.getOperand(2).getReg();
454 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) && (DstReg == Src1Reg) &&
455 HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg)) {
456 return HexagonII::HSIG_A;
459 case Hexagon::A2_andir:
460 DstReg = MCI.getOperand(0).getReg();
461 SrcReg = MCI.getOperand(1).getReg();
462 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
463 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
464 MCI.getOperand(2).isImm() && ((MCI.getOperand(2).getImm() == 1) ||
465 (MCI.getOperand(2).getImm() == 255))) {
466 return HexagonII::HSIG_A;
469 case Hexagon::A2_tfr:
471 DstReg = MCI.getOperand(0).getReg();
472 SrcReg = MCI.getOperand(1).getReg();
473 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
474 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg)) {
475 return HexagonII::HSIG_A;
478 case Hexagon::A2_tfrsi:
479 DstReg = MCI.getOperand(0).getReg();
481 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
482 return HexagonII::HSIG_A;
485 case Hexagon::C2_cmoveit:
486 case Hexagon::C2_cmovenewit:
487 case Hexagon::C2_cmoveif:
488 case Hexagon::C2_cmovenewif:
489 // if ([!]P0[.new]) Rd = #0
491 // %R16<def> = C2_cmovenewit %P0<internal>, 0, %R16<imp-use,undef>;
492 DstReg = MCI.getOperand(0).getReg(); // Rd
493 PredReg = MCI.getOperand(1).getReg(); // P0
494 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
495 Hexagon::P0 == PredReg && MCI.getOperand(2).isImm() &&
496 MCI.getOperand(2).getImm() == 0) {
497 return HexagonII::HSIG_A;
500 case Hexagon::C2_cmpeqi:
501 // P0 = cmp.eq(Rs,#u2)
502 DstReg = MCI.getOperand(0).getReg();
503 SrcReg = MCI.getOperand(1).getReg();
504 if (Hexagon::P0 == DstReg &&
505 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
506 MCI.getOperand(2).isImm() && isUInt<2>(MCI.getOperand(2).getImm())) {
507 return HexagonII::HSIG_A;
510 case Hexagon::A2_combineii:
511 case Hexagon::A4_combineii:
512 // Rdd = combine(#u2,#U2)
513 DstReg = MCI.getOperand(0).getReg();
514 if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
515 // TODO: Handle Globals/Symbols
516 (MCI.getOperand(1).isImm() && isUInt<2>(MCI.getOperand(1).getImm())) &&
517 ((MCI.getOperand(2).isImm() &&
518 isUInt<2>(MCI.getOperand(2).getImm())))) {
519 return HexagonII::HSIG_A;
522 case Hexagon::A4_combineri:
523 // Rdd = combine(Rs,#0)
524 DstReg = MCI.getOperand(0).getReg();
525 SrcReg = MCI.getOperand(1).getReg();
526 if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
527 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
528 (MCI.getOperand(2).isImm() && MCI.getOperand(2).getImm() == 0)) {
529 return HexagonII::HSIG_A;
532 case Hexagon::A4_combineir:
533 // Rdd = combine(#0,Rs)
534 DstReg = MCI.getOperand(0).getReg();
535 SrcReg = MCI.getOperand(2).getReg();
536 if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
537 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
538 (MCI.getOperand(1).isImm() && MCI.getOperand(1).getImm() == 0)) {
539 return HexagonII::HSIG_A;
542 case Hexagon::A2_sxtb:
543 case Hexagon::A2_sxth:
544 case Hexagon::A2_zxtb:
545 case Hexagon::A2_zxth:
546 // Rd = sxth/sxtb/zxtb/zxth(Rs)
547 DstReg = MCI.getOperand(0).getReg();
548 SrcReg = MCI.getOperand(1).getReg();
549 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
550 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg)) {
551 return HexagonII::HSIG_A;
556 return HexagonII::HSIG_None;
559 bool HexagonMCInstrInfo::subInstWouldBeExtended(MCInst const &potentialDuplex) {
561 unsigned DstReg, SrcReg;
563 switch (potentialDuplex.getOpcode()) {
564 case Hexagon::A2_addi:
565 // testing for case of: Rx = add(Rx,#s7)
566 DstReg = potentialDuplex.getOperand(0).getReg();
567 SrcReg = potentialDuplex.getOperand(1).getReg();
568 if (DstReg == SrcReg && HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
569 if (potentialDuplex.getOperand(2).isExpr())
571 if (potentialDuplex.getOperand(2).isImm() &&
572 !(isShiftedInt<7, 0>(potentialDuplex.getOperand(2).getImm())))
576 case Hexagon::A2_tfrsi:
577 DstReg = potentialDuplex.getOperand(0).getReg();
579 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
580 if (potentialDuplex.getOperand(1).isExpr())
582 // Check for case of Rd = #-1.
583 if (potentialDuplex.getOperand(1).isImm() &&
584 (potentialDuplex.getOperand(1).getImm() == -1))
586 // Check for case of Rd = #u6.
587 if (potentialDuplex.getOperand(1).isImm() &&
588 !isShiftedUInt<6, 0>(potentialDuplex.getOperand(1).getImm()))
598 /// non-Symmetrical. See if these two instructions are fit for duplex pair.
599 bool HexagonMCInstrInfo::isOrderedDuplexPair(MCInstrInfo const &MCII,
600 MCInst const &MIa, bool ExtendedA,
601 MCInst const &MIb, bool ExtendedB,
602 bool bisReversable) {
603 // Slot 1 cannot be extended in duplexes PRM 10.5
606 // Only A2_addi and A2_tfrsi can be extended in duplex form PRM 10.5
608 unsigned Opcode = MIb.getOpcode();
609 if ((Opcode != Hexagon::A2_addi) && (Opcode != Hexagon::A2_tfrsi))
612 unsigned MIaG = HexagonMCInstrInfo::getDuplexCandidateGroup(MIa),
613 MIbG = HexagonMCInstrInfo::getDuplexCandidateGroup(MIb);
615 // If a duplex contains 2 insns in the same group, the insns must be
616 // ordered such that the numerically smaller opcode is in slot 1.
617 if ((MIaG != HexagonII::HSIG_None) && (MIaG == MIbG) && bisReversable) {
618 MCInst SubInst0 = HexagonMCInstrInfo::deriveSubInst(MIa);
619 MCInst SubInst1 = HexagonMCInstrInfo::deriveSubInst(MIb);
621 unsigned zeroedSubInstS0 =
622 subinstOpcodeMap.find(SubInst0.getOpcode())->second;
623 unsigned zeroedSubInstS1 =
624 subinstOpcodeMap.find(SubInst1.getOpcode())->second;
626 if (zeroedSubInstS0 < zeroedSubInstS1)
627 // subinstS0 (maps to slot 0) must be greater than
628 // subinstS1 (maps to slot 1)
632 // allocframe must always be in slot 0
633 if (MIb.getOpcode() == Hexagon::S2_allocframe)
636 if ((MIaG != HexagonII::HSIG_None) && (MIbG != HexagonII::HSIG_None)) {
637 // Prevent 2 instructions with extenders from duplexing
638 // Note that MIb (slot1) can be extended and MIa (slot0)
639 // can never be extended
640 if (subInstWouldBeExtended(MIa))
643 // If duplexing produces an extender, but the original did not
644 // have an extender, do not duplex.
645 if (subInstWouldBeExtended(MIb) && !ExtendedB)
649 // If jumpr r31 appears, it must be in slot 0, and never slot 1 (MIb).
650 if (MIbG == HexagonII::HSIG_L2) {
651 if ((MIb.getNumOperands() > 1) && MIb.getOperand(1).isReg() &&
652 (MIb.getOperand(1).getReg() == Hexagon::R31))
654 if ((MIb.getNumOperands() > 0) && MIb.getOperand(0).isReg() &&
655 (MIb.getOperand(0).getReg() == Hexagon::R31))
659 // If a store appears, it must be in slot 0 (MIa) 1st, and then slot 1 (MIb);
660 // therefore, not duplexable if slot 1 is a store, and slot 0 is not.
661 if ((MIbG == HexagonII::HSIG_S1) || (MIbG == HexagonII::HSIG_S2)) {
662 if ((MIaG != HexagonII::HSIG_S1) && (MIaG != HexagonII::HSIG_S2))
666 return (isDuplexPairMatch(MIaG, MIbG));
669 /// Symmetrical. See if these two instructions are fit for duplex pair.
670 bool HexagonMCInstrInfo::isDuplexPair(MCInst const &MIa, MCInst const &MIb) {
671 unsigned MIaG = getDuplexCandidateGroup(MIa),
672 MIbG = getDuplexCandidateGroup(MIb);
673 return (isDuplexPairMatch(MIaG, MIbG) || isDuplexPairMatch(MIbG, MIaG));
676 inline static void addOps(MCInst &subInstPtr, MCInst const &Inst,
678 if (Inst.getOperand(opNum).isReg()) {
679 switch (Inst.getOperand(opNum).getReg()) {
681 llvm_unreachable("Not Duplexable Register");
707 subInstPtr.addOperand(Inst.getOperand(opNum));
711 subInstPtr.addOperand(Inst.getOperand(opNum));
714 MCInst HexagonMCInstrInfo::deriveSubInst(MCInst const &Inst) {
716 switch (Inst.getOpcode()) {
718 // dbgs() << "opcode: "<< Inst->getOpcode() << "\n";
719 llvm_unreachable("Unimplemented subinstruction \n");
721 case Hexagon::A2_addi:
722 if (Inst.getOperand(2).isImm() && Inst.getOperand(2).getImm() == 1) {
723 Result.setOpcode(Hexagon::V4_SA1_inc);
724 addOps(Result, Inst, 0);
725 addOps(Result, Inst, 1);
727 } // 1,2 SUBInst $Rd = add($Rs, #1)
728 else if (Inst.getOperand(2).isImm() && Inst.getOperand(2).getImm() == -1) {
729 Result.setOpcode(Hexagon::V4_SA1_dec);
730 addOps(Result, Inst, 0);
731 addOps(Result, Inst, 1);
733 } // 1,2 SUBInst $Rd = add($Rs,#-1)
734 else if (Inst.getOperand(1).getReg() == Hexagon::R29) {
735 Result.setOpcode(Hexagon::V4_SA1_addsp);
736 addOps(Result, Inst, 0);
737 addOps(Result, Inst, 2);
739 } // 1,3 SUBInst $Rd = add(r29, #$u6_2)
741 Result.setOpcode(Hexagon::V4_SA1_addi);
742 addOps(Result, Inst, 0);
743 addOps(Result, Inst, 1);
744 addOps(Result, Inst, 2);
746 } // 1,2,3 SUBInst $Rx = add($Rx, #$s7)
747 case Hexagon::A2_add:
748 Result.setOpcode(Hexagon::V4_SA1_addrx);
749 addOps(Result, Inst, 0);
750 addOps(Result, Inst, 1);
751 addOps(Result, Inst, 2);
752 break; // 1,2,3 SUBInst $Rx = add($_src_, $Rs)
753 case Hexagon::S2_allocframe:
754 Result.setOpcode(Hexagon::V4_SS2_allocframe);
755 addOps(Result, Inst, 0);
756 break; // 1 SUBInst allocframe(#$u5_3)
757 case Hexagon::A2_andir:
758 if (Inst.getOperand(2).getImm() == 255) {
759 Result.setOpcode(Hexagon::V4_SA1_zxtb);
760 addOps(Result, Inst, 0);
761 addOps(Result, Inst, 1);
762 break; // 1,2 $Rd = and($Rs, #255)
764 Result.setOpcode(Hexagon::V4_SA1_and1);
765 addOps(Result, Inst, 0);
766 addOps(Result, Inst, 1);
767 break; // 1,2 SUBInst $Rd = and($Rs, #1)
769 case Hexagon::C2_cmpeqi:
770 Result.setOpcode(Hexagon::V4_SA1_cmpeqi);
771 addOps(Result, Inst, 1);
772 addOps(Result, Inst, 2);
773 break; // 2,3 SUBInst p0 = cmp.eq($Rs, #$u2)
774 case Hexagon::A4_combineii:
775 case Hexagon::A2_combineii:
776 if (Inst.getOperand(1).getImm() == 1) {
777 Result.setOpcode(Hexagon::V4_SA1_combine1i);
778 addOps(Result, Inst, 0);
779 addOps(Result, Inst, 2);
780 break; // 1,3 SUBInst $Rdd = combine(#1, #$u2)
783 if (Inst.getOperand(1).getImm() == 3) {
784 Result.setOpcode(Hexagon::V4_SA1_combine3i);
785 addOps(Result, Inst, 0);
786 addOps(Result, Inst, 2);
787 break; // 1,3 SUBInst $Rdd = combine(#3, #$u2)
789 if (Inst.getOperand(1).getImm() == 0) {
790 Result.setOpcode(Hexagon::V4_SA1_combine0i);
791 addOps(Result, Inst, 0);
792 addOps(Result, Inst, 2);
793 break; // 1,3 SUBInst $Rdd = combine(#0, #$u2)
795 if (Inst.getOperand(1).getImm() == 2) {
796 Result.setOpcode(Hexagon::V4_SA1_combine2i);
797 addOps(Result, Inst, 0);
798 addOps(Result, Inst, 2);
799 break; // 1,3 SUBInst $Rdd = combine(#2, #$u2)
801 case Hexagon::A4_combineir:
802 Result.setOpcode(Hexagon::V4_SA1_combinezr);
803 addOps(Result, Inst, 0);
804 addOps(Result, Inst, 2);
805 break; // 1,3 SUBInst $Rdd = combine(#0, $Rs)
807 case Hexagon::A4_combineri:
808 Result.setOpcode(Hexagon::V4_SA1_combinerz);
809 addOps(Result, Inst, 0);
810 addOps(Result, Inst, 1);
811 break; // 1,2 SUBInst $Rdd = combine($Rs, #0)
812 case Hexagon::L4_return_tnew_pnt:
813 case Hexagon::L4_return_tnew_pt:
814 Result.setOpcode(Hexagon::V4_SL2_return_tnew);
815 break; // none SUBInst if (p0.new) dealloc_return:nt
816 case Hexagon::L4_return_fnew_pnt:
817 case Hexagon::L4_return_fnew_pt:
818 Result.setOpcode(Hexagon::V4_SL2_return_fnew);
819 break; // none SUBInst if (!p0.new) dealloc_return:nt
820 case Hexagon::L4_return_f:
821 Result.setOpcode(Hexagon::V4_SL2_return_f);
822 break; // none SUBInst if (!p0) dealloc_return
823 case Hexagon::L4_return_t:
824 Result.setOpcode(Hexagon::V4_SL2_return_t);
825 break; // none SUBInst if (p0) dealloc_return
826 case Hexagon::L4_return:
827 Result.setOpcode(Hexagon::V4_SL2_return);
828 break; // none SUBInst dealloc_return
829 case Hexagon::L2_deallocframe:
830 Result.setOpcode(Hexagon::V4_SL2_deallocframe);
831 break; // none SUBInst deallocframe
832 case Hexagon::EH_RETURN_JMPR:
833 case Hexagon::J2_jumpr:
834 case Hexagon::JMPret:
835 Result.setOpcode(Hexagon::V4_SL2_jumpr31);
836 break; // none SUBInst jumpr r31
837 case Hexagon::J2_jumprf:
838 case Hexagon::JMPretf:
839 Result.setOpcode(Hexagon::V4_SL2_jumpr31_f);
840 break; // none SUBInst if (!p0) jumpr r31
841 case Hexagon::J2_jumprfnew:
842 case Hexagon::JMPretfnewpt:
843 case Hexagon::JMPretfnew:
844 Result.setOpcode(Hexagon::V4_SL2_jumpr31_fnew);
845 break; // none SUBInst if (!p0.new) jumpr:nt r31
846 case Hexagon::J2_jumprt:
847 case Hexagon::JMPrett:
848 Result.setOpcode(Hexagon::V4_SL2_jumpr31_t);
849 break; // none SUBInst if (p0) jumpr r31
850 case Hexagon::J2_jumprtnew:
851 case Hexagon::JMPrettnewpt:
852 case Hexagon::JMPrettnew:
853 Result.setOpcode(Hexagon::V4_SL2_jumpr31_tnew);
854 break; // none SUBInst if (p0.new) jumpr:nt r31
855 case Hexagon::L2_loadrb_io:
856 Result.setOpcode(Hexagon::V4_SL2_loadrb_io);
857 addOps(Result, Inst, 0);
858 addOps(Result, Inst, 1);
859 addOps(Result, Inst, 2);
860 break; // 1,2,3 SUBInst $Rd = memb($Rs + #$u3_0)
861 case Hexagon::L2_loadrd_io:
862 Result.setOpcode(Hexagon::V4_SL2_loadrd_sp);
863 addOps(Result, Inst, 0);
864 addOps(Result, Inst, 2);
865 break; // 1,3 SUBInst $Rdd = memd(r29 + #$u5_3)
866 case Hexagon::L2_loadrh_io:
867 Result.setOpcode(Hexagon::V4_SL2_loadrh_io);
868 addOps(Result, Inst, 0);
869 addOps(Result, Inst, 1);
870 addOps(Result, Inst, 2);
871 break; // 1,2,3 SUBInst $Rd = memh($Rs + #$u3_1)
872 case Hexagon::L2_loadrub_io:
873 Result.setOpcode(Hexagon::V4_SL1_loadrub_io);
874 addOps(Result, Inst, 0);
875 addOps(Result, Inst, 1);
876 addOps(Result, Inst, 2);
877 break; // 1,2,3 SUBInst $Rd = memub($Rs + #$u4_0)
878 case Hexagon::L2_loadruh_io:
879 Result.setOpcode(Hexagon::V4_SL2_loadruh_io);
880 addOps(Result, Inst, 0);
881 addOps(Result, Inst, 1);
882 addOps(Result, Inst, 2);
883 break; // 1,2,3 SUBInst $Rd = memuh($Rs + #$u3_1)
884 case Hexagon::L2_loadri_io:
885 if (Inst.getOperand(1).getReg() == Hexagon::R29) {
886 Result.setOpcode(Hexagon::V4_SL2_loadri_sp);
887 addOps(Result, Inst, 0);
888 addOps(Result, Inst, 2);
889 break; // 2 1,3 SUBInst $Rd = memw(r29 + #$u5_2)
891 Result.setOpcode(Hexagon::V4_SL1_loadri_io);
892 addOps(Result, Inst, 0);
893 addOps(Result, Inst, 1);
894 addOps(Result, Inst, 2);
895 break; // 1,2,3 SUBInst $Rd = memw($Rs + #$u4_2)
897 case Hexagon::S4_storeirb_io:
898 if (Inst.getOperand(2).getImm() == 0) {
899 Result.setOpcode(Hexagon::V4_SS2_storebi0);
900 addOps(Result, Inst, 0);
901 addOps(Result, Inst, 1);
902 break; // 1,2 SUBInst memb($Rs + #$u4_0)=#0
903 } else if (Inst.getOperand(2).getImm() == 1) {
904 Result.setOpcode(Hexagon::V4_SS2_storebi1);
905 addOps(Result, Inst, 0);
906 addOps(Result, Inst, 1);
907 break; // 2 1,2 SUBInst memb($Rs + #$u4_0)=#1
909 case Hexagon::S2_storerb_io:
910 Result.setOpcode(Hexagon::V4_SS1_storeb_io);
911 addOps(Result, Inst, 0);
912 addOps(Result, Inst, 1);
913 addOps(Result, Inst, 2);
914 break; // 1,2,3 SUBInst memb($Rs + #$u4_0) = $Rt
915 case Hexagon::S2_storerd_io:
916 Result.setOpcode(Hexagon::V4_SS2_stored_sp);
917 addOps(Result, Inst, 1);
918 addOps(Result, Inst, 2);
919 break; // 2,3 SUBInst memd(r29 + #$s6_3) = $Rtt
920 case Hexagon::S2_storerh_io:
921 Result.setOpcode(Hexagon::V4_SS2_storeh_io);
922 addOps(Result, Inst, 0);
923 addOps(Result, Inst, 1);
924 addOps(Result, Inst, 2);
925 break; // 1,2,3 SUBInst memb($Rs + #$u4_0) = $Rt
926 case Hexagon::S4_storeiri_io:
927 if (Inst.getOperand(2).getImm() == 0) {
928 Result.setOpcode(Hexagon::V4_SS2_storewi0);
929 addOps(Result, Inst, 0);
930 addOps(Result, Inst, 1);
931 break; // 3 1,2 SUBInst memw($Rs + #$u4_2)=#0
932 } else if (Inst.getOperand(2).getImm() == 1) {
933 Result.setOpcode(Hexagon::V4_SS2_storewi1);
934 addOps(Result, Inst, 0);
935 addOps(Result, Inst, 1);
936 break; // 3 1,2 SUBInst memw($Rs + #$u4_2)=#1
937 } else if (Inst.getOperand(0).getReg() == Hexagon::R29) {
938 Result.setOpcode(Hexagon::V4_SS2_storew_sp);
939 addOps(Result, Inst, 1);
940 addOps(Result, Inst, 2);
941 break; // 1 2,3 SUBInst memw(r29 + #$u5_2) = $Rt
943 case Hexagon::S2_storeri_io:
944 if (Inst.getOperand(0).getReg() == Hexagon::R29) {
945 Result.setOpcode(Hexagon::V4_SS2_storew_sp);
946 addOps(Result, Inst, 1);
947 addOps(Result, Inst, 2); // 1,2,3 SUBInst memw(sp + #$u5_2) = $Rt
949 Result.setOpcode(Hexagon::V4_SS1_storew_io);
950 addOps(Result, Inst, 0);
951 addOps(Result, Inst, 1);
952 addOps(Result, Inst, 2); // 1,2,3 SUBInst memw($Rs + #$u4_2) = $Rt
955 case Hexagon::A2_sxtb:
956 Result.setOpcode(Hexagon::V4_SA1_sxtb);
957 addOps(Result, Inst, 0);
958 addOps(Result, Inst, 1);
959 break; // 1,2 SUBInst $Rd = sxtb($Rs)
960 case Hexagon::A2_sxth:
961 Result.setOpcode(Hexagon::V4_SA1_sxth);
962 addOps(Result, Inst, 0);
963 addOps(Result, Inst, 1);
964 break; // 1,2 SUBInst $Rd = sxth($Rs)
965 case Hexagon::A2_tfr:
966 Result.setOpcode(Hexagon::V4_SA1_tfr);
967 addOps(Result, Inst, 0);
968 addOps(Result, Inst, 1);
969 break; // 1,2 SUBInst $Rd = $Rs
970 case Hexagon::C2_cmovenewif:
971 Result.setOpcode(Hexagon::V4_SA1_clrfnew);
972 addOps(Result, Inst, 0);
973 break; // 2 SUBInst if (!p0.new) $Rd = #0
974 case Hexagon::C2_cmovenewit:
975 Result.setOpcode(Hexagon::V4_SA1_clrtnew);
976 addOps(Result, Inst, 0);
977 break; // 2 SUBInst if (p0.new) $Rd = #0
978 case Hexagon::C2_cmoveif:
979 Result.setOpcode(Hexagon::V4_SA1_clrf);
980 addOps(Result, Inst, 0);
981 break; // 2 SUBInst if (!p0) $Rd = #0
982 case Hexagon::C2_cmoveit:
983 Result.setOpcode(Hexagon::V4_SA1_clrt);
984 addOps(Result, Inst, 0);
985 break; // 2 SUBInst if (p0) $Rd = #0
986 case Hexagon::A2_tfrsi:
987 if (Inst.getOperand(1).isImm() && Inst.getOperand(1).getImm() == -1) {
988 Result.setOpcode(Hexagon::V4_SA1_setin1);
989 addOps(Result, Inst, 0);
990 break; // 2 1 SUBInst $Rd = #-1
992 Result.setOpcode(Hexagon::V4_SA1_seti);
993 addOps(Result, Inst, 0);
994 addOps(Result, Inst, 1);
995 break; // 1,2 SUBInst $Rd = #$u6
997 case Hexagon::A2_zxtb:
998 Result.setOpcode(Hexagon::V4_SA1_zxtb);
999 addOps(Result, Inst, 0);
1000 addOps(Result, Inst, 1);
1001 break; // 1,2 $Rd = and($Rs, #255)
1003 case Hexagon::A2_zxth:
1004 Result.setOpcode(Hexagon::V4_SA1_zxth);
1005 addOps(Result, Inst, 0);
1006 addOps(Result, Inst, 1);
1007 break; // 1,2 SUBInst $Rd = zxth($Rs)
1012 static bool isStoreInst(unsigned opCode) {
1014 case Hexagon::S2_storeri_io:
1015 case Hexagon::S2_storerb_io:
1016 case Hexagon::S2_storerh_io:
1017 case Hexagon::S2_storerd_io:
1018 case Hexagon::S4_storeiri_io:
1019 case Hexagon::S4_storeirb_io:
1020 case Hexagon::S2_allocframe:
1027 SmallVector<DuplexCandidate, 8>
1028 HexagonMCInstrInfo::getDuplexPossibilties(MCInstrInfo const &MCII,
1029 MCInst const &MCB) {
1030 assert(isBundle(MCB));
1031 SmallVector<DuplexCandidate, 8> duplexToTry;
1032 // Use an "order matters" version of isDuplexPair.
1033 unsigned numInstrInPacket = MCB.getNumOperands();
1035 for (unsigned distance = 1; distance < numInstrInPacket; ++distance) {
1036 for (unsigned j = HexagonMCInstrInfo::bundleInstructionsOffset,
1038 (j < numInstrInPacket) && (k < numInstrInPacket); ++j, ++k) {
1040 // Check if reversable.
1041 bool bisReversable = true;
1042 if (isStoreInst(MCB.getOperand(j).getInst()->getOpcode()) &&
1043 isStoreInst(MCB.getOperand(k).getInst()->getOpcode())) {
1044 DEBUG(dbgs() << "skip out of order write pair: " << k << "," << j
1046 bisReversable = false;
1050 if (isOrderedDuplexPair(
1051 MCII, *MCB.getOperand(k).getInst(),
1052 HexagonMCInstrInfo::hasExtenderForIndex(MCB, k - 1),
1053 *MCB.getOperand(j).getInst(),
1054 HexagonMCInstrInfo::hasExtenderForIndex(MCB, j - 1),
1057 unsigned iClass = iClassOfDuplexPair(
1058 getDuplexCandidateGroup(*MCB.getOperand(k).getInst()),
1059 getDuplexCandidateGroup(*MCB.getOperand(j).getInst()));
1061 // Save off pairs for duplex checking.
1062 duplexToTry.push_back(DuplexCandidate(j, k, iClass));
1063 DEBUG(dbgs() << "adding pair: " << j << "," << k << ":"
1064 << MCB.getOperand(j).getInst()->getOpcode() << ","
1065 << MCB.getOperand(k).getInst()->getOpcode() << "\n");
1068 DEBUG(dbgs() << "skipping pair: " << j << "," << k << ":"
1069 << MCB.getOperand(j).getInst()->getOpcode() << ","
1070 << MCB.getOperand(k).getInst()->getOpcode() << "\n");
1074 if (bisReversable) {
1075 if (isOrderedDuplexPair(
1076 MCII, *MCB.getOperand(j).getInst(),
1077 HexagonMCInstrInfo::hasExtenderForIndex(MCB, j - 1),
1078 *MCB.getOperand(k).getInst(),
1079 HexagonMCInstrInfo::hasExtenderForIndex(MCB, k - 1),
1082 unsigned iClass = iClassOfDuplexPair(
1083 getDuplexCandidateGroup(*MCB.getOperand(j).getInst()),
1084 getDuplexCandidateGroup(*MCB.getOperand(k).getInst()));
1086 // Save off pairs for duplex checking.
1087 duplexToTry.push_back(DuplexCandidate(k, j, iClass));
1088 DEBUG(dbgs() << "adding pair:" << k << "," << j << ":"
1089 << MCB.getOperand(j).getInst()->getOpcode() << ","
1090 << MCB.getOperand(k).getInst()->getOpcode() << "\n");
1092 DEBUG(dbgs() << "skipping pair: " << k << "," << j << ":"
1093 << MCB.getOperand(j).getInst()->getOpcode() << ","
1094 << MCB.getOperand(k).getInst()->getOpcode() << "\n");