1 //===- HexagonMCInstrInfo.cpp - Utility functions on Hexagon MCInsts ------===//
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 // Utility functions for Hexagon specific MCInst queries
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCINSTRINFO_H
14 #define LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCINSTRINFO_H
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/ADT/iterator_range.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/Support/MathExtras.h"
26 class HexagonMCChecker
;
32 class MCSubtargetInfo
;
34 class DuplexCandidate
{
36 unsigned packetIndexI
, packetIndexJ
, iClass
;
38 DuplexCandidate(unsigned i
, unsigned j
, unsigned iClass
)
39 : packetIndexI(i
), packetIndexJ(j
), iClass(iClass
) {}
44 class PacketIterator
{
45 MCInstrInfo
const &MCII
;
46 MCInst::const_iterator BundleCurrent
;
47 MCInst::const_iterator BundleEnd
;
48 MCInst::const_iterator DuplexCurrent
;
49 MCInst::const_iterator DuplexEnd
;
52 PacketIterator(MCInstrInfo
const &MCII
, MCInst
const &Inst
);
53 PacketIterator(MCInstrInfo
const &MCII
, MCInst
const &Inst
, std::nullptr_t
);
55 PacketIterator
&operator++();
56 MCInst
const &operator*() const;
57 bool operator==(PacketIterator
const &Other
) const;
58 bool operator!=(PacketIterator
const &Other
) const {
59 return !(*this == Other
);
63 } // end namespace Hexagon
65 namespace HexagonMCInstrInfo
{
67 size_t const innerLoopOffset
= 0;
68 int64_t const innerLoopMask
= 1 << innerLoopOffset
;
70 size_t const outerLoopOffset
= 1;
71 int64_t const outerLoopMask
= 1 << outerLoopOffset
;
73 // do not reorder memory load/stores by default load/stores are re-ordered
74 // and by default loads can be re-ordered
75 size_t const memReorderDisabledOffset
= 2;
76 int64_t const memReorderDisabledMask
= 1 << memReorderDisabledOffset
;
78 size_t const bundleInstructionsOffset
= 1;
80 void addConstant(MCInst
&MI
, uint64_t Value
, MCContext
&Context
);
81 void addConstExtender(MCContext
&Context
, MCInstrInfo
const &MCII
, MCInst
&MCB
,
84 // Returns a iterator range of instructions in this bundle
85 iterator_range
<Hexagon::PacketIterator
>
86 bundleInstructions(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
87 iterator_range
<MCInst::const_iterator
> bundleInstructions(MCInst
const &MCI
);
89 // Returns the number of instructions in the bundle
90 size_t bundleSize(MCInst
const &MCI
);
92 // Put the packet in to canonical form, compound, duplex, pad, and shuffle
93 bool canonicalizePacket(MCInstrInfo
const &MCII
, MCSubtargetInfo
const &STI
,
94 MCContext
&Context
, MCInst
&MCB
,
95 HexagonMCChecker
*Checker
,
96 bool AttemptCompatibility
= false);
98 // Create a duplex instruction given the two subinsts
99 MCInst
*deriveDuplex(MCContext
&Context
, unsigned iClass
, MCInst
const &inst0
,
100 MCInst
const &inst1
);
101 MCInst
deriveExtender(MCInstrInfo
const &MCII
, MCInst
const &Inst
,
102 MCOperand
const &MO
);
104 // Convert this instruction in to a duplex subinst
105 MCInst
deriveSubInst(MCInst
const &Inst
);
107 // Return the extender for instruction at Index or nullptr if none
108 MCInst
const *extenderForIndex(MCInst
const &MCB
, size_t Index
);
109 void extendIfNeeded(MCContext
&Context
, MCInstrInfo
const &MCII
, MCInst
&MCB
,
112 // Return memory access size in bytes
113 unsigned getMemAccessSize(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
115 // Return memory access size
116 unsigned getAddrMode(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
118 MCInstrDesc
const &getDesc(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
120 // Return which duplex group this instruction belongs to
121 unsigned getDuplexCandidateGroup(MCInst
const &MI
);
123 // Return a list of all possible instruction duplex combinations
124 SmallVector
<DuplexCandidate
, 8>
125 getDuplexPossibilties(MCInstrInfo
const &MCII
, MCSubtargetInfo
const &STI
,
127 unsigned getDuplexRegisterNumbering(unsigned Reg
);
129 MCExpr
const &getExpr(MCExpr
const &Expr
);
131 // Return the index of the extendable operand
132 unsigned short getExtendableOp(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
134 // Return a reference to the extendable operand
135 MCOperand
const &getExtendableOperand(MCInstrInfo
const &MCII
,
138 // Return the implicit alignment of the extendable operand
139 unsigned getExtentAlignment(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
141 // Return the number of logical bits of the extendable operand
142 unsigned getExtentBits(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
144 // Check if the extendable operand is signed.
145 bool isExtentSigned(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
147 // Return the max value that a constant extendable operand can have
148 // without being extended.
149 int getMaxValue(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
151 // Return the min value that a constant extendable operand can have
152 // without being extended.
153 int getMinValue(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
155 // Return instruction name
156 StringRef
getName(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
158 // Return the operand index for the new value.
159 unsigned short getNewValueOp(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
161 // Return the operand that consumes or produces a new value.
162 MCOperand
const &getNewValueOperand(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
163 unsigned short getNewValueOp2(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
164 MCOperand
const &getNewValueOperand2(MCInstrInfo
const &MCII
,
167 // Return the Hexagon ISA class for the insn.
168 unsigned getType(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
170 /// Return the resources used by this instruction
171 unsigned getCVIResources(MCInstrInfo
const &MCII
,
172 MCSubtargetInfo
const &STI
,
175 /// Return the slots used by the insn.
176 unsigned getUnits(MCInstrInfo
const &MCII
, MCSubtargetInfo
const &STI
,
178 unsigned getOtherReservedSlots(MCInstrInfo
const &MCII
,
179 MCSubtargetInfo
const &STI
, MCInst
const &MCI
);
180 bool hasDuplex(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
182 // Does the packet have an extender for the instruction at Index
183 bool hasExtenderForIndex(MCInst
const &MCB
, size_t Index
);
185 bool hasImmExt(MCInst
const &MCI
);
187 // Return whether the instruction is a legal new-value producer.
188 bool hasNewValue(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
189 bool hasNewValue2(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
190 bool hasTmpDst(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
191 unsigned iClassOfDuplexPair(unsigned Ga
, unsigned Gb
);
193 int64_t minConstant(MCInst
const &MCI
, size_t Index
);
194 template <unsigned N
, unsigned S
>
195 bool inRange(MCInst
const &MCI
, size_t Index
) {
196 return isShiftedUInt
<N
, S
>(minConstant(MCI
, Index
));
198 template <unsigned N
, unsigned S
>
199 bool inSRange(MCInst
const &MCI
, size_t Index
) {
200 return isShiftedInt
<N
, S
>(minConstant(MCI
, Index
));
202 template <unsigned N
> bool inRange(MCInst
const &MCI
, size_t Index
) {
203 return isUInt
<N
>(minConstant(MCI
, Index
));
206 // Return the instruction at Index
207 MCInst
const &instruction(MCInst
const &MCB
, size_t Index
);
208 bool isAccumulator(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
210 // Returns whether this MCInst is a wellformed bundle
211 bool isBundle(MCInst
const &MCI
);
213 // Return whether the insn is an actual insn.
214 bool isCanon(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
215 bool isCofMax1(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
216 bool isCofRelax1(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
217 bool isCofRelax2(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
218 bool isCompound(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
220 // Return whether the instruction needs to be constant extended.
221 bool isConstExtended(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
222 bool isCVINew(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
224 // Is this double register suitable for use in a duplex subinst
225 bool isDblRegForSubInst(unsigned Reg
);
227 // Is this a duplex instruction
228 bool isDuplex(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
230 // Can these instructions be duplexed
231 bool isDuplexPair(MCInst
const &MIa
, MCInst
const &MIb
);
233 // Can these duplex classes be combine in to a duplex instruction
234 bool isDuplexPairMatch(unsigned Ga
, unsigned Gb
);
236 // Return true if the insn may be extended based on the operand value.
237 bool isExtendable(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
239 // Return whether the instruction must be always extended.
240 bool isExtended(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
242 /// Return whether it is a floating-point insn.
243 bool isFloat(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
245 bool isHVX(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
247 // Returns whether this instruction is an immediate extender
248 bool isImmext(MCInst
const &MCI
);
250 // Returns whether this bundle is an endloop0
251 bool isInnerLoop(MCInst
const &MCI
);
253 // Is this an integer register
254 bool isIntReg(unsigned Reg
);
256 // Is this register suitable for use in a duplex subinst
257 bool isIntRegForSubInst(unsigned Reg
);
258 bool isMemReorderDisabled(MCInst
const &MCI
);
260 // Return whether the insn is a new-value consumer.
261 bool isNewValue(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
262 /// Return true if the operand is a new-value store insn.
263 bool isNewValueStore(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
264 bool isOpExtendable(MCInstrInfo
const &MCII
, MCInst
const &MCI
, unsigned short);
266 // Can these two instructions be duplexed
267 bool isOrderedDuplexPair(MCInstrInfo
const &MCII
, MCInst
const &MIa
,
268 bool ExtendedA
, MCInst
const &MIb
, bool ExtendedB
,
269 bool bisReversable
, MCSubtargetInfo
const &STI
);
271 // Returns whether this bundle is an endloop1
272 bool isOuterLoop(MCInst
const &MCI
);
274 // Return whether this instruction is predicated
275 bool isPredicated(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
276 bool isPredicateLate(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
277 bool isPredicatedNew(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
279 // Return whether the predicate sense is true
280 bool isPredicatedTrue(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
282 // Return true if this is a scalar predicate register.
283 bool isPredReg(MCRegisterInfo
const &MRI
, unsigned Reg
);
285 // Returns true if the Ith operand is a predicate register.
286 bool isPredRegister(MCInstrInfo
const &MCII
, MCInst
const &Inst
, unsigned I
);
288 // Return whether the insn is a prefix.
289 bool isPrefix(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
291 // Return whether the insn is solo, i.e., cannot be in a packet.
292 bool isSolo(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
294 /// Return whether the insn can be packaged only with A and X-type insns.
295 bool isSoloAX(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
297 /// Return whether the insn can be packaged only with an A-type insn in slot #1.
298 bool isRestrictSlot1AOK(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
299 bool isRestrictNoSlot1Store(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
300 bool isSubInstruction(MCInst
const &MCI
);
301 bool isVector(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
302 bool mustExtend(MCExpr
const &Expr
);
303 bool mustNotExtend(MCExpr
const &Expr
);
305 // Returns true if this instruction requires a slot to execute.
306 bool requiresSlot(MCSubtargetInfo
const &STI
, MCInst
const &MCI
);
308 unsigned packetSize(StringRef CPU
);
310 // Returns the maximum number of slots available in the given
311 // subtarget's packets.
312 unsigned packetSizeSlots(MCSubtargetInfo
const &STI
);
314 // Returns the number of slots consumed by this packet, considering duplexed
315 // and compound instructions.
316 unsigned slotsConsumed(MCInstrInfo
const &MCII
, MCSubtargetInfo
const &STI
,
320 // Pad the bundle with nops to satisfy endloop requirements
321 void padEndloop(MCInst
&MCI
, MCContext
&Context
);
322 class PredicateInfo
{
324 PredicateInfo() : Register(0), Operand(0), PredicatedTrue(false) {}
325 PredicateInfo(unsigned Register
, unsigned Operand
, bool PredicatedTrue
)
326 : Register(Register
), Operand(Operand
), PredicatedTrue(PredicatedTrue
) {}
327 bool isPredicated() const;
332 PredicateInfo
predicateInfo(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
333 bool prefersSlot3(MCInstrInfo
const &MCII
, MCInst
const &MCI
);
335 // Replace the instructions inside MCB, represented by Candidate
336 void replaceDuplex(MCContext
&Context
, MCInst
&MCI
, DuplexCandidate Candidate
);
338 bool s27_2_reloc(MCExpr
const &Expr
);
339 // Marks a bundle as endloop0
340 void setInnerLoop(MCInst
&MCI
);
341 void setMemReorderDisabled(MCInst
&MCI
);
342 void setMustExtend(MCExpr
const &Expr
, bool Val
= true);
343 void setMustNotExtend(MCExpr
const &Expr
, bool Val
= true);
344 void setS27_2_reloc(MCExpr
const &Expr
, bool Val
= true);
346 // Marks a bundle as endloop1
347 void setOuterLoop(MCInst
&MCI
);
349 // Would duplexing this instruction create a requirement to extend
350 bool subInstWouldBeExtended(MCInst
const &potentialDuplex
);
351 unsigned SubregisterBit(unsigned Consumer
, unsigned Producer
,
354 bool IsVecRegSingle(unsigned VecReg
);
355 bool IsVecRegPair(unsigned VecReg
);
356 bool IsReverseVecRegPair(unsigned VecReg
);
357 bool IsSingleConsumerRefPairProducer(unsigned Producer
, unsigned Consumer
);
359 /// Returns an ordered pair of the constituent register ordinals for
360 /// each of the elements of \a VecRegPair. For example, Hexagon::W0 ("v0:1")
361 /// returns { 0, 1 } and Hexagon::W1 ("v3:2") returns { 3, 2 }.
362 std::pair
<unsigned, unsigned> GetVecRegPairIndices(unsigned VecRegPair
);
364 // Attempt to find and replace compound pairs
365 void tryCompound(MCInstrInfo
const &MCII
, MCSubtargetInfo
const &STI
,
366 MCContext
&Context
, MCInst
&MCI
);
368 } // end namespace HexagonMCInstrInfo
370 } // end namespace llvm
372 #endif // LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCINSTRINFO_H