/src/llvm-project/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- HexagonMCInstrInfo.cpp - Hexagon sub-class of MCInst ---------------===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | // |
9 | | // This class extends MCInstrInfo to allow Hexagon specific MCInstr queries |
10 | | // |
11 | | //===----------------------------------------------------------------------===// |
12 | | |
13 | | #include "MCTargetDesc/HexagonMCInstrInfo.h" |
14 | | #include "MCTargetDesc/HexagonBaseInfo.h" |
15 | | #include "MCTargetDesc/HexagonMCChecker.h" |
16 | | #include "MCTargetDesc/HexagonMCExpr.h" |
17 | | #include "MCTargetDesc/HexagonMCShuffler.h" |
18 | | #include "MCTargetDesc/HexagonMCTargetDesc.h" |
19 | | #include "llvm/ADT/SmallVector.h" |
20 | | #include "llvm/ADT/StringSwitch.h" |
21 | | #include "llvm/MC/MCContext.h" |
22 | | #include "llvm/MC/MCExpr.h" |
23 | | #include "llvm/MC/MCInst.h" |
24 | | #include "llvm/MC/MCInstrInfo.h" |
25 | | #include "llvm/MC/MCInstrItineraries.h" |
26 | | #include "llvm/MC/MCSubtargetInfo.h" |
27 | | #include "llvm/Support/Casting.h" |
28 | | #include "llvm/Support/ErrorHandling.h" |
29 | | #include <cassert> |
30 | | #include <cstdint> |
31 | | #include <limits> |
32 | | |
33 | | using namespace llvm; |
34 | | |
35 | 0 | bool HexagonMCInstrInfo::PredicateInfo::isPredicated() const { |
36 | 0 | return Register != Hexagon::NoRegister; |
37 | 0 | } |
38 | | |
39 | | Hexagon::PacketIterator::PacketIterator(MCInstrInfo const &MCII, |
40 | | MCInst const &Inst) |
41 | | : MCII(MCII), BundleCurrent(Inst.begin() + |
42 | | HexagonMCInstrInfo::bundleInstructionsOffset), |
43 | 0 | BundleEnd(Inst.end()), DuplexCurrent(Inst.end()), DuplexEnd(Inst.end()) {} |
44 | | |
45 | | Hexagon::PacketIterator::PacketIterator(MCInstrInfo const &MCII, |
46 | | MCInst const &Inst, std::nullptr_t) |
47 | | : MCII(MCII), BundleCurrent(Inst.end()), BundleEnd(Inst.end()), |
48 | 0 | DuplexCurrent(Inst.end()), DuplexEnd(Inst.end()) {} |
49 | | |
50 | 0 | Hexagon::PacketIterator &Hexagon::PacketIterator::operator++() { |
51 | 0 | if (DuplexCurrent != DuplexEnd) { |
52 | 0 | ++DuplexCurrent; |
53 | 0 | if (DuplexCurrent == DuplexEnd) { |
54 | 0 | DuplexCurrent = BundleEnd; |
55 | 0 | DuplexEnd = BundleEnd; |
56 | 0 | ++BundleCurrent; |
57 | 0 | } |
58 | 0 | return *this; |
59 | 0 | } |
60 | 0 | ++BundleCurrent; |
61 | 0 | if (BundleCurrent != BundleEnd) { |
62 | 0 | MCInst const &Inst = *BundleCurrent->getInst(); |
63 | 0 | if (HexagonMCInstrInfo::isDuplex(MCII, Inst)) { |
64 | 0 | DuplexCurrent = Inst.begin(); |
65 | 0 | DuplexEnd = Inst.end(); |
66 | 0 | } |
67 | 0 | } |
68 | 0 | return *this; |
69 | 0 | } |
70 | | |
71 | 0 | MCInst const &Hexagon::PacketIterator::operator*() const { |
72 | 0 | if (DuplexCurrent != DuplexEnd) |
73 | 0 | return *DuplexCurrent->getInst(); |
74 | 0 | return *BundleCurrent->getInst(); |
75 | 0 | } |
76 | | |
77 | 0 | bool Hexagon::PacketIterator::operator==(PacketIterator const &Other) const { |
78 | 0 | return BundleCurrent == Other.BundleCurrent && BundleEnd == Other.BundleEnd && |
79 | 0 | DuplexCurrent == Other.DuplexCurrent && DuplexEnd == Other.DuplexEnd; |
80 | 0 | } |
81 | | |
82 | | void HexagonMCInstrInfo::addConstant(MCInst &MI, uint64_t Value, |
83 | 0 | MCContext &Context) { |
84 | 0 | MI.addOperand(MCOperand::createExpr(MCConstantExpr::create(Value, Context))); |
85 | 0 | } |
86 | | |
87 | | void HexagonMCInstrInfo::addConstExtender(MCContext &Context, |
88 | | MCInstrInfo const &MCII, MCInst &MCB, |
89 | 12.9k | MCInst const &MCI) { |
90 | 12.9k | assert(HexagonMCInstrInfo::isBundle(MCB)); |
91 | 0 | MCOperand const &exOp = |
92 | 12.9k | MCI.getOperand(HexagonMCInstrInfo::getExtendableOp(MCII, MCI)); |
93 | | |
94 | | // Create the extender. |
95 | 12.9k | MCInst *XMCI = |
96 | 12.9k | new (Context) MCInst(HexagonMCInstrInfo::deriveExtender(MCII, MCI, exOp)); |
97 | 12.9k | XMCI->setLoc(MCI.getLoc()); |
98 | | |
99 | 12.9k | MCB.addOperand(MCOperand::createInst(XMCI)); |
100 | 12.9k | } |
101 | | |
102 | | iterator_range<Hexagon::PacketIterator> |
103 | | HexagonMCInstrInfo::bundleInstructions(MCInstrInfo const &MCII, |
104 | 0 | MCInst const &MCI) { |
105 | 0 | assert(isBundle(MCI)); |
106 | 0 | return make_range(Hexagon::PacketIterator(MCII, MCI), |
107 | 0 | Hexagon::PacketIterator(MCII, MCI, nullptr)); |
108 | 0 | } |
109 | | |
110 | | iterator_range<MCInst::const_iterator> |
111 | 736k | HexagonMCInstrInfo::bundleInstructions(MCInst const &MCI) { |
112 | 736k | assert(isBundle(MCI)); |
113 | 0 | return drop_begin(MCI, bundleInstructionsOffset); |
114 | 736k | } |
115 | | |
116 | 4.23M | size_t HexagonMCInstrInfo::bundleSize(MCInst const &MCI) { |
117 | 4.23M | if (HexagonMCInstrInfo::isBundle(MCI)) |
118 | 4.23M | return (MCI.size() - bundleInstructionsOffset); |
119 | 0 | else |
120 | 0 | return (1); |
121 | 4.23M | } |
122 | | |
123 | | namespace { |
124 | | bool canonicalizePacketImpl(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, |
125 | | MCContext &Context, MCInst &MCB, |
126 | 229k | HexagonMCChecker *Check) { |
127 | | // Check the bundle for errors. |
128 | 229k | bool CheckOk = Check ? Check->check(false) : true; |
129 | 229k | if (!CheckOk) |
130 | 0 | return false; |
131 | | |
132 | 229k | MCInst OrigMCB = MCB; |
133 | | |
134 | | // Examine the packet and convert pairs of instructions to compound |
135 | | // instructions when possible. |
136 | 229k | if (!HexagonDisableCompound) |
137 | 229k | HexagonMCInstrInfo::tryCompound(MCII, STI, Context, MCB); |
138 | 229k | HexagonMCShuffle(Context, false, MCII, STI, MCB); |
139 | | |
140 | 229k | const SmallVector<DuplexCandidate, 8> possibleDuplexes = |
141 | 229k | (STI.hasFeature(Hexagon::FeatureDuplex)) |
142 | 229k | ? HexagonMCInstrInfo::getDuplexPossibilties(MCII, STI, MCB) |
143 | 229k | : SmallVector<DuplexCandidate, 8>(); |
144 | | |
145 | | // Examine the packet and convert pairs of instructions to duplex |
146 | | // instructions when possible. |
147 | 229k | HexagonMCShuffle(Context, MCII, STI, MCB, possibleDuplexes); |
148 | | |
149 | | // Examines packet and pad the packet, if needed, when an |
150 | | // end-loop is in the bundle. |
151 | 229k | HexagonMCInstrInfo::padEndloop(MCB, Context); |
152 | | |
153 | | // If compounding and duplexing didn't reduce the size below |
154 | | // 4 or less we have a packet that is too big. |
155 | 229k | if (HexagonMCInstrInfo::bundleSize(MCB) > HEXAGON_PACKET_SIZE) { |
156 | 0 | if (Check) |
157 | 0 | Check->reportError("invalid instruction packet: out of slots"); |
158 | 0 | return false; |
159 | 0 | } |
160 | | // Check the bundle for errors. |
161 | 229k | CheckOk = Check ? Check->check(true) : true; |
162 | 229k | if (!CheckOk) |
163 | 0 | return false; |
164 | | |
165 | 229k | HexagonMCShuffle(Context, true, MCII, STI, MCB); |
166 | | |
167 | 229k | return true; |
168 | 229k | } |
169 | | } // namespace |
170 | | |
171 | | bool HexagonMCInstrInfo::canonicalizePacket(MCInstrInfo const &MCII, |
172 | | MCSubtargetInfo const &STI, |
173 | | MCContext &Context, MCInst &MCB, |
174 | | HexagonMCChecker *Check, |
175 | 229k | bool AttemptCompatibility) { |
176 | 229k | auto ArchSTI = Hexagon_MC::getArchSubtarget(&STI); |
177 | 229k | if (!AttemptCompatibility || ArchSTI == nullptr) |
178 | 229k | return canonicalizePacketImpl(MCII, STI, Context, MCB, Check); |
179 | | |
180 | 0 | const MCRegisterInfo *RI = Context.getRegisterInfo(); |
181 | 0 | HexagonMCChecker DefaultCheck(Context, MCII, STI, MCB, *RI, false); |
182 | 0 | HexagonMCChecker *BaseCheck = (Check == nullptr) ? &DefaultCheck : Check; |
183 | 0 | HexagonMCChecker PerfCheck(*BaseCheck, STI, false); |
184 | 0 | if (canonicalizePacketImpl(MCII, STI, Context, MCB, &PerfCheck)) |
185 | 0 | return true; |
186 | | |
187 | 0 | HexagonMCChecker ArchCheck(*BaseCheck, *ArchSTI, true); |
188 | 0 | return canonicalizePacketImpl(MCII, *ArchSTI, Context, MCB, &ArchCheck); |
189 | 0 | } |
190 | | |
191 | | MCInst HexagonMCInstrInfo::deriveExtender(MCInstrInfo const &MCII, |
192 | | MCInst const &Inst, |
193 | 12.9k | MCOperand const &MO) { |
194 | 12.9k | assert(HexagonMCInstrInfo::isExtendable(MCII, Inst) || |
195 | 12.9k | HexagonMCInstrInfo::isExtended(MCII, Inst)); |
196 | | |
197 | 0 | MCInst XMI; |
198 | 12.9k | XMI.setOpcode(Hexagon::A4_ext); |
199 | 12.9k | if (MO.isImm()) |
200 | 0 | XMI.addOperand(MCOperand::createImm(MO.getImm() & (~0x3f))); |
201 | 12.9k | else if (MO.isExpr()) |
202 | 12.9k | XMI.addOperand(MCOperand::createExpr(MO.getExpr())); |
203 | 0 | else |
204 | 0 | llvm_unreachable("invalid extendable operand"); |
205 | 12.9k | return XMI; |
206 | 12.9k | } |
207 | | |
208 | | MCInst *HexagonMCInstrInfo::deriveDuplex(MCContext &Context, unsigned iClass, |
209 | | MCInst const &inst0, |
210 | 37.8k | MCInst const &inst1) { |
211 | 37.8k | assert((iClass <= 0xf) && "iClass must have range of 0 to 0xf"); |
212 | 0 | MCInst *duplexInst = new (Context) MCInst; |
213 | 37.8k | duplexInst->setOpcode(Hexagon::DuplexIClass0 + iClass); |
214 | | |
215 | 37.8k | MCInst *SubInst0 = new (Context) MCInst(deriveSubInst(inst0)); |
216 | 37.8k | MCInst *SubInst1 = new (Context) MCInst(deriveSubInst(inst1)); |
217 | 37.8k | duplexInst->addOperand(MCOperand::createInst(SubInst0)); |
218 | 37.8k | duplexInst->addOperand(MCOperand::createInst(SubInst1)); |
219 | 37.8k | return duplexInst; |
220 | 37.8k | } |
221 | | |
222 | | MCInst const *HexagonMCInstrInfo::extenderForIndex(MCInst const &MCB, |
223 | 3.05M | size_t Index) { |
224 | 3.05M | assert(Index <= bundleSize(MCB)); |
225 | 3.05M | if (Index == 0) |
226 | 891k | return nullptr; |
227 | 2.16M | MCInst const *Inst = |
228 | 2.16M | MCB.getOperand(Index + bundleInstructionsOffset - 1).getInst(); |
229 | 2.16M | if (isImmext(*Inst)) |
230 | 72.3k | return Inst; |
231 | 2.09M | return nullptr; |
232 | 2.16M | } |
233 | | |
234 | | void HexagonMCInstrInfo::extendIfNeeded(MCContext &Context, |
235 | | MCInstrInfo const &MCII, MCInst &MCB, |
236 | 671k | MCInst const &MCI) { |
237 | 671k | if (isConstExtended(MCII, MCI)) |
238 | 12.9k | addConstExtender(Context, MCII, MCB, MCI); |
239 | 671k | } |
240 | | |
241 | | unsigned HexagonMCInstrInfo::getMemAccessSize(MCInstrInfo const &MCII, |
242 | 0 | MCInst const &MCI) { |
243 | 0 | uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
244 | 0 | unsigned S = (F >> HexagonII::MemAccessSizePos) & HexagonII::MemAccesSizeMask; |
245 | 0 | return HexagonII::getMemAccessSizeInBytes(HexagonII::MemAccessSize(S)); |
246 | 0 | } |
247 | | |
248 | | unsigned HexagonMCInstrInfo::getAddrMode(MCInstrInfo const &MCII, |
249 | 0 | MCInst const &MCI) { |
250 | 0 | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
251 | 0 | return static_cast<unsigned>((F >> HexagonII::AddrModePos) & |
252 | 0 | HexagonII::AddrModeMask); |
253 | 0 | } |
254 | | |
255 | | MCInstrDesc const &HexagonMCInstrInfo::getDesc(MCInstrInfo const &MCII, |
256 | 24.6M | MCInst const &MCI) { |
257 | 24.6M | return MCII.get(MCI.getOpcode()); |
258 | 24.6M | } |
259 | | |
260 | 0 | unsigned HexagonMCInstrInfo::getDuplexRegisterNumbering(unsigned Reg) { |
261 | 0 | using namespace Hexagon; |
262 | |
|
263 | 0 | switch (Reg) { |
264 | 0 | default: |
265 | 0 | llvm_unreachable("unknown duplex register"); |
266 | | // Rs Rss |
267 | 0 | case R0: |
268 | 0 | case D0: |
269 | 0 | return 0; |
270 | 0 | case R1: |
271 | 0 | case D1: |
272 | 0 | return 1; |
273 | 0 | case R2: |
274 | 0 | case D2: |
275 | 0 | return 2; |
276 | 0 | case R3: |
277 | 0 | case D3: |
278 | 0 | return 3; |
279 | 0 | case R4: |
280 | 0 | case D8: |
281 | 0 | return 4; |
282 | 0 | case R5: |
283 | 0 | case D9: |
284 | 0 | return 5; |
285 | 0 | case R6: |
286 | 0 | case D10: |
287 | 0 | return 6; |
288 | 0 | case R7: |
289 | 0 | case D11: |
290 | 0 | return 7; |
291 | 0 | case R16: |
292 | 0 | return 8; |
293 | 0 | case R17: |
294 | 0 | return 9; |
295 | 0 | case R18: |
296 | 0 | return 10; |
297 | 0 | case R19: |
298 | 0 | return 11; |
299 | 0 | case R20: |
300 | 0 | return 12; |
301 | 0 | case R21: |
302 | 0 | return 13; |
303 | 0 | case R22: |
304 | 0 | return 14; |
305 | 0 | case R23: |
306 | 0 | return 15; |
307 | 0 | } |
308 | 0 | } |
309 | | |
310 | 0 | MCExpr const &HexagonMCInstrInfo::getExpr(MCExpr const &Expr) { |
311 | 0 | const auto &HExpr = cast<HexagonMCExpr>(Expr); |
312 | 0 | assert(HExpr.getExpr()); |
313 | 0 | return *HExpr.getExpr(); |
314 | 0 | } |
315 | | |
316 | | unsigned short HexagonMCInstrInfo::getExtendableOp(MCInstrInfo const &MCII, |
317 | 349k | MCInst const &MCI) { |
318 | 349k | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
319 | 349k | return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask); |
320 | 349k | } |
321 | | |
322 | | MCOperand const & |
323 | | HexagonMCInstrInfo::getExtendableOperand(MCInstrInfo const &MCII, |
324 | 336k | MCInst const &MCI) { |
325 | 336k | unsigned O = HexagonMCInstrInfo::getExtendableOp(MCII, MCI); |
326 | 336k | MCOperand const &MO = MCI.getOperand(O); |
327 | | |
328 | 336k | assert((HexagonMCInstrInfo::isExtendable(MCII, MCI) || |
329 | 336k | HexagonMCInstrInfo::isExtended(MCII, MCI)) && |
330 | 336k | (MO.isImm() || MO.isExpr())); |
331 | 0 | return (MO); |
332 | 336k | } |
333 | | |
334 | | unsigned HexagonMCInstrInfo::getExtentAlignment(MCInstrInfo const &MCII, |
335 | 0 | MCInst const &MCI) { |
336 | 0 | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
337 | 0 | return ((F >> HexagonII::ExtentAlignPos) & HexagonII::ExtentAlignMask); |
338 | 0 | } |
339 | | |
340 | | unsigned HexagonMCInstrInfo::getExtentBits(MCInstrInfo const &MCII, |
341 | 629k | MCInst const &MCI) { |
342 | 629k | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
343 | 629k | return ((F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask); |
344 | 629k | } |
345 | | |
346 | | bool HexagonMCInstrInfo::isExtentSigned(MCInstrInfo const &MCII, |
347 | 950k | MCInst const &MCI) { |
348 | 950k | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
349 | 950k | return (F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask; |
350 | 950k | } |
351 | | |
352 | | /// Return the maximum value of an extendable operand. |
353 | | int HexagonMCInstrInfo::getMaxValue(MCInstrInfo const &MCII, |
354 | 316k | MCInst const &MCI) { |
355 | 316k | assert(HexagonMCInstrInfo::isExtendable(MCII, MCI) || |
356 | 316k | HexagonMCInstrInfo::isExtended(MCII, MCI)); |
357 | | |
358 | 316k | if (HexagonMCInstrInfo::isExtentSigned(MCII, MCI)) // if value is signed |
359 | 312k | return (1 << (HexagonMCInstrInfo::getExtentBits(MCII, MCI) - 1)) - 1; |
360 | 4.66k | return (1 << HexagonMCInstrInfo::getExtentBits(MCII, MCI)) - 1; |
361 | 316k | } |
362 | | |
363 | | /// Return the minimum value of an extendable operand. |
364 | | int HexagonMCInstrInfo::getMinValue(MCInstrInfo const &MCII, |
365 | 316k | MCInst const &MCI) { |
366 | 316k | assert(HexagonMCInstrInfo::isExtendable(MCII, MCI) || |
367 | 316k | HexagonMCInstrInfo::isExtended(MCII, MCI)); |
368 | | |
369 | 316k | if (HexagonMCInstrInfo::isExtentSigned(MCII, MCI)) // if value is signed |
370 | 312k | return -(1 << (HexagonMCInstrInfo::getExtentBits(MCII, MCI) - 1)); |
371 | 4.66k | return 0; |
372 | 316k | } |
373 | | |
374 | | StringRef HexagonMCInstrInfo::getName(MCInstrInfo const &MCII, |
375 | 0 | MCInst const &MCI) { |
376 | 0 | return MCII.getName(MCI.getOpcode()); |
377 | 0 | } |
378 | | |
379 | | unsigned short HexagonMCInstrInfo::getNewValueOp(MCInstrInfo const &MCII, |
380 | 0 | MCInst const &MCI) { |
381 | 0 | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
382 | 0 | return ((F >> HexagonII::NewValueOpPos) & HexagonII::NewValueOpMask); |
383 | 0 | } |
384 | | |
385 | | MCOperand const &HexagonMCInstrInfo::getNewValueOperand(MCInstrInfo const &MCII, |
386 | 0 | MCInst const &MCI) { |
387 | 0 | if (HexagonMCInstrInfo::hasTmpDst(MCII, MCI)) { |
388 | | // VTMP doesn't actually exist in the encodings for these 184 |
389 | | // 3 instructions so go ahead and create it here. |
390 | 0 | static MCOperand MCO = MCOperand::createReg(Hexagon::VTMP); |
391 | 0 | return (MCO); |
392 | 0 | } else { |
393 | 0 | unsigned O = HexagonMCInstrInfo::getNewValueOp(MCII, MCI); |
394 | 0 | MCOperand const &MCO = MCI.getOperand(O); |
395 | |
|
396 | 0 | assert((HexagonMCInstrInfo::isNewValue(MCII, MCI) || |
397 | 0 | HexagonMCInstrInfo::hasNewValue(MCII, MCI)) && |
398 | 0 | MCO.isReg()); |
399 | 0 | return (MCO); |
400 | 0 | } |
401 | 0 | } |
402 | | |
403 | | /// Return the new value or the newly produced value. |
404 | | unsigned short HexagonMCInstrInfo::getNewValueOp2(MCInstrInfo const &MCII, |
405 | 0 | MCInst const &MCI) { |
406 | 0 | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
407 | 0 | return ((F >> HexagonII::NewValueOpPos2) & HexagonII::NewValueOpMask2); |
408 | 0 | } |
409 | | |
410 | | MCOperand const & |
411 | | HexagonMCInstrInfo::getNewValueOperand2(MCInstrInfo const &MCII, |
412 | 0 | MCInst const &MCI) { |
413 | 0 | unsigned O = HexagonMCInstrInfo::getNewValueOp2(MCII, MCI); |
414 | 0 | MCOperand const &MCO = MCI.getOperand(O); |
415 | |
|
416 | 0 | assert((HexagonMCInstrInfo::isNewValue(MCII, MCI) || |
417 | 0 | HexagonMCInstrInfo::hasNewValue2(MCII, MCI)) && |
418 | 0 | MCO.isReg()); |
419 | 0 | return (MCO); |
420 | 0 | } |
421 | | |
422 | | /// Return the Hexagon ISA class for the insn. |
423 | | unsigned HexagonMCInstrInfo::getType(MCInstrInfo const &MCII, |
424 | 4.83M | MCInst const &MCI) { |
425 | 4.83M | const uint64_t F = MCII.get(MCI.getOpcode()).TSFlags; |
426 | 4.83M | return ((F >> HexagonII::TypePos) & HexagonII::TypeMask); |
427 | 4.83M | } |
428 | | |
429 | | /// Return the resources used by this instruction |
430 | | unsigned HexagonMCInstrInfo::getCVIResources(MCInstrInfo const &MCII, |
431 | | MCSubtargetInfo const &STI, |
432 | 2.12M | MCInst const &MCI) { |
433 | | |
434 | 2.12M | const InstrItinerary *II = STI.getSchedModel().InstrItineraries; |
435 | 2.12M | int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass(); |
436 | 2.12M | int Size = II[SchedClass].LastStage - II[SchedClass].FirstStage; |
437 | | |
438 | | // HVX resources used are currenty located at the second to last stage. |
439 | | // This could also be done with a linear search of the stages looking for: |
440 | | // CVI_ALL, CVI_MPY01, CVI_XLSHF, CVI_MPY0, CVI_MPY1, CVI_SHIFT, CVI_XLANE, |
441 | | // CVI_ZW |
442 | 2.12M | unsigned Stage = II[SchedClass].LastStage - 1; |
443 | | |
444 | 2.12M | if (Size < 2) |
445 | 2.12M | return 0; |
446 | 0 | return ((Stage + HexagonStages)->getUnits()); |
447 | 2.12M | } |
448 | | |
449 | | /// Return the slots this instruction can execute out of |
450 | | unsigned HexagonMCInstrInfo::getUnits(MCInstrInfo const &MCII, |
451 | | MCSubtargetInfo const &STI, |
452 | 2.12M | MCInst const &MCI) { |
453 | 2.12M | const InstrItinerary *II = STI.getSchedModel().InstrItineraries; |
454 | 2.12M | int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass(); |
455 | 2.12M | return ((II[SchedClass].FirstStage + HexagonStages)->getUnits()); |
456 | 2.12M | } |
457 | | |
458 | | /// Return the slots this instruction consumes in addition to |
459 | | /// the slot(s) it can execute out of |
460 | | |
461 | | unsigned HexagonMCInstrInfo::getOtherReservedSlots(MCInstrInfo const &MCII, |
462 | | MCSubtargetInfo const &STI, |
463 | 2.12M | MCInst const &MCI) { |
464 | 2.12M | const InstrItinerary *II = STI.getSchedModel().InstrItineraries; |
465 | 2.12M | int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass(); |
466 | 2.12M | unsigned Slots = 0; |
467 | | |
468 | | // FirstStage are slots that this instruction can execute in. |
469 | | // FirstStage+1 are slots that are also consumed by this instruction. |
470 | | // For example: vmemu can only execute in slot 0 but also consumes slot 1. |
471 | 2.12M | for (unsigned Stage = II[SchedClass].FirstStage + 1; |
472 | 2.12M | Stage < II[SchedClass].LastStage; ++Stage) { |
473 | 0 | unsigned Units = (Stage + HexagonStages)->getUnits(); |
474 | 0 | if (Units > HexagonGetLastSlot()) |
475 | 0 | break; |
476 | | // fyi: getUnits() will return 0x1, 0x2, 0x4 or 0x8 |
477 | 0 | Slots |= Units; |
478 | 0 | } |
479 | | |
480 | | // if 0 is returned, then no additional slots are consumed by this inst. |
481 | 2.12M | return Slots; |
482 | 2.12M | } |
483 | | |
484 | 0 | bool HexagonMCInstrInfo::hasDuplex(MCInstrInfo const &MCII, MCInst const &MCI) { |
485 | 0 | if (!HexagonMCInstrInfo::isBundle(MCI)) |
486 | 0 | return false; |
487 | | |
488 | 0 | for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCI)) { |
489 | 0 | if (HexagonMCInstrInfo::isDuplex(MCII, *I.getInst())) |
490 | 0 | return true; |
491 | 0 | } |
492 | | |
493 | 0 | return false; |
494 | 0 | } |
495 | | |
496 | 3.05M | bool HexagonMCInstrInfo::hasExtenderForIndex(MCInst const &MCB, size_t Index) { |
497 | 3.05M | return extenderForIndex(MCB, Index) != nullptr; |
498 | 3.05M | } |
499 | | |
500 | 0 | bool HexagonMCInstrInfo::hasImmExt(MCInst const &MCI) { |
501 | 0 | if (!HexagonMCInstrInfo::isBundle(MCI)) |
502 | 0 | return false; |
503 | | |
504 | 0 | for (const auto &I : HexagonMCInstrInfo::bundleInstructions(MCI)) { |
505 | 0 | if (isImmext(*I.getInst())) |
506 | 0 | return true; |
507 | 0 | } |
508 | | |
509 | 0 | return false; |
510 | 0 | } |
511 | | |
512 | | /// Return whether the insn produces a value. |
513 | | bool HexagonMCInstrInfo::hasNewValue(MCInstrInfo const &MCII, |
514 | 0 | MCInst const &MCI) { |
515 | 0 | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
516 | 0 | return ((F >> HexagonII::hasNewValuePos) & HexagonII::hasNewValueMask); |
517 | 0 | } |
518 | | |
519 | | /// Return whether the insn produces a second value. |
520 | | bool HexagonMCInstrInfo::hasNewValue2(MCInstrInfo const &MCII, |
521 | 0 | MCInst const &MCI) { |
522 | 0 | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
523 | 0 | return ((F >> HexagonII::hasNewValuePos2) & HexagonII::hasNewValueMask2); |
524 | 0 | } |
525 | | |
526 | 0 | MCInst const &HexagonMCInstrInfo::instruction(MCInst const &MCB, size_t Index) { |
527 | 0 | assert(isBundle(MCB)); |
528 | 0 | assert(Index < HEXAGON_PRESHUFFLE_PACKET_SIZE); |
529 | 0 | return *MCB.getOperand(bundleInstructionsOffset + Index).getInst(); |
530 | 0 | } |
531 | | |
532 | | /// Return where the instruction is an accumulator. |
533 | | bool HexagonMCInstrInfo::isAccumulator(MCInstrInfo const &MCII, |
534 | 0 | MCInst const &MCI) { |
535 | 0 | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
536 | 0 | return ((F >> HexagonII::AccumulatorPos) & HexagonII::AccumulatorMask); |
537 | 0 | } |
538 | | |
539 | 8.69M | bool HexagonMCInstrInfo::isBundle(MCInst const &MCI) { |
540 | 8.69M | auto Result = Hexagon::BUNDLE == MCI.getOpcode(); |
541 | 8.69M | assert(!Result || (MCI.size() > 0 && MCI.getOperand(0).isImm())); |
542 | 0 | return Result; |
543 | 8.69M | } |
544 | | |
545 | | bool HexagonMCInstrInfo::isConstExtended(MCInstrInfo const &MCII, |
546 | 671k | MCInst const &MCI) { |
547 | 671k | if (HexagonMCInstrInfo::isExtended(MCII, MCI)) |
548 | 21 | return true; |
549 | 671k | if (!HexagonMCInstrInfo::isExtendable(MCII, MCI)) |
550 | 334k | return false; |
551 | 336k | MCOperand const &MO = HexagonMCInstrInfo::getExtendableOperand(MCII, MCI); |
552 | 336k | if (isa<HexagonMCExpr>(MO.getExpr()) && |
553 | 336k | HexagonMCInstrInfo::mustExtend(*MO.getExpr())) |
554 | 0 | return true; |
555 | | // Branch insns are handled as necessary by relaxation. |
556 | 336k | if ((HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeJ) || |
557 | 336k | (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCJ && |
558 | 319k | HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch()) || |
559 | 336k | (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeNCJ && |
560 | 319k | HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch())) |
561 | 16.4k | return false; |
562 | | // Otherwise loop instructions and other CR insts are handled by relaxation |
563 | 319k | else if ((HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCR) && |
564 | 319k | (MCI.getOpcode() != Hexagon::C4_addipc)) |
565 | 0 | return false; |
566 | | |
567 | 319k | assert(!MO.isImm()); |
568 | 319k | if (isa<HexagonMCExpr>(MO.getExpr()) && |
569 | 319k | HexagonMCInstrInfo::mustNotExtend(*MO.getExpr())) |
570 | 0 | return false; |
571 | | |
572 | 319k | int64_t Value; |
573 | 319k | if (!MO.getExpr()->evaluateAsAbsolute(Value)) |
574 | 3.04k | return true; |
575 | 316k | if (HexagonMCInstrInfo::isExtentSigned(MCII, MCI)) { |
576 | 312k | int32_t SValue = Value; |
577 | 312k | int32_t MinValue = HexagonMCInstrInfo::getMinValue(MCII, MCI); |
578 | 312k | int32_t MaxValue = HexagonMCInstrInfo::getMaxValue(MCII, MCI); |
579 | 312k | return SValue < MinValue || SValue > MaxValue; |
580 | 312k | } |
581 | 4.66k | uint32_t UValue = Value; |
582 | 4.66k | uint32_t MinValue = HexagonMCInstrInfo::getMinValue(MCII, MCI); |
583 | 4.66k | uint32_t MaxValue = HexagonMCInstrInfo::getMaxValue(MCII, MCI); |
584 | 4.66k | return UValue < MinValue || UValue > MaxValue; |
585 | 316k | } |
586 | | |
587 | 0 | bool HexagonMCInstrInfo::isCanon(MCInstrInfo const &MCII, MCInst const &MCI) { |
588 | 0 | return !HexagonMCInstrInfo::getDesc(MCII, MCI).isPseudo() && |
589 | 0 | !HexagonMCInstrInfo::isPrefix(MCII, MCI); |
590 | 0 | } |
591 | | |
592 | 0 | bool HexagonMCInstrInfo::isCofMax1(MCInstrInfo const &MCII, MCInst const &MCI) { |
593 | 0 | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
594 | 0 | return ((F >> HexagonII::CofMax1Pos) & HexagonII::CofMax1Mask); |
595 | 0 | } |
596 | | |
597 | | bool HexagonMCInstrInfo::isCofRelax1(MCInstrInfo const &MCII, |
598 | 0 | MCInst const &MCI) { |
599 | 0 | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
600 | 0 | return ((F >> HexagonII::CofRelax1Pos) & HexagonII::CofRelax1Mask); |
601 | 0 | } |
602 | | |
603 | | bool HexagonMCInstrInfo::isCofRelax2(MCInstrInfo const &MCII, |
604 | 0 | MCInst const &MCI) { |
605 | 0 | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
606 | 0 | return ((F >> HexagonII::CofRelax2Pos) & HexagonII::CofRelax2Mask); |
607 | 0 | } |
608 | | |
609 | | bool HexagonMCInstrInfo::isCompound(MCInstrInfo const &MCII, |
610 | 0 | MCInst const &MCI) { |
611 | 0 | return (getType(MCII, MCI) == HexagonII::TypeCJ); |
612 | 0 | } |
613 | | |
614 | 0 | bool HexagonMCInstrInfo::isCVINew(MCInstrInfo const &MCII, MCInst const &MCI) { |
615 | 0 | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
616 | 0 | return ((F >> HexagonII::CVINewPos) & HexagonII::CVINewMask); |
617 | 0 | } |
618 | | |
619 | 343k | bool HexagonMCInstrInfo::isDblRegForSubInst(unsigned Reg) { |
620 | 343k | return ((Reg >= Hexagon::D0 && Reg <= Hexagon::D3) || |
621 | 343k | (Reg >= Hexagon::D8 && Reg <= Hexagon::D11)); |
622 | 343k | } |
623 | | |
624 | 0 | bool HexagonMCInstrInfo::isDuplex(MCInstrInfo const &MCII, MCInst const &MCI) { |
625 | 0 | return HexagonII::TypeDUPLEX == HexagonMCInstrInfo::getType(MCII, MCI); |
626 | 0 | } |
627 | | |
628 | | bool HexagonMCInstrInfo::isExtendable(MCInstrInfo const &MCII, |
629 | 1.65M | MCInst const &MCI) { |
630 | 1.65M | uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
631 | 1.65M | return (F >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask; |
632 | 1.65M | } |
633 | | |
634 | | bool HexagonMCInstrInfo::isExtended(MCInstrInfo const &MCII, |
635 | 671k | MCInst const &MCI) { |
636 | 671k | uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
637 | 671k | return (F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask; |
638 | 671k | } |
639 | | |
640 | 0 | bool HexagonMCInstrInfo::isFloat(MCInstrInfo const &MCII, MCInst const &MCI) { |
641 | 0 | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
642 | 0 | return ((F >> HexagonII::FPPos) & HexagonII::FPMask); |
643 | 0 | } |
644 | | |
645 | 0 | bool HexagonMCInstrInfo::isHVX(MCInstrInfo const &MCII, MCInst const &MCI) { |
646 | 0 | const uint64_t V = getType(MCII, MCI); |
647 | 0 | return HexagonII::TypeCVI_FIRST <= V && V <= HexagonII::TypeCVI_LAST; |
648 | 0 | } |
649 | | |
650 | 5.04M | bool HexagonMCInstrInfo::isImmext(MCInst const &MCI) { |
651 | 5.04M | return MCI.getOpcode() == Hexagon::A4_ext; |
652 | 5.04M | } |
653 | | |
654 | 229k | bool HexagonMCInstrInfo::isInnerLoop(MCInst const &MCI) { |
655 | 229k | assert(isBundle(MCI)); |
656 | 0 | int64_t Flags = MCI.getOperand(0).getImm(); |
657 | 229k | return (Flags & innerLoopMask) != 0; |
658 | 229k | } |
659 | | |
660 | 620k | bool HexagonMCInstrInfo::isIntReg(unsigned Reg) { |
661 | 620k | return (Reg >= Hexagon::R0 && Reg <= Hexagon::R31); |
662 | 620k | } |
663 | | |
664 | 1.45M | bool HexagonMCInstrInfo::isIntRegForSubInst(unsigned Reg) { |
665 | 1.45M | return ((Reg >= Hexagon::R0 && Reg <= Hexagon::R7) || |
666 | 1.45M | (Reg >= Hexagon::R16 && Reg <= Hexagon::R23)); |
667 | 1.45M | } |
668 | | |
669 | | /// Return whether the insn expects newly produced value. |
670 | | bool HexagonMCInstrInfo::isNewValue(MCInstrInfo const &MCII, |
671 | 0 | MCInst const &MCI) { |
672 | 0 | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
673 | 0 | return ((F >> HexagonII::NewValuePos) & HexagonII::NewValueMask); |
674 | 0 | } |
675 | | |
676 | | bool HexagonMCInstrInfo::isNewValueStore(MCInstrInfo const &MCII, |
677 | 0 | MCInst const &MCI) { |
678 | 0 | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
679 | 0 | return (F >> HexagonII::NVStorePos) & HexagonII::NVStoreMask; |
680 | 0 | } |
681 | | |
682 | | /// Return whether the operand is extendable. |
683 | | bool HexagonMCInstrInfo::isOpExtendable(MCInstrInfo const &MCII, |
684 | 0 | MCInst const &MCI, unsigned short O) { |
685 | 0 | return (O == HexagonMCInstrInfo::getExtendableOp(MCII, MCI)); |
686 | 0 | } |
687 | | |
688 | 229k | bool HexagonMCInstrInfo::isOuterLoop(MCInst const &MCI) { |
689 | 229k | assert(isBundle(MCI)); |
690 | 0 | int64_t Flags = MCI.getOperand(0).getImm(); |
691 | 229k | return (Flags & outerLoopMask) != 0; |
692 | 229k | } |
693 | | |
694 | 0 | bool HexagonMCInstrInfo::IsVecRegPair(unsigned VecReg) { |
695 | 0 | return (VecReg >= Hexagon::W0 && VecReg <= Hexagon::W15) || |
696 | 0 | (VecReg >= Hexagon::WR0 && VecReg <= Hexagon::WR15); |
697 | 0 | } |
698 | | |
699 | 0 | bool HexagonMCInstrInfo::IsReverseVecRegPair(unsigned VecReg) { |
700 | 0 | return (VecReg >= Hexagon::WR0 && VecReg <= Hexagon::WR15); |
701 | 0 | } |
702 | | |
703 | 0 | bool HexagonMCInstrInfo::IsVecRegSingle(unsigned VecReg) { |
704 | 0 | return (VecReg >= Hexagon::V0 && VecReg <= Hexagon::V31); |
705 | 0 | } |
706 | | |
707 | | std::pair<unsigned, unsigned> |
708 | 0 | HexagonMCInstrInfo::GetVecRegPairIndices(unsigned VecRegPair) { |
709 | 0 | assert(IsVecRegPair(VecRegPair) && |
710 | 0 | "VecRegPair must be a vector register pair"); |
711 | | |
712 | 0 | const bool IsRev = IsReverseVecRegPair(VecRegPair); |
713 | 0 | const unsigned PairIndex = |
714 | 0 | 2 * (IsRev ? VecRegPair - Hexagon::WR0 : VecRegPair - Hexagon::W0); |
715 | |
|
716 | 0 | return IsRev ? std::make_pair(PairIndex, PairIndex + 1) |
717 | 0 | : std::make_pair(PairIndex + 1, PairIndex); |
718 | 0 | } |
719 | | |
720 | | bool HexagonMCInstrInfo::IsSingleConsumerRefPairProducer(unsigned Producer, |
721 | 0 | unsigned Consumer) { |
722 | 0 | if (IsVecRegPair(Producer) && IsVecRegSingle(Consumer)) { |
723 | 0 | const unsigned ProdPairIndex = IsReverseVecRegPair(Producer) |
724 | 0 | ? Producer - Hexagon::WR0 |
725 | 0 | : Producer - Hexagon::W0; |
726 | 0 | const unsigned ConsumerSingleIndex = (Consumer - Hexagon::V0) >> 1; |
727 | |
|
728 | 0 | return ConsumerSingleIndex == ProdPairIndex; |
729 | 0 | } |
730 | 0 | return false; |
731 | 0 | } |
732 | | |
733 | | bool HexagonMCInstrInfo::isPredicated(MCInstrInfo const &MCII, |
734 | 0 | MCInst const &MCI) { |
735 | 0 | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
736 | 0 | return ((F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask); |
737 | 0 | } |
738 | | |
739 | 0 | bool HexagonMCInstrInfo::isPrefix(MCInstrInfo const &MCII, MCInst const &MCI) { |
740 | 0 | return HexagonII::TypeEXTENDER == HexagonMCInstrInfo::getType(MCII, MCI); |
741 | 0 | } |
742 | | |
743 | | bool HexagonMCInstrInfo::isPredicateLate(MCInstrInfo const &MCII, |
744 | 0 | MCInst const &MCI) { |
745 | 0 | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
746 | 0 | return (F >> HexagonII::PredicateLatePos & HexagonII::PredicateLateMask); |
747 | 0 | } |
748 | | |
749 | | /// Return whether the insn is newly predicated. |
750 | | bool HexagonMCInstrInfo::isPredicatedNew(MCInstrInfo const &MCII, |
751 | 0 | MCInst const &MCI) { |
752 | 0 | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
753 | 0 | return ((F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask); |
754 | 0 | } |
755 | | |
756 | | bool HexagonMCInstrInfo::isPredicatedTrue(MCInstrInfo const &MCII, |
757 | 0 | MCInst const &MCI) { |
758 | 0 | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
759 | 0 | return ( |
760 | 0 | !((F >> HexagonII::PredicatedFalsePos) & HexagonII::PredicatedFalseMask)); |
761 | 0 | } |
762 | | |
763 | 0 | bool HexagonMCInstrInfo::isPredReg(MCRegisterInfo const &MRI, unsigned Reg) { |
764 | 0 | auto &PredRegClass = MRI.getRegClass(Hexagon::PredRegsRegClassID); |
765 | 0 | return PredRegClass.contains(Reg); |
766 | 0 | } |
767 | | |
768 | | bool HexagonMCInstrInfo::isPredRegister(MCInstrInfo const &MCII, |
769 | 0 | MCInst const &Inst, unsigned I) { |
770 | 0 | MCInstrDesc const &Desc = HexagonMCInstrInfo::getDesc(MCII, Inst); |
771 | |
|
772 | 0 | return Inst.getOperand(I).isReg() && |
773 | 0 | Desc.operands()[I].RegClass == Hexagon::PredRegsRegClassID; |
774 | 0 | } |
775 | | |
776 | | /// Return whether the insn can be packaged only with A and X-type insns. |
777 | 0 | bool HexagonMCInstrInfo::isSoloAX(MCInstrInfo const &MCII, MCInst const &MCI) { |
778 | 0 | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
779 | 0 | return ((F >> HexagonII::SoloAXPos) & HexagonII::SoloAXMask); |
780 | 0 | } |
781 | | |
782 | | /// Return whether the insn can be packaged only with an A-type insn in slot #1. |
783 | | bool HexagonMCInstrInfo::isRestrictSlot1AOK(MCInstrInfo const &MCII, |
784 | 2.12M | MCInst const &MCI) { |
785 | 2.12M | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
786 | 2.12M | return ((F >> HexagonII::RestrictSlot1AOKPos) & |
787 | 2.12M | HexagonII::RestrictSlot1AOKMask); |
788 | 2.12M | } |
789 | | |
790 | | bool HexagonMCInstrInfo::isRestrictNoSlot1Store(MCInstrInfo const &MCII, |
791 | 2.12M | MCInst const &MCI) { |
792 | 2.12M | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
793 | 2.12M | return ((F >> HexagonII::RestrictNoSlot1StorePos) & |
794 | 2.12M | HexagonII::RestrictNoSlot1StoreMask); |
795 | 2.12M | } |
796 | | |
797 | | /// Return whether the insn is solo, i.e., cannot be in a packet. |
798 | 0 | bool HexagonMCInstrInfo::isSolo(MCInstrInfo const &MCII, MCInst const &MCI) { |
799 | 0 | const uint64_t F = MCII.get(MCI.getOpcode()).TSFlags; |
800 | 0 | return ((F >> HexagonII::SoloPos) & HexagonII::SoloMask); |
801 | 0 | } |
802 | | |
803 | 789k | bool HexagonMCInstrInfo::isMemReorderDisabled(MCInst const &MCI) { |
804 | 789k | assert(isBundle(MCI)); |
805 | 0 | auto Flags = MCI.getOperand(0).getImm(); |
806 | 789k | return (Flags & memReorderDisabledMask) != 0; |
807 | 789k | } |
808 | | |
809 | 0 | bool HexagonMCInstrInfo::isSubInstruction(MCInst const &MCI) { |
810 | 0 | switch (MCI.getOpcode()) { |
811 | 0 | default: |
812 | 0 | return false; |
813 | 0 | case Hexagon::SA1_addi: |
814 | 0 | case Hexagon::SA1_addrx: |
815 | 0 | case Hexagon::SA1_addsp: |
816 | 0 | case Hexagon::SA1_and1: |
817 | 0 | case Hexagon::SA1_clrf: |
818 | 0 | case Hexagon::SA1_clrfnew: |
819 | 0 | case Hexagon::SA1_clrt: |
820 | 0 | case Hexagon::SA1_clrtnew: |
821 | 0 | case Hexagon::SA1_cmpeqi: |
822 | 0 | case Hexagon::SA1_combine0i: |
823 | 0 | case Hexagon::SA1_combine1i: |
824 | 0 | case Hexagon::SA1_combine2i: |
825 | 0 | case Hexagon::SA1_combine3i: |
826 | 0 | case Hexagon::SA1_combinerz: |
827 | 0 | case Hexagon::SA1_combinezr: |
828 | 0 | case Hexagon::SA1_dec: |
829 | 0 | case Hexagon::SA1_inc: |
830 | 0 | case Hexagon::SA1_seti: |
831 | 0 | case Hexagon::SA1_setin1: |
832 | 0 | case Hexagon::SA1_sxtb: |
833 | 0 | case Hexagon::SA1_sxth: |
834 | 0 | case Hexagon::SA1_tfr: |
835 | 0 | case Hexagon::SA1_zxtb: |
836 | 0 | case Hexagon::SA1_zxth: |
837 | 0 | case Hexagon::SL1_loadri_io: |
838 | 0 | case Hexagon::SL1_loadrub_io: |
839 | 0 | case Hexagon::SL2_deallocframe: |
840 | 0 | case Hexagon::SL2_jumpr31: |
841 | 0 | case Hexagon::SL2_jumpr31_f: |
842 | 0 | case Hexagon::SL2_jumpr31_fnew: |
843 | 0 | case Hexagon::SL2_jumpr31_t: |
844 | 0 | case Hexagon::SL2_jumpr31_tnew: |
845 | 0 | case Hexagon::SL2_loadrb_io: |
846 | 0 | case Hexagon::SL2_loadrd_sp: |
847 | 0 | case Hexagon::SL2_loadrh_io: |
848 | 0 | case Hexagon::SL2_loadri_sp: |
849 | 0 | case Hexagon::SL2_loadruh_io: |
850 | 0 | case Hexagon::SL2_return: |
851 | 0 | case Hexagon::SL2_return_f: |
852 | 0 | case Hexagon::SL2_return_fnew: |
853 | 0 | case Hexagon::SL2_return_t: |
854 | 0 | case Hexagon::SL2_return_tnew: |
855 | 0 | case Hexagon::SS1_storeb_io: |
856 | 0 | case Hexagon::SS1_storew_io: |
857 | 0 | case Hexagon::SS2_allocframe: |
858 | 0 | case Hexagon::SS2_storebi0: |
859 | 0 | case Hexagon::SS2_storebi1: |
860 | 0 | case Hexagon::SS2_stored_sp: |
861 | 0 | case Hexagon::SS2_storeh_io: |
862 | 0 | case Hexagon::SS2_storew_sp: |
863 | 0 | case Hexagon::SS2_storewi0: |
864 | 0 | case Hexagon::SS2_storewi1: |
865 | 0 | return true; |
866 | 0 | } |
867 | 0 | } |
868 | | |
869 | 0 | bool HexagonMCInstrInfo::isVector(MCInstrInfo const &MCII, MCInst const &MCI) { |
870 | 0 | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
871 | 0 | return (F >> HexagonII::isCVIPos) & HexagonII::isCVIMask; |
872 | 0 | } |
873 | | |
874 | 628k | int64_t HexagonMCInstrInfo::minConstant(MCInst const &MCI, size_t Index) { |
875 | 628k | auto Sentinel = static_cast<int64_t>(std::numeric_limits<uint32_t>::max()) |
876 | 628k | << 8; |
877 | 628k | if (MCI.size() <= Index) |
878 | 0 | return Sentinel; |
879 | 628k | MCOperand const &MCO = MCI.getOperand(Index); |
880 | 628k | if (!MCO.isExpr()) |
881 | 0 | return Sentinel; |
882 | 628k | int64_t Value; |
883 | 628k | if (!MCO.getExpr()->evaluateAsAbsolute(Value)) |
884 | 0 | return Sentinel; |
885 | 628k | return Value; |
886 | 628k | } |
887 | | |
888 | 520k | void HexagonMCInstrInfo::setMustExtend(MCExpr const &Expr, bool Val) { |
889 | 520k | HexagonMCExpr &HExpr = const_cast<HexagonMCExpr &>(cast<HexagonMCExpr>(Expr)); |
890 | 520k | HExpr.setMustExtend(Val); |
891 | 520k | } |
892 | | |
893 | 335k | bool HexagonMCInstrInfo::mustExtend(MCExpr const &Expr) { |
894 | 335k | HexagonMCExpr const &HExpr = cast<HexagonMCExpr>(Expr); |
895 | 335k | return HExpr.mustExtend(); |
896 | 335k | } |
897 | 0 | void HexagonMCInstrInfo::setMustNotExtend(MCExpr const &Expr, bool Val) { |
898 | 0 | HexagonMCExpr &HExpr = const_cast<HexagonMCExpr &>(cast<HexagonMCExpr>(Expr)); |
899 | 0 | HExpr.setMustNotExtend(Val); |
900 | 0 | } |
901 | 318k | bool HexagonMCInstrInfo::mustNotExtend(MCExpr const &Expr) { |
902 | 318k | HexagonMCExpr const &HExpr = cast<HexagonMCExpr>(Expr); |
903 | 318k | return HExpr.mustNotExtend(); |
904 | 318k | } |
905 | 0 | void HexagonMCInstrInfo::setS27_2_reloc(MCExpr const &Expr, bool Val) { |
906 | 0 | HexagonMCExpr &HExpr = |
907 | 0 | const_cast<HexagonMCExpr &>(*cast<HexagonMCExpr>(&Expr)); |
908 | 0 | HExpr.setS27_2_reloc(Val); |
909 | 0 | } |
910 | 0 | bool HexagonMCInstrInfo::s27_2_reloc(MCExpr const &Expr) { |
911 | 0 | HexagonMCExpr const *HExpr = dyn_cast<HexagonMCExpr>(&Expr); |
912 | 0 | if (!HExpr) |
913 | 0 | return false; |
914 | 0 | return HExpr->s27_2_reloc(); |
915 | 0 | } |
916 | | |
917 | 0 | unsigned HexagonMCInstrInfo::packetSizeSlots(MCSubtargetInfo const &STI) { |
918 | 0 | const bool IsTiny = STI.hasFeature(Hexagon::ProcTinyCore); |
919 | |
|
920 | 0 | return IsTiny ? (HEXAGON_PACKET_SIZE - 1) : HEXAGON_PACKET_SIZE; |
921 | 0 | } |
922 | | |
923 | 0 | unsigned HexagonMCInstrInfo::packetSize(StringRef CPU) { |
924 | 0 | return llvm::StringSwitch<unsigned>(CPU) |
925 | 0 | .Case("hexagonv67t", 3) |
926 | 0 | .Default(4); |
927 | 0 | } |
928 | | |
929 | 229k | void HexagonMCInstrInfo::padEndloop(MCInst &MCB, MCContext &Context) { |
930 | 229k | MCInst Nop; |
931 | 229k | Nop.setOpcode(Hexagon::A2_nop); |
932 | 229k | assert(isBundle(MCB)); |
933 | 229k | while (LoopNeedsPadding(MCB)) |
934 | 0 | MCB.addOperand(MCOperand::createInst(new (Context) MCInst(Nop))); |
935 | 229k | } |
936 | | |
937 | | HexagonMCInstrInfo::PredicateInfo |
938 | 0 | HexagonMCInstrInfo::predicateInfo(MCInstrInfo const &MCII, MCInst const &MCI) { |
939 | 0 | if (!isPredicated(MCII, MCI)) |
940 | 0 | return {0, 0, false}; |
941 | 0 | MCInstrDesc const &Desc = getDesc(MCII, MCI); |
942 | 0 | for (auto I = Desc.getNumDefs(), N = Desc.getNumOperands(); I != N; ++I) |
943 | 0 | if (Desc.operands()[I].RegClass == Hexagon::PredRegsRegClassID) |
944 | 0 | return {MCI.getOperand(I).getReg(), I, isPredicatedTrue(MCII, MCI)}; |
945 | 0 | return {0, 0, false}; |
946 | 0 | } |
947 | | |
948 | | bool HexagonMCInstrInfo::prefersSlot3(MCInstrInfo const &MCII, |
949 | 2.12M | MCInst const &MCI) { |
950 | 2.12M | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
951 | 2.12M | return (F >> HexagonII::PrefersSlot3Pos) & HexagonII::PrefersSlot3Mask; |
952 | 2.12M | } |
953 | | |
954 | 0 | bool HexagonMCInstrInfo::hasTmpDst(MCInstrInfo const &MCII, MCInst const &MCI) { |
955 | 0 | switch (MCI.getOpcode()) { |
956 | 0 | default: |
957 | 0 | return false; |
958 | 0 | case Hexagon::V6_vgathermh: |
959 | 0 | case Hexagon::V6_vgathermhq: |
960 | 0 | case Hexagon::V6_vgathermhw: |
961 | 0 | case Hexagon::V6_vgathermhwq: |
962 | 0 | case Hexagon::V6_vgathermw: |
963 | 0 | case Hexagon::V6_vgathermwq: |
964 | 0 | return true; |
965 | 0 | } |
966 | 0 | return false; |
967 | 0 | } |
968 | | |
969 | 0 | bool HexagonMCInstrInfo::hasHvxTmp(MCInstrInfo const &MCII, MCInst const &MCI) { |
970 | 0 | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
971 | 0 | return (F >> HexagonII::HasHvxTmpPos) & HexagonII::HasHvxTmpMask; |
972 | 0 | } |
973 | | |
974 | | bool HexagonMCInstrInfo::requiresSlot(MCSubtargetInfo const &STI, |
975 | 2.12M | MCInst const &MCI) { |
976 | 2.12M | const unsigned OpCode = MCI.getOpcode(); |
977 | 2.12M | const bool IsTiny = STI.getFeatureBits() [Hexagon::ProcTinyCore]; |
978 | 2.12M | const bool NoSlotReqd = Hexagon::A4_ext == OpCode || |
979 | 2.12M | (IsTiny && Hexagon::A2_nop == OpCode) || |
980 | 2.12M | (IsTiny && Hexagon::J4_hintjumpr == OpCode); |
981 | | |
982 | 2.12M | return !NoSlotReqd; |
983 | 2.12M | } |
984 | | |
985 | | unsigned HexagonMCInstrInfo::slotsConsumed(MCInstrInfo const &MCII, |
986 | | MCSubtargetInfo const &STI, |
987 | 0 | MCInst const &MCI) { |
988 | 0 | unsigned slotsUsed = 0; |
989 | 0 | for (auto HMI : bundleInstructions(MCI)) { |
990 | 0 | MCInst const &MCI = *HMI.getInst(); |
991 | 0 | if (!requiresSlot(STI, MCI)) |
992 | 0 | continue; |
993 | 0 | if (isDuplex(MCII, MCI)) |
994 | 0 | slotsUsed += 2; |
995 | 0 | else |
996 | 0 | ++slotsUsed; |
997 | 0 | } |
998 | 0 | return slotsUsed; |
999 | 0 | } |
1000 | | |
1001 | | void HexagonMCInstrInfo::replaceDuplex(MCContext &Context, MCInst &MCB, |
1002 | 37.8k | DuplexCandidate Candidate) { |
1003 | 37.8k | assert(Candidate.packetIndexI < MCB.size()); |
1004 | 0 | assert(Candidate.packetIndexJ < MCB.size()); |
1005 | 0 | assert(isBundle(MCB)); |
1006 | 0 | MCInst *Duplex = |
1007 | 37.8k | deriveDuplex(Context, Candidate.iClass, |
1008 | 37.8k | *MCB.getOperand(Candidate.packetIndexJ).getInst(), |
1009 | 37.8k | *MCB.getOperand(Candidate.packetIndexI).getInst()); |
1010 | 37.8k | assert(Duplex != nullptr); |
1011 | 0 | MCB.getOperand(Candidate.packetIndexI).setInst(Duplex); |
1012 | 37.8k | MCB.erase(MCB.begin() + Candidate.packetIndexJ); |
1013 | 37.8k | } |
1014 | | |
1015 | 0 | void HexagonMCInstrInfo::setInnerLoop(MCInst &MCI) { |
1016 | 0 | assert(isBundle(MCI)); |
1017 | 0 | MCOperand &Operand = MCI.getOperand(0); |
1018 | 0 | Operand.setImm(Operand.getImm() | innerLoopMask); |
1019 | 0 | } |
1020 | | |
1021 | 0 | void HexagonMCInstrInfo::setMemReorderDisabled(MCInst &MCI) { |
1022 | 0 | assert(isBundle(MCI)); |
1023 | 0 | MCOperand &Operand = MCI.getOperand(0); |
1024 | 0 | Operand.setImm(Operand.getImm() | memReorderDisabledMask); |
1025 | 0 | assert(isMemReorderDisabled(MCI)); |
1026 | 0 | } |
1027 | | |
1028 | 0 | void HexagonMCInstrInfo::setOuterLoop(MCInst &MCI) { |
1029 | 0 | assert(isBundle(MCI)); |
1030 | 0 | MCOperand &Operand = MCI.getOperand(0); |
1031 | 0 | Operand.setImm(Operand.getImm() | outerLoopMask); |
1032 | 0 | } |
1033 | | |
1034 | | unsigned HexagonMCInstrInfo::SubregisterBit(unsigned Consumer, |
1035 | | unsigned Producer, |
1036 | 0 | unsigned Producer2) { |
1037 | | // If we're a single vector consumer of a double producer, set subreg bit |
1038 | | // based on if we're accessing the lower or upper register component |
1039 | 0 | if (IsVecRegPair(Producer) && IsVecRegSingle(Consumer)) |
1040 | 0 | return (Consumer - Hexagon::V0) & 0x1; |
1041 | 0 | if (Producer2 != Hexagon::NoRegister) |
1042 | 0 | return Consumer == Producer; |
1043 | 0 | return 0; |
1044 | 0 | } |
1045 | | |
1046 | 229k | bool HexagonMCInstrInfo::LoopNeedsPadding(MCInst const &MCB) { |
1047 | 229k | return ( |
1048 | 229k | (HexagonMCInstrInfo::isInnerLoop(MCB) && |
1049 | 229k | (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_INNER_SIZE)) || |
1050 | 229k | ((HexagonMCInstrInfo::isOuterLoop(MCB) && |
1051 | 229k | (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_OUTER_SIZE)))); |
1052 | 229k | } |
1053 | | |
1054 | | bool HexagonMCInstrInfo::IsABranchingInst(MCInstrInfo const &MCII, |
1055 | | MCSubtargetInfo const &STI, |
1056 | 56.0k | MCInst const &I) { |
1057 | 56.0k | assert(!HexagonMCInstrInfo::isBundle(I)); |
1058 | 0 | MCInstrDesc const &Desc = HexagonMCInstrInfo::getDesc(MCII, I); |
1059 | 56.0k | return (Desc.isBranch() || Desc.isCall() || Desc.isReturn()); |
1060 | 56.0k | } |