diff options
author | John McCall <rjmccall@apple.com> | 2013-05-03 00:10:13 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2013-05-03 00:10:13 +0000 |
commit | aeeacf725c9e0ddd64ea9764bd008e5b6873ce51 (patch) | |
tree | 370063ad5a0cf0312992d978ed703abc92c53403 /test/CodeGen/ms-inline-asm.cpp | |
parent | c70fac3c52092013b08163187f034b73c94bf3d0 (diff) |
Move parsing of identifiers in MS-style inline assembly into
the actual parser and support arbitrary id-expressions.
We're actually basically set up to do arbitrary expressions here
if we wanted to.
Assembly operands permit things like A::x to be written regardless
of language mode, which forces us to embellish the evaluation
context logic somewhat. The logic here under template instantiation
is incorrect; we need to preserve the fact that an expression was
unevaluated. Of course, template instantiation in general is fishy
here because we have no way of delaying semantic analysis in the
MC parser. It's all just fishy.
I've also fixed the serialization of MS asm statements.
This commit depends on an LLVM commit.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@180976 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGen/ms-inline-asm.cpp')
-rw-r--r-- | test/CodeGen/ms-inline-asm.cpp | 77 |
1 files changed, 62 insertions, 15 deletions
diff --git a/test/CodeGen/ms-inline-asm.cpp b/test/CodeGen/ms-inline-asm.cpp index 99071aa81c..8f824f9947 100644 --- a/test/CodeGen/ms-inline-asm.cpp +++ b/test/CodeGen/ms-inline-asm.cpp @@ -1,6 +1,8 @@ // REQUIRES: x86-64-registered-target // RUN: %clang_cc1 -x c++ %s -triple i386-apple-darwin10 -O0 -fasm-blocks -emit-llvm -o - | FileCheck %s +// rdar://13645930 + struct Foo { static int *ptr; static int a, b; @@ -14,17 +16,17 @@ struct Foo { void t1() { Foo::ptr = (int *)0xDEADBEEF; Foo::Bar::ptr = (int *)0xDEADBEEF; - __asm mov eax, Foo::ptr - __asm mov eax, Foo::Bar::ptr - __asm mov eax, [Foo::ptr] - __asm mov eax, dword ptr [Foo::ptr] - __asm mov eax, dword ptr [Foo::ptr] + __asm mov eax, Foo ::ptr + __asm mov eax, Foo :: Bar :: ptr + __asm mov eax, [Foo:: ptr] + __asm mov eax, dword ptr [Foo :: ptr] + __asm mov eax, dword ptr [Foo :: ptr] // CHECK: @_Z2t1v -// CHECK: call void asm sideeffect inteldialect "mov eax, Foo::ptr", "~{eax},~{dirflag},~{fpsr},~{flags}"() -// CHECK: call void asm sideeffect inteldialect "mov eax, Foo::Bar::ptr", "~{eax},~{dirflag},~{fpsr},~{flags}"() -// CHECK: call void asm sideeffect inteldialect "mov eax, Foo::ptr", "~{eax},~{dirflag},~{fpsr},~{flags}"() -// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr Foo::ptr", "~{eax},~{dirflag},~{fpsr},~{flags}"() -// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr Foo::ptr", "~{eax},~{dirflag},~{fpsr},~{flags}"() +// 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) } int gvar = 10; @@ -33,26 +35,71 @@ 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, Foo::ptr", "~{eax},~{dirflag},~{fpsr},~{flags}"() -// CHECK: call void asm sideeffect inteldialect "mov eax, Foo::Bar::ptr", "~{eax},~{dirflag},~{fpsr},~{flags}"() +// 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: 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: t3 -// FIXME: These tests just make sure we can parse things properly. -// Additional work needs to be done in Sema to perform the lookup. +// CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"() + +} + +struct T4 { + int x; + static int y; + void test(); +}; + +// CHECK: define void @_ZN2T44testEv( +void T4::test() { +// CHECK: [[T0:%.*]] = alloca [[T4:%.*]]*, +// 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) +} + +template <class T> struct T5 { + template <class U> static T create(U); + void run(); +}; +// CHECK: define void @_Z5test5v() +void test5() { + // CHECK: [[X:%.*]] = alloca i32 + // CHECK: [[Y:%.*]] = alloca i32 + int x, y; + __asm push y + // CHECK: call void asm sideeffect inteldialect "push dword ptr $0", "=*m,~{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]]) } |