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