X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FCodeGenInstruction.h;h=5f1e0bea7666d59eed526dbee5c631196f5ac5cd;hb=c017bc1c1e2fa0995e957f6c2ada1339832bb221;hp=669280c1bbc8eb007bffb7dc18c2570bd7479a87;hpb=8b50f9b8dcd6da00ddc961ecda967719eb745dee;p=oota-llvm.git diff --git a/utils/TableGen/CodeGenInstruction.h b/utils/TableGen/CodeGenInstruction.h index 669280c1bbc..5f1e0bea766 100644 --- a/utils/TableGen/CodeGenInstruction.h +++ b/utils/TableGen/CodeGenInstruction.h @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -15,21 +15,49 @@ #define CODEGEN_INSTRUCTION_H #include "llvm/CodeGen/ValueTypes.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/SourceMgr.h" #include #include #include namespace llvm { class Record; + class DagInit; + class CodeGenTarget; + class StringRef; - struct CodeGenInstruction { - Record *TheDef; // The actual record defining this instruction. - std::string Name; // Contents of the 'Name' field. - std::string Namespace; // The namespace the instruction is in. + class CGIOperandList { + public: + class ConstraintInfo { + enum { None, EarlyClobber, Tied } Kind; + unsigned OtherTiedOperand; + public: + ConstraintInfo() : Kind(None) {} - /// AsmString - The format string used to emit a .s file for the - /// instruction. - std::string AsmString; + static ConstraintInfo getEarlyClobber() { + ConstraintInfo I; + I.Kind = EarlyClobber; + I.OtherTiedOperand = 0; + return I; + } + + static ConstraintInfo getTied(unsigned Op) { + ConstraintInfo I; + I.Kind = Tied; + I.OtherTiedOperand = Op; + return I; + } + + bool isNone() const { return Kind == None; } + bool isEarlyClobber() const { return Kind == EarlyClobber; } + bool isTied() const { return Kind == Tied; } + + unsigned getTiedOperand() const { + assert(isTied()); + return OtherTiedOperand; + } + }; /// OperandInfo - The information we keep track of for each operand in the /// operand list for a tablegen instruction. @@ -38,10 +66,6 @@ namespace llvm { /// Record *Rec; - /// Ty - The MachineValueType of the operand. - /// - MVT::ValueType Ty; - /// Name - If this operand was assigned a symbolic name, this is it, /// otherwise, it's empty. std::string Name; @@ -50,6 +74,10 @@ namespace llvm { /// the asmprinter. std::string PrinterMethodName; + /// EncoderMethodName - The method used to get the machine operand value + /// for binary encoding. "getMachineOpValue" by default. + std::string EncoderMethodName; + /// MIOperandNo - Currently (this is meant to be phased out), some logical /// operands correspond to multiple MachineInstr operands. In the X86 /// target for example, one address operand is represented as 4 @@ -59,37 +87,231 @@ namespace llvm { unsigned MIOperandNo; unsigned MINumOperands; // The number of operands. - OperandInfo(Record *R, MVT::ValueType T, const std::string &N, - const std::string &PMN, unsigned MION, unsigned MINO) - : Rec(R), Ty(T), Name(N), PrinterMethodName(PMN), MIOperandNo(MION), - MINumOperands(MINO) {} + /// DoNotEncode - Bools are set to true in this vector for each operand in + /// the DisableEncoding list. These should not be emitted by the code + /// emitter. + std::vector DoNotEncode; + + /// MIOperandInfo - Default MI operand type. Note an operand may be made + /// up of multiple MI operands. + DagInit *MIOperandInfo; + + /// Constraint info for this operand. This operand can have pieces, so we + /// track constraint info for each. + std::vector Constraints; + + OperandInfo(Record *R, const std::string &N, const std::string &PMN, + const std::string &EMN, unsigned MION, unsigned MINO, + DagInit *MIOI) + : Rec(R), Name(N), PrinterMethodName(PMN), EncoderMethodName(EMN), + MIOperandNo(MION), MINumOperands(MINO), MIOperandInfo(MIOI) {} + + + /// getTiedOperand - If this operand is tied to another one, return the + /// other operand number. Otherwise, return -1. + int getTiedRegister() const { + for (unsigned j = 0, e = Constraints.size(); j != e; ++j) { + const CGIOperandList::ConstraintInfo &CI = Constraints[j]; + if (CI.isTied()) return CI.getTiedOperand(); + } + return -1; + } }; + CGIOperandList(Record *D); + + Record *TheDef; // The actual record containing this OperandList. + + /// NumDefs - Number of def operands declared, this is the number of + /// elements in the instruction's (outs) list. + /// + unsigned NumDefs; + /// OperandList - The list of declared operands, along with their declared /// type (which is a record). std::vector OperandList; + // Information gleaned from the operand list. + bool isPredicable; + bool hasOptionalDef; + bool isVariadic; + + // Provide transparent accessors to the operand list. + bool empty() const { return OperandList.empty(); } + unsigned size() const { return OperandList.size(); } + const OperandInfo &operator[](unsigned i) const { return OperandList[i]; } + OperandInfo &operator[](unsigned i) { return OperandList[i]; } + OperandInfo &back() { return OperandList.back(); } + const OperandInfo &back() const { return OperandList.back(); } + + + /// getOperandNamed - Return the index of the operand with the specified + /// non-empty name. If the instruction does not have an operand with the + /// specified name, throw an exception. + unsigned getOperandNamed(StringRef Name) const; + + /// hasOperandNamed - Query whether the instruction has an operand of the + /// given name. If so, return true and set OpIdx to the index of the + /// operand. Otherwise, return false. + bool hasOperandNamed(StringRef Name, unsigned &OpIdx) const; + + /// ParseOperandName - Parse an operand name like "$foo" or "$foo.bar", + /// where $foo is a whole operand and $foo.bar refers to a suboperand. + /// This throws an exception if the name is invalid. If AllowWholeOp is + /// true, references to operands with suboperands are allowed, otherwise + /// not. + std::pair ParseOperandName(const std::string &Op, + bool AllowWholeOp = true); + + /// getFlattenedOperandNumber - Flatten a operand/suboperand pair into a + /// flat machineinstr operand #. + unsigned getFlattenedOperandNumber(std::pair Op) const { + return OperandList[Op.first].MIOperandNo + Op.second; + } + + /// getSubOperandNumber - Unflatten a operand number into an + /// operand/suboperand pair. + std::pair getSubOperandNumber(unsigned Op) const { + for (unsigned i = 0; ; ++i) { + assert(i < OperandList.size() && "Invalid flat operand #"); + if (OperandList[i].MIOperandNo+OperandList[i].MINumOperands > Op) + return std::make_pair(i, Op-OperandList[i].MIOperandNo); + } + } + + + /// isFlatOperandNotEmitted - Return true if the specified flat operand # + /// should not be emitted with the code emitter. + bool isFlatOperandNotEmitted(unsigned FlatOpNo) const { + std::pair Op = getSubOperandNumber(FlatOpNo); + if (OperandList[Op.first].DoNotEncode.size() > Op.second) + return OperandList[Op.first].DoNotEncode[Op.second]; + return false; + } + + void ProcessDisableEncoding(std::string Value); + }; + + + class CodeGenInstruction { + public: + Record *TheDef; // The actual record defining this instruction. + std::string Namespace; // The namespace the instruction is in. + + /// AsmString - The format string used to emit a .s file for the + /// instruction. + std::string AsmString; + + /// Operands - This is information about the (ins) and (outs) list specified + /// to the instruction. + CGIOperandList Operands; + + /// ImplicitDefs/ImplicitUses - These are lists of registers that are + /// implicitly defined and used by the instruction. + std::vector ImplicitDefs, ImplicitUses; + // Various boolean values we track for the instruction. bool isReturn; bool isBranch; + bool isIndirectBranch; + bool isCompare; + bool isMoveImm; + bool isBitcast; bool isBarrier; bool isCall; - bool isLoad; - bool isStore; - bool isTwoAddress; + bool canFoldAsLoad; + bool mayLoad, mayStore; + bool isPredicable; bool isConvertibleToThreeAddress; bool isCommutable; bool isTerminator; + bool isReMaterializable; bool hasDelaySlot; - bool usesCustomDAGSChedInserter; - bool hasVariableNumberOfOperands; + bool usesCustomInserter; + bool hasCtrlDep; + bool isNotDuplicable; + bool hasSideEffects; + bool neverHasSideEffects; + bool isAsCheapAsAMove; + bool hasExtraSrcRegAllocReq; + bool hasExtraDefRegAllocReq; - CodeGenInstruction(Record *R, const std::string &AsmStr); - /// getOperandNamed - Return the index of the operand with the specified - /// non-empty name. If the instruction does not have an operand with the - /// specified name, throw an exception. - unsigned getOperandNamed(const std::string &Name) const; + CodeGenInstruction(Record *R); + + /// HasOneImplicitDefWithKnownVT - If the instruction has at least one + /// implicit def and it has a known VT, return the VT, otherwise return + /// MVT::Other. + MVT::SimpleValueType + HasOneImplicitDefWithKnownVT(const CodeGenTarget &TargetInfo) const; + + + /// FlattenAsmStringVariants - Flatten the specified AsmString to only + /// include text from the specified variant, returning the new string. + static std::string FlattenAsmStringVariants(StringRef AsmString, + unsigned Variant); + }; + + + /// CodeGenInstAlias - This represents an InstAlias definition. + class CodeGenInstAlias { + public: + Record *TheDef; // The actual record defining this InstAlias. + + /// AsmString - The format string used to emit a .s file for the + /// instruction. + std::string AsmString; + + /// Result - The result instruction. + DagInit *Result; + + /// ResultInst - The instruction generated by the alias (decoded from + /// Result). + CodeGenInstruction *ResultInst; + + + struct ResultOperand { + private: + StringRef Name; + Record *R; + + int64_t Imm; + public: + enum { + K_Record, + K_Imm, + K_Reg + } Kind; + + ResultOperand(StringRef N, Record *r) : Name(N), R(r), Kind(K_Record) {} + ResultOperand(int64_t I) : Imm(I), Kind(K_Imm) {} + ResultOperand(Record *r) : R(r), Kind(K_Reg) {} + + bool isRecord() const { return Kind == K_Record; } + bool isImm() const { return Kind == K_Imm; } + bool isReg() const { return Kind == K_Reg; } + + StringRef getName() const { assert(isRecord()); return Name; } + Record *getRecord() const { assert(isRecord()); return R; } + int64_t getImm() const { assert(isImm()); return Imm; } + Record *getRegister() const { assert(isReg()); return R; } + }; + + /// ResultOperands - The decoded operands for the result instruction. + std::vector ResultOperands; + + /// ResultInstOperandIndex - For each operand, this vector holds a pair of + /// indices to identify the corresponding operand in the result + /// instruction. The first index specifies the operand and the second + /// index specifies the suboperand. If there are no suboperands or if all + /// of them are matched by the operand, the second value should be -1. + std::vector > ResultInstOperandIndex; + + CodeGenInstAlias(Record *R, CodeGenTarget &T); + + bool tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo, + Record *InstOpRec, bool hasSubOps, SMLoc Loc, + CodeGenTarget &T, ResultOperand &ResOp); }; }