diff options
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 27 | ||||
-rw-r--r-- | test/CodeGen/ms-inline-asm.c | 20 |
2 files changed, 46 insertions, 1 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 74d1c596ad..5493e343c6 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -2762,6 +2762,17 @@ StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc, bool IsSimple, return Owned(NS); } +// isMSAsmKeyword - Return true if this is an MS-style inline asm keyword. These +// require special handling. +static bool isMSAsmKeyword(StringRef Name) { + bool Ret = llvm::StringSwitch<bool>(Name) + .Cases("EVEN", "ALIGN", true) // Alignment directives. + .Cases("LENGTH", "SIZE", "TYPE", true) // Type and variable sizes. + .Case("_emit", true) // _emit Pseudoinstruction. + .Default(false); + return Ret; +} + static void patchMSAsmStrings(Sema &SemaRef, bool &IsSimple, SourceLocation AsmLoc, ArrayRef<Token> AsmToks, @@ -2795,7 +2806,14 @@ static void patchMSAsmStrings(Sema &SemaRef, bool &IsSimple, if (isNewAsm) { AsmRegs[NumAsmStrings].resize(AsmToks.size()); AsmNames[NumAsmStrings].resize(AsmToks.size()); - Asm = AsmToks[i].getIdentifierInfo()->getName().str(); + + StringRef Piece = AsmToks[i].getIdentifierInfo()->getName(); + // MS-style inline asm keywords require special handling. + if (isMSAsmKeyword(Piece)) + IsSimple = false; + + // TODO: Verify this is a valid opcode. + Asm = Piece; continue; } @@ -2834,6 +2852,13 @@ static void patchMSAsmStrings(Sema &SemaRef, bool &IsSimple, IsSimple = false; + // MS-style inline asm keywords require special handling. + if (isMSAsmKeyword(Name)) { + IsSimple = false; + Asm += Name; + break; + } + // FIXME: Why are we missing this segment register? if (Name == "fs") { Asm += Name; diff --git a/test/CodeGen/ms-inline-asm.c b/test/CodeGen/ms-inline-asm.c index 310fbd1e00..c140d60551 100644 --- a/test/CodeGen/ms-inline-asm.c +++ b/test/CodeGen/ms-inline-asm.c @@ -98,3 +98,23 @@ unsigned t11(void) { // CHECK: [[RET:%[a-zA-Z0-9]+]] = load i32* [[J]], align 4 // CHECK: ret i32 [[RET]] } + +void t12(void) { + __asm EVEN + __asm ALIGN +} + +void t13(void) { + __asm { + _emit 0x4A + _emit 0x43 + _emit 0x4B + } +} + +void t14(void) { + unsigned arr[10]; + __asm LENGTH arr ; sizeof(arr)/sizeof(arr[0]) + __asm SIZE arr ; sizeof(arr) + __asm TYPE arr ; sizeof(arr[0]) +} |