Merging r258611:
[oota-llvm.git] / include / llvm / IR / InlineAsm.h
index ac190892bab011f44c59c0b6532c2115306bea69..d2e9e48539ceb430d393fb50946299f4ef994f06 100644 (file)
@@ -25,12 +25,9 @@ namespace llvm {
 class PointerType;
 class FunctionType;
 class Module;
+
 struct InlineAsmKeyType;
-template<class ValType, class ValRefType, class TypeClass, class ConstantClass,
-         bool HasLargeKey>
-class ConstantUniqueMap;
-template<class ConstantClass, class TypeClass, class ValType>
-struct ConstantCreator;
+template <class ConstantClass> class ConstantUniqueMap;
 
 class InlineAsm : public Value {
 public:
@@ -40,35 +37,35 @@ public:
   };
 
 private:
-  friend struct ConstantCreator<InlineAsm, PointerType, InlineAsmKeyType>;
-  friend class ConstantUniqueMap<InlineAsmKeyType, const InlineAsmKeyType&,
-                                 PointerType, InlineAsm, false>;
+  friend struct InlineAsmKeyType;
+  friend class ConstantUniqueMap<InlineAsm>;
 
-  InlineAsm(const InlineAsm &) LLVM_DELETED_FUNCTION;
-  void operator=(const InlineAsm&) LLVM_DELETED_FUNCTION;
+  InlineAsm(const InlineAsm &) = delete;
+  void operator=(const InlineAsm&) = delete;
 
   std::string AsmString, Constraints;
+  FunctionType *FTy;
   bool HasSideEffects;
   bool IsAlignStack;
   AsmDialect Dialect;
 
-  InlineAsm(PointerType *Ty, const std::string &AsmString,
+  InlineAsm(FunctionType *Ty, const std::string &AsmString,
             const std::string &Constraints, bool hasSideEffects,
             bool isAlignStack, AsmDialect asmDialect);
-  virtual ~InlineAsm();
+  ~InlineAsm() override;
 
   /// When the ConstantUniqueMap merges two types and makes two InlineAsms
   /// identical, it destroys one of them with this method.
   void destroyConstant();
-public:
 
+public:
   /// InlineAsm::get - Return the specified uniqued inline asm string.
   ///
   static InlineAsm *get(FunctionType *Ty, StringRef AsmString,
                         StringRef Constraints, bool hasSideEffects,
                         bool isAlignStack = false,
                         AsmDialect asmDialect = AD_ATT);
-  
+
   bool hasSideEffects() const { return HasSideEffects; }
   bool isAlignStack() const { return IsAlignStack; }
   AsmDialect getDialect() const { return Dialect; }
@@ -78,11 +75,11 @@ public:
   PointerType *getType() const {
     return reinterpret_cast<PointerType*>(Value::getType());
   }
-  
+
   /// getFunctionType - InlineAsm's are always pointers to functions.
   ///
   FunctionType *getFunctionType() const;
-  
+
   const std::string &getAsmString() const { return AsmString; }
   const std::string &getConstraintString() const { return Constraints; }
 
@@ -92,15 +89,15 @@ public:
   ///
   static bool Verify(FunctionType *Ty, StringRef Constraints);
 
-  // Constraint String Parsing 
+  // Constraint String Parsing
   enum ConstraintPrefix {
     isInput,            // 'x'
     isOutput,           // '=x'
     isClobber           // '~x'
   };
-  
+
   typedef std::vector<std::string> ConstraintCodeVector;
-  
+
   struct SubConstraintInfo {
     /// MatchingInput - If this is not -1, this is an output constraint where an
     /// input constraint is required to match it (e.g. "0").  The value is the
@@ -117,83 +114,96 @@ public:
   typedef std::vector<SubConstraintInfo> SubConstraintInfoVector;
   struct ConstraintInfo;
   typedef std::vector<ConstraintInfo> ConstraintInfoVector;
-  
+
   struct ConstraintInfo {
     /// Type - The basic type of the constraint: input/output/clobber
     ///
     ConstraintPrefix Type;
-    
+
     /// isEarlyClobber - "&": output operand writes result before inputs are all
     /// read.  This is only ever set for an output operand.
-    bool isEarlyClobber; 
-    
+    bool isEarlyClobber;
+
     /// MatchingInput - If this is not -1, this is an output constraint where an
     /// input constraint is required to match it (e.g. "0").  The value is the
     /// constraint number that matches this one (for example, if this is
     /// constraint #0 and constraint #4 has the value "0", this will be 4).
     signed char MatchingInput;
-    
+
     /// hasMatchingInput - Return true if this is an output constraint that has
     /// a matching input constraint.
     bool hasMatchingInput() const { return MatchingInput != -1; }
-    
+
     /// isCommutative - This is set to true for a constraint that is commutative
     /// with the next operand.
     bool isCommutative;
-    
+
     /// isIndirect - True if this operand is an indirect operand.  This means
     /// that the address of the source or destination is present in the call
     /// instruction, instead of it being returned or passed in explicitly.  This
     /// is represented with a '*' in the asm string.
     bool isIndirect;
-    
+
     /// Code - The constraint code, either the register name (in braces) or the
     /// constraint letter/number.
     ConstraintCodeVector Codes;
-    
+
     /// isMultipleAlternative - '|': has multiple-alternative constraints.
     bool isMultipleAlternative;
-    
+
     /// multipleAlternatives - If there are multiple alternative constraints,
     /// this array will contain them.  Otherwise it will be empty.
     SubConstraintInfoVector multipleAlternatives;
-    
+
     /// The currently selected alternative constraint index.
     unsigned currentAlternativeIndex;
-    
-    ///Default constructor.
+
+    /// Default constructor.
     ConstraintInfo();
-    
+
     /// Parse - Analyze the specified string (e.g. "=*&{eax}") and fill in the
     /// fields in this structure.  If the constraint string is not understood,
     /// return true, otherwise return false.
     bool Parse(StringRef Str, ConstraintInfoVector &ConstraintsSoFar);
-               
+
     /// selectAlternative - Point this constraint to the alternative constraint
     /// indicated by the index.
     void selectAlternative(unsigned index);
   };
-  
+
   /// ParseConstraints - Split up the constraint string into the specific
   /// constraints and their prefixes.  If this returns an empty vector, and if
   /// the constraint string itself isn't empty, there was an error parsing.
   static ConstraintInfoVector ParseConstraints(StringRef ConstraintString);
-  
-  /// ParseConstraints - Parse the constraints of this inlineasm object, 
+
+  /// ParseConstraints - Parse the constraints of this inlineasm object,
   /// returning them the same way that ParseConstraints(str) does.
   ConstraintInfoVector ParseConstraints() const {
     return ParseConstraints(Constraints);
   }
-  
+
   // Methods for support type inquiry through isa, cast, and dyn_cast:
   static inline bool classof(const Value *V) {
     return V->getValueID() == Value::InlineAsmVal;
   }
 
-  
   // These are helper methods for dealing with flags in the INLINEASM SDNode
   // in the backend.
-  
+  //
+  // The encoding of the flag word is currently:
+  //   Bits 2-0 - A Kind_* value indicating the kind of the operand.
+  //   Bits 15-3 - The number of SDNode operands associated with this inline
+  //               assembly operand.
+  //   If bit 31 is set:
+  //     Bit 30-16 - The operand number that this operand must match.
+  //                 When bits 2-0 are Kind_Mem, the Constraint_* value must be
+  //                 obtained from the flags for this operand number.
+  //   Else if bits 2-0 are Kind_Mem:
+  //     Bit 30-16 - A Constraint_* value indicating the original constraint
+  //                 code.
+  //   Else:
+  //     Bit 30-16 - The register class ID to use for the operand.
+
   enum : uint32_t {
     // Fixed operands on an INLINEASM SDNode.
     Op_InputChain = 0,
@@ -224,17 +234,45 @@ public:
     Kind_Imm = 5,                // Immediate.
     Kind_Mem = 6,                // Memory operand, "m".
 
+    // Memory constraint codes.
+    // These could be tablegenerated but there's little need to do that since
+    // there's plenty of space in the encoding to support the union of all
+    // constraint codes for all targets.
+    Constraint_Unknown = 0,
+    Constraint_es,
+    Constraint_i,
+    Constraint_m,
+    Constraint_o,
+    Constraint_v,
+    Constraint_Q,
+    Constraint_R,
+    Constraint_S,
+    Constraint_T,
+    Constraint_Um,
+    Constraint_Un,
+    Constraint_Uq,
+    Constraint_Us,
+    Constraint_Ut,
+    Constraint_Uv,
+    Constraint_Uy,
+    Constraint_X,
+    Constraint_Z,
+    Constraint_ZC,
+    Constraint_Zy,
+    Constraints_Max = Constraint_Zy,
+    Constraints_ShiftAmount = 16,
+
     Flag_MatchingOperand = 0x80000000
   };
-  
+
   static unsigned getFlagWord(unsigned Kind, unsigned NumOps) {
     assert(((NumOps << 3) & ~0xffff) == 0 && "Too many inline asm operands!");
     assert(Kind >= Kind_RegUse && Kind <= Kind_Mem && "Invalid Kind");
     return Kind | (NumOps << 3);
   }
-  
+
   /// getFlagWordForMatchingOp - Augment an existing flag word returned by
-  /// getFlagWord with information indicating that this input operand is tied 
+  /// getFlagWord with information indicating that this input operand is tied
   /// to a previous output operand.
   static unsigned getFlagWordForMatchingOp(unsigned InputFlag,
                                            unsigned MatchedOperandNo) {
@@ -256,6 +294,20 @@ public:
     return InputFlag | (RC << 16);
   }
 
+  /// Augment an existing flag word returned by getFlagWord with the constraint
+  /// code for a memory constraint.
+  static unsigned getFlagWordForMem(unsigned InputFlag, unsigned Constraint) {
+    assert(Constraint <= 0x7fff && "Too large a memory constraint ID");
+    assert(Constraint <= Constraints_Max && "Unknown constraint ID");
+    assert((InputFlag & ~0xffff) == 0 && "High bits already contain data");
+    return InputFlag | (Constraint << Constraints_ShiftAmount);
+  }
+
+  static unsigned convertMemFlagWordToMatchingFlagWord(unsigned InputFlag) {
+    assert(isMemKind(InputFlag));
+    return InputFlag & ~(0x7fff << Constraints_ShiftAmount);
+  }
+
   static unsigned getKind(unsigned Flags) {
     return Flags & 7;
   }
@@ -270,6 +322,11 @@ public:
     return getKind(Flag) == Kind_Clobber;
   }
 
+  static unsigned getMemoryConstraintID(unsigned Flag) {
+    assert(isMemKind(Flag));
+    return (Flag >> Constraints_ShiftAmount) & 0x7fff;
+  }
+
   /// getNumOperandRegisters - Extract the number of registers field from the
   /// inline asm operand flag.
   static unsigned getNumOperandRegisters(unsigned Flag) {
@@ -298,7 +355,6 @@ public:
     RC = High - 1;
     return true;
   }
-
 };
 
 } // End llvm namespace