[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / lib / Target / Hexagon / MCTargetDesc / HexagonMCInstrInfo.cpp
blobfa12fe1da4488b9deba71ea9860b1323c159ef5c
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
11 //===----------------------------------------------------------------------===//
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>
33 using namespace llvm;
35 bool HexagonMCInstrInfo::PredicateInfo::isPredicated() const {
36 return Register != Hexagon::NoRegister;
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()) {}
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()) {}
50 Hexagon::PacketIterator &Hexagon::PacketIterator::operator++() {
51 if (DuplexCurrent != DuplexEnd) {
52 ++DuplexCurrent;
53 if (DuplexCurrent == DuplexEnd) {
54 DuplexCurrent = BundleEnd;
55 DuplexEnd = BundleEnd;
56 ++BundleCurrent;
58 return *this;
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();
68 return *this;
71 MCInst const &Hexagon::PacketIterator::operator*() const {
72 if (DuplexCurrent != DuplexEnd)
73 return *DuplexCurrent->getInst();
74 return *BundleCurrent->getInst();
77 bool Hexagon::PacketIterator::operator==(PacketIterator const &Other) const {
78 return BundleCurrent == Other.BundleCurrent && BundleEnd == Other.BundleEnd &&
79 DuplexCurrent == Other.DuplexCurrent && DuplexEnd == Other.DuplexEnd;
82 void HexagonMCInstrInfo::addConstant(MCInst &MI, uint64_t Value,
83 MCContext &Context) {
84 MI.addOperand(MCOperand::createExpr(MCConstantExpr::create(Value, Context)));
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));
94 // Create the extender.
95 MCInst *XMCI =
96 new (Context) MCInst(HexagonMCInstrInfo::deriveExtender(MCII, MCI, exOp));
97 XMCI->setLoc(MCI.getLoc());
99 MCB.addOperand(MCOperand::createInst(XMCI));
102 iterator_range<Hexagon::PacketIterator>
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));
110 iterator_range<MCInst::const_iterator>
111 HexagonMCInstrInfo::bundleInstructions(MCInst const &MCI) {
112 assert(isBundle(MCI));
113 return drop_begin(MCI, bundleInstructionsOffset);
116 size_t HexagonMCInstrInfo::bundleSize(MCInst const &MCI) {
117 if (HexagonMCInstrInfo::isBundle(MCI))
118 return (MCI.size() - bundleInstructionsOffset);
119 else
120 return (1);
123 namespace {
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);
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);
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;
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;
162 } // namespace
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);
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;
180 HexagonMCChecker ArchCheck(*BaseCheck, *ArchSTI, true);
181 return canonicalizePacketImpl(MCII, *ArchSTI, Context, MCB, &ArchCheck);
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));
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;
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);
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;
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;
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);
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));
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);
248 MCInstrDesc const &HexagonMCInstrInfo::getDesc(MCInstrInfo const &MCII,
249 MCInst const &MCI) {
250 return MCII.get(MCI.getOpcode());
253 unsigned HexagonMCInstrInfo::getDuplexRegisterNumbering(unsigned Reg) {
254 using namespace Hexagon;
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;
303 MCExpr const &HexagonMCInstrInfo::getExpr(MCExpr const &Expr) {
304 const auto &HExpr = cast<HexagonMCExpr>(Expr);
305 assert(HExpr.getExpr());
306 return *HExpr.getExpr();
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);
315 MCOperand const &
316 HexagonMCInstrInfo::getExtendableOperand(MCInstrInfo const &MCII,
317 MCInst const &MCI) {
318 unsigned O = HexagonMCInstrInfo::getExtendableOp(MCII, MCI);
319 MCOperand const &MO = MCI.getOperand(O);
321 assert((HexagonMCInstrInfo::isExtendable(MCII, MCI) ||
322 HexagonMCInstrInfo::isExtended(MCII, MCI)) &&
323 (MO.isImm() || MO.isExpr()));
324 return (MO);
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);
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);
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;
345 /// Return the maximum value of an extendable operand.
346 int HexagonMCInstrInfo::getMaxValue(MCInstrInfo const &MCII,
347 MCInst const &MCI) {
348 assert(HexagonMCInstrInfo::isExtendable(MCII, MCI) ||
349 HexagonMCInstrInfo::isExtended(MCII, MCI));
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;
356 /// Return the minimum value of an extendable operand.
357 int HexagonMCInstrInfo::getMinValue(MCInstrInfo const &MCII,
358 MCInst const &MCI) {
359 assert(HexagonMCInstrInfo::isExtendable(MCII, MCI) ||
360 HexagonMCInstrInfo::isExtended(MCII, MCI));
362 if (HexagonMCInstrInfo::isExtentSigned(MCII, MCI)) // if value is signed
363 return -(1 << (HexagonMCInstrInfo::getExtentBits(MCII, MCI) - 1));
364 return 0;
367 StringRef HexagonMCInstrInfo::getName(MCInstrInfo const &MCII,
368 MCInst const &MCI) {
369 return MCII.getName(MCI.getOpcode());
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);
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);
389 assert((HexagonMCInstrInfo::isNewValue(MCII, MCI) ||
390 HexagonMCInstrInfo::hasNewValue(MCII, MCI)) &&
391 MCO.isReg());
392 return (MCO);
396 /// Return the new value or the newly produced value.
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);
403 MCOperand const &
404 HexagonMCInstrInfo::getNewValueOperand2(MCInstrInfo const &MCII,
405 MCInst const &MCI) {
406 unsigned O = HexagonMCInstrInfo::getNewValueOp2(MCII, MCI);
407 MCOperand const &MCO = MCI.getOperand(O);
409 assert((HexagonMCInstrInfo::isNewValue(MCII, MCI) ||
410 HexagonMCInstrInfo::hasNewValue2(MCII, MCI)) &&
411 MCO.isReg());
412 return (MCO);
415 /// Return the Hexagon ISA class for the insn.
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);
422 /// Return the resources used by this instruction
423 unsigned HexagonMCInstrInfo::getCVIResources(MCInstrInfo const &MCII,
424 MCSubtargetInfo const &STI,
425 MCInst const &MCI) {
427 const InstrItinerary *II = STI.getSchedModel().InstrItineraries;
428 int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass();
429 int Size = II[SchedClass].LastStage - II[SchedClass].FirstStage;
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;
437 if (Size < 2)
438 return 0;
439 return ((Stage + HexagonStages)->getUnits());
442 /// Return the slots this instruction can execute out of
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());
451 /// Return the slots this instruction consumes in addition to
452 /// the slot(s) it can execute out of
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;
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;
473 // if 0 is returned, then no additional slots are consumed by this inst.
474 return Slots;
477 bool HexagonMCInstrInfo::hasDuplex(MCInstrInfo const &MCII, MCInst const &MCI) {
478 if (!HexagonMCInstrInfo::isBundle(MCI))
479 return false;
481 for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCI)) {
482 if (HexagonMCInstrInfo::isDuplex(MCII, *I.getInst()))
483 return true;
486 return false;
489 bool HexagonMCInstrInfo::hasExtenderForIndex(MCInst const &MCB, size_t Index) {
490 return extenderForIndex(MCB, Index) != nullptr;
493 bool HexagonMCInstrInfo::hasImmExt(MCInst const &MCI) {
494 if (!HexagonMCInstrInfo::isBundle(MCI))
495 return false;
497 for (const auto &I : HexagonMCInstrInfo::bundleInstructions(MCI)) {
498 if (isImmext(*I.getInst()))
499 return true;
502 return false;
505 /// Return whether the insn produces a value.
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);
512 /// Return whether the insn produces a second value.
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);
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();
525 /// Return where the instruction is an accumulator.
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);
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;
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;
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);
572 bool HexagonMCInstrInfo::isCanon(MCInstrInfo const &MCII, MCInst const &MCI) {
573 return !HexagonMCInstrInfo::getDesc(MCII, MCI).isPseudo() &&
574 !HexagonMCInstrInfo::isPrefix(MCII, 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);
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);
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);
594 bool HexagonMCInstrInfo::isCompound(MCInstrInfo const &MCII,
595 MCInst const &MCI) {
596 return (getType(MCII, MCI) == HexagonII::TypeCJ);
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);
604 bool HexagonMCInstrInfo::isDblRegForSubInst(unsigned Reg) {
605 return ((Reg >= Hexagon::D0 && Reg <= Hexagon::D3) ||
606 (Reg >= Hexagon::D8 && Reg <= Hexagon::D11));
609 bool HexagonMCInstrInfo::isDuplex(MCInstrInfo const &MCII, MCInst const &MCI) {
610 return HexagonII::TypeDUPLEX == HexagonMCInstrInfo::getType(MCII, 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;
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;
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);
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;
635 bool HexagonMCInstrInfo::isImmext(MCInst const &MCI) {
636 return MCI.getOpcode() == Hexagon::A4_ext;
639 bool HexagonMCInstrInfo::isInnerLoop(MCInst const &MCI) {
640 assert(isBundle(MCI));
641 int64_t Flags = MCI.getOperand(0).getImm();
642 return (Flags & innerLoopMask) != 0;
645 bool HexagonMCInstrInfo::isIntReg(unsigned Reg) {
646 return (Reg >= Hexagon::R0 && Reg <= Hexagon::R31);
649 bool HexagonMCInstrInfo::isIntRegForSubInst(unsigned Reg) {
650 return ((Reg >= Hexagon::R0 && Reg <= Hexagon::R7) ||
651 (Reg >= Hexagon::R16 && Reg <= Hexagon::R23));
654 /// Return whether the insn expects newly produced value.
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);
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;
667 /// Return whether the operand is extendable.
668 bool HexagonMCInstrInfo::isOpExtendable(MCInstrInfo const &MCII,
669 MCInst const &MCI, unsigned short O) {
670 return (O == HexagonMCInstrInfo::getExtendableOp(MCII, 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;
679 bool HexagonMCInstrInfo::IsVecRegPair(unsigned VecReg) {
680 return (VecReg >= Hexagon::W0 && VecReg <= Hexagon::W15) ||
681 (VecReg >= Hexagon::WR0 && VecReg <= Hexagon::WR15);
684 bool HexagonMCInstrInfo::IsReverseVecRegPair(unsigned VecReg) {
685 return (VecReg >= Hexagon::WR0 && VecReg <= Hexagon::WR15);
688 bool HexagonMCInstrInfo::IsVecRegSingle(unsigned VecReg) {
689 return (VecReg >= Hexagon::V0 && VecReg <= Hexagon::V31);
692 std::pair<unsigned, unsigned>
693 HexagonMCInstrInfo::GetVecRegPairIndices(unsigned VecRegPair) {
694 assert(IsVecRegPair(VecRegPair) &&
695 "VecRegPair must be a vector register pair");
697 const bool IsRev = IsReverseVecRegPair(VecRegPair);
698 const unsigned PairIndex =
699 2 * (IsRev ? VecRegPair - Hexagon::WR0 : VecRegPair - Hexagon::W0);
701 return IsRev ? std::make_pair(PairIndex, PairIndex + 1)
702 : std::make_pair(PairIndex + 1, PairIndex);
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;
713 return ConsumerSingleIndex == ProdPairIndex;
715 return false;
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);
724 bool HexagonMCInstrInfo::isPrefix(MCInstrInfo const &MCII, MCInst const &MCI) {
725 return HexagonII::TypeEXTENDER == HexagonMCInstrInfo::getType(MCII, 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);
734 /// Return whether the insn is newly predicated.
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);
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));
748 bool HexagonMCInstrInfo::isPredReg(MCRegisterInfo const &MRI, unsigned Reg) {
749 auto &PredRegClass = MRI.getRegClass(Hexagon::PredRegsRegClassID);
750 return PredRegClass.contains(Reg);
753 bool HexagonMCInstrInfo::isPredRegister(MCInstrInfo const &MCII,
754 MCInst const &Inst, unsigned I) {
755 MCInstrDesc const &Desc = HexagonMCInstrInfo::getDesc(MCII, Inst);
757 return Inst.getOperand(I).isReg() &&
758 Desc.OpInfo[I].RegClass == Hexagon::PredRegsRegClassID;
761 /// Return whether the insn can be packaged only with A and X-type insns.
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);
767 /// Return whether the insn can be packaged only with an A-type insn in slot #1.
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);
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);
782 /// Return whether the insn is solo, i.e., cannot be in a packet.
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);
788 bool HexagonMCInstrInfo::isMemReorderDisabled(MCInst const &MCI) {
789 assert(isBundle(MCI));
790 auto Flags = MCI.getOperand(0).getImm();
791 return (Flags & memReorderDisabledMask) != 0;
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;
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;
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;
873 void HexagonMCInstrInfo::setMustExtend(MCExpr const &Expr, bool Val) {
874 HexagonMCExpr &HExpr = const_cast<HexagonMCExpr &>(cast<HexagonMCExpr>(Expr));
875 HExpr.setMustExtend(Val);
878 bool HexagonMCInstrInfo::mustExtend(MCExpr const &Expr) {
879 HexagonMCExpr const &HExpr = cast<HexagonMCExpr>(Expr);
880 return HExpr.mustExtend();
882 void HexagonMCInstrInfo::setMustNotExtend(MCExpr const &Expr, bool Val) {
883 HexagonMCExpr &HExpr = const_cast<HexagonMCExpr &>(cast<HexagonMCExpr>(Expr));
884 HExpr.setMustNotExtend(Val);
886 bool HexagonMCInstrInfo::mustNotExtend(MCExpr const &Expr) {
887 HexagonMCExpr const &HExpr = cast<HexagonMCExpr>(Expr);
888 return HExpr.mustNotExtend();
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);
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();
902 unsigned HexagonMCInstrInfo::packetSizeSlots(MCSubtargetInfo const &STI) {
903 const bool IsTiny = STI.getFeatureBits()[Hexagon::ProcTinyCore];
905 return IsTiny ? (HEXAGON_PACKET_SIZE - 1) : HEXAGON_PACKET_SIZE;
908 unsigned HexagonMCInstrInfo::packetSize(StringRef CPU) {
909 return llvm::StringSwitch<unsigned>(CPU)
910 .Case("hexagonv67t", 3)
911 .Default(4);
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)));
925 HexagonMCInstrInfo::PredicateInfo
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};
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;
942 /// return true if instruction has hasTmpDst attribute.
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;
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);
956 return !NoSlotReqd;
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;
972 return slotsUsed;
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);
989 void HexagonMCInstrInfo::setInnerLoop(MCInst &MCI) {
990 assert(isBundle(MCI));
991 MCOperand &Operand = MCI.getOperand(0);
992 Operand.setImm(Operand.getImm() | innerLoopMask);
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));
1002 void HexagonMCInstrInfo::setOuterLoop(MCInst &MCI) {
1003 assert(isBundle(MCI));
1004 MCOperand &Operand = MCI.getOperand(0);
1005 Operand.setImm(Operand.getImm() | outerLoopMask);
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;