xref: /freebsd-src/contrib/llvm-project/llvm/utils/TableGen/Common/CodeGenInstruction.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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