LLVM 24.0.0git
HexagonMCInstrInfo.cpp
Go to the documentation of this file.
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
21#include "llvm/MC/MCContext.h"
22#include "llvm/MC/MCExpr.h"
23#include "llvm/MC/MCInst.h"
24#include "llvm/MC/MCInstrInfo.h"
29#include <cassert>
30#include <cstdint>
31#include <limits>
32
33using namespace llvm;
34
36 return Register != Hexagon::NoRegister;
37}
38
40 MCInst const &Inst)
41 : MCII(MCII), BundleCurrent(Inst.begin() +
43 BundleEnd(Inst.end()), DuplexCurrent(Inst.end()), DuplexEnd(Inst.end()) {}
44
46 MCInst const &Inst, std::nullptr_t)
47 : MCII(MCII), BundleCurrent(Inst.end()), BundleEnd(Inst.end()),
48 DuplexCurrent(Inst.end()), DuplexEnd(Inst.end()) {}
49
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
72 if (DuplexCurrent != DuplexEnd)
73 return *DuplexCurrent->getInst();
74 return *BundleCurrent->getInst();
75}
76
78 return BundleCurrent == Other.BundleCurrent && BundleEnd == Other.BundleEnd &&
79 DuplexCurrent == Other.DuplexCurrent && DuplexEnd == Other.DuplexEnd;
80}
81
83 MCContext &Context) {
85}
86
88 MCInstrInfo const &MCII, MCInst &MCB,
89 MCInst const &MCI) {
91 MCOperand const &exOp =
93
94 // Create the extender.
95 MCInst *XMCI =
96 new (Context) MCInst(HexagonMCInstrInfo::deriveExtender(MCII, MCI, exOp));
97 XMCI->setLoc(MCI.getLoc());
98
100}
101
104 MCInst const &MCI) {
105 assert(isBundle(MCI));
106 return make_range(Hexagon::PacketIterator(MCII, MCI),
107 Hexagon::PacketIterator(MCII, MCI, nullptr));
108}
109
115
118 return (MCI.size() - bundleInstructionsOffset);
119 else
120 return (1);
121}
122
123namespace {
124bool canonicalizePacketImpl(MCInstrInfo const &MCII, MCSubtargetInfo const &STI,
125 MCContext &Context, MCInst &MCB,
127 // Check the bundle for errors.
128 bool CheckOk = Check ? Check->check(false) : true;
129 if (!CheckOk)
130 return false;
131
132 // Examine the packet and convert pairs of instructions to compound
133 // instructions when possible.
135 HexagonMCInstrInfo::tryCompound(MCII, STI, Context, MCB);
136 HexagonMCShuffle(Context, false, MCII, STI, MCB);
137
138 const SmallVector<DuplexCandidate, 8> possibleDuplexes =
139 (STI.hasFeature(Hexagon::FeatureDuplex))
142
143 // Examine the packet and convert pairs of instructions to duplex
144 // instructions when possible.
145 HexagonMCShuffle(Context, MCII, STI, MCB, possibleDuplexes);
146
147 // Examines packet and pad the packet, if needed, when an
148 // end-loop is in the bundle.
149 HexagonMCInstrInfo::padEndloop(MCB, Context);
150
151 // If compounding and duplexing didn't reduce the size below
152 // 4 or less we have a packet that is too big.
154 if (Check)
155 Check->reportError("invalid instruction packet: out of slots");
156 return false;
157 }
158 // Check the bundle for errors.
159 CheckOk = Check ? Check->check(true) : true;
160 if (!CheckOk)
161 return false;
162
163 HexagonMCShuffle(Context, true, MCII, STI, MCB);
164
165 return true;
166}
167} // namespace
168
170 MCSubtargetInfo const &STI,
171 MCContext &Context, MCInst &MCB,
173 bool AttemptCompatibility) {
174 auto ArchSTI = Hexagon_MC::getArchSubtarget(&STI);
175 if (!AttemptCompatibility || ArchSTI == nullptr)
176 return canonicalizePacketImpl(MCII, STI, Context, MCB, Check);
177
178 const MCRegisterInfo *RI = Context.getRegisterInfo();
179 HexagonMCChecker DefaultCheck(Context, MCII, STI, MCB, *RI, false);
180 HexagonMCChecker *BaseCheck = (Check == nullptr) ? &DefaultCheck : Check;
181 HexagonMCChecker PerfCheck(*BaseCheck, STI, false);
182 if (canonicalizePacketImpl(MCII, STI, Context, MCB, &PerfCheck))
183 return true;
184
185 HexagonMCChecker ArchCheck(*BaseCheck, *ArchSTI, true);
186 return canonicalizePacketImpl(MCII, *ArchSTI, Context, MCB, &ArchCheck);
187}
188
190 MCInst const &Inst,
191 MCOperand const &MO) {
194
195 MCInst XMI;
196 XMI.setOpcode(Hexagon::A4_ext);
197 if (MO.isImm())
198 XMI.addOperand(MCOperand::createImm(MO.getImm() & (~0x3f)));
199 else if (MO.isExpr())
201 else
202 llvm_unreachable("invalid extendable operand");
203 return XMI;
204}
205
207 MCInst const &inst0,
208 MCInst const &inst1) {
209 assert((iClass <= 0xf) && "iClass must have range of 0 to 0xf");
210 MCInst *duplexInst = new (Context) MCInst;
211 duplexInst->setOpcode(Hexagon::DuplexIClass0 + iClass);
212
213 MCInst *SubInst0 = new (Context) MCInst(deriveSubInst(inst0));
214 MCInst *SubInst1 = new (Context) MCInst(deriveSubInst(inst1));
215 duplexInst->addOperand(MCOperand::createInst(SubInst0));
216 duplexInst->addOperand(MCOperand::createInst(SubInst1));
217 return duplexInst;
218}
219
221 size_t Index) {
222 assert(Index <= bundleSize(MCB));
223 if (Index == 0)
224 return nullptr;
225 MCInst const *Inst =
227 if (isImmext(*Inst))
228 return Inst;
229 return nullptr;
230}
231
233 MCInstrInfo const &MCII, MCInst &MCB,
234 MCInst const &MCI) {
235 if (isConstExtended(MCII, MCI))
236 addConstExtender(Context, MCII, MCB, MCI);
237}
238
245
247 MCInst const &MCI) {
248 const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
249 return static_cast<unsigned>((F >> HexagonII::AddrModePos) &
251}
252
254 MCInst const &MCI) {
255 return MCII.get(MCI.getOpcode());
256}
257
259 using namespace Hexagon;
260
261 switch (Reg.id()) {
262 default:
263 llvm_unreachable("unknown duplex register");
264 // Rs Rss
265 case R0:
266 case D0:
267 return 0;
268 case R1:
269 case D1:
270 return 1;
271 case R2:
272 case D2:
273 return 2;
274 case R3:
275 case D3:
276 return 3;
277 case R4:
278 case D8:
279 return 4;
280 case R5:
281 case D9:
282 return 5;
283 case R6:
284 case D10:
285 return 6;
286 case R7:
287 case D11:
288 return 7;
289 case R16:
290 return 8;
291 case R17:
292 return 9;
293 case R18:
294 return 10;
295 case R19:
296 return 11;
297 case R20:
298 return 12;
299 case R21:
300 return 13;
301 case R22:
302 return 14;
303 case R23:
304 return 15;
305 }
306}
307
309 const auto &HExpr = cast<HexagonMCExpr>(Expr);
310 assert(HExpr.getExpr());
311 return *HExpr.getExpr();
312}
313
315 MCInst const &MCI) {
316 const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
318}
319
320MCOperand const &
322 MCInst const &MCI) {
323 unsigned O = HexagonMCInstrInfo::getExtendableOp(MCII, MCI);
324 MCOperand const &MO = MCI.getOperand(O);
325
327 HexagonMCInstrInfo::isExtended(MCII, MCI)) &&
328 (MO.isImm() || MO.isExpr()));
329 return (MO);
330}
331
333 MCInst const &MCI) {
334 const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
336}
337
339 MCInst const &MCI) {
340 const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
342}
343
345 MCInst const &MCI) {
346 const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
348}
349
350/// Return the maximum value of an extendable operand.
352 MCInst const &MCI) {
355
356 if (HexagonMCInstrInfo::isExtentSigned(MCII, MCI)) // if value is signed
357 return (1 << (HexagonMCInstrInfo::getExtentBits(MCII, MCI) - 1)) - 1;
358 return (1 << HexagonMCInstrInfo::getExtentBits(MCII, MCI)) - 1;
359}
360
361/// Return the minimum value of an extendable operand.
363 MCInst const &MCI) {
366
367 if (HexagonMCInstrInfo::isExtentSigned(MCII, MCI)) // if value is signed
368 return -(1 << (HexagonMCInstrInfo::getExtentBits(MCII, MCI) - 1));
369 return 0;
370}
371
373 MCInst const &MCI) {
374 return MCII.getName(MCI.getOpcode());
375}
376
378 MCInst const &MCI) {
379 const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
381}
382
384 MCInst const &MCI) {
385 if (HexagonMCInstrInfo::hasTmpDst(MCII, MCI)) {
386 // VTMP doesn't actually exist in the encodings for these 184
387 // 3 instructions so go ahead and create it here.
388 static MCOperand MCO = MCOperand::createReg(Hexagon::VTMP);
389 return (MCO);
390 } else {
391 unsigned O = HexagonMCInstrInfo::getNewValueOp(MCII, MCI);
392 MCOperand const &MCO = MCI.getOperand(O);
393
396 MCO.isReg());
397 return (MCO);
398 }
399}
400
401/// Return the new value or the newly produced value.
403 MCInst const &MCI) {
404 const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
406}
407
408MCOperand const &
410 MCInst const &MCI) {
411 unsigned O = HexagonMCInstrInfo::getNewValueOp2(MCII, MCI);
412 MCOperand const &MCO = MCI.getOperand(O);
413
416 MCO.isReg());
417 return (MCO);
418}
419
420/// Return the Hexagon ISA class for the insn.
422 MCInst const &MCI) {
423 const uint64_t F = MCII.get(MCI.getOpcode()).TSFlags;
425}
426
427/// Return the resources used by this instruction
429 MCSubtargetInfo const &STI,
430 MCInst const &MCI) {
431
433 int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass();
434 int Size = II[SchedClass].LastStage - II[SchedClass].FirstStage;
435
436 // HVX resources used are currently located at the second to last stage.
437 // This could also be done with a linear search of the stages looking for:
438 // CVI_ALL, CVI_MPY01, CVI_XLSHF, CVI_MPY0, CVI_MPY1, CVI_SHIFT, CVI_XLANE,
439 // CVI_ZW
440 unsigned Stage = II[SchedClass].LastStage - 1;
441
442 if (Size < 2)
443 return 0;
444 return ((Stage + HexagonStages)->getUnits());
445}
446
447/// Return the slots this instruction can execute out of
449 MCSubtargetInfo const &STI,
450 MCInst const &MCI) {
452 int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass();
453 return ((II[SchedClass].FirstStage + HexagonStages)->getUnits());
454}
455
456/// Return the slots this instruction consumes in addition to
457/// the slot(s) it can execute out of
458
460 MCSubtargetInfo const &STI,
461 MCInst const &MCI) {
463 int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass();
464 unsigned Slots = 0;
465
466 // FirstStage are slots that this instruction can execute in.
467 // FirstStage+1 are slots that are also consumed by this instruction.
468 // For example: vmemu can only execute in slot 0 but also consumes slot 1.
469 for (unsigned Stage = II[SchedClass].FirstStage + 1;
470 Stage < II[SchedClass].LastStage; ++Stage) {
471 unsigned Units = (Stage + HexagonStages)->getUnits();
472 if (Units > HexagonGetLastSlot())
473 break;
474 // fyi: getUnits() will return 0x1, 0x2, 0x4 or 0x8
475 Slots |= Units;
476 }
477
478 // if 0 is returned, then no additional slots are consumed by this inst.
479 return Slots;
480}
481
482bool HexagonMCInstrInfo::hasDuplex(MCInstrInfo const &MCII, MCInst const &MCI) {
484 return false;
485
486 for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCI)) {
487 if (HexagonMCInstrInfo::isDuplex(MCII, *I.getInst()))
488 return true;
489 }
490
491 return false;
492}
493
494bool HexagonMCInstrInfo::hasExtenderForIndex(MCInst const &MCB, size_t Index) {
495 return extenderForIndex(MCB, Index) != nullptr;
496}
497
500 return false;
501
502 for (const auto &I : HexagonMCInstrInfo::bundleInstructions(MCI)) {
503 if (isImmext(*I.getInst()))
504 return true;
505 }
506
507 return false;
508}
509
510/// Return whether the insn produces a value.
512 MCInst const &MCI) {
513 const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
515}
516
517/// Return whether the insn produces a second value.
519 MCInst const &MCI) {
520 const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
522}
523
524MCInst const &HexagonMCInstrInfo::instruction(MCInst const &MCB, size_t Index) {
525 assert(isBundle(MCB));
527 return *MCB.getOperand(bundleInstructionsOffset + Index).getInst();
528}
529
530/// Return where the instruction is an accumulator.
532 MCInst const &MCI) {
533 const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
535}
536
538 auto Result = Hexagon::BUNDLE == MCI.getOpcode();
539 assert(!Result || (MCI.size() > 0 && MCI.getOperand(0).isImm()));
540 return Result;
541}
542
544 MCInst const &MCI) {
545 if (HexagonMCInstrInfo::isExtended(MCII, MCI))
546 return true;
547 if (!HexagonMCInstrInfo::isExtendable(MCII, MCI))
548 return false;
550 if (isa<HexagonMCExpr>(MO.getExpr()) &&
552 return true;
553 // Branch insns are handled as necessary by relaxation.
554 if ((HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeJ) ||
559 return false;
560 // Otherwise loop instructions and other CR insts are handled by relaxation
561 else if ((HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCR) &&
562 (MCI.getOpcode() != Hexagon::C4_addipc))
563 return false;
564
565 assert(!MO.isImm());
566 if (isa<HexagonMCExpr>(MO.getExpr()) &&
568 return false;
569
570 int64_t Value;
571 if (!MO.getExpr()->evaluateAsAbsolute(Value))
572 return true;
573 if (HexagonMCInstrInfo::isExtentSigned(MCII, MCI)) {
574 int32_t SValue = Value;
575 int32_t MinValue = HexagonMCInstrInfo::getMinValue(MCII, MCI);
576 int32_t MaxValue = HexagonMCInstrInfo::getMaxValue(MCII, MCI);
577 return SValue < MinValue || SValue > MaxValue;
578 }
579 uint32_t UValue = Value;
580 uint32_t MinValue = HexagonMCInstrInfo::getMinValue(MCII, MCI);
581 uint32_t MaxValue = HexagonMCInstrInfo::getMaxValue(MCII, MCI);
582 return UValue < MinValue || UValue > MaxValue;
583}
584
585bool HexagonMCInstrInfo::isCanon(MCInstrInfo const &MCII, MCInst const &MCI) {
586 return !HexagonMCInstrInfo::getDesc(MCII, MCI).isPseudo() &&
588}
589
590bool HexagonMCInstrInfo::isCofMax1(MCInstrInfo const &MCII, MCInst const &MCI) {
591 const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
593}
594
596 MCInst const &MCI) {
597 const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
599}
600
602 MCInst const &MCI) {
603 const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
605}
606
608 MCInst const &MCI) {
609 return (getType(MCII, MCI) == HexagonII::TypeCJ);
610}
611
612bool HexagonMCInstrInfo::isCVINew(MCInstrInfo const &MCII, MCInst const &MCI) {
613 const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
615}
616
618 return ((Reg >= Hexagon::D0 && Reg <= Hexagon::D3) ||
619 (Reg >= Hexagon::D8 && Reg <= Hexagon::D11));
620}
621
622bool HexagonMCInstrInfo::isDuplex(MCInstrInfo const &MCII, MCInst const &MCI) {
624}
625
627 MCInst const &MCI) {
628 uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
630}
631
633 MCInst const &MCI) {
634 uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
636}
637
638bool HexagonMCInstrInfo::isFloat(MCInstrInfo const &MCII, MCInst const &MCI) {
639 const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
640 return ((F >> HexagonII::FPPos) & HexagonII::FPMask);
641}
642
643bool HexagonMCInstrInfo::isHVX(MCInstrInfo const &MCII, MCInst const &MCI) {
644 const uint64_t V = getType(MCII, MCI);
646}
647
649 return MCI.getOpcode() == Hexagon::A4_ext;
650}
651
653 assert(isBundle(MCI));
654 int64_t Flags = MCI.getOperand(0).getImm();
655 return (Flags & innerLoopMask) != 0;
656}
657
659 return (Reg >= Hexagon::R0 && Reg <= Hexagon::R31);
660}
661
663 return ((Reg >= Hexagon::R0 && Reg <= Hexagon::R7) ||
664 (Reg >= Hexagon::R16 && Reg <= Hexagon::R23));
665}
666
667/// Return whether the insn expects newly produced value.
669 MCInst const &MCI) {
670 const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
672}
673
675 MCInst const &MCI) {
676 const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
678}
679
680/// Return whether the operand is extendable.
682 MCInst const &MCI, unsigned short O) {
683 return (O == HexagonMCInstrInfo::getExtendableOp(MCII, MCI));
684}
685
687 assert(isBundle(MCI));
688 int64_t Flags = MCI.getOperand(0).getImm();
689 return (Flags & outerLoopMask) != 0;
690}
691
693 return (VecReg >= Hexagon::W0 && VecReg <= Hexagon::W15) ||
694 (VecReg >= Hexagon::WR0 && VecReg <= Hexagon::WR15);
695}
696
698 return (VecReg >= Hexagon::WR0 && VecReg <= Hexagon::WR15);
699}
700
702 return (VecReg >= Hexagon::V0 && VecReg <= Hexagon::V31);
703}
704
705std::pair<unsigned, unsigned>
707 assert(IsVecRegPair(VecRegPair) &&
708 "VecRegPair must be a vector register pair");
709
710 const bool IsRev = IsReverseVecRegPair(VecRegPair);
711 const unsigned PairIndex =
712 2 * (IsRev ? VecRegPair - Hexagon::WR0 : VecRegPair - Hexagon::W0);
713
714 return IsRev ? std::make_pair(PairIndex, PairIndex + 1)
715 : std::make_pair(PairIndex + 1, PairIndex);
716}
717
719 MCRegister Consumer) {
720 if (IsVecRegPair(Producer) && IsVecRegSingle(Consumer)) {
721 const unsigned ProdPairIndex = IsReverseVecRegPair(Producer)
722 ? Producer - Hexagon::WR0
723 : Producer - Hexagon::W0;
724 const unsigned ConsumerSingleIndex = (Consumer - Hexagon::V0) >> 1;
725
726 return ConsumerSingleIndex == ProdPairIndex;
727 }
728 return false;
729}
730
732 MCInst const &MCI) {
733 const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
735}
736
737bool HexagonMCInstrInfo::isPrefix(MCInstrInfo const &MCII, MCInst const &MCI) {
739}
740
742 MCInst const &MCI) {
743 const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
745}
746
747/// Return whether the insn is newly predicated.
749 MCInst const &MCI) {
750 const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
752}
753
755 MCInst const &MCI) {
756 const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
757 return (
759}
760
762 auto &PredRegClass = MRI.getRegClass(Hexagon::PredRegsRegClassID);
763 return PredRegClass.contains(Reg);
764}
765
767 MCInst const &Inst, unsigned I) {
768 MCInstrDesc const &Desc = HexagonMCInstrInfo::getDesc(MCII, Inst);
769
770 return Inst.getOperand(I).isReg() &&
771 Desc.operands()[I].RegClass == Hexagon::PredRegsRegClassID;
772}
773
774/// Return whether the insn can be packaged only with A and X-type insns.
775bool HexagonMCInstrInfo::isSoloAX(MCInstrInfo const &MCII, MCInst const &MCI) {
776 const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
778}
779
780/// Return whether the insn can be packaged only with an A-type insn in slot #1.
782 MCInst const &MCI) {
783 const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
784 return ((F >> HexagonII::RestrictSlot1AOKPos) &
786}
787
794
795/// Return whether the insn is solo, i.e., cannot be in a packet.
796bool HexagonMCInstrInfo::isSolo(MCInstrInfo const &MCII, MCInst const &MCI) {
797 const uint64_t F = MCII.get(MCI.getOpcode()).TSFlags;
799}
800
802 assert(isBundle(MCI));
803 auto Flags = MCI.getOperand(0).getImm();
804 return (Flags & memReorderDisabledMask) != 0;
805}
806
808 switch (MCI.getOpcode()) {
809 default:
810 return false;
811 case Hexagon::SA1_addi:
812 case Hexagon::SA1_addrx:
813 case Hexagon::SA1_addsp:
814 case Hexagon::SA1_and1:
815 case Hexagon::SA1_clrf:
816 case Hexagon::SA1_clrfnew:
817 case Hexagon::SA1_clrt:
818 case Hexagon::SA1_clrtnew:
819 case Hexagon::SA1_cmpeqi:
820 case Hexagon::SA1_combine0i:
821 case Hexagon::SA1_combine1i:
822 case Hexagon::SA1_combine2i:
823 case Hexagon::SA1_combine3i:
824 case Hexagon::SA1_combinerz:
825 case Hexagon::SA1_combinezr:
826 case Hexagon::SA1_dec:
827 case Hexagon::SA1_inc:
828 case Hexagon::SA1_seti:
829 case Hexagon::SA1_setin1:
830 case Hexagon::SA1_sxtb:
831 case Hexagon::SA1_sxth:
832 case Hexagon::SA1_tfr:
833 case Hexagon::SA1_zxtb:
834 case Hexagon::SA1_zxth:
835 case Hexagon::SL1_loadri_io:
836 case Hexagon::SL1_loadrub_io:
837 case Hexagon::SL2_deallocframe:
838 case Hexagon::SL2_jumpr31:
839 case Hexagon::SL2_jumpr31_f:
840 case Hexagon::SL2_jumpr31_fnew:
841 case Hexagon::SL2_jumpr31_t:
842 case Hexagon::SL2_jumpr31_tnew:
843 case Hexagon::SL2_loadrb_io:
844 case Hexagon::SL2_loadrd_sp:
845 case Hexagon::SL2_loadrh_io:
846 case Hexagon::SL2_loadri_sp:
847 case Hexagon::SL2_loadruh_io:
848 case Hexagon::SL2_return:
849 case Hexagon::SL2_return_f:
850 case Hexagon::SL2_return_fnew:
851 case Hexagon::SL2_return_t:
852 case Hexagon::SL2_return_tnew:
853 case Hexagon::SS1_storeb_io:
854 case Hexagon::SS1_storew_io:
855 case Hexagon::SS2_allocframe:
856 case Hexagon::SS2_storebi0:
857 case Hexagon::SS2_storebi1:
858 case Hexagon::SS2_stored_sp:
859 case Hexagon::SS2_storeh_io:
860 case Hexagon::SS2_storew_sp:
861 case Hexagon::SS2_storewi0:
862 case Hexagon::SS2_storewi1:
863 return true;
864 }
865}
866
867bool HexagonMCInstrInfo::isVector(MCInstrInfo const &MCII, MCInst const &MCI) {
868 const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
870}
871
872int64_t HexagonMCInstrInfo::minConstant(MCInst const &MCI, size_t Index) {
873 auto Sentinel = static_cast<int64_t>(std::numeric_limits<uint32_t>::max())
874 << 8;
875 if (MCI.size() <= Index)
876 return Sentinel;
877 MCOperand const &MCO = MCI.getOperand(Index);
878 if (!MCO.isExpr())
879 return Sentinel;
880 int64_t Value;
881 if (!MCO.getExpr()->evaluateAsAbsolute(Value))
882 return Sentinel;
883 return Value;
884}
885
886void HexagonMCInstrInfo::setMustExtend(MCExpr const &Expr, bool Val) {
887 HexagonMCExpr &HExpr = const_cast<HexagonMCExpr &>(cast<HexagonMCExpr>(Expr));
888 HExpr.setMustExtend(Val);
889}
890
892 HexagonMCExpr const &HExpr = cast<HexagonMCExpr>(Expr);
893 return HExpr.mustExtend();
894}
895void HexagonMCInstrInfo::setMustNotExtend(MCExpr const &Expr, bool Val) {
896 HexagonMCExpr &HExpr = const_cast<HexagonMCExpr &>(cast<HexagonMCExpr>(Expr));
897 HExpr.setMustNotExtend(Val);
898}
900 HexagonMCExpr const &HExpr = cast<HexagonMCExpr>(Expr);
901 return HExpr.mustNotExtend();
902}
903void HexagonMCInstrInfo::setS27_2_reloc(MCExpr const &Expr, bool Val) {
904 HexagonMCExpr &HExpr =
905 const_cast<HexagonMCExpr &>(*cast<HexagonMCExpr>(&Expr));
906 HExpr.setS27_2_reloc(Val);
907}
909 HexagonMCExpr const *HExpr = dyn_cast<HexagonMCExpr>(&Expr);
910 if (!HExpr)
911 return false;
912 return HExpr->s27_2_reloc();
913}
914
916 const bool IsTiny = STI.hasFeature(Hexagon::ProcTinyCore);
917
918 return IsTiny ? (HEXAGON_PACKET_SIZE - 1) : HEXAGON_PACKET_SIZE;
919}
920
923 .Case("hexagonv67t", 3)
924 .Default(4);
925}
926
928 MCInst Nop;
929 Nop.setOpcode(Hexagon::A2_nop);
930 assert(isBundle(MCB));
931 while (LoopNeedsPadding(MCB))
932 MCB.addOperand(MCOperand::createInst(new (Context) MCInst(Nop)));
933}
934
937 if (!isPredicated(MCII, MCI))
938 return {0, 0, false};
939 MCInstrDesc const &Desc = getDesc(MCII, MCI);
940 for (auto I = Desc.getNumDefs(), N = Desc.getNumOperands(); I != N; ++I)
941 if (Desc.operands()[I].RegClass == Hexagon::PredRegsRegClassID)
942 return {MCI.getOperand(I).getReg(), I, isPredicatedTrue(MCII, MCI)};
943 return {0, 0, false};
944}
945
947 MCInst const &MCI) {
948 const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
950}
951
952bool HexagonMCInstrInfo::hasTmpDst(MCInstrInfo const &MCII, MCInst const &MCI) {
953 switch (MCI.getOpcode()) {
954 default:
955 return false;
956 case Hexagon::V6_vgathermh:
957 case Hexagon::V6_vgathermhq:
958 case Hexagon::V6_vgathermhw:
959 case Hexagon::V6_vgathermhwq:
960 case Hexagon::V6_vgathermw:
961 case Hexagon::V6_vgathermwq:
962 return true;
963 }
964 return false;
965}
966
967bool HexagonMCInstrInfo::hasHvxTmp(MCInstrInfo const &MCII, MCInst const &MCI) {
968 const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
970}
971
973 MCInst const &MCI) {
974 const unsigned OpCode = MCI.getOpcode();
975 const bool IsTiny = STI.getFeatureBits() [Hexagon::ProcTinyCore];
976 const bool NoSlotReqd = Hexagon::A4_ext == OpCode ||
977 (IsTiny && Hexagon::A2_nop == OpCode) ||
978 (IsTiny && Hexagon::J4_hintjumpr == OpCode);
979
980 return !NoSlotReqd;
981}
982
984 MCSubtargetInfo const &STI,
985 MCInst const &MCI) {
986 unsigned slotsUsed = 0;
987 for (auto HMI : bundleInstructions(MCI)) {
988 MCInst const &MCI = *HMI.getInst();
989 if (!requiresSlot(STI, MCI))
990 continue;
991 if (isDuplex(MCII, MCI))
992 slotsUsed += 2;
993 else
994 ++slotsUsed;
995 }
996 return slotsUsed;
997}
998
1000 DuplexCandidate Candidate) {
1001 assert(Candidate.packetIndexI < MCB.size());
1002 assert(Candidate.packetIndexJ < MCB.size());
1003 assert(isBundle(MCB));
1004 MCInst *Duplex =
1005 deriveDuplex(Context, Candidate.iClass,
1006 *MCB.getOperand(Candidate.packetIndexJ).getInst(),
1007 *MCB.getOperand(Candidate.packetIndexI).getInst());
1008 assert(Duplex != nullptr);
1009 MCB.getOperand(Candidate.packetIndexI).setInst(Duplex);
1010 MCB.erase(MCB.begin() + Candidate.packetIndexJ);
1011}
1012
1014 assert(isBundle(MCI));
1015 MCOperand &Operand = MCI.getOperand(0);
1016 Operand.setImm(Operand.getImm() | innerLoopMask);
1017}
1018
1020 assert(isBundle(MCI));
1021 MCOperand &Operand = MCI.getOperand(0);
1022 Operand.setImm(Operand.getImm() | memReorderDisabledMask);
1024}
1025
1027 assert(isBundle(MCI));
1028 MCOperand &Operand = MCI.getOperand(0);
1029 Operand.setImm(Operand.getImm() | outerLoopMask);
1030}
1031
1033 MCRegister Producer,
1034 MCRegister Producer2) {
1035 // If we're a single vector consumer of a double producer, set subreg bit
1036 // based on if we're accessing the lower or upper register component
1037 if (IsVecRegPair(Producer) && IsVecRegSingle(Consumer)) {
1038 unsigned Rev = IsReverseVecRegPair(Producer);
1039 return ((Consumer - Hexagon::V0) & 0x1) ^ Rev;
1040 }
1041 if (Producer2 != Hexagon::NoRegister)
1042 return Consumer == Producer;
1043 return 0;
1044}
1045
1053
1055 MCSubtargetInfo const &STI,
1056 MCInst const &I) {
1059 return (Desc.isBranch() || Desc.isCall() || Desc.isReturn());
1060}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define Check(C,...)
#define HEXAGON_PACKET_OUTER_SIZE
#define HEXAGON_PACKET_INNER_SIZE
#define HEXAGON_PACKET_SIZE
#define HEXAGON_PRESHUFFLE_PACKET_SIZE
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define R4(n)
#define R2(n)
#define R6(n)
uint64_t IntrinsicInst * II
static bool isBranch(unsigned Opcode)
MachineRegisterInfo & MRI
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static SymbolRef::Type getType(const Symbol *Sym)
Definition TapiFile.cpp:39
Check for a valid bundle.
void setMustNotExtend(bool Val=true)
bool mustNotExtend() const
bool mustExtend() const
bool s27_2_reloc() const
void setMustExtend(bool Val=true)
void setS27_2_reloc(bool Val=true)
bool operator==(PacketIterator const &Other) const
PacketIterator(MCInstrInfo const &MCII, MCInst const &Inst)
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition MCExpr.cpp:212
Context object for machine code objects.
Definition MCContext.h:83
Base class for the full range of assembler expressions which are needed for parsing.
Definition MCExpr.h:34
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
void erase(iterator I)
Definition MCInst.h:224
SMLoc getLoc() const
Definition MCInst.h:208
void setLoc(SMLoc loc)
Definition MCInst.h:207
unsigned getOpcode() const
Definition MCInst.h:202
void addOperand(const MCOperand Op)
Definition MCInst.h:215
iterator begin()
Definition MCInst.h:227
iterator end()
Definition MCInst.h:229
size_t size() const
Definition MCInst.h:226
void setOpcode(unsigned Op)
Definition MCInst.h:201
const MCOperand & getOperand(unsigned i) const
Definition MCInst.h:210
Describe properties that are true of each instruction in the target description file.
unsigned getSchedClass() const
Return the scheduling class for this instruction.
bool isPseudo() const
Return true if this is a pseudo instruction that doesn't correspond to a real machine instruction.
Interface to description of machine instruction set.
Definition MCInstrInfo.h:27
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
Definition MCInstrInfo.h:89
StringRef getName(unsigned Opcode) const
Returns the name for the instructions with the given opcode.
Definition MCInstrInfo.h:96
Instances of this class represent operands of the MCInst class.
Definition MCInst.h:40
void setImm(int64_t Val)
Definition MCInst.h:89
static MCOperand createExpr(const MCExpr *Val)
Definition MCInst.h:166
int64_t getImm() const
Definition MCInst.h:84
static MCOperand createReg(MCRegister Reg)
Definition MCInst.h:138
static MCOperand createImm(int64_t Val)
Definition MCInst.h:145
bool isImm() const
Definition MCInst.h:66
bool isReg() const
Definition MCInst.h:65
void setInst(const MCInst *Val)
Definition MCInst.h:133
MCRegister getReg() const
Returns the register number.
Definition MCInst.h:73
const MCInst * getInst() const
Definition MCInst.h:128
const MCExpr * getExpr() const
Definition MCInst.h:118
bool isExpr() const
Definition MCInst.h:69
static MCOperand createInst(const MCInst *Val)
Definition MCInst.h:173
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
const FeatureBitset & getFeatureBits() const
const MCSchedModel & getSchedModel() const
Get the machine model for this subtarget's CPU.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
LLVM Value Representation.
Definition Value.h:75
A range adaptor for a pair of iterators.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned const TypeCVI_LAST
static unsigned getMemAccessSizeInBytes(MemAccessSize S)
unsigned const TypeCVI_FIRST
std::pair< unsigned, unsigned > GetVecRegPairIndices(MCRegister VecRegPair)
Returns an ordered pair of the constituent register ordinals for each of the elements of VecRegPair.
bool isExtentSigned(MCInstrInfo const &MCII, MCInst const &MCI)
MCInst deriveSubInst(MCInst const &Inst)
bool hasHvxTmp(MCInstrInfo const &MCII, MCInst const &MCI)
bool isRestrictSlot1AOK(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn can be packaged only with an A-type insn in slot #1.
bool isConstExtended(MCInstrInfo const &MCII, MCInst const &MCI)
bool isIntReg(MCRegister Reg)
void addConstant(MCInst &MI, uint64_t Value, MCContext &Context)
unsigned getMemAccessSize(MCInstrInfo const &MCII, MCInst const &MCI)
bool isSolo(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn is solo, i.e., cannot be in a packet.
SmallVector< DuplexCandidate, 8 > getDuplexPossibilties(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst const &MCB)
bool isPredicatedNew(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn is newly predicated.
bool IsReverseVecRegPair(MCRegister VecReg)
bool isOuterLoop(MCInst const &MCI)
MCInst * deriveDuplex(MCContext &Context, unsigned iClass, MCInst const &inst0, MCInst const &inst1)
unsigned getAddrMode(MCInstrInfo const &MCII, MCInst const &MCI)
size_t bundleSize(MCInst const &MCI)
bool IsABranchingInst(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst const &I)
bool isDuplex(MCInstrInfo const &MCII, MCInst const &MCI)
unsigned getCVIResources(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst const &MCI)
Return the resources used by this instruction.
void padEndloop(MCInst &MCI, MCContext &Context)
constexpr int64_t memReorderDisabledMask
bool isPrefix(MCInstrInfo const &MCII, MCInst const &MCI)
bool IsSingleConsumerRefPairProducer(MCRegister Producer, MCRegister Consumer)
bool isPredicateLate(MCInstrInfo const &MCII, MCInst const &MCI)
void setS27_2_reloc(MCExpr const &Expr, bool Val=true)
unsigned getExtentBits(MCInstrInfo const &MCII, MCInst const &MCI)
unsigned short getNewValueOp2(MCInstrInfo const &MCII, MCInst const &MCI)
Return the new value or the newly produced value.
bool isSoloAX(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn can be packaged only with A and X-type insns.
bool isNewValue(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn expects newly produced value.
unsigned short getNewValueOp(MCInstrInfo const &MCII, MCInst const &MCI)
bool isHVX(MCInstrInfo const &MCII, MCInst const &MCI)
bool isMemReorderDisabled(MCInst const &MCI)
unsigned short getExtendableOp(MCInstrInfo const &MCII, MCInst const &MCI)
bool isCompound(MCInstrInfo const &MCII, MCInst const &MCI)
bool IsVecRegPair(MCRegister VecReg)
bool mustNotExtend(MCExpr const &Expr)
bool isNewValueStore(MCInstrInfo const &MCII, MCInst const &MCI)
Return true if the operand is a new-value store insn.
MCInstrDesc const & getDesc(MCInstrInfo const &MCII, MCInst const &MCI)
iterator_range< Hexagon::PacketIterator > bundleInstructions(MCInstrInfo const &MCII, MCInst const &MCI)
bool IsVecRegSingle(MCRegister VecReg)
bool LoopNeedsPadding(MCInst const &MCB)
void tryCompound(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCContext &Context, MCInst &MCI)
tryCompound - Given a bundle check for compound insns when one is found update the contents of the bu...
void setMemReorderDisabled(MCInst &MCI)
bool isBundle(MCInst const &MCI)
int64_t minConstant(MCInst const &MCI, size_t Index)
bool isCofRelax1(MCInstrInfo const &MCII, MCInst const &MCI)
bool isDblRegForSubInst(MCRegister Reg)
MCExpr const & getExpr(MCExpr const &Expr)
bool isOpExtendable(MCInstrInfo const &MCII, MCInst const &MCI, unsigned short)
Return whether the operand is extendable.
int getMinValue(MCInstrInfo const &MCII, MCInst const &MCI)
Return the minimum value of an extendable operand.
bool prefersSlot3(MCInstrInfo const &MCII, MCInst const &MCI)
bool hasDuplex(MCInstrInfo const &MCII, MCInst const &MCI)
bool isExtendable(MCInstrInfo const &MCII, MCInst const &MCI)
bool isIntRegForSubInst(MCRegister Reg)
unsigned getUnits(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst const &MCI)
Return the slots used by the insn.
MCInst const * extenderForIndex(MCInst const &MCB, size_t Index)
unsigned getType(MCInstrInfo const &MCII, MCInst const &MCI)
Return the Hexagon ISA class for the insn.
bool isImmext(MCInst const &MCI)
void addConstExtender(MCContext &Context, MCInstrInfo const &MCII, MCInst &MCB, MCInst const &MCI)
MCOperand const & getNewValueOperand(MCInstrInfo const &MCII, MCInst const &MCI)
bool isPredRegister(MCInstrInfo const &MCII, MCInst const &Inst, unsigned I)
bool isPredicated(MCInstrInfo const &MCII, MCInst const &MCI)
constexpr int64_t innerLoopMask
bool isCofMax1(MCInstrInfo const &MCII, MCInst const &MCI)
unsigned SubregisterBit(MCRegister Consumer, MCRegister Producer, MCRegister Producer2)
constexpr size_t bundleInstructionsOffset
bool s27_2_reloc(MCExpr const &Expr)
bool hasImmExt(MCInst const &MCI)
bool isInnerLoop(MCInst const &MCI)
bool hasNewValue2(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn produces a second value.
PredicateInfo predicateInfo(MCInstrInfo const &MCII, MCInst const &MCI)
bool canonicalizePacket(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCContext &Context, MCInst &MCB, HexagonMCChecker *Checker, bool AttemptCompatibility=false)
unsigned getOtherReservedSlots(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst const &MCI)
Return the slots this instruction consumes in addition to the slot(s) it can execute out of.
bool isCanon(MCInstrInfo const &MCII, MCInst const &MCI)
unsigned slotsConsumed(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst const &MCI)
int getMaxValue(MCInstrInfo const &MCII, MCInst const &MCI)
Return the maximum value of an extendable operand.
void replaceDuplex(MCContext &Context, MCInst &MCI, DuplexCandidate Candidate)
void setMustNotExtend(MCExpr const &Expr, bool Val=true)
bool requiresSlot(MCSubtargetInfo const &STI, MCInst const &MCI)
unsigned getExtentAlignment(MCInstrInfo const &MCII, MCInst const &MCI)
void extendIfNeeded(MCContext &Context, MCInstrInfo const &MCII, MCInst &MCB, MCInst const &MCI)
bool hasTmpDst(MCInstrInfo const &MCII, MCInst const &MCI)
StringRef getName(MCInstrInfo const &MCII, MCInst const &MCI)
unsigned packetSizeSlots(MCSubtargetInfo const &STI)
bool isPredReg(MCRegisterInfo const &MRI, MCRegister Reg)
bool isPredicatedTrue(MCInstrInfo const &MCII, MCInst const &MCI)
bool hasExtenderForIndex(MCInst const &MCB, size_t Index)
bool isRestrictNoSlot1Store(MCInstrInfo const &MCII, MCInst const &MCI)
constexpr int64_t outerLoopMask
MCInst const & instruction(MCInst const &MCB, size_t Index)
bool isAccumulator(MCInstrInfo const &MCII, MCInst const &MCI)
Return where the instruction is an accumulator.
bool mustExtend(MCExpr const &Expr)
bool isVector(MCInstrInfo const &MCII, MCInst const &MCI)
MCOperand const & getExtendableOperand(MCInstrInfo const &MCII, MCInst const &MCI)
bool isSubInstruction(MCInst const &MCI)
MCOperand const & getNewValueOperand2(MCInstrInfo const &MCII, MCInst const &MCI)
void setMustExtend(MCExpr const &Expr, bool Val=true)
unsigned getDuplexRegisterNumbering(MCRegister Reg)
bool isExtended(MCInstrInfo const &MCII, MCInst const &MCI)
bool isCVINew(MCInstrInfo const &MCII, MCInst const &MCI)
bool isFloat(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether it is a floating-point insn.
bool hasNewValue(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn produces a value.
unsigned packetSize(StringRef CPU)
bool isCofRelax2(MCInstrInfo const &MCII, MCInst const &MCI)
MCInst deriveExtender(MCInstrInfo const &MCII, MCInst const &Inst, MCOperand const &MO)
MCSubtargetInfo const * getArchSubtarget(MCSubtargetInfo const *STI)
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:316
cl::opt< bool > HexagonDisableCompound
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
bool HexagonMCShuffle(MCContext &Context, bool ReportErrors, MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst &MCB)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Op::Description Desc
unsigned HexagonGetLastSlot()
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
@ Other
Any other memory.
Definition ModRef.h:68
const InstrStage HexagonStages[]
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
#define N
An itinerary represents the scheduling information for an instruction.
const InstrItinerary * InstrItineraries
Definition MCSchedule.h:347