MC/AsmMatcher: Fix indirect 80-col viola.
[oota-llvm.git] / utils / TableGen / CodeGenInstruction.h
index 9ced62005ae884be53736050a3a7117619a05d6c..d58bfb12968d1c709158148ce754942ea7e705c7 100644 (file)
@@ -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,6 +15,7 @@
 #define CODEGEN_INSTRUCTION_H
 
 #include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/ADT/StringRef.h"
 #include <string>
 #include <vector>
 #include <utility>
 namespace llvm {
   class Record;
   class DagInit;
-
-  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.
-
-    /// AsmString - The format string used to emit a .s file for the
-    /// instruction.
-    std::string AsmString;
+  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.
@@ -38,15 +64,19 @@ namespace llvm {
       /// 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;
+      
       /// 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
@@ -55,45 +85,225 @@ namespace llvm {
       /// 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;
-
-      OperandInfo(Record *R, const std::string &N, const std::string &PMN, 
-                  unsigned MION, unsigned MINO, DagInit *MIOI)
-        : Rec(R), Name(N), PrinterMethodName(PMN), MIOperandNo(MION),
-          MINumOperands(MINO), MIOperandInfo(MIOI) {}
+      
+      /// 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, 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<OperandInfo> OperandList;
+    
+    // Information gleaned from the operand list.
+    bool isPredicable;
+    bool hasOptionalDef;
+    bool isVariadic;
+    
+    // Provide transparent accessors to the operand list.
+    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<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 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 noResults;
+    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<ResultOperand> ResultOperands;
+    
+    CodeGenInstAlias(Record *R, CodeGenTarget &T);
+    
+    /// getResultInstOperandIndexForResultOperandIndex - Given an index into the
+    /// ResultOperands array, translate it to a valid index in ResultInst's
+    /// operand list.
+    unsigned getResultInstOperandIndexForResultOperandIndex(unsigned i) const;
+  };    
 }
 
 #endif