1 //===- HexagonMCInstrInfo.cpp - Utility functions on Hexagon MCInsts ------===// 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 // Utility functions for Hexagon specific MCInst queries 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCINSTRINFO_H 14 #define LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCINSTRINFO_H 15 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" 21 #include <cstddef> 22 #include <cstdint> 23 24 namespace llvm { 25 26 class HexagonMCChecker; 27 class MCContext; 28 class MCExpr; 29 class MCInstrDesc; 30 class MCInstrInfo; 31 class MCSubtargetInfo; 32 33 class DuplexCandidate { 34 public: 35 unsigned packetIndexI, packetIndexJ, iClass; 36 37 DuplexCandidate(unsigned i, unsigned j, unsigned iClass) 38 : packetIndexI(i), packetIndexJ(j), iClass(iClass) {} 39 }; 40 41 namespace Hexagon { 42 43 class PacketIterator { 44 MCInstrInfo const &MCII; 45 MCInst::const_iterator BundleCurrent; 46 MCInst::const_iterator BundleEnd; 47 MCInst::const_iterator DuplexCurrent; 48 MCInst::const_iterator DuplexEnd; 49 50 public: 51 PacketIterator(MCInstrInfo const &MCII, MCInst const &Inst); 52 PacketIterator(MCInstrInfo const &MCII, MCInst const &Inst, std::nullptr_t); 53 54 PacketIterator &operator++(); 55 MCInst const &operator*() const; 56 bool operator==(PacketIterator const &Other) const; 57 bool operator!=(PacketIterator const &Other) const { 58 return !(*this == Other); 59 } 60 }; 61 62 } // end namespace Hexagon 63 64 namespace HexagonMCInstrInfo { 65 66 size_t const innerLoopOffset = 0; 67 int64_t const innerLoopMask = 1 << innerLoopOffset; 68 69 size_t const outerLoopOffset = 1; 70 int64_t const outerLoopMask = 1 << outerLoopOffset; 71 72 // do not reorder memory load/stores by default load/stores are re-ordered 73 // and by default loads can be re-ordered 74 size_t const memReorderDisabledOffset = 2; 75 int64_t const memReorderDisabledMask = 1 << memReorderDisabledOffset; 76 77 size_t const bundleInstructionsOffset = 1; 78 79 void addConstant(MCInst &MI, uint64_t Value, MCContext &Context); 80 void addConstExtender(MCContext &Context, MCInstrInfo const &MCII, MCInst &MCB, 81 MCInst const &MCI); 82 83 // Returns a iterator range of instructions in this bundle 84 iterator_range<Hexagon::PacketIterator> 85 bundleInstructions(MCInstrInfo const &MCII, MCInst const &MCI); 86 iterator_range<MCInst::const_iterator> bundleInstructions(MCInst const &MCI); 87 88 // Returns the number of instructions in the bundle 89 size_t bundleSize(MCInst const &MCI); 90 91 // Put the packet in to canonical form, compound, duplex, pad, and shuffle 92 bool canonicalizePacket(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, 93 MCContext &Context, MCInst &MCB, 94 HexagonMCChecker *Checker); 95 96 // Create a duplex instruction given the two subinsts 97 MCInst *deriveDuplex(MCContext &Context, unsigned iClass, MCInst const &inst0, 98 MCInst const &inst1); 99 MCInst deriveExtender(MCInstrInfo const &MCII, MCInst const &Inst, 100 MCOperand const &MO); 101 102 // Convert this instruction in to a duplex subinst 103 MCInst deriveSubInst(MCInst const &Inst); 104 105 // Return the extender for instruction at Index or nullptr if none 106 MCInst const *extenderForIndex(MCInst const &MCB, size_t Index); 107 void extendIfNeeded(MCContext &Context, MCInstrInfo const &MCII, MCInst &MCB, 108 MCInst const &MCI); 109 110 // Return memory access size in bytes 111 unsigned getMemAccessSize(MCInstrInfo const &MCII, MCInst const &MCI); 112 113 // Return memory access size 114 unsigned getAddrMode(MCInstrInfo const &MCII, MCInst const &MCI); 115 116 MCInstrDesc const &getDesc(MCInstrInfo const &MCII, MCInst const &MCI); 117 118 // Return which duplex group this instruction belongs to 119 unsigned getDuplexCandidateGroup(MCInst const &MI); 120 121 // Return a list of all possible instruction duplex combinations 122 SmallVector<DuplexCandidate, 8> 123 getDuplexPossibilties(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, 124 MCInst const &MCB); 125 unsigned getDuplexRegisterNumbering(unsigned Reg); 126 127 MCExpr const &getExpr(MCExpr const &Expr); 128 129 // Return the index of the extendable operand 130 unsigned short getExtendableOp(MCInstrInfo const &MCII, MCInst const &MCI); 131 132 // Return a reference to the extendable operand 133 MCOperand const &getExtendableOperand(MCInstrInfo const &MCII, 134 MCInst const &MCI); 135 136 // Return the implicit alignment of the extendable operand 137 unsigned getExtentAlignment(MCInstrInfo const &MCII, MCInst const &MCI); 138 139 // Return the number of logical bits of the extendable operand 140 unsigned getExtentBits(MCInstrInfo const &MCII, MCInst const &MCI); 141 142 // Check if the extendable operand is signed. 143 bool isExtentSigned(MCInstrInfo const &MCII, MCInst const &MCI); 144 145 // Return the max value that a constant extendable operand can have 146 // without being extended. 147 int getMaxValue(MCInstrInfo const &MCII, MCInst const &MCI); 148 149 // Return the min value that a constant extendable operand can have 150 // without being extended. 151 int getMinValue(MCInstrInfo const &MCII, MCInst const &MCI); 152 153 // Return instruction name 154 StringRef getName(MCInstrInfo const &MCII, MCInst const &MCI); 155 156 // Return the operand index for the new value. 157 unsigned short getNewValueOp(MCInstrInfo const &MCII, MCInst const &MCI); 158 159 // Return the operand that consumes or produces a new value. 160 MCOperand const &getNewValueOperand(MCInstrInfo const &MCII, MCInst const &MCI); 161 unsigned short getNewValueOp2(MCInstrInfo const &MCII, MCInst const &MCI); 162 MCOperand const &getNewValueOperand2(MCInstrInfo const &MCII, 163 MCInst const &MCI); 164 165 // Return the Hexagon ISA class for the insn. 166 unsigned getType(MCInstrInfo const &MCII, MCInst const &MCI); 167 168 /// Return the slots used by the insn. 169 unsigned getUnits(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, 170 MCInst const &MCI); 171 unsigned getOtherReservedSlots(MCInstrInfo const &MCII, 172 MCSubtargetInfo const &STI, MCInst const &MCI); 173 bool hasDuplex(MCInstrInfo const &MCII, MCInst const &MCI); 174 175 // Does the packet have an extender for the instruction at Index 176 bool hasExtenderForIndex(MCInst const &MCB, size_t Index); 177 178 bool hasImmExt(MCInst const &MCI); 179 180 // Return whether the instruction is a legal new-value producer. 181 bool hasNewValue(MCInstrInfo const &MCII, MCInst const &MCI); 182 bool hasNewValue2(MCInstrInfo const &MCII, MCInst const &MCI); 183 bool hasTmpDst(MCInstrInfo const &MCII, MCInst const &MCI); 184 unsigned iClassOfDuplexPair(unsigned Ga, unsigned Gb); 185 186 int64_t minConstant(MCInst const &MCI, size_t Index); 187 template <unsigned N, unsigned S> 188 bool inRange(MCInst const &MCI, size_t Index) { 189 return isShiftedUInt<N, S>(minConstant(MCI, Index)); 190 } 191 template <unsigned N, unsigned S> 192 bool inSRange(MCInst const &MCI, size_t Index) { 193 return isShiftedInt<N, S>(minConstant(MCI, Index)); 194 } 195 template <unsigned N> bool inRange(MCInst const &MCI, size_t Index) { 196 return isUInt<N>(minConstant(MCI, Index)); 197 } 198 199 // Return the instruction at Index 200 MCInst const &instruction(MCInst const &MCB, size_t Index); 201 bool isAccumulator(MCInstrInfo const &MCII, MCInst const &MCI); 202 203 // Returns whether this MCInst is a wellformed bundle 204 bool isBundle(MCInst const &MCI); 205 206 // Return whether the insn is an actual insn. 207 bool isCanon(MCInstrInfo const &MCII, MCInst const &MCI); 208 bool isCofMax1(MCInstrInfo const &MCII, MCInst const &MCI); 209 bool isCofRelax1(MCInstrInfo const &MCII, MCInst const &MCI); 210 bool isCofRelax2(MCInstrInfo const &MCII, MCInst const &MCI); 211 bool isCompound(MCInstrInfo const &MCII, MCInst const &MCI); 212 213 // Return whether the instruction needs to be constant extended. 214 bool isConstExtended(MCInstrInfo const &MCII, MCInst const &MCI); 215 bool isCVINew(MCInstrInfo const &MCII, MCInst const &MCI); 216 217 // Is this double register suitable for use in a duplex subinst 218 bool isDblRegForSubInst(unsigned Reg); 219 220 // Is this a duplex instruction 221 bool isDuplex(MCInstrInfo const &MCII, MCInst const &MCI); 222 223 // Can these instructions be duplexed 224 bool isDuplexPair(MCInst const &MIa, MCInst const &MIb); 225 226 // Can these duplex classes be combine in to a duplex instruction 227 bool isDuplexPairMatch(unsigned Ga, unsigned Gb); 228 229 // Return true if the insn may be extended based on the operand value. 230 bool isExtendable(MCInstrInfo const &MCII, MCInst const &MCI); 231 232 // Return whether the instruction must be always extended. 233 bool isExtended(MCInstrInfo const &MCII, MCInst const &MCI); 234 235 /// Return whether it is a floating-point insn. 236 bool isFloat(MCInstrInfo const &MCII, MCInst const &MCI); 237 238 bool isHVX(MCInstrInfo const &MCII, MCInst const &MCI); 239 240 // Returns whether this instruction is an immediate extender 241 bool isImmext(MCInst const &MCI); 242 243 // Returns whether this bundle is an endloop0 244 bool isInnerLoop(MCInst const &MCI); 245 246 // Is this an integer register 247 bool isIntReg(unsigned Reg); 248 249 // Is this register suitable for use in a duplex subinst 250 bool isIntRegForSubInst(unsigned Reg); 251 bool isMemReorderDisabled(MCInst const &MCI); 252 253 // Return whether the insn is a new-value consumer. 254 bool isNewValue(MCInstrInfo const &MCII, MCInst const &MCI); 255 bool isOpExtendable(MCInstrInfo const &MCII, MCInst const &MCI, unsigned short); 256 257 // Can these two instructions be duplexed 258 bool isOrderedDuplexPair(MCInstrInfo const &MCII, MCInst const &MIa, 259 bool ExtendedA, MCInst const &MIb, bool ExtendedB, 260 bool bisReversable, MCSubtargetInfo const &STI); 261 262 // Returns whether this bundle is an endloop1 263 bool isOuterLoop(MCInst const &MCI); 264 265 // Return whether this instruction is predicated 266 bool isPredicated(MCInstrInfo const &MCII, MCInst const &MCI); 267 bool isPredicateLate(MCInstrInfo const &MCII, MCInst const &MCI); 268 bool isPredicatedNew(MCInstrInfo const &MCII, MCInst const &MCI); 269 270 // Return whether the predicate sense is true 271 bool isPredicatedTrue(MCInstrInfo const &MCII, MCInst const &MCI); 272 273 // Is this a predicate register 274 bool isPredReg(unsigned Reg); 275 276 // Return whether the insn is a prefix. 277 bool isPrefix(MCInstrInfo const &MCII, MCInst const &MCI); 278 279 // Return whether the insn is solo, i.e., cannot be in a packet. 280 bool isSolo(MCInstrInfo const &MCII, MCInst const &MCI); 281 282 /// Return whether the insn can be packaged only with A and X-type insns. 283 bool isSoloAX(MCInstrInfo const &MCII, MCInst const &MCI); 284 285 /// Return whether the insn can be packaged only with an A-type insn in slot #1. 286 bool isRestrictSlot1AOK(MCInstrInfo const &MCII, MCInst const &MCI); 287 bool isRestrictNoSlot1Store(MCInstrInfo const &MCII, MCInst const &MCI); 288 bool isSubInstruction(MCInst const &MCI); 289 bool isVector(MCInstrInfo const &MCII, MCInst const &MCI); 290 bool mustExtend(MCExpr const &Expr); 291 bool mustNotExtend(MCExpr const &Expr); 292 293 // Pad the bundle with nops to satisfy endloop requirements 294 void padEndloop(MCInst &MCI, MCContext &Context); 295 class PredicateInfo { 296 public: 297 PredicateInfo() : Register(0), Operand(0), PredicatedTrue(false) {} 298 PredicateInfo(unsigned Register, unsigned Operand, bool PredicatedTrue) 299 : Register(Register), Operand(Operand), PredicatedTrue(PredicatedTrue) {} 300 bool isPredicated() const; 301 unsigned Register; 302 unsigned Operand; 303 bool PredicatedTrue; 304 }; 305 PredicateInfo predicateInfo(MCInstrInfo const &MCII, MCInst const &MCI); 306 bool prefersSlot3(MCInstrInfo const &MCII, MCInst const &MCI); 307 308 // Replace the instructions inside MCB, represented by Candidate 309 void replaceDuplex(MCContext &Context, MCInst &MCI, DuplexCandidate Candidate); 310 311 bool s27_2_reloc(MCExpr const &Expr); 312 // Marks a bundle as endloop0 313 void setInnerLoop(MCInst &MCI); 314 void setMemReorderDisabled(MCInst &MCI); 315 void setMustExtend(MCExpr const &Expr, bool Val = true); 316 void setMustNotExtend(MCExpr const &Expr, bool Val = true); 317 void setS27_2_reloc(MCExpr const &Expr, bool Val = true); 318 319 // Marks a bundle as endloop1 320 void setOuterLoop(MCInst &MCI); 321 322 // Would duplexing this instruction create a requirement to extend 323 bool subInstWouldBeExtended(MCInst const &potentialDuplex); 324 unsigned SubregisterBit(unsigned Consumer, unsigned Producer, 325 unsigned Producer2); 326 327 // Attempt to find and replace compound pairs 328 void tryCompound(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, 329 MCContext &Context, MCInst &MCI); 330 331 } // end namespace HexagonMCInstrInfo 332 333 } // end namespace llvm 334 335 #endif // LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCINSTRINFO_H 336