blob: fd064416fd9630de8eaddfc73b4bd698731f1678 [file] [log] [blame]
Eugene Zelenko52889212017-08-01 21:20:10 +00001//===- HexagonMCDuplexInfo.cpp - Instruction bundle checking --------------===//
Colin LeMahieube8c4532015-06-05 16:00:11 +00002//
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
Eugene Zelenko52889212017-08-01 21:20:10 +000014#include "MCTargetDesc/HexagonBaseInfo.h"
Colin LeMahieube8c4532015-06-05 16:00:11 +000015#include "MCTargetDesc/HexagonMCInstrInfo.h"
Eugene Zelenko52889212017-08-01 21:20:10 +000016#include "MCTargetDesc/HexagonMCTargetDesc.h"
Colin LeMahieube8c4532015-06-05 16:00:11 +000017#include "llvm/ADT/SmallVector.h"
Eugene Zelenko52889212017-08-01 21:20:10 +000018#include "llvm/MC/MCExpr.h"
19#include "llvm/MC/MCInst.h"
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +000020#include "llvm/MC/MCSubtargetInfo.h"
Colin LeMahieube8c4532015-06-05 16:00:11 +000021#include "llvm/Support/Debug.h"
Eugene Zelenko52889212017-08-01 21:20:10 +000022#include "llvm/Support/ErrorHandling.h"
23#include "llvm/Support/MathExtras.h"
Colin LeMahieube8c4532015-06-05 16:00:11 +000024#include "llvm/Support/raw_ostream.h"
Eugene Zelenko52889212017-08-01 21:20:10 +000025#include <cassert>
26#include <cstdint>
27#include <iterator>
Colin LeMahieube8c4532015-06-05 16:00:11 +000028#include <map>
Eugene Zelenko52889212017-08-01 21:20:10 +000029#include <utility>
Colin LeMahieube8c4532015-06-05 16:00:11 +000030
31using namespace llvm;
32using namespace Hexagon;
33
34#define DEBUG_TYPE "hexagon-mcduplex-info"
35
36// pair table of subInstructions with opcodes
Craig Topper26260942015-10-18 05:15:34 +000037static const std::pair<unsigned, unsigned> opcodeData[] = {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +000038 std::make_pair((unsigned)SA1_addi, 0),
39 std::make_pair((unsigned)SA1_addrx, 6144),
40 std::make_pair((unsigned)SA1_addsp, 3072),
41 std::make_pair((unsigned)SA1_and1, 4608),
42 std::make_pair((unsigned)SA1_clrf, 6768),
43 std::make_pair((unsigned)SA1_clrfnew, 6736),
44 std::make_pair((unsigned)SA1_clrt, 6752),
45 std::make_pair((unsigned)SA1_clrtnew, 6720),
46 std::make_pair((unsigned)SA1_cmpeqi, 6400),
47 std::make_pair((unsigned)SA1_combine0i, 7168),
48 std::make_pair((unsigned)SA1_combine1i, 7176),
49 std::make_pair((unsigned)SA1_combine2i, 7184),
50 std::make_pair((unsigned)SA1_combine3i, 7192),
51 std::make_pair((unsigned)SA1_combinerz, 7432),
52 std::make_pair((unsigned)SA1_combinezr, 7424),
53 std::make_pair((unsigned)SA1_dec, 4864),
54 std::make_pair((unsigned)SA1_inc, 4352),
55 std::make_pair((unsigned)SA1_seti, 2048),
56 std::make_pair((unsigned)SA1_setin1, 6656),
57 std::make_pair((unsigned)SA1_sxtb, 5376),
58 std::make_pair((unsigned)SA1_sxth, 5120),
59 std::make_pair((unsigned)SA1_tfr, 4096),
60 std::make_pair((unsigned)SA1_zxtb, 5888),
61 std::make_pair((unsigned)SA1_zxth, 5632),
62 std::make_pair((unsigned)SL1_loadri_io, 0),
63 std::make_pair((unsigned)SL1_loadrub_io, 4096),
64 std::make_pair((unsigned)SL2_deallocframe, 7936),
65 std::make_pair((unsigned)SL2_jumpr31, 8128),
66 std::make_pair((unsigned)SL2_jumpr31_f, 8133),
67 std::make_pair((unsigned)SL2_jumpr31_fnew, 8135),
68 std::make_pair((unsigned)SL2_jumpr31_t, 8132),
69 std::make_pair((unsigned)SL2_jumpr31_tnew, 8134),
70 std::make_pair((unsigned)SL2_loadrb_io, 4096),
71 std::make_pair((unsigned)SL2_loadrd_sp, 7680),
72 std::make_pair((unsigned)SL2_loadrh_io, 0),
73 std::make_pair((unsigned)SL2_loadri_sp, 7168),
74 std::make_pair((unsigned)SL2_loadruh_io, 2048),
75 std::make_pair((unsigned)SL2_return, 8000),
76 std::make_pair((unsigned)SL2_return_f, 8005),
77 std::make_pair((unsigned)SL2_return_fnew, 8007),
78 std::make_pair((unsigned)SL2_return_t, 8004),
79 std::make_pair((unsigned)SL2_return_tnew, 8006),
80 std::make_pair((unsigned)SS1_storeb_io, 4096),
81 std::make_pair((unsigned)SS1_storew_io, 0),
82 std::make_pair((unsigned)SS2_allocframe, 7168),
83 std::make_pair((unsigned)SS2_storebi0, 4608),
84 std::make_pair((unsigned)SS2_storebi1, 4864),
85 std::make_pair((unsigned)SS2_stored_sp, 2560),
86 std::make_pair((unsigned)SS2_storeh_io, 0),
87 std::make_pair((unsigned)SS2_storew_sp, 2048),
88 std::make_pair((unsigned)SS2_storewi0, 4096),
89 std::make_pair((unsigned)SS2_storewi1, 4352)};
Colin LeMahieube8c4532015-06-05 16:00:11 +000090
Colin LeMahieube8c4532015-06-05 16:00:11 +000091bool HexagonMCInstrInfo::isDuplexPairMatch(unsigned Ga, unsigned Gb) {
92 switch (Ga) {
93 case HexagonII::HSIG_None:
94 default:
95 return false;
96 case HexagonII::HSIG_L1:
97 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_A);
98 case HexagonII::HSIG_L2:
99 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
100 Gb == HexagonII::HSIG_A);
101 case HexagonII::HSIG_S1:
102 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
103 Gb == HexagonII::HSIG_S1 || Gb == HexagonII::HSIG_A);
104 case HexagonII::HSIG_S2:
105 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
106 Gb == HexagonII::HSIG_S1 || Gb == HexagonII::HSIG_S2 ||
107 Gb == HexagonII::HSIG_A);
108 case HexagonII::HSIG_A:
109 return (Gb == HexagonII::HSIG_A);
110 case HexagonII::HSIG_Compound:
111 return (Gb == HexagonII::HSIG_Compound);
112 }
113 return false;
114}
115
116unsigned HexagonMCInstrInfo::iClassOfDuplexPair(unsigned Ga, unsigned Gb) {
117 switch (Ga) {
118 case HexagonII::HSIG_None:
119 default:
120 break;
121 case HexagonII::HSIG_L1:
122 switch (Gb) {
123 default:
124 break;
125 case HexagonII::HSIG_L1:
126 return 0;
127 case HexagonII::HSIG_A:
128 return 0x4;
129 }
130 case HexagonII::HSIG_L2:
131 switch (Gb) {
132 default:
133 break;
134 case HexagonII::HSIG_L1:
135 return 0x1;
136 case HexagonII::HSIG_L2:
137 return 0x2;
138 case HexagonII::HSIG_A:
139 return 0x5;
140 }
141 case HexagonII::HSIG_S1:
142 switch (Gb) {
143 default:
144 break;
145 case HexagonII::HSIG_L1:
146 return 0x8;
147 case HexagonII::HSIG_L2:
148 return 0x9;
149 case HexagonII::HSIG_S1:
150 return 0xA;
151 case HexagonII::HSIG_A:
152 return 0x6;
153 }
154 case HexagonII::HSIG_S2:
155 switch (Gb) {
156 default:
157 break;
158 case HexagonII::HSIG_L1:
159 return 0xC;
160 case HexagonII::HSIG_L2:
161 return 0xD;
162 case HexagonII::HSIG_S1:
163 return 0xB;
164 case HexagonII::HSIG_S2:
165 return 0xE;
166 case HexagonII::HSIG_A:
167 return 0x7;
168 }
169 case HexagonII::HSIG_A:
170 switch (Gb) {
171 default:
172 break;
173 case HexagonII::HSIG_A:
174 return 0x3;
175 }
176 case HexagonII::HSIG_Compound:
177 switch (Gb) {
178 case HexagonII::HSIG_Compound:
179 return 0xFFFFFFFF;
180 }
181 }
182 return 0xFFFFFFFF;
183}
184
185unsigned HexagonMCInstrInfo::getDuplexCandidateGroup(MCInst const &MCI) {
186 unsigned DstReg, PredReg, SrcReg, Src1Reg, Src2Reg;
187
188 switch (MCI.getOpcode()) {
189 default:
190 return HexagonII::HSIG_None;
191 //
192 // Group L1:
193 //
194 // Rd = memw(Rs+#u4:2)
195 // Rd = memub(Rs+#u4:0)
196 case Hexagon::L2_loadri_io:
197 DstReg = MCI.getOperand(0).getReg();
198 SrcReg = MCI.getOperand(1).getReg();
199 // Special case this one from Group L2.
200 // Rd = memw(r29+#u5:2)
201 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000202 if (HexagonMCInstrInfo::isIntReg(SrcReg) &&
203 Hexagon::R29 == SrcReg && inRange<5, 2>(MCI, 2)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000204 return HexagonII::HSIG_L2;
205 }
206 // Rd = memw(Rs+#u4:2)
207 if (HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000208 inRange<4, 2>(MCI, 2)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000209 return HexagonII::HSIG_L1;
210 }
211 }
212 break;
213 case Hexagon::L2_loadrub_io:
214 // Rd = memub(Rs+#u4:0)
215 DstReg = MCI.getOperand(0).getReg();
216 SrcReg = MCI.getOperand(1).getReg();
217 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
218 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000219 inRange<4>(MCI, 2)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000220 return HexagonII::HSIG_L1;
221 }
222 break;
223 //
224 // Group L2:
225 //
226 // Rd = memh/memuh(Rs+#u3:1)
227 // Rd = memb(Rs+#u3:0)
228 // Rd = memw(r29+#u5:2) - Handled above.
229 // Rdd = memd(r29+#u5:3)
230 // deallocframe
231 // [if ([!]p0[.new])] dealloc_return
232 // [if ([!]p0[.new])] jumpr r31
233 case Hexagon::L2_loadrh_io:
234 case Hexagon::L2_loadruh_io:
235 // Rd = memh/memuh(Rs+#u3:1)
236 DstReg = MCI.getOperand(0).getReg();
237 SrcReg = MCI.getOperand(1).getReg();
238 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
239 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000240 inRange<3, 1>(MCI, 2)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000241 return HexagonII::HSIG_L2;
242 }
243 break;
244 case Hexagon::L2_loadrb_io:
245 // Rd = memb(Rs+#u3:0)
246 DstReg = MCI.getOperand(0).getReg();
247 SrcReg = MCI.getOperand(1).getReg();
248 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
249 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000250 inRange<3>(MCI, 2)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000251 return HexagonII::HSIG_L2;
252 }
253 break;
254 case Hexagon::L2_loadrd_io:
255 // Rdd = memd(r29+#u5:3)
256 DstReg = MCI.getOperand(0).getReg();
257 SrcReg = MCI.getOperand(1).getReg();
258 if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
259 HexagonMCInstrInfo::isIntReg(SrcReg) && Hexagon::R29 == SrcReg &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000260 inRange<5, 3>(MCI, 2)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000261 return HexagonII::HSIG_L2;
262 }
263 break;
264
265 case Hexagon::L4_return:
Colin LeMahieube8c4532015-06-05 16:00:11 +0000266 case Hexagon::L2_deallocframe:
Colin LeMahieube8c4532015-06-05 16:00:11 +0000267 return HexagonII::HSIG_L2;
Colin LeMahieube8c4532015-06-05 16:00:11 +0000268
Krzysztof Parzyszek9315c0d2018-03-20 19:23:18 +0000269 case Hexagon::EH_RETURN_JMPR:
Colin LeMahieube8c4532015-06-05 16:00:11 +0000270 case Hexagon::J2_jumpr:
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000271 case Hexagon::PS_jmpret:
Colin LeMahieube8c4532015-06-05 16:00:11 +0000272 // jumpr r31
Francis Visoiu Mistriha8a83d12017-12-07 10:40:31 +0000273 // Actual form JMPR implicit-def %pc, implicit %r31, implicit internal %r0.
Colin LeMahieube8c4532015-06-05 16:00:11 +0000274 DstReg = MCI.getOperand(0).getReg();
Krzysztof Parzyszek6421b932016-08-19 14:04:45 +0000275 if (Hexagon::R31 == DstReg)
Colin LeMahieube8c4532015-06-05 16:00:11 +0000276 return HexagonII::HSIG_L2;
Colin LeMahieube8c4532015-06-05 16:00:11 +0000277 break;
278
279 case Hexagon::J2_jumprt:
280 case Hexagon::J2_jumprf:
281 case Hexagon::J2_jumprtnew:
282 case Hexagon::J2_jumprfnew:
Krzysztof Parzyszek6421b932016-08-19 14:04:45 +0000283 case Hexagon::J2_jumprtnewpt:
284 case Hexagon::J2_jumprfnewpt:
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000285 case Hexagon::PS_jmprett:
286 case Hexagon::PS_jmpretf:
287 case Hexagon::PS_jmprettnew:
288 case Hexagon::PS_jmpretfnew:
289 case Hexagon::PS_jmprettnewpt:
290 case Hexagon::PS_jmpretfnewpt:
Colin LeMahieube8c4532015-06-05 16:00:11 +0000291 DstReg = MCI.getOperand(1).getReg();
292 SrcReg = MCI.getOperand(0).getReg();
293 // [if ([!]p0[.new])] jumpr r31
294 if ((HexagonMCInstrInfo::isPredReg(SrcReg) && (Hexagon::P0 == SrcReg)) &&
295 (Hexagon::R31 == DstReg)) {
296 return HexagonII::HSIG_L2;
297 }
298 break;
299 case Hexagon::L4_return_t:
Colin LeMahieube8c4532015-06-05 16:00:11 +0000300 case Hexagon::L4_return_f:
Colin LeMahieube8c4532015-06-05 16:00:11 +0000301 case Hexagon::L4_return_tnew_pnt:
Colin LeMahieube8c4532015-06-05 16:00:11 +0000302 case Hexagon::L4_return_fnew_pnt:
Colin LeMahieube8c4532015-06-05 16:00:11 +0000303 case Hexagon::L4_return_tnew_pt:
Colin LeMahieube8c4532015-06-05 16:00:11 +0000304 case Hexagon::L4_return_fnew_pt:
305 // [if ([!]p0[.new])] dealloc_return
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000306 SrcReg = MCI.getOperand(1).getReg();
Colin LeMahieube8c4532015-06-05 16:00:11 +0000307 if (Hexagon::P0 == SrcReg) {
308 return HexagonII::HSIG_L2;
309 }
310 break;
311 //
312 // Group S1:
313 //
314 // memw(Rs+#u4:2) = Rt
315 // memb(Rs+#u4:0) = Rt
316 case Hexagon::S2_storeri_io:
317 // Special case this one from Group S2.
318 // memw(r29+#u5:2) = Rt
319 Src1Reg = MCI.getOperand(0).getReg();
320 Src2Reg = MCI.getOperand(2).getReg();
321 if (HexagonMCInstrInfo::isIntReg(Src1Reg) &&
322 HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000323 Hexagon::R29 == Src1Reg && inRange<5, 2>(MCI, 1)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000324 return HexagonII::HSIG_S2;
325 }
326 // memw(Rs+#u4:2) = Rt
327 if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
328 HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000329 inRange<4, 2>(MCI, 1)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000330 return HexagonII::HSIG_S1;
331 }
332 break;
333 case Hexagon::S2_storerb_io:
334 // memb(Rs+#u4:0) = Rt
335 Src1Reg = MCI.getOperand(0).getReg();
336 Src2Reg = MCI.getOperand(2).getReg();
337 if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
338 HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000339 inRange<4>(MCI, 1)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000340 return HexagonII::HSIG_S1;
341 }
342 break;
343 //
344 // Group S2:
345 //
346 // memh(Rs+#u3:1) = Rt
347 // memw(r29+#u5:2) = Rt
348 // memd(r29+#s6:3) = Rtt
349 // memw(Rs+#u4:2) = #U1
350 // memb(Rs+#u4) = #U1
351 // allocframe(#u5:3)
352 case Hexagon::S2_storerh_io:
353 // memh(Rs+#u3:1) = Rt
354 Src1Reg = MCI.getOperand(0).getReg();
355 Src2Reg = MCI.getOperand(2).getReg();
356 if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
357 HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000358 inRange<3, 1>(MCI, 1)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000359 return HexagonII::HSIG_S2;
360 }
361 break;
362 case Hexagon::S2_storerd_io:
363 // memd(r29+#s6:3) = Rtt
364 Src1Reg = MCI.getOperand(0).getReg();
365 Src2Reg = MCI.getOperand(2).getReg();
366 if (HexagonMCInstrInfo::isDblRegForSubInst(Src2Reg) &&
367 HexagonMCInstrInfo::isIntReg(Src1Reg) && Hexagon::R29 == Src1Reg &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000368 inSRange<6, 3>(MCI, 1)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000369 return HexagonII::HSIG_S2;
370 }
371 break;
372 case Hexagon::S4_storeiri_io:
373 // memw(Rs+#u4:2) = #U1
374 Src1Reg = MCI.getOperand(0).getReg();
375 if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000376 inRange<4, 2>(MCI, 1) && inRange<1>(MCI, 2)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000377 return HexagonII::HSIG_S2;
378 }
379 break;
380 case Hexagon::S4_storeirb_io:
381 // memb(Rs+#u4) = #U1
382 Src1Reg = MCI.getOperand(0).getReg();
383 if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000384 inRange<4>(MCI, 1) && inRange<1>(MCI, 2)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000385 return HexagonII::HSIG_S2;
386 }
387 break;
388 case Hexagon::S2_allocframe:
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000389 if (inRange<5, 3>(MCI, 2))
Colin LeMahieube8c4532015-06-05 16:00:11 +0000390 return HexagonII::HSIG_S2;
Colin LeMahieube8c4532015-06-05 16:00:11 +0000391 break;
392 //
393 // Group A:
394 //
395 // Rx = add(Rx,#s7)
396 // Rd = Rs
397 // Rd = #u6
398 // Rd = #-1
399 // if ([!]P0[.new]) Rd = #0
400 // Rd = add(r29,#u6:2)
401 // Rx = add(Rx,Rs)
402 // P0 = cmp.eq(Rs,#u2)
403 // Rdd = combine(#0,Rs)
404 // Rdd = combine(Rs,#0)
405 // Rdd = combine(#u2,#U2)
406 // Rd = add(Rs,#1)
407 // Rd = add(Rs,#-1)
408 // Rd = sxth/sxtb/zxtb/zxth(Rs)
409 // Rd = and(Rs,#1)
410 case Hexagon::A2_addi:
411 DstReg = MCI.getOperand(0).getReg();
412 SrcReg = MCI.getOperand(1).getReg();
413 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
414 // Rd = add(r29,#u6:2)
415 if (HexagonMCInstrInfo::isIntReg(SrcReg) && Hexagon::R29 == SrcReg &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000416 inRange<6, 2>(MCI, 2)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000417 return HexagonII::HSIG_A;
418 }
419 // Rx = add(Rx,#s7)
420 if (DstReg == SrcReg) {
421 return HexagonII::HSIG_A;
422 }
423 // Rd = add(Rs,#1)
424 // Rd = add(Rs,#-1)
425 if (HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000426 (minConstant(MCI, 2) == 1 || minConstant(MCI, 2) == -1)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000427 return HexagonII::HSIG_A;
428 }
429 }
430 break;
431 case Hexagon::A2_add:
432 // Rx = add(Rx,Rs)
433 DstReg = MCI.getOperand(0).getReg();
434 Src1Reg = MCI.getOperand(1).getReg();
435 Src2Reg = MCI.getOperand(2).getReg();
436 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) && (DstReg == Src1Reg) &&
437 HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg)) {
438 return HexagonII::HSIG_A;
439 }
440 break;
441 case Hexagon::A2_andir:
442 DstReg = MCI.getOperand(0).getReg();
443 SrcReg = MCI.getOperand(1).getReg();
444 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
445 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000446 (minConstant(MCI, 2) == 1 || minConstant(MCI, 2) == 255)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000447 return HexagonII::HSIG_A;
448 }
449 break;
450 case Hexagon::A2_tfr:
451 // Rd = Rs
452 DstReg = MCI.getOperand(0).getReg();
453 SrcReg = MCI.getOperand(1).getReg();
454 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
455 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg)) {
456 return HexagonII::HSIG_A;
457 }
458 break;
459 case Hexagon::A2_tfrsi:
460 DstReg = MCI.getOperand(0).getReg();
461
462 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
463 return HexagonII::HSIG_A;
464 }
465 break;
466 case Hexagon::C2_cmoveit:
467 case Hexagon::C2_cmovenewit:
468 case Hexagon::C2_cmoveif:
469 case Hexagon::C2_cmovenewif:
470 // if ([!]P0[.new]) Rd = #0
471 // Actual form:
Francis Visoiu Mistriha8a83d12017-12-07 10:40:31 +0000472 // %r16 = C2_cmovenewit internal %p0, 0, implicit undef %r16;
Colin LeMahieube8c4532015-06-05 16:00:11 +0000473 DstReg = MCI.getOperand(0).getReg(); // Rd
474 PredReg = MCI.getOperand(1).getReg(); // P0
475 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000476 Hexagon::P0 == PredReg && minConstant(MCI, 2) == 0) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000477 return HexagonII::HSIG_A;
478 }
479 break;
480 case Hexagon::C2_cmpeqi:
481 // P0 = cmp.eq(Rs,#u2)
482 DstReg = MCI.getOperand(0).getReg();
483 SrcReg = MCI.getOperand(1).getReg();
484 if (Hexagon::P0 == DstReg &&
485 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000486 inRange<2>(MCI, 2)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000487 return HexagonII::HSIG_A;
488 }
489 break;
490 case Hexagon::A2_combineii:
491 case Hexagon::A4_combineii:
492 // Rdd = combine(#u2,#U2)
493 DstReg = MCI.getOperand(0).getReg();
494 if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000495 inRange<2>(MCI, 1) && inRange<2>(MCI, 2)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000496 return HexagonII::HSIG_A;
497 }
498 break;
499 case Hexagon::A4_combineri:
500 // Rdd = combine(Rs,#0)
501 DstReg = MCI.getOperand(0).getReg();
502 SrcReg = MCI.getOperand(1).getReg();
503 if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
504 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000505 minConstant(MCI, 2) == 0) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000506 return HexagonII::HSIG_A;
507 }
508 break;
509 case Hexagon::A4_combineir:
510 // Rdd = combine(#0,Rs)
511 DstReg = MCI.getOperand(0).getReg();
512 SrcReg = MCI.getOperand(2).getReg();
513 if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
514 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000515 minConstant(MCI, 1) == 0) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000516 return HexagonII::HSIG_A;
517 }
518 break;
519 case Hexagon::A2_sxtb:
520 case Hexagon::A2_sxth:
521 case Hexagon::A2_zxtb:
522 case Hexagon::A2_zxth:
523 // Rd = sxth/sxtb/zxtb/zxth(Rs)
524 DstReg = MCI.getOperand(0).getReg();
525 SrcReg = MCI.getOperand(1).getReg();
526 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
527 HexagonMCInstrInfo::isIntRegForSubInst(SrcReg)) {
528 return HexagonII::HSIG_A;
529 }
530 break;
531 }
532
533 return HexagonII::HSIG_None;
534}
535
536bool HexagonMCInstrInfo::subInstWouldBeExtended(MCInst const &potentialDuplex) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000537 unsigned DstReg, SrcReg;
Colin LeMahieube8c4532015-06-05 16:00:11 +0000538 switch (potentialDuplex.getOpcode()) {
539 case Hexagon::A2_addi:
540 // testing for case of: Rx = add(Rx,#s7)
541 DstReg = potentialDuplex.getOperand(0).getReg();
542 SrcReg = potentialDuplex.getOperand(1).getReg();
543 if (DstReg == SrcReg && HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000544 int64_t Value;
545 if (!potentialDuplex.getOperand(2).getExpr()->evaluateAsAbsolute(Value))
Colin LeMahieube8c4532015-06-05 16:00:11 +0000546 return true;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000547 if (!isShiftedInt<7, 0>(Value))
Colin LeMahieube8c4532015-06-05 16:00:11 +0000548 return true;
549 }
550 break;
551 case Hexagon::A2_tfrsi:
552 DstReg = potentialDuplex.getOperand(0).getReg();
553
554 if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000555 int64_t Value;
556 if (!potentialDuplex.getOperand(1).getExpr()->evaluateAsAbsolute(Value))
Colin LeMahieube8c4532015-06-05 16:00:11 +0000557 return true;
558 // Check for case of Rd = #-1.
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000559 if (Value == -1)
Colin LeMahieube8c4532015-06-05 16:00:11 +0000560 return false;
561 // Check for case of Rd = #u6.
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000562 if (!isShiftedUInt<6, 0>(Value))
Colin LeMahieube8c4532015-06-05 16:00:11 +0000563 return true;
564 }
565 break;
566 default:
567 break;
568 }
569 return false;
570}
571
572/// non-Symmetrical. See if these two instructions are fit for duplex pair.
573bool HexagonMCInstrInfo::isOrderedDuplexPair(MCInstrInfo const &MCII,
574 MCInst const &MIa, bool ExtendedA,
575 MCInst const &MIb, bool ExtendedB,
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000576 bool bisReversable,
577 MCSubtargetInfo const &STI) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000578 // Slot 1 cannot be extended in duplexes PRM 10.5
579 if (ExtendedA)
580 return false;
581 // Only A2_addi and A2_tfrsi can be extended in duplex form PRM 10.5
582 if (ExtendedB) {
583 unsigned Opcode = MIb.getOpcode();
584 if ((Opcode != Hexagon::A2_addi) && (Opcode != Hexagon::A2_tfrsi))
585 return false;
586 }
587 unsigned MIaG = HexagonMCInstrInfo::getDuplexCandidateGroup(MIa),
588 MIbG = HexagonMCInstrInfo::getDuplexCandidateGroup(MIb);
589
Benjamin Kramer4d9d2cc2016-07-02 13:05:12 +0000590 static std::map<unsigned, unsigned> subinstOpcodeMap(std::begin(opcodeData),
591 std::end(opcodeData));
592
Colin LeMahieube8c4532015-06-05 16:00:11 +0000593 // If a duplex contains 2 insns in the same group, the insns must be
594 // ordered such that the numerically smaller opcode is in slot 1.
595 if ((MIaG != HexagonII::HSIG_None) && (MIaG == MIbG) && bisReversable) {
596 MCInst SubInst0 = HexagonMCInstrInfo::deriveSubInst(MIa);
597 MCInst SubInst1 = HexagonMCInstrInfo::deriveSubInst(MIb);
598
599 unsigned zeroedSubInstS0 =
600 subinstOpcodeMap.find(SubInst0.getOpcode())->second;
601 unsigned zeroedSubInstS1 =
602 subinstOpcodeMap.find(SubInst1.getOpcode())->second;
603
604 if (zeroedSubInstS0 < zeroedSubInstS1)
605 // subinstS0 (maps to slot 0) must be greater than
606 // subinstS1 (maps to slot 1)
607 return false;
608 }
609
610 // allocframe must always be in slot 0
611 if (MIb.getOpcode() == Hexagon::S2_allocframe)
612 return false;
613
614 if ((MIaG != HexagonII::HSIG_None) && (MIbG != HexagonII::HSIG_None)) {
615 // Prevent 2 instructions with extenders from duplexing
616 // Note that MIb (slot1) can be extended and MIa (slot0)
617 // can never be extended
618 if (subInstWouldBeExtended(MIa))
619 return false;
620
621 // If duplexing produces an extender, but the original did not
622 // have an extender, do not duplex.
623 if (subInstWouldBeExtended(MIb) && !ExtendedB)
624 return false;
625 }
626
627 // If jumpr r31 appears, it must be in slot 0, and never slot 1 (MIb).
628 if (MIbG == HexagonII::HSIG_L2) {
629 if ((MIb.getNumOperands() > 1) && MIb.getOperand(1).isReg() &&
630 (MIb.getOperand(1).getReg() == Hexagon::R31))
631 return false;
632 if ((MIb.getNumOperands() > 0) && MIb.getOperand(0).isReg() &&
633 (MIb.getOperand(0).getReg() == Hexagon::R31))
634 return false;
635 }
636
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000637 if (STI.getCPU().equals_lower("hexagonv4") ||
638 STI.getCPU().equals_lower("hexagonv5") ||
639 STI.getCPU().equals_lower("hexagonv55") ||
640 STI.getCPU().equals_lower("hexagonv60")) {
641 // If a store appears, it must be in slot 0 (MIa) 1st, and then slot 1 (MIb);
642 // therefore, not duplexable if slot 1 is a store, and slot 0 is not.
643 if ((MIbG == HexagonII::HSIG_S1) || (MIbG == HexagonII::HSIG_S2)) {
644 if ((MIaG != HexagonII::HSIG_S1) && (MIaG != HexagonII::HSIG_S2))
645 return false;
646 }
Colin LeMahieube8c4532015-06-05 16:00:11 +0000647 }
648
649 return (isDuplexPairMatch(MIaG, MIbG));
650}
651
652/// Symmetrical. See if these two instructions are fit for duplex pair.
653bool HexagonMCInstrInfo::isDuplexPair(MCInst const &MIa, MCInst const &MIb) {
654 unsigned MIaG = getDuplexCandidateGroup(MIa),
655 MIbG = getDuplexCandidateGroup(MIb);
656 return (isDuplexPairMatch(MIaG, MIbG) || isDuplexPairMatch(MIbG, MIaG));
657}
658
659inline static void addOps(MCInst &subInstPtr, MCInst const &Inst,
660 unsigned opNum) {
661 if (Inst.getOperand(opNum).isReg()) {
662 switch (Inst.getOperand(opNum).getReg()) {
663 default:
664 llvm_unreachable("Not Duplexable Register");
665 break;
666 case Hexagon::R0:
667 case Hexagon::R1:
668 case Hexagon::R2:
669 case Hexagon::R3:
670 case Hexagon::R4:
671 case Hexagon::R5:
672 case Hexagon::R6:
673 case Hexagon::R7:
674 case Hexagon::D0:
675 case Hexagon::D1:
676 case Hexagon::D2:
677 case Hexagon::D3:
678 case Hexagon::R16:
679 case Hexagon::R17:
680 case Hexagon::R18:
681 case Hexagon::R19:
682 case Hexagon::R20:
683 case Hexagon::R21:
684 case Hexagon::R22:
685 case Hexagon::R23:
686 case Hexagon::D8:
687 case Hexagon::D9:
688 case Hexagon::D10:
689 case Hexagon::D11:
Krzysztof Parzyszek0b867222016-08-19 15:17:19 +0000690 case Hexagon::P0:
Colin LeMahieube8c4532015-06-05 16:00:11 +0000691 subInstPtr.addOperand(Inst.getOperand(opNum));
692 break;
693 }
694 } else
695 subInstPtr.addOperand(Inst.getOperand(opNum));
696}
697
698MCInst HexagonMCInstrInfo::deriveSubInst(MCInst const &Inst) {
699 MCInst Result;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000700 bool Absolute;
701 int64_t Value;
Colin LeMahieube8c4532015-06-05 16:00:11 +0000702 switch (Inst.getOpcode()) {
703 default:
704 // dbgs() << "opcode: "<< Inst->getOpcode() << "\n";
705 llvm_unreachable("Unimplemented subinstruction \n");
706 break;
707 case Hexagon::A2_addi:
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000708 Absolute = Inst.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
Krzysztof Parzyszekf63ad392017-06-22 15:53:31 +0000709 if (Absolute) {
710 if (Value == 1) {
711 Result.setOpcode(Hexagon::SA1_inc);
712 addOps(Result, Inst, 0);
713 addOps(Result, Inst, 1);
714 break;
715 } // 1,2 SUBInst $Rd = add($Rs, #1)
716 if (Value == -1) {
717 Result.setOpcode(Hexagon::SA1_dec);
718 addOps(Result, Inst, 0);
719 addOps(Result, Inst, 1);
720 addOps(Result, Inst, 2);
721 break;
722 } // 1,2 SUBInst $Rd = add($Rs,#-1)
723 if (Inst.getOperand(1).getReg() == Hexagon::R29) {
724 Result.setOpcode(Hexagon::SA1_addsp);
725 addOps(Result, Inst, 0);
726 addOps(Result, Inst, 2);
727 break;
728 } // 1,3 SUBInst $Rd = add(r29, #$u6_2)
729 }
730 Result.setOpcode(Hexagon::SA1_addi);
731 addOps(Result, Inst, 0);
732 addOps(Result, Inst, 1);
733 addOps(Result, Inst, 2);
734 break; // 1,2,3 SUBInst $Rx = add($Rx, #$s7)
Colin LeMahieube8c4532015-06-05 16:00:11 +0000735 case Hexagon::A2_add:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000736 Result.setOpcode(Hexagon::SA1_addrx);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000737 addOps(Result, Inst, 0);
738 addOps(Result, Inst, 1);
739 addOps(Result, Inst, 2);
740 break; // 1,2,3 SUBInst $Rx = add($_src_, $Rs)
741 case Hexagon::S2_allocframe:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000742 Result.setOpcode(Hexagon::SS2_allocframe);
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +0000743 addOps(Result, Inst, 2);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000744 break; // 1 SUBInst allocframe(#$u5_3)
745 case Hexagon::A2_andir:
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000746 if (minConstant(Inst, 2) == 255) {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000747 Result.setOpcode(Hexagon::SA1_zxtb);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000748 addOps(Result, Inst, 0);
749 addOps(Result, Inst, 1);
750 break; // 1,2 $Rd = and($Rs, #255)
751 } else {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000752 Result.setOpcode(Hexagon::SA1_and1);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000753 addOps(Result, Inst, 0);
754 addOps(Result, Inst, 1);
755 break; // 1,2 SUBInst $Rd = and($Rs, #1)
756 }
757 case Hexagon::C2_cmpeqi:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000758 Result.setOpcode(Hexagon::SA1_cmpeqi);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000759 addOps(Result, Inst, 1);
760 addOps(Result, Inst, 2);
761 break; // 2,3 SUBInst p0 = cmp.eq($Rs, #$u2)
762 case Hexagon::A4_combineii:
763 case Hexagon::A2_combineii:
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000764 Absolute = Inst.getOperand(1).getExpr()->evaluateAsAbsolute(Value);
765 assert(Absolute);(void)Absolute;
766 if (Value == 1) {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000767 Result.setOpcode(Hexagon::SA1_combine1i);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000768 addOps(Result, Inst, 0);
769 addOps(Result, Inst, 2);
770 break; // 1,3 SUBInst $Rdd = combine(#1, #$u2)
771 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000772 if (Value == 3) {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000773 Result.setOpcode(Hexagon::SA1_combine3i);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000774 addOps(Result, Inst, 0);
775 addOps(Result, Inst, 2);
776 break; // 1,3 SUBInst $Rdd = combine(#3, #$u2)
777 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000778 if (Value == 0) {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000779 Result.setOpcode(Hexagon::SA1_combine0i);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000780 addOps(Result, Inst, 0);
781 addOps(Result, Inst, 2);
782 break; // 1,3 SUBInst $Rdd = combine(#0, #$u2)
783 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000784 if (Value == 2) {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000785 Result.setOpcode(Hexagon::SA1_combine2i);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000786 addOps(Result, Inst, 0);
787 addOps(Result, Inst, 2);
788 break; // 1,3 SUBInst $Rdd = combine(#2, #$u2)
789 }
Krzysztof Parzyszek9315c0d2018-03-20 19:23:18 +0000790 break;
Colin LeMahieube8c4532015-06-05 16:00:11 +0000791 case Hexagon::A4_combineir:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000792 Result.setOpcode(Hexagon::SA1_combinezr);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000793 addOps(Result, Inst, 0);
794 addOps(Result, Inst, 2);
795 break; // 1,3 SUBInst $Rdd = combine(#0, $Rs)
Colin LeMahieube8c4532015-06-05 16:00:11 +0000796 case Hexagon::A4_combineri:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000797 Result.setOpcode(Hexagon::SA1_combinerz);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000798 addOps(Result, Inst, 0);
799 addOps(Result, Inst, 1);
800 break; // 1,2 SUBInst $Rdd = combine($Rs, #0)
801 case Hexagon::L4_return_tnew_pnt:
802 case Hexagon::L4_return_tnew_pt:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000803 Result.setOpcode(Hexagon::SL2_return_tnew);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000804 break; // none SUBInst if (p0.new) dealloc_return:nt
805 case Hexagon::L4_return_fnew_pnt:
806 case Hexagon::L4_return_fnew_pt:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000807 Result.setOpcode(Hexagon::SL2_return_fnew);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000808 break; // none SUBInst if (!p0.new) dealloc_return:nt
809 case Hexagon::L4_return_f:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000810 Result.setOpcode(Hexagon::SL2_return_f);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000811 break; // none SUBInst if (!p0) dealloc_return
812 case Hexagon::L4_return_t:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000813 Result.setOpcode(Hexagon::SL2_return_t);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000814 break; // none SUBInst if (p0) dealloc_return
815 case Hexagon::L4_return:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000816 Result.setOpcode(Hexagon::SL2_return);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000817 break; // none SUBInst dealloc_return
818 case Hexagon::L2_deallocframe:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000819 Result.setOpcode(Hexagon::SL2_deallocframe);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000820 break; // none SUBInst deallocframe
821 case Hexagon::EH_RETURN_JMPR:
822 case Hexagon::J2_jumpr:
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000823 case Hexagon::PS_jmpret:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000824 Result.setOpcode(Hexagon::SL2_jumpr31);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000825 break; // none SUBInst jumpr r31
826 case Hexagon::J2_jumprf:
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000827 case Hexagon::PS_jmpretf:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000828 Result.setOpcode(Hexagon::SL2_jumpr31_f);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000829 break; // none SUBInst if (!p0) jumpr r31
830 case Hexagon::J2_jumprfnew:
Krzysztof Parzyszek6421b932016-08-19 14:04:45 +0000831 case Hexagon::J2_jumprfnewpt:
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000832 case Hexagon::PS_jmpretfnewpt:
833 case Hexagon::PS_jmpretfnew:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000834 Result.setOpcode(Hexagon::SL2_jumpr31_fnew);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000835 break; // none SUBInst if (!p0.new) jumpr:nt r31
836 case Hexagon::J2_jumprt:
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000837 case Hexagon::PS_jmprett:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000838 Result.setOpcode(Hexagon::SL2_jumpr31_t);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000839 break; // none SUBInst if (p0) jumpr r31
840 case Hexagon::J2_jumprtnew:
Krzysztof Parzyszek6421b932016-08-19 14:04:45 +0000841 case Hexagon::J2_jumprtnewpt:
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000842 case Hexagon::PS_jmprettnewpt:
843 case Hexagon::PS_jmprettnew:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000844 Result.setOpcode(Hexagon::SL2_jumpr31_tnew);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000845 break; // none SUBInst if (p0.new) jumpr:nt r31
846 case Hexagon::L2_loadrb_io:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000847 Result.setOpcode(Hexagon::SL2_loadrb_io);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000848 addOps(Result, Inst, 0);
849 addOps(Result, Inst, 1);
850 addOps(Result, Inst, 2);
851 break; // 1,2,3 SUBInst $Rd = memb($Rs + #$u3_0)
852 case Hexagon::L2_loadrd_io:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000853 Result.setOpcode(Hexagon::SL2_loadrd_sp);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000854 addOps(Result, Inst, 0);
855 addOps(Result, Inst, 2);
856 break; // 1,3 SUBInst $Rdd = memd(r29 + #$u5_3)
857 case Hexagon::L2_loadrh_io:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000858 Result.setOpcode(Hexagon::SL2_loadrh_io);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000859 addOps(Result, Inst, 0);
860 addOps(Result, Inst, 1);
861 addOps(Result, Inst, 2);
862 break; // 1,2,3 SUBInst $Rd = memh($Rs + #$u3_1)
863 case Hexagon::L2_loadrub_io:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000864 Result.setOpcode(Hexagon::SL1_loadrub_io);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000865 addOps(Result, Inst, 0);
866 addOps(Result, Inst, 1);
867 addOps(Result, Inst, 2);
868 break; // 1,2,3 SUBInst $Rd = memub($Rs + #$u4_0)
869 case Hexagon::L2_loadruh_io:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000870 Result.setOpcode(Hexagon::SL2_loadruh_io);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000871 addOps(Result, Inst, 0);
872 addOps(Result, Inst, 1);
873 addOps(Result, Inst, 2);
874 break; // 1,2,3 SUBInst $Rd = memuh($Rs + #$u3_1)
875 case Hexagon::L2_loadri_io:
876 if (Inst.getOperand(1).getReg() == Hexagon::R29) {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000877 Result.setOpcode(Hexagon::SL2_loadri_sp);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000878 addOps(Result, Inst, 0);
879 addOps(Result, Inst, 2);
880 break; // 2 1,3 SUBInst $Rd = memw(r29 + #$u5_2)
881 } else {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000882 Result.setOpcode(Hexagon::SL1_loadri_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 $Rd = memw($Rs + #$u4_2)
887 }
888 case Hexagon::S4_storeirb_io:
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000889 Absolute = Inst.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
890 assert(Absolute);(void)Absolute;
891 if (Value == 0) {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000892 Result.setOpcode(Hexagon::SS2_storebi0);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000893 addOps(Result, Inst, 0);
894 addOps(Result, Inst, 1);
895 break; // 1,2 SUBInst memb($Rs + #$u4_0)=#0
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000896 } else if (Value == 1) {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000897 Result.setOpcode(Hexagon::SS2_storebi1);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000898 addOps(Result, Inst, 0);
899 addOps(Result, Inst, 1);
900 break; // 2 1,2 SUBInst memb($Rs + #$u4_0)=#1
901 }
Krzysztof Parzyszek9315c0d2018-03-20 19:23:18 +0000902 break;
Colin LeMahieube8c4532015-06-05 16:00:11 +0000903 case Hexagon::S2_storerb_io:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000904 Result.setOpcode(Hexagon::SS1_storeb_io);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000905 addOps(Result, Inst, 0);
906 addOps(Result, Inst, 1);
907 addOps(Result, Inst, 2);
908 break; // 1,2,3 SUBInst memb($Rs + #$u4_0) = $Rt
909 case Hexagon::S2_storerd_io:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000910 Result.setOpcode(Hexagon::SS2_stored_sp);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000911 addOps(Result, Inst, 1);
912 addOps(Result, Inst, 2);
913 break; // 2,3 SUBInst memd(r29 + #$s6_3) = $Rtt
914 case Hexagon::S2_storerh_io:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000915 Result.setOpcode(Hexagon::SS2_storeh_io);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000916 addOps(Result, Inst, 0);
917 addOps(Result, Inst, 1);
918 addOps(Result, Inst, 2);
919 break; // 1,2,3 SUBInst memb($Rs + #$u4_0) = $Rt
920 case Hexagon::S4_storeiri_io:
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000921 Absolute = Inst.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
922 assert(Absolute);(void)Absolute;
923 if (Value == 0) {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000924 Result.setOpcode(Hexagon::SS2_storewi0);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000925 addOps(Result, Inst, 0);
926 addOps(Result, Inst, 1);
927 break; // 3 1,2 SUBInst memw($Rs + #$u4_2)=#0
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000928 } else if (Value == 1) {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000929 Result.setOpcode(Hexagon::SS2_storewi1);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000930 addOps(Result, Inst, 0);
931 addOps(Result, Inst, 1);
932 break; // 3 1,2 SUBInst memw($Rs + #$u4_2)=#1
933 } else if (Inst.getOperand(0).getReg() == Hexagon::R29) {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000934 Result.setOpcode(Hexagon::SS2_storew_sp);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000935 addOps(Result, Inst, 1);
936 addOps(Result, Inst, 2);
937 break; // 1 2,3 SUBInst memw(r29 + #$u5_2) = $Rt
938 }
Krzysztof Parzyszek9315c0d2018-03-20 19:23:18 +0000939 break;
Colin LeMahieube8c4532015-06-05 16:00:11 +0000940 case Hexagon::S2_storeri_io:
941 if (Inst.getOperand(0).getReg() == Hexagon::R29) {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000942 Result.setOpcode(Hexagon::SS2_storew_sp);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000943 addOps(Result, Inst, 1);
944 addOps(Result, Inst, 2); // 1,2,3 SUBInst memw(sp + #$u5_2) = $Rt
945 } else {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000946 Result.setOpcode(Hexagon::SS1_storew_io);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000947 addOps(Result, Inst, 0);
948 addOps(Result, Inst, 1);
949 addOps(Result, Inst, 2); // 1,2,3 SUBInst memw($Rs + #$u4_2) = $Rt
950 }
951 break;
952 case Hexagon::A2_sxtb:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000953 Result.setOpcode(Hexagon::SA1_sxtb);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000954 addOps(Result, Inst, 0);
955 addOps(Result, Inst, 1);
956 break; // 1,2 SUBInst $Rd = sxtb($Rs)
957 case Hexagon::A2_sxth:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000958 Result.setOpcode(Hexagon::SA1_sxth);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000959 addOps(Result, Inst, 0);
960 addOps(Result, Inst, 1);
961 break; // 1,2 SUBInst $Rd = sxth($Rs)
962 case Hexagon::A2_tfr:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000963 Result.setOpcode(Hexagon::SA1_tfr);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000964 addOps(Result, Inst, 0);
965 addOps(Result, Inst, 1);
966 break; // 1,2 SUBInst $Rd = $Rs
967 case Hexagon::C2_cmovenewif:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000968 Result.setOpcode(Hexagon::SA1_clrfnew);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000969 addOps(Result, Inst, 0);
Krzysztof Parzyszek0b867222016-08-19 15:17:19 +0000970 addOps(Result, Inst, 1);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000971 break; // 2 SUBInst if (!p0.new) $Rd = #0
972 case Hexagon::C2_cmovenewit:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000973 Result.setOpcode(Hexagon::SA1_clrtnew);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000974 addOps(Result, Inst, 0);
Krzysztof Parzyszek0b867222016-08-19 15:17:19 +0000975 addOps(Result, Inst, 1);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000976 break; // 2 SUBInst if (p0.new) $Rd = #0
977 case Hexagon::C2_cmoveif:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000978 Result.setOpcode(Hexagon::SA1_clrf);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000979 addOps(Result, Inst, 0);
Krzysztof Parzyszek0b867222016-08-19 15:17:19 +0000980 addOps(Result, Inst, 1);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000981 break; // 2 SUBInst if (!p0) $Rd = #0
982 case Hexagon::C2_cmoveit:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000983 Result.setOpcode(Hexagon::SA1_clrt);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000984 addOps(Result, Inst, 0);
Krzysztof Parzyszek0b867222016-08-19 15:17:19 +0000985 addOps(Result, Inst, 1);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000986 break; // 2 SUBInst if (p0) $Rd = #0
987 case Hexagon::A2_tfrsi:
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000988 Absolute = Inst.getOperand(1).getExpr()->evaluateAsAbsolute(Value);
989 if (Absolute && Value == -1) {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000990 Result.setOpcode(Hexagon::SA1_setin1);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000991 addOps(Result, Inst, 0);
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000992 addOps(Result, Inst, 1);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000993 break; // 2 1 SUBInst $Rd = #-1
994 } else {
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +0000995 Result.setOpcode(Hexagon::SA1_seti);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000996 addOps(Result, Inst, 0);
997 addOps(Result, Inst, 1);
998 break; // 1,2 SUBInst $Rd = #$u6
999 }
1000 case Hexagon::A2_zxtb:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +00001001 Result.setOpcode(Hexagon::SA1_zxtb);
Colin LeMahieube8c4532015-06-05 16:00:11 +00001002 addOps(Result, Inst, 0);
1003 addOps(Result, Inst, 1);
1004 break; // 1,2 $Rd = and($Rs, #255)
1005
1006 case Hexagon::A2_zxth:
Colin LeMahieu8ed1aee2016-10-07 00:15:07 +00001007 Result.setOpcode(Hexagon::SA1_zxth);
Colin LeMahieube8c4532015-06-05 16:00:11 +00001008 addOps(Result, Inst, 0);
1009 addOps(Result, Inst, 1);
1010 break; // 1,2 SUBInst $Rd = zxth($Rs)
1011 }
1012 return Result;
1013}
1014
1015static bool isStoreInst(unsigned opCode) {
1016 switch (opCode) {
1017 case Hexagon::S2_storeri_io:
1018 case Hexagon::S2_storerb_io:
1019 case Hexagon::S2_storerh_io:
1020 case Hexagon::S2_storerd_io:
1021 case Hexagon::S4_storeiri_io:
1022 case Hexagon::S4_storeirb_io:
1023 case Hexagon::S2_allocframe:
1024 return true;
1025 default:
1026 return false;
1027 }
1028}
1029
1030SmallVector<DuplexCandidate, 8>
1031HexagonMCInstrInfo::getDuplexPossibilties(MCInstrInfo const &MCII,
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +00001032 MCSubtargetInfo const &STI,
Colin LeMahieube8c4532015-06-05 16:00:11 +00001033 MCInst const &MCB) {
1034 assert(isBundle(MCB));
1035 SmallVector<DuplexCandidate, 8> duplexToTry;
1036 // Use an "order matters" version of isDuplexPair.
1037 unsigned numInstrInPacket = MCB.getNumOperands();
1038
1039 for (unsigned distance = 1; distance < numInstrInPacket; ++distance) {
1040 for (unsigned j = HexagonMCInstrInfo::bundleInstructionsOffset,
1041 k = j + distance;
1042 (j < numInstrInPacket) && (k < numInstrInPacket); ++j, ++k) {
1043
Simon Pilgrim6ba672e2016-11-17 19:21:20 +00001044 // Check if reversible.
Colin LeMahieube8c4532015-06-05 16:00:11 +00001045 bool bisReversable = true;
1046 if (isStoreInst(MCB.getOperand(j).getInst()->getOpcode()) &&
1047 isStoreInst(MCB.getOperand(k).getInst()->getOpcode())) {
1048 DEBUG(dbgs() << "skip out of order write pair: " << k << "," << j
1049 << "\n");
1050 bisReversable = false;
1051 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001052 if (HexagonMCInstrInfo::isMemReorderDisabled(MCB)) // }:mem_noshuf
1053 bisReversable = false;
Colin LeMahieube8c4532015-06-05 16:00:11 +00001054
1055 // Try in order.
1056 if (isOrderedDuplexPair(
1057 MCII, *MCB.getOperand(k).getInst(),
1058 HexagonMCInstrInfo::hasExtenderForIndex(MCB, k - 1),
1059 *MCB.getOperand(j).getInst(),
1060 HexagonMCInstrInfo::hasExtenderForIndex(MCB, j - 1),
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +00001061 bisReversable, STI)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +00001062 // Get iClass.
1063 unsigned iClass = iClassOfDuplexPair(
1064 getDuplexCandidateGroup(*MCB.getOperand(k).getInst()),
1065 getDuplexCandidateGroup(*MCB.getOperand(j).getInst()));
1066
1067 // Save off pairs for duplex checking.
1068 duplexToTry.push_back(DuplexCandidate(j, k, iClass));
1069 DEBUG(dbgs() << "adding pair: " << j << "," << k << ":"
1070 << MCB.getOperand(j).getInst()->getOpcode() << ","
1071 << MCB.getOperand(k).getInst()->getOpcode() << "\n");
1072 continue;
1073 } else {
1074 DEBUG(dbgs() << "skipping pair: " << j << "," << k << ":"
1075 << MCB.getOperand(j).getInst()->getOpcode() << ","
1076 << MCB.getOperand(k).getInst()->getOpcode() << "\n");
1077 }
1078
1079 // Try reverse.
1080 if (bisReversable) {
1081 if (isOrderedDuplexPair(
1082 MCII, *MCB.getOperand(j).getInst(),
1083 HexagonMCInstrInfo::hasExtenderForIndex(MCB, j - 1),
1084 *MCB.getOperand(k).getInst(),
1085 HexagonMCInstrInfo::hasExtenderForIndex(MCB, k - 1),
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +00001086 bisReversable, STI)) {
Colin LeMahieube8c4532015-06-05 16:00:11 +00001087 // Get iClass.
1088 unsigned iClass = iClassOfDuplexPair(
1089 getDuplexCandidateGroup(*MCB.getOperand(j).getInst()),
1090 getDuplexCandidateGroup(*MCB.getOperand(k).getInst()));
1091
1092 // Save off pairs for duplex checking.
1093 duplexToTry.push_back(DuplexCandidate(k, j, iClass));
1094 DEBUG(dbgs() << "adding pair:" << k << "," << j << ":"
1095 << MCB.getOperand(j).getInst()->getOpcode() << ","
1096 << MCB.getOperand(k).getInst()->getOpcode() << "\n");
1097 } else {
1098 DEBUG(dbgs() << "skipping pair: " << k << "," << j << ":"
1099 << MCB.getOperand(j).getInst()->getOpcode() << ","
1100 << MCB.getOperand(k).getInst()->getOpcode() << "\n");
1101 }
1102 }
1103 }
1104 }
1105 return duplexToTry;
1106}