1*0fca6ea1SDimitry Andric //===- CodeGenInstruction.h - Instruction Class Wrapper ---------*- C++ -*-===// 2*0fca6ea1SDimitry Andric // 3*0fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0fca6ea1SDimitry Andric // 7*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 8*0fca6ea1SDimitry Andric // 9*0fca6ea1SDimitry Andric // This file defines a wrapper class for the 'Instruction' TableGen class. 10*0fca6ea1SDimitry Andric // 11*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 12*0fca6ea1SDimitry Andric 13*0fca6ea1SDimitry Andric #ifndef LLVM_UTILS_TABLEGEN_CODEGENINSTRUCTION_H 14*0fca6ea1SDimitry Andric #define LLVM_UTILS_TABLEGEN_CODEGENINSTRUCTION_H 15*0fca6ea1SDimitry Andric 16*0fca6ea1SDimitry Andric #include "llvm/ADT/BitVector.h" 17*0fca6ea1SDimitry Andric #include "llvm/ADT/StringMap.h" 18*0fca6ea1SDimitry Andric #include "llvm/ADT/StringRef.h" 19*0fca6ea1SDimitry Andric #include "llvm/CodeGenTypes/MachineValueType.h" 20*0fca6ea1SDimitry Andric #include "llvm/TableGen/Record.h" 21*0fca6ea1SDimitry Andric #include <cassert> 22*0fca6ea1SDimitry Andric #include <string> 23*0fca6ea1SDimitry Andric #include <utility> 24*0fca6ea1SDimitry Andric #include <vector> 25*0fca6ea1SDimitry Andric 26*0fca6ea1SDimitry Andric namespace llvm { 27*0fca6ea1SDimitry Andric class CodeGenTarget; 28*0fca6ea1SDimitry Andric 29*0fca6ea1SDimitry Andric class CGIOperandList { 30*0fca6ea1SDimitry Andric public: 31*0fca6ea1SDimitry Andric class ConstraintInfo { 32*0fca6ea1SDimitry Andric enum { None, EarlyClobber, Tied } Kind = None; 33*0fca6ea1SDimitry Andric unsigned OtherTiedOperand = 0; 34*0fca6ea1SDimitry Andric 35*0fca6ea1SDimitry Andric public: 36*0fca6ea1SDimitry Andric ConstraintInfo() = default; 37*0fca6ea1SDimitry Andric 38*0fca6ea1SDimitry Andric static ConstraintInfo getEarlyClobber() { 39*0fca6ea1SDimitry Andric ConstraintInfo I; 40*0fca6ea1SDimitry Andric I.Kind = EarlyClobber; 41*0fca6ea1SDimitry Andric I.OtherTiedOperand = 0; 42*0fca6ea1SDimitry Andric return I; 43*0fca6ea1SDimitry Andric } 44*0fca6ea1SDimitry Andric 45*0fca6ea1SDimitry Andric static ConstraintInfo getTied(unsigned Op) { 46*0fca6ea1SDimitry Andric ConstraintInfo I; 47*0fca6ea1SDimitry Andric I.Kind = Tied; 48*0fca6ea1SDimitry Andric I.OtherTiedOperand = Op; 49*0fca6ea1SDimitry Andric return I; 50*0fca6ea1SDimitry Andric } 51*0fca6ea1SDimitry Andric 52*0fca6ea1SDimitry Andric bool isNone() const { return Kind == None; } 53*0fca6ea1SDimitry Andric bool isEarlyClobber() const { return Kind == EarlyClobber; } 54*0fca6ea1SDimitry Andric bool isTied() const { return Kind == Tied; } 55*0fca6ea1SDimitry Andric 56*0fca6ea1SDimitry Andric unsigned getTiedOperand() const { 57*0fca6ea1SDimitry Andric assert(isTied()); 58*0fca6ea1SDimitry Andric return OtherTiedOperand; 59*0fca6ea1SDimitry Andric } 60*0fca6ea1SDimitry Andric 61*0fca6ea1SDimitry Andric bool operator==(const ConstraintInfo &RHS) const { 62*0fca6ea1SDimitry Andric if (Kind != RHS.Kind) 63*0fca6ea1SDimitry Andric return false; 64*0fca6ea1SDimitry Andric if (Kind == Tied && OtherTiedOperand != RHS.OtherTiedOperand) 65*0fca6ea1SDimitry Andric return false; 66*0fca6ea1SDimitry Andric return true; 67*0fca6ea1SDimitry Andric } 68*0fca6ea1SDimitry Andric bool operator!=(const ConstraintInfo &RHS) const { return !(*this == RHS); } 69*0fca6ea1SDimitry Andric }; 70*0fca6ea1SDimitry Andric 71*0fca6ea1SDimitry Andric /// OperandInfo - The information we keep track of for each operand in the 72*0fca6ea1SDimitry Andric /// operand list for a tablegen instruction. 73*0fca6ea1SDimitry Andric struct OperandInfo { 74*0fca6ea1SDimitry Andric /// Rec - The definition this operand is declared as. 75*0fca6ea1SDimitry Andric /// 76*0fca6ea1SDimitry Andric Record *Rec; 77*0fca6ea1SDimitry Andric 78*0fca6ea1SDimitry Andric /// Name - If this operand was assigned a symbolic name, this is it, 79*0fca6ea1SDimitry Andric /// otherwise, it's empty. 80*0fca6ea1SDimitry Andric std::string Name; 81*0fca6ea1SDimitry Andric 82*0fca6ea1SDimitry Andric /// The names of sub-operands, if given, otherwise empty. 83*0fca6ea1SDimitry Andric std::vector<std::string> SubOpNames; 84*0fca6ea1SDimitry Andric 85*0fca6ea1SDimitry Andric /// PrinterMethodName - The method used to print operands of this type in 86*0fca6ea1SDimitry Andric /// the asmprinter. 87*0fca6ea1SDimitry Andric std::string PrinterMethodName; 88*0fca6ea1SDimitry Andric 89*0fca6ea1SDimitry Andric /// The method used to get the machine operand value for binary 90*0fca6ea1SDimitry Andric /// encoding, per sub-operand. If empty, uses "getMachineOpValue". 91*0fca6ea1SDimitry Andric std::vector<std::string> EncoderMethodNames; 92*0fca6ea1SDimitry Andric 93*0fca6ea1SDimitry Andric /// OperandType - A value from MCOI::OperandType representing the type of 94*0fca6ea1SDimitry Andric /// the operand. 95*0fca6ea1SDimitry Andric std::string OperandType; 96*0fca6ea1SDimitry Andric 97*0fca6ea1SDimitry Andric /// MIOperandNo - Currently (this is meant to be phased out), some logical 98*0fca6ea1SDimitry Andric /// operands correspond to multiple MachineInstr operands. In the X86 99*0fca6ea1SDimitry Andric /// target for example, one address operand is represented as 4 100*0fca6ea1SDimitry Andric /// MachineOperands. Because of this, the operand number in the 101*0fca6ea1SDimitry Andric /// OperandList may not match the MachineInstr operand num. Until it 102*0fca6ea1SDimitry Andric /// does, this contains the MI operand index of this operand. 103*0fca6ea1SDimitry Andric unsigned MIOperandNo; 104*0fca6ea1SDimitry Andric unsigned MINumOperands; // The number of operands. 105*0fca6ea1SDimitry Andric 106*0fca6ea1SDimitry Andric /// DoNotEncode - Bools are set to true in this vector for each operand in 107*0fca6ea1SDimitry Andric /// the DisableEncoding list. These should not be emitted by the code 108*0fca6ea1SDimitry Andric /// emitter. 109*0fca6ea1SDimitry Andric BitVector DoNotEncode; 110*0fca6ea1SDimitry Andric 111*0fca6ea1SDimitry Andric /// MIOperandInfo - Default MI operand type. Note an operand may be made 112*0fca6ea1SDimitry Andric /// up of multiple MI operands. 113*0fca6ea1SDimitry Andric DagInit *MIOperandInfo; 114*0fca6ea1SDimitry Andric 115*0fca6ea1SDimitry Andric /// Constraint info for this operand. This operand can have pieces, so we 116*0fca6ea1SDimitry Andric /// track constraint info for each. 117*0fca6ea1SDimitry Andric std::vector<ConstraintInfo> Constraints; 118*0fca6ea1SDimitry Andric 119*0fca6ea1SDimitry Andric OperandInfo(Record *R, const std::string &N, const std::string &PMN, 120*0fca6ea1SDimitry Andric const std::string &OT, unsigned MION, unsigned MINO, 121*0fca6ea1SDimitry Andric DagInit *MIOI) 122*0fca6ea1SDimitry Andric : Rec(R), Name(N), SubOpNames(MINO), PrinterMethodName(PMN), 123*0fca6ea1SDimitry Andric EncoderMethodNames(MINO), OperandType(OT), MIOperandNo(MION), 124*0fca6ea1SDimitry Andric MINumOperands(MINO), DoNotEncode(MINO), MIOperandInfo(MIOI), 125*0fca6ea1SDimitry Andric Constraints(MINO) {} 126*0fca6ea1SDimitry Andric 127*0fca6ea1SDimitry Andric /// getTiedOperand - If this operand is tied to another one, return the 128*0fca6ea1SDimitry Andric /// other operand number. Otherwise, return -1. 129*0fca6ea1SDimitry Andric int getTiedRegister() const { 130*0fca6ea1SDimitry Andric for (unsigned j = 0, e = Constraints.size(); j != e; ++j) { 131*0fca6ea1SDimitry Andric const CGIOperandList::ConstraintInfo &CI = Constraints[j]; 132*0fca6ea1SDimitry Andric if (CI.isTied()) 133*0fca6ea1SDimitry Andric return CI.getTiedOperand(); 134*0fca6ea1SDimitry Andric } 135*0fca6ea1SDimitry Andric return -1; 136*0fca6ea1SDimitry Andric } 137*0fca6ea1SDimitry Andric }; 138*0fca6ea1SDimitry Andric 139*0fca6ea1SDimitry Andric CGIOperandList(Record *D); 140*0fca6ea1SDimitry Andric 141*0fca6ea1SDimitry Andric Record *TheDef; // The actual record containing this OperandList. 142*0fca6ea1SDimitry Andric 143*0fca6ea1SDimitry Andric /// NumDefs - Number of def operands declared, this is the number of 144*0fca6ea1SDimitry Andric /// elements in the instruction's (outs) list. 145*0fca6ea1SDimitry Andric /// 146*0fca6ea1SDimitry Andric unsigned NumDefs; 147*0fca6ea1SDimitry Andric 148*0fca6ea1SDimitry Andric /// OperandList - The list of declared operands, along with their declared 149*0fca6ea1SDimitry Andric /// type (which is a record). 150*0fca6ea1SDimitry Andric std::vector<OperandInfo> OperandList; 151*0fca6ea1SDimitry Andric 152*0fca6ea1SDimitry Andric /// SubOpAliases - List of alias names for suboperands. 153*0fca6ea1SDimitry Andric StringMap<std::pair<unsigned, unsigned>> SubOpAliases; 154*0fca6ea1SDimitry Andric 155*0fca6ea1SDimitry Andric // Information gleaned from the operand list. 156*0fca6ea1SDimitry Andric bool isPredicable; 157*0fca6ea1SDimitry Andric bool hasOptionalDef; 158*0fca6ea1SDimitry Andric bool isVariadic; 159*0fca6ea1SDimitry Andric 160*0fca6ea1SDimitry Andric // Provide transparent accessors to the operand list. 161*0fca6ea1SDimitry Andric bool empty() const { return OperandList.empty(); } 162*0fca6ea1SDimitry Andric unsigned size() const { return OperandList.size(); } 163*0fca6ea1SDimitry Andric const OperandInfo &operator[](unsigned i) const { return OperandList[i]; } 164*0fca6ea1SDimitry Andric OperandInfo &operator[](unsigned i) { return OperandList[i]; } 165*0fca6ea1SDimitry Andric OperandInfo &back() { return OperandList.back(); } 166*0fca6ea1SDimitry Andric const OperandInfo &back() const { return OperandList.back(); } 167*0fca6ea1SDimitry Andric 168*0fca6ea1SDimitry Andric typedef std::vector<OperandInfo>::iterator iterator; 169*0fca6ea1SDimitry Andric typedef std::vector<OperandInfo>::const_iterator const_iterator; 170*0fca6ea1SDimitry Andric iterator begin() { return OperandList.begin(); } 171*0fca6ea1SDimitry Andric const_iterator begin() const { return OperandList.begin(); } 172*0fca6ea1SDimitry Andric iterator end() { return OperandList.end(); } 173*0fca6ea1SDimitry Andric const_iterator end() const { return OperandList.end(); } 174*0fca6ea1SDimitry Andric 175*0fca6ea1SDimitry Andric /// getOperandNamed - Return the index of the operand with the specified 176*0fca6ea1SDimitry Andric /// non-empty name. If the instruction does not have an operand with the 177*0fca6ea1SDimitry Andric /// specified name, abort. 178*0fca6ea1SDimitry Andric unsigned getOperandNamed(StringRef Name) const; 179*0fca6ea1SDimitry Andric 180*0fca6ea1SDimitry Andric /// hasOperandNamed - Query whether the instruction has an operand of the 181*0fca6ea1SDimitry Andric /// given name. If so, return true and set OpIdx to the index of the 182*0fca6ea1SDimitry Andric /// operand. Otherwise, return false. 183*0fca6ea1SDimitry Andric bool hasOperandNamed(StringRef Name, unsigned &OpIdx) const; 184*0fca6ea1SDimitry Andric 185*0fca6ea1SDimitry Andric bool hasSubOperandAlias(StringRef Name, 186*0fca6ea1SDimitry Andric std::pair<unsigned, unsigned> &SubOp) const; 187*0fca6ea1SDimitry Andric 188*0fca6ea1SDimitry Andric /// ParseOperandName - Parse an operand name like "$foo" or "$foo.bar", 189*0fca6ea1SDimitry Andric /// where $foo is a whole operand and $foo.bar refers to a suboperand. 190*0fca6ea1SDimitry Andric /// This aborts if the name is invalid. If AllowWholeOp is true, references 191*0fca6ea1SDimitry Andric /// to operands with suboperands are allowed, otherwise not. 192*0fca6ea1SDimitry Andric std::pair<unsigned, unsigned> ParseOperandName(StringRef Op, 193*0fca6ea1SDimitry Andric bool AllowWholeOp = true); 194*0fca6ea1SDimitry Andric 195*0fca6ea1SDimitry Andric /// getFlattenedOperandNumber - Flatten a operand/suboperand pair into a 196*0fca6ea1SDimitry Andric /// flat machineinstr operand #. 197*0fca6ea1SDimitry Andric unsigned getFlattenedOperandNumber(std::pair<unsigned, unsigned> Op) const { 198*0fca6ea1SDimitry Andric return OperandList[Op.first].MIOperandNo + Op.second; 199*0fca6ea1SDimitry Andric } 200*0fca6ea1SDimitry Andric 201*0fca6ea1SDimitry Andric /// getSubOperandNumber - Unflatten a operand number into an 202*0fca6ea1SDimitry Andric /// operand/suboperand pair. 203*0fca6ea1SDimitry Andric std::pair<unsigned, unsigned> getSubOperandNumber(unsigned Op) const { 204*0fca6ea1SDimitry Andric for (unsigned i = 0;; ++i) { 205*0fca6ea1SDimitry Andric assert(i < OperandList.size() && "Invalid flat operand #"); 206*0fca6ea1SDimitry Andric if (OperandList[i].MIOperandNo + OperandList[i].MINumOperands > Op) 207*0fca6ea1SDimitry Andric return std::pair(i, Op - OperandList[i].MIOperandNo); 208*0fca6ea1SDimitry Andric } 209*0fca6ea1SDimitry Andric } 210*0fca6ea1SDimitry Andric 211*0fca6ea1SDimitry Andric /// isFlatOperandNotEmitted - Return true if the specified flat operand # 212*0fca6ea1SDimitry Andric /// should not be emitted with the code emitter. 213*0fca6ea1SDimitry Andric bool isFlatOperandNotEmitted(unsigned FlatOpNo) const { 214*0fca6ea1SDimitry Andric std::pair<unsigned, unsigned> Op = getSubOperandNumber(FlatOpNo); 215*0fca6ea1SDimitry Andric if (OperandList[Op.first].DoNotEncode.size() > Op.second) 216*0fca6ea1SDimitry Andric return OperandList[Op.first].DoNotEncode[Op.second]; 217*0fca6ea1SDimitry Andric return false; 218*0fca6ea1SDimitry Andric } 219*0fca6ea1SDimitry Andric 220*0fca6ea1SDimitry Andric void ProcessDisableEncoding(StringRef Value); 221*0fca6ea1SDimitry Andric }; 222*0fca6ea1SDimitry Andric 223*0fca6ea1SDimitry Andric class CodeGenInstruction { 224*0fca6ea1SDimitry Andric public: 225*0fca6ea1SDimitry Andric Record *TheDef; // The actual record defining this instruction. 226*0fca6ea1SDimitry Andric StringRef Namespace; // The namespace the instruction is in. 227*0fca6ea1SDimitry Andric 228*0fca6ea1SDimitry Andric /// AsmString - The format string used to emit a .s file for the 229*0fca6ea1SDimitry Andric /// instruction. 230*0fca6ea1SDimitry Andric std::string AsmString; 231*0fca6ea1SDimitry Andric 232*0fca6ea1SDimitry Andric /// Operands - This is information about the (ins) and (outs) list specified 233*0fca6ea1SDimitry Andric /// to the instruction. 234*0fca6ea1SDimitry Andric CGIOperandList Operands; 235*0fca6ea1SDimitry Andric 236*0fca6ea1SDimitry Andric /// ImplicitDefs/ImplicitUses - These are lists of registers that are 237*0fca6ea1SDimitry Andric /// implicitly defined and used by the instruction. 238*0fca6ea1SDimitry Andric std::vector<Record *> ImplicitDefs, ImplicitUses; 239*0fca6ea1SDimitry Andric 240*0fca6ea1SDimitry Andric // Various boolean values we track for the instruction. 241*0fca6ea1SDimitry Andric bool isPreISelOpcode : 1; 242*0fca6ea1SDimitry Andric bool isReturn : 1; 243*0fca6ea1SDimitry Andric bool isEHScopeReturn : 1; 244*0fca6ea1SDimitry Andric bool isBranch : 1; 245*0fca6ea1SDimitry Andric bool isIndirectBranch : 1; 246*0fca6ea1SDimitry Andric bool isCompare : 1; 247*0fca6ea1SDimitry Andric bool isMoveImm : 1; 248*0fca6ea1SDimitry Andric bool isMoveReg : 1; 249*0fca6ea1SDimitry Andric bool isBitcast : 1; 250*0fca6ea1SDimitry Andric bool isSelect : 1; 251*0fca6ea1SDimitry Andric bool isBarrier : 1; 252*0fca6ea1SDimitry Andric bool isCall : 1; 253*0fca6ea1SDimitry Andric bool isAdd : 1; 254*0fca6ea1SDimitry Andric bool isTrap : 1; 255*0fca6ea1SDimitry Andric bool canFoldAsLoad : 1; 256*0fca6ea1SDimitry Andric bool mayLoad : 1; 257*0fca6ea1SDimitry Andric bool mayLoad_Unset : 1; 258*0fca6ea1SDimitry Andric bool mayStore : 1; 259*0fca6ea1SDimitry Andric bool mayStore_Unset : 1; 260*0fca6ea1SDimitry Andric bool mayRaiseFPException : 1; 261*0fca6ea1SDimitry Andric bool isPredicable : 1; 262*0fca6ea1SDimitry Andric bool isConvertibleToThreeAddress : 1; 263*0fca6ea1SDimitry Andric bool isCommutable : 1; 264*0fca6ea1SDimitry Andric bool isTerminator : 1; 265*0fca6ea1SDimitry Andric bool isReMaterializable : 1; 266*0fca6ea1SDimitry Andric bool hasDelaySlot : 1; 267*0fca6ea1SDimitry Andric bool usesCustomInserter : 1; 268*0fca6ea1SDimitry Andric bool hasPostISelHook : 1; 269*0fca6ea1SDimitry Andric bool hasCtrlDep : 1; 270*0fca6ea1SDimitry Andric bool isNotDuplicable : 1; 271*0fca6ea1SDimitry Andric bool hasSideEffects : 1; 272*0fca6ea1SDimitry Andric bool hasSideEffects_Unset : 1; 273*0fca6ea1SDimitry Andric bool isAsCheapAsAMove : 1; 274*0fca6ea1SDimitry Andric bool hasExtraSrcRegAllocReq : 1; 275*0fca6ea1SDimitry Andric bool hasExtraDefRegAllocReq : 1; 276*0fca6ea1SDimitry Andric bool isCodeGenOnly : 1; 277*0fca6ea1SDimitry Andric bool isPseudo : 1; 278*0fca6ea1SDimitry Andric bool isMeta : 1; 279*0fca6ea1SDimitry Andric bool isRegSequence : 1; 280*0fca6ea1SDimitry Andric bool isExtractSubreg : 1; 281*0fca6ea1SDimitry Andric bool isInsertSubreg : 1; 282*0fca6ea1SDimitry Andric bool isConvergent : 1; 283*0fca6ea1SDimitry Andric bool hasNoSchedulingInfo : 1; 284*0fca6ea1SDimitry Andric bool FastISelShouldIgnore : 1; 285*0fca6ea1SDimitry Andric bool hasChain : 1; 286*0fca6ea1SDimitry Andric bool hasChain_Inferred : 1; 287*0fca6ea1SDimitry Andric bool variadicOpsAreDefs : 1; 288*0fca6ea1SDimitry Andric bool isAuthenticated : 1; 289*0fca6ea1SDimitry Andric 290*0fca6ea1SDimitry Andric std::string DeprecatedReason; 291*0fca6ea1SDimitry Andric bool HasComplexDeprecationPredicate; 292*0fca6ea1SDimitry Andric 293*0fca6ea1SDimitry Andric /// Are there any undefined flags? 294*0fca6ea1SDimitry Andric bool hasUndefFlags() const { 295*0fca6ea1SDimitry Andric return mayLoad_Unset || mayStore_Unset || hasSideEffects_Unset; 296*0fca6ea1SDimitry Andric } 297*0fca6ea1SDimitry Andric 298*0fca6ea1SDimitry Andric // The record used to infer instruction flags, or NULL if no flag values 299*0fca6ea1SDimitry Andric // have been inferred. 300*0fca6ea1SDimitry Andric Record *InferredFrom; 301*0fca6ea1SDimitry Andric 302*0fca6ea1SDimitry Andric // The enum value assigned by CodeGenTarget::computeInstrsByEnum. 303*0fca6ea1SDimitry Andric mutable unsigned EnumVal = 0; 304*0fca6ea1SDimitry Andric 305*0fca6ea1SDimitry Andric CodeGenInstruction(Record *R); 306*0fca6ea1SDimitry Andric 307*0fca6ea1SDimitry Andric /// HasOneImplicitDefWithKnownVT - If the instruction has at least one 308*0fca6ea1SDimitry Andric /// implicit def and it has a known VT, return the VT, otherwise return 309*0fca6ea1SDimitry Andric /// MVT::Other. 310*0fca6ea1SDimitry Andric MVT::SimpleValueType 311*0fca6ea1SDimitry Andric HasOneImplicitDefWithKnownVT(const CodeGenTarget &TargetInfo) const; 312*0fca6ea1SDimitry Andric 313*0fca6ea1SDimitry Andric /// FlattenAsmStringVariants - Flatten the specified AsmString to only 314*0fca6ea1SDimitry Andric /// include text from the specified variant, returning the new string. 315*0fca6ea1SDimitry Andric static std::string FlattenAsmStringVariants(StringRef AsmString, 316*0fca6ea1SDimitry Andric unsigned Variant); 317*0fca6ea1SDimitry Andric 318*0fca6ea1SDimitry Andric // Is the specified operand in a generic instruction implicitly a pointer. 319*0fca6ea1SDimitry Andric // This can be used on intructions that use typeN or ptypeN to identify 320*0fca6ea1SDimitry Andric // operands that should be considered as pointers even though SelectionDAG 321*0fca6ea1SDimitry Andric // didn't make a distinction between integer and pointers. 322*0fca6ea1SDimitry Andric bool isInOperandAPointer(unsigned i) const { 323*0fca6ea1SDimitry Andric return isOperandImpl("InOperandList", i, "IsPointer"); 324*0fca6ea1SDimitry Andric } 325*0fca6ea1SDimitry Andric 326*0fca6ea1SDimitry Andric bool isOutOperandAPointer(unsigned i) const { 327*0fca6ea1SDimitry Andric return isOperandImpl("OutOperandList", i, "IsPointer"); 328*0fca6ea1SDimitry Andric } 329*0fca6ea1SDimitry Andric 330*0fca6ea1SDimitry Andric /// Check if the operand is required to be an immediate. 331*0fca6ea1SDimitry Andric bool isInOperandImmArg(unsigned i) const { 332*0fca6ea1SDimitry Andric return isOperandImpl("InOperandList", i, "IsImmediate"); 333*0fca6ea1SDimitry Andric } 334*0fca6ea1SDimitry Andric 335*0fca6ea1SDimitry Andric /// Return true if the instruction uses a variable length encoding. 336*0fca6ea1SDimitry Andric bool isVariableLengthEncoding() const { 337*0fca6ea1SDimitry Andric const RecordVal *RV = TheDef->getValue("Inst"); 338*0fca6ea1SDimitry Andric return RV && isa<DagInit>(RV->getValue()); 339*0fca6ea1SDimitry Andric } 340*0fca6ea1SDimitry Andric 341*0fca6ea1SDimitry Andric private: 342*0fca6ea1SDimitry Andric bool isOperandImpl(StringRef OpListName, unsigned i, 343*0fca6ea1SDimitry Andric StringRef PropertyName) const; 344*0fca6ea1SDimitry Andric }; 345*0fca6ea1SDimitry Andric } // namespace llvm 346*0fca6ea1SDimitry Andric 347*0fca6ea1SDimitry Andric #endif 348