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) && 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() && isUInt<1>(MCI.getOperand(2).getImm())) {
398 return HexagonII::HSIG_S2;
401 case Hexagon::S2_allocframe:
402 if (MCI.getOperand(0).isImm() &&
403 isShiftedUInt<5, 3>(MCI.getOperand(0).getImm())) {
404 return HexagonII::HSIG_S2;
414 // if ([!]P0[.new]) Rd = #0
415 // Rd = add(r29,#u6:2)
417 // P0 = cmp.eq(Rs,#u2)
418 // Rdd = combine(#0,Rs)
419 // Rdd = combine(Rs,#0)
420 // Rdd = combine(#u2,#U2)
423 // Rd = sxth/sxtb/zxtb/zxth(Rs)
425 case Hexagon::A2_addi:
426 DstReg = MCI.getOperand(0).getReg();
427 SrcReg = MCI.getOperand(1).getReg();
428 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
429 // Rd = add(r29,#u6:2)
430 if (HexagonMCInstrInfo::isIntReg(SrcReg) && Hexagon::R29 == SrcReg &&
431 MCI.getOperand(2).isImm() &&
432 isShiftedUInt<6, 2>(MCI.getOperand(2).getImm())) {
433 return HexagonII::HSIG_A;
436 if (DstReg == SrcReg) {
437 return HexagonII::HSIG_A;
441 if (HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
442 MCI.getOperand(2).isImm() && ((MCI.getOperand(2).getImm() == 1) ||
443 (MCI.getOperand(2).getImm() == -1))) {
444 return HexagonII::HSIG_A;
448 case Hexagon::A2_add:
450 DstReg = MCI.getOperand(0).getReg();
451 Src1Reg = MCI.getOperand(1).getReg();
452 Src2Reg = MCI.getOperand(2).getReg();
453 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) && (DstReg == Src1Reg) &&
454 HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg)) {
455 return HexagonII::HSIG_A;
458 case Hexagon::A2_andir:
459 DstReg = MCI.getOperand(0).getReg();
460 SrcReg = MCI.getOperand(1).getReg();
461 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
462 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
463 MCI.getOperand(2).isImm() && ((MCI.getOperand(2).getImm() == 1) ||
464 (MCI.getOperand(2).getImm() == 255))) {
465 return HexagonII::HSIG_A;
468 case Hexagon::A2_tfr:
470 DstReg = MCI.getOperand(0).getReg();
471 SrcReg = MCI.getOperand(1).getReg();
472 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
473 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg)) {
474 return HexagonII::HSIG_A;
477 case Hexagon::A2_tfrsi:
478 DstReg = MCI.getOperand(0).getReg();
480 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
481 return HexagonII::HSIG_A;
484 case Hexagon::C2_cmoveit:
485 case Hexagon::C2_cmovenewit:
486 case Hexagon::C2_cmoveif:
487 case Hexagon::C2_cmovenewif:
488 // if ([!]P0[.new]) Rd = #0
490 // %R16<def> = C2_cmovenewit %P0<internal>, 0, %R16<imp-use,undef>;
491 DstReg = MCI.getOperand(0).getReg(); // Rd
492 PredReg = MCI.getOperand(1).getReg(); // P0
493 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
494 Hexagon::P0 == PredReg && MCI.getOperand(2).isImm() &&
495 MCI.getOperand(2).getImm() == 0) {
496 return HexagonII::HSIG_A;
499 case Hexagon::C2_cmpeqi:
500 // P0 = cmp.eq(Rs,#u2)
501 DstReg = MCI.getOperand(0).getReg();
502 SrcReg = MCI.getOperand(1).getReg();
503 if (Hexagon::P0 == DstReg &&
504 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
505 MCI.getOperand(2).isImm() && isUInt<2>(MCI.getOperand(2).getImm())) {
506 return HexagonII::HSIG_A;
509 case Hexagon::A2_combineii:
510 case Hexagon::A4_combineii:
511 // Rdd = combine(#u2,#U2)
512 DstReg = MCI.getOperand(0).getReg();
513 if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
514 // TODO: Handle Globals/Symbols
515 (MCI.getOperand(1).isImm() && isUInt<2>(MCI.getOperand(1).getImm())) &&
516 ((MCI.getOperand(2).isImm() &&
517 isUInt<2>(MCI.getOperand(2).getImm())))) {
518 return HexagonII::HSIG_A;
521 case Hexagon::A4_combineri:
522 // Rdd = combine(Rs,#0)
523 DstReg = MCI.getOperand(0).getReg();
524 SrcReg = MCI.getOperand(1).getReg();
525 if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
526 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
527 (MCI.getOperand(2).isImm() && MCI.getOperand(2).getImm() == 0)) {
528 return HexagonII::HSIG_A;
531 case Hexagon::A4_combineir:
532 // Rdd = combine(#0,Rs)
533 DstReg = MCI.getOperand(0).getReg();
534 SrcReg = MCI.getOperand(2).getReg();
535 if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
536 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
537 (MCI.getOperand(1).isImm() && MCI.getOperand(1).getImm() == 0)) {
538 return HexagonII::HSIG_A;
541 case Hexagon::A2_sxtb:
542 case Hexagon::A2_sxth:
543 case Hexagon::A2_zxtb:
544 case Hexagon::A2_zxth:
545 // Rd = sxth/sxtb/zxtb/zxth(Rs)
546 DstReg = MCI.getOperand(0).getReg();
547 SrcReg = MCI.getOperand(1).getReg();
548 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
549 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg)) {
550 return HexagonII::HSIG_A;
555 return HexagonII::HSIG_None;
558 bool HexagonMCInstrInfo::subInstWouldBeExtended(MCInst const &potentialDuplex) {
560 unsigned DstReg, SrcReg;
562 switch (potentialDuplex.getOpcode()) {
563 case Hexagon::A2_addi:
564 // testing for case of: Rx = add(Rx,#s7)
565 DstReg = potentialDuplex.getOperand(0).getReg();
566 SrcReg = potentialDuplex.getOperand(1).getReg();
567 if (DstReg == SrcReg && HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
568 if (potentialDuplex.getOperand(2).isExpr())
570 if (potentialDuplex.getOperand(2).isImm() &&
571 !(isShiftedInt<7, 0>(potentialDuplex.getOperand(2).getImm())))
575 case Hexagon::A2_tfrsi:
576 DstReg = potentialDuplex.getOperand(0).getReg();
578 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
579 if (potentialDuplex.getOperand(1).isExpr())
581 // Check for case of Rd = #-1.
582 if (potentialDuplex.getOperand(1).isImm() &&
583 (potentialDuplex.getOperand(1).getImm() == -1))
585 // Check for case of Rd = #u6.
586 if (potentialDuplex.getOperand(1).isImm() &&
587 !isShiftedUInt<6, 0>(potentialDuplex.getOperand(1).getImm()))
597 /// non-Symmetrical. See if these two instructions are fit for duplex pair.
598 bool HexagonMCInstrInfo::isOrderedDuplexPair(MCInstrInfo const &MCII,
599 MCInst const &MIa, bool ExtendedA,
600 MCInst const &MIb, bool ExtendedB,
601 bool bisReversable) {
602 // Slot 1 cannot be extended in duplexes PRM 10.5
605 // Only A2_addi and A2_tfrsi can be extended in duplex form PRM 10.5
607 unsigned Opcode = MIb.getOpcode();
608 if ((Opcode != Hexagon::A2_addi) && (Opcode != Hexagon::A2_tfrsi))
611 unsigned MIaG = HexagonMCInstrInfo::getDuplexCandidateGroup(MIa),
612 MIbG = HexagonMCInstrInfo::getDuplexCandidateGroup(MIb);
614 // If a duplex contains 2 insns in the same group, the insns must be
615 // ordered such that the numerically smaller opcode is in slot 1.
616 if ((MIaG != HexagonII::HSIG_None) && (MIaG == MIbG) && bisReversable) {
617 MCInst SubInst0 = HexagonMCInstrInfo::deriveSubInst(MIa);
618 MCInst SubInst1 = HexagonMCInstrInfo::deriveSubInst(MIb);
620 unsigned zeroedSubInstS0 =
621 subinstOpcodeMap.find(SubInst0.getOpcode())->second;
622 unsigned zeroedSubInstS1 =
623 subinstOpcodeMap.find(SubInst1.getOpcode())->second;
625 if (zeroedSubInstS0 < zeroedSubInstS1)
626 // subinstS0 (maps to slot 0) must be greater than
627 // subinstS1 (maps to slot 1)
631 // allocframe must always be in slot 0
632 if (MIb.getOpcode() == Hexagon::S2_allocframe)
635 if ((MIaG != HexagonII::HSIG_None) && (MIbG != HexagonII::HSIG_None)) {
636 // Prevent 2 instructions with extenders from duplexing
637 // Note that MIb (slot1) can be extended and MIa (slot0)
638 // can never be extended
639 if (subInstWouldBeExtended(MIa))
642 // If duplexing produces an extender, but the original did not
643 // have an extender, do not duplex.
644 if (subInstWouldBeExtended(MIb) && !ExtendedB)
648 // If jumpr r31 appears, it must be in slot 0, and never slot 1 (MIb).
649 if (MIbG == HexagonII::HSIG_L2) {
650 if ((MIb.getNumOperands() > 1) && MIb.getOperand(1).isReg() &&
651 (MIb.getOperand(1).getReg() == Hexagon::R31))
653 if ((MIb.getNumOperands() > 0) && MIb.getOperand(0).isReg() &&
654 (MIb.getOperand(0).getReg() == Hexagon::R31))
658 // If a store appears, it must be in slot 0 (MIa) 1st, and then slot 1 (MIb);
659 // therefore, not duplexable if slot 1 is a store, and slot 0 is not.
660 if ((MIbG == HexagonII::HSIG_S1) || (MIbG == HexagonII::HSIG_S2)) {
661 if ((MIaG != HexagonII::HSIG_S1) && (MIaG != HexagonII::HSIG_S2))
665 return (isDuplexPairMatch(MIaG, MIbG));
668 /// Symmetrical. See if these two instructions are fit for duplex pair.
669 bool HexagonMCInstrInfo::isDuplexPair(MCInst const &MIa, MCInst const &MIb) {
670 unsigned MIaG = getDuplexCandidateGroup(MIa),
671 MIbG = getDuplexCandidateGroup(MIb);
672 return (isDuplexPairMatch(MIaG, MIbG) || isDuplexPairMatch(MIbG, MIaG));
675 inline static void addOps(MCInst &subInstPtr, MCInst const &Inst,
677 if (Inst.getOperand(opNum).isReg()) {
678 switch (Inst.getOperand(opNum).getReg()) {
680 llvm_unreachable("Not Duplexable Register");
706 subInstPtr.addOperand(Inst.getOperand(opNum));
710 subInstPtr.addOperand(Inst.getOperand(opNum));
713 MCInst HexagonMCInstrInfo::deriveSubInst(MCInst const &Inst) {
715 switch (Inst.getOpcode()) {
717 // dbgs() << "opcode: "<< Inst->getOpcode() << "\n";
718 llvm_unreachable("Unimplemented subinstruction \n");
720 case Hexagon::A2_addi:
721 if (Inst.getOperand(2).isImm() && Inst.getOperand(2).getImm() == 1) {
722 Result.setOpcode(Hexagon::V4_SA1_inc);
723 addOps(Result, Inst, 0);
724 addOps(Result, Inst, 1);
726 } // 1,2 SUBInst $Rd = add($Rs, #1)
727 else if (Inst.getOperand(2).isImm() && Inst.getOperand(2).getImm() == -1) {
728 Result.setOpcode(Hexagon::V4_SA1_dec);
729 addOps(Result, Inst, 0);
730 addOps(Result, Inst, 1);
732 } // 1,2 SUBInst $Rd = add($Rs,#-1)
733 else if (Inst.getOperand(1).getReg() == Hexagon::R29) {
734 Result.setOpcode(Hexagon::V4_SA1_addsp);
735 addOps(Result, Inst, 0);
736 addOps(Result, Inst, 2);
738 } // 1,3 SUBInst $Rd = add(r29, #$u6_2)
740 Result.setOpcode(Hexagon::V4_SA1_addi);
741 addOps(Result, Inst, 0);
742 addOps(Result, Inst, 1);
743 addOps(Result, Inst, 2);
745 } // 1,2,3 SUBInst $Rx = add($Rx, #$s7)
746 case Hexagon::A2_add:
747 Result.setOpcode(Hexagon::V4_SA1_addrx);
748 addOps(Result, Inst, 0);
749 addOps(Result, Inst, 1);
750 addOps(Result, Inst, 2);
751 break; // 1,2,3 SUBInst $Rx = add($_src_, $Rs)
752 case Hexagon::S2_allocframe:
753 Result.setOpcode(Hexagon::V4_SS2_allocframe);
754 addOps(Result, Inst, 0);
755 break; // 1 SUBInst allocframe(#$u5_3)
756 case Hexagon::A2_andir:
757 if (Inst.getOperand(2).getImm() == 255) {
758 Result.setOpcode(Hexagon::V4_SA1_zxtb);
759 addOps(Result, Inst, 0);
760 addOps(Result, Inst, 1);
761 break; // 1,2 $Rd = and($Rs, #255)
763 Result.setOpcode(Hexagon::V4_SA1_and1);
764 addOps(Result, Inst, 0);
765 addOps(Result, Inst, 1);
766 break; // 1,2 SUBInst $Rd = and($Rs, #1)
768 case Hexagon::C2_cmpeqi:
769 Result.setOpcode(Hexagon::V4_SA1_cmpeqi);
770 addOps(Result, Inst, 1);
771 addOps(Result, Inst, 2);
772 break; // 2,3 SUBInst p0 = cmp.eq($Rs, #$u2)
773 case Hexagon::A4_combineii:
774 case Hexagon::A2_combineii:
775 if (Inst.getOperand(1).getImm() == 1) {
776 Result.setOpcode(Hexagon::V4_SA1_combine1i);
777 addOps(Result, Inst, 0);
778 addOps(Result, Inst, 2);
779 break; // 1,3 SUBInst $Rdd = combine(#1, #$u2)
782 if (Inst.getOperand(1).getImm() == 3) {
783 Result.setOpcode(Hexagon::V4_SA1_combine3i);
784 addOps(Result, Inst, 0);
785 addOps(Result, Inst, 2);
786 break; // 1,3 SUBInst $Rdd = combine(#3, #$u2)
788 if (Inst.getOperand(1).getImm() == 0) {
789 Result.setOpcode(Hexagon::V4_SA1_combine0i);
790 addOps(Result, Inst, 0);
791 addOps(Result, Inst, 2);
792 break; // 1,3 SUBInst $Rdd = combine(#0, #$u2)
794 if (Inst.getOperand(1).getImm() == 2) {
795 Result.setOpcode(Hexagon::V4_SA1_combine2i);
796 addOps(Result, Inst, 0);
797 addOps(Result, Inst, 2);
798 break; // 1,3 SUBInst $Rdd = combine(#2, #$u2)
800 case Hexagon::A4_combineir:
801 Result.setOpcode(Hexagon::V4_SA1_combinezr);
802 addOps(Result, Inst, 0);
803 addOps(Result, Inst, 2);
804 break; // 1,3 SUBInst $Rdd = combine(#0, $Rs)
806 case Hexagon::A4_combineri:
807 Result.setOpcode(Hexagon::V4_SA1_combinerz);
808 addOps(Result, Inst, 0);
809 addOps(Result, Inst, 1);
810 break; // 1,2 SUBInst $Rdd = combine($Rs, #0)
811 case Hexagon::L4_return_tnew_pnt:
812 case Hexagon::L4_return_tnew_pt:
813 Result.setOpcode(Hexagon::V4_SL2_return_tnew);
814 break; // none SUBInst if (p0.new) dealloc_return:nt
815 case Hexagon::L4_return_fnew_pnt:
816 case Hexagon::L4_return_fnew_pt:
817 Result.setOpcode(Hexagon::V4_SL2_return_fnew);
818 break; // none SUBInst if (!p0.new) dealloc_return:nt
819 case Hexagon::L4_return_f:
820 Result.setOpcode(Hexagon::V4_SL2_return_f);
821 break; // none SUBInst if (!p0) dealloc_return
822 case Hexagon::L4_return_t:
823 Result.setOpcode(Hexagon::V4_SL2_return_t);
824 break; // none SUBInst if (p0) dealloc_return
825 case Hexagon::L4_return:
826 Result.setOpcode(Hexagon::V4_SL2_return);
827 break; // none SUBInst dealloc_return
828 case Hexagon::L2_deallocframe:
829 Result.setOpcode(Hexagon::V4_SL2_deallocframe);
830 break; // none SUBInst deallocframe
831 case Hexagon::EH_RETURN_JMPR:
832 case Hexagon::J2_jumpr:
833 case Hexagon::JMPret:
834 Result.setOpcode(Hexagon::V4_SL2_jumpr31);
835 break; // none SUBInst jumpr r31
836 case Hexagon::J2_jumprf:
837 case Hexagon::JMPretf:
838 Result.setOpcode(Hexagon::V4_SL2_jumpr31_f);
839 break; // none SUBInst if (!p0) jumpr r31
840 case Hexagon::J2_jumprfnew:
841 case Hexagon::JMPretfnewpt:
842 case Hexagon::JMPretfnew:
843 Result.setOpcode(Hexagon::V4_SL2_jumpr31_fnew);
844 break; // none SUBInst if (!p0.new) jumpr:nt r31
845 case Hexagon::J2_jumprt:
846 case Hexagon::JMPrett:
847 Result.setOpcode(Hexagon::V4_SL2_jumpr31_t);
848 break; // none SUBInst if (p0) jumpr r31
849 case Hexagon::J2_jumprtnew:
850 case Hexagon::JMPrettnewpt:
851 case Hexagon::JMPrettnew:
852 Result.setOpcode(Hexagon::V4_SL2_jumpr31_tnew);
853 break; // none SUBInst if (p0.new) jumpr:nt r31
854 case Hexagon::L2_loadrb_io:
855 Result.setOpcode(Hexagon::V4_SL2_loadrb_io);
856 addOps(Result, Inst, 0);
857 addOps(Result, Inst, 1);
858 addOps(Result, Inst, 2);
859 break; // 1,2,3 SUBInst $Rd = memb($Rs + #$u3_0)
860 case Hexagon::L2_loadrd_io:
861 Result.setOpcode(Hexagon::V4_SL2_loadrd_sp);
862 addOps(Result, Inst, 0);
863 addOps(Result, Inst, 2);
864 break; // 1,3 SUBInst $Rdd = memd(r29 + #$u5_3)
865 case Hexagon::L2_loadrh_io:
866 Result.setOpcode(Hexagon::V4_SL2_loadrh_io);
867 addOps(Result, Inst, 0);
868 addOps(Result, Inst, 1);
869 addOps(Result, Inst, 2);
870 break; // 1,2,3 SUBInst $Rd = memh($Rs + #$u3_1)
871 case Hexagon::L2_loadrub_io:
872 Result.setOpcode(Hexagon::V4_SL1_loadrub_io);
873 addOps(Result, Inst, 0);
874 addOps(Result, Inst, 1);
875 addOps(Result, Inst, 2);
876 break; // 1,2,3 SUBInst $Rd = memub($Rs + #$u4_0)
877 case Hexagon::L2_loadruh_io:
878 Result.setOpcode(Hexagon::V4_SL2_loadruh_io);
879 addOps(Result, Inst, 0);
880 addOps(Result, Inst, 1);
881 addOps(Result, Inst, 2);
882 break; // 1,2,3 SUBInst $Rd = memuh($Rs + #$u3_1)
883 case Hexagon::L2_loadri_io:
884 if (Inst.getOperand(1).getReg() == Hexagon::R29) {
885 Result.setOpcode(Hexagon::V4_SL2_loadri_sp);
886 addOps(Result, Inst, 0);
887 addOps(Result, Inst, 2);
888 break; // 2 1,3 SUBInst $Rd = memw(r29 + #$u5_2)
890 Result.setOpcode(Hexagon::V4_SL1_loadri_io);
891 addOps(Result, Inst, 0);
892 addOps(Result, Inst, 1);
893 addOps(Result, Inst, 2);
894 break; // 1,2,3 SUBInst $Rd = memw($Rs + #$u4_2)
896 case Hexagon::S4_storeirb_io:
897 if (Inst.getOperand(2).getImm() == 0) {
898 Result.setOpcode(Hexagon::V4_SS2_storebi0);
899 addOps(Result, Inst, 0);
900 addOps(Result, Inst, 1);
901 break; // 1,2 SUBInst memb($Rs + #$u4_0)=#0
902 } else if (Inst.getOperand(2).getImm() == 1) {
903 Result.setOpcode(Hexagon::V4_SS2_storebi1);
904 addOps(Result, Inst, 0);
905 addOps(Result, Inst, 1);
906 break; // 2 1,2 SUBInst memb($Rs + #$u4_0)=#1
908 case Hexagon::S2_storerb_io:
909 Result.setOpcode(Hexagon::V4_SS1_storeb_io);
910 addOps(Result, Inst, 0);
911 addOps(Result, Inst, 1);
912 addOps(Result, Inst, 2);
913 break; // 1,2,3 SUBInst memb($Rs + #$u4_0) = $Rt
914 case Hexagon::S2_storerd_io:
915 Result.setOpcode(Hexagon::V4_SS2_stored_sp);
916 addOps(Result, Inst, 1);
917 addOps(Result, Inst, 2);
918 break; // 2,3 SUBInst memd(r29 + #$s6_3) = $Rtt
919 case Hexagon::S2_storerh_io:
920 Result.setOpcode(Hexagon::V4_SS2_storeh_io);
921 addOps(Result, Inst, 0);
922 addOps(Result, Inst, 1);
923 addOps(Result, Inst, 2);
924 break; // 1,2,3 SUBInst memb($Rs + #$u4_0) = $Rt
925 case Hexagon::S4_storeiri_io:
926 if (Inst.getOperand(2).getImm() == 0) {
927 Result.setOpcode(Hexagon::V4_SS2_storewi0);
928 addOps(Result, Inst, 0);
929 addOps(Result, Inst, 1);
930 break; // 3 1,2 SUBInst memw($Rs + #$u4_2)=#0
931 } else if (Inst.getOperand(2).getImm() == 1) {
932 Result.setOpcode(Hexagon::V4_SS2_storewi1);
933 addOps(Result, Inst, 0);
934 addOps(Result, Inst, 1);
935 break; // 3 1,2 SUBInst memw($Rs + #$u4_2)=#1
936 } else if (Inst.getOperand(0).getReg() == Hexagon::R29) {
937 Result.setOpcode(Hexagon::V4_SS2_storew_sp);
938 addOps(Result, Inst, 1);
939 addOps(Result, Inst, 2);
940 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::V4_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::V4_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::V4_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::V4_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::V4_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::V4_SA1_clrfnew);
971 addOps(Result, Inst, 0);
972 break; // 2 SUBInst if (!p0.new) $Rd = #0
973 case Hexagon::C2_cmovenewit:
974 Result.setOpcode(Hexagon::V4_SA1_clrtnew);
975 addOps(Result, Inst, 0);
976 break; // 2 SUBInst if (p0.new) $Rd = #0
977 case Hexagon::C2_cmoveif:
978 Result.setOpcode(Hexagon::V4_SA1_clrf);
979 addOps(Result, Inst, 0);
980 break; // 2 SUBInst if (!p0) $Rd = #0
981 case Hexagon::C2_cmoveit:
982 Result.setOpcode(Hexagon::V4_SA1_clrt);
983 addOps(Result, Inst, 0);
984 break; // 2 SUBInst if (p0) $Rd = #0
985 case Hexagon::A2_tfrsi:
986 if (Inst.getOperand(1).isImm() && Inst.getOperand(1).getImm() == -1) {
987 Result.setOpcode(Hexagon::V4_SA1_setin1);
988 addOps(Result, Inst, 0);
989 break; // 2 1 SUBInst $Rd = #-1
991 Result.setOpcode(Hexagon::V4_SA1_seti);
992 addOps(Result, Inst, 0);
993 addOps(Result, Inst, 1);
994 break; // 1,2 SUBInst $Rd = #$u6
996 case Hexagon::A2_zxtb:
997 Result.setOpcode(Hexagon::V4_SA1_zxtb);
998 addOps(Result, Inst, 0);
999 addOps(Result, Inst, 1);
1000 break; // 1,2 $Rd = and($Rs, #255)
1002 case Hexagon::A2_zxth:
1003 Result.setOpcode(Hexagon::V4_SA1_zxth);
1004 addOps(Result, Inst, 0);
1005 addOps(Result, Inst, 1);
1006 break; // 1,2 SUBInst $Rd = zxth($Rs)
1011 static bool isStoreInst(unsigned opCode) {
1013 case Hexagon::S2_storeri_io:
1014 case Hexagon::S2_storerb_io:
1015 case Hexagon::S2_storerh_io:
1016 case Hexagon::S2_storerd_io:
1017 case Hexagon::S4_storeiri_io:
1018 case Hexagon::S4_storeirb_io:
1019 case Hexagon::S2_allocframe:
1026 SmallVector<DuplexCandidate, 8>
1027 HexagonMCInstrInfo::getDuplexPossibilties(MCInstrInfo const &MCII,
1028 MCInst const &MCB) {
1029 assert(isBundle(MCB));
1030 SmallVector<DuplexCandidate, 8> duplexToTry;
1031 // Use an "order matters" version of isDuplexPair.
1032 unsigned numInstrInPacket = MCB.getNumOperands();
1034 for (unsigned distance = 1; distance < numInstrInPacket; ++distance) {
1035 for (unsigned j = HexagonMCInstrInfo::bundleInstructionsOffset,
1037 (j < numInstrInPacket) && (k < numInstrInPacket); ++j, ++k) {
1039 // Check if reversable.
1040 bool bisReversable = true;
1041 if (isStoreInst(MCB.getOperand(j).getInst()->getOpcode()) &&
1042 isStoreInst(MCB.getOperand(k).getInst()->getOpcode())) {
1043 DEBUG(dbgs() << "skip out of order write pair: " << k << "," << j
1045 bisReversable = false;
1049 if (isOrderedDuplexPair(
1050 MCII, *MCB.getOperand(k).getInst(),
1051 HexagonMCInstrInfo::hasExtenderForIndex(MCB, k - 1),
1052 *MCB.getOperand(j).getInst(),
1053 HexagonMCInstrInfo::hasExtenderForIndex(MCB, j - 1),
1056 unsigned iClass = iClassOfDuplexPair(
1057 getDuplexCandidateGroup(*MCB.getOperand(k).getInst()),
1058 getDuplexCandidateGroup(*MCB.getOperand(j).getInst()));
1060 // Save off pairs for duplex checking.
1061 duplexToTry.push_back(DuplexCandidate(j, k, iClass));
1062 DEBUG(dbgs() << "adding pair: " << j << "," << k << ":"
1063 << MCB.getOperand(j).getInst()->getOpcode() << ","
1064 << MCB.getOperand(k).getInst()->getOpcode() << "\n");
1067 DEBUG(dbgs() << "skipping pair: " << j << "," << k << ":"
1068 << MCB.getOperand(j).getInst()->getOpcode() << ","
1069 << MCB.getOperand(k).getInst()->getOpcode() << "\n");
1073 if (bisReversable) {
1074 if (isOrderedDuplexPair(
1075 MCII, *MCB.getOperand(j).getInst(),
1076 HexagonMCInstrInfo::hasExtenderForIndex(MCB, j - 1),
1077 *MCB.getOperand(k).getInst(),
1078 HexagonMCInstrInfo::hasExtenderForIndex(MCB, k - 1),
1081 unsigned iClass = iClassOfDuplexPair(
1082 getDuplexCandidateGroup(*MCB.getOperand(j).getInst()),
1083 getDuplexCandidateGroup(*MCB.getOperand(k).getInst()));
1085 // Save off pairs for duplex checking.
1086 duplexToTry.push_back(DuplexCandidate(k, j, iClass));
1087 DEBUG(dbgs() << "adding pair:" << k << "," << j << ":"
1088 << MCB.getOperand(j).getInst()->getOpcode() << ","
1089 << MCB.getOperand(k).getInst()->getOpcode() << "\n");
1091 DEBUG(dbgs() << "skipping pair: " << k << "," << j << ":"
1092 << MCB.getOperand(j).getInst()->getOpcode() << ","
1093 << MCB.getOperand(k).getInst()->getOpcode() << "\n");