xref: /openbsd-src/gnu/llvm/llvm/utils/TableGen/CodeGenInstruction.h (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
109467b48Spatrick //===- CodeGenInstruction.h - Instruction Class Wrapper ---------*- C++ -*-===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // This file defines a wrapper class for the 'Instruction' TableGen class.
1009467b48Spatrick //
1109467b48Spatrick //===----------------------------------------------------------------------===//
1209467b48Spatrick 
1309467b48Spatrick #ifndef LLVM_UTILS_TABLEGEN_CODEGENINSTRUCTION_H
1409467b48Spatrick #define LLVM_UTILS_TABLEGEN_CODEGENINSTRUCTION_H
1509467b48Spatrick 
16*d415bd75Srobert #include "llvm/ADT/BitVector.h"
17*d415bd75Srobert #include "llvm/ADT/StringMap.h"
1809467b48Spatrick #include "llvm/ADT/StringRef.h"
1909467b48Spatrick #include "llvm/Support/MachineValueType.h"
20097a140dSpatrick #include <cassert>
2109467b48Spatrick #include <string>
2209467b48Spatrick #include <utility>
2309467b48Spatrick #include <vector>
2409467b48Spatrick 
2509467b48Spatrick namespace llvm {
26*d415bd75Srobert class SMLoc;
2709467b48Spatrick template <typename T> class ArrayRef;
2809467b48Spatrick   class Record;
2909467b48Spatrick   class DagInit;
3009467b48Spatrick   class CodeGenTarget;
3109467b48Spatrick 
3209467b48Spatrick   class CGIOperandList {
3309467b48Spatrick   public:
3409467b48Spatrick     class ConstraintInfo {
3509467b48Spatrick       enum { None, EarlyClobber, Tied } Kind = None;
3609467b48Spatrick       unsigned OtherTiedOperand = 0;
3709467b48Spatrick 
3809467b48Spatrick     public:
3909467b48Spatrick       ConstraintInfo() = default;
4009467b48Spatrick 
getEarlyClobber()4109467b48Spatrick       static ConstraintInfo getEarlyClobber() {
4209467b48Spatrick         ConstraintInfo I;
4309467b48Spatrick         I.Kind = EarlyClobber;
4409467b48Spatrick         I.OtherTiedOperand = 0;
4509467b48Spatrick         return I;
4609467b48Spatrick       }
4709467b48Spatrick 
getTied(unsigned Op)4809467b48Spatrick       static ConstraintInfo getTied(unsigned Op) {
4909467b48Spatrick         ConstraintInfo I;
5009467b48Spatrick         I.Kind = Tied;
5109467b48Spatrick         I.OtherTiedOperand = Op;
5209467b48Spatrick         return I;
5309467b48Spatrick       }
5409467b48Spatrick 
isNone()5509467b48Spatrick       bool isNone() const { return Kind == None; }
isEarlyClobber()5609467b48Spatrick       bool isEarlyClobber() const { return Kind == EarlyClobber; }
isTied()5709467b48Spatrick       bool isTied() const { return Kind == Tied; }
5809467b48Spatrick 
getTiedOperand()5909467b48Spatrick       unsigned getTiedOperand() const {
6009467b48Spatrick         assert(isTied());
6109467b48Spatrick         return OtherTiedOperand;
6209467b48Spatrick       }
6309467b48Spatrick 
6409467b48Spatrick       bool operator==(const ConstraintInfo &RHS) const {
6509467b48Spatrick         if (Kind != RHS.Kind)
6609467b48Spatrick           return false;
6709467b48Spatrick         if (Kind == Tied && OtherTiedOperand != RHS.OtherTiedOperand)
6809467b48Spatrick           return false;
6909467b48Spatrick         return true;
7009467b48Spatrick       }
7109467b48Spatrick       bool operator!=(const ConstraintInfo &RHS) const {
7209467b48Spatrick         return !(*this == RHS);
7309467b48Spatrick       }
7409467b48Spatrick     };
7509467b48Spatrick 
7609467b48Spatrick     /// OperandInfo - The information we keep track of for each operand in the
7709467b48Spatrick     /// operand list for a tablegen instruction.
7809467b48Spatrick     struct OperandInfo {
7909467b48Spatrick       /// Rec - The definition this operand is declared as.
8009467b48Spatrick       ///
8109467b48Spatrick       Record *Rec;
8209467b48Spatrick 
8309467b48Spatrick       /// Name - If this operand was assigned a symbolic name, this is it,
8409467b48Spatrick       /// otherwise, it's empty.
8509467b48Spatrick       std::string Name;
8609467b48Spatrick 
87*d415bd75Srobert       /// The names of sub-operands, if given, otherwise empty.
88*d415bd75Srobert       std::vector<std::string> SubOpNames;
89*d415bd75Srobert 
9009467b48Spatrick       /// PrinterMethodName - The method used to print operands of this type in
9109467b48Spatrick       /// the asmprinter.
9209467b48Spatrick       std::string PrinterMethodName;
9309467b48Spatrick 
94*d415bd75Srobert       /// The method used to get the machine operand value for binary
95*d415bd75Srobert       /// encoding, per sub-operand. If empty, uses "getMachineOpValue".
96*d415bd75Srobert       std::vector<std::string> EncoderMethodNames;
9709467b48Spatrick 
9809467b48Spatrick       /// OperandType - A value from MCOI::OperandType representing the type of
9909467b48Spatrick       /// the operand.
10009467b48Spatrick       std::string OperandType;
10109467b48Spatrick 
10209467b48Spatrick       /// MIOperandNo - Currently (this is meant to be phased out), some logical
10309467b48Spatrick       /// operands correspond to multiple MachineInstr operands.  In the X86
10409467b48Spatrick       /// target for example, one address operand is represented as 4
10509467b48Spatrick       /// MachineOperands.  Because of this, the operand number in the
10609467b48Spatrick       /// OperandList may not match the MachineInstr operand num.  Until it
10709467b48Spatrick       /// does, this contains the MI operand index of this operand.
10809467b48Spatrick       unsigned MIOperandNo;
10909467b48Spatrick       unsigned MINumOperands;   // The number of operands.
11009467b48Spatrick 
11109467b48Spatrick       /// DoNotEncode - Bools are set to true in this vector for each operand in
11209467b48Spatrick       /// the DisableEncoding list.  These should not be emitted by the code
11309467b48Spatrick       /// emitter.
114*d415bd75Srobert       BitVector DoNotEncode;
11509467b48Spatrick 
11609467b48Spatrick       /// MIOperandInfo - Default MI operand type. Note an operand may be made
11709467b48Spatrick       /// up of multiple MI operands.
11809467b48Spatrick       DagInit *MIOperandInfo;
11909467b48Spatrick 
12009467b48Spatrick       /// Constraint info for this operand.  This operand can have pieces, so we
12109467b48Spatrick       /// track constraint info for each.
12209467b48Spatrick       std::vector<ConstraintInfo> Constraints;
12309467b48Spatrick 
OperandInfoOperandInfo12409467b48Spatrick       OperandInfo(Record *R, const std::string &N, const std::string &PMN,
125*d415bd75Srobert                   const std::string &OT, unsigned MION, unsigned MINO,
126*d415bd75Srobert                   DagInit *MIOI)
127*d415bd75Srobert           : Rec(R), Name(N), SubOpNames(MINO), PrinterMethodName(PMN),
128*d415bd75Srobert             EncoderMethodNames(MINO), OperandType(OT), MIOperandNo(MION),
129*d415bd75Srobert             MINumOperands(MINO), DoNotEncode(MINO), MIOperandInfo(MIOI),
130*d415bd75Srobert             Constraints(MINO) {}
13109467b48Spatrick 
13209467b48Spatrick       /// getTiedOperand - If this operand is tied to another one, return the
13309467b48Spatrick       /// other operand number.  Otherwise, return -1.
getTiedRegisterOperandInfo13409467b48Spatrick       int getTiedRegister() const {
13509467b48Spatrick         for (unsigned j = 0, e = Constraints.size(); j != e; ++j) {
13609467b48Spatrick           const CGIOperandList::ConstraintInfo &CI = Constraints[j];
13709467b48Spatrick           if (CI.isTied()) return CI.getTiedOperand();
13809467b48Spatrick         }
13909467b48Spatrick         return -1;
14009467b48Spatrick       }
14109467b48Spatrick     };
14209467b48Spatrick 
14309467b48Spatrick     CGIOperandList(Record *D);
14409467b48Spatrick 
14509467b48Spatrick     Record *TheDef;            // The actual record containing this OperandList.
14609467b48Spatrick 
14709467b48Spatrick     /// NumDefs - Number of def operands declared, this is the number of
14809467b48Spatrick     /// elements in the instruction's (outs) list.
14909467b48Spatrick     ///
15009467b48Spatrick     unsigned NumDefs;
15109467b48Spatrick 
15209467b48Spatrick     /// OperandList - The list of declared operands, along with their declared
15309467b48Spatrick     /// type (which is a record).
15409467b48Spatrick     std::vector<OperandInfo> OperandList;
15509467b48Spatrick 
156*d415bd75Srobert     /// SubOpAliases - List of alias names for suboperands.
157*d415bd75Srobert     StringMap<std::pair<unsigned, unsigned>> SubOpAliases;
158*d415bd75Srobert 
15909467b48Spatrick     // Information gleaned from the operand list.
16009467b48Spatrick     bool isPredicable;
16109467b48Spatrick     bool hasOptionalDef;
16209467b48Spatrick     bool isVariadic;
16309467b48Spatrick 
16409467b48Spatrick     // Provide transparent accessors to the operand list.
empty()16509467b48Spatrick     bool empty() const { return OperandList.empty(); }
size()16609467b48Spatrick     unsigned size() const { return OperandList.size(); }
16709467b48Spatrick     const OperandInfo &operator[](unsigned i) const { return OperandList[i]; }
16809467b48Spatrick     OperandInfo &operator[](unsigned i) { return OperandList[i]; }
back()16909467b48Spatrick     OperandInfo &back() { return OperandList.back(); }
back()17009467b48Spatrick     const OperandInfo &back() const { return OperandList.back(); }
17109467b48Spatrick 
17209467b48Spatrick     typedef std::vector<OperandInfo>::iterator iterator;
17309467b48Spatrick     typedef std::vector<OperandInfo>::const_iterator const_iterator;
begin()17409467b48Spatrick     iterator begin() { return OperandList.begin(); }
begin()17509467b48Spatrick     const_iterator begin() const { return OperandList.begin(); }
end()17609467b48Spatrick     iterator end() { return OperandList.end(); }
end()17709467b48Spatrick     const_iterator end() const { return OperandList.end(); }
17809467b48Spatrick 
17909467b48Spatrick     /// getOperandNamed - Return the index of the operand with the specified
18009467b48Spatrick     /// non-empty name.  If the instruction does not have an operand with the
18109467b48Spatrick     /// specified name, abort.
18209467b48Spatrick     unsigned getOperandNamed(StringRef Name) const;
18309467b48Spatrick 
18409467b48Spatrick     /// hasOperandNamed - Query whether the instruction has an operand of the
18509467b48Spatrick     /// given name. If so, return true and set OpIdx to the index of the
18609467b48Spatrick     /// operand. Otherwise, return false.
18709467b48Spatrick     bool hasOperandNamed(StringRef Name, unsigned &OpIdx) const;
18809467b48Spatrick 
189*d415bd75Srobert     bool hasSubOperandAlias(StringRef Name,
190*d415bd75Srobert                             std::pair<unsigned, unsigned> &SubOp) const;
191*d415bd75Srobert 
19209467b48Spatrick     /// ParseOperandName - Parse an operand name like "$foo" or "$foo.bar",
19309467b48Spatrick     /// where $foo is a whole operand and $foo.bar refers to a suboperand.
19409467b48Spatrick     /// This aborts if the name is invalid.  If AllowWholeOp is true, references
19509467b48Spatrick     /// to operands with suboperands are allowed, otherwise not.
19673471bf0Spatrick     std::pair<unsigned,unsigned> ParseOperandName(StringRef Op,
19709467b48Spatrick                                                   bool AllowWholeOp = true);
19809467b48Spatrick 
19909467b48Spatrick     /// getFlattenedOperandNumber - Flatten a operand/suboperand pair into a
20009467b48Spatrick     /// flat machineinstr operand #.
getFlattenedOperandNumber(std::pair<unsigned,unsigned> Op)20109467b48Spatrick     unsigned getFlattenedOperandNumber(std::pair<unsigned,unsigned> Op) const {
20209467b48Spatrick       return OperandList[Op.first].MIOperandNo + Op.second;
20309467b48Spatrick     }
20409467b48Spatrick 
20509467b48Spatrick     /// getSubOperandNumber - Unflatten a operand number into an
20609467b48Spatrick     /// operand/suboperand pair.
getSubOperandNumber(unsigned Op)20709467b48Spatrick     std::pair<unsigned,unsigned> getSubOperandNumber(unsigned Op) const {
20809467b48Spatrick       for (unsigned i = 0; ; ++i) {
20909467b48Spatrick         assert(i < OperandList.size() && "Invalid flat operand #");
21009467b48Spatrick         if (OperandList[i].MIOperandNo+OperandList[i].MINumOperands > Op)
21109467b48Spatrick           return std::make_pair(i, Op-OperandList[i].MIOperandNo);
21209467b48Spatrick       }
21309467b48Spatrick     }
21409467b48Spatrick 
21509467b48Spatrick 
21609467b48Spatrick     /// isFlatOperandNotEmitted - Return true if the specified flat operand #
21709467b48Spatrick     /// should not be emitted with the code emitter.
isFlatOperandNotEmitted(unsigned FlatOpNo)21809467b48Spatrick     bool isFlatOperandNotEmitted(unsigned FlatOpNo) const {
21909467b48Spatrick       std::pair<unsigned,unsigned> Op = getSubOperandNumber(FlatOpNo);
22009467b48Spatrick       if (OperandList[Op.first].DoNotEncode.size() > Op.second)
22109467b48Spatrick         return OperandList[Op.first].DoNotEncode[Op.second];
22209467b48Spatrick       return false;
22309467b48Spatrick     }
22409467b48Spatrick 
22573471bf0Spatrick     void ProcessDisableEncoding(StringRef Value);
22609467b48Spatrick   };
22709467b48Spatrick 
22809467b48Spatrick 
22909467b48Spatrick   class CodeGenInstruction {
23009467b48Spatrick   public:
23109467b48Spatrick     Record *TheDef;            // The actual record defining this instruction.
23209467b48Spatrick     StringRef Namespace;       // The namespace the instruction is in.
23309467b48Spatrick 
23409467b48Spatrick     /// AsmString - The format string used to emit a .s file for the
23509467b48Spatrick     /// instruction.
23609467b48Spatrick     std::string AsmString;
23709467b48Spatrick 
23809467b48Spatrick     /// Operands - This is information about the (ins) and (outs) list specified
23909467b48Spatrick     /// to the instruction.
24009467b48Spatrick     CGIOperandList Operands;
24109467b48Spatrick 
24209467b48Spatrick     /// ImplicitDefs/ImplicitUses - These are lists of registers that are
24309467b48Spatrick     /// implicitly defined and used by the instruction.
24409467b48Spatrick     std::vector<Record*> ImplicitDefs, ImplicitUses;
24509467b48Spatrick 
24609467b48Spatrick     // Various boolean values we track for the instruction.
24709467b48Spatrick     bool isPreISelOpcode : 1;
24809467b48Spatrick     bool isReturn : 1;
24909467b48Spatrick     bool isEHScopeReturn : 1;
25009467b48Spatrick     bool isBranch : 1;
25109467b48Spatrick     bool isIndirectBranch : 1;
25209467b48Spatrick     bool isCompare : 1;
25309467b48Spatrick     bool isMoveImm : 1;
25409467b48Spatrick     bool isMoveReg : 1;
25509467b48Spatrick     bool isBitcast : 1;
25609467b48Spatrick     bool isSelect : 1;
25709467b48Spatrick     bool isBarrier : 1;
25809467b48Spatrick     bool isCall : 1;
25909467b48Spatrick     bool isAdd : 1;
26009467b48Spatrick     bool isTrap : 1;
26109467b48Spatrick     bool canFoldAsLoad : 1;
26209467b48Spatrick     bool mayLoad : 1;
26309467b48Spatrick     bool mayLoad_Unset : 1;
26409467b48Spatrick     bool mayStore : 1;
26509467b48Spatrick     bool mayStore_Unset : 1;
26609467b48Spatrick     bool mayRaiseFPException : 1;
26709467b48Spatrick     bool isPredicable : 1;
26809467b48Spatrick     bool isConvertibleToThreeAddress : 1;
26909467b48Spatrick     bool isCommutable : 1;
27009467b48Spatrick     bool isTerminator : 1;
27109467b48Spatrick     bool isReMaterializable : 1;
27209467b48Spatrick     bool hasDelaySlot : 1;
27309467b48Spatrick     bool usesCustomInserter : 1;
27409467b48Spatrick     bool hasPostISelHook : 1;
27509467b48Spatrick     bool hasCtrlDep : 1;
27609467b48Spatrick     bool isNotDuplicable : 1;
27709467b48Spatrick     bool hasSideEffects : 1;
27809467b48Spatrick     bool hasSideEffects_Unset : 1;
27909467b48Spatrick     bool isAsCheapAsAMove : 1;
28009467b48Spatrick     bool hasExtraSrcRegAllocReq : 1;
28109467b48Spatrick     bool hasExtraDefRegAllocReq : 1;
28209467b48Spatrick     bool isCodeGenOnly : 1;
28309467b48Spatrick     bool isPseudo : 1;
284*d415bd75Srobert     bool isMeta : 1;
28509467b48Spatrick     bool isRegSequence : 1;
28609467b48Spatrick     bool isExtractSubreg : 1;
28709467b48Spatrick     bool isInsertSubreg : 1;
28809467b48Spatrick     bool isConvergent : 1;
28909467b48Spatrick     bool hasNoSchedulingInfo : 1;
29009467b48Spatrick     bool FastISelShouldIgnore : 1;
29109467b48Spatrick     bool hasChain : 1;
29209467b48Spatrick     bool hasChain_Inferred : 1;
29309467b48Spatrick     bool variadicOpsAreDefs : 1;
29409467b48Spatrick     bool isAuthenticated : 1;
29509467b48Spatrick 
29609467b48Spatrick     std::string DeprecatedReason;
29709467b48Spatrick     bool HasComplexDeprecationPredicate;
29809467b48Spatrick 
29909467b48Spatrick     /// Are there any undefined flags?
hasUndefFlags()30009467b48Spatrick     bool hasUndefFlags() const {
30109467b48Spatrick       return mayLoad_Unset || mayStore_Unset || hasSideEffects_Unset;
30209467b48Spatrick     }
30309467b48Spatrick 
30409467b48Spatrick     // The record used to infer instruction flags, or NULL if no flag values
30509467b48Spatrick     // have been inferred.
30609467b48Spatrick     Record *InferredFrom;
30709467b48Spatrick 
30809467b48Spatrick     CodeGenInstruction(Record *R);
30909467b48Spatrick 
31009467b48Spatrick     /// HasOneImplicitDefWithKnownVT - If the instruction has at least one
31109467b48Spatrick     /// implicit def and it has a known VT, return the VT, otherwise return
31209467b48Spatrick     /// MVT::Other.
31309467b48Spatrick     MVT::SimpleValueType
31409467b48Spatrick       HasOneImplicitDefWithKnownVT(const CodeGenTarget &TargetInfo) const;
31509467b48Spatrick 
31609467b48Spatrick 
31709467b48Spatrick     /// FlattenAsmStringVariants - Flatten the specified AsmString to only
31809467b48Spatrick     /// include text from the specified variant, returning the new string.
31909467b48Spatrick     static std::string FlattenAsmStringVariants(StringRef AsmString,
32009467b48Spatrick                                                 unsigned Variant);
32109467b48Spatrick 
32209467b48Spatrick     // Is the specified operand in a generic instruction implicitly a pointer.
32309467b48Spatrick     // This can be used on intructions that use typeN or ptypeN to identify
32409467b48Spatrick     // operands that should be considered as pointers even though SelectionDAG
32509467b48Spatrick     // didn't make a distinction between integer and pointers.
isInOperandAPointer(unsigned i)326*d415bd75Srobert     bool isInOperandAPointer(unsigned i) const {
327*d415bd75Srobert       return isOperandImpl("InOperandList", i, "IsPointer");
328*d415bd75Srobert     }
329*d415bd75Srobert 
isOutOperandAPointer(unsigned i)330*d415bd75Srobert     bool isOutOperandAPointer(unsigned i) const {
331*d415bd75Srobert       return isOperandImpl("OutOperandList", i, "IsPointer");
33209467b48Spatrick     }
33309467b48Spatrick 
33409467b48Spatrick     /// Check if the operand is required to be an immediate.
isInOperandImmArg(unsigned i)335*d415bd75Srobert     bool isInOperandImmArg(unsigned i) const {
336*d415bd75Srobert       return isOperandImpl("InOperandList", i, "IsImmediate");
33709467b48Spatrick     }
33809467b48Spatrick 
33909467b48Spatrick   private:
340*d415bd75Srobert     bool isOperandImpl(StringRef OpListName, unsigned i,
341*d415bd75Srobert                        StringRef PropertyName) const;
34209467b48Spatrick   };
34309467b48Spatrick 
34409467b48Spatrick 
34509467b48Spatrick   /// CodeGenInstAlias - This represents an InstAlias definition.
34609467b48Spatrick   class CodeGenInstAlias {
34709467b48Spatrick   public:
34809467b48Spatrick     Record *TheDef;            // The actual record defining this InstAlias.
34909467b48Spatrick 
35009467b48Spatrick     /// AsmString - The format string used to emit a .s file for the
35109467b48Spatrick     /// instruction.
35209467b48Spatrick     std::string AsmString;
35309467b48Spatrick 
35409467b48Spatrick     /// Result - The result instruction.
35509467b48Spatrick     DagInit *Result;
35609467b48Spatrick 
35709467b48Spatrick     /// ResultInst - The instruction generated by the alias (decoded from
35809467b48Spatrick     /// Result).
35909467b48Spatrick     CodeGenInstruction *ResultInst;
36009467b48Spatrick 
36109467b48Spatrick 
36209467b48Spatrick     struct ResultOperand {
36309467b48Spatrick     private:
36409467b48Spatrick       std::string Name;
36509467b48Spatrick       Record *R = nullptr;
36609467b48Spatrick       int64_t Imm = 0;
36709467b48Spatrick 
36809467b48Spatrick     public:
36909467b48Spatrick       enum {
37009467b48Spatrick         K_Record,
37109467b48Spatrick         K_Imm,
37209467b48Spatrick         K_Reg
37309467b48Spatrick       } Kind;
37409467b48Spatrick 
ResultOperandResultOperand37509467b48Spatrick       ResultOperand(std::string N, Record *r)
37609467b48Spatrick           : Name(std::move(N)), R(r), Kind(K_Record) {}
ResultOperandResultOperand37709467b48Spatrick       ResultOperand(int64_t I) : Imm(I), Kind(K_Imm) {}
ResultOperandResultOperand37809467b48Spatrick       ResultOperand(Record *r) : R(r), Kind(K_Reg) {}
37909467b48Spatrick 
isRecordResultOperand38009467b48Spatrick       bool isRecord() const { return Kind == K_Record; }
isImmResultOperand38109467b48Spatrick       bool isImm() const { return Kind == K_Imm; }
isRegResultOperand38209467b48Spatrick       bool isReg() const { return Kind == K_Reg; }
38309467b48Spatrick 
getNameResultOperand38409467b48Spatrick       StringRef getName() const { assert(isRecord()); return Name; }
getRecordResultOperand38509467b48Spatrick       Record *getRecord() const { assert(isRecord()); return R; }
getImmResultOperand38609467b48Spatrick       int64_t getImm() const { assert(isImm()); return Imm; }
getRegisterResultOperand38709467b48Spatrick       Record *getRegister() const { assert(isReg()); return R; }
38809467b48Spatrick 
38909467b48Spatrick       unsigned getMINumOperands() const;
39009467b48Spatrick     };
39109467b48Spatrick 
39209467b48Spatrick     /// ResultOperands - The decoded operands for the result instruction.
39309467b48Spatrick     std::vector<ResultOperand> ResultOperands;
39409467b48Spatrick 
39509467b48Spatrick     /// ResultInstOperandIndex - For each operand, this vector holds a pair of
39609467b48Spatrick     /// indices to identify the corresponding operand in the result
39709467b48Spatrick     /// instruction.  The first index specifies the operand and the second
39809467b48Spatrick     /// index specifies the suboperand.  If there are no suboperands or if all
39909467b48Spatrick     /// of them are matched by the operand, the second value should be -1.
40009467b48Spatrick     std::vector<std::pair<unsigned, int> > ResultInstOperandIndex;
40109467b48Spatrick 
40209467b48Spatrick     CodeGenInstAlias(Record *R, CodeGenTarget &T);
40309467b48Spatrick 
40409467b48Spatrick     bool tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo,
40509467b48Spatrick                          Record *InstOpRec, bool hasSubOps, ArrayRef<SMLoc> Loc,
40609467b48Spatrick                          CodeGenTarget &T, ResultOperand &ResOp);
40709467b48Spatrick   };
40809467b48Spatrick }
40909467b48Spatrick 
41009467b48Spatrick #endif
411