text: //===- CodeGenInstruction.h - Instruction Class Wrapper ---------*- C++ -*-===//
  //
  //                     The LLVM Compiler Infrastructure
  //
  // This file is distributed under the University of Illinois Open Source
  // License. See LICENSE.TXT for details.
  //
  //===----------------------------------------------------------------------===//
  //
  // This file defines a wrapper class for the 'Instruction' TableGen class.
  //
  //===----------------------------------------------------------------------===//
  
  #ifndef CODEGEN_INSTRUCTION_H
  #define CODEGEN_INSTRUCTION_H
  
  #include "llvm/ADT/StringRef.h"
  #include "llvm/CodeGen/ValueTypes.h"
  #include "llvm/Support/SourceMgr.h"
  #include <string>
  #include <utility>
  #include <vector>
  
  namespace llvm {
    class Record;
    class DagInit;
    class CodeGenTarget;
    class StringRef;
  
    class CGIOperandList {
    public:
      class ConstraintInfo {
        enum { None, EarlyClobber, Tied } Kind;
        unsigned OtherTiedOperand;
      public:
        ConstraintInfo() : Kind(None) {}
  
        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.
      struct OperandInfo {
        /// Rec - The definition this operand is declared as.
        ///
        Record *Rec;
  
        /// Name - If this operand was assigned a symbolic name, this is it,
        /// otherwise, it's empty.
        std::string Name;
  
        /// PrinterMethodName - The method used to print operands of this type in
        /// the asmprinter.
        std::string PrinterMethodName;
  
        /// EncoderMethodName - The method used to get the machine operand value
        /// for binary encoding. "getMachineOpValue" by default.
        std::string EncoderMethodName;
  
        /// OperandType - A value from MCOI::OperandType representing the type of
        /// the operand.
        std::string OperandType;
  
        /// 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
        /// MachineOperands.  Because of this, the operand number in the
        /// OperandList may not match the MachineInstr operand num.  Until it
        /// does, this contains the MI operand index of this operand.
        unsigned MIOperandNo;
        unsigned MINumOperands;   // The number of operands.
  
        /// 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<bool> 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<ConstraintInfo> Constraints;
  
        OperandInfo(Record *R, const std::string &N, const std::string &PMN,
                    const std::string &EMN, const std::string &OT, unsigned MION,
                    unsigned MINO, DagInit *MIOI)
        : Rec(R), Name(N), PrinterMethodName(PMN), EncoderMethodName(EMN),
          OperandType(OT), 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<OperandInfo> 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, abort.
      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 aborts if the name is invalid.  If AllowWholeOp is true, references
      /// to operands with suboperands are allowed, otherwise not.
      std::pair<unsigned,unsigned> ParseOperandName(const std::string &Op,
                                                    bool AllowWholeOp = true);
  
      /// getFlattenedOperandNumber - Flatten a operand/suboperand pair into a
      /// flat machineinstr operand #.
      unsigned getFlattenedOperandNumber(std::pair<unsigned,unsigned> Op) const {
        return OperandList[Op.first].MIOperandNo + Op.second;
      }
  
      /// getSubOperandNumber - Unflatten a operand number into an
      /// operand/suboperand pair.
      std::pair<unsigned,unsigned> 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<unsigned,unsigned> 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<Record*> ImplicitDefs, ImplicitUses;
  
      // Various boolean values we track for the instruction.
      bool isReturn;
      bool isBranch;
      bool isIndirectBranch;
      bool isCompare;
      bool isMoveImm;
      bool isBitcast;
      bool isSelect;
      bool isBarrier;
      bool isCall;
      bool canFoldAsLoad;
      bool mayLoad;
      bool mayLoad_Unset;
      bool mayStore;
      bool mayStore_Unset;
      bool isPredicable;
      bool isConvertibleToThreeAddress;
      bool isCommutable;
      bool isTerminator;
      bool isReMaterializable;
      bool hasDelaySlot;
      bool usesCustomInserter;
      bool hasPostISelHook;
      bool hasCtrlDep;
      bool isNotDuplicable;
      bool hasSideEffects;
      bool hasSideEffects_Unset;
      bool neverHasSideEffects;
      bool isAsCheapAsAMove;
      bool hasExtraSrcRegAllocReq;
      bool hasExtraDefRegAllocReq;
      bool isCodeGenOnly;
      bool isPseudo;
  
      /// Are there any undefined flags?
      bool hasUndefFlags() const {
        return mayLoad_Unset || mayStore_Unset || hasSideEffects_Unset;
      }
  
      // The record used to infer instruction flags, or NULL if no flag values
      // have been inferred.
      Record *InferredFrom;
  
      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:
        std::string Name;
        Record *R;
  
        int64_t Imm;
      public:
        enum {
          K_Record,
          K_Imm,
          K_Reg
        } Kind;
  
        ResultOperand(std::string 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<ResultOperand> 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<std::pair<unsigned, int> > ResultInstOperandIndex;
  
      CodeGenInstAlias(Record *R, CodeGenTarget &T);
  
      bool tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo,
                           Record *InstOpRec, bool hasSubOps, ArrayRef<SMLoc> Loc,
                           CodeGenTarget &T, ResultOperand &ResOp);
    };
  }
  
  #endif
  