diff options
author | Chris Lattner <sabre@nondot.org> | 2006-01-25 22:26:43 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2006-01-25 22:26:43 +0000 |
commit | aa2c85376611f7c458232845585912b541bdc680 (patch) | |
tree | 8fa392fc06bb1568008bcadc8524d832415dcc18 /lib/AsmParser | |
parent | 80cd11561892a639a2628d19815af0695b5dbcaa (diff) | |
download | external_llvm-aa2c85376611f7c458232845585912b541bdc680.zip external_llvm-aa2c85376611f7c458232845585912b541bdc680.tar.gz external_llvm-aa2c85376611f7c458232845585912b541bdc680.tar.bz2 |
Parse inline asm objects
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25618 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AsmParser')
-rw-r--r-- | lib/AsmParser/Lexer.l | 1 | ||||
-rw-r--r-- | lib/AsmParser/ParserInternals.h | 27 | ||||
-rw-r--r-- | lib/AsmParser/llvmAsmParser.y | 31 |
3 files changed, 56 insertions, 3 deletions
diff --git a/lib/AsmParser/Lexer.l b/lib/AsmParser/Lexer.l index 772023b..71482e0 100644 --- a/lib/AsmParser/Lexer.l +++ b/lib/AsmParser/Lexer.l @@ -214,6 +214,7 @@ align { return ALIGN; } section { return SECTION; } module { return MODULE; } asm { return ASM_TOK; } +sideeffect { return SIDEEFFECT; } cc { return CC_TOK; } ccc { return CCC_TOK; } diff --git a/lib/AsmParser/ParserInternals.h b/lib/AsmParser/ParserInternals.h index 6f747c7..820e5ba 100644 --- a/lib/AsmParser/ParserInternals.h +++ b/lib/AsmParser/ParserInternals.h @@ -72,6 +72,17 @@ static inline void ThrowException(const std::string &message, throw ParseException(CurFilename, message, LineNo); } +/// InlineAsmDescriptor - This is a simple class that holds info about inline +/// asm blocks, for use by ValID. +struct InlineAsmDescriptor { + std::string AsmString, Constraints; + bool HasSideEffects; + + InlineAsmDescriptor(const std::string &as, const std::string &c, bool HSE) + : AsmString(as), Constraints(c), HasSideEffects(HSE) {} +}; + + // ValID - Represents a reference of a definition of some sort. This may either // be a numeric reference or a symbolic (%var) reference. This is just a // discriminated union. @@ -82,7 +93,7 @@ static inline void ThrowException(const std::string &message, struct ValID { enum { NumberVal, NameVal, ConstSIntVal, ConstUIntVal, ConstFPVal, ConstNullVal, - ConstUndefVal, ConstZeroVal, ConstantVal, + ConstUndefVal, ConstZeroVal, ConstantVal, InlineAsmVal } Type; union { @@ -92,6 +103,7 @@ struct ValID { uint64_t UConstPool64;// Unsigned constant pool reference. double ConstPoolFP; // Floating point constant pool reference Constant *ConstantValue; // Fully resolved constant for ConstantVal case. + InlineAsmDescriptor *IAD; }; static ValID create(int Num) { @@ -129,10 +141,21 @@ struct ValID { static ValID create(Constant *Val) { ValID D; D.Type = ConstantVal; D.ConstantValue = Val; return D; } + + static ValID createInlineAsm(const std::string &AsmString, + const std::string &Constraints, + bool HasSideEffects) { + ValID D; + D.Type = InlineAsmVal; + D.IAD = new InlineAsmDescriptor(AsmString, Constraints, HasSideEffects); + return D; + } inline void destroy() const { if (Type == NameVal) - free(Name); // Free this strdup'd memory... + free(Name); // Free this strdup'd memory. + else if (Type == InlineAsmVal) + delete IAD; } inline ValID copy() const { diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y index b859778..dfdb5f4 100644 --- a/lib/AsmParser/llvmAsmParser.y +++ b/lib/AsmParser/llvmAsmParser.y @@ -14,6 +14,7 @@ %{ #include "ParserInternals.h" #include "llvm/CallingConv.h" +#include "llvm/InlineAsm.h" #include "llvm/Instructions.h" #include "llvm/Module.h" #include "llvm/SymbolTable.h" @@ -316,6 +317,17 @@ static Value *getValNonImprovising(const Type *Ty, const ValID &D) { ThrowException("Constant expression type different from required type!"); return D.ConstantValue; + case ValID::InlineAsmVal: { // Inline asm expression + const PointerType *PTy = dyn_cast<PointerType>(Ty); + const FunctionType *FTy = + PTy ? dyn_cast<FunctionType>(PTy->getElementType()) : 0; + if (!FTy || !InlineAsm::Verify(FTy, D.IAD->Constraints)) + ThrowException("Invalid type for asm constraint string!"); + InlineAsm *IA = InlineAsm::get(FTy, D.IAD->AsmString, D.IAD->Constraints, + D.IAD->HasSideEffects); + D.destroy(); // Free InlineAsmDescriptor. + return IA; + } default: assert(0 && "Unhandled case!"); return 0; @@ -932,6 +944,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) { %type <BoolVal> GlobalType // GLOBAL or CONSTANT? %type <BoolVal> OptVolatile // 'volatile' or not %type <BoolVal> OptTailCall // TAIL CALL or plain CALL. +%type <BoolVal> OptSideEffect // 'sideeffect' or not. %type <Linkage> OptLinkage %type <Endianness> BigOrLittle @@ -967,7 +980,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) { %token DECLARE GLOBAL CONSTANT SECTION VOLATILE %token TO DOTDOTDOT NULL_TOK UNDEF CONST INTERNAL LINKONCE WEAK APPENDING %token OPAQUE NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG ALIGN -%token DEPLIBS CALL TAIL ASM_TOK MODULE +%token DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT %token CC_TOK CCC_TOK FASTCC_TOK COLDCC_TOK %type <UIntVal> OptCallingConv @@ -1831,6 +1844,13 @@ FunctionProto : DECLARE { CurFun.isDeclare = true; } FunctionHeaderH { // Rules to match Basic Blocks //===----------------------------------------------------------------------===// +OptSideEffect : /* empty */ { + $$ = false; + } + | SIDEEFFECT { + $$ = true; + }; + ConstValueRef : ESINT64VAL { // A reference to a direct constant $$ = ValID::create($1); } @@ -1881,6 +1901,15 @@ ConstValueRef : ESINT64VAL { // A reference to a direct constant } | ConstExpr { $$ = ValID::create($1); + } + | ASM_TOK OptSideEffect STRINGCONSTANT ',' STRINGCONSTANT { + char *End = UnEscapeLexed($3, true); + std::string AsmStr = std::string($3, End); + End = UnEscapeLexed($5, true); + std::string Constraints = std::string($5, End); + $$ = ValID::createInlineAsm(AsmStr, Constraints, $2); + free($3); + free($5); }; // SymbolicValueRef - Reference to one of two ways of symbolically refering to |