Coverage Report

Created: 2025-08-30 07:19

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