aboutsummaryrefslogtreecommitdiff
path: root/clang/test/CodeGen/ms-inline-asm.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2013-05-03 00:10:13 +0000
committerJohn McCall <rjmccall@apple.com>2013-05-03 00:10:13 +0000
commitf413f5ed44dd49df3a3f1212eadb5b5c3d1a195c (patch)
treea353ebd6ea1e61c952b658ec53dfc30aa5d2311a /clang/test/CodeGen/ms-inline-asm.cpp
parentbfa9fb134bd951b4b6fff94d0df07f5bb277fd21 (diff)
downloadllvm-f413f5ed44dd49df3a3f1212eadb5b5c3d1a195c.zip
llvm-f413f5ed44dd49df3a3f1212eadb5b5c3d1a195c.tar.gz
llvm-f413f5ed44dd49df3a3f1212eadb5b5c3d1a195c.tar.bz2
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. llvm-svn: 180976
Diffstat (limited to 'clang/test/CodeGen/ms-inline-asm.cpp')
-rw-r--r--clang/test/CodeGen/ms-inline-asm.cpp77
1 files changed, 62 insertions, 15 deletions
diff --git a/clang/test/CodeGen/ms-inline-asm.cpp b/clang/test/CodeGen/ms-inline-asm.cpp
index 99071aa..8f824f99 100644
--- a/clang/test/CodeGen/ms-inline-asm.cpp
+++ b/clang/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]])
}