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