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