xref: /llvm-project/clang/test/CodeGen/ms-inline-asm.cpp (revision dc5b614fa9a1c83e8275fcb9c3f78444d0a30514)
1 // REQUIRES: x86-registered-target
2 // RUN: %clang_cc1 -x c++ %s -triple i386-apple-darwin10 -fasm-blocks -emit-llvm -o - -std=c++11 | FileCheck %s
3 
4 // rdar://13645930
5 
6 struct Foo {
7   static int *ptr;
8   static int a, b;
9   int arr[4];
10   struct Bar {
11     static int *ptr;
12     char arr[2];
13   };
14 };
15 
16 void t1() {
17 // CHECK-LABEL: define void @_Z2t1v()
18   Foo::ptr = (int *)0xDEADBEEF;
19   Foo::Bar::ptr = (int *)0xDEADBEEF;
20 // CHECK: call void asm sideeffect inteldialect
21 // CHECK-SAME: mov eax, $0
22 // CHECK-SAME: mov eax, $1
23 // CHECK-SAME: mov eax, $2
24 // CHECK-SAME: mov eax, dword ptr $3
25 // CHECK-SAME: mov eax, dword ptr $4
26 // CHECK-SAME: "*m,*m,*m,*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE, i32** @_ZN3Foo3Bar3ptrE, i32** @_ZN3Foo3ptrE, i32** @_ZN3Foo3ptrE, i32** @_ZN3Foo3ptrE)
27   __asm mov eax, Foo ::ptr
28   __asm mov eax, Foo :: Bar :: ptr
29   __asm mov eax, [Foo:: ptr]
30   __asm mov eax, dword ptr [Foo :: ptr]
31   __asm mov eax, dword ptr [Foo :: ptr]
32 }
33 
34 int gvar = 10;
35 void t2() {
36   int lvar = 10;
37   __asm mov eax, offset Foo::ptr
38   __asm mov eax, offset Foo::Bar::ptr
39 // CHECK-LABEL: define void @_Z2t2v()
40 // CHECK: call void asm sideeffect inteldialect
41 // CHECK-SAME: mov eax, $0
42 // CHECK-SAME: mov eax, $1
43 // CHECK-SAME: "r,r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE, i32** @_ZN3Foo3Bar3ptrE)
44 }
45 
46 // CHECK-LABEL: define void @_Z2t3v()
47 void t3() {
48   __asm mov eax, LENGTH Foo::ptr
49   __asm mov eax, LENGTH Foo::Bar::ptr
50   __asm mov eax, LENGTH Foo::arr
51   __asm mov eax, LENGTH Foo::Bar::arr
52 
53   __asm mov eax, TYPE Foo::ptr
54   __asm mov eax, TYPE Foo::Bar::ptr
55   __asm mov eax, TYPE Foo::arr
56   __asm mov eax, TYPE Foo::Bar::arr
57 
58   __asm mov eax, SIZE Foo::ptr
59   __asm mov eax, SIZE Foo::Bar::ptr
60   __asm mov eax, SIZE Foo::arr
61   __asm mov eax, SIZE Foo::Bar::arr
62 // CHECK: call void asm sideeffect inteldialect
63 // CHECK-SAME: mov eax, $$1
64 // CHECK-SAME: mov eax, $$1
65 // CHECK-SAME: mov eax, $$4
66 // CHECK-SAME: mov eax, $$2
67 // CHECK-SAME: mov eax, $$4
68 // CHECK-SAME: mov eax, $$4
69 // CHECK-SAME: mov eax, $$4
70 // CHECK-SAME: mov eax, $$1
71 // CHECK-SAME: mov eax, $$4
72 // CHECK-SAME: mov eax, $$4
73 // CHECK-SAME: mov eax, $$16
74 // CHECK-SAME: mov eax, $$2
75 // CHECK-SAME: "~{eax},~{dirflag},~{fpsr},~{flags}"()
76 
77 }
78 
79 struct T4 {
80   int x;
81   static int y;
82   void test();
83 };
84 
85 // CHECK-LABEL: define void @_ZN2T44testEv(
86 void T4::test() {
87 // CHECK: [[T0:%.*]] = alloca [[T4:%.*]]*,
88 // CHECK: [[THIS:%.*]] = load [[T4]]*, [[T4]]** [[T0]]
89 // CHECK: [[X:%.*]] = getelementptr inbounds [[T4]], [[T4]]* [[THIS]], i32 0, i32 0
90   __asm mov eax, x;
91   __asm mov y, eax;
92 // CHECK: call void asm sideeffect inteldialect
93 // CHECK-SAME: mov eax, $1
94 // CHECK-SAME: mov $0, eax
95 // CHECK-SAME: "=*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* @_ZN2T41yE, i32* {{.*}})
96 }
97 
98 template <class T> struct T5 {
99   template <class U> static T create(U);
100   void run();
101 };
102 // CHECK-LABEL: define void @_Z5test5v()
103 void test5() {
104   // CHECK: [[X:%.*]] = alloca i32
105   // CHECK: [[Y:%.*]] = alloca i32
106   int x, y;
107   __asm push y
108   __asm call T5<int>::create<float>
109   __asm mov x, eax
110   // CHECK: call void asm sideeffect inteldialect
111   // CHECK-SAME: push $0
112   // CHECK-SAME: call dword ptr ${2:P}
113   // CHECK-SAME: mov $1, eax
114   // CHECK-SAME: "=*m,=*m,*m,~{esp},~{dirflag},~{fpsr},~{flags}"(i32* %y, i32* %x, i32 (float)* @_ZN2T5IiE6createIfEEiT_)
115 }
116 
117 // Just verify this doesn't emit an error.
118 void test6() {
119   __asm {
120    a:
121    jmp a
122   }
123 }
124 
125 void t7_struct() {
126   struct A {
127     int a;
128     int b;
129   };
130   __asm mov eax, [eax].A.b
131   // CHECK-LABEL: define void @_Z9t7_structv
132   // CHECK: call void asm sideeffect inteldialect
133   // CHECK-SAME: mov eax, [eax + $$4]
134   // CHECK-SAME: "~{eax},~{dirflag},~{fpsr},~{flags}"()
135 }
136 
137 void t7_typedef() {
138   typedef struct {
139     int a;
140     int b;
141   } A;
142   __asm mov eax, [eax].A.b
143   // CHECK-LABEL: define void @_Z10t7_typedefv
144   // CHECK: call void asm sideeffect inteldialect
145   // CHECK-SAME: mov eax, [eax + $$4]
146   // CHECK-SAME: "~{eax},~{dirflag},~{fpsr},~{flags}"()
147 }
148 
149 void t7_using() {
150   using A = struct {
151     int a;
152     int b;
153   };
154   __asm mov eax, [eax].A.b
155   // CHECK-LABEL: define void @_Z8t7_usingv
156   // CHECK: call void asm sideeffect inteldialect
157   // CHECK-SAME: mov eax, [eax + $$4]
158   // CHECK-SAME: "~{eax},~{dirflag},~{fpsr},~{flags}"()
159 }
160 
161 void t8() {
162   __asm some_label:
163   // CHECK-LABEL: define void @_Z2t8v()
164   // CHECK: call void asm sideeffect inteldialect
165   // CHECK-SAME: L__MSASMLABEL_.${:uid}__some_label:
166   // CHECK-SAME: "~{dirflag},~{fpsr},~{flags}"()
167   struct A {
168     static void g() {
169       __asm jmp some_label ; This should jump forwards
170       __asm some_label:
171       __asm nop
172       // CHECK-LABEL: define internal void @_ZZ2t8vEN1A1gEv()
173       // CHECK: call void asm sideeffect inteldialect
174       // CHECK-SAME: jmp L__MSASMLABEL_.${:uid}__some_label
175       // CHECK-SAME: L__MSASMLABEL_.${:uid}__some_label:
176       // CHECK-SAME: nop
177       // CHECK-SAME: "~{dirflag},~{fpsr},~{flags}"()
178     }
179   };
180   A::g();
181 }
182 
183 void t9() {
184   // CHECK-LABEL: define void @_Z2t9v()
185   struct A {
186     int a;
187     int b;
188     void g() {
189       __asm mov eax, dword ptr [eax]this.b
190       // CHECK: call void asm sideeffect inteldialect
191       // CHECK-SAME: mov eax, dword ptr [eax + $$4]
192       // CHECK-SAME: "~{eax},~{dirflag},~{fpsr},~{flags}"()
193     }
194   };
195   A AA;
196   AA.g();
197 }
198 
199