X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FInlineAsm.h;h=58c1e84e53f1876e9e829a765f5e6c4d9b92b3f1;hb=5b957e6fd9853f938b8b33cfeb03d80595a9c2f8;hp=ed5bf8b38af12a165acfd68d03644bb8c79f4506;hpb=f792fa90f1125553008659c743cba85b9b5d2e5e;p=oota-llvm.git diff --git a/include/llvm/InlineAsm.h b/include/llvm/InlineAsm.h index ed5bf8b38af..58c1e84e53f 100644 --- a/include/llvm/InlineAsm.h +++ b/include/llvm/InlineAsm.h @@ -17,6 +17,7 @@ #define LLVM_INLINEASM_H #include "llvm/Value.h" +#include "llvm/ADT/StringRef.h" #include namespace llvm { @@ -32,20 +33,28 @@ template struct ConstantCreator; class InlineAsm : public Value { +public: + enum AsmDialect { + AD_ATT, + AD_Intel + }; + +private: friend struct ConstantCreator; friend class ConstantUniqueMap; - InlineAsm(const InlineAsm &); // do not implement - void operator=(const InlineAsm&); // do not implement + InlineAsm(const InlineAsm &) LLVM_DELETED_FUNCTION; + void operator=(const InlineAsm&) LLVM_DELETED_FUNCTION; std::string AsmString, Constraints; bool HasSideEffects; bool IsAlignStack; - - InlineAsm(const PointerType *Ty, const std::string &AsmString, + AsmDialect Dialect; + + InlineAsm(PointerType *Ty, const std::string &AsmString, const std::string &Constraints, bool hasSideEffects, - bool isAlignStack); + bool isAlignStack, AsmDialect asmDialect); virtual ~InlineAsm(); /// When the ConstantUniqueMap merges two types and makes two InlineAsms @@ -55,22 +64,24 @@ public: /// InlineAsm::get - Return the specified uniqued inline asm string. /// - static InlineAsm *get(const FunctionType *Ty, StringRef AsmString, + static InlineAsm *get(FunctionType *Ty, StringRef AsmString, StringRef Constraints, bool hasSideEffects, - bool isAlignStack = false); + bool isAlignStack = false, + AsmDialect asmDialect = AD_ATT); bool hasSideEffects() const { return HasSideEffects; } bool isAlignStack() const { return IsAlignStack; } - + AsmDialect getDialect() const { return Dialect; } + /// getType - InlineAsm's are always pointers. /// - const PointerType *getType() const { - return reinterpret_cast(Value::getType()); + PointerType *getType() const { + return reinterpret_cast(Value::getType()); } /// getFunctionType - InlineAsm's are always pointers to functions. /// - const FunctionType *getFunctionType() const; + FunctionType *getFunctionType() const; const std::string &getAsmString() const { return AsmString; } const std::string &getConstraintString() const { return Constraints; } @@ -79,7 +90,7 @@ public: /// the specified constraint string is legal for the type. This returns true /// if legal, false if not. /// - static bool Verify(const FunctionType *Ty, StringRef Constraints); + static bool Verify(FunctionType *Ty, StringRef Constraints); // Constraint String Parsing enum ConstraintPrefix { @@ -192,17 +203,18 @@ public: Op_InputChain = 0, Op_AsmString = 1, Op_MDNode = 2, - Op_ExtraInfo = 3, // HasSideEffects, IsAlignStack + Op_ExtraInfo = 3, // HasSideEffects, IsAlignStack, AsmDialect. Op_FirstOperand = 4, // Fixed operands on an INLINEASM MachineInstr. MIOp_AsmString = 0, - MIOp_ExtraInfo = 1, // HasSideEffects, IsAlignStack + MIOp_ExtraInfo = 1, // HasSideEffects, IsAlignStack, AsmDialect. MIOp_FirstOperand = 2, // Interpretation of the MIOp_ExtraInfo bit field. Extra_HasSideEffects = 1, Extra_IsAlignStack = 2, + Extra_AsmDialect = 4, // Inline asm operands map to multiple SDNode / MachineInstr operands. // The first operand is an immediate describing the asm operand, the low @@ -219,6 +231,7 @@ public: 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); } @@ -227,9 +240,24 @@ public: /// to a previous output operand. static unsigned getFlagWordForMatchingOp(unsigned InputFlag, unsigned MatchedOperandNo) { + assert(MatchedOperandNo <= 0x7fff && "Too big matched operand"); + assert((InputFlag & ~0xffff) == 0 && "High bits already contain data"); return InputFlag | Flag_MatchingOperand | (MatchedOperandNo << 16); } + /// getFlagWordForRegClass - Augment an existing flag word returned by + /// getFlagWord with the required register class for the following register + /// operands. + /// A tied use operand cannot have a register class, use the register class + /// from the def operand instead. + static unsigned getFlagWordForRegClass(unsigned InputFlag, unsigned RC) { + // Store RC + 1, reserve the value 0 to mean 'no register class'. + ++RC; + assert(RC <= 0x7fff && "Too large register class ID"); + assert((InputFlag & ~0xffff) == 0 && "High bits already contain data"); + return InputFlag | (RC << 16); + } + static unsigned getKind(unsigned Flags) { return Flags & 7; } @@ -259,6 +287,19 @@ public: return true; } + /// hasRegClassConstraint - Returns true if the flag contains a register + /// class constraint. Sets RC to the register class ID. + static bool hasRegClassConstraint(unsigned Flag, unsigned &RC) { + if (Flag & Flag_MatchingOperand) + return false; + unsigned High = Flag >> 16; + // getFlagWordForRegClass() uses 0 to mean no register class, and otherwise + // stores RC + 1. + if (!High) + return false; + RC = High - 1; + return true; + } };