1 //===- HexagonMCInstrInfo.cpp - Hexagon sub-class of MCInst ---------------===//
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
7 //===----------------------------------------------------------------------===//
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"
35 bool HexagonMCInstrInfo::PredicateInfo::isPredicated() const {
36 return Register
!= Hexagon::NoRegister
;
39 Hexagon::PacketIterator::PacketIterator(MCInstrInfo
const &MCII
,
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
) {
53 if (DuplexCurrent
== DuplexEnd
) {
54 DuplexCurrent
= BundleEnd
;
55 DuplexEnd
= BundleEnd
;
61 if (BundleCurrent
!= BundleEnd
) {
62 MCInst
const &Inst
= *BundleCurrent
->getInst();
63 if (HexagonMCInstrInfo::isDuplex(MCII
, Inst
)) {
64 DuplexCurrent
= Inst
.begin();
65 DuplexEnd
= Inst
.end();
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
,
84 MI
.addOperand(MCOperand::createExpr(MCConstantExpr::create(Value
, Context
)));
87 void HexagonMCInstrInfo::addConstExtender(MCContext
&Context
,
88 MCInstrInfo
const &MCII
, MCInst
&MCB
,
90 assert(HexagonMCInstrInfo::isBundle(MCB
));
91 MCOperand
const &exOp
=
92 MCI
.getOperand(HexagonMCInstrInfo::getExtendableOp(MCII
, MCI
));
94 // Create the extender.
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
,
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
);
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;
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
;
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
) {
152 Check
->reportError("invalid instruction packet: out of slots");
155 // Check the bundle for errors.
156 CheckOk
= Check
? Check
->check(true) : true;
159 HexagonMCShuffle(Context
, true, MCII
, STI
, MCB
);
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
))
180 HexagonMCChecker
ArchCheck(*BaseCheck
, *ArchSTI
, true);
181 return canonicalizePacketImpl(MCII
, *ArchSTI
, Context
, MCB
, &ArchCheck
);
184 MCInst
HexagonMCInstrInfo::deriveExtender(MCInstrInfo
const &MCII
,
186 MCOperand
const &MO
) {
187 assert(HexagonMCInstrInfo::isExtendable(MCII
, Inst
) ||
188 HexagonMCInstrInfo::isExtended(MCII
, Inst
));
191 XMI
.setOpcode(Hexagon::A4_ext
);
193 XMI
.addOperand(MCOperand::createImm(MO
.getImm() & (~0x3f)));
194 else if (MO
.isExpr())
195 XMI
.addOperand(MCOperand::createExpr(MO
.getExpr()));
197 llvm_unreachable("invalid extendable operand");
201 MCInst
*HexagonMCInstrInfo::deriveDuplex(MCContext
&Context
, unsigned iClass
,
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
));
215 MCInst
const *HexagonMCInstrInfo::extenderForIndex(MCInst
const &MCB
,
217 assert(Index
<= bundleSize(MCB
));
221 MCB
.getOperand(Index
+ bundleInstructionsOffset
- 1).getInst();
227 void HexagonMCInstrInfo::extendIfNeeded(MCContext
&Context
,
228 MCInstrInfo
const &MCII
, MCInst
&MCB
,
230 if (isConstExtended(MCII
, MCI
))
231 addConstExtender(Context
, MCII
, MCB
, MCI
);
234 unsigned HexagonMCInstrInfo::getMemAccessSize(MCInstrInfo
const &MCII
,
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
,
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
,
250 return MCII
.get(MCI
.getOpcode());
253 unsigned HexagonMCInstrInfo::getDuplexRegisterNumbering(unsigned Reg
) {
254 using namespace Hexagon
;
258 llvm_unreachable("unknown duplex register");
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
,
311 const uint64_t F
= HexagonMCInstrInfo::getDesc(MCII
, MCI
).TSFlags
;
312 return ((F
>> HexagonII::ExtendableOpPos
) & HexagonII::ExtendableOpMask
);
316 HexagonMCInstrInfo::getExtendableOperand(MCInstrInfo
const &MCII
,
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()));
327 unsigned HexagonMCInstrInfo::getExtentAlignment(MCInstrInfo
const &MCII
,
329 const uint64_t F
= HexagonMCInstrInfo::getDesc(MCII
, MCI
).TSFlags
;
330 return ((F
>> HexagonII::ExtentAlignPos
) & HexagonII::ExtentAlignMask
);
333 unsigned HexagonMCInstrInfo::getExtentBits(MCInstrInfo
const &MCII
,
335 const uint64_t F
= HexagonMCInstrInfo::getDesc(MCII
, MCI
).TSFlags
;
336 return ((F
>> HexagonII::ExtentBitsPos
) & HexagonII::ExtentBitsMask
);
339 bool HexagonMCInstrInfo::isExtentSigned(MCInstrInfo
const &MCII
,
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
,
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
,
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));
367 StringRef
HexagonMCInstrInfo::getName(MCInstrInfo
const &MCII
,
369 return MCII
.getName(MCI
.getOpcode());
372 unsigned short HexagonMCInstrInfo::getNewValueOp(MCInstrInfo
const &MCII
,
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
,
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
);
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
)) &&
396 /// Return the new value or the newly produced value.
397 unsigned short HexagonMCInstrInfo::getNewValueOp2(MCInstrInfo
const &MCII
,
399 const uint64_t F
= HexagonMCInstrInfo::getDesc(MCII
, MCI
).TSFlags
;
400 return ((F
>> HexagonII::NewValueOpPos2
) & HexagonII::NewValueOpMask2
);
404 HexagonMCInstrInfo::getNewValueOperand2(MCInstrInfo
const &MCII
,
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
)) &&
415 /// Return the Hexagon ISA class for the insn.
416 unsigned HexagonMCInstrInfo::getType(MCInstrInfo
const &MCII
,
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
,
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,
435 unsigned Stage
= II
[SchedClass
].LastStage
- 1;
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
,
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
,
457 const InstrItinerary
*II
= STI
.getSchedModel().InstrItineraries
;
458 int SchedClass
= HexagonMCInstrInfo::getDesc(MCII
, MCI
).getSchedClass();
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())
469 // fyi: getUnits() will return 0x1, 0x2, 0x4 or 0x8
473 // if 0 is returned, then no additional slots are consumed by this inst.
477 bool HexagonMCInstrInfo::hasDuplex(MCInstrInfo
const &MCII
, MCInst
const &MCI
) {
478 if (!HexagonMCInstrInfo::isBundle(MCI
))
481 for (auto const &I
: HexagonMCInstrInfo::bundleInstructions(MCI
)) {
482 if (HexagonMCInstrInfo::isDuplex(MCII
, *I
.getInst()))
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
))
497 for (const auto &I
: HexagonMCInstrInfo::bundleInstructions(MCI
)) {
498 if (isImmext(*I
.getInst()))
505 /// Return whether the insn produces a value.
506 bool HexagonMCInstrInfo::hasNewValue(MCInstrInfo
const &MCII
,
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
,
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
,
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()));
538 bool HexagonMCInstrInfo::isConstExtended(MCInstrInfo
const &MCII
,
540 if (HexagonMCInstrInfo::isExtended(MCII
, MCI
))
542 if (!HexagonMCInstrInfo::isExtendable(MCII
, MCI
))
544 MCOperand
const &MO
= HexagonMCInstrInfo::getExtendableOperand(MCII
, MCI
);
545 if (isa
<HexagonMCExpr
>(MO
.getExpr()) &&
546 HexagonMCInstrInfo::mustExtend(*MO
.getExpr()))
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()))
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
))
561 if (isa
<HexagonMCExpr
>(MO
.getExpr()) &&
562 HexagonMCInstrInfo::mustNotExtend(*MO
.getExpr()))
565 if (!MO
.getExpr()->evaluateAsAbsolute(Value
))
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
,
584 const uint64_t F
= HexagonMCInstrInfo::getDesc(MCII
, MCI
).TSFlags
;
585 return ((F
>> HexagonII::CofRelax1Pos
) & HexagonII::CofRelax1Mask
);
588 bool HexagonMCInstrInfo::isCofRelax2(MCInstrInfo
const &MCII
,
590 const uint64_t F
= HexagonMCInstrInfo::getDesc(MCII
, MCI
).TSFlags
;
591 return ((F
>> HexagonII::CofRelax2Pos
) & HexagonII::CofRelax2Mask
);
594 bool HexagonMCInstrInfo::isCompound(MCInstrInfo
const &MCII
,
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
,
615 uint64_t const F
= HexagonMCInstrInfo::getDesc(MCII
, MCI
).TSFlags
;
616 return (F
>> HexagonII::ExtendablePos
) & HexagonII::ExtendableMask
;
619 bool HexagonMCInstrInfo::isExtended(MCInstrInfo
const &MCII
,
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
,
657 const uint64_t F
= HexagonMCInstrInfo::getDesc(MCII
, MCI
).TSFlags
;
658 return ((F
>> HexagonII::NewValuePos
) & HexagonII::NewValueMask
);
661 bool HexagonMCInstrInfo::isNewValueStore(MCInstrInfo
const &MCII
,
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
,
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
;
718 bool HexagonMCInstrInfo::isPredicated(MCInstrInfo
const &MCII
,
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
,
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
,
737 const uint64_t F
= HexagonMCInstrInfo::getDesc(MCII
, MCI
).TSFlags
;
738 return ((F
>> HexagonII::PredicatedNewPos
) & HexagonII::PredicatedNewMask
);
741 bool HexagonMCInstrInfo::isPredicatedTrue(MCInstrInfo
const &MCII
,
743 const uint64_t F
= HexagonMCInstrInfo::getDesc(MCII
, MCI
).TSFlags
;
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
,
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
,
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()) {
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
:
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())
862 if (MCI
.size() <= Index
)
864 MCOperand
const &MCO
= MCI
.getOperand(Index
);
868 if (!MCO
.getExpr()->evaluateAsAbsolute(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
);
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)
914 void HexagonMCInstrInfo::padEndloop(MCInst
&MCB
, MCContext
&Context
) {
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
,
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
,
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
);
959 unsigned HexagonMCInstrInfo::slotsConsumed(MCInstrInfo
const &MCII
,
960 MCSubtargetInfo
const &STI
,
962 unsigned slotsUsed
= 0;
963 for (auto HMI
: bundleInstructions(MCI
)) {
964 MCInst
const &MCI
= *HMI
.getInst();
965 if (!requiresSlot(STI
, MCI
))
967 if (isDuplex(MCII
, MCI
))
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
));
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
,
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
;