LLVM 22.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
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 MCInst OrigMCB = MCB;
133
134 // Examine the packet and convert pairs of instructions to compound
135 // instructions when possible.
137 HexagonMCInstrInfo::tryCompound(MCII, STI, Context, MCB);
138 HexagonMCShuffle(Context, false, MCII, STI, MCB);
139
140 const SmallVector<DuplexCandidate, 8> possibleDuplexes =
141 (STI.hasFeature(Hexagon::FeatureDuplex))
144
145 // Examine the packet and convert pairs of instructions to duplex
146 // instructions when possible.
147 HexagonMCShuffle(Context, MCII, STI, MCB, possibleDuplexes);
148
149 // Examines packet and pad the packet, if needed, when an
150 // end-loop is in the bundle.
151 HexagonMCInstrInfo::padEndloop(MCB, Context);
152
153 // If compounding and duplexing didn't reduce the size below
154 // 4 or less we have a packet that is too big.
156 if (Check)
157 Check->reportError("invalid instruction packet: out of slots");
158 return false;
159 }
160 // Check the bundle for errors.
161 CheckOk = Check ? Check->check(true) : true;
162 if (!CheckOk)
163 return false;
164
165 HexagonMCShuffle(Context, true, MCII, STI, MCB);
166
167 return true;
168}
169} // namespace
170
172 MCSubtargetInfo const &STI,
173 MCContext &Context, MCInst &MCB,
175 bool AttemptCompatibility) {
176 auto ArchSTI = Hexagon_MC::getArchSubtarget(&STI);
177 if (!AttemptCompatibility || ArchSTI == nullptr)
178 return canonicalizePacketImpl(MCII, STI, Context, MCB, Check);
179
180 const MCRegisterInfo *RI = Context.getRegisterInfo();
181 HexagonMCChecker DefaultCheck(Context, MCII, STI, MCB, *RI, false);
182 HexagonMCChecker *BaseCheck = (Check == nullptr) ? &DefaultCheck : Check;
183 HexagonMCChecker PerfCheck(*BaseCheck, STI, false);
184 if (canonicalizePacketImpl(MCII, STI, Context, MCB, &PerfCheck))
185 return true;
186
187 HexagonMCChecker ArchCheck(*BaseCheck, *ArchSTI, true);
188 return canonicalizePacketImpl(MCII, *ArchSTI, Context, MCB, &ArchCheck);
189}
190
192 MCInst const &Inst,
193 MCOperand const &MO) {
196
197 MCInst XMI;
198 XMI.setOpcode(Hexagon::A4_ext);
199 if (MO.isImm())
200 XMI.addOperand(MCOperand::createImm(MO.getImm() & (~0x3f)));
201 else if (MO.isExpr())
203 else
204 llvm_unreachable("invalid extendable operand");
205 return XMI;
206}
207
209 MCInst const &inst0,
210 MCInst const &inst1) {
211 assert((iClass <= 0xf) && "iClass must have range of 0 to 0xf");
212 MCInst *duplexInst = new (Context) MCInst;
213 duplexInst->setOpcode(Hexagon::DuplexIClass0 + iClass);
214
215 MCInst *SubInst0 = new (Context) MCInst(deriveSubInst(inst0));
216 MCInst *SubInst1 = new (Context) MCInst(deriveSubInst(inst1));
217 duplexInst->addOperand(MCOperand::createInst(SubInst0));
218 duplexInst->addOperand(MCOperand::createInst(SubInst1));
219 return duplexInst;
220}
221
223 size_t Index) {
224 assert(Index <= bundleSize(MCB));
225 if (Index == 0)
226 return nullptr;
227 MCInst const *Inst =
229 if (isImmext(*Inst))
230 return Inst;
231 return nullptr;
232}
233
235 MCInstrInfo const &MCII, MCInst &MCB,
236 MCInst const &MCI) {
237 if (isConstExtended(MCII, MCI))
238 addConstExtender(Context, MCII, MCB, MCI);
239}
240
247
249 MCInst const &MCI) {
251 return static_cast<unsigned>((F >> HexagonII::AddrModePos) &
253}
254
256 MCInst const &MCI) {
257 return MCII.get(MCI.getOpcode());
258}
259
261 using namespace Hexagon;
262
263 switch (Reg.id()) {
264 default:
265 llvm_unreachable("unknown duplex register");
266 // Rs Rss
267 case R0:
268 case D0:
269 return 0;
270 case R1:
271 case D1:
272 return 1;
273 case R2:
274 case D2:
275 return 2;
276 case R3:
277 case D3:
278 return 3;
279 case R4:
280 case D8:
281 return 4;
282 case R5:
283 case D9:
284 return 5;
285 case R6:
286 case D10:
287 return 6;
288 case R7:
289 case D11:
290 return 7;
291 case R16:
292 return 8;
293 case R17:
294 return 9;
295 case R18:
296 return 10;
297 case R19:
298 return 11;
299 case R20:
300 return 12;
301 case R21:
302 return 13;
303 case R22:
304 return 14;
305 case R23:
306 return 15;
307 }
308}
309
311 const auto &HExpr = cast<HexagonMCExpr>(Expr);
312 assert(HExpr.getExpr());
313 return *HExpr.getExpr();
314}
315
317 MCInst const &MCI) {
320}
321
322MCOperand const &
324 MCInst const &MCI) {
325 unsigned O = HexagonMCInstrInfo::getExtendableOp(MCII, MCI);
326 MCOperand const &MO = MCI.getOperand(O);
327
329 HexagonMCInstrInfo::isExtended(MCII, MCI)) &&
330 (MO.isImm() || MO.isExpr()));
331 return (MO);
332}
333
339
341 MCInst const &MCI) {
344}
345
351
352/// Return the maximum value of an extendable operand.
354 MCInst const &MCI) {
357
358 if (HexagonMCInstrInfo::isExtentSigned(MCII, MCI)) // if value is signed
359 return (1 << (HexagonMCInstrInfo::getExtentBits(MCII, MCI) - 1)) - 1;
360 return (1 << HexagonMCInstrInfo::getExtentBits(MCII, MCI)) - 1;
361}
362
363/// Return the minimum value of an extendable operand.
365 MCInst const &MCI) {
368
369 if (HexagonMCInstrInfo::isExtentSigned(MCII, MCI)) // if value is signed
370 return -(1 << (HexagonMCInstrInfo::getExtentBits(MCII, MCI) - 1));
371 return 0;
372}
373
375 MCInst const &MCI) {
376 return MCII.getName(MCI.getOpcode());
377}
378
380 MCInst const &MCI) {
383}
384
386 MCInst const &MCI) {
387 if (HexagonMCInstrInfo::hasTmpDst(MCII, MCI)) {
388 // VTMP doesn't actually exist in the encodings for these 184
389 // 3 instructions so go ahead and create it here.
390 static MCOperand MCO = MCOperand::createReg(Hexagon::VTMP);
391 return (MCO);
392 } else {
393 unsigned O = HexagonMCInstrInfo::getNewValueOp(MCII, MCI);
394 MCOperand const &MCO = MCI.getOperand(O);
395
398 MCO.isReg());
399 return (MCO);
400 }
401}
402
403/// Return the new value or the newly produced value.
405 MCInst const &MCI) {
408}
409
410MCOperand const &
412 MCInst const &MCI) {
413 unsigned O = HexagonMCInstrInfo::getNewValueOp2(MCII, MCI);
414 MCOperand const &MCO = MCI.getOperand(O);
415
418 MCO.isReg());
419 return (MCO);
420}
421
422/// Return the Hexagon ISA class for the insn.
424 MCInst const &MCI) {
425 const uint64_t F = MCII.get(MCI.getOpcode()).TSFlags;
427}
428
429/// Return the resources used by this instruction
431 MCSubtargetInfo const &STI,
432 MCInst const &MCI) {
433
435 int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass();
436 int Size = II[SchedClass].LastStage - II[SchedClass].FirstStage;
437
438 // HVX resources used are currently located at the second to last stage.
439 // This could also be done with a linear search of the stages looking for:
440 // CVI_ALL, CVI_MPY01, CVI_XLSHF, CVI_MPY0, CVI_MPY1, CVI_SHIFT, CVI_XLANE,
441 // CVI_ZW
442 unsigned Stage = II[SchedClass].LastStage - 1;
443
444 if (Size < 2)
445 return 0;
446 return ((Stage + HexagonStages)->getUnits());
447}
448
449/// Return the slots this instruction can execute out of
451 MCSubtargetInfo const &STI,
452 MCInst const &MCI) {
454 int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass();
455 return ((II[SchedClass].FirstStage + HexagonStages)->getUnits());
456}
457
458/// Return the slots this instruction consumes in addition to
459/// the slot(s) it can execute out of
460
462 MCSubtargetInfo const &STI,
463 MCInst const &MCI) {
465 int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass();
466 unsigned Slots = 0;
467
468 // FirstStage are slots that this instruction can execute in.
469 // FirstStage+1 are slots that are also consumed by this instruction.
470 // For example: vmemu can only execute in slot 0 but also consumes slot 1.
471 for (unsigned Stage = II[SchedClass].FirstStage + 1;
472 Stage < II[SchedClass].LastStage; ++Stage) {
473 unsigned Units = (Stage + HexagonStages)->getUnits();
474 if (Units > HexagonGetLastSlot())
475 break;
476 // fyi: getUnits() will return 0x1, 0x2, 0x4 or 0x8
477 Slots |= Units;
478 }
479
480 // if 0 is returned, then no additional slots are consumed by this inst.
481 return Slots;
482}
483
484bool HexagonMCInstrInfo::hasDuplex(MCInstrInfo const &MCII, MCInst const &MCI) {
486 return false;
487
488 for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCI)) {
489 if (HexagonMCInstrInfo::isDuplex(MCII, *I.getInst()))
490 return true;
491 }
492
493 return false;
494}
495
496bool HexagonMCInstrInfo::hasExtenderForIndex(MCInst const &MCB, size_t Index) {
497 return extenderForIndex(MCB, Index) != nullptr;
498}
499
502 return false;
503
504 for (const auto &I : HexagonMCInstrInfo::bundleInstructions(MCI)) {
505 if (isImmext(*I.getInst()))
506 return true;
507 }
508
509 return false;
510}
511
512/// Return whether the insn produces a value.
518
519/// Return whether the insn produces a second value.
525
526MCInst const &HexagonMCInstrInfo::instruction(MCInst const &MCB, size_t Index) {
527 assert(isBundle(MCB));
529 return *MCB.getOperand(bundleInstructionsOffset + Index).getInst();
530}
531
532/// Return where the instruction is an accumulator.
538
540 auto Result = Hexagon::BUNDLE == MCI.getOpcode();
541 assert(!Result || (MCI.size() > 0 && MCI.getOperand(0).isImm()));
542 return Result;
543}
544
546 MCInst const &MCI) {
547 if (HexagonMCInstrInfo::isExtended(MCII, MCI))
548 return true;
549 if (!HexagonMCInstrInfo::isExtendable(MCII, MCI))
550 return false;
552 if (isa<HexagonMCExpr>(MO.getExpr()) &&
554 return true;
555 // Branch insns are handled as necessary by relaxation.
556 if ((HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeJ) ||
561 return false;
562 // Otherwise loop instructions and other CR insts are handled by relaxation
563 else if ((HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCR) &&
564 (MCI.getOpcode() != Hexagon::C4_addipc))
565 return false;
566
567 assert(!MO.isImm());
568 if (isa<HexagonMCExpr>(MO.getExpr()) &&
570 return false;
571
572 int64_t Value;
573 if (!MO.getExpr()->evaluateAsAbsolute(Value))
574 return true;
575 if (HexagonMCInstrInfo::isExtentSigned(MCII, MCI)) {
576 int32_t SValue = Value;
577 int32_t MinValue = HexagonMCInstrInfo::getMinValue(MCII, MCI);
578 int32_t MaxValue = HexagonMCInstrInfo::getMaxValue(MCII, MCI);
579 return SValue < MinValue || SValue > MaxValue;
580 }
581 uint32_t UValue = Value;
582 uint32_t MinValue = HexagonMCInstrInfo::getMinValue(MCII, MCI);
583 uint32_t MaxValue = HexagonMCInstrInfo::getMaxValue(MCII, MCI);
584 return UValue < MinValue || UValue > MaxValue;
585}
586
587bool HexagonMCInstrInfo::isCanon(MCInstrInfo const &MCII, MCInst const &MCI) {
588 return !HexagonMCInstrInfo::getDesc(MCII, MCI).isPseudo() &&
590}
591
592bool HexagonMCInstrInfo::isCofMax1(MCInstrInfo const &MCII, MCInst const &MCI) {
595}
596
598 MCInst const &MCI) {
601}
602
604 MCInst const &MCI) {
607}
608
610 MCInst const &MCI) {
611 return (getType(MCII, MCI) == HexagonII::TypeCJ);
612}
613
614bool HexagonMCInstrInfo::isCVINew(MCInstrInfo const &MCII, MCInst const &MCI) {
617}
618
620 return ((Reg >= Hexagon::D0 && Reg <= Hexagon::D3) ||
621 (Reg >= Hexagon::D8 && Reg <= Hexagon::D11));
622}
623
624bool HexagonMCInstrInfo::isDuplex(MCInstrInfo const &MCII, MCInst const &MCI) {
626}
627
633
635 MCInst const &MCI) {
638}
639
640bool HexagonMCInstrInfo::isFloat(MCInstrInfo const &MCII, MCInst const &MCI) {
642 return ((F >> HexagonII::FPPos) & HexagonII::FPMask);
643}
644
645bool HexagonMCInstrInfo::isHVX(MCInstrInfo const &MCII, MCInst const &MCI) {
646 const uint64_t V = getType(MCII, MCI);
648}
649
651 return MCI.getOpcode() == Hexagon::A4_ext;
652}
653
655 assert(isBundle(MCI));
656 int64_t Flags = MCI.getOperand(0).getImm();
657 return (Flags & innerLoopMask) != 0;
658}
659
661 return (Reg >= Hexagon::R0 && Reg <= Hexagon::R31);
662}
663
665 return ((Reg >= Hexagon::R0 && Reg <= Hexagon::R7) ||
666 (Reg >= Hexagon::R16 && Reg <= Hexagon::R23));
667}
668
669/// Return whether the insn expects newly produced value.
671 MCInst const &MCI) {
674}
675
681
682/// Return whether the operand is extendable.
684 MCInst const &MCI, unsigned short O) {
685 return (O == HexagonMCInstrInfo::getExtendableOp(MCII, MCI));
686}
687
689 assert(isBundle(MCI));
690 int64_t Flags = MCI.getOperand(0).getImm();
691 return (Flags & outerLoopMask) != 0;
692}
693
695 return (VecReg >= Hexagon::W0 && VecReg <= Hexagon::W15) ||
696 (VecReg >= Hexagon::WR0 && VecReg <= Hexagon::WR15);
697}
698
700 return (VecReg >= Hexagon::WR0 && VecReg <= Hexagon::WR15);
701}
702
704 return (VecReg >= Hexagon::V0 && VecReg <= Hexagon::V31);
705}
706
707std::pair<unsigned, unsigned>
709 assert(IsVecRegPair(VecRegPair) &&
710 "VecRegPair must be a vector register pair");
711
712 const bool IsRev = IsReverseVecRegPair(VecRegPair);
713 const unsigned PairIndex =
714 2 * (IsRev ? VecRegPair - Hexagon::WR0 : VecRegPair - Hexagon::W0);
715
716 return IsRev ? std::make_pair(PairIndex, PairIndex + 1)
717 : std::make_pair(PairIndex + 1, PairIndex);
718}
719
721 MCRegister Consumer) {
722 if (IsVecRegPair(Producer) && IsVecRegSingle(Consumer)) {
723 const unsigned ProdPairIndex = IsReverseVecRegPair(Producer)
724 ? Producer - Hexagon::WR0
725 : Producer - Hexagon::W0;
726 const unsigned ConsumerSingleIndex = (Consumer - Hexagon::V0) >> 1;
727
728 return ConsumerSingleIndex == ProdPairIndex;
729 }
730 return false;
731}
732
738
739bool HexagonMCInstrInfo::isPrefix(MCInstrInfo const &MCII, MCInst const &MCI) {
741}
742
748
749/// Return whether the insn is newly predicated.
755
762
764 auto &PredRegClass = MRI.getRegClass(Hexagon::PredRegsRegClassID);
765 return PredRegClass.contains(Reg);
766}
767
769 MCInst const &Inst, unsigned I) {
770 MCInstrDesc const &Desc = HexagonMCInstrInfo::getDesc(MCII, Inst);
771
772 return Inst.getOperand(I).isReg() &&
773 Desc.operands()[I].RegClass == Hexagon::PredRegsRegClassID;
774}
775
776/// Return whether the insn can be packaged only with A and X-type insns.
777bool HexagonMCInstrInfo::isSoloAX(MCInstrInfo const &MCII, MCInst const &MCI) {
780}
781
782/// Return whether the insn can be packaged only with an A-type insn in slot #1.
789
796
797/// Return whether the insn is solo, i.e., cannot be in a packet.
798bool HexagonMCInstrInfo::isSolo(MCInstrInfo const &MCII, MCInst const &MCI) {
799 const uint64_t F = MCII.get(MCI.getOpcode()).TSFlags;
801}
802
804 assert(isBundle(MCI));
805 auto Flags = MCI.getOperand(0).getImm();
806 return (Flags & memReorderDisabledMask) != 0;
807}
808
810 switch (MCI.getOpcode()) {
811 default:
812 return false;
813 case Hexagon::SA1_addi:
814 case Hexagon::SA1_addrx:
815 case Hexagon::SA1_addsp:
816 case Hexagon::SA1_and1:
817 case Hexagon::SA1_clrf:
818 case Hexagon::SA1_clrfnew:
819 case Hexagon::SA1_clrt:
820 case Hexagon::SA1_clrtnew:
821 case Hexagon::SA1_cmpeqi:
822 case Hexagon::SA1_combine0i:
823 case Hexagon::SA1_combine1i:
824 case Hexagon::SA1_combine2i:
825 case Hexagon::SA1_combine3i:
826 case Hexagon::SA1_combinerz:
827 case Hexagon::SA1_combinezr:
828 case Hexagon::SA1_dec:
829 case Hexagon::SA1_inc:
830 case Hexagon::SA1_seti:
831 case Hexagon::SA1_setin1:
832 case Hexagon::SA1_sxtb:
833 case Hexagon::SA1_sxth:
834 case Hexagon::SA1_tfr:
835 case Hexagon::SA1_zxtb:
836 case Hexagon::SA1_zxth:
837 case Hexagon::SL1_loadri_io:
838 case Hexagon::SL1_loadrub_io:
839 case Hexagon::SL2_deallocframe:
840 case Hexagon::SL2_jumpr31:
841 case Hexagon::SL2_jumpr31_f:
842 case Hexagon::SL2_jumpr31_fnew:
843 case Hexagon::SL2_jumpr31_t:
844 case Hexagon::SL2_jumpr31_tnew:
845 case Hexagon::SL2_loadrb_io:
846 case Hexagon::SL2_loadrd_sp:
847 case Hexagon::SL2_loadrh_io:
848 case Hexagon::SL2_loadri_sp:
849 case Hexagon::SL2_loadruh_io:
850 case Hexagon::SL2_return:
851 case Hexagon::SL2_return_f:
852 case Hexagon::SL2_return_fnew:
853 case Hexagon::SL2_return_t:
854 case Hexagon::SL2_return_tnew:
855 case Hexagon::SS1_storeb_io:
856 case Hexagon::SS1_storew_io:
857 case Hexagon::SS2_allocframe:
858 case Hexagon::SS2_storebi0:
859 case Hexagon::SS2_storebi1:
860 case Hexagon::SS2_stored_sp:
861 case Hexagon::SS2_storeh_io:
862 case Hexagon::SS2_storew_sp:
863 case Hexagon::SS2_storewi0:
864 case Hexagon::SS2_storewi1:
865 return true;
866 }
867}
868
869bool HexagonMCInstrInfo::isVector(MCInstrInfo const &MCII, MCInst const &MCI) {
872}
873
874int64_t HexagonMCInstrInfo::minConstant(MCInst const &MCI, size_t Index) {
875 auto Sentinel = static_cast<int64_t>(std::numeric_limits<uint32_t>::max())
876 << 8;
877 if (MCI.size() <= Index)
878 return Sentinel;
879 MCOperand const &MCO = MCI.getOperand(Index);
880 if (!MCO.isExpr())
881 return Sentinel;
882 int64_t Value;
883 if (!MCO.getExpr()->evaluateAsAbsolute(Value))
884 return Sentinel;
885 return Value;
886}
887
888void HexagonMCInstrInfo::setMustExtend(MCExpr const &Expr, bool Val) {
889 HexagonMCExpr &HExpr = const_cast<HexagonMCExpr &>(cast<HexagonMCExpr>(Expr));
890 HExpr.setMustExtend(Val);
891}
892
894 HexagonMCExpr const &HExpr = cast<HexagonMCExpr>(Expr);
895 return HExpr.mustExtend();
896}
897void HexagonMCInstrInfo::setMustNotExtend(MCExpr const &Expr, bool Val) {
898 HexagonMCExpr &HExpr = const_cast<HexagonMCExpr &>(cast<HexagonMCExpr>(Expr));
899 HExpr.setMustNotExtend(Val);
900}
902 HexagonMCExpr const &HExpr = cast<HexagonMCExpr>(Expr);
903 return HExpr.mustNotExtend();
904}
905void HexagonMCInstrInfo::setS27_2_reloc(MCExpr const &Expr, bool Val) {
906 HexagonMCExpr &HExpr =
907 const_cast<HexagonMCExpr &>(*cast<HexagonMCExpr>(&Expr));
908 HExpr.setS27_2_reloc(Val);
909}
911 HexagonMCExpr const *HExpr = dyn_cast<HexagonMCExpr>(&Expr);
912 if (!HExpr)
913 return false;
914 return HExpr->s27_2_reloc();
915}
916
918 const bool IsTiny = STI.hasFeature(Hexagon::ProcTinyCore);
919
920 return IsTiny ? (HEXAGON_PACKET_SIZE - 1) : HEXAGON_PACKET_SIZE;
921}
922
925 .Case("hexagonv67t", 3)
926 .Default(4);
927}
928
930 MCInst Nop;
931 Nop.setOpcode(Hexagon::A2_nop);
932 assert(isBundle(MCB));
933 while (LoopNeedsPadding(MCB))
934 MCB.addOperand(MCOperand::createInst(new (Context) MCInst(Nop)));
935}
936
939 if (!isPredicated(MCII, MCI))
940 return {0, 0, false};
941 MCInstrDesc const &Desc = getDesc(MCII, MCI);
942 for (auto I = Desc.getNumDefs(), N = Desc.getNumOperands(); I != N; ++I)
943 if (Desc.operands()[I].RegClass == Hexagon::PredRegsRegClassID)
944 return {MCI.getOperand(I).getReg(), I, isPredicatedTrue(MCII, MCI)};
945 return {0, 0, false};
946}
947
953
954bool HexagonMCInstrInfo::hasTmpDst(MCInstrInfo const &MCII, MCInst const &MCI) {
955 switch (MCI.getOpcode()) {
956 default:
957 return false;
958 case Hexagon::V6_vgathermh:
959 case Hexagon::V6_vgathermhq:
960 case Hexagon::V6_vgathermhw:
961 case Hexagon::V6_vgathermhwq:
962 case Hexagon::V6_vgathermw:
963 case Hexagon::V6_vgathermwq:
964 return true;
965 }
966 return false;
967}
968
973
975 MCInst const &MCI) {
976 const unsigned OpCode = MCI.getOpcode();
977 const bool IsTiny = STI.getFeatureBits() [Hexagon::ProcTinyCore];
978 const bool NoSlotReqd = Hexagon::A4_ext == OpCode ||
979 (IsTiny && Hexagon::A2_nop == OpCode) ||
980 (IsTiny && Hexagon::J4_hintjumpr == OpCode);
981
982 return !NoSlotReqd;
983}
984
986 MCSubtargetInfo const &STI,
987 MCInst const &MCI) {
988 unsigned slotsUsed = 0;
989 for (auto HMI : bundleInstructions(MCI)) {
990 MCInst const &MCI = *HMI.getInst();
991 if (!requiresSlot(STI, MCI))
992 continue;
993 if (isDuplex(MCII, MCI))
994 slotsUsed += 2;
995 else
996 ++slotsUsed;
997 }
998 return slotsUsed;
999}
1000
1002 DuplexCandidate Candidate) {
1003 assert(Candidate.packetIndexI < MCB.size());
1004 assert(Candidate.packetIndexJ < MCB.size());
1005 assert(isBundle(MCB));
1006 MCInst *Duplex =
1007 deriveDuplex(Context, Candidate.iClass,
1008 *MCB.getOperand(Candidate.packetIndexJ).getInst(),
1009 *MCB.getOperand(Candidate.packetIndexI).getInst());
1010 assert(Duplex != nullptr);
1011 MCB.getOperand(Candidate.packetIndexI).setInst(Duplex);
1012 MCB.erase(MCB.begin() + Candidate.packetIndexJ);
1013}
1014
1016 assert(isBundle(MCI));
1017 MCOperand &Operand = MCI.getOperand(0);
1018 Operand.setImm(Operand.getImm() | innerLoopMask);
1019}
1020
1022 assert(isBundle(MCI));
1023 MCOperand &Operand = MCI.getOperand(0);
1024 Operand.setImm(Operand.getImm() | memReorderDisabledMask);
1026}
1027
1029 assert(isBundle(MCI));
1030 MCOperand &Operand = MCI.getOperand(0);
1031 Operand.setImm(Operand.getImm() | outerLoopMask);
1032}
1033
1035 MCRegister Producer,
1036 MCRegister Producer2) {
1037 // If we're a single vector consumer of a double producer, set subreg bit
1038 // based on if we're accessing the lower or upper register component
1039 if (IsVecRegPair(Producer) && IsVecRegSingle(Consumer)) {
1040 unsigned Rev = IsReverseVecRegPair(Producer);
1041 return ((Consumer - Hexagon::V0) & 0x1) ^ Rev;
1042 }
1043 if (Producer2 != Hexagon::NoRegister)
1044 return Consumer == Producer;
1045 return 0;
1046}
1047
1055
1057 MCSubtargetInfo const &STI,
1058 MCInst const &I) {
1061 return (Desc.isBranch() || Desc.isCall() || Desc.isReturn());
1062}
unsigned const MachineRegisterInfo * MRI
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:55
#define I(x, y, z)
Definition MD5.cpp:58
#define R4(n)
#define R2(n)
#define R6(n)
uint64_t IntrinsicInst * II
static bool isBranch(unsigned Opcode)
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:64
StringRef getName(unsigned Opcode) const
Returns the name for the instructions with the given opcode.
Definition MCInstrInfo.h:71
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:33
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.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
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 LLVM_ATTRIBUTE_UNUSED 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:330
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:649
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:548
@ 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:565
#define N
An itinerary represents the scheduling information for an instruction.
const InstrItinerary * InstrItineraries
Definition MCSchedule.h:331