blob: 4c508d6d29efb70bfeeff1289ae382f8b4415f67 [file] [log] [blame]
Colin LeMahieube8c4532015-06-05 16:00:11 +00001//===----- 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
23using namespace llvm;
24using namespace Hexagon;
25
26#define DEBUG_TYPE "hexagon-mcduplex-info"
27
28// pair table of subInstructions with opcodes
Craig Topper26260942015-10-18 05:15:34 +000029static const std::pair<unsigned, unsigned> opcodeData[] = {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +000030 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)};
Colin LeMahieube8c4532015-06-05 16:00:11 +000082
Colin LeMahieube8c4532015-06-05 16:00:11 +000083bool HexagonMCInstrInfo::isDuplexPairMatch(unsigned Ga, unsigned Gb) {
84 switch (Ga) {
85 case HexagonII::HSIG_None:
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);
102 case HexagonII::HSIG_Compound:
103 return (Gb == HexagonII::HSIG_Compound);
104 }
105 return false;
106}
107
108unsigned HexagonMCInstrInfo::iClassOfDuplexPair(unsigned Ga, unsigned Gb) {
109 switch (Ga) {
110 case HexagonII::HSIG_None:
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 }
168 case HexagonII::HSIG_Compound:
169 switch (Gb) {
170 case HexagonII::HSIG_Compound:
171 return 0xFFFFFFFF;
172 }
173 }
174 return 0xFFFFFFFF;
175}
176
177unsigned HexagonMCInstrInfo::getDuplexCandidateGroup(MCInst const &MCI) {
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)
193 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000194 if (HexagonMCInstrInfo::isIntReg(SrcReg) &&
195 Hexagon::R29 == SrcReg && inRange<5, 2>(MCI, 2)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000196 return HexagonII::HSIG_L2;
197 }
198 // Rd = memw(Rs+#u4:2)
199 if (HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000200 inRange<4, 2>(MCI, 2)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000201 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();
209 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
210 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000211 inRange<4>(MCI, 2)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000212 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();
230 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
231 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000232 inRange<3, 1>(MCI, 2)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000233 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();
240 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
241 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000242 inRange<3>(MCI, 2)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000243 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();
250 if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
251 HexagonMCInstrInfo::isIntReg(SrcReg) && Hexagon::R29 == SrcReg &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000252 inRange<5, 3>(MCI, 2)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000253 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:
Colin LeMahieube8c4532015-06-05 16:00:11 +0000265 // jumpr r31
266 // Actual form JMPR %PC<imp-def>, %R31<imp-use>, %R0<imp-use,internal>.
267 DstReg = MCI.getOperand(0).getReg();
Krzysztof Parzyszek6421b932016-08-19 14:04:45 +0000268 if (Hexagon::R31 == DstReg)
Colin LeMahieube8c4532015-06-05 16:00:11 +0000269 return HexagonII::HSIG_L2;
Colin LeMahieube8c4532015-06-05 16:00:11 +0000270 break;
271
272 case Hexagon::J2_jumprt:
273 case Hexagon::J2_jumprf:
274 case Hexagon::J2_jumprtnew:
275 case Hexagon::J2_jumprfnew:
Krzysztof Parzyszek6421b932016-08-19 14:04:45 +0000276 case Hexagon::J2_jumprtnewpt:
277 case Hexagon::J2_jumprfnewpt:
Colin LeMahieube8c4532015-06-05 16:00:11 +0000278 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) &&
314 HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000315 Hexagon::R29 == Src1Reg && inRange<5, 2>(MCI, 1)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000316 return HexagonII::HSIG_S2;
317 }
318 // memw(Rs+#u4:2) = Rt
319 if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
320 HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000321 inRange<4, 2>(MCI, 1)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000322 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();
329 if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
330 HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000331 inRange<4>(MCI, 1)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000332 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();
348 if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
349 HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000350 inRange<3, 1>(MCI, 1)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000351 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();
358 if (HexagonMCInstrInfo::isDblRegForSubInst(Src2Reg) &&
359 HexagonMCInstrInfo::isIntReg(Src1Reg) && Hexagon::R29 == Src1Reg &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000360 inSRange<6, 3>(MCI, 1)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000361 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();
367 if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000368 inRange<4, 2>(MCI, 1) && inRange<1>(MCI, 2)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000369 return HexagonII::HSIG_S2;
370 }
371 break;
372 case Hexagon::S4_storeirb_io:
373 // memb(Rs+#u4) = #U1
374 Src1Reg = MCI.getOperand(0).getReg();
375 if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000376 inRange<4>(MCI, 1) && inRange<1>(MCI, 2)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000377 return HexagonII::HSIG_S2;
378 }
379 break;
380 case Hexagon::S2_allocframe:
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000381 if (inRange<5, 3>(MCI, 0))
Colin LeMahieube8c4532015-06-05 16:00:11 +0000382 return HexagonII::HSIG_S2;
Colin LeMahieube8c4532015-06-05 16:00:11 +0000383 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();
405 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
406 // Rd = add(r29,#u6:2)
407 if (HexagonMCInstrInfo::isIntReg(SrcReg) && Hexagon::R29 == SrcReg &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000408 inRange<6, 2>(MCI, 2)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000409 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)
417 if (HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000418 (minConstant(MCI, 2) == 1 || minConstant(MCI, 2) == -1)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000419 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) &&
429 HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg)) {
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();
436 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
437 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000438 (minConstant(MCI, 2) == 1 || minConstant(MCI, 2) == 255)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000439 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();
446 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
447 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg)) {
448 return HexagonII::HSIG_A;
449 }
450 break;
451 case Hexagon::A2_tfrsi:
452 DstReg = MCI.getOperand(0).getReg();
453
454 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
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
467 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000468 Hexagon::P0 == PredReg && minConstant(MCI, 2) == 0) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000469 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 &&
477 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000478 inRange<2>(MCI, 2)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000479 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();
486 if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000487 inRange<2>(MCI, 1) && inRange<2>(MCI, 2)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000488 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();
495 if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
496 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000497 minConstant(MCI, 2) == 0) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000498 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();
505 if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
506 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000507 minConstant(MCI, 1) == 0) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000508 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();
518 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
519 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg)) {
520 return HexagonII::HSIG_A;
521 }
522 break;
523 }
524
525 return HexagonII::HSIG_None;
526}
527
528bool HexagonMCInstrInfo::subInstWouldBeExtended(MCInst const &potentialDuplex) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000529 unsigned DstReg, SrcReg;
Colin LeMahieube8c4532015-06-05 16:00:11 +0000530 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)) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000536 int64_t Value;
537 if (!potentialDuplex.getOperand(2).getExpr()->evaluateAsAbsolute(Value))
Colin LeMahieube8c4532015-06-05 16:00:11 +0000538 return true;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000539 if (!isShiftedInt<7, 0>(Value))
Colin LeMahieube8c4532015-06-05 16:00:11 +0000540 return true;
541 }
542 break;
543 case Hexagon::A2_tfrsi:
544 DstReg = potentialDuplex.getOperand(0).getReg();
545
546 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000547 int64_t Value;
548 if (!potentialDuplex.getOperand(1).getExpr()->evaluateAsAbsolute(Value))
Colin LeMahieube8c4532015-06-05 16:00:11 +0000549 return true;
550 // Check for case of Rd = #-1.
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000551 if (Value == -1)
Colin LeMahieube8c4532015-06-05 16:00:11 +0000552 return false;
553 // Check for case of Rd = #u6.
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000554 if (!isShiftedUInt<6, 0>(Value))
Colin LeMahieube8c4532015-06-05 16:00:11 +0000555 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.
565bool HexagonMCInstrInfo::isOrderedDuplexPair(MCInstrInfo const &MCII,
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),
579 MIbG = HexagonMCInstrInfo::getDuplexCandidateGroup(MIb);
580
Benjamin Kramer4d9d2cc2016-07-02 13:05:12 +0000581 static std::map<unsigned, unsigned> subinstOpcodeMap(std::begin(opcodeData),
582 std::end(opcodeData));
583
Colin LeMahieube8c4532015-06-05 16:00:11 +0000584 // 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) {
587 MCInst SubInst0 = HexagonMCInstrInfo::deriveSubInst(MIa);
588 MCInst SubInst1 = HexagonMCInstrInfo::deriveSubInst(MIb);
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.
639bool 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
645inline 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:
Krzysztof Parzyszek0b867222016-08-19 15:17:19 +0000676 case Hexagon::P0:
Colin LeMahieube8c4532015-06-05 16:00:11 +0000677 subInstPtr.addOperand(Inst.getOperand(opNum));
678 break;
679 }
680 } else
681 subInstPtr.addOperand(Inst.getOperand(opNum));
682}
683
684MCInst HexagonMCInstrInfo::deriveSubInst(MCInst const &Inst) {
685 MCInst Result;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000686 bool Absolute;
687 int64_t Value;
Colin LeMahieube8c4532015-06-05 16:00:11 +0000688 switch (Inst.getOpcode()) {
689 default:
690 // dbgs() << "opcode: "<< Inst->getOpcode() << "\n";
691 llvm_unreachable("Unimplemented subinstruction \n");
692 break;
693 case Hexagon::A2_addi:
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000694 Absolute = Inst.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
695 assert(Absolute);(void)Absolute;
696 if (Value == 1) {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000697 Result.setOpcode(Hexagon::SA1_inc);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000698 addOps(Result, Inst, 0);
699 addOps(Result, Inst, 1);
700 break;
701 } // 1,2 SUBInst $Rd = add($Rs, #1)
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000702 else if (Value == -1) {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000703 Result.setOpcode(Hexagon::SA1_dec);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000704 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) {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000709 Result.setOpcode(Hexagon::SA1_addsp);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000710 addOps(Result, Inst, 0);
711 addOps(Result, Inst, 2);
712 break;
713 } // 1,3 SUBInst $Rd = add(r29, #$u6_2)
714 else {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000715 Result.setOpcode(Hexagon::SA1_addi);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000716 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:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000722 Result.setOpcode(Hexagon::SA1_addrx);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000723 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:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000728 Result.setOpcode(Hexagon::SS2_allocframe);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000729 addOps(Result, Inst, 0);
730 break; // 1 SUBInst allocframe(#$u5_3)
731 case Hexagon::A2_andir:
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000732 if (minConstant(Inst, 2) == 255) {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000733 Result.setOpcode(Hexagon::SA1_zxtb);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000734 addOps(Result, Inst, 0);
735 addOps(Result, Inst, 1);
736 break; // 1,2 $Rd = and($Rs, #255)
737 } else {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000738 Result.setOpcode(Hexagon::SA1_and1);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000739 addOps(Result, Inst, 0);
740 addOps(Result, Inst, 1);
741 break; // 1,2 SUBInst $Rd = and($Rs, #1)
742 }
743 case Hexagon::C2_cmpeqi:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000744 Result.setOpcode(Hexagon::SA1_cmpeqi);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000745 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:
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000750 Absolute = Inst.getOperand(1).getExpr()->evaluateAsAbsolute(Value);
751 assert(Absolute);(void)Absolute;
752 if (Value == 1) {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000753 Result.setOpcode(Hexagon::SA1_combine1i);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000754 addOps(Result, Inst, 0);
755 addOps(Result, Inst, 2);
756 break; // 1,3 SUBInst $Rdd = combine(#1, #$u2)
757 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000758 if (Value == 3) {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000759 Result.setOpcode(Hexagon::SA1_combine3i);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000760 addOps(Result, Inst, 0);
761 addOps(Result, Inst, 2);
762 break; // 1,3 SUBInst $Rdd = combine(#3, #$u2)
763 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000764 if (Value == 0) {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000765 Result.setOpcode(Hexagon::SA1_combine0i);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000766 addOps(Result, Inst, 0);
767 addOps(Result, Inst, 2);
768 break; // 1,3 SUBInst $Rdd = combine(#0, #$u2)
769 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000770 if (Value == 2) {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000771 Result.setOpcode(Hexagon::SA1_combine2i);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000772 addOps(Result, Inst, 0);
773 addOps(Result, Inst, 2);
774 break; // 1,3 SUBInst $Rdd = combine(#2, #$u2)
775 }
776 case Hexagon::A4_combineir:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000777 Result.setOpcode(Hexagon::SA1_combinezr);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000778 addOps(Result, Inst, 0);
779 addOps(Result, Inst, 2);
780 break; // 1,3 SUBInst $Rdd = combine(#0, $Rs)
781
782 case Hexagon::A4_combineri:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000783 Result.setOpcode(Hexagon::SA1_combinerz);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000784 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:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000789 Result.setOpcode(Hexagon::SL2_return_tnew);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000790 break; // none SUBInst if (p0.new) dealloc_return:nt
791 case Hexagon::L4_return_fnew_pnt:
792 case Hexagon::L4_return_fnew_pt:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000793 Result.setOpcode(Hexagon::SL2_return_fnew);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000794 break; // none SUBInst if (!p0.new) dealloc_return:nt
795 case Hexagon::L4_return_f:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000796 Result.setOpcode(Hexagon::SL2_return_f);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000797 break; // none SUBInst if (!p0) dealloc_return
798 case Hexagon::L4_return_t:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000799 Result.setOpcode(Hexagon::SL2_return_t);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000800 break; // none SUBInst if (p0) dealloc_return
801 case Hexagon::L4_return:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000802 Result.setOpcode(Hexagon::SL2_return);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000803 break; // none SUBInst dealloc_return
804 case Hexagon::L2_deallocframe:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000805 Result.setOpcode(Hexagon::SL2_deallocframe);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000806 break; // none SUBInst deallocframe
807 case Hexagon::EH_RETURN_JMPR:
808 case Hexagon::J2_jumpr:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000809 Result.setOpcode(Hexagon::SL2_jumpr31);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000810 break; // none SUBInst jumpr r31
811 case Hexagon::J2_jumprf:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000812 Result.setOpcode(Hexagon::SL2_jumpr31_f);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000813 break; // none SUBInst if (!p0) jumpr r31
814 case Hexagon::J2_jumprfnew:
Krzysztof Parzyszek6421b932016-08-19 14:04:45 +0000815 case Hexagon::J2_jumprfnewpt:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000816 Result.setOpcode(Hexagon::SL2_jumpr31_fnew);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000817 break; // none SUBInst if (!p0.new) jumpr:nt r31
818 case Hexagon::J2_jumprt:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000819 Result.setOpcode(Hexagon::SL2_jumpr31_t);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000820 break; // none SUBInst if (p0) jumpr r31
821 case Hexagon::J2_jumprtnew:
Krzysztof Parzyszek6421b932016-08-19 14:04:45 +0000822 case Hexagon::J2_jumprtnewpt:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000823 Result.setOpcode(Hexagon::SL2_jumpr31_tnew);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000824 break; // none SUBInst if (p0.new) jumpr:nt r31
825 case Hexagon::L2_loadrb_io:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000826 Result.setOpcode(Hexagon::SL2_loadrb_io);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000827 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:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000832 Result.setOpcode(Hexagon::SL2_loadrd_sp);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000833 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:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000837 Result.setOpcode(Hexagon::SL2_loadrh_io);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000838 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:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000843 Result.setOpcode(Hexagon::SL1_loadrub_io);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000844 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:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000849 Result.setOpcode(Hexagon::SL2_loadruh_io);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000850 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) {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000856 Result.setOpcode(Hexagon::SL2_loadri_sp);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000857 addOps(Result, Inst, 0);
858 addOps(Result, Inst, 2);
859 break; // 2 1,3 SUBInst $Rd = memw(r29 + #$u5_2)
860 } else {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000861 Result.setOpcode(Hexagon::SL1_loadri_io);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000862 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:
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000868 Absolute = Inst.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
869 assert(Absolute);(void)Absolute;
870 if (Value == 0) {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000871 Result.setOpcode(Hexagon::SS2_storebi0);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000872 addOps(Result, Inst, 0);
873 addOps(Result, Inst, 1);
874 break; // 1,2 SUBInst memb($Rs + #$u4_0)=#0
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000875 } else if (Value == 1) {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000876 Result.setOpcode(Hexagon::SS2_storebi1);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000877 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:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000882 Result.setOpcode(Hexagon::SS1_storeb_io);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000883 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:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000888 Result.setOpcode(Hexagon::SS2_stored_sp);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000889 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:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000893 Result.setOpcode(Hexagon::SS2_storeh_io);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000894 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:
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000899 Absolute = Inst.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
900 assert(Absolute);(void)Absolute;
901 if (Value == 0) {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000902 Result.setOpcode(Hexagon::SS2_storewi0);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000903 addOps(Result, Inst, 0);
904 addOps(Result, Inst, 1);
905 break; // 3 1,2 SUBInst memw($Rs + #$u4_2)=#0
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000906 } else if (Value == 1) {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000907 Result.setOpcode(Hexagon::SS2_storewi1);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000908 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) {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000912 Result.setOpcode(Hexagon::SS2_storew_sp);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000913 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) {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000919 Result.setOpcode(Hexagon::SS2_storew_sp);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000920 addOps(Result, Inst, 1);
921 addOps(Result, Inst, 2); // 1,2,3 SUBInst memw(sp + #$u5_2) = $Rt
922 } else {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000923 Result.setOpcode(Hexagon::SS1_storew_io);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000924 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:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000930 Result.setOpcode(Hexagon::SA1_sxtb);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000931 addOps(Result, Inst, 0);
932 addOps(Result, Inst, 1);
933 break; // 1,2 SUBInst $Rd = sxtb($Rs)
934 case Hexagon::A2_sxth:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000935 Result.setOpcode(Hexagon::SA1_sxth);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000936 addOps(Result, Inst, 0);
937 addOps(Result, Inst, 1);
938 break; // 1,2 SUBInst $Rd = sxth($Rs)
939 case Hexagon::A2_tfr:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000940 Result.setOpcode(Hexagon::SA1_tfr);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000941 addOps(Result, Inst, 0);
942 addOps(Result, Inst, 1);
943 break; // 1,2 SUBInst $Rd = $Rs
944 case Hexagon::C2_cmovenewif:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000945 Result.setOpcode(Hexagon::SA1_clrfnew);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000946 addOps(Result, Inst, 0);
Krzysztof Parzyszek0b867222016-08-19 15:17:19 +0000947 addOps(Result, Inst, 1);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000948 break; // 2 SUBInst if (!p0.new) $Rd = #0
949 case Hexagon::C2_cmovenewit:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000950 Result.setOpcode(Hexagon::SA1_clrtnew);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000951 addOps(Result, Inst, 0);
Krzysztof Parzyszek0b867222016-08-19 15:17:19 +0000952 addOps(Result, Inst, 1);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000953 break; // 2 SUBInst if (p0.new) $Rd = #0
954 case Hexagon::C2_cmoveif:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000955 Result.setOpcode(Hexagon::SA1_clrf);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000956 addOps(Result, Inst, 0);
Krzysztof Parzyszek0b867222016-08-19 15:17:19 +0000957 addOps(Result, Inst, 1);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000958 break; // 2 SUBInst if (!p0) $Rd = #0
959 case Hexagon::C2_cmoveit:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000960 Result.setOpcode(Hexagon::SA1_clrt);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000961 addOps(Result, Inst, 0);
Krzysztof Parzyszek0b867222016-08-19 15:17:19 +0000962 addOps(Result, Inst, 1);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000963 break; // 2 SUBInst if (p0) $Rd = #0
964 case Hexagon::A2_tfrsi:
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000965 Absolute = Inst.getOperand(1).getExpr()->evaluateAsAbsolute(Value);
966 if (Absolute && Value == -1) {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000967 Result.setOpcode(Hexagon::SA1_setin1);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000968 addOps(Result, Inst, 0);
969 break; // 2 1 SUBInst $Rd = #-1
970 } else {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000971 Result.setOpcode(Hexagon::SA1_seti);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000972 addOps(Result, Inst, 0);
973 addOps(Result, Inst, 1);
974 break; // 1,2 SUBInst $Rd = #$u6
975 }
976 case Hexagon::A2_zxtb:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000977 Result.setOpcode(Hexagon::SA1_zxtb);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000978 addOps(Result, Inst, 0);
979 addOps(Result, Inst, 1);
980 break; // 1,2 $Rd = and($Rs, #255)
981
982 case Hexagon::A2_zxth:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000983 Result.setOpcode(Hexagon::SA1_zxth);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000984 addOps(Result, Inst, 0);
985 addOps(Result, Inst, 1);
986 break; // 1,2 SUBInst $Rd = zxth($Rs)
987 }
988 return Result;
989}
990
991static 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
1006SmallVector<DuplexCandidate, 8>
1007HexagonMCInstrInfo::getDuplexPossibilties(MCInstrInfo const &MCII,
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) {
1015 for (unsigned j = HexagonMCInstrInfo::bundleInstructionsOffset,
1016 k = j + distance;
1017 (j < numInstrInPacket) && (k < numInstrInPacket); ++j, ++k) {
1018
1019 // Check if reversable.
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 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001027 if (HexagonMCInstrInfo::isMemReorderDisabled(MCB)) // }:mem_noshuf
1028 bisReversable = false;
Colin LeMahieube8c4532015-06-05 16:00:11 +00001029
1030 // Try in order.
1031 if (isOrderedDuplexPair(
1032 MCII, *MCB.getOperand(k).getInst(),
1033 HexagonMCInstrInfo::hasExtenderForIndex(MCB, k - 1),
1034 *MCB.getOperand(j).getInst(),
1035 HexagonMCInstrInfo::hasExtenderForIndex(MCB, j - 1),
1036 bisReversable)) {
1037 // Get iClass.
1038 unsigned iClass = iClassOfDuplexPair(
1039 getDuplexCandidateGroup(*MCB.getOperand(k).getInst()),
1040 getDuplexCandidateGroup(*MCB.getOperand(j).getInst()));
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(),
1058 HexagonMCInstrInfo::hasExtenderForIndex(MCB, j - 1),
1059 *MCB.getOperand(k).getInst(),
1060 HexagonMCInstrInfo::hasExtenderForIndex(MCB, k - 1),
1061 bisReversable)) {
1062 // Get iClass.
1063 unsigned iClass = iClassOfDuplexPair(
1064 getDuplexCandidateGroup(*MCB.getOperand(j).getInst()),
1065 getDuplexCandidateGroup(*MCB.getOperand(k).getInst()));
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}