summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Parse/ParseStmtAsm.cpp29
-rw-r--r--test/CodeGen/ms-inline-asm.c260
-rw-r--r--test/CodeGen/ms-inline-asm.cpp29
-rw-r--r--test/Parser/ms-inline-asm.c2
-rw-r--r--test/Sema/ms-inline-asm.c26
5 files changed, 174 insertions, 172 deletions
diff --git a/lib/Parse/ParseStmtAsm.cpp b/lib/Parse/ParseStmtAsm.cpp
index 58d69965de..f1d2946e0e 100644
--- a/lib/Parse/ParseStmtAsm.cpp
+++ b/lib/Parse/ParseStmtAsm.cpp
@@ -322,6 +322,7 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) {
SourceLocation EndLoc = AsmLoc;
SmallVector<Token, 4> AsmToks;
+ bool SingleLineMode = true;
unsigned BraceNesting = 0;
unsigned short savedBraceCount = BraceCount;
bool InAsmComment = false;
@@ -333,6 +334,7 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) {
if (Tok.is(tok::l_brace)) {
// Braced inline asm: consume the opening brace.
+ SingleLineMode = false;
BraceNesting = 1;
EndLoc = ConsumeBrace();
LBraceLocs.push_back(EndLoc);
@@ -364,30 +366,39 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) {
} else if (!InAsmComment && Tok.is(tok::semi)) {
// A semicolon in an asm is the start of a comment.
InAsmComment = true;
- if (BraceNesting) {
+ if (!SingleLineMode) {
// Compute which line the comment is on.
std::pair<FileID, unsigned> ExpSemiLoc =
SrcMgr.getDecomposedExpansionLoc(TokLoc);
FID = ExpSemiLoc.first;
LineNo = SrcMgr.getLineNumber(FID, ExpSemiLoc.second);
}
- } else if (!BraceNesting || InAsmComment) {
+ } else if (SingleLineMode || InAsmComment) {
// If end-of-line is significant, check whether this token is on a
// new line.
std::pair<FileID, unsigned> ExpLoc =
SrcMgr.getDecomposedExpansionLoc(TokLoc);
if (ExpLoc.first != FID ||
SrcMgr.getLineNumber(ExpLoc.first, ExpLoc.second) != LineNo) {
- // If this is a single-line __asm, we're done.
- if (!BraceNesting)
+ // If this is a single-line __asm, we're done, except if the next
+ // line begins with an __asm too, in which case we finish a comment
+ // if needed and then keep processing the next line as a single
+ // line __asm.
+ bool isAsm = Tok.is(tok::kw_asm);
+ if (SingleLineMode && !isAsm)
break;
// We're no longer in a comment.
InAsmComment = false;
+ if (isAsm) {
+ LineNo = SrcMgr.getLineNumber(ExpLoc.first, ExpLoc.second);
+ SkippedStartOfLine = Tok.isAtStartOfLine();
+ }
} else if (!InAsmComment && Tok.is(tok::r_brace)) {
- // Single-line asm always ends when a closing brace is seen.
- // FIXME: This is compatible with Apple gcc's -fasm-blocks; what
- // does MSVC do here?
- break;
+ // In MSVC mode, braces only participate in brace matching and
+ // separating the asm statements. This is an intentional
+ // departure from the Apple gcc behavior.
+ if (!BraceNesting)
+ break;
}
}
if (!InAsmComment && BraceNesting && Tok.is(tok::r_brace) &&
@@ -398,7 +409,7 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) {
BraceNesting--;
// Finish if all of the opened braces in the inline asm section were
// consumed.
- if (BraceNesting == 0)
+ if (BraceNesting == 0 && !SingleLineMode)
break;
else {
LBraceLocs.pop_back();
diff --git a/test/CodeGen/ms-inline-asm.c b/test/CodeGen/ms-inline-asm.c
index 2c67106941..cd41d73e92 100644
--- a/test/CodeGen/ms-inline-asm.c
+++ b/test/CodeGen/ms-inline-asm.c
@@ -10,9 +10,7 @@ void t1() {
void t2() {
// CHECK: @t2
-// CHECK: call void asm sideeffect inteldialect "nop", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "nop", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "nop", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "nop\0A\09nop\0A\09nop", "~{dirflag},~{fpsr},~{flags}"()
// CHECK: ret void
__asm nop
__asm nop
@@ -28,8 +26,7 @@ void t3() {
void t4(void) {
// CHECK: @t4
-// CHECK: call void asm sideeffect inteldialect "mov ebx, eax", "~{ebx},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov ecx, ebx", "~{ecx},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov ebx, eax\0A\09mov ecx, ebx", "~{ebx},~{ecx},~{dirflag},~{fpsr},~{flags}"()
// CHECK: ret void
__asm mov ebx, eax
__asm mov ecx, ebx
@@ -69,9 +66,7 @@ int t8() {
__asm int 4
return 10;
// CHECK: t8
-// CHECK: call void asm sideeffect inteldialect "int $$4", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "int $$4", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "int $$4\0A\09int $$4", "~{dirflag},~{fpsr},~{flags}"()
// CHECK: ret i32 10
}
@@ -126,8 +121,7 @@ void t13() {
__asm movzx eax, i
__asm movzx eax, j
// CHECK: t13
-// CHECK: call void asm sideeffect inteldialect "movzx eax, byte ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i8* %{{.*}})
-// CHECK: call void asm sideeffect inteldialect "movzx eax, word ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i16* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "movzx eax, byte ptr $0\0A\09movzx eax, word ptr $1", "*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i8* %{{.*}}i, i16* %{{.*}}j)
}
void t14() {
@@ -145,14 +139,15 @@ void t14() {
int gvar = 10;
void t15() {
+// CHECK: t15
int lvar = 10;
__asm mov eax, lvar ; eax = 10
+// CHECK: mov eax, dword ptr $0
__asm mov eax, offset lvar ; eax = address of lvar
+// CHECK: mov eax, $1
__asm mov eax, offset gvar ; eax = address of gvar
-// CHECK: t15
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
-// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
-// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* @{{.*}})
+// CHECK: mov eax, $2
+// CHECK: "*m,r,r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* @{{.*}})
}
void t16() {
@@ -163,50 +158,52 @@ void t16() {
}
void t17() {
+// CHECK: t17
__asm _emit 0x4A
+// CHECK: .byte 0x4A
__asm _emit 0x43
+// CHECK: .byte 0x43
__asm _emit 0x4B
+// CHECK: .byte 0x4B
__asm _EMIT 0x4B
-// CHECK: t17
-// CHECK: call void asm sideeffect inteldialect ".byte 0x4A", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect ".byte 0x43", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect ".byte 0x4B", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect ".byte 0x4B", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: .byte 0x4B
+// CHECK: "~{dirflag},~{fpsr},~{flags}"()
}
void t20() {
+// CHECK: t20
char bar;
int foo;
char _bar[2];
int _foo[4];
__asm mov eax, LENGTH foo
+// CHECK: mov eax, $$1
__asm mov eax, LENGTH bar
+// CHECK: mov eax, $$1
__asm mov eax, LENGTH _foo
+// CHECK: mov eax, $$4
__asm mov eax, LENGTH _bar
-// CHECK: t20
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: mov eax, $$2
__asm mov eax, TYPE foo
+// CHECK: mov eax, $$4
__asm mov eax, TYPE bar
+// CHECK: mov eax, $$1
__asm mov eax, TYPE _foo
+// CHECK: mov eax, $$4
__asm mov eax, TYPE _bar
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: mov eax, $$1
__asm mov eax, SIZE foo
+// CHECK: mov eax, $$4
__asm mov eax, SIZE bar
+// CHECK: mov eax, $$1
__asm mov eax, SIZE _foo
+// CHECK: mov eax, $$16
__asm mov eax, SIZE _bar
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$16", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: mov eax, $$2
+// CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"()
}
void t21() {
@@ -253,34 +250,35 @@ void t24() {
}
void t25() {
+// CHECK: t25
__asm mov eax, 0ffffffffh
+// CHECK: mov eax, $$4294967295
__asm mov eax, 0fh
+// CHECK: mov eax, $$15
__asm mov eax, 0a2h
+// CHECK: mov eax, $$162
__asm mov eax, 0xa2h
+// CHECK: mov eax, $$0xa2h
__asm mov eax, 0xa2
-// CHECK: t25
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4294967295", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$15", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$162", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$0xa2h", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$0xa2", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: mov eax, $$0xa2
+// CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"()
}
void t26() {
+// CHECK: t26
__asm pushad
+// CHECK: pushad
__asm mov eax, 0
+// CHECK: mov eax, $$0
__asm __emit 0fh
+// CHECK: .byte 0fh
__asm __emit 0a2h
+// CHECK: .byte 0a2h
__asm __EMIT 0a2h
+// CHECK: .byte 0a2h
__asm popad
-// FIXME: These all need to be merged into the same asm blob.
-// CHECK: t26
-// CHECK: call void asm sideeffect inteldialect "pushad", "~{esp},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$0", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect ".byte 0fh", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect ".byte 0a2h", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect ".byte 0a2h", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "popad", "~{eax},~{ebp},~{ebx},~{ecx},~{edi},~{edx},~{esi},~{esp},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: popad
+// CHECK: "~{eax},~{ebp},~{ebx},~{ecx},~{edi},~{edx},~{esi},~{esp},~{dirflag},~{fpsr},~{flags}"()
}
void t27() {
@@ -290,160 +288,171 @@ void t27() {
}
void t28() {
+// CHECK: t28
__asm align 8
+// CHECK: .align 3
__asm align 16;
+// CHECK: .align 4
__asm align 128;
+// CHECK: .align 7
__asm ALIGN 256;
-// CHECK: t28
-// CHECK: call void asm sideeffect inteldialect ".align 3", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect ".align 4", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect ".align 7", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect ".align 8", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: .align 8
+// CHECK: "~{dirflag},~{fpsr},~{flags}"()
}
void t29() {
+// CHECK: t29
int arr[2] = {0, 0};
int olen = 0, osize = 0, otype = 0;
__asm mov olen, LENGTH arr
+// CHECK: mov dword ptr $0, $$2
__asm mov osize, SIZE arr
+// CHECK: mov dword ptr $1, $$8
__asm mov otype, TYPE arr
-// CHECK: t29
-// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, $$2", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
-// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, $$8", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
-// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, $$4", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: mov dword ptr $2, $$4
+// CHECK: "=*m,=*m,=*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}})
}
int results[2] = {13, 37};
int *t30()
+// CHECK: t30
{
int *res;
__asm lea edi, results
+// CHECK: lea edi, dword ptr $1
__asm mov res, edi
+// CHECK: mov dword ptr $0, edi
return res;
-// CHECK: t30
-// CHECK: call void asm sideeffect inteldialect "lea edi, dword ptr $0", "*m,~{edi},~{dirflag},~{fpsr},~{flags}"([2 x i32]* @{{.*}})
-// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, edi", "=*m,~{dirflag},~{fpsr},~{flags}"(i32** %{{.*}})
+// CHECK: "=*m,*m,~{edi},~{dirflag},~{fpsr},~{flags}"(i32** %{{.*}}, [2 x i32]* @{{.*}})
}
void t31() {
+// CHECK: t31
__asm pushad
+// CHECK: pushad
__asm popad
-// CHECK: t31
-// CHECK: call void asm sideeffect inteldialect "pushad", "~{esp},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "popad", "~{eax},~{ebp},~{ebx},~{ecx},~{edi},~{edx},~{esi},~{esp},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: popad
+// CHECK: "~{eax},~{ebp},~{ebx},~{ecx},~{edi},~{edx},~{esi},~{esp},~{dirflag},~{fpsr},~{flags}"()
}
void t32() {
+// CHECK: t32
int i;
__asm mov eax, i
+// CHECK: mov eax, dword ptr $0
__asm mov eax, dword ptr i
+// CHECK: mov eax, dword ptr $1
__asm mov ax, word ptr i
+// CHECK: mov ax, word ptr $2
__asm mov al, byte ptr i
-// CHECK: t32
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
-// CHECK: call void asm sideeffect inteldialect "mov ax, word ptr $0", "*m,~{ax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
-// CHECK: call void asm sideeffect inteldialect "mov al, byte ptr $0", "*m,~{al},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: mov al, byte ptr $3
+// CHECK: "*m,*m,*m,*m,~{al},~{ax},~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}})
}
void t33() {
+// CHECK: t33
int i;
__asm mov eax, [i]
+// CHECK: mov eax, dword ptr $0
__asm mov eax, dword ptr [i]
+// CHECK: mov eax, dword ptr $1
__asm mov ax, word ptr [i]
+// CHECK: mov ax, word ptr $2
__asm mov al, byte ptr [i]
-// CHECK: t33
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
-// CHECK: call void asm sideeffect inteldialect "mov ax, word ptr $0", "*m,~{ax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
-// CHECK: call void asm sideeffect inteldialect "mov al, byte ptr $0", "*m,~{al},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
+// CHECK: mov al, byte ptr $3
+// CHECK: "*m,*m,*m,*m,~{al},~{ax},~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}})
}
void t34() {
+// CHECK: t34
__asm prefetchnta 64[eax]
+// CHECK: prefetchnta $$64[eax]
__asm mov eax, dword ptr 4[eax]
-// CHECK: t34
-// CHECK: call void asm sideeffect inteldialect "prefetchnta $$64[eax]", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4[eax]", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: mov eax, dword ptr $$4[eax]
+// CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"()
}
void t35() {
+// CHECK: t35
__asm prefetchnta [eax + (200*64)]
+// CHECK: prefetchnta [eax + ($$200*$$64)]
__asm mov eax, dword ptr [eax + (200*64)]
-// CHECK: t35
-// CHECK: call void asm sideeffect inteldialect "prefetchnta [eax + ($$200*$$64)]", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr [eax + ($$200*$$64)]", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: mov eax, dword ptr [eax + ($$200*$$64)]
+// CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"()
}
void t36() {
- int arr[4];
- __asm mov eax, 4[arr]
- __asm mov eax, 4[arr + 4]
- __asm mov eax, 8[arr + 4 + 32*2 - 4]
- __asm mov eax, 12[4 + arr]
- __asm mov eax, 4[4 + arr + 4]
- __asm mov eax, 4[64 + arr + (2*32)]
- __asm mov eax, 4[64 + arr - 2*32]
- __asm mov eax, [arr + 4]
- __asm mov eax, [arr + 4 + 32*2 - 4]
- __asm mov eax, [4 + arr]
- __asm mov eax, [4 + arr + 4]
- __asm mov eax, [64 + arr + (2*32)]
- __asm mov eax, [64 + arr - 2*32]
// CHECK: t36
+ int arr[4];
+ // Work around PR20368: These should be single line blocks
+ __asm { mov eax, 4[arr] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+ __asm { mov eax, 4[arr + 4] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+ __asm { mov eax, 8[arr + 4 + 32*2 - 4] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$72$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+ __asm { mov eax, 12[4 + arr] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$16$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+ __asm { mov eax, 4[4 + arr + 4] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$12$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+ __asm { mov eax, 4[64 + arr + (2*32)] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$132$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+ __asm { mov eax, 4[64 + arr - 2*32] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+ __asm { mov eax, [arr + 4] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+ __asm { mov eax, [arr + 4 + 32*2 - 4] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$64$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+ __asm { mov eax, [4 + arr] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+ __asm { mov eax, [4 + arr + 4] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+ __asm { mov eax, [64 + arr + (2*32)] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$128$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+ __asm { mov eax, [64 + arr - 2*32] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
}
void t37() {
+// CHECK: t37
__asm mov eax, 4 + 8
+// CHECK: mov eax, $$12
__asm mov eax, 4 + 8 * 16
+// CHECK: mov eax, $$132
__asm mov eax, -4 + 8 * 16
+// CHECK: mov eax, $$124
__asm mov eax, (4 + 4) * 16
+// CHECK: mov eax, $$128
__asm mov eax, 4 + 8 * -16
+// CHECK: mov eax, $$4294967172
__asm mov eax, 4 + 16 / -8
+// CHECK: mov eax, $$2
__asm mov eax, (16 + 16) / -8
+// CHECK: mov eax, $$4294967292
__asm mov eax, ~15
-// CHECK: t37
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$12", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$132", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$124", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$128", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4294967172", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4294967292", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4294967280", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: mov eax, $$4294967280
+// CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"()
}
void t38() {
- int arr[4];
- __asm mov eax, 4+4[arr]
- __asm mov eax, (4+4)[arr + 4]
- __asm mov eax, 8*2[arr + 4 + 32*2 - 4]
- __asm mov eax, 12+20[4 + arr]
- __asm mov eax, 4*16+4[4 + arr + 4]
- __asm mov eax, 4*4[64 + arr + (2*32)]
- __asm mov eax, 4*(4-2)[64 + arr - 2*32]
- __asm mov eax, 32*(4-2)[arr - 2*32]
// CHECK: t38
+ int arr[4];
+ // Work around PR20368: These should be single line blocks
+ __asm { mov eax, 4+4[arr] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+ __asm { mov eax, (4+4)[arr + 4] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$12$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+ __asm { mov eax, 8*2[arr + 4 + 32*2 - 4] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$80$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+ __asm { mov eax, 12+20[4 + arr] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$36$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+ __asm { mov eax, 4*16+4[4 + arr + 4] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$76$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+ __asm { mov eax, 4*4[64 + arr + (2*32)] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$144$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+ __asm { mov eax, 4*(4-2)[64 + arr - 2*32] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+ __asm { mov eax, 32*(4-2)[arr - 2*32] }
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$0$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
}
@@ -459,38 +468,39 @@ typedef struct {
} A;
void t39() {
+// CHECK-LABEL: define void @t39
__asm mov eax, [eax].A.b
+// CHECK: mov eax, [eax].4
__asm mov eax, [eax] A.b
+// CHECK: mov eax, [eax] .4
__asm mov eax, fs:[0] A.b
- // CHECK-LABEL: define void @t39
- // CHECK: call void asm sideeffect inteldialect "mov eax, [eax].4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
- // CHECK: call void asm sideeffect inteldialect "mov eax, [eax] .4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
- // CHECK: call void asm sideeffect inteldialect "mov eax, fs:[$$0] .4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: mov eax, fs:[$$0] .4
+// CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"()
}
void t40(float a) {
+// CHECK-LABEL: define void @t40
int i;
__asm fld a
+// CHECK: fld dword ptr $1
__asm fistp i
- // CHECK-LABEL: define void @t40
- // CHECK: call void asm sideeffect inteldialect "fld dword ptr $0", "*m,~{dirflag},~{fpsr},~{flags}"(float* {{.*}})
- // CHECK: call void asm sideeffect inteldialect "fistp dword ptr $0", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* {{.*}})
+// CHECK: fistp dword ptr $0
+// CHECK: "=*m,*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, float* %{{.*}})
}
void t41(unsigned short a) {
+// CHECK-LABEL: define void @t41(i16 zeroext %a)
__asm mov cs, a;
+// CHECK: mov cs, word ptr $0
__asm mov ds, a;
+// CHECK: mov ds, word ptr $1
__asm mov es, a;
+// CHECK: mov es, word ptr $2
__asm mov fs, a;
+// CHECK: mov fs, word ptr $3
__asm mov gs, a;
+// CHECK: mov gs, word ptr $4
__asm mov ss, a;
- // CHECK-LABEL: define void @t41(i16 zeroext %a)
- // CHECK: [[T41_A_ADDR:%.+]] = alloca i16
- // CHECK: store i16 %a, i16* [[T41_A_ADDR]]
- // CHECK: call void asm sideeffect inteldialect "mov cs, word ptr $0", "*m,~{dirflag},~{fpsr},~{flags}"(i16* [[T41_A_ADDR]])
- // CHECK: call void asm sideeffect inteldialect "mov ds, word ptr $0", "*m,~{dirflag},~{fpsr},~{flags}"(i16* [[T41_A_ADDR]])
- // CHECK: call void asm sideeffect inteldialect "mov es, word ptr $0", "*m,~{dirflag},~{fpsr},~{flags}"(i16* [[T41_A_ADDR]])
- // CHECK: call void asm sideeffect inteldialect "mov fs, word ptr $0", "*m,~{dirflag},~{fpsr},~{flags}"(i16* [[T41_A_ADDR]])
- // CHECK: call void asm sideeffect inteldialect "mov gs, word ptr $0", "*m,~{dirflag},~{fpsr},~{flags}"(i16* [[T41_A_ADDR]])
- // CHECK: call void asm sideeffect inteldialect "mov ss, word ptr $0", "*m,~{dirflag},~{fpsr},~{flags}"(i16* [[T41_A_ADDR]])
+// CHECK: mov ss, word ptr $5
+// CHECK: "*m,*m,*m,*m,*m,*m,~{dirflag},~{fpsr},~{flags}"(i16* %a.addr, i16* %a.addr, i16* %a.addr, i16* %a.addr, i16* %a.addr, i16* %a.addr)
}
diff --git a/test/CodeGen/ms-inline-asm.cpp b/test/CodeGen/ms-inline-asm.cpp
index 83fe1075af..aaeb45477f 100644
--- a/test/CodeGen/ms-inline-asm.cpp
+++ b/test/CodeGen/ms-inline-asm.cpp
@@ -22,11 +22,7 @@ void t1() {
__asm mov eax, dword ptr [Foo :: ptr]
__asm mov eax, dword ptr [Foo :: ptr]
// CHECK: @_Z2t1v
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE)
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3Bar3ptrE)
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE)
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE)
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE)
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0\0A\09mov eax, dword ptr $1\0A\09mov eax, dword ptr $2\0A\09mov eax, dword ptr $3\0A\09mov eax, dword ptr $4", "*m,*m,*m,*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE, i32** @_ZN3Foo3Bar3ptrE, i32** @_ZN3Foo3ptrE, i32** @_ZN3Foo3ptrE, i32** @_ZN3Foo3ptrE)
}
int gvar = 10;
@@ -35,38 +31,26 @@ void t2() {
__asm mov eax, offset Foo::ptr
__asm mov eax, offset Foo::Bar::ptr
// CHECK: t2
-// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE)
-// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3Bar3ptrE)
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0\0A\09mov eax, $1", "r,r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE, i32** @_ZN3Foo3Bar3ptrE)
}
// CHECK-LABEL: define void @_Z2t3v()
void t3() {
__asm mov eax, LENGTH Foo::ptr
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
__asm mov eax, LENGTH Foo::Bar::ptr
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
__asm mov eax, LENGTH Foo::arr
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
__asm mov eax, LENGTH Foo::Bar::arr
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"()
__asm mov eax, TYPE Foo::ptr
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
__asm mov eax, TYPE Foo::Bar::ptr
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
__asm mov eax, TYPE Foo::arr
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
__asm mov eax, TYPE Foo::Bar::arr
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
__asm mov eax, SIZE Foo::ptr
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
__asm mov eax, SIZE Foo::Bar::ptr
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
__asm mov eax, SIZE Foo::arr
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$16", "~{eax},~{dirflag},~{fpsr},~{flags}"()
__asm mov eax, SIZE Foo::Bar::arr
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$1\0A\09mov eax, $$1\0A\09mov eax, $$4\0A\09mov eax, $$2\0A\09mov eax, $$4\0A\09mov eax, $$4\0A\09mov eax, $$4\0A\09mov eax, $$1\0A\09mov eax, $$4\0A\09mov eax, $$4\0A\09mov eax, $$16\0A\09mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"()
}
@@ -82,9 +66,8 @@ void T4::test() {
// CHECK: [[THIS:%.*]] = load [[T4]]** [[T0]]
// CHECK: [[X:%.*]] = getelementptr inbounds [[T4]]* [[THIS]], i32 0, i32 0
__asm mov eax, x;
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* [[X]])
__asm mov y, eax;
-// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, eax", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* @_ZN2T41yE)
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $1\0A\09mov dword ptr $0, eax", "=*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* @_ZN2T41yE, i32* %x)
}
template <class T> struct T5 {
@@ -97,11 +80,9 @@ void test5() {
// CHECK: [[Y:%.*]] = alloca i32
int x, y;
__asm push y
- // CHECK: call void asm sideeffect inteldialect "push dword ptr $0", "=*m,~{esp},~{dirflag},~{fpsr},~{flags}"(i32* [[Y]])
__asm call T5<int>::create<float>
- // CHECK: call void asm sideeffect inteldialect "call $0", "r,~{dirflag},~{fpsr},~{flags}"(i32 (float)* @_ZN2T5IiE6createIfEEiT_)
__asm mov x, eax
- // CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, eax", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* [[X]])
+ // CHECK: call void asm sideeffect inteldialect "push dword ptr $0\0A\09call $2\0A\09mov dword ptr $1, eax", "=*m,=*m,r,~{esp},~{dirflag},~{fpsr},~{flags}"(i32* %y, i32* %x, i32 (float)* @_ZN2T5IiE6createIfEEiT_)
}
// Just verify this doesn't emit an error.
diff --git a/test/Parser/ms-inline-asm.c b/test/Parser/ms-inline-asm.c
index 00508f5cf0..646f547e32 100644
--- a/test/Parser/ms-inline-asm.c
+++ b/test/Parser/ms-inline-asm.c
@@ -50,4 +50,4 @@ void t11() {
}
int t_fail() { // expected-note {{to match this}}
__asm
- __asm { // expected-error 3 {{expected}} expected-note {{to match this}}
+ __asm { // expected-error 2 {{expected}} expected-note {{to match this}}
diff --git a/test/Sema/ms-inline-asm.c b/test/Sema/ms-inline-asm.c
index 66504aa084..e1d79c116c 100644
--- a/test/Sema/ms-inline-asm.c
+++ b/test/Sema/ms-inline-asm.c
@@ -60,13 +60,13 @@ int t2(int *arr, int i) {
}
// expected-error@+1 {{cannot use base register with variable reference}}
- __asm mov eax, arr[ebp + 1 + (2 * 5) - 3 + 1<<1]
+ __asm { mov eax, arr[ebp + 1 + (2 * 5) - 3 + 1<<1] }
// expected-error@+1 {{cannot use index register with variable reference}}
- __asm mov eax, arr[esi * 4]
+ __asm { mov eax, arr[esi * 4] }
// expected-error@+1 {{cannot use more than one symbol in memory operand}}
- __asm mov eax, arr[i]
+ __asm { mov eax, arr[i] }
// expected-error@+1 {{cannot use more than one symbol in memory operand}}
- __asm mov eax, global[i]
+ __asm { mov eax, global[i] }
// FIXME: Why don't we diagnose this?
// expected-Xerror@+1 {{cannot reference multiple local variables in assembly operand}}
@@ -80,22 +80,22 @@ typedef struct {
} A;
void t3() {
- __asm mov eax, [eax] UndeclaredId // expected-error {{unknown token in expression}}
+ __asm { mov eax, [eax] UndeclaredId } // expected-error {{unknown token in expression}}
// FIXME: Only emit one diagnostic here.
// expected-error@+2 {{unexpected type name 'A': expected expression}}
// expected-error@+1 {{unknown token in expression}}
- __asm mov eax, [eax] A
+ __asm { mov eax, [eax] A }
}
void t4() {
// The dot in the "intel dot operator" is optional in MSVC. MSVC also does
// global field lookup, but we don't.
- __asm mov eax, [0] A.a
- __asm mov eax, [0].A.a
- __asm mov eax, [0].a // expected-error {{Unable to lookup field reference!}}
- __asm mov eax, fs:[0] A.a
- __asm mov eax, fs:[0].A.a
- __asm mov eax, fs:[0].a // expected-error {{Unable to lookup field reference!}}
- __asm mov eax, fs:[0]. A.a // expected-error {{Unexpected token type!}}
+ __asm { mov eax, [0] A.a }
+ __asm { mov eax, [0].A.a }
+ __asm { mov eax, [0].a } // expected-error {{Unable to lookup field reference!}}
+ __asm { mov eax, fs:[0] A.a }
+ __asm { mov eax, fs:[0].A.a }
+ __asm { mov eax, fs:[0].a } // expected-error {{Unable to lookup field reference!}}
+ __asm { mov eax, fs:[0]. A.a } // expected-error {{Unexpected token type!}}
}