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