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