1//===- HexagonMCDuplexInfo.cpp - Instruction bundle checking --------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This implements duplexing of instructions to reduce code size
10//
11//===----------------------------------------------------------------------===//
12
13#include "HexagonMCExpr.h"
14#include "MCTargetDesc/HexagonBaseInfo.h"
15#include "MCTargetDesc/HexagonMCInstrInfo.h"
16#include "MCTargetDesc/HexagonMCTargetDesc.h"
17#include "llvm/ADT/SmallVector.h"
18#include "llvm/MC/MCSubtargetInfo.h"
19#include "llvm/Support/Debug.h"
20#include "llvm/Support/ErrorHandling.h"
21#include "llvm/Support/MathExtras.h"
22#include "llvm/Support/raw_ostream.h"
23#include <cassert>
24#include <cstdint>
25#include <iterator>
26#include <map>
27#include <utility>
28
29using namespace llvm;
30using namespace Hexagon;
31
32#define DEBUG_TYPE "hexagon-mcduplex-info"
33
34// pair table of subInstructions with opcodes
35static const std::pair<unsigned, unsigned> opcodeData[] = {
36    std::make_pair((unsigned)SA1_addi, 0),
37    std::make_pair((unsigned)SA1_addrx, 6144),
38    std::make_pair((unsigned)SA1_addsp, 3072),
39    std::make_pair((unsigned)SA1_and1, 4608),
40    std::make_pair((unsigned)SA1_clrf, 6768),
41    std::make_pair((unsigned)SA1_clrfnew, 6736),
42    std::make_pair((unsigned)SA1_clrt, 6752),
43    std::make_pair((unsigned)SA1_clrtnew, 6720),
44    std::make_pair((unsigned)SA1_cmpeqi, 6400),
45    std::make_pair((unsigned)SA1_combine0i, 7168),
46    std::make_pair((unsigned)SA1_combine1i, 7176),
47    std::make_pair((unsigned)SA1_combine2i, 7184),
48    std::make_pair((unsigned)SA1_combine3i, 7192),
49    std::make_pair((unsigned)SA1_combinerz, 7432),
50    std::make_pair((unsigned)SA1_combinezr, 7424),
51    std::make_pair((unsigned)SA1_dec, 4864),
52    std::make_pair((unsigned)SA1_inc, 4352),
53    std::make_pair((unsigned)SA1_seti, 2048),
54    std::make_pair((unsigned)SA1_setin1, 6656),
55    std::make_pair((unsigned)SA1_sxtb, 5376),
56    std::make_pair((unsigned)SA1_sxth, 5120),
57    std::make_pair((unsigned)SA1_tfr, 4096),
58    std::make_pair((unsigned)SA1_zxtb, 5888),
59    std::make_pair((unsigned)SA1_zxth, 5632),
60    std::make_pair((unsigned)SL1_loadri_io, 0),
61    std::make_pair((unsigned)SL1_loadrub_io, 4096),
62    std::make_pair((unsigned)SL2_deallocframe, 7936),
63    std::make_pair((unsigned)SL2_jumpr31, 8128),
64    std::make_pair((unsigned)SL2_jumpr31_f, 8133),
65    std::make_pair((unsigned)SL2_jumpr31_fnew, 8135),
66    std::make_pair((unsigned)SL2_jumpr31_t, 8132),
67    std::make_pair((unsigned)SL2_jumpr31_tnew, 8134),
68    std::make_pair((unsigned)SL2_loadrb_io, 4096),
69    std::make_pair((unsigned)SL2_loadrd_sp, 7680),
70    std::make_pair((unsigned)SL2_loadrh_io, 0),
71    std::make_pair((unsigned)SL2_loadri_sp, 7168),
72    std::make_pair((unsigned)SL2_loadruh_io, 2048),
73    std::make_pair((unsigned)SL2_return, 8000),
74    std::make_pair((unsigned)SL2_return_f, 8005),
75    std::make_pair((unsigned)SL2_return_fnew, 8007),
76    std::make_pair((unsigned)SL2_return_t, 8004),
77    std::make_pair((unsigned)SL2_return_tnew, 8006),
78    std::make_pair((unsigned)SS1_storeb_io, 4096),
79    std::make_pair((unsigned)SS1_storew_io, 0),
80    std::make_pair((unsigned)SS2_allocframe, 7168),
81    std::make_pair((unsigned)SS2_storebi0, 4608),
82    std::make_pair((unsigned)SS2_storebi1, 4864),
83    std::make_pair((unsigned)SS2_stored_sp, 2560),
84    std::make_pair((unsigned)SS2_storeh_io, 0),
85    std::make_pair((unsigned)SS2_storew_sp, 2048),
86    std::make_pair((unsigned)SS2_storewi0, 4096),
87    std::make_pair((unsigned)SS2_storewi1, 4352)};
88
89bool HexagonMCInstrInfo::isDuplexPairMatch(unsigned Ga, unsigned Gb) {
90  switch (Ga) {
91  case HexagonII::HSIG_None:
92  default:
93    return false;
94  case HexagonII::HSIG_L1:
95    return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_A);
96  case HexagonII::HSIG_L2:
97    return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
98            Gb == HexagonII::HSIG_A);
99  case HexagonII::HSIG_S1:
100    return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
101            Gb == HexagonII::HSIG_S1 || Gb == HexagonII::HSIG_A);
102  case HexagonII::HSIG_S2:
103    return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
104            Gb == HexagonII::HSIG_S1 || Gb == HexagonII::HSIG_S2 ||
105            Gb == HexagonII::HSIG_A);
106  case HexagonII::HSIG_A:
107    return (Gb == HexagonII::HSIG_A);
108  case HexagonII::HSIG_Compound:
109    return (Gb == HexagonII::HSIG_Compound);
110  }
111  return false;
112}
113
114unsigned HexagonMCInstrInfo::iClassOfDuplexPair(unsigned Ga, unsigned Gb) {
115  switch (Ga) {
116  case HexagonII::HSIG_None:
117  default:
118    break;
119  case HexagonII::HSIG_L1:
120    switch (Gb) {
121    default:
122      break;
123    case HexagonII::HSIG_L1:
124      return 0;
125    case HexagonII::HSIG_A:
126      return 0x4;
127    }
128    break;
129  case HexagonII::HSIG_L2:
130    switch (Gb) {
131    default:
132      break;
133    case HexagonII::HSIG_L1:
134      return 0x1;
135    case HexagonII::HSIG_L2:
136      return 0x2;
137    case HexagonII::HSIG_A:
138      return 0x5;
139    }
140    break;
141  case HexagonII::HSIG_S1:
142    switch (Gb) {
143    default:
144      break;
145    case HexagonII::HSIG_L1:
146      return 0x8;
147    case HexagonII::HSIG_L2:
148      return 0x9;
149    case HexagonII::HSIG_S1:
150      return 0xA;
151    case HexagonII::HSIG_A:
152      return 0x6;
153    }
154    break;
155  case HexagonII::HSIG_S2:
156    switch (Gb) {
157    default:
158      break;
159    case HexagonII::HSIG_L1:
160      return 0xC;
161    case HexagonII::HSIG_L2:
162      return 0xD;
163    case HexagonII::HSIG_S1:
164      return 0xB;
165    case HexagonII::HSIG_S2:
166      return 0xE;
167    case HexagonII::HSIG_A:
168      return 0x7;
169    }
170    break;
171  case HexagonII::HSIG_A:
172    switch (Gb) {
173    default:
174      break;
175    case HexagonII::HSIG_A:
176      return 0x3;
177    }
178    break;
179  case HexagonII::HSIG_Compound:
180    switch (Gb) {
181    case HexagonII::HSIG_Compound:
182      return 0xFFFFFFFF;
183    }
184    break;
185  }
186  return 0xFFFFFFFF;
187}
188
189unsigned HexagonMCInstrInfo::getDuplexCandidateGroup(MCInst const &MCI) {
190  unsigned DstReg, PredReg, SrcReg, Src1Reg, Src2Reg;
191
192  switch (MCI.getOpcode()) {
193  default:
194    return HexagonII::HSIG_None;
195  //
196  // Group L1:
197  //
198  // Rd = memw(Rs+#u4:2)
199  // Rd = memub(Rs+#u4:0)
200  case Hexagon::L2_loadri_io:
201    DstReg = MCI.getOperand(0).getReg();
202    SrcReg = MCI.getOperand(1).getReg();
203    // Special case this one from Group L2.
204    // Rd = memw(r29+#u5:2)
205    if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
206      if (HexagonMCInstrInfo::isIntReg(SrcReg) &&
207          Hexagon::R29 == SrcReg && inRange<5, 2>(MCI, 2)) {
208        return HexagonII::HSIG_L2;
209      }
210      // Rd = memw(Rs+#u4:2)
211      if (HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
212          inRange<4, 2>(MCI, 2)) {
213        return HexagonII::HSIG_L1;
214      }
215    }
216    break;
217  case Hexagon::L2_loadrub_io:
218    // Rd = memub(Rs+#u4:0)
219    DstReg = MCI.getOperand(0).getReg();
220    SrcReg = MCI.getOperand(1).getReg();
221    if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
222        HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
223        inRange<4>(MCI, 2)) {
224      return HexagonII::HSIG_L1;
225    }
226    break;
227  //
228  // Group L2:
229  //
230  // Rd = memh/memuh(Rs+#u3:1)
231  // Rd = memb(Rs+#u3:0)
232  // Rd = memw(r29+#u5:2) - Handled above.
233  // Rdd = memd(r29+#u5:3)
234  // deallocframe
235  // [if ([!]p0[.new])] dealloc_return
236  // [if ([!]p0[.new])] jumpr r31
237  case Hexagon::L2_loadrh_io:
238  case Hexagon::L2_loadruh_io:
239    // Rd = memh/memuh(Rs+#u3:1)
240    DstReg = MCI.getOperand(0).getReg();
241    SrcReg = MCI.getOperand(1).getReg();
242    if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
243        HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
244        inRange<3, 1>(MCI, 2)) {
245      return HexagonII::HSIG_L2;
246    }
247    break;
248  case Hexagon::L2_loadrb_io:
249    // Rd = memb(Rs+#u3:0)
250    DstReg = MCI.getOperand(0).getReg();
251    SrcReg = MCI.getOperand(1).getReg();
252    if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
253        HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
254        inRange<3>(MCI, 2)) {
255      return HexagonII::HSIG_L2;
256    }
257    break;
258  case Hexagon::L2_loadrd_io:
259    // Rdd = memd(r29+#u5:3)
260    DstReg = MCI.getOperand(0).getReg();
261    SrcReg = MCI.getOperand(1).getReg();
262    if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
263        HexagonMCInstrInfo::isIntReg(SrcReg) && Hexagon::R29 == SrcReg &&
264        inRange<5, 3>(MCI, 2)) {
265      return HexagonII::HSIG_L2;
266    }
267    break;
268
269  case Hexagon::L4_return:
270  case Hexagon::L2_deallocframe:
271    return HexagonII::HSIG_L2;
272
273  case Hexagon::EH_RETURN_JMPR:
274  case Hexagon::J2_jumpr:
275  case Hexagon::PS_jmpret:
276    // jumpr r31
277    // Actual form JMPR implicit-def %pc, implicit %r31, implicit internal %r0.
278    DstReg = MCI.getOperand(0).getReg();
279    if (Hexagon::R31 == DstReg)
280      return HexagonII::HSIG_L2;
281    break;
282
283  case Hexagon::J2_jumprt:
284  case Hexagon::J2_jumprf:
285  case Hexagon::J2_jumprtnew:
286  case Hexagon::J2_jumprfnew:
287  case Hexagon::J2_jumprtnewpt:
288  case Hexagon::J2_jumprfnewpt:
289  case Hexagon::PS_jmprett:
290  case Hexagon::PS_jmpretf:
291  case Hexagon::PS_jmprettnew:
292  case Hexagon::PS_jmpretfnew:
293  case Hexagon::PS_jmprettnewpt:
294  case Hexagon::PS_jmpretfnewpt:
295    DstReg = MCI.getOperand(1).getReg();
296    SrcReg = MCI.getOperand(0).getReg();
297    // [if ([!]p0[.new])] jumpr r31
298    if ((Hexagon::P0 == SrcReg) && (Hexagon::R31 == DstReg)) {
299      return HexagonII::HSIG_L2;
300    }
301    break;
302  case Hexagon::L4_return_t:
303  case Hexagon::L4_return_f:
304  case Hexagon::L4_return_tnew_pnt:
305  case Hexagon::L4_return_fnew_pnt:
306  case Hexagon::L4_return_tnew_pt:
307  case Hexagon::L4_return_fnew_pt:
308    // [if ([!]p0[.new])] dealloc_return
309    SrcReg = MCI.getOperand(1).getReg();
310    if (Hexagon::P0 == SrcReg) {
311      return HexagonII::HSIG_L2;
312    }
313    break;
314  //
315  // Group S1:
316  //
317  // memw(Rs+#u4:2) = Rt
318  // memb(Rs+#u4:0) = Rt
319  case Hexagon::S2_storeri_io:
320    // Special case this one from Group S2.
321    // memw(r29+#u5:2) = Rt
322    Src1Reg = MCI.getOperand(0).getReg();
323    Src2Reg = MCI.getOperand(2).getReg();
324    if (HexagonMCInstrInfo::isIntReg(Src1Reg) &&
325        HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
326        Hexagon::R29 == Src1Reg && inRange<5, 2>(MCI, 1)) {
327      return HexagonII::HSIG_S2;
328    }
329    // memw(Rs+#u4:2) = Rt
330    if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
331        HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
332        inRange<4, 2>(MCI, 1)) {
333      return HexagonII::HSIG_S1;
334    }
335    break;
336  case Hexagon::S2_storerb_io:
337    // memb(Rs+#u4:0) = Rt
338    Src1Reg = MCI.getOperand(0).getReg();
339    Src2Reg = MCI.getOperand(2).getReg();
340    if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
341        HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
342        inRange<4>(MCI, 1)) {
343      return HexagonII::HSIG_S1;
344    }
345    break;
346  //
347  // Group S2:
348  //
349  // memh(Rs+#u3:1) = Rt
350  // memw(r29+#u5:2) = Rt
351  // memd(r29+#s6:3) = Rtt
352  // memw(Rs+#u4:2) = #U1
353  // memb(Rs+#u4) = #U1
354  // allocframe(#u5:3)
355  case Hexagon::S2_storerh_io:
356    // memh(Rs+#u3:1) = Rt
357    Src1Reg = MCI.getOperand(0).getReg();
358    Src2Reg = MCI.getOperand(2).getReg();
359    if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
360        HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
361        inRange<3, 1>(MCI, 1)) {
362      return HexagonII::HSIG_S2;
363    }
364    break;
365  case Hexagon::S2_storerd_io:
366    // memd(r29+#s6:3) = Rtt
367    Src1Reg = MCI.getOperand(0).getReg();
368    Src2Reg = MCI.getOperand(2).getReg();
369    if (HexagonMCInstrInfo::isDblRegForSubInst(Src2Reg) &&
370        HexagonMCInstrInfo::isIntReg(Src1Reg) && Hexagon::R29 == Src1Reg &&
371        inSRange<6, 3>(MCI, 1)) {
372      return HexagonII::HSIG_S2;
373    }
374    break;
375  case Hexagon::S4_storeiri_io:
376    // memw(Rs+#u4:2) = #U1
377    Src1Reg = MCI.getOperand(0).getReg();
378    if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
379        inRange<4, 2>(MCI, 1) && inRange<1>(MCI, 2)) {
380      return HexagonII::HSIG_S2;
381    }
382    break;
383  case Hexagon::S4_storeirb_io:
384    // memb(Rs+#u4) = #U1
385    Src1Reg = MCI.getOperand(0).getReg();
386    if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
387        inRange<4>(MCI, 1) && inRange<1>(MCI, 2)) {
388      return HexagonII::HSIG_S2;
389    }
390    break;
391  case Hexagon::S2_allocframe:
392    if (inRange<5, 3>(MCI, 2))
393      return HexagonII::HSIG_S2;
394    break;
395  //
396  // Group A:
397  //
398  // Rx = add(Rx,#s7)
399  // Rd = Rs
400  // Rd = #u6
401  // Rd = #-1
402  // if ([!]P0[.new]) Rd = #0
403  // Rd = add(r29,#u6:2)
404  // Rx = add(Rx,Rs)
405  // P0 = cmp.eq(Rs,#u2)
406  // Rdd = combine(#0,Rs)
407  // Rdd = combine(Rs,#0)
408  // Rdd = combine(#u2,#U2)
409  // Rd = add(Rs,#1)
410  // Rd = add(Rs,#-1)
411  // Rd = sxth/sxtb/zxtb/zxth(Rs)
412  // Rd = and(Rs,#1)
413  case Hexagon::A2_addi:
414    DstReg = MCI.getOperand(0).getReg();
415    SrcReg = MCI.getOperand(1).getReg();
416    if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
417      // Rd = add(r29,#u6:2)
418      if (HexagonMCInstrInfo::isIntReg(SrcReg) && Hexagon::R29 == SrcReg &&
419          inRange<6, 2>(MCI, 2)) {
420        return HexagonII::HSIG_A;
421      }
422      // Rx = add(Rx,#s7)
423      if (DstReg == SrcReg) {
424        return HexagonII::HSIG_A;
425      }
426      // Rd = add(Rs,#1)
427      // Rd = add(Rs,#-1)
428      if (HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
429          (minConstant(MCI, 2) == 1 || minConstant(MCI, 2) == -1)) {
430        return HexagonII::HSIG_A;
431      }
432    }
433    break;
434  case Hexagon::A2_add:
435    // Rx = add(Rx,Rs)
436    DstReg = MCI.getOperand(0).getReg();
437    Src1Reg = MCI.getOperand(1).getReg();
438    Src2Reg = MCI.getOperand(2).getReg();
439    if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) && (DstReg == Src1Reg) &&
440        HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg)) {
441      return HexagonII::HSIG_A;
442    }
443    break;
444  case Hexagon::A2_andir:
445    DstReg = MCI.getOperand(0).getReg();
446    SrcReg = MCI.getOperand(1).getReg();
447    if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
448        HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
449        (minConstant(MCI, 2) == 1 || minConstant(MCI, 2) == 255)) {
450      return HexagonII::HSIG_A;
451    }
452    break;
453  case Hexagon::A2_tfr:
454    // Rd = Rs
455    DstReg = MCI.getOperand(0).getReg();
456    SrcReg = MCI.getOperand(1).getReg();
457    if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
458        HexagonMCInstrInfo::isIntRegForSubInst(SrcReg)) {
459      return HexagonII::HSIG_A;
460    }
461    break;
462  case Hexagon::A2_tfrsi:
463    DstReg = MCI.getOperand(0).getReg();
464
465    if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
466      return HexagonII::HSIG_A;
467    }
468    break;
469  case Hexagon::C2_cmoveit:
470  case Hexagon::C2_cmovenewit:
471  case Hexagon::C2_cmoveif:
472  case Hexagon::C2_cmovenewif:
473    // if ([!]P0[.new]) Rd = #0
474    // Actual form:
475    // %r16 = C2_cmovenewit internal %p0, 0, implicit undef %r16;
476    DstReg = MCI.getOperand(0).getReg();  // Rd
477    PredReg = MCI.getOperand(1).getReg(); // P0
478    if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
479        Hexagon::P0 == PredReg && minConstant(MCI, 2) == 0) {
480      return HexagonII::HSIG_A;
481    }
482    break;
483  case Hexagon::C2_cmpeqi:
484    // P0 = cmp.eq(Rs,#u2)
485    DstReg = MCI.getOperand(0).getReg();
486    SrcReg = MCI.getOperand(1).getReg();
487    if (Hexagon::P0 == DstReg &&
488        HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
489        inRange<2>(MCI, 2)) {
490      return HexagonII::HSIG_A;
491    }
492    break;
493  case Hexagon::A2_combineii:
494  case Hexagon::A4_combineii:
495    // Rdd = combine(#u2,#U2)
496    DstReg = MCI.getOperand(0).getReg();
497    if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
498        inRange<2>(MCI, 1) && inRange<2>(MCI, 2)) {
499      return HexagonII::HSIG_A;
500    }
501    break;
502  case Hexagon::A4_combineri:
503    // Rdd = combine(Rs,#0)
504    DstReg = MCI.getOperand(0).getReg();
505    SrcReg = MCI.getOperand(1).getReg();
506    if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
507        HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
508        minConstant(MCI, 2) == 0) {
509      return HexagonII::HSIG_A;
510    }
511    break;
512  case Hexagon::A4_combineir:
513    // Rdd = combine(#0,Rs)
514    DstReg = MCI.getOperand(0).getReg();
515    SrcReg = MCI.getOperand(2).getReg();
516    if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
517        HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
518        minConstant(MCI, 1) == 0) {
519      return HexagonII::HSIG_A;
520    }
521    break;
522  case Hexagon::A2_sxtb:
523  case Hexagon::A2_sxth:
524  case Hexagon::A2_zxtb:
525  case Hexagon::A2_zxth:
526    // Rd = sxth/sxtb/zxtb/zxth(Rs)
527    DstReg = MCI.getOperand(0).getReg();
528    SrcReg = MCI.getOperand(1).getReg();
529    if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
530        HexagonMCInstrInfo::isIntRegForSubInst(SrcReg)) {
531      return HexagonII::HSIG_A;
532    }
533    break;
534  }
535
536  return HexagonII::HSIG_None;
537}
538
539bool HexagonMCInstrInfo::subInstWouldBeExtended(MCInst const &potentialDuplex) {
540  unsigned DstReg, SrcReg;
541  switch (potentialDuplex.getOpcode()) {
542  case Hexagon::A2_addi:
543    // testing for case of: Rx = add(Rx,#s7)
544    DstReg = potentialDuplex.getOperand(0).getReg();
545    SrcReg = potentialDuplex.getOperand(1).getReg();
546    if (DstReg == SrcReg && HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
547      int64_t Value;
548      if (!potentialDuplex.getOperand(2).getExpr()->evaluateAsAbsolute(Value))
549        return true;
550      if (!isShiftedInt<7, 0>(Value))
551        return true;
552    }
553    break;
554  case Hexagon::A2_tfrsi:
555    DstReg = potentialDuplex.getOperand(0).getReg();
556
557    if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
558      int64_t Value;
559      if (!potentialDuplex.getOperand(1).getExpr()->evaluateAsAbsolute(Value))
560        return true;
561      // Check for case of Rd = #-1.
562      if (Value == -1)
563        return false;
564      // Check for case of Rd = #u6.
565      if (!isShiftedUInt<6, 0>(Value))
566        return true;
567    }
568    break;
569  default:
570    break;
571  }
572  return false;
573}
574
575/// non-Symmetrical. See if these two instructions are fit for duplex pair.
576bool HexagonMCInstrInfo::isOrderedDuplexPair(MCInstrInfo const &MCII,
577                                             MCInst const &MIa, bool ExtendedA,
578                                             MCInst const &MIb, bool ExtendedB,
579                                             bool bisReversable,
580                                             MCSubtargetInfo const &STI) {
581  // Slot 1 cannot be extended in duplexes PRM 10.5
582  if (ExtendedA)
583    return false;
584  // Only A2_addi and A2_tfrsi can be extended in duplex form PRM 10.5
585  if (ExtendedB) {
586    unsigned Opcode = MIb.getOpcode();
587    if ((Opcode != Hexagon::A2_addi) && (Opcode != Hexagon::A2_tfrsi))
588      return false;
589  }
590  unsigned MIaG = HexagonMCInstrInfo::getDuplexCandidateGroup(MIa),
591           MIbG = HexagonMCInstrInfo::getDuplexCandidateGroup(MIb);
592
593  static std::map<unsigned, unsigned> subinstOpcodeMap(std::begin(opcodeData),
594                                                       std::end(opcodeData));
595
596  // If a duplex contains 2 insns in the same group, the insns must be
597  // ordered such that the numerically smaller opcode is in slot 1.
598  if ((MIaG != HexagonII::HSIG_None) && (MIaG == MIbG) && bisReversable) {
599    MCInst SubInst0 = HexagonMCInstrInfo::deriveSubInst(MIa);
600    MCInst SubInst1 = HexagonMCInstrInfo::deriveSubInst(MIb);
601
602    unsigned zeroedSubInstS0 =
603        subinstOpcodeMap.find(SubInst0.getOpcode())->second;
604    unsigned zeroedSubInstS1 =
605        subinstOpcodeMap.find(SubInst1.getOpcode())->second;
606
607    if (zeroedSubInstS0 < zeroedSubInstS1)
608      // subinstS0 (maps to slot 0) must be greater than
609      // subinstS1 (maps to slot 1)
610      return false;
611  }
612
613  // allocframe must always be in slot 0
614  if (MIb.getOpcode() == Hexagon::S2_allocframe)
615    return false;
616
617  if ((MIaG != HexagonII::HSIG_None) && (MIbG != HexagonII::HSIG_None)) {
618    // Prevent 2 instructions with extenders from duplexing
619    // Note that MIb (slot1) can be extended and MIa (slot0)
620    //   can never be extended
621    if (subInstWouldBeExtended(MIa))
622      return false;
623
624    // If duplexing produces an extender, but the original did not
625    //   have an extender, do not duplex.
626    if (subInstWouldBeExtended(MIb) && !ExtendedB)
627      return false;
628  }
629
630  // If jumpr r31 appears, it must be in slot 0, and never slot 1 (MIb).
631  if (MIbG == HexagonII::HSIG_L2) {
632    if ((MIb.getNumOperands() > 1) && MIb.getOperand(1).isReg() &&
633        (MIb.getOperand(1).getReg() == Hexagon::R31))
634      return false;
635    if ((MIb.getNumOperands() > 0) && MIb.getOperand(0).isReg() &&
636        (MIb.getOperand(0).getReg() == Hexagon::R31))
637      return false;
638  }
639
640  if (STI.getCPU().equals_lower("hexagonv5") ||
641      STI.getCPU().equals_lower("hexagonv55") ||
642      STI.getCPU().equals_lower("hexagonv60")) {
643    // If a store appears, it must be in slot 0 (MIa) 1st, and then slot 1 (MIb);
644    //   therefore, not duplexable if slot 1 is a store, and slot 0 is not.
645    if ((MIbG == HexagonII::HSIG_S1) || (MIbG == HexagonII::HSIG_S2)) {
646      if ((MIaG != HexagonII::HSIG_S1) && (MIaG != HexagonII::HSIG_S2))
647        return false;
648    }
649  }
650
651  return (isDuplexPairMatch(MIaG, MIbG));
652}
653
654/// Symmetrical. See if these two instructions are fit for duplex pair.
655bool HexagonMCInstrInfo::isDuplexPair(MCInst const &MIa, MCInst const &MIb) {
656  unsigned MIaG = getDuplexCandidateGroup(MIa),
657           MIbG = getDuplexCandidateGroup(MIb);
658  return (isDuplexPairMatch(MIaG, MIbG) || isDuplexPairMatch(MIbG, MIaG));
659}
660
661inline static void addOps(MCInst &subInstPtr, MCInst const &Inst,
662                          unsigned opNum) {
663  if (Inst.getOperand(opNum).isReg()) {
664    switch (Inst.getOperand(opNum).getReg()) {
665    default:
666      llvm_unreachable("Not Duplexable Register");
667      break;
668    case Hexagon::R0:
669    case Hexagon::R1:
670    case Hexagon::R2:
671    case Hexagon::R3:
672    case Hexagon::R4:
673    case Hexagon::R5:
674    case Hexagon::R6:
675    case Hexagon::R7:
676    case Hexagon::D0:
677    case Hexagon::D1:
678    case Hexagon::D2:
679    case Hexagon::D3:
680    case Hexagon::R16:
681    case Hexagon::R17:
682    case Hexagon::R18:
683    case Hexagon::R19:
684    case Hexagon::R20:
685    case Hexagon::R21:
686    case Hexagon::R22:
687    case Hexagon::R23:
688    case Hexagon::D8:
689    case Hexagon::D9:
690    case Hexagon::D10:
691    case Hexagon::D11:
692    case Hexagon::P0:
693      subInstPtr.addOperand(Inst.getOperand(opNum));
694      break;
695    }
696  } else
697    subInstPtr.addOperand(Inst.getOperand(opNum));
698}
699
700MCInst HexagonMCInstrInfo::deriveSubInst(MCInst const &Inst) {
701  MCInst Result;
702  bool Absolute;
703  int64_t Value;
704  switch (Inst.getOpcode()) {
705  default:
706    // dbgs() << "opcode: "<< Inst->getOpcode() << "\n";
707    llvm_unreachable("Unimplemented subinstruction \n");
708    break;
709  case Hexagon::A2_addi:
710    Absolute = Inst.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
711    if (Absolute) {
712      if (Value == 1) {
713        Result.setOpcode(Hexagon::SA1_inc);
714        addOps(Result, Inst, 0);
715        addOps(Result, Inst, 1);
716        break;
717      } //  1,2 SUBInst $Rd = add($Rs, #1)
718      if (Value == -1) {
719        Result.setOpcode(Hexagon::SA1_dec);
720        addOps(Result, Inst, 0);
721        addOps(Result, Inst, 1);
722        addOps(Result, Inst, 2);
723        break;
724      } //  1,2 SUBInst $Rd = add($Rs,#-1)
725      if (Inst.getOperand(1).getReg() == Hexagon::R29) {
726        Result.setOpcode(Hexagon::SA1_addsp);
727        addOps(Result, Inst, 0);
728        addOps(Result, Inst, 2);
729        break;
730      } //  1,3 SUBInst $Rd = add(r29, #$u6_2)
731    }
732    Result.setOpcode(Hexagon::SA1_addi);
733    addOps(Result, Inst, 0);
734    addOps(Result, Inst, 1);
735    addOps(Result, Inst, 2);
736    break; //    1,2,3 SUBInst $Rx = add($Rx, #$s7)
737  case Hexagon::A2_add:
738    Result.setOpcode(Hexagon::SA1_addrx);
739    addOps(Result, Inst, 0);
740    addOps(Result, Inst, 1);
741    addOps(Result, Inst, 2);
742    break; //    1,2,3 SUBInst $Rx = add($_src_, $Rs)
743  case Hexagon::S2_allocframe:
744    Result.setOpcode(Hexagon::SS2_allocframe);
745    addOps(Result, Inst, 2);
746    break; //    1 SUBInst allocframe(#$u5_3)
747  case Hexagon::A2_andir:
748    if (minConstant(Inst, 2) == 255) {
749      Result.setOpcode(Hexagon::SA1_zxtb);
750      addOps(Result, Inst, 0);
751      addOps(Result, Inst, 1);
752      break; //    1,2    $Rd = and($Rs, #255)
753    } else {
754      Result.setOpcode(Hexagon::SA1_and1);
755      addOps(Result, Inst, 0);
756      addOps(Result, Inst, 1);
757      break; //    1,2 SUBInst $Rd = and($Rs, #1)
758    }
759  case Hexagon::C2_cmpeqi:
760    Result.setOpcode(Hexagon::SA1_cmpeqi);
761    addOps(Result, Inst, 1);
762    addOps(Result, Inst, 2);
763    break; //    2,3 SUBInst p0 = cmp.eq($Rs, #$u2)
764  case Hexagon::A4_combineii:
765  case Hexagon::A2_combineii:
766    Absolute = Inst.getOperand(1).getExpr()->evaluateAsAbsolute(Value);
767    assert(Absolute);(void)Absolute;
768    if (Value == 1) {
769      Result.setOpcode(Hexagon::SA1_combine1i);
770      addOps(Result, Inst, 0);
771      addOps(Result, Inst, 2);
772      break; //  1,3 SUBInst $Rdd = combine(#1, #$u2)
773    }
774    if (Value == 3) {
775      Result.setOpcode(Hexagon::SA1_combine3i);
776      addOps(Result, Inst, 0);
777      addOps(Result, Inst, 2);
778      break; //  1,3 SUBInst $Rdd = combine(#3, #$u2)
779    }
780    if (Value == 0) {
781      Result.setOpcode(Hexagon::SA1_combine0i);
782      addOps(Result, Inst, 0);
783      addOps(Result, Inst, 2);
784      break; //  1,3 SUBInst $Rdd = combine(#0, #$u2)
785    }
786    if (Value == 2) {
787      Result.setOpcode(Hexagon::SA1_combine2i);
788      addOps(Result, Inst, 0);
789      addOps(Result, Inst, 2);
790      break; //  1,3 SUBInst $Rdd = combine(#2, #$u2)
791    }
792    break;
793  case Hexagon::A4_combineir:
794    Result.setOpcode(Hexagon::SA1_combinezr);
795    addOps(Result, Inst, 0);
796    addOps(Result, Inst, 2);
797    break; //    1,3 SUBInst $Rdd = combine(#0, $Rs)
798  case Hexagon::A4_combineri:
799    Result.setOpcode(Hexagon::SA1_combinerz);
800    addOps(Result, Inst, 0);
801    addOps(Result, Inst, 1);
802    break; //    1,2 SUBInst $Rdd = combine($Rs, #0)
803  case Hexagon::L4_return_tnew_pnt:
804  case Hexagon::L4_return_tnew_pt:
805    Result.setOpcode(Hexagon::SL2_return_tnew);
806    break; //    none  SUBInst if (p0.new) dealloc_return:nt
807  case Hexagon::L4_return_fnew_pnt:
808  case Hexagon::L4_return_fnew_pt:
809    Result.setOpcode(Hexagon::SL2_return_fnew);
810    break; //    none  SUBInst if (!p0.new) dealloc_return:nt
811  case Hexagon::L4_return_f:
812    Result.setOpcode(Hexagon::SL2_return_f);
813    break; //    none  SUBInst if (!p0) dealloc_return
814  case Hexagon::L4_return_t:
815    Result.setOpcode(Hexagon::SL2_return_t);
816    break; //    none  SUBInst if (p0) dealloc_return
817  case Hexagon::L4_return:
818    Result.setOpcode(Hexagon::SL2_return);
819    break; //    none  SUBInst dealloc_return
820  case Hexagon::L2_deallocframe:
821    Result.setOpcode(Hexagon::SL2_deallocframe);
822    break; //    none  SUBInst deallocframe
823  case Hexagon::EH_RETURN_JMPR:
824  case Hexagon::J2_jumpr:
825  case Hexagon::PS_jmpret:
826    Result.setOpcode(Hexagon::SL2_jumpr31);
827    break; //    none  SUBInst jumpr r31
828  case Hexagon::J2_jumprf:
829  case Hexagon::PS_jmpretf:
830    Result.setOpcode(Hexagon::SL2_jumpr31_f);
831    break; //    none  SUBInst if (!p0) jumpr r31
832  case Hexagon::J2_jumprfnew:
833  case Hexagon::J2_jumprfnewpt:
834  case Hexagon::PS_jmpretfnewpt:
835  case Hexagon::PS_jmpretfnew:
836    Result.setOpcode(Hexagon::SL2_jumpr31_fnew);
837    break; //    none  SUBInst if (!p0.new) jumpr:nt r31
838  case Hexagon::J2_jumprt:
839  case Hexagon::PS_jmprett:
840    Result.setOpcode(Hexagon::SL2_jumpr31_t);
841    break; //    none  SUBInst if (p0) jumpr r31
842  case Hexagon::J2_jumprtnew:
843  case Hexagon::J2_jumprtnewpt:
844  case Hexagon::PS_jmprettnewpt:
845  case Hexagon::PS_jmprettnew:
846    Result.setOpcode(Hexagon::SL2_jumpr31_tnew);
847    break; //    none  SUBInst if (p0.new) jumpr:nt r31
848  case Hexagon::L2_loadrb_io:
849    Result.setOpcode(Hexagon::SL2_loadrb_io);
850    addOps(Result, Inst, 0);
851    addOps(Result, Inst, 1);
852    addOps(Result, Inst, 2);
853    break; //    1,2,3 SUBInst $Rd = memb($Rs + #$u3_0)
854  case Hexagon::L2_loadrd_io:
855    Result.setOpcode(Hexagon::SL2_loadrd_sp);
856    addOps(Result, Inst, 0);
857    addOps(Result, Inst, 2);
858    break; //    1,3 SUBInst $Rdd = memd(r29 + #$u5_3)
859  case Hexagon::L2_loadrh_io:
860    Result.setOpcode(Hexagon::SL2_loadrh_io);
861    addOps(Result, Inst, 0);
862    addOps(Result, Inst, 1);
863    addOps(Result, Inst, 2);
864    break; //    1,2,3 SUBInst $Rd = memh($Rs + #$u3_1)
865  case Hexagon::L2_loadrub_io:
866    Result.setOpcode(Hexagon::SL1_loadrub_io);
867    addOps(Result, Inst, 0);
868    addOps(Result, Inst, 1);
869    addOps(Result, Inst, 2);
870    break; //    1,2,3 SUBInst $Rd = memub($Rs + #$u4_0)
871  case Hexagon::L2_loadruh_io:
872    Result.setOpcode(Hexagon::SL2_loadruh_io);
873    addOps(Result, Inst, 0);
874    addOps(Result, Inst, 1);
875    addOps(Result, Inst, 2);
876    break; //    1,2,3 SUBInst $Rd = memuh($Rs + #$u3_1)
877  case Hexagon::L2_loadri_io:
878    if (Inst.getOperand(1).getReg() == Hexagon::R29) {
879      Result.setOpcode(Hexagon::SL2_loadri_sp);
880      addOps(Result, Inst, 0);
881      addOps(Result, Inst, 2);
882      break; //  2 1,3 SUBInst $Rd = memw(r29 + #$u5_2)
883    } else {
884      Result.setOpcode(Hexagon::SL1_loadri_io);
885      addOps(Result, Inst, 0);
886      addOps(Result, Inst, 1);
887      addOps(Result, Inst, 2);
888      break; //    1,2,3 SUBInst $Rd = memw($Rs + #$u4_2)
889    }
890  case Hexagon::S4_storeirb_io:
891    Absolute = Inst.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
892    assert(Absolute);(void)Absolute;
893    if (Value == 0) {
894      Result.setOpcode(Hexagon::SS2_storebi0);
895      addOps(Result, Inst, 0);
896      addOps(Result, Inst, 1);
897      break; //    1,2 SUBInst memb($Rs + #$u4_0)=#0
898    } else if (Value == 1) {
899      Result.setOpcode(Hexagon::SS2_storebi1);
900      addOps(Result, Inst, 0);
901      addOps(Result, Inst, 1);
902      break; //  2 1,2 SUBInst memb($Rs + #$u4_0)=#1
903    }
904    break;
905  case Hexagon::S2_storerb_io:
906    Result.setOpcode(Hexagon::SS1_storeb_io);
907    addOps(Result, Inst, 0);
908    addOps(Result, Inst, 1);
909    addOps(Result, Inst, 2);
910    break; //    1,2,3 SUBInst memb($Rs + #$u4_0) = $Rt
911  case Hexagon::S2_storerd_io:
912    Result.setOpcode(Hexagon::SS2_stored_sp);
913    addOps(Result, Inst, 1);
914    addOps(Result, Inst, 2);
915    break; //    2,3 SUBInst memd(r29 + #$s6_3) = $Rtt
916  case Hexagon::S2_storerh_io:
917    Result.setOpcode(Hexagon::SS2_storeh_io);
918    addOps(Result, Inst, 0);
919    addOps(Result, Inst, 1);
920    addOps(Result, Inst, 2);
921    break; //    1,2,3 SUBInst memb($Rs + #$u4_0) = $Rt
922  case Hexagon::S4_storeiri_io:
923    Absolute = Inst.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
924    assert(Absolute);(void)Absolute;
925    if (Value == 0) {
926      Result.setOpcode(Hexagon::SS2_storewi0);
927      addOps(Result, Inst, 0);
928      addOps(Result, Inst, 1);
929      break; //  3 1,2 SUBInst memw($Rs + #$u4_2)=#0
930    } else if (Value == 1) {
931      Result.setOpcode(Hexagon::SS2_storewi1);
932      addOps(Result, Inst, 0);
933      addOps(Result, Inst, 1);
934      break; //  3 1,2 SUBInst memw($Rs + #$u4_2)=#1
935    } else if (Inst.getOperand(0).getReg() == Hexagon::R29) {
936      Result.setOpcode(Hexagon::SS2_storew_sp);
937      addOps(Result, Inst, 1);
938      addOps(Result, Inst, 2);
939      break; //  1 2,3 SUBInst memw(r29 + #$u5_2) = $Rt
940    }
941    break;
942  case Hexagon::S2_storeri_io:
943    if (Inst.getOperand(0).getReg() == Hexagon::R29) {
944      Result.setOpcode(Hexagon::SS2_storew_sp);
945      addOps(Result, Inst, 1);
946      addOps(Result, Inst, 2); //  1,2,3 SUBInst memw(sp + #$u5_2) = $Rt
947    } else {
948      Result.setOpcode(Hexagon::SS1_storew_io);
949      addOps(Result, Inst, 0);
950      addOps(Result, Inst, 1);
951      addOps(Result, Inst, 2); //  1,2,3 SUBInst memw($Rs + #$u4_2) = $Rt
952    }
953    break;
954  case Hexagon::A2_sxtb:
955    Result.setOpcode(Hexagon::SA1_sxtb);
956    addOps(Result, Inst, 0);
957    addOps(Result, Inst, 1);
958    break; //  1,2 SUBInst $Rd = sxtb($Rs)
959  case Hexagon::A2_sxth:
960    Result.setOpcode(Hexagon::SA1_sxth);
961    addOps(Result, Inst, 0);
962    addOps(Result, Inst, 1);
963    break; //  1,2 SUBInst $Rd = sxth($Rs)
964  case Hexagon::A2_tfr:
965    Result.setOpcode(Hexagon::SA1_tfr);
966    addOps(Result, Inst, 0);
967    addOps(Result, Inst, 1);
968    break; //  1,2 SUBInst $Rd = $Rs
969  case Hexagon::C2_cmovenewif:
970    Result.setOpcode(Hexagon::SA1_clrfnew);
971    addOps(Result, Inst, 0);
972    addOps(Result, Inst, 1);
973    break; //  2 SUBInst if (!p0.new) $Rd = #0
974  case Hexagon::C2_cmovenewit:
975    Result.setOpcode(Hexagon::SA1_clrtnew);
976    addOps(Result, Inst, 0);
977    addOps(Result, Inst, 1);
978    break; //  2 SUBInst if (p0.new) $Rd = #0
979  case Hexagon::C2_cmoveif:
980    Result.setOpcode(Hexagon::SA1_clrf);
981    addOps(Result, Inst, 0);
982    addOps(Result, Inst, 1);
983    break; //  2 SUBInst if (!p0) $Rd = #0
984  case Hexagon::C2_cmoveit:
985    Result.setOpcode(Hexagon::SA1_clrt);
986    addOps(Result, Inst, 0);
987    addOps(Result, Inst, 1);
988    break; //  2 SUBInst if (p0) $Rd = #0
989  case Hexagon::A2_tfrsi:
990    Absolute = Inst.getOperand(1).getExpr()->evaluateAsAbsolute(Value);
991    if (Absolute && Value == -1) {
992      Result.setOpcode(Hexagon::SA1_setin1);
993      addOps(Result, Inst, 0);
994      addOps(Result, Inst, 1);
995      break; //  2 1 SUBInst $Rd = #-1
996    } else {
997      Result.setOpcode(Hexagon::SA1_seti);
998      addOps(Result, Inst, 0);
999      addOps(Result, Inst, 1);
1000      break; //    1,2 SUBInst $Rd = #$u6
1001    }
1002  case Hexagon::A2_zxtb:
1003    Result.setOpcode(Hexagon::SA1_zxtb);
1004    addOps(Result, Inst, 0);
1005    addOps(Result, Inst, 1);
1006    break; //    1,2    $Rd = and($Rs, #255)
1007
1008  case Hexagon::A2_zxth:
1009    Result.setOpcode(Hexagon::SA1_zxth);
1010    addOps(Result, Inst, 0);
1011    addOps(Result, Inst, 1);
1012    break; //    1,2 SUBInst $Rd = zxth($Rs)
1013  }
1014  return Result;
1015}
1016
1017static bool isStoreInst(unsigned opCode) {
1018  switch (opCode) {
1019  case Hexagon::S2_storeri_io:
1020  case Hexagon::S2_storerb_io:
1021  case Hexagon::S2_storerh_io:
1022  case Hexagon::S2_storerd_io:
1023  case Hexagon::S4_storeiri_io:
1024  case Hexagon::S4_storeirb_io:
1025  case Hexagon::S2_allocframe:
1026    return true;
1027  default:
1028    return false;
1029  }
1030}
1031
1032SmallVector<DuplexCandidate, 8>
1033HexagonMCInstrInfo::getDuplexPossibilties(MCInstrInfo const &MCII,
1034                                          MCSubtargetInfo const &STI,
1035                                          MCInst const &MCB) {
1036  assert(isBundle(MCB));
1037  SmallVector<DuplexCandidate, 8> duplexToTry;
1038  // Use an "order matters" version of isDuplexPair.
1039  unsigned numInstrInPacket = MCB.getNumOperands();
1040
1041  for (unsigned distance = 1; distance < numInstrInPacket; ++distance) {
1042    for (unsigned j = HexagonMCInstrInfo::bundleInstructionsOffset,
1043                  k = j + distance;
1044         (j < numInstrInPacket) && (k < numInstrInPacket); ++j, ++k) {
1045
1046      // Check if reversible.
1047      bool bisReversable = true;
1048      if (isStoreInst(MCB.getOperand(j).getInst()->getOpcode()) &&
1049          isStoreInst(MCB.getOperand(k).getInst()->getOpcode())) {
1050        LLVM_DEBUG(dbgs() << "skip out of order write pair: " << k << "," << j
1051                          << "\n");
1052        bisReversable = false;
1053      }
1054      if (HexagonMCInstrInfo::isMemReorderDisabled(MCB)) // }:mem_noshuf
1055        bisReversable = false;
1056
1057      // Try in order.
1058      if (isOrderedDuplexPair(
1059              MCII, *MCB.getOperand(k).getInst(),
1060              HexagonMCInstrInfo::hasExtenderForIndex(MCB, k - 1),
1061              *MCB.getOperand(j).getInst(),
1062              HexagonMCInstrInfo::hasExtenderForIndex(MCB, j - 1),
1063              bisReversable, STI)) {
1064        // Get iClass.
1065        unsigned iClass = iClassOfDuplexPair(
1066            getDuplexCandidateGroup(*MCB.getOperand(k).getInst()),
1067            getDuplexCandidateGroup(*MCB.getOperand(j).getInst()));
1068
1069        // Save off pairs for duplex checking.
1070        duplexToTry.push_back(DuplexCandidate(j, k, iClass));
1071        LLVM_DEBUG(dbgs() << "adding pair: " << j << "," << k << ":"
1072                          << MCB.getOperand(j).getInst()->getOpcode() << ","
1073                          << MCB.getOperand(k).getInst()->getOpcode() << "\n");
1074        continue;
1075      } else {
1076        LLVM_DEBUG(dbgs() << "skipping pair: " << j << "," << k << ":"
1077                          << MCB.getOperand(j).getInst()->getOpcode() << ","
1078                          << MCB.getOperand(k).getInst()->getOpcode() << "\n");
1079      }
1080
1081      // Try reverse.
1082      if (bisReversable) {
1083        if (isOrderedDuplexPair(
1084                MCII, *MCB.getOperand(j).getInst(),
1085                HexagonMCInstrInfo::hasExtenderForIndex(MCB, j - 1),
1086                *MCB.getOperand(k).getInst(),
1087                HexagonMCInstrInfo::hasExtenderForIndex(MCB, k - 1),
1088                bisReversable, STI)) {
1089          // Get iClass.
1090          unsigned iClass = iClassOfDuplexPair(
1091              getDuplexCandidateGroup(*MCB.getOperand(j).getInst()),
1092              getDuplexCandidateGroup(*MCB.getOperand(k).getInst()));
1093
1094          // Save off pairs for duplex checking.
1095          duplexToTry.push_back(DuplexCandidate(k, j, iClass));
1096          LLVM_DEBUG(dbgs()
1097                     << "adding pair:" << k << "," << j << ":"
1098                     << MCB.getOperand(j).getInst()->getOpcode() << ","
1099                     << MCB.getOperand(k).getInst()->getOpcode() << "\n");
1100        } else {
1101          LLVM_DEBUG(dbgs()
1102                     << "skipping pair: " << k << "," << j << ":"
1103                     << MCB.getOperand(j).getInst()->getOpcode() << ","
1104                     << MCB.getOperand(k).getInst()->getOpcode() << "\n");
1105        }
1106      }
1107    }
1108  }
1109  return duplexToTry;
1110}
1111